⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 prucv.c

📁 Netscape NSPR库源码
💻 C
📖 第 1 页 / 共 2 页
字号:
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- *//*  * The contents of this file are subject to the Mozilla Public * License Version 1.1 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.mozilla.org/MPL/ *  * Software distributed under the License is distributed on an "AS * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or * implied. See the License for the specific language governing * rights and limitations under the License. *  * The Original Code is the Netscape Portable Runtime (NSPR). *  * The Initial Developer of the Original Code is Netscape * Communications Corporation.  Portions created by Netscape are  * Copyright (C) 1998-2000 Netscape Communications Corporation.  All * Rights Reserved. *  * Contributor(s): *  * Alternatively, the contents of this file may be used under the * terms of the GNU General Public License Version 2 or later (the * "GPL"), in which case the provisions of the GPL are applicable  * instead of those above.  If you wish to allow use of your  * version of this file only under the terms of the GPL and not to * allow others to use your version of this file under the MPL, * indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by * the GPL.  If you do not delete the provisions above, a recipient * may use your version of this file under either the MPL or the * GPL. */#include "primpl.h"#include "prinrval.h"#include "prtypes.h"#if defined(WIN95)/*** Some local variables report warnings on Win95 because the code paths ** using them are conditioned on HAVE_CUSTOME_USER_THREADS.** The pragma suppresses the warning.** */#pragma warning(disable : 4101)#endif/*** Notify one thread that it has finished waiting on a condition variable** Caller must hold the _PR_CVAR_LOCK(cv)*/PRBool _PR_NotifyThread (PRThread *thread, PRThread *me){    PRBool rv;    PR_ASSERT(_PR_IS_NATIVE_THREAD(me) || _PR_MD_GET_INTSOFF() != 0);    _PR_THREAD_LOCK(thread);    PR_ASSERT(!(thread->flags & _PR_IDLE_THREAD));    if ( !_PR_IS_NATIVE_THREAD(thread) ) {        if (thread->wait.cvar != NULL) {            thread->wait.cvar = NULL;            _PR_SLEEPQ_LOCK(thread->cpu);            /* The notify and timeout can collide; in which case both may             * attempt to delete from the sleepQ; only let one do it.             */            if (thread->flags & (_PR_ON_SLEEPQ|_PR_ON_PAUSEQ))                _PR_DEL_SLEEPQ(thread, PR_TRUE);            _PR_SLEEPQ_UNLOCK(thread->cpu);	    if (thread->flags & _PR_SUSPENDING) {		/*		 * set thread state to SUSPENDED; a Resume operation		 * on the thread will move it to the runQ		 */            	thread->state = _PR_SUSPENDED;		_PR_MISCQ_LOCK(thread->cpu);		_PR_ADD_SUSPENDQ(thread, thread->cpu);		_PR_MISCQ_UNLOCK(thread->cpu);            	_PR_THREAD_UNLOCK(thread);	    } else {            	/* Make thread runnable */            	thread->state = _PR_RUNNABLE;            	_PR_THREAD_UNLOCK(thread);                _PR_AddThreadToRunQ(me, thread);                _PR_MD_WAKEUP_WAITER(thread);            }            rv = PR_TRUE;        } else {            /* Thread has already been notified */            _PR_THREAD_UNLOCK(thread);            rv = PR_FALSE;        }    } else { /* If the thread is a native thread */        if (thread->wait.cvar) {            thread->wait.cvar = NULL;	    if (thread->flags & _PR_SUSPENDING) {		/*		 * set thread state to SUSPENDED; a Resume operation		 * on the thread will enable the thread to run		 */            	thread->state = _PR_SUSPENDED;	     } else            	thread->state = _PR_RUNNING;            _PR_THREAD_UNLOCK(thread);            _PR_MD_WAKEUP_WAITER(thread);            rv = PR_TRUE;        } else {            _PR_THREAD_UNLOCK(thread);            rv = PR_FALSE;        }        }        return rv;}/* * Notify thread waiting on cvar; called when thread is interrupted * 	The thread lock is held on entry and released before return */void _PR_NotifyLockedThread (PRThread *thread){    PRThread *me = _PR_MD_CURRENT_THREAD();    PRCondVar *cvar;    PRThreadPriority pri;    if ( !_PR_IS_NATIVE_THREAD(me))    	PR_ASSERT(_PR_MD_GET_INTSOFF() != 0);    cvar = thread->wait.cvar;    thread->wait.cvar = NULL;    _PR_THREAD_UNLOCK(thread);    _PR_CVAR_LOCK(cvar);    _PR_THREAD_LOCK(thread);    if (!_PR_IS_NATIVE_THREAD(thread)) {            _PR_SLEEPQ_LOCK(thread->cpu);            /* The notify and timeout can collide; in which case both may             * attempt to delete from the sleepQ; only let one do it.             */            if (thread->flags & (_PR_ON_SLEEPQ|_PR_ON_PAUSEQ))                _PR_DEL_SLEEPQ(thread, PR_TRUE);            _PR_SLEEPQ_UNLOCK(thread->cpu);	    /* Make thread runnable */	    pri = thread->priority;	    thread->state = _PR_RUNNABLE;	    PR_ASSERT(!(thread->flags & _PR_IDLE_THREAD));            _PR_AddThreadToRunQ(me, thread);            _PR_THREAD_UNLOCK(thread);            _PR_MD_WAKEUP_WAITER(thread);    } else {	    if (thread->flags & _PR_SUSPENDING) {		/*		 * set thread state to SUSPENDED; a Resume operation		 * on the thread will enable the thread to run		 */            	thread->state = _PR_SUSPENDED;	     } else            	thread->state = _PR_RUNNING;            _PR_THREAD_UNLOCK(thread);            _PR_MD_WAKEUP_WAITER(thread);    }        _PR_CVAR_UNLOCK(cvar);    return;}/*** Make the given thread wait for the given condition variable*/PRStatus _PR_WaitCondVar(    PRThread *thread, PRCondVar *cvar, PRLock *lock, PRIntervalTime timeout){    PRIntn is;    PRStatus rv = PR_SUCCESS;    PR_ASSERT(thread == _PR_MD_CURRENT_THREAD());    PR_ASSERT(!(thread->flags & _PR_IDLE_THREAD));#ifdef _PR_GLOBAL_THREADS_ONLY    if (_PR_PENDING_INTERRUPT(thread)) {        PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0);        thread->flags &= ~_PR_INTERRUPT;        return PR_FAILURE;    }    thread->wait.cvar = cvar;    lock->owner = NULL;    _PR_MD_WAIT_CV(&cvar->md,&lock->ilock, timeout);    thread->wait.cvar = NULL;    lock->owner = thread;    if (_PR_PENDING_INTERRUPT(thread)) {        PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0);        thread->flags &= ~_PR_INTERRUPT;        return PR_FAILURE;    }    return PR_SUCCESS;#else  /* _PR_GLOBAL_THREADS_ONLY */    if ( !_PR_IS_NATIVE_THREAD(thread))    	_PR_INTSOFF(is);    _PR_CVAR_LOCK(cvar);    _PR_THREAD_LOCK(thread);    if (_PR_PENDING_INTERRUPT(thread)) {        PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0);        thread->flags &= ~_PR_INTERRUPT;    	_PR_CVAR_UNLOCK(cvar);    	_PR_THREAD_UNLOCK(thread);    	if ( !_PR_IS_NATIVE_THREAD(thread))    		_PR_INTSON(is);        return PR_FAILURE;    }    thread->state = _PR_COND_WAIT;    thread->wait.cvar = cvar;    /*    ** Put the caller thread on the condition variable's wait Q    */    PR_APPEND_LINK(&thread->waitQLinks, &cvar->condQ);    /* Note- for global scope threads, we don't put them on the     *       global sleepQ, so each global thread must put itself     *       to sleep only for the time it wants to.     */    if ( !_PR_IS_NATIVE_THREAD(thread) ) {        _PR_SLEEPQ_LOCK(thread->cpu);        _PR_ADD_SLEEPQ(thread, timeout);        _PR_SLEEPQ_UNLOCK(thread->cpu);    }    _PR_CVAR_UNLOCK(cvar);    _PR_THREAD_UNLOCK(thread);       /*     ** Release lock protecting the condition variable and thereby giving time     ** to the next thread which can potentially notify on the condition variable    */    PR_Unlock(lock);    PR_LOG(_pr_cvar_lm, PR_LOG_MIN,	   ("PR_Wait: cvar=%p waiting for %d", cvar, timeout));    rv = _PR_MD_WAIT(thread, timeout);    _PR_CVAR_LOCK(cvar);    PR_REMOVE_LINK(&thread->waitQLinks);    _PR_CVAR_UNLOCK(cvar);    PR_LOG(_pr_cvar_lm, PR_LOG_MIN,	   ("PR_Wait: cvar=%p done waiting", cvar));    if ( !_PR_IS_NATIVE_THREAD(thread))    	_PR_INTSON(is);    /* Acquire lock again that we had just relinquished */    PR_Lock(lock);    if (_PR_PENDING_INTERRUPT(thread)) {        PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0);        thread->flags &= ~_PR_INTERRUPT;        return PR_FAILURE;    }    return rv;#endif  /* _PR_GLOBAL_THREADS_ONLY */}void _PR_NotifyCondVar(PRCondVar *cvar, PRThread *me){#ifdef _PR_GLOBAL_THREADS_ONLY    _PR_MD_NOTIFY_CV(&cvar->md, &cvar->lock->ilock);#else  /* _PR_GLOBAL_THREADS_ONLY */    PRCList *q;    PRIntn is;    if ( !_PR_IS_NATIVE_THREAD(me))    	_PR_INTSOFF(is);    PR_ASSERT(_PR_IS_NATIVE_THREAD(me) || _PR_MD_GET_INTSOFF() != 0);    _PR_CVAR_LOCK(cvar);    q = cvar->condQ.next;    while (q != &cvar->condQ) {#ifndef XP_MAC        PR_LOG(_pr_cvar_lm, PR_LOG_MIN, ("_PR_NotifyCondVar: cvar=%p", cvar));#endif        if (_PR_THREAD_CONDQ_PTR(q)->wait.cvar)  {            if (_PR_NotifyThread(_PR_THREAD_CONDQ_PTR(q), me) == PR_TRUE)                break;        }        q = q->next;    }    _PR_CVAR_UNLOCK(cvar);    if ( !_PR_IS_NATIVE_THREAD(me))    	_PR_INTSON(is);#endif  /* _PR_GLOBAL_THREADS_ONLY */}/*** Cndition variable debugging log info.*/PRUint32 _PR_CondVarToString(PRCondVar *cvar, char *buf, PRUint32 buflen){    PRUint32 nb;    if (cvar->lock->owner) {	nb = PR_snprintf(buf, buflen, "[%p] owner=%ld[%p]",			 cvar, cvar->lock->owner->id, cvar->lock->owner);    } else {	nb = PR_snprintf(buf, buflen, "[%p]", cvar);    }    return nb;}/*** Expire condition variable waits that are ready to expire. "now" is the current** time.*/void _PR_ClockInterrupt(void){    PRThread *thread, *me = _PR_MD_CURRENT_THREAD();    _PRCPU *cpu = me->cpu;    PRIntervalTime elapsed, now;

⌨️ 快捷键说明

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