_MD_CreateThread(
    PRThread *thread,
    void (*start) (void *),
    PRThreadPriority priority,
    PRThreadScope scope,
    PRThreadState state,
    PRUint32 stackSize)
{
    PRIntn is;
    int rv;
	PRThread *me = _PR_MD_CURRENT_THREAD();	
	pthread_attr_t attr;

	if (!_PR_IS_NATIVE_THREAD(me))
		_PR_INTSOFF(is);

	if (pthread_mutex_init(&thread->md.pthread_mutex, NULL) != 0) {
		if (!_PR_IS_NATIVE_THREAD(me))
			_PR_FAST_INTSON(is);
        return PR_FAILURE;
	}

	if (pthread_cond_init(&thread->md.pthread_cond, NULL) != 0) {
		pthread_mutex_destroy(&thread->md.pthread_mutex);
		if (!_PR_IS_NATIVE_THREAD(me))
			_PR_FAST_INTSON(is);
        return PR_FAILURE;
	}
    thread->flags |= _PR_GLOBAL_SCOPE;

	pthread_attr_init(&attr); /* initialize attr with default attributes */
	if (pthread_attr_setstacksize(&attr, (size_t) stackSize) != 0) {
		pthread_mutex_destroy(&thread->md.pthread_mutex);
		pthread_cond_destroy(&thread->md.pthread_cond);
		pthread_attr_destroy(&attr);
		if (!_PR_IS_NATIVE_THREAD(me))
			_PR_FAST_INTSON(is);
        return PR_FAILURE;
	}

	thread->md.wait = 0;
    rv = pthread_create(&thread->md.pthread, &attr, start, (void *)thread);
    if (0 == rv) {
        _MD_ATOMIC_INCREMENT(&_pr_md_pthreads_created);
        _MD_ATOMIC_INCREMENT(&_pr_md_pthreads);
		if (!_PR_IS_NATIVE_THREAD(me))
			_PR_FAST_INTSON(is);
        return PR_SUCCESS;
    } else {
		pthread_mutex_destroy(&thread->md.pthread_mutex);
		pthread_cond_destroy(&thread->md.pthread_cond);
		pthread_attr_destroy(&attr);
        _MD_ATOMIC_INCREMENT(&_pr_md_pthreads_failed);
		if (!_PR_IS_NATIVE_THREAD(me))
			_PR_FAST_INTSON(is);
        PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, rv);
        return PR_FAILURE;
    }
}
Exemple #2
0
    PR_WaitCondVar (PRCondVar *cvar, PRIntervalTime timeout)
{
    status_t err;
    if( timeout == PR_INTERVAL_NO_WAIT ) 
    {
        PR_Unlock( cvar->lock );
        PR_Lock( cvar->lock );
        return PR_SUCCESS;
    }

    if( _MD_ATOMIC_INCREMENT( &cvar->signalBenCount ) > 1 )
    {
        if (acquire_sem(cvar->signalSem) == B_INTERRUPTED) 
        {
            _MD_ATOMIC_DECREMENT( &cvar->signalBenCount );
            return PR_FAILURE;
        }
    }
    cvar->nw += 1;
    if( _MD_ATOMIC_DECREMENT( &cvar->signalBenCount ) > 0 )
    {
        release_sem_etc(cvar->signalSem, 1, B_DO_NOT_RESCHEDULE);
    }

    PR_Unlock( cvar->lock );
    if( timeout==PR_INTERVAL_NO_TIMEOUT ) 
    {
    	err = acquire_sem(cvar->sem);
    } 
    else 
    {
    	err = acquire_sem_etc(cvar->sem, 1, B_RELATIVE_TIMEOUT, PR_IntervalToMicroseconds(timeout) );
    }

    if( _MD_ATOMIC_INCREMENT( &cvar->signalBenCount ) > 1 )
    {
        while (acquire_sem(cvar->signalSem) == B_INTERRUPTED);
    }

    if (cvar->ns > 0)
    {
        release_sem_etc(cvar->handshakeSem, 1, B_DO_NOT_RESCHEDULE);
        cvar->ns -= 1;
    }
    cvar->nw -= 1;
    if( _MD_ATOMIC_DECREMENT( &cvar->signalBenCount ) > 0 )
    {
        release_sem_etc(cvar->signalSem, 1, B_DO_NOT_RESCHEDULE);
    }

    PR_Lock( cvar->lock );
    if(err==B_NO_ERROR  || (err == B_TIMED_OUT && timeout!=PR_INTERVAL_NO_TIMEOUT))
    {
    return PR_SUCCESS;
}
    return PR_FAILURE;
}
Exemple #3
0
    PR_NotifyCondVar (PRCondVar *cvar)
{
    status_t err ;
    if( _MD_ATOMIC_INCREMENT( &cvar->signalBenCount) > 1 )
    {
        if (acquire_sem(cvar->signalSem) == B_INTERRUPTED) 
        {
            _MD_ATOMIC_DECREMENT( &cvar->signalBenCount );
            return PR_FAILURE;
        }
    }
    if (cvar->nw > cvar->ns)
    {
        cvar->ns += 1;
        release_sem_etc(cvar->sem, 1, B_DO_NOT_RESCHEDULE);
        if( _MD_ATOMIC_DECREMENT( &cvar->signalBenCount) > 0 )
        {
            release_sem_etc(cvar->signalSem, 1, B_DO_NOT_RESCHEDULE);
        }

        while (acquire_sem(cvar->handshakeSem) == B_INTERRUPTED) 
        {
            err = B_INTERRUPTED; 
        }
    }
    else
    {
        if( _MD_ATOMIC_DECREMENT( &cvar->signalBenCount ) > 0 )
        {
            release_sem_etc(cvar->signalSem, 1, B_DO_NOT_RESCHEDULE);
        }
    }
    return PR_SUCCESS; 
}