Skip to content

Commit

Permalink
Fix: GC safety of Thread#start
Browse files Browse the repository at this point in the history
  • Loading branch information
ysbaddaden committed May 3, 2024
1 parent 7b39409 commit d0514bd
Showing 1 changed file with 14 additions and 3 deletions.
17 changes: 14 additions & 3 deletions src/crystal/system/thread.cr
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ class Thread
include Crystal::System::Thread

# all thread objects, so the GC can see them (it doesn't scan thread locals)
# and iterate each thread to mark its current stack (the current fiber may not
# be the main thread's fiber that the GC knows)
protected class_getter(threads) { Thread::LinkedList(Thread).new }

@system_handle : Crystal::System::Thread::Handle
Expand Down Expand Up @@ -64,6 +66,9 @@ class Thread
def initialize(@name : String? = nil, &@func : Thread ->)
@system_handle = uninitialized Crystal::System::Thread::Handle
init_handle

# keep a reference to the thread object
Thread.threads.push(self)
end

# Used once to initialize the thread object representing the main thread of
Expand Down Expand Up @@ -121,7 +126,8 @@ class Thread
getter scheduler : Crystal::Scheduler { Crystal::Scheduler.new(self) }

protected def start
Thread.threads.push(self)
# note: until we set the current fiber, the GC will mark the thread's main
# stack (i.e. it's safe to allocate objects):
Thread.current = self
@current_fiber = @main_fiber = fiber = Fiber.new(stack_address, self)

Expand All @@ -134,9 +140,14 @@ class Thread
rescue ex
@exception = ex
ensure
Thread.threads.delete(self)
Fiber.inactive(fiber)
# to shutdown the thread we first call any function that needs to access
# local or instance variables, then start cleaning up references (that
# may be the last reference, so the GC may collect them anytime):
detach { system_close }
Fiber.inactive(fiber)

# eventually forget the thread reference (must be the last thing to do)
Thread.threads.delete(self)
end
end

Expand Down

0 comments on commit d0514bd

Please sign in to comment.