summaryrefslogtreecommitdiff
path: root/cpp/src
diff options
context:
space:
mode:
authorMarc Laukien <marc@zeroc.com>2002-09-22 15:44:10 +0000
committerMarc Laukien <marc@zeroc.com>2002-09-22 15:44:10 +0000
commitf683ef370bcb987a9f96fc5da0793d71e3721d29 (patch)
treed0ef420f3cab12b8bab3563dbd71618adba704a3 /cpp/src
parentminor (diff)
downloadice-f683ef370bcb987a9f96fc5da0793d71e3721d29.tar.bz2
ice-f683ef370bcb987a9f96fc5da0793d71e3721d29.tar.xz
ice-f683ef370bcb987a9f96fc5da0793d71e3721d29.zip
thread fixes
Diffstat (limited to 'cpp/src')
-rw-r--r--cpp/src/Ice/Exception.cpp2
-rw-r--r--cpp/src/Ice/Network.cpp29
-rw-r--r--cpp/src/IceUtil/Base64.cpp542
-rw-r--r--cpp/src/IceUtil/Cond.cpp466
-rw-r--r--cpp/src/IceUtil/Exception.cpp274
-rw-r--r--cpp/src/IceUtil/InputUtil.cpp368
-rw-r--r--cpp/src/IceUtil/Makefile1
-rw-r--r--cpp/src/IceUtil/OutputUtil.cpp1142
-rw-r--r--cpp/src/IceUtil/RWRecMutex.cpp710
-rw-r--r--cpp/src/IceUtil/RecMutex.cpp336
-rw-r--r--cpp/src/IceUtil/Thread.cpp632
-rw-r--r--cpp/src/IceUtil/ThreadException.cpp100
-rw-r--r--cpp/src/IceUtil/Time.cpp284
-rw-r--r--cpp/src/IceUtil/UUID.cpp100
-rw-r--r--cpp/src/IceUtil/Unicode.cpp298
-rw-r--r--cpp/src/IceUtil/iceutil.dsp10
-rw-r--r--cpp/src/slice2cpp/Gen.cpp3
17 files changed, 2672 insertions, 2625 deletions
diff --git a/cpp/src/Ice/Exception.cpp b/cpp/src/Ice/Exception.cpp
index 50000547540..7d818ddee6f 100644
--- a/cpp/src/Ice/Exception.cpp
+++ b/cpp/src/Ice/Exception.cpp
@@ -156,7 +156,7 @@ Ice::SyscallException::ice_print(ostream& out) const
Exception::ice_print(out);
if(error != 0)
{
- out << ":\nsystem exception: " << errorToString(error);
+ out << ":\nsyscall exception: " << errorToString(error);
}
}
diff --git a/cpp/src/Ice/Network.cpp b/cpp/src/Ice/Network.cpp
index a93d113dcd6..aaf88639909 100644
--- a/cpp/src/Ice/Network.cpp
+++ b/cpp/src/Ice/Network.cpp
@@ -730,17 +730,24 @@ IceInternal::errorToString(int error)
{
if(error < WSABASEERR)
{
- LPVOID lpMsgBuf;
- FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
- NULL,
- error,
- MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
- (LPTSTR)&lpMsgBuf,
- 0,
- NULL);
- string result = (LPCTSTR)lpMsgBuf;
- LocalFree( lpMsgBuf );
- return result;
+ LPVOID lpMsgBuf = 0;
+ DWORD ok = FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
+ FORMAT_MESSAGE_FROM_SYSTEM |
+ FORMAT_MESSAGE_IGNORE_INSERTS,
+ NULL,
+ error,
+ MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
+ (LPTSTR)&lpMsgBuf,
+ 0,
+ NULL);
+ if(ok)
+ {
+ LPCTSTR msg = (LPCTSTR)lpMsgBuf;
+ assert(msg && strlen(msg) > 0);
+ string result = msg;
+ LocalFree(lpMsgBuf);
+ return result;
+ }
}
switch(error)
diff --git a/cpp/src/IceUtil/Base64.cpp b/cpp/src/IceUtil/Base64.cpp
index 00ef4d55a68..078448c8106 100644
--- a/cpp/src/IceUtil/Base64.cpp
+++ b/cpp/src/IceUtil/Base64.cpp
@@ -1,271 +1,271 @@
-// **********************************************************************
-//
-// Copyright (c) 2001
-// Mutable Realms, Inc.
-// Huntsville, AL, USA
-//
-// All Rights Reserved
-//
-// **********************************************************************
-
-#include <IceUtil/Base64.h>
-#include <iostream>
-
-using namespace std;
-
-string
-IceUtil::Base64::encode(const vector<char>& plainSeq)
-{
- string retval;
-
- if(plainSeq.size() == 0)
- {
- return retval;
- }
-
- // Reserve enough space for the returned base64 string
- unsigned long base64Bytes = (((plainSeq.size() * 4) / 3) + 1);
- unsigned long newlineBytes = (((base64Bytes * 2) / 76) + 1);
- unsigned long totalBytes = base64Bytes + newlineBytes;
-
- retval.reserve(totalBytes);
-
- unsigned char by1 = 0;
- unsigned char by2 = 0;
- unsigned char by3 = 0;
- unsigned char by4 = 0;
- unsigned char by5 = 0;
- unsigned char by6 = 0;
- unsigned char by7 = 0;
-
- for(unsigned long i = 0; i < plainSeq.size(); i += 3)
- {
- by1 = plainSeq[i];
- by2 = 0;
- by3 = 0;
-
- if((i + 1) < plainSeq.size())
- {
- by2 = plainSeq[i+1];
- }
-
- if((i + 2) < plainSeq.size())
- {
- by3 = plainSeq[i+2];
- }
-
- by4 = by1 >> 2;
- by5 = ((by1 & 0x3) << 4) | (by2 >> 4);
- by6 = ((by2 & 0xf) << 2) | (by3 >> 6);
- by7 = by3 & 0x3f;
-
- retval += encode(by4);
- retval += encode(by5);
-
- if((i + 1) < plainSeq.size())
- {
- retval += encode(by6);
- }
- else
- {
- retval += "=";
- }
-
- if((i + 2) < plainSeq.size())
- {
- retval += encode(by7);
- }
- else
- {
- retval += "=";
- }
- }
-
- string outString;
- outString.reserve(totalBytes);
- string::iterator iter = retval.begin();
-
- while((retval.end() - iter) > 76)
- {
- copy(iter, iter+76, back_inserter(outString));
- outString += "\r\n";
- iter += 76;
- }
-
- copy(iter, retval.end(), back_inserter(outString));
-
- return outString;
-}
-
-vector<char>
-IceUtil::Base64::decode(const string& str)
-{
- string newStr;
-
- newStr.reserve(str.length());
-
- for(unsigned long j = 0; j < str.length(); j++)
- {
- if(isBase64(str[j]))
- {
- newStr += str[j];
- }
- }
-
- vector<char> retval;
-
- if(newStr.length() == 0)
- {
- return retval;
- }
-
- // Note: This is how we were previously computing the size of the return
- // sequence. The method below is more efficient (and correct).
- // unsigned long lines = str.size() / 78;
- // unsigned long totalBytes = (lines * 76) + (((str.size() - (lines * 78)) * 3) / 4);
-
- // Figure out how long the final sequence is going to be.
- unsigned long totalBytes = (newStr.size() * 3 / 4) + 1;
-
- retval.reserve(totalBytes);
-
- unsigned char by1 = 0;
- unsigned char by2 = 0;
- unsigned char by3 = 0;
- unsigned char by4 = 0;
-
- char c1, c2, c3, c4;
-
- for(unsigned long i = 0; i < newStr.length(); i += 4)
- {
- c1 = 'A';
- c2 = 'A';
- c3 = 'A';
- c4 = 'A';
-
- c1 = newStr[i];
-
- if((i + 1) < newStr.length())
- {
- c2 = newStr[i + 1];
- }
-
- if((i + 2) < newStr.length())
- {
- c3 = newStr[i + 2];
- }
-
- if((i + 3) < newStr.length())
- {
- c4 = newStr[i + 3];
- }
-
- by1 = decode(c1);
- by2 = decode(c2);
- by3 = decode(c3);
- by4 = decode(c4);
-
- retval.push_back((by1 << 2) | (by2 >> 4));
-
- if(c3 != '=')
- {
- retval.push_back(((by2 & 0xf) << 4) | (by3 >> 2));
- }
-
- if(c4 != '=')
- {
- retval.push_back(((by3 & 0x3) << 6) | by4);
- }
- }
-
- return retval;
-}
-
-char
-IceUtil::Base64::encode(unsigned char uc)
-{
- if(uc < 26)
- {
- return 'A' + uc;
- }
-
- if(uc < 52)
- {
- return 'a' + (uc - 26);
- }
-
- if(uc < 62)
- {
- return '0' + (uc - 52);
- }
-
- if(uc == 62)
- {
- return '+';
- }
-
- return '/';
-}
-
-unsigned char
-IceUtil::Base64::decode(char c)
-{
- if(c >= 'A' && c <= 'Z')
- {
- return c - 'A';
- }
-
- if(c >= 'a' && c <= 'z')
- {
- return c - 'a' + 26;
- }
-
- if(c >= '0' && c <= '9')
- {
- return c - '0' + 52;
- }
-
- if(c == '+')
- {
- return 62;
- }
-
- return 63;
-}
-
-
-bool
-IceUtil::Base64::isBase64(char c)
-{
- if(c >= 'A' && c <= 'Z')
- {
- return true;
- }
-
- if(c >= 'a' && c <= 'z')
- {
- return true;
- }
-
- if(c >= '0' && c <= '9')
- {
- return true;
- }
-
- if(c == '+')
- {
- return true;
- }
-
- if(c == '/')
- {
- return true;
- }
-
- if(c == '=')
- {
- return true;
- }
-
- return false;
-}
+// **********************************************************************
+//
+// Copyright (c) 2001
+// Mutable Realms, Inc.
+// Huntsville, AL, USA
+//
+// All Rights Reserved
+//
+// **********************************************************************
+
+#include <IceUtil/Base64.h>
+#include <iostream>
+
+using namespace std;
+
+string
+IceUtil::Base64::encode(const vector<char>& plainSeq)
+{
+ string retval;
+
+ if(plainSeq.size() == 0)
+ {
+ return retval;
+ }
+
+ // Reserve enough space for the returned base64 string
+ unsigned long base64Bytes = (((plainSeq.size() * 4) / 3) + 1);
+ unsigned long newlineBytes = (((base64Bytes * 2) / 76) + 1);
+ unsigned long totalBytes = base64Bytes + newlineBytes;
+
+ retval.reserve(totalBytes);
+
+ unsigned char by1 = 0;
+ unsigned char by2 = 0;
+ unsigned char by3 = 0;
+ unsigned char by4 = 0;
+ unsigned char by5 = 0;
+ unsigned char by6 = 0;
+ unsigned char by7 = 0;
+
+ for(unsigned long i = 0; i < plainSeq.size(); i += 3)
+ {
+ by1 = plainSeq[i];
+ by2 = 0;
+ by3 = 0;
+
+ if((i + 1) < plainSeq.size())
+ {
+ by2 = plainSeq[i+1];
+ }
+
+ if((i + 2) < plainSeq.size())
+ {
+ by3 = plainSeq[i+2];
+ }
+
+ by4 = by1 >> 2;
+ by5 = ((by1 & 0x3) << 4) | (by2 >> 4);
+ by6 = ((by2 & 0xf) << 2) | (by3 >> 6);
+ by7 = by3 & 0x3f;
+
+ retval += encode(by4);
+ retval += encode(by5);
+
+ if((i + 1) < plainSeq.size())
+ {
+ retval += encode(by6);
+ }
+ else
+ {
+ retval += "=";
+ }
+
+ if((i + 2) < plainSeq.size())
+ {
+ retval += encode(by7);
+ }
+ else
+ {
+ retval += "=";
+ }
+ }
+
+ string outString;
+ outString.reserve(totalBytes);
+ string::iterator iter = retval.begin();
+
+ while((retval.end() - iter) > 76)
+ {
+ copy(iter, iter+76, back_inserter(outString));
+ outString += "\r\n";
+ iter += 76;
+ }
+
+ copy(iter, retval.end(), back_inserter(outString));
+
+ return outString;
+}
+
+vector<char>
+IceUtil::Base64::decode(const string& str)
+{
+ string newStr;
+
+ newStr.reserve(str.length());
+
+ for(unsigned long j = 0; j < str.length(); j++)
+ {
+ if(isBase64(str[j]))
+ {
+ newStr += str[j];
+ }
+ }
+
+ vector<char> retval;
+
+ if(newStr.length() == 0)
+ {
+ return retval;
+ }
+
+ // Note: This is how we were previously computing the size of the return
+ // sequence. The method below is more efficient (and correct).
+ // unsigned long lines = str.size() / 78;
+ // unsigned long totalBytes = (lines * 76) + (((str.size() - (lines * 78)) * 3) / 4);
+
+ // Figure out how long the final sequence is going to be.
+ unsigned long totalBytes = (newStr.size() * 3 / 4) + 1;
+
+ retval.reserve(totalBytes);
+
+ unsigned char by1 = 0;
+ unsigned char by2 = 0;
+ unsigned char by3 = 0;
+ unsigned char by4 = 0;
+
+ char c1, c2, c3, c4;
+
+ for(unsigned long i = 0; i < newStr.length(); i += 4)
+ {
+ c1 = 'A';
+ c2 = 'A';
+ c3 = 'A';
+ c4 = 'A';
+
+ c1 = newStr[i];
+
+ if((i + 1) < newStr.length())
+ {
+ c2 = newStr[i + 1];
+ }
+
+ if((i + 2) < newStr.length())
+ {
+ c3 = newStr[i + 2];
+ }
+
+ if((i + 3) < newStr.length())
+ {
+ c4 = newStr[i + 3];
+ }
+
+ by1 = decode(c1);
+ by2 = decode(c2);
+ by3 = decode(c3);
+ by4 = decode(c4);
+
+ retval.push_back((by1 << 2) | (by2 >> 4));
+
+ if(c3 != '=')
+ {
+ retval.push_back(((by2 & 0xf) << 4) | (by3 >> 2));
+ }
+
+ if(c4 != '=')
+ {
+ retval.push_back(((by3 & 0x3) << 6) | by4);
+ }
+ }
+
+ return retval;
+}
+
+char
+IceUtil::Base64::encode(unsigned char uc)
+{
+ if(uc < 26)
+ {
+ return 'A' + uc;
+ }
+
+ if(uc < 52)
+ {
+ return 'a' + (uc - 26);
+ }
+
+ if(uc < 62)
+ {
+ return '0' + (uc - 52);
+ }
+
+ if(uc == 62)
+ {
+ return '+';
+ }
+
+ return '/';
+}
+
+unsigned char
+IceUtil::Base64::decode(char c)
+{
+ if(c >= 'A' && c <= 'Z')
+ {
+ return c - 'A';
+ }
+
+ if(c >= 'a' && c <= 'z')
+ {
+ return c - 'a' + 26;
+ }
+
+ if(c >= '0' && c <= '9')
+ {
+ return c - '0' + 52;
+ }
+
+ if(c == '+')
+ {
+ return 62;
+ }
+
+ return 63;
+}
+
+
+bool
+IceUtil::Base64::isBase64(char c)
+{
+ if(c >= 'A' && c <= 'Z')
+ {
+ return true;
+ }
+
+ if(c >= 'a' && c <= 'z')
+ {
+ return true;
+ }
+
+ if(c >= '0' && c <= '9')
+ {
+ return true;
+ }
+
+ if(c == '+')
+ {
+ return true;
+ }
+
+ if(c == '/')
+ {
+ return true;
+ }
+
+ if(c == '=')
+ {
+ return true;
+ }
+
+ return false;
+}
diff --git a/cpp/src/IceUtil/Cond.cpp b/cpp/src/IceUtil/Cond.cpp
index 52e69510be3..cffa290dc4a 100644
--- a/cpp/src/IceUtil/Cond.cpp
+++ b/cpp/src/IceUtil/Cond.cpp
@@ -1,233 +1,233 @@
-// **********************************************************************
-//
-// Copyright (c) 2001
-// Mutable Realms, Inc.
-// Huntsville, AL, USA
-//
-// All Rights Reserved
-//
-// **********************************************************************
-
-#include <IceUtil/Cond.h>
-
-#ifndef _WIN32
-# include <sys/time.h>
-#endif
-
-#ifdef _WIN32
-
-IceUtil::Semaphore::Semaphore(long initial)
-{
- _sem = CreateSemaphore(0, initial, 0x7fffffff, 0);
- if(_sem == INVALID_HANDLE_VALUE)
- {
- throw SyscallException(SyscallException::errorToString(GetLastError()), __FILE__, __LINE__);
- }
-}
-
-IceUtil::Semaphore::~Semaphore()
-{
- CloseHandle(_sem);
-}
-
-void
-IceUtil::Semaphore::wait() const
-{
- int rc = WaitForSingleObject(_sem, INFINITE);
- if(rc != WAIT_OBJECT_0)
- {
- throw SyscallException(SyscallException::errorToString(GetLastError()), __FILE__, __LINE__);
- }
-}
-
-bool
-IceUtil::Semaphore::timedWait(const Time& timeout) const
-{
- timeval tv = timeout;
- long msec = (tv.tv_sec * 1000) + (tv.tv_usec / 1000);
-
- int rc = WaitForSingleObject(_sem, msec);
- if(rc != WAIT_TIMEOUT && rc != WAIT_OBJECT_0)
- {
- throw SyscallException(SyscallException::errorToString(GetLastError()), __FILE__, __LINE__);
- }
- return rc != WAIT_TIMEOUT;
-}
-
-void
-IceUtil::Semaphore::post(int count) const
-{
- int rc = ReleaseSemaphore(_sem, count, 0);
- if(rc == 0)
- {
- throw SyscallException(SyscallException::errorToString(GetLastError()), __FILE__, __LINE__);
- }
-}
-
-IceUtil::Cond::Cond() :
- _gate(1),
- _blocked(0),
- _unblocked(0),
- _toUnblock(0)
-{
-}
-
-IceUtil::Cond::~Cond()
-{
-}
-
-void
-IceUtil::Cond::signal()
-{
- wake(false);
-}
-
-void
-IceUtil::Cond::broadcast()
-{
- wake(true);
-}
-
-void
-IceUtil::Cond::wake(bool broadcast)
-{
- //
- // Lock gate & mutex.
- //
- _gate.wait();
- _internal.lock();
-
- if(_unblocked != 0)
- {
- _blocked -= _unblocked;
- _unblocked = 0;
- }
-
- if(_blocked > 0)
- {
- //
- // Unblock some number of waiters.
- //
- _toUnblock = (broadcast) ? _blocked : 1;
- _internal.unlock();
- _queue.post();
- }
- else
- {
- //
- // Otherwise no blocked waiters, release gate & mutex.
- //
- _gate.post();
- _internal.unlock();
- }
-}
-
-void
-IceUtil::Cond::preWait() const
-{
- _gate.wait();
- _blocked++;
- _gate.post();
-}
-
-void
-IceUtil::Cond::postWait(bool timedOut) const
-{
- _internal.lock();
- _unblocked++;
-
- if(_toUnblock != 0)
- {
- bool last = --_toUnblock == 0;
- _internal.unlock();
-
- if(timedOut)
- {
- _queue.wait();
- }
-
- if(last)
- {
- _gate.post();
- }
- else
- {
- _queue.post();
- }
- }
- else
- {
- _internal.unlock();
- }
-}
-
-void
-IceUtil::Cond::dowait() const
-{
- try
- {
- _queue.wait();
- postWait(false);
- }
- catch(...)
- {
- postWait(false);
- throw;
- }
-}
-
-bool
-IceUtil::Cond::timedDowait(const Time& timeout) const
-{
- try
- {
- bool rc = _queue.timedWait(timeout);
- postWait(!rc);
- return rc;
- }
- catch(...)
- {
- postWait(false);
- throw;
- }
-}
-
-#else
-
-IceUtil::Cond::Cond()
-{
- int rc = pthread_cond_init(&_cond, 0);
- if(rc != 0)
- {
- throw SyscallException(strerror(rc), __FILE__, __LINE__);
- }
-}
-
-IceUtil::Cond::~Cond()
-{
- int rc = 0;
- rc = pthread_cond_destroy(&_cond);
- assert(rc == 0);
-}
-
-void
-IceUtil::Cond::signal()
-{
- int rc = pthread_cond_signal(&_cond);
- if(rc != 0)
- {
- throw SyscallException(strerror(rc), __FILE__, __LINE__);
- }
-}
-
-void
-IceUtil::Cond::broadcast()
-{
- int rc = pthread_cond_broadcast(&_cond);
- if(rc != 0)
- {
- throw SyscallException(strerror(rc), __FILE__, __LINE__);
- }
-}
-
-#endif
+// **********************************************************************
+//
+// Copyright (c) 2001
+// Mutable Realms, Inc.
+// Huntsville, AL, USA
+//
+// All Rights Reserved
+//
+// **********************************************************************
+
+#include <IceUtil/Cond.h>
+
+#ifndef _WIN32
+# include <sys/time.h>
+#endif
+
+#ifdef _WIN32
+
+IceUtil::Semaphore::Semaphore(long initial)
+{
+ _sem = CreateSemaphore(0, initial, 0x7fffffff, 0);
+ if(_sem == INVALID_HANDLE_VALUE)
+ {
+ throw ThreadSyscallException(__FILE__, __LINE__);
+ }
+}
+
+IceUtil::Semaphore::~Semaphore()
+{
+ CloseHandle(_sem);
+}
+
+void
+IceUtil::Semaphore::wait() const
+{
+ int rc = WaitForSingleObject(_sem, INFINITE);
+ if(rc != WAIT_OBJECT_0)
+ {
+ throw ThreadSyscallException(__FILE__, __LINE__);
+ }
+}
+
+bool
+IceUtil::Semaphore::timedWait(const Time& timeout) const
+{
+ timeval tv = timeout;
+ long msec = (tv.tv_sec * 1000) + (tv.tv_usec / 1000);
+
+ int rc = WaitForSingleObject(_sem, msec);
+ if(rc != WAIT_TIMEOUT && rc != WAIT_OBJECT_0)
+ {
+ throw ThreadSyscallException(__FILE__, __LINE__);
+ }
+ return rc != WAIT_TIMEOUT;
+}
+
+void
+IceUtil::Semaphore::post(int count) const
+{
+ int rc = ReleaseSemaphore(_sem, count, 0);
+ if(rc == 0)
+ {
+ throw ThreadSyscallException(__FILE__, __LINE__);
+ }
+}
+
+IceUtil::Cond::Cond() :
+ _gate(1),
+ _blocked(0),
+ _unblocked(0),
+ _toUnblock(0)
+{
+}
+
+IceUtil::Cond::~Cond()
+{
+}
+
+void
+IceUtil::Cond::signal()
+{
+ wake(false);
+}
+
+void
+IceUtil::Cond::broadcast()
+{
+ wake(true);
+}
+
+void
+IceUtil::Cond::wake(bool broadcast)
+{
+ //
+ // Lock gate & mutex.
+ //
+ _gate.wait();
+ _internal.lock();
+
+ if(_unblocked != 0)
+ {
+ _blocked -= _unblocked;
+ _unblocked = 0;
+ }
+
+ if(_blocked > 0)
+ {
+ //
+ // Unblock some number of waiters.
+ //
+ _toUnblock = (broadcast) ? _blocked : 1;
+ _internal.unlock();
+ _queue.post();
+ }
+ else
+ {
+ //
+ // Otherwise no blocked waiters, release gate & mutex.
+ //
+ _gate.post();
+ _internal.unlock();
+ }
+}
+
+void
+IceUtil::Cond::preWait() const
+{
+ _gate.wait();
+ _blocked++;
+ _gate.post();
+}
+
+void
+IceUtil::Cond::postWait(bool timedOut) const
+{
+ _internal.lock();
+ _unblocked++;
+
+ if(_toUnblock != 0)
+ {
+ bool last = --_toUnblock == 0;
+ _internal.unlock();
+
+ if(timedOut)
+ {
+ _queue.wait();
+ }
+
+ if(last)
+ {
+ _gate.post();
+ }
+ else
+ {
+ _queue.post();
+ }
+ }
+ else
+ {
+ _internal.unlock();
+ }
+}
+
+void
+IceUtil::Cond::dowait() const
+{
+ try
+ {
+ _queue.wait();
+ postWait(false);
+ }
+ catch(...)
+ {
+ postWait(false);
+ throw;
+ }
+}
+
+bool
+IceUtil::Cond::timedDowait(const Time& timeout) const
+{
+ try
+ {
+ bool rc = _queue.timedWait(timeout);
+ postWait(!rc);
+ return rc;
+ }
+ catch(...)
+ {
+ postWait(false);
+ throw;
+ }
+}
+
+#else
+
+IceUtil::Cond::Cond()
+{
+ int rc = pthread_cond_init(&_cond, 0);
+ if(rc != 0)
+ {
+ throw ThreadSyscallException(strerror(rc), __FILE__, __LINE__);
+ }
+}
+
+IceUtil::Cond::~Cond()
+{
+ int rc = 0;
+ rc = pthread_cond_destroy(&_cond);
+ assert(rc == 0);
+}
+
+void
+IceUtil::Cond::signal()
+{
+ int rc = pthread_cond_signal(&_cond);
+ if(rc != 0)
+ {
+ throw ThreadSyscallException(strerror(rc), __FILE__, __LINE__);
+ }
+}
+
+void
+IceUtil::Cond::broadcast()
+{
+ int rc = pthread_cond_broadcast(&_cond);
+ if(rc != 0)
+ {
+ throw ThreadSyscallException(strerror(rc), __FILE__, __LINE__);
+ }
+}
+
+#endif
diff --git a/cpp/src/IceUtil/Exception.cpp b/cpp/src/IceUtil/Exception.cpp
index 9beb8c8a699..f239e8ba53b 100644
--- a/cpp/src/IceUtil/Exception.cpp
+++ b/cpp/src/IceUtil/Exception.cpp
@@ -1,175 +1,99 @@
-// **********************************************************************
-//
-// Copyright (c) 2001
-// Mutable Realms, Inc.
-// Huntsville, AL, USA
-//
-// All Rights Reserved
-//
-// **********************************************************************
-
-#include <IceUtil/Exception.h>
-
-using namespace std;
-
-IceUtil::Exception::Exception() :
- _file(0),
- _line(0)
-{
-}
-
-IceUtil::Exception::Exception(const char* file, int line) :
- _file(file),
- _line(line)
-{
-}
-
-IceUtil::Exception::~Exception()
-{
-}
-
-string
-IceUtil::Exception::ice_name() const
-{
- static const string name("IceUtil::Exception");
- return name;
-}
-
-void
-IceUtil::Exception::ice_print(ostream& out) const
-{
- if(_file && _line > 0)
- {
- out << _file << ':' << _line << ": ";
- }
- out << ice_name();
-}
-
-IceUtil::Exception*
-IceUtil::Exception::ice_clone() const
-{
- return new Exception(*this);
-}
-
-void
-IceUtil::Exception::ice_throw() const
-{
- throw *this;
-}
-
-const char*
-IceUtil::Exception::ice_file() const
-{
- return _file;
-}
-
-int
-IceUtil::Exception::ice_line() const
-{
- return _line;
-}
-
-ostream&
-IceUtil::operator<<(ostream& out, const IceUtil::Exception& ex)
-{
- ex.ice_print(out);
- return out;
-}
-
-IceUtil::NullHandleException::NullHandleException(const char* file, int line) :
- Exception(file, line)
-{
-}
-
-string
-IceUtil::NullHandleException::ice_name() const
-{
- static const string name("IceUtil::NullHandleException");
- return name;
-}
-
-IceUtil::Exception*
-IceUtil::NullHandleException::ice_clone() const
-{
- return new NullHandleException(*this);
-}
-
-void
-IceUtil::NullHandleException::ice_throw() const
-{
- throw *this;
-}
-
-IceUtil::SyscallException::SyscallException(const string& error, const char* file, int line) :
- Exception(file, line),
- _error(error)
-{
-}
-
-string
-IceUtil::SyscallException::ice_name() const
-{
- return "IceUtil::SyscallException";
-}
-
-void
-IceUtil::SyscallException::ice_print(ostream& os) const
-{
- os << _error << ": ";
- Exception::ice_print(os);
-}
-
-
-IceUtil::Exception*
-IceUtil::SyscallException::ice_clone() const
-{
- return new SyscallException(*this);
-}
-
-void
-IceUtil::SyscallException::ice_throw() const
-{
- throw *this;
-}
-
-#ifdef _WIN32
-string
-IceUtil::SyscallException::errorToString(DWORD error)
-{
- LPVOID lpMsgBuf;
- FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
- NULL,
- error,
- MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
- (LPTSTR)&lpMsgBuf,
- 0,
- NULL);
- string result = (LPCTSTR)lpMsgBuf;
- LocalFree( lpMsgBuf );
- return result;
-}
-#endif
-
-IceUtil::LockedException::LockedException(const char* file, int line) :
- Exception(file, line)
-{
-}
-
-string
-IceUtil::LockedException::ice_name() const
-{
- static const string name = "IceUtil::LockedException";
- return name;
-}
-
-IceUtil::Exception*
-IceUtil::LockedException::ice_clone() const
-{
- return new LockedException(*this);
-}
-
-void
-IceUtil::LockedException::ice_throw() const
-{
- throw *this;
-}
+// **********************************************************************
+//
+// Copyright (c) 2001
+// Mutable Realms, Inc.
+// Huntsville, AL, USA
+//
+// All Rights Reserved
+//
+// **********************************************************************
+
+#include <IceUtil/Exception.h>
+
+using namespace std;
+
+IceUtil::Exception::Exception() :
+ _file(0),
+ _line(0)
+{
+}
+
+IceUtil::Exception::Exception(const char* file, int line) :
+ _file(file),
+ _line(line)
+{
+}
+
+IceUtil::Exception::~Exception()
+{
+}
+
+string
+IceUtil::Exception::ice_name() const
+{
+ return "IceUtil::Exception";
+}
+
+void
+IceUtil::Exception::ice_print(ostream& out) const
+{
+ if(_file && _line > 0)
+ {
+ out << _file << ':' << _line << ": ";
+ }
+ out << ice_name();
+}
+
+IceUtil::Exception*
+IceUtil::Exception::ice_clone() const
+{
+ return new Exception(*this);
+}
+
+void
+IceUtil::Exception::ice_throw() const
+{
+ throw *this;
+}
+
+const char*
+IceUtil::Exception::ice_file() const
+{
+ return _file;
+}
+
+int
+IceUtil::Exception::ice_line() const
+{
+ return _line;
+}
+
+ostream&
+IceUtil::operator<<(ostream& out, const IceUtil::Exception& ex)
+{
+ ex.ice_print(out);
+ return out;
+}
+
+IceUtil::NullHandleException::NullHandleException(const char* file, int line) :
+ Exception(file, line)
+{
+}
+
+string
+IceUtil::NullHandleException::ice_name() const
+{
+ return "IceUtil::NullHandleException";
+}
+
+IceUtil::Exception*
+IceUtil::NullHandleException::ice_clone() const
+{
+ return new NullHandleException(*this);
+}
+
+void
+IceUtil::NullHandleException::ice_throw() const
+{
+ throw *this;
+}
diff --git a/cpp/src/IceUtil/InputUtil.cpp b/cpp/src/IceUtil/InputUtil.cpp
index 322dc195955..32959cb3fca 100644
--- a/cpp/src/IceUtil/InputUtil.cpp
+++ b/cpp/src/IceUtil/InputUtil.cpp
@@ -1,184 +1,184 @@
-// **********************************************************************
-//
-// Copyright (c) 2001
-// Mutable Realms, Inc.
-// Huntsville, AL, USA
-//
-// All Rights Reserved
-//
-// **********************************************************************
-
-#include <IceUtil/InputUtil.h>
-#include <stdlib.h>
-#include <errno.h>
-
-using namespace std;
-
-namespace IceUtil
-{
-
-//
-// strToInt64 emulates strtoll() for Windows
-//
-
-Int64
-strToInt64(const char* s, char** endptr, int base)
-{
-#if defined(_WIN32)
- //
- // Assume nothing will be there to convert for now
- //
- if(endptr)
- {
- *endptr = const_cast<char *>(s);
- }
-
- //
- // Skip leading whitespace
- //
- while(*s && isspace(*s))
- {
- ++s;
- }
-
- //
- // Check for sign
- //
- int sign = 1;
- if(*s == '+')
- {
- ++s;
- }
- else if(*s == '-')
- {
- sign = -1;
- ++s;
- }
-
- //
- // Check that base is valid
- //
- if(base == 0)
- {
- if(*s == '0')
- {
- base = 8;
- if(*++s == 'x' || *s == 'X')
- {
- base = 16;
- ++s;
- }
- }
- else
- {
- base = 10;
- }
- }
- else if(base < 2 || base > 36)
- {
- errno = EINVAL;
- return 0;
- }
-
- //
- // Check that we have something left to parse
- //
- if(*s == '/0')
- {
- return 0;
- }
-
- static const string allDigits = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
- const string validDigits(allDigits.begin(), allDigits.begin() + base);
-
- //
- // Table to convert ASCII digits/letters into their value (100 for unused slots)
- //
- static const char digitVal[] =
- {
- 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, // '0' - '9'
- 100, 100, 100, 100, 100, 100, 100, // punctuation
- 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, // 'A' - 'J'
- 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, // 'K' - 'T'
- 30, 31, 32, 33, 34, 35 // 'U' - 'Z'
- };
-
- Int64 result = 0;
- bool overflow = false;
- while(*s && validDigits.find_first_of(toupper(*s)) != validDigits.npos)
- {
- if(!overflow)
- {
- int digit = digitVal[toupper(*s) - '0'];
- assert(digit != 100);
- if(result < Int64Max / base)
- {
- result *= base;
- result += digit;
- }
- else if((digit <= Int64Max % base) || (sign == -1 && digit == Int64Max % base + 1))
- {
- result *= base;
- result += digit;
- }
- else
- {
- overflow = true;
- result = sign == -1 ? Int64Min : Int64Max;
- }
- }
- ++s;
- }
-
- if(overflow)
- {
- errno = ERANGE;
- }
- else
- {
- result *= sign;
- }
-
- if(endptr)
- {
- *endptr = const_cast<char *>(s);
- }
-
- return result;
-
-#else
- return strtoll(s, endptr, base);
-#endif
-}
-
-bool
-stringToInt64(const string& stringToParse, Int64& result, string::size_type& pos)
-{
- string::const_iterator i = stringToParse.begin();
- while(i != stringToParse.end() && isspace(*i))
- {
- ++i;
- }
- if(i == stringToParse.end()) // String empty or nothing but whitespace
- {
- result = 0;
- pos = string::npos;
- return false;
- }
- string::const_reverse_iterator j = stringToParse.rbegin();
- while(isspace(*j))
- {
- ++j;
- } // j now points at last non-whitespace char
-
- string nonWhite(i, j.base()); // nonWhite has trailing whitespace stripped
-
- errno = 0;
- const char* startp = nonWhite.c_str();
- char* endp;
- result = strToInt64(startp, &endp, 0);
- pos = *endp == '\0' ? string::npos : (i - stringToParse.begin()) + (endp - startp);
- return startp != endp && errno != ERANGE && errno != EINVAL;
-}
-
-}
+// **********************************************************************
+//
+// Copyright (c) 2001
+// Mutable Realms, Inc.
+// Huntsville, AL, USA
+//
+// All Rights Reserved
+//
+// **********************************************************************
+
+#include <IceUtil/InputUtil.h>
+#include <stdlib.h>
+#include <errno.h>
+
+using namespace std;
+
+namespace IceUtil
+{
+
+//
+// strToInt64 emulates strtoll() for Windows
+//
+
+Int64
+strToInt64(const char* s, char** endptr, int base)
+{
+#if defined(_WIN32)
+ //
+ // Assume nothing will be there to convert for now
+ //
+ if(endptr)
+ {
+ *endptr = const_cast<char *>(s);
+ }
+
+ //
+ // Skip leading whitespace
+ //
+ while(*s && isspace(*s))
+ {
+ ++s;
+ }
+
+ //
+ // Check for sign
+ //
+ int sign = 1;
+ if(*s == '+')
+ {
+ ++s;
+ }
+ else if(*s == '-')
+ {
+ sign = -1;
+ ++s;
+ }
+
+ //
+ // Check that base is valid
+ //
+ if(base == 0)
+ {
+ if(*s == '0')
+ {
+ base = 8;
+ if(*++s == 'x' || *s == 'X')
+ {
+ base = 16;
+ ++s;
+ }
+ }
+ else
+ {
+ base = 10;
+ }
+ }
+ else if(base < 2 || base > 36)
+ {
+ errno = EINVAL;
+ return 0;
+ }
+
+ //
+ // Check that we have something left to parse
+ //
+ if(*s == '/0')
+ {
+ return 0;
+ }
+
+ static const string allDigits = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
+ const string validDigits(allDigits.begin(), allDigits.begin() + base);
+
+ //
+ // Table to convert ASCII digits/letters into their value (100 for unused slots)
+ //
+ static const char digitVal[] =
+ {
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, // '0' - '9'
+ 100, 100, 100, 100, 100, 100, 100, // punctuation
+ 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, // 'A' - 'J'
+ 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, // 'K' - 'T'
+ 30, 31, 32, 33, 34, 35 // 'U' - 'Z'
+ };
+
+ Int64 result = 0;
+ bool overflow = false;
+ while(*s && validDigits.find_first_of(toupper(*s)) != validDigits.npos)
+ {
+ if(!overflow)
+ {
+ int digit = digitVal[toupper(*s) - '0'];
+ assert(digit != 100);
+ if(result < Int64Max / base)
+ {
+ result *= base;
+ result += digit;
+ }
+ else if((digit <= Int64Max % base) || (sign == -1 && digit == Int64Max % base + 1))
+ {
+ result *= base;
+ result += digit;
+ }
+ else
+ {
+ overflow = true;
+ result = sign == -1 ? Int64Min : Int64Max;
+ }
+ }
+ ++s;
+ }
+
+ if(overflow)
+ {
+ errno = ERANGE;
+ }
+ else
+ {
+ result *= sign;
+ }
+
+ if(endptr)
+ {
+ *endptr = const_cast<char *>(s);
+ }
+
+ return result;
+
+#else
+ return strtoll(s, endptr, base);
+#endif
+}
+
+bool
+stringToInt64(const string& stringToParse, Int64& result, string::size_type& pos)
+{
+ string::const_iterator i = stringToParse.begin();
+ while(i != stringToParse.end() && isspace(*i))
+ {
+ ++i;
+ }
+ if(i == stringToParse.end()) // String empty or nothing but whitespace
+ {
+ result = 0;
+ pos = string::npos;
+ return false;
+ }
+ string::const_reverse_iterator j = stringToParse.rbegin();
+ while(isspace(*j))
+ {
+ ++j;
+ } // j now points at last non-whitespace char
+
+ string nonWhite(i, j.base()); // nonWhite has trailing whitespace stripped
+
+ errno = 0;
+ const char* startp = nonWhite.c_str();
+ char* endp;
+ result = strToInt64(startp, &endp, 0);
+ pos = *endp == '\0' ? string::npos : (i - stringToParse.begin()) + (endp - startp);
+ return startp != endp && errno != ERANGE && errno != EINVAL;
+}
+
+}
diff --git a/cpp/src/IceUtil/Makefile b/cpp/src/IceUtil/Makefile
index 752f642c614..cf1298fa1bc 100644
--- a/cpp/src/IceUtil/Makefile
+++ b/cpp/src/IceUtil/Makefile
@@ -24,6 +24,7 @@ OBJS = Exception.o \
RWRecMutex.o \
Cond.o \
Thread.o \
+ ThreadException.o \
Time.o \
InputUtil.o \
OutputUtil.o \
diff --git a/cpp/src/IceUtil/OutputUtil.cpp b/cpp/src/IceUtil/OutputUtil.cpp
index b29ecd1a9be..ddb7e8d0a42 100644
--- a/cpp/src/IceUtil/OutputUtil.cpp
+++ b/cpp/src/IceUtil/OutputUtil.cpp
@@ -1,571 +1,571 @@
-// **********************************************************************
-//
-// Copyright (c) 2001
-// Mutable Realms, Inc.
-// Huntsville, AL, USA
-//
-// All Rights Reserved
-//
-// **********************************************************************
-
-#include <IceUtil/OutputUtil.h>
-
-using namespace std;
-using namespace IceUtil;
-
-namespace IceUtil
-{
-
-NextLine nl;
-StartBlock sb;
-EndBlock eb;
-Separator sp;
-EndElement ee;
-StartEscapes startEscapes;
-EndEscapes endEscapes;
-
-}
-
-// ----------------------------------------------------------------------
-// OutputBase
-// ----------------------------------------------------------------------
-
-IceUtil::OutputBase::OutputBase() :
- _out(_fout),
- _pos(0),
- _indent(0),
- _indentSize(4),
- _useTab(true),
- _separator(true)
-{
-}
-
-IceUtil::OutputBase::OutputBase(ostream& os) :
- _out(os),
- _pos(0),
- _indent(0),
- _indentSize(4),
- _useTab(true),
- _separator(true)
-{
-}
-
-
-IceUtil::OutputBase::OutputBase(const char* s) :
- _out(_fout),
- _pos(0),
- _indent(0),
- _indentSize(4),
- _useTab(true),
- _separator(true)
-{
- open(s);
-}
-
-IceUtil::OutputBase::~OutputBase()
-{
-}
-
-void
-IceUtil::OutputBase::open(const char* s)
-{
- _fout.open(s);
-}
-
-void
-IceUtil::OutputBase::print(const char* s)
-{
- for(unsigned int i = 0; i < strlen(s); ++i)
- {
- if(s[i] == '\n')
- {
- _pos = 0;
- }
- else
- {
- ++_pos;
- }
- }
-
- _out << s;
-}
-
-void
-IceUtil::OutputBase::inc()
-{
- _indent += _indentSize;
-}
-
-void
-IceUtil::OutputBase::dec()
-{
- assert(_indent >= _indentSize);
- _indent -= _indentSize;
-}
-
-void
-IceUtil::OutputBase::useCurrentPosAsIndent()
-{
- _indentSave.push(_indent);
- _indent = _pos;
-}
-
-void
-IceUtil::OutputBase::zeroIndent()
-{
- _indentSave.push(_indent);
- _indent = 0;
-}
-
-void
-IceUtil::OutputBase::restoreIndent()
-{
- assert(!_indentSave.empty());
- _indent = _indentSave.top();
- _indentSave.pop();
-}
-
-void
-IceUtil::OutputBase::setIndent(int indentSize)
-{
- _indentSize = indentSize;
-}
-
-void
-IceUtil::OutputBase::setUseTab(bool useTab)
-{
- _useTab = useTab;
-}
-
-void
-IceUtil::OutputBase::nl()
-{
- _out << '\n';
- _pos = 0;
- _separator = true;
-
- int indent = _indent;
-
- if(_useTab)
- {
- while(indent >= 8)
- {
- indent -= 8;
- _out << '\t';
- _pos += 8;
- }
- }
- else
- {
- while(indent >= _indentSize)
- {
- indent -= _indentSize;
- _out << " ";
- _pos += _indentSize;
- }
- }
-
- while(indent > 0)
- {
- --indent;
- _out << ' ';
- ++_pos;
- }
-
- _out.flush();
-}
-
-void
-IceUtil::OutputBase::sp()
-{
- if(_separator)
- {
- _out << '\n';
- }
-}
-
-bool
-IceUtil::OutputBase::operator!() const
-{
- return !_out;
-}
-
-streamsize
-IceUtil::OutputBase::width() const
-{
- return _out.width();
-}
-
-streamsize
-IceUtil::OutputBase::width(streamsize newWidth)
-{
- return _out.width(newWidth);
-}
-
-ios_base::fmtflags
-IceUtil::OutputBase::flags() const
-{
- return _out.flags();
-}
-
-ios_base::fmtflags
-IceUtil::OutputBase::flags(ios_base::fmtflags newFlags)
-{
- return _out.flags(newFlags);
-}
-
-ostream::char_type
-IceUtil::OutputBase::fill() const
-{
- return _out.fill();
-}
-
-ostream::char_type
-IceUtil::OutputBase::fill(ostream::char_type newFill)
-{
- return _out.fill(newFill);
-}
-
-// ----------------------------------------------------------------------
-// Output
-// ----------------------------------------------------------------------
-
-IceUtil::Output::Output() :
- OutputBase(),
- _blockStart("{"),
- _blockEnd("}")
-{
-}
-
-IceUtil::Output::Output(ostream& os) :
- OutputBase(os),
- _blockStart("{"),
- _blockEnd("}")
-{
-}
-
-IceUtil::Output::Output(const char* s) :
- OutputBase(s),
- _blockStart("{"),
- _blockEnd("}")
-{
-}
-
-void
-IceUtil::Output::setBeginBlock(const char *bb)
-{
- _blockStart = bb;
-}
-
-void
-IceUtil::Output::setEndBlock(const char *eb)
-{
- _blockEnd = eb;
-}
-
-void
-IceUtil::Output::sb()
-{
- if(_blockStart.length())
- {
- nl();
- _out << _blockStart;
- }
- ++_pos;
- inc();
- _separator = false;
-}
-
-void
-IceUtil::Output::eb()
-{
- dec();
- if(_blockEnd.length())
- {
- nl();
- _out << _blockEnd;
- }
- --_pos;
-}
-
-Output&
-IceUtil::operator<<(Output& out, ios_base& (*val)(ios_base&))
-{
- ostringstream s;
- s << val;
- out.print(s.str().c_str());
- return out;
-}
-
-// ----------------------------------------------------------------------
-// XMLOutput
-// ----------------------------------------------------------------------
-
-IceUtil::XMLOutput::XMLOutput() :
- OutputBase(),
- _se(false),
- _text(false),
- _sgml(false),
- _escape(false)
-{
-}
-
-IceUtil::XMLOutput::XMLOutput(ostream& os) :
- OutputBase(os),
- _se(false),
- _text(false),
- _sgml(false),
- _escape(false)
-{
-}
-
-IceUtil::XMLOutput::XMLOutput(const char* s) :
- OutputBase(s),
- _se(false),
- _text(false),
- _sgml(false),
- _escape(false)
-{
-}
-
-void
-IceUtil::XMLOutput::setSGML(bool sgml)
-{
- _sgml = true;
-}
-
-void
-IceUtil::XMLOutput::print(const char* s)
-{
- if(_se)
- {
- _out << '>';
- _se = false;
- }
- _text = true;
-
- if(_escape)
- {
- string escaped = escape(s);
- OutputBase::print(escaped.c_str());
- }
- else
- {
- OutputBase::print(s);
- }
-}
-
-void
-IceUtil::XMLOutput::nl()
-{
- if(_se)
- {
- _se = false;
- _out << '>';
- }
- OutputBase::nl();
-}
-
-void
-IceUtil::XMLOutput::se(const string& element)
-{
- nl();
-
- //
- // If we're not in SGML mode the output of the '>' character is
- // deferred until either the //end-element (in which case a /> is
- // emitted) or until something //is displayed.
- //
- if(_escape)
- {
- _out << '<' << escape(element);
- }
- else
- {
- _out << '<' << element;
- }
- _se = true;
- _text = false;
-
- string::size_type pos = element.find_first_of(" \t");
- if(pos == string::npos)
- {
- _elementStack.push(element);
- }
- else
- {
- _elementStack.push(element.substr(0, pos));
- }
-
- ++_pos; // TODO: ???
- inc();
- _separator = false;
-}
-
-void
-IceUtil::XMLOutput::ee()
-{
- string element = _elementStack.top();
- _elementStack.pop();
-
- dec();
- if(_se)
- {
- //
- // SGML (docbook) doesn't support <foo/>.
- //
- if(_sgml)
- {
- _out << "></" << element << '>';
- }
- else
- {
- _out << "/>";
- }
- }
- else
- {
- if(!_text)
- {
- nl();
- }
- _out << "</" << element << '>';
- }
- --_pos; // TODO: ???
-
- _se = false;
- _text = false;
-}
-
-void
-IceUtil::XMLOutput::attr(const string& name, const string& value)
-{
- //
- // Precondition: Attributes can only be attached to elements.
- //
- assert(_se);
- _out << " " << name << "=\"" << escape(value) << '"';
-}
-
-void
-IceUtil::XMLOutput::startEscapes()
-{
- _escape = true;
-}
-
-void
-IceUtil::XMLOutput::endEscapes()
-{
- _escape = false;
-}
-
-string
-IceUtil::XMLOutput::currentElement() const
-{
- if(_elementStack.size() > 0)
- {
- return _elementStack.top();
- }
- else
- {
- return string();
- }
-}
-
-string
-IceUtil::XMLOutput::escape(const string& input) const
-{
- string v = input;
-
- //
- // Find out whether there is a reserved character to avoid
- // conversion if not necessary.
- //
- static const string allReserved = "<>'\"&";
- if(v.find_first_of(allReserved) != string::npos)
- {
- //
- // First convert all & to &amp;
- //
- size_t pos = 0;
- while((pos = v.find_first_of('&', pos)) != string::npos)
- {
- v.insert(pos+1, "amp;");
- pos += 4;
- }
-
- //
- // Next convert remaining reserved characters.
- //
- static const string reserved = "<>'\"";
- pos = 0;
- while((pos = v.find_first_of(reserved, pos)) != string::npos)
- {
- string replace;
- switch(v[pos])
- {
- case '>':
- replace = "&gt;";
- break;
-
- case '<':
- replace = "&lt;";
- break;
-
- case '\'':
- replace = "&apos;";
- break;
-
- case '"':
- replace = "&quot;";
- break;
-
- default:
- assert(false);
- }
-
- v.erase(pos, 1);
- v.insert(pos, replace);
- pos += replace.size();
- }
- }
- return v;
-}
-
-XMLOutput&
-IceUtil::operator<<(XMLOutput& out, ios_base& (*val)(ios_base&))
-{
- ostringstream s;
- s << val;
- out.print(s.str().c_str());
- return out;
-}
-
-IceUtil::StartElement::StartElement(const string& name) :
- _name(name)
-{
-}
-
-const string&
-IceUtil::StartElement::getName() const
-{
- return _name;
-}
-
-IceUtil::Attribute::Attribute(const string& name, const string& value) :
- _name(name),
- _value(value)
-{
-}
-
-const string&
-IceUtil::Attribute::getName() const
-{
- return _name;
-}
-
-const string&
-IceUtil::Attribute::getValue() const
-{
- return _value;
-}
+// **********************************************************************
+//
+// Copyright (c) 2001
+// Mutable Realms, Inc.
+// Huntsville, AL, USA
+//
+// All Rights Reserved
+//
+// **********************************************************************
+
+#include <IceUtil/OutputUtil.h>
+
+using namespace std;
+using namespace IceUtil;
+
+namespace IceUtil
+{
+
+NextLine nl;
+StartBlock sb;
+EndBlock eb;
+Separator sp;
+EndElement ee;
+StartEscapes startEscapes;
+EndEscapes endEscapes;
+
+}
+
+// ----------------------------------------------------------------------
+// OutputBase
+// ----------------------------------------------------------------------
+
+IceUtil::OutputBase::OutputBase() :
+ _out(_fout),
+ _pos(0),
+ _indent(0),
+ _indentSize(4),
+ _useTab(true),
+ _separator(true)
+{
+}
+
+IceUtil::OutputBase::OutputBase(ostream& os) :
+ _out(os),
+ _pos(0),
+ _indent(0),
+ _indentSize(4),
+ _useTab(true),
+ _separator(true)
+{
+}
+
+
+IceUtil::OutputBase::OutputBase(const char* s) :
+ _out(_fout),
+ _pos(0),
+ _indent(0),
+ _indentSize(4),
+ _useTab(true),
+ _separator(true)
+{
+ open(s);
+}
+
+IceUtil::OutputBase::~OutputBase()
+{
+}
+
+void
+IceUtil::OutputBase::open(const char* s)
+{
+ _fout.open(s);
+}
+
+void
+IceUtil::OutputBase::print(const char* s)
+{
+ for(unsigned int i = 0; i < strlen(s); ++i)
+ {
+ if(s[i] == '\n')
+ {
+ _pos = 0;
+ }
+ else
+ {
+ ++_pos;
+ }
+ }
+
+ _out << s;
+}
+
+void
+IceUtil::OutputBase::inc()
+{
+ _indent += _indentSize;
+}
+
+void
+IceUtil::OutputBase::dec()
+{
+ assert(_indent >= _indentSize);
+ _indent -= _indentSize;
+}
+
+void
+IceUtil::OutputBase::useCurrentPosAsIndent()
+{
+ _indentSave.push(_indent);
+ _indent = _pos;
+}
+
+void
+IceUtil::OutputBase::zeroIndent()
+{
+ _indentSave.push(_indent);
+ _indent = 0;
+}
+
+void
+IceUtil::OutputBase::restoreIndent()
+{
+ assert(!_indentSave.empty());
+ _indent = _indentSave.top();
+ _indentSave.pop();
+}
+
+void
+IceUtil::OutputBase::setIndent(int indentSize)
+{
+ _indentSize = indentSize;
+}
+
+void
+IceUtil::OutputBase::setUseTab(bool useTab)
+{
+ _useTab = useTab;
+}
+
+void
+IceUtil::OutputBase::nl()
+{
+ _out << '\n';
+ _pos = 0;
+ _separator = true;
+
+ int indent = _indent;
+
+ if(_useTab)
+ {
+ while(indent >= 8)
+ {
+ indent -= 8;
+ _out << '\t';
+ _pos += 8;
+ }
+ }
+ else
+ {
+ while(indent >= _indentSize)
+ {
+ indent -= _indentSize;
+ _out << " ";
+ _pos += _indentSize;
+ }
+ }
+
+ while(indent > 0)
+ {
+ --indent;
+ _out << ' ';
+ ++_pos;
+ }
+
+ _out.flush();
+}
+
+void
+IceUtil::OutputBase::sp()
+{
+ if(_separator)
+ {
+ _out << '\n';
+ }
+}
+
+bool
+IceUtil::OutputBase::operator!() const
+{
+ return !_out;
+}
+
+streamsize
+IceUtil::OutputBase::width() const
+{
+ return _out.width();
+}
+
+streamsize
+IceUtil::OutputBase::width(streamsize newWidth)
+{
+ return _out.width(newWidth);
+}
+
+ios_base::fmtflags
+IceUtil::OutputBase::flags() const
+{
+ return _out.flags();
+}
+
+ios_base::fmtflags
+IceUtil::OutputBase::flags(ios_base::fmtflags newFlags)
+{
+ return _out.flags(newFlags);
+}
+
+ostream::char_type
+IceUtil::OutputBase::fill() const
+{
+ return _out.fill();
+}
+
+ostream::char_type
+IceUtil::OutputBase::fill(ostream::char_type newFill)
+{
+ return _out.fill(newFill);
+}
+
+// ----------------------------------------------------------------------
+// Output
+// ----------------------------------------------------------------------
+
+IceUtil::Output::Output() :
+ OutputBase(),
+ _blockStart("{"),
+ _blockEnd("}")
+{
+}
+
+IceUtil::Output::Output(ostream& os) :
+ OutputBase(os),
+ _blockStart("{"),
+ _blockEnd("}")
+{
+}
+
+IceUtil::Output::Output(const char* s) :
+ OutputBase(s),
+ _blockStart("{"),
+ _blockEnd("}")
+{
+}
+
+void
+IceUtil::Output::setBeginBlock(const char *bb)
+{
+ _blockStart = bb;
+}
+
+void
+IceUtil::Output::setEndBlock(const char *eb)
+{
+ _blockEnd = eb;
+}
+
+void
+IceUtil::Output::sb()
+{
+ if(_blockStart.length())
+ {
+ nl();
+ _out << _blockStart;
+ }
+ ++_pos;
+ inc();
+ _separator = false;
+}
+
+void
+IceUtil::Output::eb()
+{
+ dec();
+ if(_blockEnd.length())
+ {
+ nl();
+ _out << _blockEnd;
+ }
+ --_pos;
+}
+
+Output&
+IceUtil::operator<<(Output& out, ios_base& (*val)(ios_base&))
+{
+ ostringstream s;
+ s << val;
+ out.print(s.str().c_str());
+ return out;
+}
+
+// ----------------------------------------------------------------------
+// XMLOutput
+// ----------------------------------------------------------------------
+
+IceUtil::XMLOutput::XMLOutput() :
+ OutputBase(),
+ _se(false),
+ _text(false),
+ _sgml(false),
+ _escape(false)
+{
+}
+
+IceUtil::XMLOutput::XMLOutput(ostream& os) :
+ OutputBase(os),
+ _se(false),
+ _text(false),
+ _sgml(false),
+ _escape(false)
+{
+}
+
+IceUtil::XMLOutput::XMLOutput(const char* s) :
+ OutputBase(s),
+ _se(false),
+ _text(false),
+ _sgml(false),
+ _escape(false)
+{
+}
+
+void
+IceUtil::XMLOutput::setSGML(bool sgml)
+{
+ _sgml = true;
+}
+
+void
+IceUtil::XMLOutput::print(const char* s)
+{
+ if(_se)
+ {
+ _out << '>';
+ _se = false;
+ }
+ _text = true;
+
+ if(_escape)
+ {
+ string escaped = escape(s);
+ OutputBase::print(escaped.c_str());
+ }
+ else
+ {
+ OutputBase::print(s);
+ }
+}
+
+void
+IceUtil::XMLOutput::nl()
+{
+ if(_se)
+ {
+ _se = false;
+ _out << '>';
+ }
+ OutputBase::nl();
+}
+
+void
+IceUtil::XMLOutput::se(const string& element)
+{
+ nl();
+
+ //
+ // If we're not in SGML mode the output of the '>' character is
+ // deferred until either the //end-element (in which case a /> is
+ // emitted) or until something //is displayed.
+ //
+ if(_escape)
+ {
+ _out << '<' << escape(element);
+ }
+ else
+ {
+ _out << '<' << element;
+ }
+ _se = true;
+ _text = false;
+
+ string::size_type pos = element.find_first_of(" \t");
+ if(pos == string::npos)
+ {
+ _elementStack.push(element);
+ }
+ else
+ {
+ _elementStack.push(element.substr(0, pos));
+ }
+
+ ++_pos; // TODO: ???
+ inc();
+ _separator = false;
+}
+
+void
+IceUtil::XMLOutput::ee()
+{
+ string element = _elementStack.top();
+ _elementStack.pop();
+
+ dec();
+ if(_se)
+ {
+ //
+ // SGML (docbook) doesn't support <foo/>.
+ //
+ if(_sgml)
+ {
+ _out << "></" << element << '>';
+ }
+ else
+ {
+ _out << "/>";
+ }
+ }
+ else
+ {
+ if(!_text)
+ {
+ nl();
+ }
+ _out << "</" << element << '>';
+ }
+ --_pos; // TODO: ???
+
+ _se = false;
+ _text = false;
+}
+
+void
+IceUtil::XMLOutput::attr(const string& name, const string& value)
+{
+ //
+ // Precondition: Attributes can only be attached to elements.
+ //
+ assert(_se);
+ _out << " " << name << "=\"" << escape(value) << '"';
+}
+
+void
+IceUtil::XMLOutput::startEscapes()
+{
+ _escape = true;
+}
+
+void
+IceUtil::XMLOutput::endEscapes()
+{
+ _escape = false;
+}
+
+string
+IceUtil::XMLOutput::currentElement() const
+{
+ if(_elementStack.size() > 0)
+ {
+ return _elementStack.top();
+ }
+ else
+ {
+ return string();
+ }
+}
+
+string
+IceUtil::XMLOutput::escape(const string& input) const
+{
+ string v = input;
+
+ //
+ // Find out whether there is a reserved character to avoid
+ // conversion if not necessary.
+ //
+ static const string allReserved = "<>'\"&";
+ if(v.find_first_of(allReserved) != string::npos)
+ {
+ //
+ // First convert all & to &amp;
+ //
+ size_t pos = 0;
+ while((pos = v.find_first_of('&', pos)) != string::npos)
+ {
+ v.insert(pos+1, "amp;");
+ pos += 4;
+ }
+
+ //
+ // Next convert remaining reserved characters.
+ //
+ static const string reserved = "<>'\"";
+ pos = 0;
+ while((pos = v.find_first_of(reserved, pos)) != string::npos)
+ {
+ string replace;
+ switch(v[pos])
+ {
+ case '>':
+ replace = "&gt;";
+ break;
+
+ case '<':
+ replace = "&lt;";
+ break;
+
+ case '\'':
+ replace = "&apos;";
+ break;
+
+ case '"':
+ replace = "&quot;";
+ break;
+
+ default:
+ assert(false);
+ }
+
+ v.erase(pos, 1);
+ v.insert(pos, replace);
+ pos += replace.size();
+ }
+ }
+ return v;
+}
+
+XMLOutput&
+IceUtil::operator<<(XMLOutput& out, ios_base& (*val)(ios_base&))
+{
+ ostringstream s;
+ s << val;
+ out.print(s.str().c_str());
+ return out;
+}
+
+IceUtil::StartElement::StartElement(const string& name) :
+ _name(name)
+{
+}
+
+const string&
+IceUtil::StartElement::getName() const
+{
+ return _name;
+}
+
+IceUtil::Attribute::Attribute(const string& name, const string& value) :
+ _name(name),
+ _value(value)
+{
+}
+
+const string&
+IceUtil::Attribute::getName() const
+{
+ return _name;
+}
+
+const string&
+IceUtil::Attribute::getValue() const
+{
+ return _value;
+}
diff --git a/cpp/src/IceUtil/RWRecMutex.cpp b/cpp/src/IceUtil/RWRecMutex.cpp
index b8275b2b9f8..ef632a347ec 100644
--- a/cpp/src/IceUtil/RWRecMutex.cpp
+++ b/cpp/src/IceUtil/RWRecMutex.cpp
@@ -1,355 +1,355 @@
-// **********************************************************************
-//
-// Copyright (c) 2001
-// Mutable Realms, Inc.
-// Huntsville, AL, USA
-//
-// All Rights Reserved
-//
-// **********************************************************************
-
-#include <IceUtil/RWRecMutex.h>
-#include <IceUtil/Exception.h>
-#include <IceUtil/Time.h>
-
-#include <assert.h>
-
-IceUtil::RWRecMutex::RWRecMutex() :
- _count(0),
- _waitingWriters(0)
-{
-}
-
-IceUtil::RWRecMutex::~RWRecMutex()
-{
-}
-
-void
-IceUtil::RWRecMutex::readlock() const
-{
- Mutex::Lock lock(_mutex);
-
- //
- // Wait while a writer holds the lock or while writers are waiting
- // to get the lock.
- //
- while(_count < 0 || _waitingWriters != 0)
- {
- _readers.wait(lock);
- }
- _count++;
-}
-
-void
-IceUtil::RWRecMutex::tryReadlock() const
-{
- Mutex::Lock lock(_mutex);
-
- //
- // Would block if a writer holds the lock or if writers are
- // waiting to get the lock.
- //
- if(_count < 0 || _waitingWriters != 0)
- {
- throw LockedException(__FILE__, __LINE__);
- }
- _count++;
-}
-
-void
-IceUtil::RWRecMutex::timedTryReadlock(const Time& timeout) const
-{
- Mutex::Lock lock(_mutex);
-
- //
- // Wait while a writer holds the lock or while writers are waiting
- // to get the lock.
- //
- Time end = Time::now() + timeout;
- while(_count < 0 || _waitingWriters != 0)
- {
- Time remainder = end - Time::now();
- if(remainder > Time())
- {
- _readers.timedWait(lock, remainder);
- }
- else
- {
- throw LockedException(__FILE__, __LINE__);
- }
- }
-
- _count++;
-}
-
-void
-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.
- //
- while(_count != 0)
- {
- _waitingWriters++;
- try
- {
- _writers.wait(lock);
- }
- catch(...)
- {
- --_waitingWriters;
- throw;
- }
- _waitingWriters--;
- }
-
- //
- // Got the lock, indicate it's held by a writer.
- //
- _count = -1;
-}
-
-void
-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)
- {
- throw LockedException(__FILE__, __LINE__);
- }
-
- //
- // Got the lock, indicate it's held by a writer.
- //
- _count = -1;
-}
-
-void
-IceUtil::RWRecMutex::timedTryWritelock(const Time& timeout) 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.
- //
- Time end = Time::now() + timeout;
- while(_count != 0)
- {
- Time remainder = end - Time::now();
- if(remainder > Time())
- {
- _waitingWriters++;
- try
- {
- _writers.timedWait(lock, remainder);
- }
- catch(...)
- {
- --_waitingWriters;
- throw;
- }
- _waitingWriters--;
- }
- else
- {
- throw LockedException(__FILE__, __LINE__);
- }
- }
-
- //
- // Got the lock, indicate it's held by a writer.
- //
- _count = -1;
-}
-
-void
-IceUtil::RWRecMutex::unlock() const
-{
- bool ww;
- bool wr;
- {
- Mutex::Lock lock(_mutex);
-
- assert(_count != 0);
-
- //
- // If _count < 0, the calling thread is a writer that holds the
- // lock, so release the lock. Otherwise, _count is guaranteed to
- // be > 0, so the calling thread is a reader releasing the lock.
- //
- if(_count < 0)
- {
- //
- // Writer called unlock
- //
- ++_count;
-
- //
- // If the write lock wasn't totally released we're done.
- //
- if(_count != 0)
- {
- return;
- }
- }
- else
- {
- //
- // Reader called unlock
- //
- --_count;
- }
-
- //
- // Writers are waiting (ww) if _waitingWriters > 0. In that
- // case, it's OK to let another writer into the region once there
- // are no more readers (_count == 0). Otherwise, no writers are
- // waiting but readers may be waiting (wr).
- //
- ww = (_waitingWriters != 0 && _count == 0);
- wr = (_waitingWriters == 0);
- }
-
- //
- // Wake up a waiting writer if there is one. If not, wake up all
- // readers (just in case -- there may be none).
- //
- if(ww)
- {
- //
- // Wake writer
- //
- _writers.signal();
- }
- else if(wr)
- {
- //
- // Wake readers
- //
- _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;
-}
-
-void
-IceUtil::RWRecMutex::timedUpgrade(const Time& timeout) const
-{
- Mutex::Lock lock(_mutex);
-
- //
- // Reader called unlock
- //
- assert(_count > 0);
- --_count;
-
- //
- // Wait to acquire the write lock.
- //
- Time end = Time::now() + timeout;
- while(_count != 0)
- {
- Time remainder = end - Time::now();
- if(remainder > Time())
- {
- _waitingWriters++;
- try
- {
- _writers.timedWait(lock, remainder);
- }
- catch(...)
- {
- --_waitingWriters;
- throw;
- }
- _waitingWriters--;
- }
- else
- {
- //
- // If a timeout occurred then the lock wasn't acquired. Ensure
- // that the _count is increased again before returning.
- //
- ++_count;
- throw LockedException(__FILE__, __LINE__);
- }
- }
-
- //
- // Got the lock, indicate it's held by a writer.
- //
- _count = -1;
-}
+// **********************************************************************
+//
+// Copyright (c) 2001
+// Mutable Realms, Inc.
+// Huntsville, AL, USA
+//
+// All Rights Reserved
+//
+// **********************************************************************
+
+#include <IceUtil/RWRecMutex.h>
+#include <IceUtil/Exception.h>
+#include <IceUtil/Time.h>
+
+#include <assert.h>
+
+IceUtil::RWRecMutex::RWRecMutex() :
+ _count(0),
+ _waitingWriters(0)
+{
+}
+
+IceUtil::RWRecMutex::~RWRecMutex()
+{
+}
+
+void
+IceUtil::RWRecMutex::readlock() const
+{
+ Mutex::Lock lock(_mutex);
+
+ //
+ // Wait while a writer holds the lock or while writers are waiting
+ // to get the lock.
+ //
+ while(_count < 0 || _waitingWriters != 0)
+ {
+ _readers.wait(lock);
+ }
+ _count++;
+}
+
+void
+IceUtil::RWRecMutex::tryReadlock() const
+{
+ Mutex::Lock lock(_mutex);
+
+ //
+ // Would block if a writer holds the lock or if writers are
+ // waiting to get the lock.
+ //
+ if(_count < 0 || _waitingWriters != 0)
+ {
+ throw ThreadLockedException(__FILE__, __LINE__);
+ }
+ _count++;
+}
+
+void
+IceUtil::RWRecMutex::timedTryReadlock(const Time& timeout) const
+{
+ Mutex::Lock lock(_mutex);
+
+ //
+ // Wait while a writer holds the lock or while writers are waiting
+ // to get the lock.
+ //
+ Time end = Time::now() + timeout;
+ while(_count < 0 || _waitingWriters != 0)
+ {
+ Time remainder = end - Time::now();
+ if(remainder > Time())
+ {
+ _readers.timedWait(lock, remainder);
+ }
+ else
+ {
+ throw ThreadLockedException(__FILE__, __LINE__);
+ }
+ }
+
+ _count++;
+}
+
+void
+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.
+ //
+ while(_count != 0)
+ {
+ _waitingWriters++;
+ try
+ {
+ _writers.wait(lock);
+ }
+ catch(...)
+ {
+ --_waitingWriters;
+ throw;
+ }
+ _waitingWriters--;
+ }
+
+ //
+ // Got the lock, indicate it's held by a writer.
+ //
+ _count = -1;
+}
+
+void
+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)
+ {
+ throw ThreadLockedException(__FILE__, __LINE__);
+ }
+
+ //
+ // Got the lock, indicate it's held by a writer.
+ //
+ _count = -1;
+}
+
+void
+IceUtil::RWRecMutex::timedTryWritelock(const Time& timeout) 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.
+ //
+ Time end = Time::now() + timeout;
+ while(_count != 0)
+ {
+ Time remainder = end - Time::now();
+ if(remainder > Time())
+ {
+ _waitingWriters++;
+ try
+ {
+ _writers.timedWait(lock, remainder);
+ }
+ catch(...)
+ {
+ --_waitingWriters;
+ throw;
+ }
+ _waitingWriters--;
+ }
+ else
+ {
+ throw ThreadLockedException(__FILE__, __LINE__);
+ }
+ }
+
+ //
+ // Got the lock, indicate it's held by a writer.
+ //
+ _count = -1;
+}
+
+void
+IceUtil::RWRecMutex::unlock() const
+{
+ bool ww;
+ bool wr;
+ {
+ Mutex::Lock lock(_mutex);
+
+ assert(_count != 0);
+
+ //
+ // If _count < 0, the calling thread is a writer that holds the
+ // lock, so release the lock. Otherwise, _count is guaranteed to
+ // be > 0, so the calling thread is a reader releasing the lock.
+ //
+ if(_count < 0)
+ {
+ //
+ // Writer called unlock
+ //
+ ++_count;
+
+ //
+ // If the write lock wasn't totally released we're done.
+ //
+ if(_count != 0)
+ {
+ return;
+ }
+ }
+ else
+ {
+ //
+ // Reader called unlock
+ //
+ --_count;
+ }
+
+ //
+ // Writers are waiting (ww) if _waitingWriters > 0. In that
+ // case, it's OK to let another writer into the region once there
+ // are no more readers (_count == 0). Otherwise, no writers are
+ // waiting but readers may be waiting (wr).
+ //
+ ww = (_waitingWriters != 0 && _count == 0);
+ wr = (_waitingWriters == 0);
+ }
+
+ //
+ // Wake up a waiting writer if there is one. If not, wake up all
+ // readers (just in case -- there may be none).
+ //
+ if(ww)
+ {
+ //
+ // Wake writer
+ //
+ _writers.signal();
+ }
+ else if(wr)
+ {
+ //
+ // Wake readers
+ //
+ _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;
+}
+
+void
+IceUtil::RWRecMutex::timedUpgrade(const Time& timeout) const
+{
+ Mutex::Lock lock(_mutex);
+
+ //
+ // Reader called unlock
+ //
+ assert(_count > 0);
+ --_count;
+
+ //
+ // Wait to acquire the write lock.
+ //
+ Time end = Time::now() + timeout;
+ while(_count != 0)
+ {
+ Time remainder = end - Time::now();
+ if(remainder > Time())
+ {
+ _waitingWriters++;
+ try
+ {
+ _writers.timedWait(lock, remainder);
+ }
+ catch(...)
+ {
+ --_waitingWriters;
+ throw;
+ }
+ _waitingWriters--;
+ }
+ else
+ {
+ //
+ // If a timeout occurred then the lock wasn't acquired. Ensure
+ // that the _count is increased again before returning.
+ //
+ ++_count;
+ throw ThreadLockedException(__FILE__, __LINE__);
+ }
+ }
+
+ //
+ // Got the lock, indicate it's held by a writer.
+ //
+ _count = -1;
+}
diff --git a/cpp/src/IceUtil/RecMutex.cpp b/cpp/src/IceUtil/RecMutex.cpp
index 89c11b020d9..2f617b2d51d 100644
--- a/cpp/src/IceUtil/RecMutex.cpp
+++ b/cpp/src/IceUtil/RecMutex.cpp
@@ -1,168 +1,168 @@
-// **********************************************************************
-//
-// Copyright (c) 2001
-// Mutable Realms, Inc.
-// Huntsville, AL, USA
-//
-// All Rights Reserved
-//
-// **********************************************************************
-
-#include <IceUtil/RecMutex.h>
-#include <IceUtil/Exception.h>
-
-using namespace std;
-
-#ifdef _WIN32
-
-IceUtil::RecMutex::RecMutex() :
- _count(0)
-{
- InitializeCriticalSection(&_mutex);
-}
-
-IceUtil::RecMutex::~RecMutex()
-{
- assert(_count == 0);
- DeleteCriticalSection(&_mutex);
-}
-
-bool
-IceUtil::RecMutex::lock() const
-{
- EnterCriticalSection(&_mutex);
- if(++_count > 1)
- {
- LeaveCriticalSection(&_mutex);
- return false;
- }
- return true;
-}
-
-bool
-IceUtil::RecMutex::trylock() const
-{
- if(!TryEnterCriticalSection(&_mutex))
- {
- throw LockedException(__FILE__, __LINE__);
- }
- if(++_count > 1)
- {
- LeaveCriticalSection(&_mutex);
- return false;
- }
- return true;
-}
-
-bool
-IceUtil::RecMutex::unlock() const
-{
- if(--_count == 0)
- {
- LeaveCriticalSection(&_mutex);
- return true;
- }
- return false;
-}
-
-void
-IceUtil::RecMutex::unlock(LockState& state) const
-{
- state.count = _count;
- _count = 0;
- LeaveCriticalSection(&_mutex);
-}
-
-void
-IceUtil::RecMutex::lock(LockState& state) const
-{
- EnterCriticalSection(&_mutex);
- _count = state.count;
-}
-#else
-
-IceUtil::RecMutex::RecMutex() :
- _count(0)
-{
- const pthread_mutexattr_t attr = { PTHREAD_MUTEX_RECURSIVE_NP };
- int rc = pthread_mutex_init(&_mutex, &attr);
- if(rc != 0)
- {
- throw SyscallException(strerror(rc), __FILE__, __LINE__);
- }
-}
-
-IceUtil::RecMutex::~RecMutex()
-{
- assert(_count == 0);
- int rc = 0;
- rc = pthread_mutex_destroy(&_mutex);
- assert(rc == 0);
-}
-
-bool
-IceUtil::RecMutex::lock() const
-{
- int rc = pthread_mutex_lock(&_mutex);
- if(rc != 0)
- {
- throw SyscallException(strerror(rc), __FILE__, __LINE__);
- }
- if(++_count > 1)
- {
- rc = pthread_mutex_unlock(&_mutex);
- assert(rc == 0);
- return false;
- }
- return true;
-}
-
-bool
-IceUtil::RecMutex::trylock() const
-{
- int rc = pthread_mutex_trylock(&_mutex);
- if(rc != 0)
- {
- if(rc == EBUSY)
- {
- throw LockedException(__FILE__, __LINE__);
- }
- throw SyscallException(strerror(rc), __FILE__, __LINE__);
- }
- if(++_count > 1)
- {
- rc = pthread_mutex_unlock(&_mutex);
- assert(rc == 0);
- return false;
- }
- return true;
-}
-
-bool
-IceUtil::RecMutex::unlock() const
-{
- if(--_count == 0)
- {
- int rc = 0; // Prevent warnings when NDEBUG is defined.
- rc = pthread_mutex_unlock(&_mutex);
- assert(rc == 0);
- return true;
- }
- return false;
-}
-
-void
-IceUtil::RecMutex::unlock(LockState& state) const
-{
- state.mutex = &_mutex;
- state.count = _count;
- _count = 0;
-}
-
-void
-IceUtil::RecMutex::lock(LockState& state) const
-{
- _count = state.count;
-}
-
-#endif
+// **********************************************************************
+//
+// Copyright (c) 2001
+// Mutable Realms, Inc.
+// Huntsville, AL, USA
+//
+// All Rights Reserved
+//
+// **********************************************************************
+
+#include <IceUtil/RecMutex.h>
+#include <IceUtil/Exception.h>
+
+using namespace std;
+
+#ifdef _WIN32
+
+IceUtil::RecMutex::RecMutex() :
+ _count(0)
+{
+ InitializeCriticalSection(&_mutex);
+}
+
+IceUtil::RecMutex::~RecMutex()
+{
+ assert(_count == 0);
+ DeleteCriticalSection(&_mutex);
+}
+
+bool
+IceUtil::RecMutex::lock() const
+{
+ EnterCriticalSection(&_mutex);
+ if(++_count > 1)
+ {
+ LeaveCriticalSection(&_mutex);
+ return false;
+ }
+ return true;
+}
+
+bool
+IceUtil::RecMutex::trylock() const
+{
+ if(!TryEnterCriticalSection(&_mutex))
+ {
+ throw ThreadLockedException(__FILE__, __LINE__);
+ }
+ if(++_count > 1)
+ {
+ LeaveCriticalSection(&_mutex);
+ return false;
+ }
+ return true;
+}
+
+bool
+IceUtil::RecMutex::unlock() const
+{
+ if(--_count == 0)
+ {
+ LeaveCriticalSection(&_mutex);
+ return true;
+ }
+ return false;
+}
+
+void
+IceUtil::RecMutex::unlock(LockState& state) const
+{
+ state.count = _count;
+ _count = 0;
+ LeaveCriticalSection(&_mutex);
+}
+
+void
+IceUtil::RecMutex::lock(LockState& state) const
+{
+ EnterCriticalSection(&_mutex);
+ _count = state.count;
+}
+#else
+
+IceUtil::RecMutex::RecMutex() :
+ _count(0)
+{
+ const pthread_mutexattr_t attr = { PTHREAD_MUTEX_RECURSIVE_NP };
+ int rc = pthread_mutex_init(&_mutex, &attr);
+ if(rc != 0)
+ {
+ throw ThreadSyscallException(strerror(rc), __FILE__, __LINE__);
+ }
+}
+
+IceUtil::RecMutex::~RecMutex()
+{
+ assert(_count == 0);
+ int rc = 0;
+ rc = pthread_mutex_destroy(&_mutex);
+ assert(rc == 0);
+}
+
+bool
+IceUtil::RecMutex::lock() const
+{
+ int rc = pthread_mutex_lock(&_mutex);
+ if(rc != 0)
+ {
+ throw ThreadSyscallException(strerror(rc), __FILE__, __LINE__);
+ }
+ if(++_count > 1)
+ {
+ rc = pthread_mutex_unlock(&_mutex);
+ assert(rc == 0);
+ return false;
+ }
+ return true;
+}
+
+bool
+IceUtil::RecMutex::trylock() const
+{
+ int rc = pthread_mutex_trylock(&_mutex);
+ if(rc != 0)
+ {
+ if(rc == EBUSY)
+ {
+ throw ThreadLockedException(__FILE__, __LINE__);
+ }
+ throw ThreadSyscallException(strerror(rc), __FILE__, __LINE__);
+ }
+ if(++_count > 1)
+ {
+ rc = pthread_mutex_unlock(&_mutex);
+ assert(rc == 0);
+ return false;
+ }
+ return true;
+}
+
+bool
+IceUtil::RecMutex::unlock() const
+{
+ if(--_count == 0)
+ {
+ int rc = 0; // Prevent warnings when NDEBUG is defined.
+ rc = pthread_mutex_unlock(&_mutex);
+ assert(rc == 0);
+ return true;
+ }
+ return false;
+}
+
+void
+IceUtil::RecMutex::unlock(LockState& state) const
+{
+ state.mutex = &_mutex;
+ state.count = _count;
+ _count = 0;
+}
+
+void
+IceUtil::RecMutex::lock(LockState& state) const
+{
+ _count = state.count;
+}
+
+#endif
diff --git a/cpp/src/IceUtil/Thread.cpp b/cpp/src/IceUtil/Thread.cpp
index 8b66a9cdb03..31049c5cae0 100644
--- a/cpp/src/IceUtil/Thread.cpp
+++ b/cpp/src/IceUtil/Thread.cpp
@@ -1,313 +1,319 @@
-// **********************************************************************
-//
-// Copyright (c) 2001
-// Mutable Realms, Inc.
-// Huntsville, AL, USA
-//
-// All Rights Reserved
-//
-// **********************************************************************
-
-#include <IceUtil/Thread.h>
-#include <IceUtil/Exception.h>
-#include <IceUtil/Time.h>
-
-using namespace std;
-
-#ifdef _WIN32
-
-IceUtil::ThreadControl::ThreadControl() :
- _handle(new HandleWrapper(0)),
- _id(GetCurrentThreadId())
-{
- HANDLE proc = GetCurrentProcess();
- HANDLE current = GetCurrentThread();
- int rc = DuplicateHandle(proc, current, proc, &_handle->handle, SYNCHRONIZE, TRUE, 0);
- if(rc == 0)
- {
- throw SyscallException(SyscallException::errorToString(GetLastError()), __FILE__, __LINE__);
- }
-}
-
-IceUtil::ThreadControl::ThreadControl(const HandleWrapperPtr& handle, unsigned id) :
- _handle(handle),
- _id(id)
-{
-}
-
-bool
-IceUtil::ThreadControl::operator==(const ThreadControl& rhs) const
-{
- return _id == rhs._id;
-}
-
-bool
-IceUtil::ThreadControl::operator!=(const ThreadControl& rhs) const
-{
- return _id != rhs._id;
-}
-
-bool
-IceUtil::ThreadControl::operator<(const ThreadControl& rhs) const
-{
- return _id != rhs._id;
-}
-
-void
-IceUtil::ThreadControl::join()
-{
- int rc = WaitForSingleObject(_handle->handle, INFINITE);
- if(rc != WAIT_OBJECT_0)
- {
- throw SyscallException(SyscallException::errorToString(GetLastError()), __FILE__, __LINE__);
- }
-}
-
-void
-IceUtil::ThreadControl::sleep(const Time& timeout)
-{
- timeval tv = timeout;
- long msec = (tv.tv_sec * 1000) + (tv.tv_usec / 1000);
- Sleep(msec);
-}
-
-void
-IceUtil::ThreadControl::yield()
-{
- //
- // A value of zero causes the thread to relinquish the remainder
- // of its time slice to any other thread of equal priority that is
- // ready to run.
- //
- Sleep(0);
-}
-
-IceUtil::Thread::Thread() :
- _id(0),
- _handle(new HandleWrapper(0))
-{
-}
-
-IceUtil::Thread::~Thread()
-{
-}
-
-static void*
-startHook(void* arg)
-{
- try
- {
- IceUtil::Thread* rawThread = static_cast<IceUtil::Thread*>(arg);
-
- //
- // Ensure that the thread doesn't go away until run() has
- // completed.
- //
- IceUtil::ThreadPtr thread = rawThread;
-
- //
- // See the comment in IceUtil::Thread::start() for details.
- //
- rawThread->__decRef();
- thread->run();
- }
- catch(const IceUtil::Exception& e)
- {
- cerr << "IceUtil::Thread::run(): uncaught exception: ";
- cerr << e << endl;
- }
- return 0;
-}
-
-#include <process.h>
-
-IceUtil::ThreadControl
-IceUtil::Thread::start()
-{
- //
- // It's necessary to increment the reference count since
- // pthread_create won't necessarily call the thread function until
- // later. If the user does (new MyThread)->start() then the thread
- // object could be deleted before the thread object takes
- // ownership. It's also necessary to increment the reference count
- // prior to calling pthread_create since the thread itself calls
- // __decRef().
- //
- __incRef();
-
- _handle->handle = (HANDLE)_beginthreadex(0, 0, (unsigned (__stdcall*)(void*))startHook, (LPVOID)this, 0, &_id);
- if(_handle->handle == 0)
- {
- __decRef();
- throw SyscallException(SyscallException::errorToString(GetLastError()), __FILE__, __LINE__);
- }
-
- return ThreadControl(_handle, _id);
-}
-
-IceUtil::ThreadControl
-IceUtil::Thread::getThreadControl()
-{
- return ThreadControl(_handle, _id);
-}
-
-bool
-IceUtil::Thread::operator==(const Thread& rhs) const
-{
- return _id == rhs._id;
-}
-
-bool
-IceUtil::Thread::operator!=(const Thread& rhs) const
-{
- return _id != rhs._id;
-}
-
-bool
-IceUtil::Thread::operator<(const Thread& rhs) const
-{
- return _id < rhs._id;
-}
-
-#else
-
-IceUtil::ThreadControl::ThreadControl(pthread_t id) :
- _id(id)
-{
-}
-
-IceUtil::ThreadControl::ThreadControl() :
- _id(pthread_self())
-{
-}
-
-bool
-IceUtil::ThreadControl::operator==(const ThreadControl& rhs) const
-{
- return pthread_equal(_id, rhs._id);
-}
-
-bool
-IceUtil::ThreadControl::operator!=(const ThreadControl& rhs) const
-{
- return !pthread_equal(_id, rhs._id);
-}
-
-bool
-IceUtil::ThreadControl::operator<(const ThreadControl& rhs) const
-{
- // NOTE: Linux specific
- return _id < rhs._id;
-}
-
-void
-IceUtil::ThreadControl::join()
-{
- void* ignore = 0;
- int rc = pthread_join(_id, &ignore);
- if(rc != 0)
- {
- throw SyscallException(strerror(rc), __FILE__, __LINE__);
- }
-}
-
-void
-IceUtil::ThreadControl::sleep(const Time& timeout)
-{
- struct timeval tv = timeout;
- struct timespec ts;
- ts.tv_sec = tv.tv_sec;
- ts.tv_nsec = tv.tv_usec * 1000L;
- nanosleep(&ts, 0);
-}
-
-void
-IceUtil::ThreadControl::yield()
-{
- sched_yield();
-}
-
-IceUtil::Thread::Thread()
-{
-}
-
-IceUtil::Thread::~Thread()
-{
-}
-
-static void*
-startHook(void* arg)
-{
- try
- {
- IceUtil::Thread* rawThread = static_cast<IceUtil::Thread*>(arg);
-
- //
- // Ensure that the thread doesn't go away until run() has
- // completed.
- //
- IceUtil::ThreadPtr thread = rawThread;
-
- //
- // See the comment in IceUtil::Thread::start() for details.
- //
- rawThread->__decRef();
- thread->run();
- }
- catch(const IceUtil::Exception& e)
- {
- cerr << "IceUtil::Thread::run(): uncaught exception: ";
- cerr << e << endl;
- }
- return 0;
-}
-
-IceUtil::ThreadControl
-IceUtil::Thread::start()
-{
- //
- // It's necessary to increment the reference count since
- // pthread_create won't necessarily call the thread function until
- // later. If the user does (new MyThread)->start() then the thread
- // object could be deleted before the thread object takes
- // ownership. It's also necessary to increment the reference count
- // prior to calling pthread_create since the thread itself calls
- // __decRef().
- //
- __incRef();
- int rc = pthread_create(&_id, 0, startHook, this);
- if(rc != 0)
- {
- __decRef();
- throw SyscallException(strerror(rc), __FILE__, __LINE__);
- }
- return ThreadControl(_id);
-}
-
-IceUtil::ThreadControl
-IceUtil::Thread::getThreadControl()
-{
- return ThreadControl(_id);
-}
-
-bool
-IceUtil::Thread::operator==(const Thread& rhs) const
-{
- return pthread_equal(_id, rhs._id);
-}
-
-bool
-IceUtil::Thread::operator!=(const Thread& rhs) const
-{
- return !pthread_equal(_id, rhs._id);
-}
-
-bool
-IceUtil::Thread::operator<(const Thread& rhs) const
-{
- // NOTE: Linux specific
- return _id < rhs._id;
-}
-
-#endif
-
+// **********************************************************************
+//
+// Copyright (c) 2001
+// Mutable Realms, Inc.
+// Huntsville, AL, USA
+//
+// All Rights Reserved
+//
+// **********************************************************************
+
+#include <IceUtil/Thread.h>
+#include <IceUtil/Time.h>
+#include <IceUtil/ThreadException.h>
+
+using namespace std;
+
+#ifdef _WIN32
+
+IceUtil::ThreadControl::ThreadControl() :
+ _handle(new HandleWrapper(0)),
+ _id(GetCurrentThreadId())
+{
+ HANDLE proc = GetCurrentProcess();
+ HANDLE current = GetCurrentThread();
+ int rc = DuplicateHandle(proc, current, proc, &_handle->handle, SYNCHRONIZE, TRUE, 0);
+ if(rc == 0)
+ {
+ throw ThreadSyscallException(__FILE__, __LINE__);
+ }
+}
+
+IceUtil::ThreadControl::ThreadControl(const HandleWrapperPtr& handle, unsigned id) :
+ _handle(handle),
+ _id(id)
+{
+}
+
+bool
+IceUtil::ThreadControl::operator==(const ThreadControl& rhs) const
+{
+ return _id == rhs._id;
+}
+
+bool
+IceUtil::ThreadControl::operator!=(const ThreadControl& rhs) const
+{
+ return _id != rhs._id;
+}
+
+bool
+IceUtil::ThreadControl::operator<(const ThreadControl& rhs) const
+{
+ return _id != rhs._id;
+}
+
+void
+IceUtil::ThreadControl::join()
+{
+ if(_handle->handle)
+ {
+ int rc = WaitForSingleObject(_handle->handle, INFINITE);
+ if(rc != WAIT_OBJECT_0)
+ {
+ throw ThreadSyscallException(__FILE__, __LINE__);
+ }
+ }
+}
+
+void
+IceUtil::ThreadControl::sleep(const Time& timeout)
+{
+ timeval tv = timeout;
+ long msec = (tv.tv_sec * 1000) + (tv.tv_usec / 1000);
+ Sleep(msec);
+}
+
+void
+IceUtil::ThreadControl::yield()
+{
+ //
+ // A value of zero causes the thread to relinquish the remainder
+ // of its time slice to any other thread of equal priority that is
+ // ready to run.
+ //
+ Sleep(0);
+}
+
+IceUtil::Thread::Thread() :
+ _id(0),
+ _handle(new HandleWrapper(0))
+{
+}
+
+IceUtil::Thread::~Thread()
+{
+}
+
+static void*
+startHook(void* arg)
+{
+ try
+ {
+ IceUtil::Thread* rawThread = static_cast<IceUtil::Thread*>(arg);
+
+ //
+ // Ensure that the thread doesn't go away until run() has
+ // completed.
+ //
+ IceUtil::ThreadPtr thread = rawThread;
+
+ //
+ // See the comment in IceUtil::Thread::start() for details.
+ //
+ rawThread->__decRef();
+ thread->run();
+ }
+ catch(const IceUtil::Exception& e)
+ {
+ cerr << "IceUtil::Thread::run(): uncaught exception: ";
+ cerr << e << endl;
+ }
+ return 0;
+}
+
+#include <process.h>
+
+IceUtil::ThreadControl
+IceUtil::Thread::start()
+{
+ //
+ // It's necessary to increment the reference count since
+ // pthread_create won't necessarily call the thread function until
+ // later. If the user does (new MyThread)->start() then the thread
+ // object could be deleted before the thread object takes
+ // ownership. It's also necessary to increment the reference count
+ // prior to calling pthread_create since the thread itself calls
+ // __decRef().
+ //
+ __incRef();
+
+ _handle->handle = (HANDLE)_beginthreadex(0, 0, (unsigned (__stdcall*)(void*))startHook, (LPVOID)this, 0, &_id);
+ if(_handle->handle == 0)
+ {
+ __decRef();
+ throw ThreadSyscallException(__FILE__, __LINE__);
+ }
+
+ return ThreadControl(_handle, _id);
+}
+
+IceUtil::ThreadControl
+IceUtil::Thread::getThreadControl()
+{
+ return ThreadControl(_handle, _id);
+}
+
+bool
+IceUtil::Thread::operator==(const Thread& rhs) const
+{
+ return _id == rhs._id;
+}
+
+bool
+IceUtil::Thread::operator!=(const Thread& rhs) const
+{
+ return _id != rhs._id;
+}
+
+bool
+IceUtil::Thread::operator<(const Thread& rhs) const
+{
+ return _id < rhs._id;
+}
+
+#else
+
+IceUtil::ThreadControl::ThreadControl(pthread_t id) :
+ _id(id)
+{
+}
+
+IceUtil::ThreadControl::ThreadControl() :
+ _id(pthread_self())
+{
+}
+
+bool
+IceUtil::ThreadControl::operator==(const ThreadControl& rhs) const
+{
+ return pthread_equal(_id, rhs._id);
+}
+
+bool
+IceUtil::ThreadControl::operator!=(const ThreadControl& rhs) const
+{
+ return !pthread_equal(_id, rhs._id);
+}
+
+bool
+IceUtil::ThreadControl::operator<(const ThreadControl& rhs) const
+{
+ // NOTE: Linux specific
+ return _id < rhs._id;
+}
+
+void
+IceUtil::ThreadControl::join()
+{
+ if(_id)
+ {
+ void* ignore = 0;
+ int rc = pthread_join(_id, &ignore);
+ if(rc != 0)
+ {
+ throw ThreadSyscallException(__FILE__, __LINE__);
+ }
+ }
+}
+
+void
+IceUtil::ThreadControl::sleep(const Time& timeout)
+{
+ struct timeval tv = timeout;
+ struct timespec ts;
+ ts.tv_sec = tv.tv_sec;
+ ts.tv_nsec = tv.tv_usec * 1000L;
+ nanosleep(&ts, 0);
+}
+
+void
+IceUtil::ThreadControl::yield()
+{
+ sched_yield();
+}
+
+IceUtil::Thread::Thread()
+{
+}
+
+IceUtil::Thread::~Thread()
+{
+}
+
+static void*
+startHook(void* arg)
+{
+ try
+ {
+ IceUtil::Thread* rawThread = static_cast<IceUtil::Thread*>(arg);
+
+ //
+ // Ensure that the thread doesn't go away until run() has
+ // completed.
+ //
+ IceUtil::ThreadPtr thread = rawThread;
+
+ //
+ // See the comment in IceUtil::Thread::start() for details.
+ //
+ rawThread->__decRef();
+ thread->run();
+ }
+ catch(const IceUtil::Exception& e)
+ {
+ cerr << "IceUtil::Thread::run(): uncaught exception: ";
+ cerr << e << endl;
+ }
+ return 0;
+}
+
+IceUtil::ThreadControl
+IceUtil::Thread::start()
+{
+ //
+ // It's necessary to increment the reference count since
+ // pthread_create won't necessarily call the thread function until
+ // later. If the user does (new MyThread)->start() then the thread
+ // object could be deleted before the thread object takes
+ // ownership. It's also necessary to increment the reference count
+ // prior to calling pthread_create since the thread itself calls
+ // __decRef().
+ //
+ __incRef();
+ int rc = pthread_create(&_id, 0, startHook, this);
+ if(rc != 0)
+ {
+ __decRef();
+ throw ThreadSyscallException(__FILE__, __LINE__);
+ }
+ return ThreadControl(_id);
+}
+
+IceUtil::ThreadControl
+IceUtil::Thread::getThreadControl()
+{
+ return ThreadControl(_id);
+}
+
+bool
+IceUtil::Thread::operator==(const Thread& rhs) const
+{
+ return pthread_equal(_id, rhs._id);
+}
+
+bool
+IceUtil::Thread::operator!=(const Thread& rhs) const
+{
+ return !pthread_equal(_id, rhs._id);
+}
+
+bool
+IceUtil::Thread::operator<(const Thread& rhs) const
+{
+ // NOTE: Linux specific
+ return _id < rhs._id;
+}
+
+#endif
+
diff --git a/cpp/src/IceUtil/ThreadException.cpp b/cpp/src/IceUtil/ThreadException.cpp
new file mode 100644
index 00000000000..f0e9acea3b9
--- /dev/null
+++ b/cpp/src/IceUtil/ThreadException.cpp
@@ -0,0 +1,100 @@
+// **********************************************************************
+//
+// Copyright (c) 2001
+// Mutable Realms, Inc.
+// Huntsville, AL, USA
+//
+// All Rights Reserved
+//
+// **********************************************************************
+
+#include <IceUtil/ThreadException.h>
+
+using namespace std;
+
+IceUtil::ThreadSyscallException::ThreadSyscallException(const char* file, int line) :
+ Exception(file, line),
+#ifdef _WIN32
+ _error(GetLastError())
+#else
+ _error(errno)
+#endif
+{
+}
+
+string
+IceUtil::ThreadSyscallException::ice_name() const
+{
+ return "IceUtil::ThreadSyscallException";
+}
+
+void
+IceUtil::ThreadSyscallException::ice_print(ostream& os) const
+{
+ Exception::ice_print(os);
+ if(_error != 0)
+ {
+ os << ":\nthread syscall exception: ";
+#ifdef _WIN32
+ LPVOID lpMsgBuf = 0;
+ DWORD ok = FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
+ FORMAT_MESSAGE_FROM_SYSTEM |
+ FORMAT_MESSAGE_IGNORE_INSERTS,
+ NULL,
+ _error,
+ MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
+ (LPTSTR)&lpMsgBuf,
+ 0,
+ NULL);
+
+ if(ok)
+ {
+ LPCTSTR msg = (LPCTSTR)lpMsgBuf;
+ assert(msg && strlen(msg) > 0);
+ os << msg;
+ LocalFree(lpMsgBuf);
+ }
+ else
+ {
+ os << "unknown thread error";
+ }
+#else
+ os << strerror(_error);
+#endif
+ }
+}
+
+IceUtil::Exception*
+IceUtil::ThreadSyscallException::ice_clone() const
+{
+ return new ThreadSyscallException(*this);
+}
+
+void
+IceUtil::ThreadSyscallException::ice_throw() const
+{
+ throw *this;
+}
+
+IceUtil::ThreadLockedException::ThreadLockedException(const char* file, int line) :
+ Exception(file, line)
+{
+}
+
+string
+IceUtil::ThreadLockedException::ice_name() const
+{
+ return "IceUtil::ThreadLockedException";
+}
+
+IceUtil::Exception*
+IceUtil::ThreadLockedException::ice_clone() const
+{
+ return new ThreadLockedException(*this);
+}
+
+void
+IceUtil::ThreadLockedException::ice_throw() const
+{
+ throw *this;
+}
diff --git a/cpp/src/IceUtil/Time.cpp b/cpp/src/IceUtil/Time.cpp
index 6774ec97736..886edc4b6e8 100644
--- a/cpp/src/IceUtil/Time.cpp
+++ b/cpp/src/IceUtil/Time.cpp
@@ -1,142 +1,142 @@
-// **********************************************************************
-//
-// Copyright (c) 2001
-// Mutable Realms, Inc.
-// Huntsville, AL, USA
-//
-// All Rights Reserved
-//
-// **********************************************************************
-
-#include <IceUtil/Time.h>
-
-#ifdef _WIN32
-# include <sys/timeb.h>
-#else
-# include <sys/time.h>
-#endif
-
-using namespace IceUtil;
-
-Time::Time() :
- _usec(0)
-{
-}
-
-Time
-IceUtil::Time::now()
-{
-#ifdef WIN32
- struct _timeb tb;
- _ftime(&tb);
- return Time(tb.time * static_cast<Int64>(1000000) + tb.millitm * static_cast<Int64>(1000));
-#else
- struct timeval tv;
- gettimeofday(&tv, 0);
- return Time(tv.tv_sec * static_cast<Int64>(1000000) + tv.tv_usec);
-#endif
-}
-
-Time
-IceUtil::Time::seconds(long t)
-{
- return Time(t * static_cast<Int64>(1000000));
-}
-
-Time
-IceUtil::Time::milliSeconds(long t)
-{
- return Time(t * static_cast<Int64>(1000));
-}
-
-Time
-IceUtil::Time::microSeconds(Int64 t)
-{
- return Time(t);
-}
-
-Time
-IceUtil::Time::operator-() const
-{
- return Time(-_usec);
-}
-
-Time
-IceUtil::Time::operator-(const Time& rhs) const
-{
- return Time(_usec - rhs._usec);
-}
-
-Time
-IceUtil::Time::operator+(const Time& rhs) const
-{
- return Time(_usec + rhs._usec);
-}
-
-Time&
-IceUtil::Time::operator+=(const Time& rhs)
-{
- _usec += rhs._usec;
- return *this;
-}
-
-Time&
-IceUtil::Time::operator-=(const Time& rhs)
-{
- _usec -= rhs._usec;
- return *this;
-}
-
-bool
-IceUtil::Time::operator<(const Time& rhs) const
-{
- return _usec < rhs._usec;
-}
-
-bool
-IceUtil::Time::operator<=(const Time& rhs) const
-{
- return _usec <= rhs._usec;
-}
-
-bool
-IceUtil::Time::operator>(const Time& rhs) const
-{
- return _usec > rhs._usec;
-}
-
-bool
-IceUtil::Time::operator>=(const Time& rhs) const
-{
- return _usec >= rhs._usec;
-}
-
-bool
-IceUtil::Time::operator==(const Time& rhs) const
-{
- return _usec == rhs._usec;
-}
-
-bool
-IceUtil::Time::operator!=(const Time& rhs) const
-{
- return _usec != rhs._usec;
-}
-
-IceUtil::Time::operator timeval() const
-{
- timeval tv;
- tv.tv_sec = static_cast<long>(_usec / 1000000);
- tv.tv_usec = static_cast<long>(_usec % 1000000);
- return tv;
-}
-
-IceUtil::Time::operator double() const
-{
- return _usec / 1000000.0L;
-}
-
-Time::Time(Int64 usec) :
- _usec(usec)
-{
-}
+// **********************************************************************
+//
+// Copyright (c) 2001
+// Mutable Realms, Inc.
+// Huntsville, AL, USA
+//
+// All Rights Reserved
+//
+// **********************************************************************
+
+#include <IceUtil/Time.h>
+
+#ifdef _WIN32
+# include <sys/timeb.h>
+#else
+# include <sys/time.h>
+#endif
+
+using namespace IceUtil;
+
+Time::Time() :
+ _usec(0)
+{
+}
+
+Time
+IceUtil::Time::now()
+{
+#ifdef WIN32
+ struct _timeb tb;
+ _ftime(&tb);
+ return Time(tb.time * static_cast<Int64>(1000000) + tb.millitm * static_cast<Int64>(1000));
+#else
+ struct timeval tv;
+ gettimeofday(&tv, 0);
+ return Time(tv.tv_sec * static_cast<Int64>(1000000) + tv.tv_usec);
+#endif
+}
+
+Time
+IceUtil::Time::seconds(long t)
+{
+ return Time(t * static_cast<Int64>(1000000));
+}
+
+Time
+IceUtil::Time::milliSeconds(long t)
+{
+ return Time(t * static_cast<Int64>(1000));
+}
+
+Time
+IceUtil::Time::microSeconds(Int64 t)
+{
+ return Time(t);
+}
+
+Time
+IceUtil::Time::operator-() const
+{
+ return Time(-_usec);
+}
+
+Time
+IceUtil::Time::operator-(const Time& rhs) const
+{
+ return Time(_usec - rhs._usec);
+}
+
+Time
+IceUtil::Time::operator+(const Time& rhs) const
+{
+ return Time(_usec + rhs._usec);
+}
+
+Time&
+IceUtil::Time::operator+=(const Time& rhs)
+{
+ _usec += rhs._usec;
+ return *this;
+}
+
+Time&
+IceUtil::Time::operator-=(const Time& rhs)
+{
+ _usec -= rhs._usec;
+ return *this;
+}
+
+bool
+IceUtil::Time::operator<(const Time& rhs) const
+{
+ return _usec < rhs._usec;
+}
+
+bool
+IceUtil::Time::operator<=(const Time& rhs) const
+{
+ return _usec <= rhs._usec;
+}
+
+bool
+IceUtil::Time::operator>(const Time& rhs) const
+{
+ return _usec > rhs._usec;
+}
+
+bool
+IceUtil::Time::operator>=(const Time& rhs) const
+{
+ return _usec >= rhs._usec;
+}
+
+bool
+IceUtil::Time::operator==(const Time& rhs) const
+{
+ return _usec == rhs._usec;
+}
+
+bool
+IceUtil::Time::operator!=(const Time& rhs) const
+{
+ return _usec != rhs._usec;
+}
+
+IceUtil::Time::operator timeval() const
+{
+ timeval tv;
+ tv.tv_sec = static_cast<long>(_usec / 1000000);
+ tv.tv_usec = static_cast<long>(_usec % 1000000);
+ return tv;
+}
+
+IceUtil::Time::operator double() const
+{
+ return _usec / 1000000.0L;
+}
+
+Time::Time(Int64 usec) :
+ _usec(usec)
+{
+}
diff --git a/cpp/src/IceUtil/UUID.cpp b/cpp/src/IceUtil/UUID.cpp
index 95ddb2a1d38..21bab48af46 100644
--- a/cpp/src/IceUtil/UUID.cpp
+++ b/cpp/src/IceUtil/UUID.cpp
@@ -1,50 +1,50 @@
-// **********************************************************************
-//
-// Copyright (c) 2001
-// Mutable Realms, Inc.
-// Huntsville, AL, USA
-//
-// All Rights Reserved
-//
-// **********************************************************************
-
-#include <IceUtil/UUID.h>
-
-#ifdef _WIN32
-# include <rpc.h>
-#else
-extern "C" // uuid/uuid.h seems to miss extern "C" declarations.
-{
-# include <uuid/uuid.h>
-}
-#endif
-
-using namespace std;
-
-string
-IceUtil::generateUUID()
-{
-#ifdef _WIN32
-
- UUID uuid;
- UuidCreate(&uuid);
-
- unsigned char* str;
- UuidToString(&uuid, &str);
-
- string result(reinterpret_cast<char*>(str));
- RpcStringFree(&str);
- return result;
-
-#else
-
- uuid_t uuid;
- uuid_generate(uuid);
-
- char str[37];
- uuid_unparse(uuid, str);
-
- return str;
-
-#endif
-}
+// **********************************************************************
+//
+// Copyright (c) 2001
+// Mutable Realms, Inc.
+// Huntsville, AL, USA
+//
+// All Rights Reserved
+//
+// **********************************************************************
+
+#include <IceUtil/UUID.h>
+
+#ifdef _WIN32
+# include <rpc.h>
+#else
+extern "C" // uuid/uuid.h seems to miss extern "C" declarations.
+{
+# include <uuid/uuid.h>
+}
+#endif
+
+using namespace std;
+
+string
+IceUtil::generateUUID()
+{
+#ifdef _WIN32
+
+ UUID uuid;
+ UuidCreate(&uuid);
+
+ unsigned char* str;
+ UuidToString(&uuid, &str);
+
+ string result(reinterpret_cast<char*>(str));
+ RpcStringFree(&str);
+ return result;
+
+#else
+
+ uuid_t uuid;
+ uuid_generate(uuid);
+
+ char str[37];
+ uuid_unparse(uuid, str);
+
+ return str;
+
+#endif
+}
diff --git a/cpp/src/IceUtil/Unicode.cpp b/cpp/src/IceUtil/Unicode.cpp
index 2997a6e4dc7..d440bb00fe5 100644
--- a/cpp/src/IceUtil/Unicode.cpp
+++ b/cpp/src/IceUtil/Unicode.cpp
@@ -1,149 +1,149 @@
-// **********************************************************************
-//
-// Copyright (c) 2001
-// Mutable Realms, Inc.
-// Huntsville, AL, USA
-//
-// All Rights Reserved
-//
-// **********************************************************************
-
-#include <IceUtil/Unicode.h>
-#include <algorithm>
-
-using namespace std;
-
-string
-IceUtil::wstringToString(const wstring& str)
-{
- string result;
- result.reserve(str.length() * 2);
-
- for(unsigned int i = 0; i < str.length(); ++i)
- {
- wchar_t wc;
- wc = str[i];
-
- if(wc < 0x80)
- {
- result += static_cast<char>(wc);
- }
- else if(wc < 0x800)
- {
- result += 0xc0 | (wc>>6);
- result += 0x80 | (wc & 0x3f);
- }
- else if(wc < 0x10000)
- {
- result += 0xe0 | (wc>>12);
- result += 0x80 | ((wc>>6) & 0x3f);
- result += 0x80 | (wc & 0x3f);
- }
- else if(wc < 0x10FFFF)
- {
- result += 0xf0 | (wc>>18);
- result += 0x80 | ((wc>>12) & 0x3f);
- result += 0x80 | ((wc>>6) & 0x3f);
- result += 0x80 | (wc & 0x3f);
- }
- else
- {
- return result; // Error, not encodable.
- }
- }
-
- return result;
-}
-
-wstring
-IceUtil::stringToWstring(const string& str)
-{
- wstring result;
- result.reserve(str.length());
-
- unsigned int len;
- for(unsigned int i = 0; i < str.length(); i += len)
- {
- unsigned char c = str[i];
- wchar_t wc;
- int minval;
-
- if(c < 0x80)
- {
- wc = c;
- len = 1;
- minval = 0;
- }
- else if(c < 0xc0) // Lead byte must not be 10xxxxxx
- {
- return result; // Error, not encodable.
- }
- else if(c < 0xe0) // 110xxxxx
- {
- wc = c & 0x1f;
- len = 2;
- minval = 0x80;
- }
- else if(c < 0xf0) // 1110xxxx
- {
- wc = c & 0xf;
- len = 3;
- minval = 0x800;
- }
-#if SIZEOF_WCHAR_T >= 4
- else if(c < 0xf8) // 11110xxx
- {
- wc = c & 7;
- len = 4;
- minval = 0x10000;
- }
- else if(c < 0xfc) // 111110xx
- {
- // Length 5 and 6 is declared invalid in Unicode 3.1 and ISO 10646:2001.
- wc = c & 3;
- len = 5;
- minval = 0x110000;
- }
- else if(c < 0xfe) // 1111110x
- {
- // Length 5 and 6 is declared invalid in Unicode 3.1 and ISO 10646:2001.
- wc = c & 1;
- len = 6;
- minval = 0x4000000;
- }
-#endif
- else
- {
- return result; // Error, not encodable.
- }
-
- if(i + len - 1 < str.length())
- {
- for(unsigned int j = 1; j < len; ++j)
- {
- if((str[i + j] & 0xc0) != 0x80) // All other bytes must be 10xxxxxx
- {
- return result; // Error, not encodable.
- }
-
- wc <<= 6;
- wc |= str[i + j] & 0x3f;
- }
-
- if(wc < minval)
- {
- return result; // Error, non-shortest form.
- }
- else
- {
- result += wc;
- }
- }
- else
- {
- return result; // Error, not encodable.
- }
- }
-
- return result;
-}
+// **********************************************************************
+//
+// Copyright (c) 2001
+// Mutable Realms, Inc.
+// Huntsville, AL, USA
+//
+// All Rights Reserved
+//
+// **********************************************************************
+
+#include <IceUtil/Unicode.h>
+#include <algorithm>
+
+using namespace std;
+
+string
+IceUtil::wstringToString(const wstring& str)
+{
+ string result;
+ result.reserve(str.length() * 2);
+
+ for(unsigned int i = 0; i < str.length(); ++i)
+ {
+ wchar_t wc;
+ wc = str[i];
+
+ if(wc < 0x80)
+ {
+ result += static_cast<char>(wc);
+ }
+ else if(wc < 0x800)
+ {
+ result += 0xc0 | (wc>>6);
+ result += 0x80 | (wc & 0x3f);
+ }
+ else if(wc < 0x10000)
+ {
+ result += 0xe0 | (wc>>12);
+ result += 0x80 | ((wc>>6) & 0x3f);
+ result += 0x80 | (wc & 0x3f);
+ }
+ else if(wc < 0x10FFFF)
+ {
+ result += 0xf0 | (wc>>18);
+ result += 0x80 | ((wc>>12) & 0x3f);
+ result += 0x80 | ((wc>>6) & 0x3f);
+ result += 0x80 | (wc & 0x3f);
+ }
+ else
+ {
+ return result; // Error, not encodable.
+ }
+ }
+
+ return result;
+}
+
+wstring
+IceUtil::stringToWstring(const string& str)
+{
+ wstring result;
+ result.reserve(str.length());
+
+ unsigned int len;
+ for(unsigned int i = 0; i < str.length(); i += len)
+ {
+ unsigned char c = str[i];
+ wchar_t wc;
+ int minval;
+
+ if(c < 0x80)
+ {
+ wc = c;
+ len = 1;
+ minval = 0;
+ }
+ else if(c < 0xc0) // Lead byte must not be 10xxxxxx
+ {
+ return result; // Error, not encodable.
+ }
+ else if(c < 0xe0) // 110xxxxx
+ {
+ wc = c & 0x1f;
+ len = 2;
+ minval = 0x80;
+ }
+ else if(c < 0xf0) // 1110xxxx
+ {
+ wc = c & 0xf;
+ len = 3;
+ minval = 0x800;
+ }
+#if SIZEOF_WCHAR_T >= 4
+ else if(c < 0xf8) // 11110xxx
+ {
+ wc = c & 7;
+ len = 4;
+ minval = 0x10000;
+ }
+ else if(c < 0xfc) // 111110xx
+ {
+ // Length 5 and 6 is declared invalid in Unicode 3.1 and ISO 10646:2001.
+ wc = c & 3;
+ len = 5;
+ minval = 0x110000;
+ }
+ else if(c < 0xfe) // 1111110x
+ {
+ // Length 5 and 6 is declared invalid in Unicode 3.1 and ISO 10646:2001.
+ wc = c & 1;
+ len = 6;
+ minval = 0x4000000;
+ }
+#endif
+ else
+ {
+ return result; // Error, not encodable.
+ }
+
+ if(i + len - 1 < str.length())
+ {
+ for(unsigned int j = 1; j < len; ++j)
+ {
+ if((str[i + j] & 0xc0) != 0x80) // All other bytes must be 10xxxxxx
+ {
+ return result; // Error, not encodable.
+ }
+
+ wc <<= 6;
+ wc |= str[i + j] & 0x3f;
+ }
+
+ if(wc < minval)
+ {
+ return result; // Error, non-shortest form.
+ }
+ else
+ {
+ result += wc;
+ }
+ }
+ else
+ {
+ return result; // Error, not encodable.
+ }
+ }
+
+ return result;
+}
diff --git a/cpp/src/IceUtil/iceutil.dsp b/cpp/src/IceUtil/iceutil.dsp
index ee8aa967ce7..7ace7ca5ba9 100644
--- a/cpp/src/IceUtil/iceutil.dsp
+++ b/cpp/src/IceUtil/iceutil.dsp
@@ -57,6 +57,7 @@ LINK32=link.exe
# ADD LINK32 rpcrt4.lib /nologo /dll /machine:I386 /out:"Release/iceutil001.dll"
# SUBTRACT LINK32 /pdb:none /debug /nodefaultlib
# Begin Special Build Tool
+OutDir=.\Release
SOURCE="$(InputPath)"
PostBuild_Cmds=copy $(OutDir)\iceutil001.* ..\..\lib
# End Special Build Tool
@@ -89,6 +90,7 @@ LINK32=link.exe
# ADD LINK32 rpcrt4.lib /nologo /dll /debug /machine:I386 /out:"Debug/iceutil001d.dll" /pdbtype:sept
# SUBTRACT LINK32 /pdb:none /nodefaultlib
# Begin Special Build Tool
+OutDir=.\Debug
SOURCE="$(InputPath)"
PostBuild_Cmds=copy $(OutDir)\iceutil001d.* ..\..\lib
# End Special Build Tool
@@ -136,6 +138,10 @@ SOURCE=.\Thread.cpp
# End Source File
# Begin Source File
+SOURCE=.\ThreadException.cpp
+# End Source File
+# Begin Source File
+
SOURCE=.\Time.cpp
# End Source File
# Begin Source File
@@ -216,6 +222,10 @@ SOURCE=..\..\include\IceUtil\Thread.h
# End Source File
# Begin Source File
+SOURCE=..\..\include\IceUtil\ThreadException.h
+# End Source File
+# Begin Source File
+
SOURCE=..\..\include\IceUtil\Time.h
# End Source File
# Begin Source File
diff --git a/cpp/src/slice2cpp/Gen.cpp b/cpp/src/slice2cpp/Gen.cpp
index 2141aaa1ee2..fd88540dbad 100644
--- a/cpp/src/slice2cpp/Gen.cpp
+++ b/cpp/src/slice2cpp/Gen.cpp
@@ -356,8 +356,7 @@ Slice::Gen::TypesVisitor::visitExceptionStart(const ExceptionPtr& p)
H << nl << _dllExport << "virtual ::std::string ice_name() const;";
C << sp << nl << "::std::string" << nl << scoped.substr(2) << "::ice_name() const";
C << sb;
- C << nl << "static const ::std::string name(\"" << p->scoped().substr(2) << "\");";
- C << nl << "return name;";
+ C << nl << "return \"" << p->scoped().substr(2) << "\";";
C << eb;
if(p->isLocal())