fix: remove blocking project manager call on startup

closes #214

The blocking call get_mru_postion to the project mananger may cause
a deadlock if the project manager has not started running yet.
This commit is contained in:
CJ van den Berg 2025-03-25 15:04:23 +01:00
parent 739b2a776f
commit fc3224137d
Signed by: neurocyte
GPG key ID: 8EB1E1BB660E3FB9
3 changed files with 114 additions and 12 deletions

65
src/completion.zig Normal file
View file

@ -0,0 +1,65 @@
const std = @import("std");
const tp = @import("thespian");
const OutOfMemoryError = error{OutOfMemory};
const SpawnError = error{ThespianSpawnFailed};
pub fn send(
allocator: std.mem.Allocator,
to: tp.pid_ref,
m: anytype,
ctx: anytype,
) (OutOfMemoryError || SpawnError)!void {
return RequestContext(@TypeOf(ctx)).send(allocator, to, ctx, tp.message.fmt(m));
}
fn RequestContext(T: type) type {
return struct {
receiver: ReceiverT,
ctx: T,
to: tp.pid,
request: tp.message,
response: ?tp.message,
a: std.mem.Allocator,
const Self = @This();
const ReceiverT = tp.Receiver(*@This());
fn send(a: std.mem.Allocator, to: tp.pid_ref, ctx: T, request: tp.message) (OutOfMemoryError || SpawnError)!void {
const self = try a.create(@This());
self.* = .{
.receiver = undefined,
.ctx = if (@hasDecl(T, "clone")) ctx.clone() else ctx,
.to = to.clone(),
.request = try request.clone(std.heap.c_allocator),
.response = null,
.a = a,
};
self.receiver = ReceiverT.init(receive_, self);
const proc = try tp.spawn_link(a, self, start, @typeName(@This()));
defer proc.deinit();
}
fn deinit(self: *@This()) void {
if (@hasDecl(T, "deinit")) self.ctx.deinit();
std.heap.c_allocator.free(self.request.buf);
self.to.deinit();
self.a.destroy(self);
}
fn start(self: *@This()) tp.result {
_ = tp.set_trap(true);
if (@hasDecl(T, "link")) try self.ctx.link();
errdefer self.deinit();
try self.to.link();
try self.to.send_raw(self.request);
tp.receive(&self.receiver);
}
fn receive_(self: *@This(), _: tp.pid_ref, m: tp.message) tp.result {
defer self.deinit();
self.ctx.receive(m) catch |e| return tp.exit_error(e, @errorReturnTrace());
return tp.exit_normal();
}
};
}