Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 22 additions & 20 deletions lib/compiler/std-docs.zig
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,10 @@ pub fn main() !void {
var general_purpose_allocator: std.heap.GeneralPurposeAllocator(.{}) = .init;
const gpa = general_purpose_allocator.allocator();

var threaded: std.Io.Threaded = .init(gpa);
defer threaded.deinit();
const io = threaded.io();

var argv = try std.process.argsWithAllocator(arena);
defer argv.deinit();
assert(argv.skip());
Expand Down Expand Up @@ -58,11 +62,11 @@ pub fn main() !void {
}
const should_open_browser = force_open_browser orelse (listen_port == 0);

const address = std.net.Address.parseIp("127.0.0.1", listen_port) catch unreachable;
var http_server = try address.listen(.{
const address = std.Io.net.IpAddress.parse("127.0.0.1", listen_port) catch unreachable;
var http_server = try address.listen(io, .{
.reuse_address = true,
});
const port = http_server.listen_address.in.getPort();
const port = http_server.socket.address.getPort();
const url_with_newline = try std.fmt.allocPrint(arena, "http://127.0.0.1:{d}/\n", .{port});
std.fs.File.stdout().writeAll(url_with_newline) catch {};
if (should_open_browser) {
Expand All @@ -73,30 +77,31 @@ pub fn main() !void {

var context: Context = .{
.gpa = gpa,
.io = io,
.zig_exe_path = zig_exe_path,
.global_cache_path = global_cache_path,
.lib_dir = lib_dir,
.zig_lib_directory = zig_lib_directory,
};

while (true) {
const connection = try http_server.accept();
_ = std.Thread.spawn(.{}, accept, .{ &context, connection }) catch |err| {
const stream = try http_server.accept(io);
_ = std.Thread.spawn(.{}, accept, .{ &context, stream }) catch |err| {
std.log.err("unable to accept connection: {s}", .{@errorName(err)});
connection.stream.close();
stream.close(io);
continue;
};
}
}

fn accept(context: *Context, connection: std.net.Server.Connection) void {
defer connection.stream.close();
fn accept(context: *Context, stream: std.Io.net.Stream) void {
defer stream.close(context.io);

var recv_buffer: [4000]u8 = undefined;
var send_buffer: [4000]u8 = undefined;
var conn_reader = connection.stream.reader(&recv_buffer);
var conn_writer = connection.stream.writer(&send_buffer);
var server = std.http.Server.init(conn_reader.interface(), &conn_writer.interface);
var conn_reader = stream.reader(context.io, &recv_buffer);
var conn_writer = stream.writer(context.io, &send_buffer);
var server = std.http.Server.init(&conn_reader.interface, &conn_writer.interface);
while (server.reader.state == .ready) {
var request = server.receiveHead() catch |err| switch (err) {
error.HttpConnectionClosing => return,
Expand Down Expand Up @@ -124,6 +129,7 @@ fn accept(context: *Context, connection: std.net.Server.Connection) void {

const Context = struct {
gpa: Allocator,
io: std.Io,
lib_dir: std.fs.Dir,
zig_lib_directory: []const u8,
zig_exe_path: []const u8,
Expand Down Expand Up @@ -215,15 +221,11 @@ fn serveSourcesTar(request: *std.http.Server.Request, context: *Context) !void {
},
else => continue,
}
var file = try entry.dir.openFile(entry.basename, .{});
const file = try entry.dir.openFile(entry.basename, .{});
defer file.close();
const stat = try file.stat();
var file_reader: std.fs.File.Reader = .{
.file = file,
.interface = std.fs.File.Reader.initInterface(&.{}),
.size = stat.size,
};
try archiver.writeFile(entry.path, &file_reader, stat.mtime);
var file_reader = file.reader(context.io, &.{});
try archiver.writeFileTimestamp(entry.path, &file_reader, stat.mtime);
}

{
Expand Down Expand Up @@ -255,7 +257,7 @@ fn serveWasm(
const wasm_base_path = try buildWasmBinary(arena, context, optimize_mode);
const bin_name = try std.zig.binNameAlloc(arena, .{
.root_name = autodoc_root_name,
.target = &(std.zig.system.resolveTargetQuery(std.Build.parseTargetQuery(.{
.target = &(std.zig.system.resolveTargetQuery(context.io, std.Build.parseTargetQuery(.{
.arch_os_abi = autodoc_arch_os_abi,
.cpu_features = autodoc_cpu_features,
}) catch unreachable) catch unreachable),
Expand Down Expand Up @@ -394,7 +396,7 @@ fn buildWasmBinary(
}

if (result_error_bundle.errorMessageCount() > 0) {
result_error_bundle.renderToStdErr(.{}, true);
result_error_bundle.renderToStdErr(.{}, .on);
std.log.err("the following command failed with {d} compilation errors:\n{s}", .{
result_error_bundle.errorMessageCount(),
try std.Build.Step.allocPrintCmd(arena, null, argv.items),
Expand Down
8 changes: 6 additions & 2 deletions lib/std/Io/Writer.zig
Original file line number Diff line number Diff line change
Expand Up @@ -911,11 +911,15 @@ pub fn sendFileHeader(
file_reader: *File.Reader,
limit: Limit,
) FileError!usize {
const new_end = w.end + header.len;
const old_end = w.end;
const new_end = old_end + header.len;
if (new_end <= w.buffer.len) {
@memcpy(w.buffer[w.end..][0..header.len], header);
w.end = new_end;
return header.len + try w.vtable.sendFile(w, file_reader, limit);
return header.len + (w.vtable.sendFile(w, file_reader, limit) catch |err| {
w.end = old_end;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That change I'm not sure about myself...when the underlying writer returns error.Unimplemented we need to make sure w.end is in its original state so the writer above will re-send the header (because it does not know how much of it was written), but we need to write it before calling w.vtable.sendFile because it might flush. With this fix, the @memcopy call is wasted.
Another solution would be to follow through with sendFileReading but as the docstring of sendFile suggests, it may be less efficient than wasting the @memcopy once per file.

return err;
});
}
const buffered_contents = limit.slice(file_reader.interface.buffered());
const n = try w.vtable.drain(w, &.{ header, buffered_contents }, 1);
Expand Down
7 changes: 5 additions & 2 deletions lib/std/http.zig
Original file line number Diff line number Diff line change
Expand Up @@ -975,8 +975,11 @@ pub const BodyWriter = struct {
2 => {
try out.writeAll("\r\n");
bw.state.chunk_len = 0;
assert(file_reader.atEnd());
return error.EndOfStream;
if (file_reader.atEnd()) {
return error.EndOfStream;
} else {
continue :l bw.state.chunk_len;
}
},
else => {
const chunk_limit: std.Io.Limit = .limited(bw.state.chunk_len - 2);
Expand Down