Exemplo n.º 1
0
int su_base_port_start_shared(su_root_t *parent,
			      su_clone_r return_clone,
			      su_root_magic_t *magic,
			      su_root_init_f init,
			      su_root_deinit_f deinit)
{
  su_port_t *self = parent->sur_task->sut_port;
  su_root_t *child;

  child = su_salloc(su_port_home(self), sizeof *child);
  if (!child)
    return -1;

  child->sur_magic = magic;
  child->sur_deinit = deinit;
  child->sur_threading = parent->sur_threading;

  SU_TASK_COPY(child->sur_parent, su_root_task(parent),
	       su_base_port_clone_start);
  SU_TASK_COPY(child->sur_task, child->sur_parent,
	       su_base_port_clone_start);

  child->sur_task->sut_root = child;

  if (su_msg_create(return_clone,
		    child->sur_task, su_root_task(parent),
		    su_base_port_clone_break,
		    0) == 0 &&
      init(child, magic) == 0)
    return 0;

  su_msg_destroy(return_clone);
  su_root_destroy(child);
  return -1;
}
Exemplo n.º 2
0
/**
 * Allocates a message of given size.
 *
 * The function @c su_msg_create() allocates a message with given data size.
 * If successful, it moves the new message handle to the @c rmsg.
 *
 * @param  rmsg   handle to the new message (may be uninitialized prior calling)
 * @param  to     the recipient task
 * @param  from   the sender task
 * @param  wakeup function that is called when message is delivered
 * @param  size   size of the message data
 *
 * @retval  0 if successful,
 * @retval -1 if message allocation fails.
 */
int su_msg_create(su_msg_r        rmsg,
                  su_task_r const to,
                  su_task_r const from,
                  su_msg_f        wakeup,
                  isize_t         size)
{
    if (su_msg_new(rmsg, (size_t) size) == 0) {
        SU_TASK_COPY(rmsg[0]->sum_to, to, su_msg_create);
        SU_TASK_COPY(rmsg[0]->sum_from, from, su_msg_create);
        rmsg[0]->sum_func = wakeup;
        return 0;
    }

    return -1;
}
Exemplo n.º 3
0
/** Main function for clone thread.
 *
 * @internal
 */
static void *su_pthread_port_clone_main(void *varg)
{
  struct clone_args *arg = (struct clone_args *)varg;
  su_task_r task;
  int zap = 1;

#if SU_HAVE_WINSOCK
  su_init();
#endif

  task->sut_port = arg->create();

  if (task->sut_port) {
    task->sut_root = su_salloc(su_port_home(task->sut_port),
			       sizeof *task->sut_root);
    if (task->sut_root) {

      task->sut_root->sur_threading = 1;	/* By default */

      SU_TASK_COPY(task->sut_root->sur_parent, su_root_task(arg->parent),
		   su_pthread_port_clone_main);
      SU_TASK_COPY(task->sut_root->sur_task, task,
		   su_pthread_port_clone_main);

      if (su_msg_create(arg->clone,
			task,
			su_root_task(arg->parent),
			su_pthread_port_clone_break,
			0) == 0) {
	task->sut_root->sur_magic = arg->magic;
	task->sut_root->sur_deinit = arg->deinit;

	su_root_set_max_defer(task->sut_root, 
			      su_root_get_max_defer(arg->parent));

	if (arg->init(task->sut_root, arg->magic) == 0) {
	  su_pthread_port_return_to_parent(arg, 0), arg = NULL;

	  su_root_run(task->sut_root); /* Do the work */

	  /* Cleanup */
	  if (task->sut_port->sup_waiting_parent) {
	    struct su_pthread_port_waiting_parent *mom;

	    mom = task->sut_port->sup_waiting_parent;
	    pthread_mutex_lock(mom->mutex);
	    mom->waiting = 0;
	    pthread_cond_signal(mom->cv);
	    pthread_mutex_unlock(mom->mutex);

	    pthread_mutex_lock(mom->deinit);
	    su_port_getmsgs(task->sut_port);
	    pthread_mutex_unlock(mom->deinit);
	  }
	  else
	    zap = 0;
	}
	else
	  su_msg_destroy(arg->clone);

	su_root_destroy(task->sut_root);
      }
    }

    task->sut_port->sup_base->sup_vtable->
      su_port_decref(task->sut_port, zap,
		     "su_pthread_port_clone_main");
  }

#if SU_HAVE_WINSOCK
  su_deinit();
#endif

  if (arg)
    su_pthread_port_return_to_parent(arg, -1);

  return NULL;			/* Exit from thread */
}