Runtime initialization is currently spread over a number of different locations in the prelude, each executing at different times.
For example, Crystal.init_runtime only initialize Crystal::Once as well as the Fiber and Thread lists.
|
# :nodoc: |
|
def self.init_runtime : Nil |
|
# `__crystal_once` directly or indirectly depends on `Fiber` and `Thread` |
|
# so we explicitly initialize their class vars, then init crystal/once |
|
Thread.init |
|
Fiber.init |
|
Crystal::Once.init |
|
end |
kernel.cr initializes execution context / scheduler, callstack and signal handlers in top-level user code:
|
{% unless flag?(:interpreted) || flag?(:wasm32) %} |
|
{% if flag?(:execution_context) %} |
|
Fiber::ExecutionContext.init_default_context |
|
{% else %} |
|
Crystal::Scheduler.init |
|
{% end %} |
|
|
|
# load debug info on start up of the program is executed with CRYSTAL_LOAD_DEBUG_INFO=1 |
|
# this will make debug info available on print_frame that is used by Crystal's segfault handler |
|
# |
|
# - CRYSTAL_LOAD_DEBUG_INFO=0 will never use debug info (See Exception::CallStack.load_debug_info) |
|
# - CRYSTAL_LOAD_DEBUG_INFO=1 will load debug info on startup |
|
# - Other values will load debug info on demand: when the backtrace of the first exception is generated |
|
Exception::CallStack.load_debug_info if ENV["CRYSTAL_LOAD_DEBUG_INFO"]? == "1" |
|
Exception::CallStack.setup_crash_handler |
|
|
|
{% if flag?(:win32) %} |
|
Crystal::System::Process.start_interrupt_loop |
|
{% else %} |
|
Crystal::System::Signal.setup_default_handlers |
|
{% end %} |
|
{% end %} |
|
|
|
{% if flag?(:interpreted) && flag?(:unix) && Crystal::Interpreter.class.has_method?(:signal_descriptor) %} |
|
Crystal::System::Signal.setup_default_handlers |
|
{% end %} |
The odd thing is that this top-level user code is defined somewhere in the alphabetically-sorted require list from prelude.cr. It happens to work, but it would fail if we try to use IO in top-level code from any of the previously required files.
It would be nice to define the runtime startup sequence a bit more explicitly, and document the exact conditions for hooking into Crystal.main and Crystal.main_user_code.
There are use cases that require to run code at process startup when it is guaranteed to be single-threaded to avoid any threading issues (ENV modifications, fork). They might require different levels of runtime initialization. For the former, a working event loop would be nice, for example.
We should probably move all stdlib initialization code into methods instead of top-level user code. We can call these methods explicitly from Crystal.main/Crystal.main_user_code in order to establish a clear init sequence.
Add a 👍 reaction to issues you find important.
Runtime initialization is currently spread over a number of different locations in the prelude, each executing at different times.
For example,
Crystal.init_runtimeonly initializeCrystal::Onceas well as theFiberandThreadlists.crystal/src/crystal/main.cr
Lines 53 to 60 in 8365f55
kernel.crinitializes execution context / scheduler, callstack and signal handlers in top-level user code:crystal/src/kernel.cr
Lines 602 to 627 in 8365f55
The odd thing is that this top-level user code is defined somewhere in the alphabetically-sorted require list from
prelude.cr. It happens to work, but it would fail if we try to use IO in top-level code from any of the previously required files.It would be nice to define the runtime startup sequence a bit more explicitly, and document the exact conditions for hooking into
Crystal.mainandCrystal.main_user_code.There are use cases that require to run code at process startup when it is guaranteed to be single-threaded to avoid any threading issues (
ENVmodifications,fork). They might require different levels of runtime initialization. For the former, a working event loop would be nice, for example.We should probably move all stdlib initialization code into methods instead of top-level user code. We can call these methods explicitly from
Crystal.main/Crystal.main_user_codein order to establish a clear init sequence.Add a 👍 reaction to issues you find important.