Пример #1
0
PR_IMPLEMENT(PRStatus) PR_Wait(PRMonitor *mon, PRIntervalTime timeout)
{
    PRStatus rv;
    PRInt16 saved_entries;
    pthread_t saved_owner;

    PR_ASSERT(mon != NULL);
    /* we'd better be locked */
    PR_ASSERT(_PT_PTHREAD_MUTEX_IS_LOCKED(mon->lock.mutex));
    /* and the entries better be positive */
    PR_ASSERT(mon->entryCount > 0);
    /* and it better be by us */
    PR_ASSERT(pthread_equal(mon->owner, pthread_self()));

    /* tuck these away 'till later */
    saved_entries = mon->entryCount; 
    mon->entryCount = 0;
    _PT_PTHREAD_COPY_THR_HANDLE(mon->owner, saved_owner);
    _PT_PTHREAD_INVALIDATE_THR_HANDLE(mon->owner);
    
    rv = PR_WaitCondVar(mon->cvar, timeout);

    /* reinstate the intresting information */
    mon->entryCount = saved_entries;
    _PT_PTHREAD_COPY_THR_HANDLE(saved_owner, mon->owner);

    return rv;
}  /* PR_Wait */
Пример #2
0
PR_IMPLEMENT(PRStatus) PR_Wait(PRMonitor *mon, PRIntervalTime timeout)
{
    PRStatus rv;
    PRUint32 saved_entries;
    pthread_t saved_owner;

    PR_ASSERT(mon != NULL);
    rv = pthread_mutex_lock(&mon->lock);
    PR_ASSERT(0 == rv);
    /* the entries better be positive */
    PR_ASSERT(mon->entryCount > 0);
    /* and it better be owned by us */
    PR_ASSERT(pthread_equal(mon->owner, pthread_self()));

    /* tuck these away 'till later */
    saved_entries = mon->entryCount;
    mon->entryCount = 0;
    _PT_PTHREAD_COPY_THR_HANDLE(mon->owner, saved_owner);
    _PT_PTHREAD_INVALIDATE_THR_HANDLE(mon->owner);
    /*
     * If we have pending notifies, post them now.
     *
     * This is not optimal. We're going to post these notifies
     * while we're holding the lock. That means on MP systems
     * that they are going to collide for the lock that we will
     * hold until we actually wait.
     */
    if (0 != mon->notifyTimes)
    {
        pt_PostNotifiesFromMonitor(&mon->waitCV, mon->notifyTimes);
        mon->notifyTimes = 0;
    }
    rv = pthread_cond_signal(&mon->entryCV);
    PR_ASSERT(0 == rv);

    if (timeout == PR_INTERVAL_NO_TIMEOUT)
        rv = pthread_cond_wait(&mon->waitCV, &mon->lock);
    else
        rv = pt_TimedWait(&mon->waitCV, &mon->lock, timeout);
    PR_ASSERT(0 == rv);

    while (mon->entryCount != 0)
    {
        rv = pthread_cond_wait(&mon->entryCV, &mon->lock);
        PR_ASSERT(0 == rv);
    }
    PR_ASSERT(0 == mon->notifyTimes);
    /* reinstate the interesting information */
    mon->entryCount = saved_entries;
    _PT_PTHREAD_COPY_THR_HANDLE(saved_owner, mon->owner);

    rv = pthread_mutex_unlock(&mon->lock);
    PR_ASSERT(0 == rv);
    return rv;
}  /* PR_Wait */
Пример #3
0
PR_IMPLEMENT(void) PR_EnterMonitor(PRMonitor *mon)
{
    pthread_t self = pthread_self();
    PRIntn rv;

    PR_ASSERT(mon != NULL);
    rv = pthread_mutex_lock(&mon->lock);
    PR_ASSERT(0 == rv);
    if (mon->entryCount != 0)
    {
        if (pthread_equal(mon->owner, self))
            goto done;
        while (mon->entryCount != 0)
        {
            rv = pthread_cond_wait(&mon->entryCV, &mon->lock);
            PR_ASSERT(0 == rv);
        }
    }
    /* and now I have the monitor */
    PR_ASSERT(0 == mon->notifyTimes);
    PR_ASSERT(_PT_PTHREAD_THR_HANDLE_IS_INVALID(mon->owner));
    _PT_PTHREAD_COPY_THR_HANDLE(self, mon->owner);

done:
    mon->entryCount += 1;
    rv = pthread_mutex_unlock(&mon->lock);
    PR_ASSERT(0 == rv);
}  /* PR_EnterMonitor */
Пример #4
0
PR_IMPLEMENT(void) PR_EnterMonitor(PRMonitor *mon)
{
    pthread_t self = pthread_self();

    PR_ASSERT(mon != NULL);
    /*
     * This is safe only if mon->owner (a pthread_t) can be
     * read in one instruction.  Perhaps mon->owner should be
     * a "PRThread *"?
     */
    if (!pthread_equal(mon->owner, self))
    {
        PR_Lock(&mon->lock);
        /* and now I have the lock */
        PR_ASSERT(0 == mon->entryCount);
        PR_ASSERT(_PT_PTHREAD_THR_HANDLE_IS_INVALID(mon->owner));
        _PT_PTHREAD_COPY_THR_HANDLE(self, mon->owner);
    }
    mon->entryCount += 1;
}  /* PR_EnterMonitor */