예제 #1
0
int
_pthread_once(pthread_once_t *once_control, void (*init_routine) (void))
{
	int wakeup = 0;

	if (once_control->state == ONCE_DONE)
		return (0);
	_pthread_mutex_lock(&once_lock);
	while (*(volatile int *)&(once_control->state) == ONCE_IN_PROGRESS)
		_pthread_cond_wait(&once_cv, &once_lock);
	/*
	 * If previous thread was canceled, then the state still
	 * could be ONCE_NEVER_DONE, we need to check it again.
	 */
	if (*(volatile int *)&(once_control->state) == ONCE_NEVER_DONE) {
		once_control->state = ONCE_IN_PROGRESS;
		_pthread_mutex_unlock(&once_lock);
		_pthread_cleanup_push(once_cancel_handler, once_control);
		init_routine();
		_pthread_cleanup_pop(0);
		_pthread_mutex_lock(&once_lock);
		once_control->state = ONCE_DONE;
		wakeup = 1;
	}
	_pthread_mutex_unlock(&once_lock);
	if (wakeup)
		_pthread_cond_broadcast(&once_cv);
	return (0);
}
예제 #2
0
void
fn7 (void)
{
  /* This is the old LinuxThreads pthread_cleanup_{push,pop}.  */
     struct _pthread_cleanup_buffer b;
  _pthread_cleanup_push (&b, clh, (void *) 8l);

  fn6 ();

  _pthread_cleanup_pop (&b, 1);
}
예제 #3
0
static __attribute__((noinline)) void
fn3 (void)
{
  /* This is the old LinuxThreads pthread_cleanup_{push,pop}.  */
     struct _pthread_cleanup_buffer b;
  _pthread_cleanup_push (&b, clh, (void *) 4l);

  fn0 ();

  _pthread_cleanup_pop (&b, 1);
}