示例#1
0
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;
}
示例#2
0
/** 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);
}
示例#3
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;
}
示例#4
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);
}
/** 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;
}
/** 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 */
}
/*
 * test su_timer functionality:
 *
 * Create a timer, executing print_stamp() in every 20 ms
 */
int main(int argc, char *argv[])
{
  su_root_t *root;
  su_timer_t *t, *t1, *t_end;
  su_timer_t **timers;
  su_duration_t interval = 60;
  char *argv0 = argv[0];
  char *s;
  int use_t1 = 0;
  su_time_t now, started;
  intptr_t i, N = 500;
  GSource *source;

  struct timing timing[1] = {{ 0 }};
  struct tester tester[1] = {{ 0 }};

  while (argv[1] && argv[1][0] == '-') {
    char *o = argv[1] + 1;
    while (*o) {
      if (*o == '1')
	o++, use_t1 = 1;
      else if (*o == 'r')
	o++, timing->t_run = 1;
      else if (*o == 'N') {
	if (o[1])
	  N = strtoul(o + 1, &o, 0);
	else if (argv[2])
	  N = strtoul(argv++[2], &o, 0);
	break;
      }
      else
	break;

    }
    if (*o)
      usage(argv0);
    argv++;
  }

  if (argv[1]) {
    interval = strtoul(argv[1], &s, 10);

    if (interval == 0 || s == argv[1])
      usage(argv0);
  }

  su_init(); atexit(su_deinit);

  tester->root = root = su_glib_root_create(tester);

  source = su_root_gsource(tester->root);
  g_source_attach(source, NULL /*g_main_context_default ()*/);

  su_msg_create(intr_msg,
		su_root_task(root),
		su_root_task(root),
		test_break, 0);

  signal(SIGINT, intr_handler);
#if HAVE_SIGPIPE
  signal(SIGPIPE, intr_handler);
  signal(SIGQUIT, intr_handler);
  signal(SIGHUP, intr_handler);
#endif

  t = su_timer_create(su_root_task(root), interval);
  t1 = su_timer_create(su_root_task(root), 1);
  t_end = su_timer_create(su_root_task(root), 20 * interval);

  if (t == NULL || t1 == NULL || t_end == NULL)
    su_perror("su_timer_create"), exit(1);

  tester->t = t, tester->t1 = t1;

  timing->t_prev = su_now();

  if (timing->t_run)
    su_timer_run(t, print_stamp, timing);
  else
    su_timer_set(t, print_stamp, timing);

  if (use_t1)
    su_timer_set(t1, print_X, NULL);

  su_timer_set(t_end, end_test, NULL);

  su_root_run(root);

  su_msg_destroy(intr_msg);

  su_timer_destroy(t);
  su_timer_destroy(t1);

  if (timing->t_times != 10) {
    fprintf(stderr, "%s: t expired %d times (expecting 10)\n",
	    argv0, timing->t_times);
    return 1;
  }

  /* Insert timers in order */
  timers = calloc(N, sizeof *timers);
  if (!timers) { perror("calloc"); exit(1); }

  now = started = su_now();

  for (i = 0; i < N; i++) {
    t = su_timer_create(su_root_task(root), 1000);
    if (!t) { perror("su_timer_create"); exit(1); }
    if (++now.tv_usec == 0) ++now.tv_sec;
    su_timer_set_at(t, increment, (void *)i, now);
    timers[i] = t;
  }

  tester->sentinel = (void*)(i - 1);

  su_root_run(root);

  printf("Processing %u timers took %f millisec (%f expected)\n",
	 (unsigned)i, su_time_diff(su_now(), started) * 1000, (double)i / 1000);

  for (i = 0; i < N; i++) {
    su_timer_destroy(timers[i]);
  }

  su_root_destroy(root);

  su_deinit();

  return 0;
}