summaryrefslogtreecommitdiff
path: root/cpp/src
diff options
context:
space:
mode:
authorMatthew Newhook <matthew@zeroc.com>2002-04-18 17:30:42 +0000
committerMatthew Newhook <matthew@zeroc.com>2002-04-18 17:30:42 +0000
commita44de0d2616828e72e49532b4bd771a233683f84 (patch)
treec297bc1133ec1473c081b23d62eb76adbc4a4872 /cpp/src
parentfix (diff)
downloadice-a44de0d2616828e72e49532b4bd771a233683f84.tar.bz2
ice-a44de0d2616828e72e49532b4bd771a233683f84.tar.xz
ice-a44de0d2616828e72e49532b4bd771a233683f84.zip
Added support for recursive write mutexes. Added read/write mutex upgrade.
Diffstat (limited to 'cpp/src')
-rw-r--r--cpp/src/IceUtil/.depend2
-rw-r--r--cpp/src/IceUtil/RWRecMutex.cpp71
-rw-r--r--cpp/src/IceUtil/Thread.cpp31
3 files changed, 69 insertions, 35 deletions
diff --git a/cpp/src/IceUtil/.depend b/cpp/src/IceUtil/.depend
index 9690231d38c..8ce3722f926 100644
--- a/cpp/src/IceUtil/.depend
+++ b/cpp/src/IceUtil/.depend
@@ -2,7 +2,7 @@ Exception.o: Exception.cpp ../../include/IceUtil/Exception.h ../../include/IceUt
Unicode.o: Unicode.cpp ../../include/IceUtil/Unicode.h ../../include/IceUtil/Config.h
UUID.o: UUID.cpp ../../include/IceUtil/UUID.h ../../include/IceUtil/Config.h
RecMutex.o: RecMutex.cpp ../../include/IceUtil/RecMutex.h ../../include/IceUtil/Config.h ../../include/IceUtil/Lock.h ../../include/IceUtil/Exception.h
-RWRecMutex.o: RWRecMutex.cpp ../../include/IceUtil/RWRecMutex.h ../../include/IceUtil/Mutex.h ../../include/IceUtil/Config.h ../../include/IceUtil/Exception.h ../../include/IceUtil/Lock.h ../../include/IceUtil/Cond.h
+RWRecMutex.o: RWRecMutex.cpp ../../include/IceUtil/RWRecMutex.h ../../include/IceUtil/Mutex.h ../../include/IceUtil/Config.h ../../include/IceUtil/Exception.h ../../include/IceUtil/Lock.h ../../include/IceUtil/Cond.h ../../include/IceUtil/Thread.h ../../include/IceUtil/Shared.h ../../include/IceUtil/Handle.h
Cond.o: Cond.cpp ../../include/IceUtil/Cond.h ../../include/IceUtil/Config.h ../../include/IceUtil/Exception.h
Thread.o: Thread.cpp ../../include/IceUtil/Thread.h ../../include/IceUtil/Shared.h ../../include/IceUtil/Config.h ../../include/IceUtil/Handle.h ../../include/IceUtil/Exception.h
OutputUtil.o: OutputUtil.cpp ../../include/IceUtil/OutputUtil.h ../../include/IceUtil/Config.h
diff --git a/cpp/src/IceUtil/RWRecMutex.cpp b/cpp/src/IceUtil/RWRecMutex.cpp
index dd87a1ae245..b664381df5c 100644
--- a/cpp/src/IceUtil/RWRecMutex.cpp
+++ b/cpp/src/IceUtil/RWRecMutex.cpp
@@ -1,8 +1,8 @@
// **********************************************************************
//
// Copyright (c) 2001
-// IONA Technologies, Inc.
-// Waltham, MA, USA
+// MutableRealms, Inc.
+// Huntsville, AL, USA
//
// All Rights Reserved
//
@@ -61,6 +61,16 @@ IceUtil::RWRecMutex::writeLock() const
Mutex::Lock lock(_mutex);
//
+ // If the mutex is already write locked by this writer then
+ // decrement _count, and return.
+ //
+ if (_count < 0 && _writerControl == ThreadControl())
+ {
+ --_count;
+ return;
+ }
+
+ //
// Wait for the lock to become available and increment the number
// of waiting writers.
//
@@ -91,6 +101,16 @@ IceUtil::RWRecMutex::tryWriteLock() const
Mutex::Lock lock(_mutex);
//
+ // If the mutex is already write locked by this writer then
+ // decrement _count, and return.
+ //
+ if (_count < 0 && _writerControl == ThreadControl())
+ {
+ --_count;
+ return;
+ }
+
+ //
// If there are readers or other writers then the call would block.
//
if (_count != 0)
@@ -124,7 +144,15 @@ IceUtil::RWRecMutex::unlock() const
//
// Writer called unlock
//
- _count = 0;
+ ++_count;
+
+ //
+ // If the write lock wasn't totally released we're done.
+ //
+ if (_count != 0)
+ {
+ return;
+ }
}
else
{
@@ -163,3 +191,40 @@ IceUtil::RWRecMutex::unlock() const
_readers.broadcast();
}
}
+
+void
+IceUtil::RWRecMutex::upgrade() const
+{
+ Mutex::Lock lock(_mutex);
+
+ //
+ // Reader called unlock
+ //
+ assert(_count > 0);
+ --_count;
+
+ //
+ // Wait to acquire the write lock.
+ //
+ while (_count != 0)
+ {
+ _waitingWriters++;
+ try
+ {
+ _writers.wait(lock);
+ }
+ catch(...)
+ {
+ --_waitingWriters;
+ throw;
+ }
+ _waitingWriters--;
+
+
+ }
+
+ //
+ // Got the lock, indicate it's held by a writer.
+ //
+ _count = -1;
+}
diff --git a/cpp/src/IceUtil/Thread.cpp b/cpp/src/IceUtil/Thread.cpp
index 717ccb66622..6648c22da1d 100644
--- a/cpp/src/IceUtil/Thread.cpp
+++ b/cpp/src/IceUtil/Thread.cpp
@@ -307,34 +307,3 @@ IceUtil::Thread::operator<(const Thread& rhs) const
#endif
-#ifdef never
-void ice_atomic_inc(ice_atomic_t *v)
-{
- __asm__ __volatile__(
- "lock ; incl %0"
- :"=m" (v->counter)
- :"m" (v->counter));
-}
-
-int ice_atomic_dec_and_test(ice_atomic_t *v)
-{
-
- unsigned char c;
- __asm__ __volatile__(
- "lock ; decl %0; sete %1"
- :"=m" (v->counter), "=qm" (c)
- :"m" (v->counter) : "memory");
- return c != 0;
-}
-
-int ice_atomic_exchange_add(int i, ice_atomic_t* v)
-{
- int tmp = i;
- __asm__ __volatile__(
- "lock ; xadd %0,(%2)"
- :"+r"(tmp), "=m"(v->counter)
- :"r"(v), "m"(v->counter)
- : "memory");
- return tmp + i;
-}
-#endif