prucv.c revision 677833bc953b6cb418c701facbdcf4aa18d6c44e
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* 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
*
* 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 the Initial Developer are Copyright (C) 1998-2000
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#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.
**
*/
#endif
/*
** Notify one thread that it has finished waiting on a condition variable
** Caller must hold the _PR_CVAR_LOCK(cv)
*/
{
if ( !_PR_IS_NATIVE_THREAD(thread) ) {
/* The notify and timeout can collide; in which case both may
* attempt to delete from the sleepQ; only let one do it.
*/
/*
* set thread state to SUSPENDED; a Resume operation
* on the thread will move it to the runQ
*/
} else {
/* Make thread runnable */
}
} else {
/* Thread has already been notified */
}
} else { /* If the thread is a native thread */
/*
* set thread state to SUSPENDED; a Resume operation
* on the thread will enable the thread to run
*/
} else
} else {
}
}
return rv;
}
/*
* Notify thread waiting on cvar; called when thread is interrupted
* The thread lock is held on entry and released before return
*/
{
if ( !_PR_IS_NATIVE_THREAD(me))
PR_ASSERT(_PR_MD_GET_INTSOFF() != 0);
if (!_PR_IS_NATIVE_THREAD(thread)) {
/* The notify and timeout can collide; in which case both may
* attempt to delete from the sleepQ; only let one do it.
*/
/* Make thread runnable */
} else {
/*
* set thread state to SUSPENDED; a Resume operation
* on the thread will enable the thread to run
*/
} else
}
return;
}
/*
** Make the given thread wait for the given condition variable
*/
{
#ifdef _PR_GLOBAL_THREADS_ONLY
if (_PR_PENDING_INTERRUPT(thread)) {
return PR_FAILURE;
}
if (_PR_PENDING_INTERRUPT(thread)) {
return PR_FAILURE;
}
return PR_SUCCESS;
#else /* _PR_GLOBAL_THREADS_ONLY */
if ( !_PR_IS_NATIVE_THREAD(thread))
if (_PR_PENDING_INTERRUPT(thread)) {
if ( !_PR_IS_NATIVE_THREAD(thread))
_PR_INTSON(is);
return PR_FAILURE;
}
/*
** Put the caller thread on the condition variable's wait Q
*/
/* 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) ) {
}
/*
** Release lock protecting the condition variable and thereby giving time
** to the next thread which can potentially notify on the condition variable
*/
("PR_Wait: cvar=%p done waiting", cvar));
if ( !_PR_IS_NATIVE_THREAD(thread))
_PR_INTSON(is);
/* Acquire lock again that we had just relinquished */
if (_PR_PENDING_INTERRUPT(thread)) {
return PR_FAILURE;
}
return rv;
#endif /* _PR_GLOBAL_THREADS_ONLY */
}
{
#ifdef _PR_GLOBAL_THREADS_ONLY
#else /* _PR_GLOBAL_THREADS_ONLY */
PRCList *q;
if ( !_PR_IS_NATIVE_THREAD(me))
#ifndef XP_MAC
#endif
break;
}
q = q->next;
}
if ( !_PR_IS_NATIVE_THREAD(me))
_PR_INTSON(is);
#endif /* _PR_GLOBAL_THREADS_ONLY */
}
/*
** Cndition variable debugging log info.
*/
{
} else {
}
return nb;
}
/*
** Expire condition variable waits that are ready to expire. "now" is the current
** time.
*/
void _PR_ClockInterrupt(void)
{
PR_ASSERT(_PR_MD_GET_INTSOFF() != 0);
/* Figure out how much time elapsed since the last clock tick */
now = PR_IntervalNow();
#ifndef XP_MAC
("ExpireWaits: elapsed=%lld usec", elapsed));
#endif
while(1) {
break;
}
break;
}
/*
** The thread was switched to another CPU
** between the time we unlocked the sleep
** queue and the time we acquired the thread
** lock, so it is none of our business now.
*/
continue;
}
/*
** Consume this sleeper's amount of elapsed time from the elapsed
** time value. The next remaining piece of elapsed time will be
** available for the next sleeping thread's timer.
*/
} else {
/* Thread was already handled; Go get another one */
continue;
}
/* Notify the thread waiting on the condition variable */
/*
** Thread is suspended and its condition timeout
** expired. Transfer thread from sleepQ to suspendQ.
*/
} else {
/* Do work very similar to what _PR_NotifyThread does */
/* Make thread runnable */
/* Need to put IO sleeper back on runq */
#ifdef WINNT
/*
* For NT, record the cpu on which I/O was issued
* I/O cancellation is done on the same cpu
*/
#endif
}
}
}
}
/************************************************************************/
/*
** Create a new condition variable.
** "lock" is the lock to use with the condition variable.
**
** Condition variables are synchronization objects that threads can use
** to wait for some condition to occur.
**
** This may fail if memory is tight or if some operating system resource
** is low.
*/
{
if (cvar) {
#ifdef _PR_GLOBAL_THREADS_ONLY
return NULL;
}
#endif
return NULL;
}
} else {
}
return cvar;
}
/*
** Destroy a condition variable. There must be no thread
** waiting on the condvar. The caller is responsible for guaranteeing
** that the condvar is no longer in use.
**
*/
{
#ifdef _PR_GLOBAL_THREADS_ONLY
#endif
}
/*
** Wait for a notify on the condition variable. Sleep for "tiemout" amount
** of ticks (if "timeout" is zero then the sleep is indefinite). While
** the thread is waiting it unlocks lock. When the wait has
** finished the thread regains control of the condition variable after
** locking the associated lock.
**
** The thread waiting on the condvar will be resumed when the condvar is
** notified (assuming the thread is the next in line to receive the
** notify) or when the timeout elapses.
**
** Returns PR_FAILURE if the caller has not locked the lock associated
** with the condition variable or the thread has been interrupted.
*/
extern PRThread *suspendAllThread;
{
}
/*
** Notify the highest priority thread waiting on the condition
** variable. If a thread is waiting on the condition variable (using
** PR_Wait) then it is awakened and begins waiting on the lock.
*/
{
return PR_SUCCESS;
}
/*
** Notify all of the threads waiting on the condition variable. All of
** threads are notified in turn. The highest priority thread will
** probably acquire the lock.
*/
{
PRCList *q;
#ifdef _PR_GLOBAL_THREADS_ONLY
return PR_SUCCESS;
#else /* _PR_GLOBAL_THREADS_ONLY */
if ( !_PR_IS_NATIVE_THREAD(me))
q = q->next;
}
if (!_PR_IS_NATIVE_THREAD(me))
_PR_INTSON(is);
return PR_SUCCESS;
#endif /* _PR_GLOBAL_THREADS_ONLY */
}
/*********************************************************************/
/*********************************************************************/
/********************ROUTINES FOR DCE EMULATION***********************/
/*********************************************************************/
/*********************************************************************/
#include "prpdce.h"
{
{
{
}
else
{
}
}
return cvar;
}
{
}
{
} /* PRP_NakedWait */
{
return PR_SUCCESS;
} /* PRP_NakedNotify */
{
PRCList *q;
q = q->next;
}
return PR_SUCCESS;
} /* PRP_NakedBroadcast */