Skip to content

Commit 04dfe2a

Browse files
committed
move build-on-save out of the Job queue
We can directly access the thread pool instead.
1 parent 9f5efdd commit 04dfe2a

File tree

1 file changed

+33
-45
lines changed

1 file changed

+33
-45
lines changed

src/Server.zig

Lines changed: 33 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -162,13 +162,11 @@ pub const Status = enum {
162162
const Job = union(enum) {
163163
incoming_message: std.json.Parsed(Message),
164164
generate_diagnostics: DocumentStore.Uri,
165-
run_build_on_save,
166165

167166
fn deinit(self: Job, allocator: std.mem.Allocator) void {
168167
switch (self) {
169168
.incoming_message => |parsed_message| parsed_message.deinit(),
170169
.generate_diagnostics => |uri| allocator.free(uri),
171-
.run_build_on_save => {},
172170
}
173171
}
174172

@@ -179,15 +177,12 @@ const Job = union(enum) {
179177
/// this `Job` requires shared access to `Server` and `DocumentStore`
180178
/// other non exclusive jobs can be processed in parallel
181179
shared,
182-
/// this `Job` operates atomically and does not require any synchronisation
183-
atomic,
184180
};
185181

186182
fn syncMode(self: Job) SynchronizationMode {
187183
return switch (self) {
188184
.incoming_message => |parsed_message| if (isBlockingMessage(parsed_message.value)) .exclusive else .shared,
189185
.generate_diagnostics => .shared,
190-
.run_build_on_save => .atomic,
191186
};
192187
}
193188
};
@@ -943,7 +938,7 @@ pub fn updateConfiguration(
943938
server.config.enable_build_on_save != false and
944939
server.client_capabilities.supports_publish_diagnostics)
945940
{
946-
try server.pushJob(.run_build_on_save);
941+
try server.thread_pool.spawn(runBuildOnSave, .{server});
947942
}
948943
}
949944

@@ -1352,7 +1347,7 @@ fn saveDocumentHandler(server: *Server, arena: std.mem.Allocator, notification:
13521347
server.config.enable_build_on_save != false and
13531348
server.client_capabilities.supports_publish_diagnostics)
13541349
{
1355-
try server.pushJob(.run_build_on_save);
1350+
try server.thread_pool.spawn(runBuildOnSave, .{server});
13561351
}
13571352

