void* worker(void *arg) { ctx_t *ctx; task_t *task; ERL_NIF_TERM result; ctx = static_cast<ctx_t*>(arg); while (true) { task = static_cast<task_t*>(async_queue_pop(ctx->queue)); if (task->type == COMPRESS) { result = compress(task); } else if (task->type == DECOMPRESS) { result = decompress(task); } else if (task->type == SHUTDOWN) { break; } else { errx(1, "Unexpected task type: %i", task->type); } enif_send(NULL, &task->pid, task->env, result); cleanup_task(&task); } cleanup_task(&task); return NULL; }
task_t* init_task(task_type_t type, ERL_NIF_TERM ref, ErlNifPid pid, ERL_NIF_TERM orig_term) { ERL_NIF_TERM term; task_t *task; task = init_empty_task(type); task->pid = pid; task->env = enif_alloc_env(); if (task->env == NULL) { cleanup_task(&task); goto done; } term = enif_make_copy(task->env, orig_term); if (!enif_inspect_binary(task->env, term, &task->data)) { cleanup_task(&task); goto done; } task->ref = enif_make_copy(task->env, ref); done: return task; }
uint64_t syscall_kill(int32_t option, int32_t pid) { if (pid == 0 || pid == 1) { printf("-sbush: kill(%d): Not allowed\n", pid); return -1; } struct process_queue *iter = pqueue; struct process_queue *item = NULL; while (iter) { if (iter->proc.pid == pid) { item = iter; break; } iter = iter->next; } if (item) { remove_from_queue(&pqueue, item); resume_wait_proc(item->proc.pid); if (curr_task->proc.parent_fg == &item->proc) { curr_task->proc.parent_fg = item->proc.parent_fg; } cleanup_task(item); return 0; } iter = wqueue; while (iter) { if (iter->proc.pid == pid) { item = iter; break; } iter = iter->next; } if (item) { remove_from_queue(&wqueue, item); resume_wait_proc(item->proc.pid); if (curr_task->proc.parent_fg == &item->proc) { curr_task->proc.parent_fg = item->proc.parent_fg; } cleanup_task(item); return 0; } printf("-sbush: kill(%d): No such process\n", pid); return 0; }