diff options
author | 2022-03-16 05:04:23 -0700 | |
---|---|---|
committer | 2022-03-16 05:04:23 -0700 | |
commit | 3b78cfe71ad4ce7732266a8b5db5bd0f5fda992e (patch) | |
tree | b118db2b622ae989ae06bbed27958c45c2c03897 /src | |
parent | 422bdf692a94e808bd96e9d429ba79becb5b2676 (diff) | |
download | bun-3b78cfe71ad4ce7732266a8b5db5bd0f5fda992e.tar.gz bun-3b78cfe71ad4ce7732266a8b5db5bd0f5fda992e.tar.zst bun-3b78cfe71ad4ce7732266a8b5db5bd0f5fda992e.zip |
Add a way to run serial tasks on a different thread
Diffstat (limited to 'src')
-rw-r--r-- | src/javascript/jsc/javascript.zig | 68 |
1 files changed, 65 insertions, 3 deletions
diff --git a/src/javascript/jsc/javascript.zig b/src/javascript/jsc/javascript.zig index 8757f653d..9e9a8c9f8 100644 --- a/src/javascript/jsc/javascript.zig +++ b/src/javascript/jsc/javascript.zig @@ -1529,12 +1529,13 @@ const bun_file_import_path = "/node_modules.server.bun"; const FetchTasklet = Fetch.FetchTasklet; const TaggedPointerUnion = @import("../../tagged_pointer.zig").TaggedPointerUnion; -const WorkPool = @import("../../work_pool.zig"); +const WorkPool = @import("../../work_pool.zig").WorkPool; +const WorkPoolTask = @import("../../work_pool.zig").Task; pub fn ConcurrentPromiseTask(comptime Context: type) type { return struct { const This = @This(); ctx: *Context, - task: WorkPool.Task = .{ .callback = runFromThreadPool }, + task: WorkPoolTask = .{ .callback = runFromThreadPool }, event_loop: *VirtualMachine.EventLoop, allocator: std.mem.Allocator, promise: JSValue, @@ -1554,7 +1555,7 @@ pub fn ConcurrentPromiseTask(comptime Context: type) type { return this; } - pub fn runFromThreadPool(task: *WorkPool.Task) void { + pub fn runFromThreadPool(task: *WorkPoolTask) void { var this = @fieldParentPtr(This, "task", task); Context.run(this.ctx); this.onFinish(); @@ -1589,6 +1590,67 @@ pub fn ConcurrentPromiseTask(comptime Context: type) type { }; } +pub fn SerialPromiseTask(comptime Context: type) type { + return struct { + const SerialWorkPool = @import("../../work_pool.zig").NewWorkPool(1); + const This = @This(); + + ctx: *Context, + task: WorkPoolTask = .{ .callback = runFromThreadPool }, + event_loop: *VirtualMachine.EventLoop, + allocator: std.mem.Allocator, + promise: JSValue, + globalThis: *JSGlobalObject, + + pub fn createOnJSThread(allocator: std.mem.Allocator, globalThis: *JSGlobalObject, value: *Context) !*This { + var this = try allocator.create(This); + this.* = .{ + .event_loop = VirtualMachine.vm.event_loop, + .ctx = value, + .allocator = allocator, + .promise = JSValue.createInternalPromise(globalThis), + .globalThis = globalThis, + }; + js.JSValueProtect(globalThis.ref(), this.promise.asObjectRef()); + VirtualMachine.vm.active_tasks +|= 1; + return this; + } + + pub fn runFromThreadPool(task: *WorkPoolTask) void { + var this = @fieldParentPtr(This, "task", task); + Context.run(this.ctx); + this.onFinish(); + } + + pub fn runFromJS(this: This) void { + var promise_value = this.promise; + var promise = promise_value.asInternalPromise() orelse { + if (comptime @hasDecl(Context, "deinit")) { + @call(.{}, Context.deinit, .{this.ctx}); + } + return; + }; + + var ctx = this.ctx; + + js.JSValueUnprotect(this.globalThis.ref(), promise_value.asObjectRef()); + ctx.then(promise, this.globalThis); + } + + pub fn schedule(this: *This) void { + SerialWorkPool.schedule(&this.task); + } + + pub fn onFinish(this: *This) void { + this.event_loop.enqueueTaskConcurrent(Task.init(this)); + } + + pub fn deinit(this: *This) void { + this.allocator.destroy(this); + } + }; +} + pub fn IOTask(comptime Context: type) type { return struct { const This = @This(); |