mirror of
https://codeberg.org/ziglang/zig.git
synced 2025-12-06 13:54:21 +00:00
std.Thread.Pool: don't hold the job closure while blocking on IPC read
This commit is contained in:
parent
6d3a78b8dd
commit
dc207da184
1 changed files with 49 additions and 42 deletions
|
|
@ -310,58 +310,65 @@ pub fn spawn(pool: *Pool, comptime func: anytype, args: anytype) void {
|
|||
pool.cond.signal();
|
||||
}
|
||||
|
||||
fn worker(pool: *Pool) void {
|
||||
var trash_buf: [1]u8 = undefined;
|
||||
var connection: ?std.posix.fd_t = null;
|
||||
defer if (connection) |fd| std.posix.close(fd);
|
||||
fn acquireThreadToken(job_server_options: Options.JobServer, fd_ptr: *std.posix.fd_t) void {
|
||||
if (fd_ptr.* >= 0) return;
|
||||
|
||||
pool.mutex.lock();
|
||||
defer pool.mutex.unlock();
|
||||
|
||||
while (true) {
|
||||
while (pool.run_queue.popFirst()) |run_node| {
|
||||
// Temporarily unlock the mutex in order to execute the run_node.
|
||||
pool.mutex.unlock();
|
||||
defer pool.mutex.lock();
|
||||
|
||||
if (connection == null) switch (pool.job_server_options) {
|
||||
switch (job_server_options) {
|
||||
.abstain => {},
|
||||
.connect, .host => |addr| lock: {
|
||||
.connect, .host => |addr| {
|
||||
const sockfd = std.posix.socket(
|
||||
std.posix.AF.UNIX,
|
||||
std.posix.SOCK.STREAM | std.posix.SOCK.CLOEXEC,
|
||||
0,
|
||||
) catch |err| {
|
||||
std.log.debug("failed to make socket: {s}", .{@errorName(err)});
|
||||
break :lock;
|
||||
return;
|
||||
};
|
||||
connection = sockfd;
|
||||
fd_ptr.* = sockfd;
|
||||
|
||||
std.posix.connect(sockfd, &addr.any, addr.getOsSockLen()) catch |err| {
|
||||
std.log.debug("failed to connect: {s}", .{@errorName(err)});
|
||||
break :lock;
|
||||
return;
|
||||
};
|
||||
|
||||
var trash_buf: [1]u8 = undefined;
|
||||
_ = std.posix.read(sockfd, &trash_buf) catch |err| {
|
||||
std.log.debug("failed to read: {s}", .{@errorName(err)});
|
||||
break :lock;
|
||||
return;
|
||||
};
|
||||
},
|
||||
};
|
||||
|
||||
const runFn = run_node.data.runFn;
|
||||
runFn(&run_node.data);
|
||||
}
|
||||
}
|
||||
|
||||
// Stop executing instead of waiting if the thread pool is no longer running.
|
||||
if (pool.end_flag)
|
||||
break;
|
||||
|
||||
if (connection) |fd| {
|
||||
fn releaseThreadToken(fd_ptr: *std.posix.fd_t) void {
|
||||
const fd = fd_ptr.*;
|
||||
if (fd >= 0) {
|
||||
std.posix.close(fd);
|
||||
connection = null;
|
||||
fd_ptr.* = -1;
|
||||
}
|
||||
}
|
||||
|
||||
fn worker(pool: *Pool) void {
|
||||
var connection: std.posix.fd_t = -1;
|
||||
defer releaseThreadToken(&connection);
|
||||
|
||||
pool.mutex.lock();
|
||||
defer pool.mutex.unlock();
|
||||
|
||||
while (true) {
|
||||
const work_available = pool.run_queue.first != null;
|
||||
if (work_available) {
|
||||
pool.mutex.unlock();
|
||||
defer pool.mutex.lock();
|
||||
acquireThreadToken(pool.job_server_options, &connection);
|
||||
}
|
||||
while (pool.run_queue.popFirst()) |run_node| {
|
||||
pool.mutex.unlock();
|
||||
defer pool.mutex.lock();
|
||||
run_node.data.runFn(&run_node.data);
|
||||
}
|
||||
if (pool.end_flag) return;
|
||||
releaseThreadToken(&connection);
|
||||
pool.cond.wait(&pool.mutex);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue