authorgravatar for r00ster91@proton.meWooster <r00ster91@proton.me> 2023-02-21 18:09:00+01:00
committergravatar for r00ster91@proton.meWooster <r00ster91@proton.me> 2023-02-24 20:03:40+01:00
log0b2ee093788ba84c5d130c021f347844b5939889
treea03166a9379bbad387a7177e649419ed43dbece0
parentc9e02d3e69f909a6eb215286c6109f2b3f1e68a2

std.Thread.setName: use unused code

I noticed a comment saying that the intent of a code's author was unclear. What happened is that the author forgot to put the check for whether the thread is the calling thread (`self.getHandle() == std.c.pthread_self()`) in the `if (use_pthreads)`. If the thread is the calling thread, we use `prctl` to set or get the thread's name and it does not take a thread id because it knows the id of the thread we're calling `getName` or `setName` from. I have found a source saying that using `pthread_setname_np` on either the calling thread or any other thread by thread id would work too (so we don't need to call `prctl`) but I was not sure if that is the case on all systems so we keep using `pthread_setname_np` if we have a specific thread that is not the thread we're calling from, and `prctl` otherwise.

1 files changed, 17 insertions(+), 14 deletions(-)

lib/std/Thread.zig+17-14
...@@ -62,18 +62,20 @@ pub fn setName(self: Thread, name: []const u8) SetNameError!void {...@@ -62,18 +62,20 @@ pub fn setName(self: Thread, name: []const u8) SetNameError!void {
6262
63 switch (target.os.tag) {63 switch (target.os.tag) {
64 .linux => if (use_pthreads) {64 .linux => if (use_pthreads) {
65 const err = std.c.pthread_setname_np(self.getHandle(), name_with_terminator.ptr);65 if (self.getHandle() == std.c.pthread_self()) {
66 switch (err) {66 // Set the name of the calling thread (no thread id required).
67 .SUCCESS => return,67 const err = try os.prctl(.SET_NAME, .{@ptrToInt(name_with_terminator.ptr)});
68 .RANGE => unreachable,68 switch (@intToEnum(os.E, err)) {
69 else => |e| return os.unexpectedErrno(e),69 .SUCCESS => return,
70 }70 else => |e| return os.unexpectedErrno(e),
71 } else if (use_pthreads and self.getHandle() == std.c.pthread_self()) {71 }
72 // TODO: this is dead code. what did the author of this code intend to happen here?72 } else {
73 const err = try os.prctl(.SET_NAME, .{@ptrToInt(name_with_terminator.ptr)});73 const err = std.c.pthread_setname_np(self.getHandle(), name_with_terminator.ptr);
74 switch (@intToEnum(os.E, err)) {74 switch (err) {
75 .SUCCESS => return,75 .SUCCESS => return,
76 else => |e| return os.unexpectedErrno(e),76 .RANGE => unreachable,
77 else => |e| return os.unexpectedErrno(e),
78 }
77 }79 }
78 } else {80 } else {
79 var buf: [32]u8 = undefined;81 var buf: [32]u8 = undefined;
...@@ -177,6 +179,7 @@ pub fn getName(self: Thread, buffer_ptr: *[max_name_len:0]u8) GetNameError!?[]co...@@ -177,6 +179,7 @@ pub fn getName(self: Thread, buffer_ptr: *[max_name_len:0]u8) GetNameError!?[]co
177 else => |e| return os.unexpectedErrno(e),179 else => |e| return os.unexpectedErrno(e),
178 }180 }
179 } else if (use_pthreads and self.getHandle() == std.c.pthread_self()) {181 } else if (use_pthreads and self.getHandle() == std.c.pthread_self()) {
182 // Get the name of the calling thread (no thread id required).
180 const err = try os.prctl(.GET_NAME, .{@ptrToInt(buffer.ptr)});183 const err = try os.prctl(.GET_NAME, .{@ptrToInt(buffer.ptr)});
181 switch (@intToEnum(os.E, err)) {184 switch (@intToEnum(os.E, err)) {
182 .SUCCESS => return std.mem.sliceTo(buffer, 0),185 .SUCCESS => return std.mem.sliceTo(buffer, 0),
...@@ -325,10 +328,10 @@ pub const SpawnError = error{...@@ -325,10 +328,10 @@ pub const SpawnError = error{
325 Unexpected,328 Unexpected,
326};329};
327330
328/// Spawns a new thread which executes `function` using `args` and returns a handle the spawned thread.331/// Spawns a new thread which executes `function` using `args` and returns a handle to the spawned thread.
329/// `config` can be used as hints to the platform for now to spawn and execute the `function`.332/// `config` can be used as hints to the platform for now to spawn and execute the `function`.
330/// The caller must eventually either call `join()` to wait for the thread to finish and free its resources333/// The caller must eventually either call `join()` to wait for the thread to finish and free its resources
331/// or call `detach()` to excuse the caller from calling `join()` and have the thread clean up its resources on completion`.334/// or call `detach()` to excuse the caller from calling `join()` and have the thread clean up its resources on completion.
332pub fn spawn(config: SpawnConfig, comptime function: anytype, args: anytype) SpawnError!Thread {335pub fn spawn(config: SpawnConfig, comptime function: anytype, args: anytype) SpawnError!Thread {
333 if (builtin.single_threaded) {336 if (builtin.single_threaded) {
334 @compileError("Cannot spawn thread when building in single-threaded mode");337 @compileError("Cannot spawn thread when building in single-threaded mode");