/** Wait for the pthread clone to exit. * @internal * * Called by su_port_wait() and su_clone_wait(). */ void su_pthread_port_wait(su_clone_r rclone) { su_port_t *clone, *parent; struct su_pthread_port_waiting_parent mom[1]; pthread_t tid; assert(*rclone); clone = su_msg_to(rclone)->sut_port; parent = su_msg_from(rclone)->sut_port; if (clone == parent) { su_base_port_wait(rclone); return; } assert(parent); assert(clone); assert(rclone[0]->sum_func == su_pthread_port_clone_break); #if 0 assert(!clone->sup_paused); #endif tid = clone->sup_tid; if (!clone->sup_thread) { /* Already died */ su_msg_destroy(rclone); pthread_join(tid, NULL); return; } pthread_mutex_init(mom->deinit, NULL); pthread_mutex_lock(mom->deinit); pthread_cond_init(mom->cv, NULL); pthread_mutex_init(mom->mutex, NULL); pthread_mutex_lock(mom->mutex); mom->waiting = 1; clone->sup_waiting_parent = mom; su_msg_send(rclone); while (mom->waiting) pthread_cond_wait(mom->cv, mom->mutex); /* Run all messages from clone */ while (su_port_getmsgs_from(parent, clone)) ; /* Allow clone thread to exit */ pthread_mutex_unlock(mom->deinit); pthread_join(tid, NULL); pthread_mutex_destroy(mom->deinit); pthread_mutex_unlock(mom->mutex); pthread_mutex_destroy(mom->mutex); pthread_cond_destroy(mom->cv); }
/**Wait for the clone to exit. * @internal * * Called by su_port_wait() and su_clone_wait() */ void su_base_port_wait(su_clone_r rclone) { su_port_t *self; su_root_t *root_to_wait; assert(*rclone); self = su_msg_from(rclone)->sut_port; assert(self == su_msg_to(rclone)->sut_port); root_to_wait = su_msg_to(rclone)->sut_root; assert(rclone[0]->sum_func == su_base_port_clone_break); while (su_base_port_getmsgs_of_root(self, root_to_wait)) ; su_root_destroy(root_to_wait); su_msg_destroy(rclone); }
/** Pause the pthread port. * * This is a message function invoked by su_pthread_port_pause() and called * from the message dispatcher. It releases the lock sup_runlock and waits * until the condition variable sup_resume is signaled and sup_paused is * cleared by su_pthread_port_resume(). */ static void su_pthread_port_paused(su_root_magic_t *magic, su_msg_r msg, su_msg_arg_t *arg) { su_port_t *self = su_msg_to(msg)->sut_port; self->sup_paused = 1; while (self->sup_paused) pthread_cond_wait(self->sup_resume, self->sup_runlock); }
/** "Stop" message function for pthread clone. * * @sa su_clone_wait() * @internal */ static void su_pthread_port_clone_break(su_root_magic_t *m, su_msg_r msg, su_msg_arg_t *a) { su_root_t *root = su_msg_to(msg)->sut_root; root->sur_deiniting = 1; su_root_break(root); }
static void su_base_port_clone_break(su_root_magic_t *m, su_msg_r msg, su_msg_arg_t *arg) { _su_task_t const *task = su_msg_to(msg); while (su_base_port_getmsgs_of_root(task->sut_port, task->sut_root)) ; su_root_destroy(task->sut_root); }
int su_msg_reply(su_msg_r reply, su_msg_cr rmsg, su_msg_f wakeup, isize_t size) { su_msg_r rmsg0; assert(rmsg != reply); *rmsg0 = *(su_msg_t **) rmsg; *reply = NULL; return su_msg_create(reply, su_msg_from(rmsg0), su_msg_to(rmsg0), wakeup, size); }