feat: add unlinked-spawn to the C and Zig APIs
This commit is contained in:
parent
87c4a6f32c
commit
e90009074a
3 changed files with 51 additions and 0 deletions
|
|
@ -28,6 +28,9 @@ thespian_handle thespian_self();
|
||||||
int thespian_spawn_link(thespian_behaviour, thespian_behaviour_state,
|
int thespian_spawn_link(thespian_behaviour, thespian_behaviour_state,
|
||||||
const char *name, thespian_env, thespian_handle *);
|
const char *name, thespian_env, thespian_handle *);
|
||||||
|
|
||||||
|
int thespian_spawn(thespian_behaviour, thespian_behaviour_state,
|
||||||
|
const char *name, thespian_env, thespian_handle *);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -96,4 +96,30 @@ auto thespian_spawn_link(thespian_behaviour b, thespian_behaviour_state s,
|
||||||
new thespian::handle{ret.value()});
|
new thespian::handle{ret.value()});
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto thespian_spawn(thespian_behaviour b, thespian_behaviour_state s,
|
||||||
|
const char *name, thespian_env env, thespian_handle *handle)
|
||||||
|
-> int {
|
||||||
|
const thespian::env_t empty_env_{};
|
||||||
|
thespian::env_t env_ =
|
||||||
|
env ? *reinterpret_cast<thespian::env_t *>(env) : empty_env_; // NOLINT
|
||||||
|
|
||||||
|
auto ret = spawn(
|
||||||
|
[b, s]() -> thespian::result {
|
||||||
|
auto *ret = b(s);
|
||||||
|
if (ret) {
|
||||||
|
auto err = cbor::buffer();
|
||||||
|
const uint8_t *data = ret->base; // NOLINT
|
||||||
|
std::copy(data, data + ret->len, back_inserter(err)); // NOLINT
|
||||||
|
return thespian::to_error(err);
|
||||||
|
}
|
||||||
|
return thespian::ok();
|
||||||
|
},
|
||||||
|
string_view(name), std::move(env_));
|
||||||
|
if (!ret)
|
||||||
|
return -1;
|
||||||
|
*handle = reinterpret_cast<thespian_handle>( // NOLINT
|
||||||
|
new thespian::handle{ret.value()});
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -584,6 +584,28 @@ pub fn spawn_link(
|
||||||
return spawn_link_env(a, data, f, name, env.get());
|
return spawn_link_env(a, data, f, name, env.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Spawn a new actor WITHOUT creating a link to the calling actor.
|
||||||
|
/// The new actor runs independently; its exit does not propagate to the
|
||||||
|
/// caller. Think twice before you use this form of spawn. It's rarely want
|
||||||
|
/// you want to do.
|
||||||
|
pub fn spawn(
|
||||||
|
a: std.mem.Allocator,
|
||||||
|
data: anytype,
|
||||||
|
f: Behaviour(@TypeOf(data)).FunT,
|
||||||
|
name: [:0]const u8,
|
||||||
|
) error{ OutOfMemory, ThespianSpawnFailed }!pid {
|
||||||
|
const Tclosure = Behaviour(@TypeOf(data));
|
||||||
|
var handle_: c.thespian_handle = null;
|
||||||
|
try neg_to_error(c.thespian_spawn(
|
||||||
|
Tclosure.run,
|
||||||
|
try Tclosure.create(a, f, data),
|
||||||
|
name,
|
||||||
|
env.get().env,
|
||||||
|
&handle_,
|
||||||
|
), error.ThespianSpawnFailed);
|
||||||
|
return wrap_pid(handle_);
|
||||||
|
}
|
||||||
|
|
||||||
pub fn spawn_link_env(
|
pub fn spawn_link_env(
|
||||||
a: std.mem.Allocator,
|
a: std.mem.Allocator,
|
||||||
data: anytype,
|
data: anytype,
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue