Skip to content

Commit 1596aed

Browse files
committed
fetch: avoid copying Resource
1 parent 59ba197 commit 1596aed

File tree

2 files changed

+25
-27
lines changed

2 files changed

+25
-27
lines changed

src/Package/Fetch.zig

Lines changed: 22 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -400,7 +400,8 @@ pub fn run(f: *Fetch) RunError!void {
400400
.{ path_or_url, file_err, uri_err },
401401
));
402402
};
403-
var resource = try f.initResource(uri, &server_header_buffer);
403+
var resource: Resource = undefined;
404+
try f.initResource(uri, &resource, &server_header_buffer);
404405
return f.runResource(try uri.path.toRawMaybeAlloc(arena), &resource, null);
405406
}
406407
},
@@ -466,7 +467,8 @@ pub fn run(f: *Fetch) RunError!void {
466467
try eb.printString("invalid URI: {s}", .{@errorName(err)}),
467468
);
468469
var buffer: [init_resource_buffer_size]u8 = undefined;
469-
var resource = try f.initResource(uri, &buffer);
470+
var resource: Resource = undefined;
471+
try f.initResource(uri, &resource, &buffer);
470472
return f.runResource(try uri.path.toRawMaybeAlloc(arena), &resource, remote.hash);
471473
}
472474

@@ -880,7 +882,7 @@ const Resource = union(enum) {
880882

881883
const HttpRequest = struct {
882884
request: std.http.Client.Request,
883-
head: std.http.Client.Response.Head,
885+
response: std.http.Client.Response,
884886
buffer: []u8,
885887
};
886888

@@ -900,13 +902,7 @@ const Resource = union(enum) {
900902
fn reader(resource: *Resource) *std.Io.Reader {
901903
return switch (resource.*) {
902904
.file => |*file_reader| return &file_reader.interface,
903-
.http_request => |*http_request| {
904-
const response: std.http.Client.Response = .{
905-
.request = &http_request.request,
906-
.head = http_request.head,
907-
};
908-
return response.reader(http_request.buffer);
909-
},
905+
.http_request => |*http_request| return http_request.response.reader(http_request.buffer),
910906
.git => |*g| return &g.fetch_stream.reader,
911907
.dir => unreachable,
912908
};
@@ -974,7 +970,7 @@ const FileType = enum {
974970

975971
const init_resource_buffer_size = git.Packet.max_data_length;
976972

977-
fn initResource(f: *Fetch, uri: std.Uri, reader_buffer: []u8) RunError!Resource {
973+
fn initResource(f: *Fetch, uri: std.Uri, resource: *Resource, reader_buffer: []u8) RunError!void {
978974
const gpa = f.arena.child_allocator;
979975
const arena = f.arena.allocator();
980976
const eb = &f.error_bundle;
@@ -986,35 +982,38 @@ fn initResource(f: *Fetch, uri: std.Uri, reader_buffer: []u8) RunError!Resource
986982
f.parent_package_root, path, err,
987983
}));
988984
};
989-
return .{ .file = file.reader(reader_buffer) };
985+
resource.* = .{ .file = file.reader(reader_buffer) };
986+
return;
990987
}
991988

992989
const http_client = f.job_queue.http_client;
993990

994991
if (ascii.eqlIgnoreCase(uri.scheme, "http") or
995992
ascii.eqlIgnoreCase(uri.scheme, "https"))
996993
{
997-
var request = http_client.request(.GET, uri, .{}) catch |err|
998-
return f.fail(f.location_tok, try eb.printString("unable to connect to server: {t}", .{err}));
994+
resource.* = .{ .http_request = .{
995+
.request = http_client.request(.GET, uri, .{}) catch |err|
996+
return f.fail(f.location_tok, try eb.printString("unable to connect to server: {t}", .{err})),
997+
.response = undefined,
998+
.buffer = reader_buffer,
999+
} };
1000+
const request = &resource.http_request.request;
9991001
defer request.deinit();
10001002

10011003
request.sendBodiless() catch |err|
10021004
return f.fail(f.location_tok, try eb.printString("HTTP request failed: {t}", .{err}));
10031005

10041006
var redirect_buffer: [1024]u8 = undefined;
1005-
const response = request.receiveHead(&redirect_buffer) catch |err|
1007+
const response = &resource.http_request.response;
1008+
response.* = request.receiveHead(&redirect_buffer) catch |err|
10061009
return f.fail(f.location_tok, try eb.printString("invalid HTTP response: {t}", .{err}));
10071010

10081011
if (response.head.status != .ok) return f.fail(f.location_tok, try eb.printString(
10091012
"bad HTTP response code: '{d} {s}'",
10101013
.{ response.head.status, response.head.status.phrase() orelse "" },
10111014
));
10121015

1013-
return .{ .http_request = .{
1014-
.request = request,
1015-
.head = response.head,
1016-
.buffer = reader_buffer,
1017-
} };
1016+
return;
10181017
}
10191018

10201019
if (ascii.eqlIgnoreCase(uri.scheme, "git+http") or
@@ -1087,13 +1086,12 @@ fn initResource(f: *Fetch, uri: std.Uri, reader_buffer: []u8) RunError!Resource
10871086
};
10881087
errdefer fetch_stream.deinit();
10891088

1090-
if (true) @panic("TODO this moves fetch_stream, invalidating its reader");
1091-
1092-
return .{ .git = .{
1089+
resource.* = .{ .git = .{
10931090
.session = session,
10941091
.fetch_stream = fetch_stream,
10951092
.want_oid = want_oid,
10961093
} };
1094+
return;
10971095
}
10981096

10991097
return f.fail(f.location_tok, try eb.printString("unsupported URL scheme: {s}", .{uri.scheme}));
@@ -1111,7 +1109,7 @@ fn unpackResource(
11111109
return f.fail(f.location_tok, try eb.printString("unknown file type: '{s}'", .{uri_path})),
11121110

11131111
.http_request => |*http_request| ft: {
1114-
const head = &http_request.head;
1112+
const head = &http_request.response.head;
11151113

11161114
// Content-Type takes first precedence.
11171115
const content_type = head.content_type orelse

src/Package/Fetch/git.zig

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -773,7 +773,7 @@ pub const Session = struct {
773773
try request.sendBodiless();
774774

775775
var redirect_buffer: [1024]u8 = undefined;
776-
const response = try request.receiveHead(&redirect_buffer);
776+
var response = try request.receiveHead(&redirect_buffer);
777777
if (response.head.status != .ok) return error.ProtocolError;
778778
const any_redirects_occurred = request.redirect_behavior.remaining() < max_redirects;
779779
if (any_redirects_occurred) {
@@ -918,7 +918,7 @@ pub const Session = struct {
918918
errdefer request.deinit();
919919
try request.sendBodyComplete(body.buffered());
920920

921-
const response = try request.receiveHead(options.buffer);
921+
var response = try request.receiveHead(options.buffer);
922922
if (response.head.status != .ok) return error.ProtocolError;
923923
it.reader = response.reader(options.buffer);
924924
}
@@ -1037,7 +1037,7 @@ pub const Session = struct {
10371037

10381038
try request.sendBodyComplete(body.buffered());
10391039

1040-
const response = try request.receiveHead(&.{});
1040+
var response = try request.receiveHead(&.{});
10411041
if (response.head.status != .ok) return error.ProtocolError;
10421042

10431043
const reader = response.reader(response_buffer);

0 commit comments

Comments
 (0)