/** 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);
}
Beispiel #6
0
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);
}