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();
|
pool.cond.signal();
|
||||||
}
|
}
|
||||||
|
|
||||||
fn worker(pool: *Pool) void {
|
fn acquireThreadToken(job_server_options: Options.JobServer, fd_ptr: *std.posix.fd_t) void {
|
||||||
var trash_buf: [1]u8 = undefined;
|
if (fd_ptr.* >= 0) return;
|
||||||
var connection: ?std.posix.fd_t = null;
|
|
||||||
defer if (connection) |fd| std.posix.close(fd);
|
|
||||||
|
|
||||||
pool.mutex.lock();
|
switch (job_server_options) {
|
||||||
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) {
|
|
||||||
.abstain => {},
|
.abstain => {},
|
||||||
.connect, .host => |addr| lock: {
|
.connect, .host => |addr| {
|
||||||
const sockfd = std.posix.socket(
|
const sockfd = std.posix.socket(
|
||||||
std.posix.AF.UNIX,
|
std.posix.AF.UNIX,
|
||||||
std.posix.SOCK.STREAM | std.posix.SOCK.CLOEXEC,
|
std.posix.SOCK.STREAM | std.posix.SOCK.CLOEXEC,
|
||||||
0,
|
0,
|
||||||
) catch |err| {
|
) catch |err| {
|
||||||
std.log.debug("failed to make socket: {s}", .{@errorName(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.posix.connect(sockfd, &addr.any, addr.getOsSockLen()) catch |err| {
|
||||||
std.log.debug("failed to connect: {s}", .{@errorName(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.posix.read(sockfd, &trash_buf) catch |err| {
|
||||||
std.log.debug("failed to read: {s}", .{@errorName(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.
|
fn releaseThreadToken(fd_ptr: *std.posix.fd_t) void {
|
||||||
if (pool.end_flag)
|
const fd = fd_ptr.*;
|
||||||
break;
|
if (fd >= 0) {
|
||||||
|
|
||||||
if (connection) |fd| {
|
|
||||||
std.posix.close(fd);
|
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);
|
pool.cond.wait(&pool.mutex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue