@zigc/lib 0.16.0-dev.3061 → 0.16.0-dev.3070

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zigc/lib",
3
- "version": "0.16.0-dev.3061",
3
+ "version": "0.16.0-dev.3070",
4
4
  "description": "Zig standard library and libc headers (shared across all platforms)",
5
5
  "repository": {
6
6
  "type": "git",
@@ -6,7 +6,7 @@ root_prog_node: std.Progress.Node,
6
6
  watch: bool,
7
7
 
8
8
  tcp_server: ?net.Server,
9
- serve_thread: ?std.Thread,
9
+ serve_task: ?Io.Future(Io.Cancelable!void),
10
10
 
11
11
  /// Uses `Io.Clock.awake`.
12
12
  base_timestamp: Io.Timestamp,
@@ -103,7 +103,7 @@ pub fn init(opts: Options) WebServer {
103
103
  .watch = opts.watch,
104
104
 
105
105
  .tcp_server = null,
106
- .serve_thread = null,
106
+ .serve_task = null,
107
107
 
108
108
  .base_timestamp = opts.base_timestamp.raw,
109
109
  .step_names_trailing = step_names_trailing,
@@ -136,9 +136,9 @@ pub fn deinit(ws: *WebServer) void {
136
136
  gpa.free(ws.time_report_msgs);
137
137
  gpa.free(ws.time_report_update_times);
138
138
 
139
- if (ws.serve_thread) |t| {
139
+ if (ws.serve_task) |t| {
140
140
  if (ws.tcp_server) |*s| s.stream.close(io);
141
- t.join();
141
+ t.await();
142
142
  }
143
143
  if (ws.tcp_server) |*s| s.deinit();
144
144
 
@@ -146,15 +146,15 @@ pub fn deinit(ws: *WebServer) void {
146
146
  }
147
147
  pub fn start(ws: *WebServer) error{AlreadyReported}!void {
148
148
  assert(ws.tcp_server == null);
149
- assert(ws.serve_thread == null);
149
+ assert(ws.serve_task == null);
150
150
  const io = ws.graph.io;
151
151
 
152
152
  ws.tcp_server = ws.listen_address.listen(io, .{ .reuse_address = true }) catch |err| {
153
- log.err("failed to listen to port {d}: {s}", .{ ws.listen_address.getPort(), @errorName(err) });
153
+ log.err("failed to listen to port {d}: {t}", .{ ws.listen_address.getPort(), err });
154
154
  return error.AlreadyReported;
155
155
  };
156
- ws.serve_thread = std.Thread.spawn(.{}, serve, .{ws}) catch |err| {
157
- log.err("unable to spawn web server thread: {s}", .{@errorName(err)});
156
+ ws.serve_task = io.concurrent(serve, .{ws}) catch |err| {
157
+ log.err("unable to spawn web server thread: {t}", .{err});
158
158
  ws.tcp_server.?.deinit(io);
159
159
  ws.tcp_server = null;
160
160
  return error.AlreadyReported;
@@ -165,15 +165,20 @@ pub fn start(ws: *WebServer) error{AlreadyReported}!void {
165
165
  log.info("hint: pass '--webui={f}' to use the same port next time", .{ws.tcp_server.?.socket.address});
166
166
  }
167
167
  }
168
- fn serve(ws: *WebServer) void {
168
+ fn serve(ws: *WebServer) Io.Cancelable!void {
169
169
  const io = ws.graph.io;
170
+ var group: Io.Group = .init;
171
+ defer group.cancel(io);
170
172
  while (true) {
171
- var stream = ws.tcp_server.?.accept(io) catch |err| {
172
- log.err("failed to accept connection: {s}", .{@errorName(err)});
173
- return;
173
+ var stream = ws.tcp_server.?.accept(io) catch |err| switch (err) {
174
+ error.Canceled => |e| return e,
175
+ else => |e| {
176
+ log.err("failed to accept connection: {t}", .{e});
177
+ return;
178
+ },
174
179
  };
175
- _ = std.Thread.spawn(.{}, accept, .{ ws, stream }) catch |err| {
176
- log.err("unable to spawn connection thread: {s}", .{@errorName(err)});
180
+ group.concurrent(io, accept, .{ ws, stream }) catch |err| {
181
+ log.err("unable to spawn connection thread: {t}", .{err});
177
182
  stream.close(io);
178
183
  continue;
179
184
  };
@@ -303,8 +308,8 @@ fn serveWebSocket(ws: *WebServer, sock: *http.Server.WebSocket) !noreturn {
303
308
  copy.* = @atomicLoad(u8, shared, .monotonic);
304
309
  }
305
310
 
306
- const recv_thread = try std.Thread.spawn(.{}, recvWebSocketMessages, .{ ws, sock });
307
- defer recv_thread.join();
311
+ var recv_thread = try io.concurrent(recvWebSocketMessages, .{ ws, sock });
312
+ defer recv_thread.cancel(io);
308
313
 
309
314
  {
310
315
  const hello_header: abi.Hello = .{
package/std/Thread.zig CHANGED
@@ -1147,6 +1147,11 @@ const LinuxThreadImpl = struct {
1147
1147
  /// Ported over from musl libc's pthread detached implementation:
1148
1148
  /// https://github.com/ifduyue/musl/search?q=__unmapself
1149
1149
  fn freeAndExit(self: *ThreadCompletion) noreturn {
1150
+ // If we do not reset the child_tidptr to null here, the kernel would later write the
1151
+ // value zero to that address, which is inside the block we're unmapping below, after
1152
+ // our thread exits. This can sometimes corrupt memory in other mmap blocks from
1153
+ // unrelated concurrent threads.
1154
+ _ = linux.set_tid_address(null);
1150
1155
  // If a signal were delivered between SYS_munmap and SYS_exit, any installed signal
1151
1156
  // handler would immediately segfault due to the stack being unmapped. To avoid this,
1152
1157
  // we need to mask all signals before entering the inline asm.
@@ -1484,7 +1489,7 @@ const LinuxThreadImpl = struct {
1484
1489
  }
1485
1490
 
1486
1491
  // Prepare the TLS segment and prepare a user_desc struct when needed on x86
1487
- var tls_ptr = linux.tls.prepareArea(mapped[tls_offset..]);
1492
+ var tls_ptr = linux.tls.prepareArea(mapped[tls_offset..][0..linux.tls.area_desc.size]);
1488
1493
  var user_desc: if (target.cpu.arch == .x86) linux.user_desc else void = undefined;
1489
1494
  if (target.cpu.arch == .x86) {
1490
1495
  defer tls_ptr = @intFromPtr(&user_desc);
package/std/os/linux.zig CHANGED
@@ -1584,6 +1584,11 @@ pub fn clone2(flags: u32, child_stack_ptr: usize) usize {
1584
1584
  return syscall2(.clone, flags, child_stack_ptr);
1585
1585
  }
1586
1586
 
1587
+ /// This call cannot fail, and the return value is the caller's thread id
1588
+ pub fn set_tid_address(tidptr: ?*pid_t) pid_t {
1589
+ return @intCast(@as(u32, @truncate(syscall1(.set_tid_address, @intFromPtr(tidptr)))));
1590
+ }
1591
+
1587
1592
  pub fn close(fd: fd_t) usize {
1588
1593
  return syscall1(.close, @as(usize, @bitCast(@as(isize, fd))));
1589
1594
  }