mirror of
https://github.com/lightpanda-io/browser.git
synced 2026-03-21 20:24:42 +00:00
Add transfer-specific "performing" flag
In the previous commits, two separte crash resolution conspired to introduce 1 tick delay in request handling. When we're in a libcurl perform, we can't re-enter libcurl. So we added a check before processing new requests to make sure we weren't "performing" and, if we were, we'd queue the request (hence the 1 tick delay). But for another issue, we set the same "performing" check when manually triggering callbacks. This extended the situations where the above check fired thus causing the 1-tick delay to happen under more (and even common) situation. This commit improves this - instead of relying on the global "performing" check when processing 1 transfer explicitly, we now have a per-transfer performing check. This prevents the transfer from being deinitialized during a callback but does not block requests from being started immediately.
This commit is contained in:
@@ -496,6 +496,8 @@ fn waitForInterceptedResponse(self: *Client, transfer: *Transfer) !bool {
|
||||
// cases, the interecptor is expected to call resume to continue the transfer
|
||||
// or transfer.abort() to abort it.
|
||||
fn process(self: *Client, transfer: *Transfer) !void {
|
||||
// libcurl doesn't allow recursive calls, if we're in a `perform()` operation
|
||||
// then we _have_ to queue this.
|
||||
if (self.handles.performing == false) {
|
||||
if (self.handles.get()) |conn| {
|
||||
return self.makeRequest(conn, transfer);
|
||||
@@ -791,30 +793,30 @@ fn processMessages(self: *Client) !bool {
|
||||
if (msg.err) |err| {
|
||||
requestFailed(transfer, err, true);
|
||||
} else blk: {
|
||||
{
|
||||
self.handles.performing = true;
|
||||
defer self.handles.performing = false;
|
||||
// make sure the transfer can't be immediately aborted from a callback
|
||||
// since we still need it here.
|
||||
transfer._performing = true;
|
||||
defer transfer._performing = false;
|
||||
|
||||
if (!transfer._header_done_called) {
|
||||
// In case of request w/o data, we need to call the header done
|
||||
// callback now.
|
||||
if (!transfer._header_done_called) {
|
||||
const proceed = transfer.headerDoneCallback(&msg.conn) catch |err| {
|
||||
log.err(.http, "header_done_callback", .{ .err = err });
|
||||
requestFailed(transfer, err, true);
|
||||
continue;
|
||||
};
|
||||
if (!proceed) {
|
||||
requestFailed(transfer, error.Abort, true);
|
||||
break :blk;
|
||||
}
|
||||
}
|
||||
transfer.req.done_callback(transfer.ctx) catch |err| {
|
||||
// transfer isn't valid at this point, don't use it.
|
||||
log.err(.http, "done_callback", .{ .err = err });
|
||||
const proceed = transfer.headerDoneCallback(&msg.conn) catch |err| {
|
||||
log.err(.http, "header_done_callback", .{ .err = err });
|
||||
requestFailed(transfer, err, true);
|
||||
continue;
|
||||
};
|
||||
if (!proceed) {
|
||||
requestFailed(transfer, error.Abort, true);
|
||||
break :blk;
|
||||
}
|
||||
}
|
||||
transfer.req.done_callback(transfer.ctx) catch |err| {
|
||||
// transfer isn't valid at this point, don't use it.
|
||||
log.err(.http, "done_callback", .{ .err = err });
|
||||
requestFailed(transfer, err, true);
|
||||
continue;
|
||||
};
|
||||
|
||||
transfer.req.notification.dispatch(.http_request_done, &.{
|
||||
.transfer = transfer,
|
||||
@@ -944,6 +946,7 @@ pub const Transfer = struct {
|
||||
// number of times the transfer has been tried.
|
||||
// incremented by reset func.
|
||||
_tries: u8 = 0,
|
||||
_performing: bool = false,
|
||||
|
||||
// for when a Transfer is queued in the client.queue
|
||||
_node: std.DoublyLinkedList.Node = .{},
|
||||
@@ -1050,7 +1053,7 @@ pub const Transfer = struct {
|
||||
requestFailed(self, err, true);
|
||||
|
||||
const client = self.client;
|
||||
if (client.handles.performing) {
|
||||
if (self._performing or client.handles.performing) {
|
||||
// We're currently in a curl_multi_perform. We cannot call endTransfer
|
||||
// as that calls curl_multi_remove_handle, and you can't do that
|
||||
// from a curl callback. Instead, we flag this transfer and all of
|
||||
|
||||
Reference in New Issue
Block a user