13581353
if (server.getAutofixMode() == .on_save) {
@@ -1652,6 +1647,33 @@ fn selectionRangeHandler(server: *Server, arena: std.mem.Allocator, request: typ
16521647
return try selection_range.generateSelectionRanges(arena, handle, request.positions, server.offset_encoding);
16531648
}
16541649

1650+
fn runBuildOnSave(server: *Server) void {
1651+
comptime std.debug.assert(std.process.can_spawn);
1652+
1653+
// TODO data-race on server.workspaces
1654+
for (server.workspaces.items) |*workspace| {
1655+
const was_build_on_save_running = workspace.is_build_on_save_running.swap(true, .acq_rel);
1656+
if (was_build_on_save_running) continue;
1657+
defer workspace.is_build_on_save_running.store(false, .release);
1658+
1659+
var arena_allocator = std.heap.ArenaAllocator.init(server.allocator);
1660+
defer arena_allocator.deinit();
1661+
var diagnostic_set = std.StringArrayHashMapUnmanaged(std.ArrayListUnmanaged(types.Diagnostic)){};
1662+
diagnostics_gen.generateBuildOnSaveDiagnostics(server, workspace.uri, arena_allocator.allocator(), &diagnostic_set) catch |err| {
1663+
log.err("failed to run build on save on {s}: {}", .{ workspace.uri, err });
1664+
return;
1665+
};
1666+
1667+
for (diagnostic_set.keys(), diagnostic_set.values()) |document_uri, diagnostics| {
1668+
const json_message = server.sendToClientNotification("textDocument/publishDiagnostics", .{
1669+
.uri = document_uri,
1670+
.diagnostics = diagnostics.items,
1671+
}) catch return;
1672+
server.allocator.free(json_message);
1673+
}
1674+
}
1675+
}
1676+
16551677
const HandledRequestParams = union(enum) {
16561678
initialize: types.InitializeParams,
16571679
shutdown,
@@ -1816,23 +1838,17 @@ pub fn loop(server: *Server) !void {
18161838

18171839
while (server.job_queue.readItem()) |job| {
18181840
if (zig_builtin.single_threaded) {
1819-
server.processJob(job, null);
1841+
server.processJob(job);
18201842
continue;
18211843
}
18221844

18231845
switch (job.syncMode()) {
18241846
.exclusive => {
18251847
server.waitAndWork();
1826-
server.processJob(job, null);
1848+
server.processJob(job);
18271849
},
18281850
.shared => {
1829-
server.wait_group.start();
1830-
errdefer job.deinit(server.allocator);
1831-
try server.thread_pool.spawn(processJob, .{ server, job, &server.wait_group });
1832-
},
1833-
.atomic => {
1834-
errdefer job.deinit(server.allocator);
1835-
try server.thread_pool.spawn(processJob, .{ server, job, null });
1851+
server.thread_pool.spawnWg(&server.wait_group, processJob, .{ server, job });
18361852
},
18371853
}
18381854
}
@@ -1990,12 +2006,10 @@ fn processMessageReportError(server: *Server, message: Message) ?[]const u8 {
19902006
};
19912007
}
19922008

1993-
fn processJob(server: *Server, job: Job, wait_group: ?*std.Thread.WaitGroup) void {
2009+
fn processJob(server: *Server, job: Job) void {
19942010
const tracy_zone = tracy.trace(@src());
19952011
defer tracy_zone.end();
19962012
tracy_zone.setName(@tagName(job));
1997-
defer if (!zig_builtin.single_threaded and wait_group != null) wait_group.?.finish();
1998-
19992013
defer job.deinit(server.allocator);
20002014

20012015
switch (job) {
@@ -2011,32 +2025,6 @@ fn processJob(server: *Server, job: Job, wait_group: ?*std.Thread.WaitGroup) voi
20112025
const json_message = server.sendToClientNotification("textDocument/publishDiagnostics", diagnostics) catch return;
20122026
server.allocator.free(json_message);
20132027
},
2014-
.run_build_on_save => {
2015-
if (!std.process.can_spawn) unreachable;
2016-
2017-
// TODO data-race on server.workspaces
2018-
for (server.workspaces.items) |*workspace| {
2019-
const was_build_on_save_running = workspace.is_build_on_save_running.swap(true, .acq_rel);
2020-
if (was_build_on_save_running) continue;
2021-
defer workspace.is_build_on_save_running.store(false, .release);
2022-
2023-
var arena_allocator = std.heap.ArenaAllocator.init(server.allocator);
2024-
defer arena_allocator.deinit();
2025-
var diagnostic_set = std.StringArrayHashMapUnmanaged(std.ArrayListUnmanaged(types.Diagnostic)){};
2026-
diagnostics_gen.generateBuildOnSaveDiagnostics(server, workspace.uri, arena_allocator.allocator(), &diagnostic_set) catch |err| {
2027-
log.err("failed to run build on save on {s}: {}", .{ workspace.uri, err });
2028-
return;
2029-
};
2030-
2031-
for (diagnostic_set.keys(), diagnostic_set.values()) |document_uri, diagnostics| {
2032-
const json_message = server.sendToClientNotification("textDocument/publishDiagnostics", .{
2033-
.uri = document_uri,
2034-
.diagnostics = diagnostics.items,
2035-
}) catch return;
2036-
server.allocator.free(json_message);
2037-
}
2038-
}
2039-
},
20402028
}
20412029
}
20422030

0 commit comments

Comments
 (0)