summaryrefslogtreecommitdiff
path: root/cpp/include/IceUtil/Cond.h
diff options
context:
space:
mode:
Diffstat (limited to 'cpp/include/IceUtil/Cond.h')
-rw-r--r--cpp/include/IceUtil/Cond.h668
1 files changed, 334 insertions, 334 deletions
diff --git a/cpp/include/IceUtil/Cond.h b/cpp/include/IceUtil/Cond.h
index c9ad5036ae3..88647bc4d3d 100644
--- a/cpp/include/IceUtil/Cond.h
+++ b/cpp/include/IceUtil/Cond.h
@@ -1,334 +1,334 @@
-// **********************************************************************
-//
-// Copyright (c) 2001
-// Mutable Realms, Inc.
-// Huntsville, AL, USA
-//
-// All Rights Reserved
-//
-// **********************************************************************
-
-#ifndef ICE_UTIL_COND_H
-#define ICE_UTIL_COND_H
-
-#include <IceUtil/Config.h>
-#include <IceUtil/Time.h>
-#include <IceUtil/ThreadException.h>
-
-#ifdef _WIN32
-//
-// Needed for implementation under WIN32.
-//
-# include <IceUtil/Mutex.h>
-//
-// See member-template note for waitImpl & timedWaitImpl.
-//
-# include <IceUtil/RecMutex.h>
-#endif
-
-namespace IceUtil
-{
-
-//
-// Forward declaration (for friend declarations).
-//
-template <class T> class Monitor;
-class RecMutex;
-class Mutex;
-
-#ifdef _WIN32
-//
-// Needed for implementation.
-//
-class Semaphore
-{
-public:
-
- Semaphore(long = 0);
- ~Semaphore();
-
- void wait() const;
- bool timedWait(const Time&) const;
- void post(int = 1) const;
-
-private:
-
- mutable HANDLE _sem;
-};
-#endif
-
-//
-// Condition variable implementation. Conforms to the same semantics
-// as a POSIX threads condition variable.
-//
-class ICE_UTIL_API Cond : public noncopyable
-{
-public:
-
- Cond();
- ~Cond();
-
- //
- // signal restarts one of the threads that are waiting on the
- // condition variable cond. If no threads are waiting on cond,
- // nothing happens. If several threads are waiting on cond,
- // exactly one is restarted, but it is not specified which.
- //
- void signal();
-
- //
- // broadcast restarts all the threads that are waiting on the
- // condition variable cond. Nothing happens if no threads are
- // waiting on cond.
- //
- void broadcast();
-
- //
- // MSVC doesn't support out-of-class definitions of member
- // templates. See KB Article Q241949 for details.
- //
-
- //
- // wait atomically unlocks the mutex and waits for the condition
- // variable to be signaled. Before returning to the calling thread
- // the mutex is reaquired.
- //
- template <typename Lock> inline void
- wait(const Lock& lock) const
- {
- waitImpl(lock._mutex);
- }
-
- //
- // wait atomically unlocks the mutex and waits for the condition
- // variable to be signaled for up to the given timeout. Before
- // returning to the calling thread the mutex is reaquired. Returns
- // true if the condition variable was signaled, false on a
- // timeout.
- //
- template <typename Lock> inline bool
- timedWait(const Lock& lock, const Time& timeout) const
- {
- return timedWaitImpl(lock._mutex, timeout);
- }
-
-private:
-
- friend class Monitor<Mutex>;
- friend class Monitor<RecMutex>;
-
- //
- // The Monitor implementation uses waitImpl & timedWaitImpl.
- //
-#ifdef _WIN32
-
- //
- // For some reason under WIN32 with VC6 using a member-template
- // for waitImpl & timedWaitImpl results in a link error for
- // RecMutex.
- //
-/*
- template <typename M> void
- waitImpl(const M& mutex) const
- {
- preWait();
-
- typedef typename M::LockState LockState;
-
- LockState state;
- mutex.unlock(state);
-
- try
- {
- dowait(-1);
- mutex.lock(state);
- }
- catch(...)
- {
- mutex.lock(state);
- throw;
- }
- }
- template <typename M> bool
- timedWaitImpl(const M& mutex, const Time& timeout) const
- {
- preWait();
-
- typedef typename M::LockState LockState;
-
- LockState state;
- mutex.unlock(state);
-
- try
- {
- bool rc = dowait(timeout);
- mutex.lock(state);
- return rc;
- }
- catch(...)
- {
- mutex.lock(state);
- throw;
- }
- }
- */
-
- void
- waitImpl(const RecMutex& mutex) const
- {
- preWait();
-
- RecMutex::LockState state;
- mutex.unlock(state);
-
- try
- {
- dowait();
- mutex.lock(state);
- }
- catch(...)
- {
- mutex.lock(state);
- throw;
- }
- }
-
- void
- waitImpl(const Mutex& mutex) const
- {
- preWait();
-
- Mutex::LockState state;
- mutex.unlock(state);
-
- try
- {
- dowait();
- mutex.lock(state);
- }
- catch(...)
- {
- mutex.lock(state);
- throw;
- }
- }
-
- bool
- timedWaitImpl(const RecMutex& mutex, const Time& timeout) const
- {
- preWait();
-
- RecMutex::LockState state;
- mutex.unlock(state);
-
- try
- {
- bool rc = timedDowait(timeout);
- mutex.lock(state);
- return rc;
- }
- catch(...)
- {
- mutex.lock(state);
- throw;
- }
- }
-
- bool
- timedWaitImpl(const Mutex& mutex, const Time& timeout) const
- {
- preWait();
-
- Mutex::LockState state;
- mutex.unlock(state);
-
- try
- {
- bool rc = timedDowait(timeout);
- mutex.lock(state);
- return rc;
- }
- catch(...)
- {
- mutex.lock(state);
- throw;
- }
- }
-
-#else
-
- template <typename M> void waitImpl(const M&) const;
- template <typename M> bool timedWaitImpl(const M&, const Time&) const;
-
-#endif
-
-#ifdef _WIN32
- void wake(bool);
- void preWait() const;
- void postWait(bool) const;
- bool timedDowait(const Time&) const;
- void dowait() const;
-
- Mutex _internal;
- Semaphore _gate;
- Semaphore _queue;
- mutable long _blocked;
- mutable long _unblocked;
- mutable long _toUnblock;
-#else
- mutable pthread_cond_t _cond;
-#endif
-
-};
-
-#ifndef _WIN32
-template <typename M> inline void
-Cond::waitImpl(const M& mutex) const
-{
- typedef typename M::LockState LockState;
-
- LockState state;
- mutex.unlock(state);
- int rc = pthread_cond_wait(&_cond, state.mutex);
- mutex.lock(state);
-
- if(rc != 0)
- {
- throw ThreadSyscallException(strerror(rc), __FILE__, __LINE__);
- }
-}
-
-template <typename M> inline bool
-Cond::timedWaitImpl(const M& mutex, const Time& timeout) const
-{
- typedef typename M::LockState LockState;
-
- LockState state;
- mutex.unlock(state);
-
- timeval tv = Time::now() + timeout;
- timespec ts;
- ts.tv_sec = tv.tv_sec;
- ts.tv_nsec = tv.tv_usec*1000;
- int rc = pthread_cond_timedwait(&_cond, state.mutex, &ts);
- mutex.lock(state);
-
- if(rc != 0)
- {
- //
- // pthread_cond_timedwait returns ETIMEOUT in the event of a
- // timeout.
- //
- if(rc != ETIMEDOUT)
- {
- throw ThreadSyscallException(strerror(rc), __FILE__, __LINE__);
- }
- return false;
- }
- return true;
-}
-#endif
-
-} // End namespace IceUtil
-
-#endif
+// **********************************************************************
+//
+// Copyright (c) 2001
+// Mutable Realms, Inc.
+// Huntsville, AL, USA
+//
+// All Rights Reserved
+//
+// **********************************************************************
+
+#ifndef ICE_UTIL_COND_H
+#define ICE_UTIL_COND_H
+
+#include <IceUtil/Config.h>
+#include <IceUtil/Time.h>
+#include <IceUtil/ThreadException.h>
+
+#ifdef _WIN32
+//
+// Needed for implementation under WIN32.
+//
+# include <IceUtil/Mutex.h>
+//
+// See member-template note for waitImpl & timedWaitImpl.
+//
+# include <IceUtil/RecMutex.h>
+#endif
+
+namespace IceUtil
+{
+
+//
+// Forward declaration (for friend declarations).
+//
+template <class T> class Monitor;
+class RecMutex;
+class Mutex;
+
+#ifdef _WIN32
+//
+// Needed for implementation.
+//
+class Semaphore
+{
+public:
+
+ Semaphore(long = 0);
+ ~Semaphore();
+
+ void wait() const;
+ bool timedWait(const Time&) const;
+ void post(int = 1) const;
+
+private:
+
+ mutable HANDLE _sem;
+};
+#endif
+
+//
+// Condition variable implementation. Conforms to the same semantics
+// as a POSIX threads condition variable.
+//
+class ICE_UTIL_API Cond : public noncopyable
+{
+public:
+
+ Cond();
+ ~Cond();
+
+ //
+ // signal restarts one of the threads that are waiting on the
+ // condition variable cond. If no threads are waiting on cond,
+ // nothing happens. If several threads are waiting on cond,
+ // exactly one is restarted, but it is not specified which.
+ //
+ void signal();
+
+ //
+ // broadcast restarts all the threads that are waiting on the
+ // condition variable cond. Nothing happens if no threads are
+ // waiting on cond.
+ //
+ void broadcast();
+
+ //
+ // MSVC doesn't support out-of-class definitions of member
+ // templates. See KB Article Q241949 for details.
+ //
+
+ //
+ // wait atomically unlocks the mutex and waits for the condition
+ // variable to be signaled. Before returning to the calling thread
+ // the mutex is reaquired.
+ //
+ template <typename Lock> inline void
+ wait(const Lock& lock) const
+ {
+ waitImpl(lock._mutex);
+ }
+
+ //
+ // wait atomically unlocks the mutex and waits for the condition
+ // variable to be signaled for up to the given timeout. Before
+ // returning to the calling thread the mutex is reaquired. Returns
+ // true if the condition variable was signaled, false on a
+ // timeout.
+ //
+ template <typename Lock> inline bool
+ timedWait(const Lock& lock, const Time& timeout) const
+ {
+ return timedWaitImpl(lock._mutex, timeout);
+ }
+
+private:
+
+ friend class Monitor<Mutex>;
+ friend class Monitor<RecMutex>;
+
+ //
+ // The Monitor implementation uses waitImpl & timedWaitImpl.
+ //
+#ifdef _WIN32
+
+ //
+ // For some reason under WIN32 with VC6 using a member-template
+ // for waitImpl & timedWaitImpl results in a link error for
+ // RecMutex.
+ //
+/*
+ template <typename M> void
+ waitImpl(const M& mutex) const
+ {
+ preWait();
+
+ typedef typename M::LockState LockState;
+
+ LockState state;
+ mutex.unlock(state);
+
+ try
+ {
+ dowait(-1);
+ mutex.lock(state);
+ }
+ catch(...)
+ {
+ mutex.lock(state);
+ throw;
+ }
+ }
+ template <typename M> bool
+ timedWaitImpl(const M& mutex, const Time& timeout) const
+ {
+ preWait();
+
+ typedef typename M::LockState LockState;
+
+ LockState state;
+ mutex.unlock(state);
+
+ try
+ {
+ bool rc = dowait(timeout);
+ mutex.lock(state);
+ return rc;
+ }
+ catch(...)
+ {
+ mutex.lock(state);
+ throw;
+ }
+ }
+ */
+
+ void
+ waitImpl(const RecMutex& mutex) const
+ {
+ preWait();
+
+ RecMutex::LockState state;
+ mutex.unlock(state);
+
+ try
+ {
+ dowait();
+ mutex.lock(state);
+ }
+ catch(...)
+ {
+ mutex.lock(state);
+ throw;
+ }
+ }
+
+ void
+ waitImpl(const Mutex& mutex) const
+ {
+ preWait();
+
+ Mutex::LockState state;
+ mutex.unlock(state);
+
+ try
+ {
+ dowait();
+ mutex.lock(state);
+ }
+ catch(...)
+ {
+ mutex.lock(state);
+ throw;
+ }
+ }
+
+ bool
+ timedWaitImpl(const RecMutex& mutex, const Time& timeout) const
+ {
+ preWait();
+
+ RecMutex::LockState state;
+ mutex.unlock(state);
+
+ try
+ {
+ bool rc = timedDowait(timeout);
+ mutex.lock(state);
+ return rc;
+ }
+ catch(...)
+ {
+ mutex.lock(state);
+ throw;
+ }
+ }
+
+ bool
+ timedWaitImpl(const Mutex& mutex, const Time& timeout) const
+ {
+ preWait();
+
+ Mutex::LockState state;
+ mutex.unlock(state);
+
+ try
+ {
+ bool rc = timedDowait(timeout);
+ mutex.lock(state);
+ return rc;
+ }
+ catch(...)
+ {
+ mutex.lock(state);
+ throw;
+ }
+ }
+
+#else
+
+ template <typename M> void waitImpl(const M&) const;
+ template <typename M> bool timedWaitImpl(const M&, const Time&) const;
+
+#endif
+
+#ifdef _WIN32
+ void wake(bool);
+ void preWait() const;
+ void postWait(bool) const;
+ bool timedDowait(const Time&) const;
+ void dowait() const;
+
+ Mutex _internal;
+ Semaphore _gate;
+ Semaphore _queue;
+ mutable long _blocked;
+ mutable long _unblocked;
+ mutable long _toUnblock;
+#else
+ mutable pthread_cond_t _cond;
+#endif
+
+};
+
+#ifndef _WIN32
+template <typename M> inline void
+Cond::waitImpl(const M& mutex) const
+{
+ typedef typename M::LockState LockState;
+
+ LockState state;
+ mutex.unlock(state);
+ int rc = pthread_cond_wait(&_cond, state.mutex);
+ mutex.lock(state);
+
+ if(rc != 0)
+ {
+ throw ThreadSyscallException(strerror(rc), __FILE__, __LINE__);
+ }
+}
+
+template <typename M> inline bool
+Cond::timedWaitImpl(const M& mutex, const Time& timeout) const
+{
+ typedef typename M::LockState LockState;
+
+ LockState state;
+ mutex.unlock(state);
+
+ timeval tv = Time::now() + timeout;
+ timespec ts;
+ ts.tv_sec = tv.tv_sec;
+ ts.tv_nsec = tv.tv_usec*1000;
+ int rc = pthread_cond_timedwait(&_cond, state.mutex, &ts);
+ mutex.lock(state);
+
+ if(rc != 0)
+ {
+ //
+ // pthread_cond_timedwait returns ETIMEOUT in the event of a
+ // timeout.
+ //
+ if(rc != ETIMEDOUT)
+ {
+ throw ThreadSyscallException(strerror(rc), __FILE__, __LINE__);
+ }
+ return false;
+ }
+ return true;
+}
+#endif
+
+} // End namespace IceUtil
+
+#endif