/** Process msg statefully using the leg. */ int nta_leg_stateful(nta_leg_t *leg, msg_t *msg) { su_msg_r su_msg = SU_MSG_RINITIALIZER; nta_agent_t *agent = leg->leg_agent; su_root_t *root = agent->sa_root; struct leg_recv_s *a; /* Create a su message that is passed to NTA network thread */ if (su_msg_create(su_msg, su_root_task(root), su_root_task(root), sm_leg_recv, /* Function to call */ sizeof(struct leg_recv_s)) == SU_FAILURE) return -1; agent->sa_stats->as_trless_to_tr++; a = su_msg_data(su_msg)->a_leg_recv; a->leg = leg; a->msg = msg; a->tport = tport_incref(tport_delivered_by(agent->sa_tports, msg)); return su_msg_send(su_msg); }
/** 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); }
void nw_changed_cb(SCDynamicStoreRef store, CFArrayRef changedKeys, void *info) { su_network_changed_t *snc = (su_network_changed_t *) info; su_network_changed_t *snc2; su_msg_r rmsg = SU_MSG_R_INIT; SU_DEBUG_7(("nw_changed_cb: entering.\n")); if (su_msg_create(rmsg, su_root_task(snc->su_root), su_root_task(snc->su_root), su_nw_changed_msg_recv, sizeof *snc) == SU_FAILURE) { return; } snc2 = su_msg_data(rmsg); assert(snc2); snc2->su_root = snc->su_root; snc2->su_home = snc->su_home; memcpy(snc2->su_storeRef, snc->su_storeRef, sizeof(SCDynamicStoreRef)); memcpy(snc2->su_sourceRef, snc->su_sourceRef, sizeof(CFRunLoopSourceRef)); snc2->su_os_thread = snc->su_os_thread; snc2->su_network_changed_cb = snc->su_network_changed_cb; snc2->su_network_changed_magic = snc->su_network_changed_magic; if (su_msg_send(rmsg) == SU_FAILURE) { su_msg_destroy(rmsg); return; } return; }
/** Pause a port. * * Obtain an exclusive lock on port's private data. * * @retval 0 if successful (and clone is paused) * @retval -1 upon an error */ int su_pthread_port_pause(su_port_t *self) { su_msg_r m = SU_MSG_R_INIT; _su_task_t task[1] = {{ self, NULL }}; if (su_msg_create(m, task, su_task_null, su_pthread_port_paused, 0) < 0) return -1; if (su_msg_send(m) < 0) return -1; if (pthread_mutex_lock(self->sup_runlock) < 0) return -1; return 0; }
/** Execute the @a function by a pthread @a task. * * @retval 0 if successful * @retval -1 upon an error * * @sa su_task_execute() * * @internal */ int su_pthread_port_execute(su_task_r const task, int (*function)(void *), void *arg, int *return_value) { int success; su_msg_r m = SU_MSG_R_INIT; #if HAVE_OPEN_C struct su_pthread_port_execute frame = { { PTHREAD_MUTEX_INITIALIZER }, { _ENeedsNormalInit, NULL }, NULL, NULL, 0 }; frame.function = function; frame.arg = arg; #else struct su_pthread_port_execute frame = { { PTHREAD_MUTEX_INITIALIZER }, { PTHREAD_COND_INITIALIZER }, function, arg, 0 }; #endif if (su_msg_create(m, task, su_task_null, _su_pthread_port_execute, (sizeof &frame)) < 0) return -1; *(struct su_pthread_port_execute **)su_msg_data(m) = &frame; pthread_mutex_lock(frame.mutex); success = su_msg_send(m); if (success == 0) while (frame.function) pthread_cond_wait(frame.cond, frame.mutex); else su_msg_destroy(m); pthread_mutex_unlock(frame.mutex); pthread_mutex_destroy(frame.mutex); pthread_cond_destroy(frame.cond); if (return_value) *return_value = frame.value; return success; }
static void delayed_auth_method(auth_mod_t *am, auth_status_t *as, msg_auth_t *auth, auth_challenger_t const *ach) { auth_plugin_t *ap = AUTH_PLUGIN(am); su_msg_r mamc = SU_MSG_R_INIT; auth_splugin_t *asp; if (su_msg_create(mamc, su_root_task(ap->ap_root), su_root_task(ap->ap_root), delayed_auth_method_recv, sizeof *asp) == SU_FAILURE) { as->as_status = 500; as->as_phrase = "Asynchronous authentication failure"; return; } asp = su_msg_data(mamc); assert(asp); asp->asp_cookie = delayed_asp_cookie; asp->asp_am = am; asp->asp_as = as; asp->asp_header = auth; asp->asp_ach = ach; asp->asp_canceled = 0; if (su_msg_send(mamc) == SU_FAILURE) { su_msg_destroy(mamc); as->as_status = 500; as->as_phrase = "Asynchronous authentication failure"; return; } as->as_plugin = asp; as->as_status = 100; as->as_phrase = "Trying"; return; }
/** Send a delivery report. * * If the sender has attached a delivery report function to message with * su_msg_report(), the message is returned to the message queue of the * sending task. The sending task calls the delivery report function when it * has received the message. */ void su_msg_delivery_report(su_msg_r rmsg) { su_task_r swap; if (!rmsg || !rmsg[0]) return; if (!rmsg[0]->sum_report) { su_msg_destroy(rmsg); return; } *swap = *rmsg[0]->sum_from; *rmsg[0]->sum_from = *rmsg[0]->sum_to; *rmsg[0]->sum_to = *swap; rmsg[0]->sum_func = rmsg[0]->sum_report; rmsg[0]->sum_report = NULL; su_msg_send(rmsg); }
static RETSIGTYPE intr_handler(int signum) { su_msg_send(intr_msg); }