Skip to content

Commit

Permalink
Thread: set name (#14257)
Browse files Browse the repository at this point in the history
Co-authored-by: Johannes Müller <straightshoota@gmail.com>
  • Loading branch information
ysbaddaden and straight-shoota committed Jan 30, 2024
1 parent f663121 commit 8d1c080
Show file tree
Hide file tree
Showing 20 changed files with 74 additions and 2 deletions.
13 changes: 13 additions & 0 deletions spec/std/thread_spec.cr
Original file line number Diff line number Diff line change
Expand Up @@ -49,4 +49,17 @@ describe Thread do

thread.join
end

it "names the thread" do
Thread.current.name.should be_nil
name = nil

thread = Thread.new(name: "some-name") do
name = Thread.current.name
end
thread.name.should eq("some-name")

thread.join
name.should eq("some-name")
end
end
2 changes: 1 addition & 1 deletion src/crystal/scheduler.cr
Original file line number Diff line number Diff line change
Expand Up @@ -234,7 +234,7 @@ class Crystal::Scheduler
Thread.current.scheduler.enqueue worker_loop
Thread.current
else
Thread.new do
Thread.new(name: "CRYSTAL-MT-#{i}") do
scheduler = Thread.current.scheduler
pending.sub(1)
scheduler.run_loop
Expand Down
20 changes: 19 additions & 1 deletion src/crystal/system/thread.cr
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ module Crystal::System::Thread
# private def system_close

# private def stack_address : Void*

# private def system_name=(String) : String
end

{% if flag?(:wasi) %}
Expand Down Expand Up @@ -49,12 +51,14 @@ class Thread
# :nodoc:
property previous : Thread?

getter name : String?

def self.unsafe_each(&)
threads.unsafe_each { |thread| yield thread }
end

# Creates and starts a new system thread.
def initialize(&@func : ->)
def initialize(@name : String? = nil, &@func : ->)
@system_handle = uninitialized Crystal::System::Thread::Handle
init_handle
end
Expand Down Expand Up @@ -104,6 +108,12 @@ class Thread
Crystal::System::Thread.yield_current
end

# Changes the name of the current thread.
def self.name=(name : String) : String
thread = Thread.current
thread.name = name
end

# :nodoc:
getter scheduler : Crystal::Scheduler { Crystal::Scheduler.new(self) }

Expand All @@ -112,6 +122,10 @@ class Thread
Thread.current = self
@main_fiber = fiber = Fiber.new(stack_address, self)

if name = @name
self.system_name = name
end

begin
@func.call
rescue ex
Expand All @@ -123,6 +137,10 @@ class Thread
end
end

protected def name=(@name : String)
self.system_name = name
end

# Holds the GC thread handler
property gc_thread_handler : Void* = Pointer(Void).null
end
Expand Down
17 changes: 17 additions & 0 deletions src/crystal/system/unix/pthread.cr
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,23 @@ module Crystal::System::Thread

address
end

# Warning: must be called from the current thread itself, because Darwin
# doesn't allow to set the name of any thread but the current one!
private def system_name=(name : String) : String
{% if flag?(:darwin) %}
LibC.pthread_setname_np(name)
{% elsif flag?(:netbsd) %}
LibC.pthread_setname_np(@system_handle, name, nil)
{% elsif LibC.has_method?(:pthread_setname_np) %}
LibC.pthread_setname_np(@system_handle, name)
{% elsif LibC.has_method?(:pthread_set_name_np) %}
LibC.pthread_set_name_np(@system_handle, name)
{% else %}
{% raise "No `Crystal::System::Thread#system_name` implementation available" %}
{% end %}
name
end
end

# In musl (alpine) the calls to unwind API segfaults
Expand Down
7 changes: 7 additions & 0 deletions src/crystal/system/win32/thread.cr
Original file line number Diff line number Diff line change
Expand Up @@ -72,4 +72,11 @@ module Crystal::System::Thread
low_limit
{% end %}
end

private def system_name=(name : String) : String
{% if LibC.has_method?(:SetThreadDescription) %}
LibC.SetThreadDescription(@system_handle, System.to_wstr(name))
{% end %}
name
end
end
1 change: 1 addition & 0 deletions src/lib_c/aarch64-android/c/pthread.cr
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ lib LibC
fun pthread_mutex_unlock(__mutex : PthreadMutexT*) : Int

fun pthread_self : PthreadT
fun pthread_setname_np(__key : PthreadT, __name : Char*) : Int

fun pthread_setspecific(__key : PthreadKeyT, __value : Void*) : Int
end
1 change: 1 addition & 0 deletions src/lib_c/aarch64-darwin/c/pthread.cr
Original file line number Diff line number Diff line change
Expand Up @@ -25,4 +25,5 @@ lib LibC
fun pthread_mutex_trylock(x0 : PthreadMutexT*) : Int
fun pthread_mutex_unlock(x0 : PthreadMutexT*) : Int
fun pthread_self : PthreadT
fun pthread_setname_np(Char*) : Int
end
1 change: 1 addition & 0 deletions src/lib_c/aarch64-linux-gnu/c/pthread.cr
Original file line number Diff line number Diff line change
Expand Up @@ -36,4 +36,5 @@ lib LibC
fun pthread_mutex_trylock(mutex : PthreadMutexT*) : Int
fun pthread_mutex_unlock(mutex : PthreadMutexT*) : Int
fun pthread_self : PthreadT
fun pthread_setname_np(PthreadT, Char*) : Int
end
1 change: 1 addition & 0 deletions src/lib_c/aarch64-linux-musl/c/pthread.cr
Original file line number Diff line number Diff line change
Expand Up @@ -27,4 +27,5 @@ lib LibC
fun pthread_mutex_trylock(x0 : PthreadMutexT*) : Int
fun pthread_mutex_unlock(x0 : PthreadMutexT*) : Int
fun pthread_self : PthreadT
fun pthread_setname_np(PthreadT, Char*) : Int
end
1 change: 1 addition & 0 deletions src/lib_c/arm-linux-gnueabihf/c/pthread.cr
Original file line number Diff line number Diff line change
Expand Up @@ -36,4 +36,5 @@ lib LibC
fun pthread_mutex_trylock(mutex : PthreadMutexT*) : Int
fun pthread_mutex_unlock(mutex : PthreadMutexT*) : Int
fun pthread_self : PthreadT
fun pthread_setname_np(PthreadT, Char*) : Int
end
1 change: 1 addition & 0 deletions src/lib_c/i386-linux-gnu/c/pthread.cr
Original file line number Diff line number Diff line change
Expand Up @@ -35,4 +35,5 @@ lib LibC
fun pthread_mutex_trylock(mutex : PthreadMutexT*) : Int
fun pthread_mutex_unlock(mutex : PthreadMutexT*) : Int
fun pthread_self : PthreadT
fun pthread_setname_np(PthreadT, Char*) : Int
end
1 change: 1 addition & 0 deletions src/lib_c/i386-linux-musl/c/pthread.cr
Original file line number Diff line number Diff line change
Expand Up @@ -27,4 +27,5 @@ lib LibC
fun pthread_mutex_trylock(x0 : PthreadMutexT*) : Int
fun pthread_mutex_unlock(x0 : PthreadMutexT*) : Int
fun pthread_self : PthreadT
fun pthread_setname_np(PthreadT, Char*) : Int
end
1 change: 1 addition & 0 deletions src/lib_c/x86_64-darwin/c/pthread.cr
Original file line number Diff line number Diff line change
Expand Up @@ -25,4 +25,5 @@ lib LibC
fun pthread_mutex_trylock(x0 : PthreadMutexT*) : Int
fun pthread_mutex_unlock(x0 : PthreadMutexT*) : Int
fun pthread_self : PthreadT
fun pthread_setname_np(Char*) : Int
end
1 change: 1 addition & 0 deletions src/lib_c/x86_64-dragonfly/c/pthread.cr
Original file line number Diff line number Diff line change
Expand Up @@ -29,4 +29,5 @@ lib LibC
fun pthread_mutex_trylock(x0 : PthreadMutexT*) : Int
fun pthread_mutex_unlock(x0 : PthreadMutexT*) : Int
fun pthread_self : PthreadT
fun pthread_setname_np(PthreadT, Char*) : Int
end
1 change: 1 addition & 0 deletions src/lib_c/x86_64-freebsd/c/pthread.cr
Original file line number Diff line number Diff line change
Expand Up @@ -29,4 +29,5 @@ lib LibC
fun pthread_mutex_trylock(x0 : PthreadMutexT*) : Int
fun pthread_mutex_unlock(x0 : PthreadMutexT*) : Int
fun pthread_self : PthreadT
fun pthread_set_name_np(PthreadT, Char*)
end
1 change: 1 addition & 0 deletions src/lib_c/x86_64-linux-gnu/c/pthread.cr
Original file line number Diff line number Diff line change
Expand Up @@ -35,4 +35,5 @@ lib LibC
fun pthread_mutex_trylock(mutex : PthreadMutexT*) : Int
fun pthread_mutex_unlock(mutex : PthreadMutexT*) : Int
fun pthread_self : PthreadT
fun pthread_setname_np(PthreadT, Char*) : Int
end
1 change: 1 addition & 0 deletions src/lib_c/x86_64-linux-musl/c/pthread.cr
Original file line number Diff line number Diff line change
Expand Up @@ -27,4 +27,5 @@ lib LibC
fun pthread_mutex_trylock(x0 : PthreadMutexT*) : Int
fun pthread_mutex_unlock(x0 : PthreadMutexT*) : Int
fun pthread_self : PthreadT
fun pthread_setname_np(PthreadT, Char*) : Int
end
1 change: 1 addition & 0 deletions src/lib_c/x86_64-netbsd/c/pthread.cr
Original file line number Diff line number Diff line change
Expand Up @@ -35,5 +35,6 @@ lib LibC
fun pthread_mutex_trylock(x0 : PthreadMutexT*) : Int
fun pthread_mutex_unlock(x0 : PthreadMutexT*) : Int
fun pthread_self : PthreadT
fun pthread_setname_np(PthreadT, Char*, Void*) : Int
fun pthread_setspecific(PthreadKeyT, Void*) : Int
end
1 change: 1 addition & 0 deletions src/lib_c/x86_64-openbsd/c/pthread.cr
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ lib LibC
fun pthread_mutex_trylock(x0 : PthreadMutexT*) : Int
fun pthread_mutex_unlock(x0 : PthreadMutexT*) : Int
fun pthread_self : PthreadT
fun pthread_set_name_np(PthreadT, Char*)
fun pthread_setspecific(PthreadKeyT, Void*) : Int
fun pthread_stackseg_np(PthreadT, StackT*) : Int
end
3 changes: 3 additions & 0 deletions src/lib_c/x86_64-windows-msvc/c/processthreadsapi.cr
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,9 @@ lib LibC
bInheritHandles : BOOL, dwCreationFlags : DWORD,
lpEnvironment : Void*, lpCurrentDirectory : LPWSTR,
lpStartupInfo : STARTUPINFOW*, lpProcessInformation : PROCESS_INFORMATION*) : BOOL
{% if LibC::WIN32_WINNT >= LibC::WIN32_WINNT_WIN10 %}
fun SetThreadDescription(hThread : HANDLE, lpThreadDescription : LPWSTR) : LONG
{% end %}
fun SetThreadStackGuarantee(stackSizeInBytes : DWORD*) : BOOL
fun GetProcessTimes(hProcess : HANDLE, lpCreationTime : FILETIME*, lpExitTime : FILETIME*,
lpKernelTime : FILETIME*, lpUserTime : FILETIME*) : BOOL
Expand Down

0 comments on commit 8d1c080

Please sign in to comment.