aboutsummaryrefslogtreecommitdiff
path: root/src/uapi/ipc.c
diff options
context:
space:
mode:
authorKimplul <kimi.h.kuparinen@gmail.com>2024-07-04 22:52:47 +0300
committerKimplul <kimi.h.kuparinen@gmail.com>2024-07-04 22:52:47 +0300
commitfdbc5adf83741d7e3af0c3f0ffdb59bdf42493b6 (patch)
tree2eb538b9ecc2898d1f94305fe56d0625060834de /src/uapi/ipc.c
parentb82479a69cd6110c9099031e133fda62f8e11222 (diff)
downloadkmi-fdbc5adf83741d7e3af0c3f0ffdb59bdf42493b6.tar.gz
kmi-fdbc5adf83741d7e3af0c3f0ffdb59bdf42493b6.zip
generalize orphants
+ Allow threads to make themselves become orphants
Diffstat (limited to 'src/uapi/ipc.c')
-rw-r--r--src/uapi/ipc.c19
1 files changed, 11 insertions, 8 deletions
diff --git a/src/uapi/ipc.c b/src/uapi/ipc.c
index f3896f5..bc49dbb 100644
--- a/src/uapi/ipc.c
+++ b/src/uapi/ipc.c
@@ -83,7 +83,7 @@ static vm_t enter_rpc(struct tcb *t, struct sys_ret a,
{
/* reuse current rpc stack location if we're being kicked */
vm_t rpc_stack = (kind == IPC_KICK &&
- is_rpc(t)) ? t->rpc_stack :rpc_position(t);
+ is_rpc(t)) ? t->rpc_stack : rpc_position(t);
struct call_ctx *ctx = (struct call_ctx *)(rpc_stack) - 1;
ctx->regs = t->regs;
@@ -179,8 +179,8 @@ void notify(struct tcb *t, enum notify_flag flag)
return;
struct tcb *r = get_tcb(t->notify_id);
- if (!r || !r->callback) {
- error("notify callback dead\n");
+ if (!r || r->state || !r->callback) {
+ error("notify callback unavailable\n");
t->notify_flags = 0;
return;
}
@@ -218,31 +218,34 @@ static void leave_rpc(struct tcb *t, struct sys_ret a)
{
vm_t rpc_stack = t->rpc_stack + BASE_PAGE_SIZE;
struct call_ctx *ctx = (struct call_ctx *)(rpc_stack) - 1;
- vm_t top = ctx->rpc_stack;
t->regs = ctx->regs;
/* again, get rid of args as fast as possible */
set_args(t, 6, a);
struct tcb *r = get_tcb(ctx->pid);
- while (!r || r->dead) {
+ while (!r || !is_proc(r) || zombie(r)) {
/* we unwound back to our root process which is apparently dead,
* we're orphaned :( */
- if (ctx->pid == t->rid) {
+ if (rpc_stack_empty(ctx->rpc_stack)) {
orphanize(t);
- return;
+ break;
}
rpc_stack = ctx->rpc_stack + BASE_PAGE_SIZE;
ctx = (struct call_ctx *)(rpc_stack) - 1;
r = get_tcb(ctx->pid);
+ set_args1(t, ERR_NF);
}
+ if (orphan(t) && !is_rpc(t))
+ unorphanize(t);
+
set_return(t, ctx->exec);
/* if we're returning from a failed rpc, this should essentially be a
* no-op */
- mark_rpc_valid(t, top);
+ mark_rpc_valid(t, ctx->rpc_stack);
t->rpc_stack = ctx->rpc_stack;
t->pid = ctx->pid;
t->eid = ctx->eid;