nssrwlk.c

来自「支持SSL v2/v3, TLS, PKCS #5, PKCS #7, PKCS」· C语言 代码 · 共 513 行 · 第 1/2 页

C
513
字号
#ifdef NSS_RWLOCK_RANK_ORDER_DEBUG    /*     * update thread's lock rank     */    nssRWLock_UnsetThreadRank(me, rwlock);#endif    return;}/*** Write-lock the RWLock.*/PR_IMPLEMENT(void)NSSRWLock_LockWrite(NSSRWLock *rwlock){    PRInt32 lock_acquired = 0;    PRThread *me = PR_GetCurrentThread();    PR_Lock(rwlock->rw_lock);#ifdef NSS_RWLOCK_RANK_ORDER_DEBUG    /*     * assert that rank ordering is not violated; the rank of 'rwlock' should     * be equal to or greater than the highest rank of all the locks held by     * the thread.     */    PR_ASSERT((rwlock->rw_rank == NSS_RWLOCK_RANK_NONE) ||                    (rwlock->rw_rank >= nssRWLock_GetThreadRank(me)));#endif    /*     * wait if read locked or write locked.     */    PR_ASSERT(rwlock->rw_reader_locks >= 0);    PR_ASSERT(me != NULL);    UNTIL ( (rwlock->rw_owner == me) ||           /* I own write lock, or */	   ((rwlock->rw_owner == NULL) &&	  /* no writer   and */	    (rwlock->rw_reader_locks == 0))) {    /* no readers, either. */        rwlock->rw_waiting_writers++;        PR_WaitCondVar(rwlock->rw_writer_waitq, PR_INTERVAL_NO_TIMEOUT);        rwlock->rw_waiting_writers--;	PR_ASSERT(rwlock->rw_reader_locks >= 0);    }    PR_ASSERT(rwlock->rw_reader_locks == 0);    /*     * apply write lock     */    rwlock->rw_owner = me;    rwlock->rw_writer_locks++; 		/* Increment write-lock count */    PR_Unlock(rwlock->rw_lock);#ifdef NSS_RWLOCK_RANK_ORDER_DEBUG    /*     * update thread's lock rank     */    nssRWLock_SetThreadRank(me,rwlock);#endif}/* Unlock a Read lock held on this RW lock.*/PR_IMPLEMENT(void)NSSRWLock_UnlockWrite(NSSRWLock *rwlock){    PRThread *me = PR_GetCurrentThread();    PR_Lock(rwlock->rw_lock);    PR_ASSERT(rwlock->rw_owner == me); /* lock must be write-locked by me.  */    PR_ASSERT(rwlock->rw_writer_locks > 0); /* lock must be write locked */    if (  rwlock->rw_owner        == me  &&	/* I own it, and            */          rwlock->rw_writer_locks  > 0   &&	/* I own it, and            */        --rwlock->rw_writer_locks == 0) {	/* I'm all done with it     */	rwlock->rw_owner = NULL;		/* I don't own it any more. */	if (rwlock->rw_reader_locks == 0) { /* no readers, wake up somebody. */	    /* Give preference to waiting writers. */	    if (rwlock->rw_waiting_writers > 0) 		PR_NotifyCondVar(rwlock->rw_writer_waitq);	    else if (rwlock->rw_waiting_readers > 0)		PR_NotifyAllCondVar(rwlock->rw_reader_waitq);	}    }    PR_Unlock(rwlock->rw_lock);#ifdef NSS_RWLOCK_RANK_ORDER_DEBUG    /*     * update thread's lock rank     */    nssRWLock_UnsetThreadRank(me, rwlock);#endif    return;}/* This is primarily for debugging, i.e. for inclusion in ASSERT calls. */PR_IMPLEMENT(PRBool)NSSRWLock_HaveWriteLock(NSSRWLock *rwlock) {    PRBool ownWriteLock;    PRThread *me = PR_GetCurrentThread();    /* This lock call isn't really necessary.    ** If this thread is the owner, that fact cannot change during this call,    ** because this thread is in this call.    ** If this thread is NOT the owner, the owner could change, but it     ** could not become this thread.      */#if UNNECESSARY    PR_Lock(rwlock->rw_lock);	#endif    ownWriteLock = (PRBool)(me == rwlock->rw_owner);#if UNNECESSARY    PR_Unlock(rwlock->rw_lock);#endif    return ownWriteLock;}#ifdef NSS_RWLOCK_RANK_ORDER_DEBUG/* * nssRWLock_SetThreadRank *      Set a thread's lock rank, which is the highest of the ranks of all *      the locks held by the thread. Pointers to the locks are added to a *      per-thread list, which is anchored off a thread-private data key. */static voidnssRWLock_SetThreadRank(PRThread *me, NSSRWLock *rwlock){    thread_rwlock_stack *lock_stack;    PRStatus rv;    /*     * allocated thread-private-data for rwlock list, if not already allocated     */    if (!nss_thread_rwlock_initialized) {        /*         * allocate tpd, only if not failed already         */        if (!nss_thread_rwlock_alloc_failed) {            if (PR_NewThreadPrivateIndex(&nss_thread_rwlock,                                        nssRWLock_ReleaseLockStack)                                                == PR_FAILURE) {                nss_thread_rwlock_alloc_failed = 1;                return;            }        } else            return;    }    /*     * allocate a lock stack     */    if ((lock_stack = PR_GetThreadPrivate(nss_thread_rwlock)) == NULL) {        lock_stack = (thread_rwlock_stack *)                        PR_CALLOC(1 * sizeof(thread_rwlock_stack));        if (lock_stack) {            rv = PR_SetThreadPrivate(nss_thread_rwlock, lock_stack);            if (rv == PR_FAILURE) {                PR_DELETE(lock_stack);                nss_thread_rwlock_alloc_failed = 1;                return;            }        } else {            nss_thread_rwlock_alloc_failed = 1;            return;        }    }    /*     * add rwlock to lock stack, if limit is not exceeded     */    if (lock_stack) {        if (lock_stack->trs_index < _NSS_RWLOCK_RANK_ORDER_LIMIT)            lock_stack->trs_stack[lock_stack->trs_index++] = rwlock;    }    nss_thread_rwlock_initialized = 1;}static voidnssRWLock_ReleaseLockStack(void *lock_stack){    PR_ASSERT(lock_stack);    PR_DELETE(lock_stack);}/* * nssRWLock_GetThreadRank * *      return thread's lock rank. If thread-private-data for the lock *      stack is not allocated, return NSS_RWLOCK_RANK_NONE. */static PRUint32nssRWLock_GetThreadRank(PRThread *me){    thread_rwlock_stack *lock_stack;    if (nss_thread_rwlock_initialized) {        if ((lock_stack = PR_GetThreadPrivate(nss_thread_rwlock)) == NULL)            return (NSS_RWLOCK_RANK_NONE);        else            return(lock_stack->trs_stack[lock_stack->trs_index - 1]->rw_rank);    } else            return (NSS_RWLOCK_RANK_NONE);}/* * nssRWLock_UnsetThreadRank * *      remove the rwlock from the lock stack. Since locks may not be *      unlocked in a FIFO order, the entire lock stack is searched. */static voidnssRWLock_UnsetThreadRank(PRThread *me, NSSRWLock *rwlock){    thread_rwlock_stack *lock_stack;    int new_index = 0, index, done = 0;    if (!nss_thread_rwlock_initialized)        return;    lock_stack = PR_GetThreadPrivate(nss_thread_rwlock);    PR_ASSERT(lock_stack != NULL);    index = lock_stack->trs_index - 1;    while (index-- >= 0) {        if ((lock_stack->trs_stack[index] == rwlock) && !done)  {            /*             * reset the slot for rwlock             */            lock_stack->trs_stack[index] = NULL;            done = 1;        }        /*         * search for the lowest-numbered empty slot, above which there are         * no non-empty slots         */        if ((lock_stack->trs_stack[index] != NULL) && !new_index)            new_index = index + 1;        if (done && new_index)            break;    }    /*     * set top of stack to highest numbered empty slot     */    lock_stack->trs_index = new_index;}#endif  /* NSS_RWLOCK_RANK_ORDER_DEBUG */

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?