From f683ef370bcb987a9f96fc5da0793d71e3721d29 Mon Sep 17 00:00:00 2001 From: Marc Laukien Date: Sun, 22 Sep 2002 15:44:10 +0000 Subject: thread fixes --- cpp/include/IceUtil/Base64.h | 76 +-- cpp/include/IceUtil/Cond.h | 668 ++++++++++++------------- cpp/include/IceUtil/Config.h | 288 +++++------ cpp/include/IceUtil/Exception.h | 138 ++---- cpp/include/IceUtil/Functional.h | 906 +++++++++++++++++----------------- cpp/include/IceUtil/Handle.h | 462 ++++++++--------- cpp/include/IceUtil/IceUtil.h | 64 +-- cpp/include/IceUtil/InputUtil.h | 130 ++--- cpp/include/IceUtil/Lock.h | 144 +++--- cpp/include/IceUtil/Monitor.h | 470 +++++++++--------- cpp/include/IceUtil/Mutex.h | 500 +++++++++---------- cpp/include/IceUtil/OutputUtil.h | 650 ++++++++++++------------ cpp/include/IceUtil/RWRecMutex.h | 512 +++++++++---------- cpp/include/IceUtil/RecMutex.h | 223 ++++----- cpp/include/IceUtil/Shared.h | 728 +++++++++++++-------------- cpp/include/IceUtil/Thread.h | 234 ++++----- cpp/include/IceUtil/ThreadException.h | 47 ++ cpp/include/IceUtil/Time.h | 126 ++--- cpp/include/IceUtil/UUID.h | 46 +- cpp/include/IceUtil/Unicode.h | 48 +- 20 files changed, 3238 insertions(+), 3222 deletions(-) create mode 100644 cpp/include/IceUtil/ThreadException.h (limited to 'cpp/include') diff --git a/cpp/include/IceUtil/Base64.h b/cpp/include/IceUtil/Base64.h index a4563e4cb8e..3e1dc03e8ee 100644 --- a/cpp/include/IceUtil/Base64.h +++ b/cpp/include/IceUtil/Base64.h @@ -1,38 +1,38 @@ -// ********************************************************************** -// -// Copyright (c) 2001 -// Mutable Realms, Inc. -// Huntsville, AL, USA -// -// All Rights Reserved -// -// ********************************************************************** - -#ifndef ICE_UTIL_BASE_64_H -#define ICE_UTIL_BASE_64_H - -#include -#include -#include - -namespace IceUtil -{ - -class ICE_UTIL_API Base64 -{ -public: - - static std::string encode(const std::vector&); - static std::vector decode(const std::string&); - - -private: - - static char encode(unsigned char); - static unsigned char decode(char); - static bool isBase64(char); -}; - -} - -#endif +// ********************************************************************** +// +// Copyright (c) 2001 +// Mutable Realms, Inc. +// Huntsville, AL, USA +// +// All Rights Reserved +// +// ********************************************************************** + +#ifndef ICE_UTIL_BASE_64_H +#define ICE_UTIL_BASE_64_H + +#include +#include +#include + +namespace IceUtil +{ + +class ICE_UTIL_API Base64 +{ +public: + + static std::string encode(const std::vector&); + static std::vector decode(const std::string&); + + +private: + + static char encode(unsigned char); + static unsigned char decode(char); + static bool isBase64(char); +}; + +} + +#endif diff --git a/cpp/include/IceUtil/Cond.h b/cpp/include/IceUtil/Cond.h index 5f4251530ed..c9ad5036ae3 100644 --- a/cpp/include/IceUtil/Cond.h +++ b/cpp/include/IceUtil/Cond.h @@ -1,334 +1,334 @@ -// ********************************************************************** -// -// Copyright (c) 2001 -// Mutable Realms, Inc. -// Huntsville, AL, USA -// -// All Rights Reserved -// -// ********************************************************************** - -#ifndef ICE_UTIL_COND_H -#define ICE_UTIL_COND_H - -#include -#include -#include - -#ifdef _WIN32 -// -// Needed for implementation under WIN32. -// -# include -// -// See member-template note for waitImpl & timedWaitImpl. -// -# include -#endif - -namespace IceUtil -{ - -// -// Forward declaration (for friend declarations). -// -template class Monitor; -class RecMutex; -class Mutex; - -#ifdef _WIN32 -// -// Needed for implementation. -// -class Semaphore -{ -public: - - Semaphore(long = 0); - ~Semaphore(); - - void wait() const; - bool timedWait(const Time&) const; - void post(int = 1) const; - -private: - - mutable HANDLE _sem; -}; -#endif - -// -// Condition variable implementation. Conforms to the same semantics -// as a POSIX threads condition variable. -// -class ICE_UTIL_API Cond : public noncopyable -{ -public: - - Cond(); - ~Cond(); - - // - // signal restarts one of the threads that are waiting on the - // condition variable cond. If no threads are waiting on cond, - // nothing happens. If several threads are waiting on cond, - // exactly one is restarted, but it is not specified which. - // - void signal(); - - // - // broadcast restarts all the threads that are waiting on the - // condition variable cond. Nothing happens if no threads are - // waiting on cond. - // - void broadcast(); - - // - // MSVC doesn't support out-of-class definitions of member - // templates. See KB Article Q241949 for details. - // - - // - // wait atomically unlocks the mutex and waits for the condition - // variable to be signaled. Before returning to the calling thread - // the mutex is reaquired. - // - template inline void - wait(const Lock& lock) const - { - waitImpl(lock._mutex); - } - - // - // wait atomically unlocks the mutex and waits for the condition - // variable to be signaled for up to the given timeout. Before - // returning to the calling thread the mutex is reaquired. Returns - // true if the condition variable was signaled, false on a - // timeout. - // - template inline bool - timedWait(const Lock& lock, const Time& timeout) const - { - return timedWaitImpl(lock._mutex, timeout); - } - -private: - - friend class Monitor; - friend class Monitor; - - // - // The Monitor implementation uses waitImpl & timedWaitImpl. - // -#ifdef _WIN32 - - // - // For some reason under WIN32 with VC6 using a member-template - // for waitImpl & timedWaitImpl results in a link error for - // RecMutex. - // -/* - template void - waitImpl(const M& mutex) const - { - preWait(); - - typedef typename M::LockState LockState; - - LockState state; - mutex.unlock(state); - - try - { - dowait(-1); - mutex.lock(state); - } - catch(...) - { - mutex.lock(state); - throw; - } - } - template bool - timedWaitImpl(const M& mutex, const Time& timeout) const - { - preWait(); - - typedef typename M::LockState LockState; - - LockState state; - mutex.unlock(state); - - try - { - bool rc = dowait(timeout); - mutex.lock(state); - return rc; - } - catch(...) - { - mutex.lock(state); - throw; - } - } - */ - - void - waitImpl(const RecMutex& mutex) const - { - preWait(); - - RecMutex::LockState state; - mutex.unlock(state); - - try - { - dowait(); - mutex.lock(state); - } - catch(...) - { - mutex.lock(state); - throw; - } - } - - void - waitImpl(const Mutex& mutex) const - { - preWait(); - - Mutex::LockState state; - mutex.unlock(state); - - try - { - dowait(); - mutex.lock(state); - } - catch(...) - { - mutex.lock(state); - throw; - } - } - - bool - timedWaitImpl(const RecMutex& mutex, const Time& timeout) const - { - preWait(); - - RecMutex::LockState state; - mutex.unlock(state); - - try - { - bool rc = timedDowait(timeout); - mutex.lock(state); - return rc; - } - catch(...) - { - mutex.lock(state); - throw; - } - } - - bool - timedWaitImpl(const Mutex& mutex, const Time& timeout) const - { - preWait(); - - Mutex::LockState state; - mutex.unlock(state); - - try - { - bool rc = timedDowait(timeout); - mutex.lock(state); - return rc; - } - catch(...) - { - mutex.lock(state); - throw; - } - } - -#else - - template void waitImpl(const M&) const; - template bool timedWaitImpl(const M&, const Time&) const; - -#endif - -#ifdef _WIN32 - void wake(bool); - void preWait() const; - void postWait(bool) const; - bool timedDowait(const Time&) const; - void dowait() const; - - Mutex _internal; - Semaphore _gate; - Semaphore _queue; - mutable long _blocked; - mutable long _unblocked; - mutable long _toUnblock; -#else - mutable pthread_cond_t _cond; -#endif - -}; - -#ifndef _WIN32 -template inline void -Cond::waitImpl(const M& mutex) const -{ - typedef typename M::LockState LockState; - - LockState state; - mutex.unlock(state); - int rc = pthread_cond_wait(&_cond, state.mutex); - mutex.lock(state); - - if(rc != 0) - { - throw SyscallException(strerror(rc), __FILE__, __LINE__); - } -} - -template inline bool -Cond::timedWaitImpl(const M& mutex, const Time& timeout) const -{ - typedef typename M::LockState LockState; - - LockState state; - mutex.unlock(state); - - timeval tv = Time::now() + timeout; - timespec ts; - ts.tv_sec = tv.tv_sec; - ts.tv_nsec = tv.tv_usec*1000; - int rc = pthread_cond_timedwait(&_cond, state.mutex, &ts); - mutex.lock(state); - - if(rc != 0) - { - // - // pthread_cond_timedwait returns ETIMEOUT in the event of a - // timeout. - // - if(rc != ETIMEDOUT) - { - throw SyscallException(strerror(rc), __FILE__, __LINE__); - } - return false; - } - return true; -} -#endif - -} // End namespace IceUtil - -#endif +// ********************************************************************** +// +// Copyright (c) 2001 +// Mutable Realms, Inc. +// Huntsville, AL, USA +// +// All Rights Reserved +// +// ********************************************************************** + +#ifndef ICE_UTIL_COND_H +#define ICE_UTIL_COND_H + +#include +#include +#include + +#ifdef _WIN32 +// +// Needed for implementation under WIN32. +// +# include +// +// See member-template note for waitImpl & timedWaitImpl. +// +# include +#endif + +namespace IceUtil +{ + +// +// Forward declaration (for friend declarations). +// +template class Monitor; +class RecMutex; +class Mutex; + +#ifdef _WIN32 +// +// Needed for implementation. +// +class Semaphore +{ +public: + + Semaphore(long = 0); + ~Semaphore(); + + void wait() const; + bool timedWait(const Time&) const; + void post(int = 1) const; + +private: + + mutable HANDLE _sem; +}; +#endif + +// +// Condition variable implementation. Conforms to the same semantics +// as a POSIX threads condition variable. +// +class ICE_UTIL_API Cond : public noncopyable +{ +public: + + Cond(); + ~Cond(); + + // + // signal restarts one of the threads that are waiting on the + // condition variable cond. If no threads are waiting on cond, + // nothing happens. If several threads are waiting on cond, + // exactly one is restarted, but it is not specified which. + // + void signal(); + + // + // broadcast restarts all the threads that are waiting on the + // condition variable cond. Nothing happens if no threads are + // waiting on cond. + // + void broadcast(); + + // + // MSVC doesn't support out-of-class definitions of member + // templates. See KB Article Q241949 for details. + // + + // + // wait atomically unlocks the mutex and waits for the condition + // variable to be signaled. Before returning to the calling thread + // the mutex is reaquired. + // + template inline void + wait(const Lock& lock) const + { + waitImpl(lock._mutex); + } + + // + // wait atomically unlocks the mutex and waits for the condition + // variable to be signaled for up to the given timeout. Before + // returning to the calling thread the mutex is reaquired. Returns + // true if the condition variable was signaled, false on a + // timeout. + // + template inline bool + timedWait(const Lock& lock, const Time& timeout) const + { + return timedWaitImpl(lock._mutex, timeout); + } + +private: + + friend class Monitor; + friend class Monitor; + + // + // The Monitor implementation uses waitImpl & timedWaitImpl. + // +#ifdef _WIN32 + + // + // For some reason under WIN32 with VC6 using a member-template + // for waitImpl & timedWaitImpl results in a link error for + // RecMutex. + // +/* + template void + waitImpl(const M& mutex) const + { + preWait(); + + typedef typename M::LockState LockState; + + LockState state; + mutex.unlock(state); + + try + { + dowait(-1); + mutex.lock(state); + } + catch(...) + { + mutex.lock(state); + throw; + } + } + template bool + timedWaitImpl(const M& mutex, const Time& timeout) const + { + preWait(); + + typedef typename M::LockState LockState; + + LockState state; + mutex.unlock(state); + + try + { + bool rc = dowait(timeout); + mutex.lock(state); + return rc; + } + catch(...) + { + mutex.lock(state); + throw; + } + } + */ + + void + waitImpl(const RecMutex& mutex) const + { + preWait(); + + RecMutex::LockState state; + mutex.unlock(state); + + try + { + dowait(); + mutex.lock(state); + } + catch(...) + { + mutex.lock(state); + throw; + } + } + + void + waitImpl(const Mutex& mutex) const + { + preWait(); + + Mutex::LockState state; + mutex.unlock(state); + + try + { + dowait(); + mutex.lock(state); + } + catch(...) + { + mutex.lock(state); + throw; + } + } + + bool + timedWaitImpl(const RecMutex& mutex, const Time& timeout) const + { + preWait(); + + RecMutex::LockState state; + mutex.unlock(state); + + try + { + bool rc = timedDowait(timeout); + mutex.lock(state); + return rc; + } + catch(...) + { + mutex.lock(state); + throw; + } + } + + bool + timedWaitImpl(const Mutex& mutex, const Time& timeout) const + { + preWait(); + + Mutex::LockState state; + mutex.unlock(state); + + try + { + bool rc = timedDowait(timeout); + mutex.lock(state); + return rc; + } + catch(...) + { + mutex.lock(state); + throw; + } + } + +#else + + template void waitImpl(const M&) const; + template bool timedWaitImpl(const M&, const Time&) const; + +#endif + +#ifdef _WIN32 + void wake(bool); + void preWait() const; + void postWait(bool) const; + bool timedDowait(const Time&) const; + void dowait() const; + + Mutex _internal; + Semaphore _gate; + Semaphore _queue; + mutable long _blocked; + mutable long _unblocked; + mutable long _toUnblock; +#else + mutable pthread_cond_t _cond; +#endif + +}; + +#ifndef _WIN32 +template inline void +Cond::waitImpl(const M& mutex) const +{ + typedef typename M::LockState LockState; + + LockState state; + mutex.unlock(state); + int rc = pthread_cond_wait(&_cond, state.mutex); + mutex.lock(state); + + if(rc != 0) + { + throw ThreadSyscallException(strerror(rc), __FILE__, __LINE__); + } +} + +template inline bool +Cond::timedWaitImpl(const M& mutex, const Time& timeout) const +{ + typedef typename M::LockState LockState; + + LockState state; + mutex.unlock(state); + + timeval tv = Time::now() + timeout; + timespec ts; + ts.tv_sec = tv.tv_sec; + ts.tv_nsec = tv.tv_usec*1000; + int rc = pthread_cond_timedwait(&_cond, state.mutex, &ts); + mutex.lock(state); + + if(rc != 0) + { + // + // pthread_cond_timedwait returns ETIMEOUT in the event of a + // timeout. + // + if(rc != ETIMEDOUT) + { + throw ThreadSyscallException(strerror(rc), __FILE__, __LINE__); + } + return false; + } + return true; +} +#endif + +} // End namespace IceUtil + +#endif diff --git a/cpp/include/IceUtil/Config.h b/cpp/include/IceUtil/Config.h index d555854f10c..81c63eb07a6 100644 --- a/cpp/include/IceUtil/Config.h +++ b/cpp/include/IceUtil/Config.h @@ -1,144 +1,144 @@ -// ********************************************************************** -// -// Copyright (c) 2001 -// Mutable Realms, Inc. -// Huntsville, AL, USA -// -// All Rights Reserved -// -// ********************************************************************** - -#ifndef ICE_UTIL_CONFIG_H -#define ICE_UTIL_CONFIG_H - -// -// For STLport. If we compile in debug mode, we want to use the debug -// STLport library. This is done by setting _STLP_DEBUG before any -// STLport header files are included. -// -# if !defined(NDEBUG) && !defined(_STLP_DEBUG) -# define _STLP_DEBUG -# endif - -// -// For STLport. If we compile in debug mode, we want to use the debug -// memory allocation, so that purify doesn't report bogus memory -// leaks. This is done by setting _STLP_USE_MALLOC before any STLport -// header files are included. -// -# if !defined(NDEBUG) && !defined(_STLP_USE_MALLOC) -# define _STLP_USE_MALLOC -# endif - -#if defined(_WIN32) - -// Necessary for TryEnterCriticalSection. -# define _WIN32_WINNT 0x0400 - -# if !defined(_UNICODE) -# error "Only unicode libraries can be used with Ice!" -# endif - -# if !defined(_DLL) || !defined(_MT) -# error "Only multi-threaded DLL libraries can be used with Ice!" -# endif - -# ifdef ICE_UTIL_API_EXPORTS -# define ICE_UTIL_API __declspec(dllexport) -# else -# define ICE_UTIL_API __declspec(dllimport) -# endif - -# include - -// '...' : forcing value to bool 'true' or 'false' (performance warning) -# pragma warning( disable : 4800 ) -// ... identifier was truncated to '255' characters in the debug information -# pragma warning( disable : 4786 ) -// 'this' : used in base member initializer list -# pragma warning( disable : 4355 ) -// class ... needs to have dll-interface to be used by clients of class ... -# pragma warning( disable : 4251 ) -// ... : inherits ... via dominance -# pragma warning( disable : 4250 ) -// non dll-interface class ... used as base for dll-interface class ... -# pragma warning( disable : 4275 ) -// ...: decorated name length exceeded, name was truncated -# pragma warning( disable : 4503 ) - -# define SIZEOF_WCHAR_T 2 - -#elif defined(__linux__) && defined(i386) - -# define ICE_UTIL_API /**/ -# define HAVE_READLINE -# define SIZEOF_WCHAR_T 4 - -#else - -# error "unsupported operating system or platform" - -#endif - -// -// Some include files we need almost everywhere -// -#include -#include -#include - -#ifndef _WIN32 -# ifndef _REENTRANT -# define _REENTRANT 1 -# endif -# include -# include -#endif - -// -// By deriving from this class, other classes are made non-copyable -// -namespace IceUtil -{ - -// -// TODO: Constructor and destructor should not be inlined, as they are -// not performance critical. -// -// TODO: Naming conventions? -// -class noncopyable -{ -protected: - - noncopyable() { } - ~noncopyable() { } // May not be virtual! Classes without virtual operations also derive from noncopyable. - -private: - - noncopyable(const noncopyable&); - const noncopyable& operator=(const noncopyable&); -}; -// -// -// Some definitions for 64-bit integers -// -#if defined(_WIN32) - typedef __int64 Int64; - const Int64 Int64Min = -9223372036854775808i64; - const Int64 Int64Max = 9223372036854775807i64; -#elif defined(__linux__) && defined(i386) - typedef long long Int64; - const Int64 Int64Min = LONGLONG_MIN; - const Int64 Int64Max = LONGLONG_MAX; -#endif - -} - -// -// The Ice version -// -#define ICE_STRING_VERSION "0.0.1" -#define ICE_INT_VERSION 0x00000001 - -#endif +// ********************************************************************** +// +// Copyright (c) 2001 +// Mutable Realms, Inc. +// Huntsville, AL, USA +// +// All Rights Reserved +// +// ********************************************************************** + +#ifndef ICE_UTIL_CONFIG_H +#define ICE_UTIL_CONFIG_H + +// +// For STLport. If we compile in debug mode, we want to use the debug +// STLport library. This is done by setting _STLP_DEBUG before any +// STLport header files are included. +// +# if !defined(NDEBUG) && !defined(_STLP_DEBUG) +# define _STLP_DEBUG +# endif + +// +// For STLport. If we compile in debug mode, we want to use the debug +// memory allocation, so that purify doesn't report bogus memory +// leaks. This is done by setting _STLP_USE_MALLOC before any STLport +// header files are included. +// +# if !defined(NDEBUG) && !defined(_STLP_USE_MALLOC) +# define _STLP_USE_MALLOC +# endif + +#if defined(_WIN32) + +// Necessary for TryEnterCriticalSection. +# define _WIN32_WINNT 0x0400 + +# if !defined(_UNICODE) +# error "Only unicode libraries can be used with Ice!" +# endif + +# if !defined(_DLL) || !defined(_MT) +# error "Only multi-threaded DLL libraries can be used with Ice!" +# endif + +# ifdef ICE_UTIL_API_EXPORTS +# define ICE_UTIL_API __declspec(dllexport) +# else +# define ICE_UTIL_API __declspec(dllimport) +# endif + +# include + +// '...' : forcing value to bool 'true' or 'false' (performance warning) +# pragma warning( disable : 4800 ) +// ... identifier was truncated to '255' characters in the debug information +# pragma warning( disable : 4786 ) +// 'this' : used in base member initializer list +# pragma warning( disable : 4355 ) +// class ... needs to have dll-interface to be used by clients of class ... +# pragma warning( disable : 4251 ) +// ... : inherits ... via dominance +# pragma warning( disable : 4250 ) +// non dll-interface class ... used as base for dll-interface class ... +# pragma warning( disable : 4275 ) +// ...: decorated name length exceeded, name was truncated +# pragma warning( disable : 4503 ) + +# define SIZEOF_WCHAR_T 2 + +#elif defined(__linux__) && defined(i386) + +# define ICE_UTIL_API /**/ +# define HAVE_READLINE +# define SIZEOF_WCHAR_T 4 + +#else + +# error "unsupported operating system or platform" + +#endif + +// +// Some include files we need almost everywhere +// +#include +#include +#include + +#ifndef _WIN32 +# ifndef _REENTRANT +# define _REENTRANT 1 +# endif +# include +# include +#endif + +// +// By deriving from this class, other classes are made non-copyable +// +namespace IceUtil +{ + +// +// TODO: Constructor and destructor should not be inlined, as they are +// not performance critical. +// +// TODO: Naming conventions? +// +class noncopyable +{ +protected: + + noncopyable() { } + ~noncopyable() { } // May not be virtual! Classes without virtual operations also derive from noncopyable. + +private: + + noncopyable(const noncopyable&); + const noncopyable& operator=(const noncopyable&); +}; +// +// +// Some definitions for 64-bit integers +// +#if defined(_WIN32) + typedef __int64 Int64; + const Int64 Int64Min = -9223372036854775808i64; + const Int64 Int64Max = 9223372036854775807i64; +#elif defined(__linux__) && defined(i386) + typedef long long Int64; + const Int64 Int64Min = LONGLONG_MIN; + const Int64 Int64Max = LONGLONG_MAX; +#endif + +} + +// +// The Ice version +// +#define ICE_STRING_VERSION "0.0.1" +#define ICE_INT_VERSION 0x00000001 + +#endif diff --git a/cpp/include/IceUtil/Exception.h b/cpp/include/IceUtil/Exception.h index 42f1e9505ba..c694cceea23 100644 --- a/cpp/include/IceUtil/Exception.h +++ b/cpp/include/IceUtil/Exception.h @@ -1,85 +1,53 @@ -// ********************************************************************** -// -// Copyright (c) 2001 -// Mutable Realms, Inc. -// Huntsville, AL, USA -// -// All Rights Reserved -// -// ********************************************************************** - -#ifndef ICE_UTIL_EXCEPTION_H -#define ICE_UTIL_EXCEPTION_H - -#include - -namespace IceUtil -{ - -class ICE_UTIL_API Exception -{ -public: - - Exception(); - Exception(const char*, int); - virtual ~Exception(); - virtual std::string ice_name() const; - virtual void ice_print(std::ostream&) const; - virtual Exception* ice_clone() const; - virtual void ice_throw() const; - const char* ice_file() const; - int ice_line() const; - -private: - - const char* _file; - int _line; -}; - -ICE_UTIL_API std::ostream& operator<<(std::ostream&, const Exception&); - -class ICE_UTIL_API NullHandleException : public Exception -{ -public: - - NullHandleException(const char*, int); - virtual std::string ice_name() const; - virtual Exception* ice_clone() const; - virtual void ice_throw() const; -}; - -class ICE_UTIL_API SyscallException : public Exception -{ -public: - - SyscallException(const std::string&, const char*, int); - virtual std::string ice_name() const; - virtual void ice_print(std::ostream&) const; - virtual Exception* ice_clone() const; - virtual void ice_throw() const; - -#ifdef _WIN32 - // - // IceInternal::errorToString does the same thing... refactor? - // - static std::string errorToString(DWORD); -#endif - -private: - - std::string _error; -}; - -class ICE_UTIL_API LockedException : public Exception -{ -public: - - LockedException(const char*, int); - virtual std::string ice_name() const; - virtual Exception* ice_clone() const; - virtual void ice_throw() const; -}; - -} - -#endif +// ********************************************************************** +// +// Copyright (c) 2001 +// Mutable Realms, Inc. +// Huntsville, AL, USA +// +// All Rights Reserved +// +// ********************************************************************** + +#ifndef ICE_UTIL_EXCEPTION_H +#define ICE_UTIL_EXCEPTION_H + +#include + +namespace IceUtil +{ + +class ICE_UTIL_API Exception +{ +public: + + Exception(); + Exception(const char*, int); + virtual ~Exception(); + virtual std::string ice_name() const; + virtual void ice_print(std::ostream&) const; + virtual Exception* ice_clone() const; + virtual void ice_throw() const; + const char* ice_file() const; + int ice_line() const; + +private: + + const char* _file; + int _line; +}; + +ICE_UTIL_API std::ostream& operator<<(std::ostream&, const Exception&); + +class ICE_UTIL_API NullHandleException : public Exception +{ +public: + + NullHandleException(const char*, int); + virtual std::string ice_name() const; + virtual Exception* ice_clone() const; + virtual void ice_throw() const; +}; + +} + +#endif diff --git a/cpp/include/IceUtil/Functional.h b/cpp/include/IceUtil/Functional.h index bf8b4ceac65..57b0df17243 100644 --- a/cpp/include/IceUtil/Functional.h +++ b/cpp/include/IceUtil/Functional.h @@ -1,453 +1,453 @@ -// ********************************************************************** -// -// Copyright (c) 2001 -// Mutable Realms, Inc. -// Huntsville, AL, USA -// -// All Rights Reserved -// -// ********************************************************************** - -#ifndef ICE_UTIL_FUNCTIONAL_H -#define ICE_UTIL_FUNCTIONAL_H - -#include -#include - -namespace IceUtilInternal -{ - -// ---------------------------------------------------------------------- -// Various function objects that work with handles instead of plain -// pointers. -// ---------------------------------------------------------------------- - -template -class MemFun : public std::unary_function -{ - typedef R (T::*MemberFN)(void); - MemberFN _mfn; - -public: - - explicit MemFun(MemberFN p) : _mfn(p) { } - R operator()(H handle) const - { - return (handle.get() ->* _mfn)(); - } -}; - -template -class MemFun1 : public std::binary_function -{ - typedef R (T::*MemberFN)(A); - MemberFN _mfn; - -public: - - explicit MemFun1(MemberFN p) : _mfn(p) { } - R operator()(H handle, A arg) const - { - return (handle.get() ->* _mfn)(arg); - } -}; - -template -class VoidMemFun : public std::unary_function -{ - typedef void (T::*MemberFN)(void); - MemberFN _mfn; - -public: - - explicit VoidMemFun(MemberFN p) : _mfn(p) { } - void operator()(H handle) const - { - (handle.get() ->* _mfn)(); - } -}; - -template -class VoidMemFun1 : public std::binary_function -{ - typedef void (T::*MemberFN)(A); - MemberFN _mfn; - -public: - - explicit VoidMemFun1(MemberFN p) : _mfn(p) { } - void operator()(H handle, A arg) const - { - (handle.get() ->* _mfn)(arg); - } -}; - -template -class SecondMemFun : public std::unary_function, R> -{ - typedef R (T::*MemberFN)(void); - MemberFN _mfn; - -public: - - explicit SecondMemFun(MemberFN p) : _mfn(p) { } - R operator()(std::pair pair) const - { - return (pair.second.get() ->* _mfn)(); - } -}; - -template -class SecondMemFun1 : public std::binary_function, A, R> -{ - typedef R (T::*MemberFN)(A); - MemberFN _mfn; - -public: - - explicit SecondMemFun1(MemberFN p) : _mfn(p) { } - R operator()(std::pair pair, A arg) const - { - return (pair.second.get() ->* _mfn)(arg); - } -}; - -template -class SecondVoidMemFun : public std::unary_function, void> -{ - typedef void (T::*MemberFN)(void); - MemberFN _mfn; - -public: - - explicit SecondVoidMemFun(MemberFN p) : _mfn(p) { } - void operator()(std::pair pair) const - { - (pair.second.get() ->* _mfn)(); - } -}; - -template -class SecondVoidMemFun1 : public std::binary_function, A, void> -{ - typedef void (T::*MemberFN)(A); - MemberFN _mfn; - -public: - - explicit SecondVoidMemFun1(MemberFN p) : _mfn(p) { } - void operator()(std::pair pair, A arg) const - { - (pair.second.get() ->* _mfn)(arg); - } -}; - -template -class ConstMemFun : public std::unary_function -{ - typedef R (T::*MemberFN)(void) const; - MemberFN _mfn; - -public: - - explicit ConstMemFun(MemberFN p) : _mfn(p) { } - R operator()(H handle) const - { - return (handle.get() ->* _mfn)(); - } -}; - -template -class ConstMemFun1 : public std::binary_function -{ - typedef R (T::*MemberFN)(A) const; - MemberFN _mfn; - -public: - - explicit ConstMemFun1(MemberFN p) : _mfn(p) { } - R operator()(H handle, A arg) const - { - return (handle.get() ->* _mfn)(arg); - } -}; - -template -class ConstVoidMemFun : public std::unary_function -{ - typedef void (T::*MemberFN)(void) const; - MemberFN _mfn; - -public: - - explicit ConstVoidMemFun(MemberFN p) : _mfn(p) { } - void operator()(H handle) const - { - (handle.get() ->* _mfn)(); - } -}; - -template -class ConstVoidMemFun1 : public std::binary_function -{ - typedef void (T::*MemberFN)(A) const; - MemberFN _mfn; - -public: - - explicit ConstVoidMemFun1(MemberFN p) : _mfn(p) { } - void operator()(H handle, A arg) const - { - (handle.get() ->* _mfn)(arg); - } -}; - -template -class SecondConstMemFun : public std::unary_function, R> -{ - typedef R (T::*MemberFN)(void) const; - MemberFN _mfn; - -public: - - explicit SecondConstMemFun(MemberFN p) : _mfn(p) { } - R operator()(std::pair pair) const - { - return (pair.second.get() ->* _mfn)(); - } -}; - -template -class SecondConstMemFun1 : public std::binary_function, A, R> -{ - typedef R (T::*MemberFN)(A) const; - MemberFN _mfn; - -public: - - explicit SecondConstMemFun1(MemberFN p) : _mfn(p) { } - R operator()(std::pair pair, A arg) const - { - return (pair.second.get() ->* _mfn)(arg); - } -}; - -template -class SecondConstVoidMemFun : public std::unary_function, void> -{ - typedef void (T::*MemberFN)(void) const; - MemberFN _mfn; - -public: - - explicit SecondConstVoidMemFun(MemberFN p) : _mfn(p) { } - void operator()(std::pair pair) const - { - (pair.second.get() ->* _mfn)(); - } -}; - -template -class SecondConstVoidMemFun1 : public std::binary_function, A, void> -{ - typedef void (T::*MemberFN)(A) const; - MemberFN _mfn; - -public: - - explicit SecondConstVoidMemFun1(MemberFN p) : _mfn(p) { } - void operator()(std::pair pair, A arg) const - { - (pair.second.get() ->* _mfn)(arg); - } -}; - -} - -// ---------------------------------------------------------------------- -// Inline functions that return function objects that work with -// IceUtil::Handle -// ---------------------------------------------------------------------- - -namespace IceUtil -{ - -template -inline ::IceUtilInternal::MemFun > -memFun(R (T::*p)(void)) -{ - return ::IceUtilInternal::MemFun >(p); -} - -template -inline ::IceUtilInternal::MemFun1, A> -memFun1(R (T::*p)(A)) -{ - return ::IceUtilInternal::MemFun1, A>(p); -} - -template -inline ::IceUtilInternal::VoidMemFun > -voidMemFun(void (T::*p)(void)) -{ - return ::IceUtilInternal::VoidMemFun >(p); -} - -template -inline ::IceUtilInternal::VoidMemFun1, A> -voidMemFun1(void (T::*p)(A)) -{ - return ::IceUtilInternal::VoidMemFun1, A>(p); -} - -template -inline ::IceUtilInternal::SecondMemFun > -secondMemFun(R (T::*p)(void)) -{ - return ::IceUtilInternal::SecondMemFun >(p); -} - -template -inline ::IceUtilInternal::SecondMemFun1, A> -secondMemFun1(R (T::*p)(A)) -{ - return ::IceUtilInternal::SecondMemFun1, A>(p); -} - -template -inline ::IceUtilInternal::SecondVoidMemFun > -secondVoidMemFun(void (T::*p)(void)) -{ - return ::IceUtilInternal::SecondVoidMemFun >(p); -} - -template -inline ::IceUtilInternal::SecondVoidMemFun1, A> -secondVoidMemFun1(void (T::*p)(A)) -{ - return ::IceUtilInternal::SecondVoidMemFun1, A>(p); -} - -template -inline ::IceUtilInternal::ConstMemFun > -constMemFun(R (T::*p)(void) const) -{ - return ::IceUtilInternal::ConstMemFun >(p); -} - -template -inline ::IceUtilInternal::ConstMemFun1, A> -constMemFun1(R (T::*p)(A) const) -{ - return ::IceUtilInternal::ConstMemFun1, A>(p); -} - -template -inline ::IceUtilInternal::ConstVoidMemFun > -constVoidMemFun(void (T::*p)(void) const) -{ - return ::IceUtilInternal::ConstVoidMemFun >(p); -} - -template -inline ::IceUtilInternal::ConstVoidMemFun1, A> -constVoidMemFun1(void (T::*p)(A) const) -{ - return ::IceUtilInternal::ConstVoidMemFun1, A>(p); -} - -template -inline ::IceUtilInternal::SecondConstMemFun > -secondConstMemFun(R (T::*p)(void) const) -{ - return ::IceUtilInternal::SecondConstMemFun >(p); -} - -template -inline ::IceUtilInternal::SecondConstMemFun1, A> -secondConstMemFun1(R (T::*p)(A) const) -{ - return ::IceUtilInternal::SecondConstMemFun1, A>(p); -} - -template -inline ::IceUtilInternal::SecondConstVoidMemFun > -secondConstVoidMemFun(void (T::*p)(void) const) -{ - return ::IceUtilInternal::SecondConstVoidMemFun >(p); -} - -template -inline ::IceUtilInternal::SecondConstVoidMemFun1, A> -secondConstVoidMemFun1(void (T::*p)(A) const) -{ - return ::IceUtilInternal::SecondConstVoidMemFun1, A>(p); -} - -} - -// ---------------------------------------------------------------------- -// Extension for STLport: Special versions for bind1st and bind2nd for -// operations that do not return anything (i.e., return void). Needed -// for broken compilers, such as Visual C++ -// ---------------------------------------------------------------------- - -#ifdef _STLP_BEGIN_NAMESPACE - -_STLP_BEGIN_NAMESPACE - -template -class voidbinder1st : - public unary_function { -protected: - _Operation _M_op; - typename _Operation::first_argument_type _M_value; -public: - voidbinder1st(const _Operation& __x, - const typename _Operation::first_argument_type& __y) - : _M_op(__x), _M_value(__y) {} - typename _Operation::result_type - operator()(const typename _Operation::second_argument_type& __x) const { - _M_op(_M_value, __x); - } -}; - -template -inline voidbinder1st<_Operation> -voidbind1st(const _Operation& __fn, const _Tp& __x) -{ - typedef typename _Operation::first_argument_type _Arg1_type; - return voidbinder1st<_Operation>(__fn, _Arg1_type(__x)); -} - -template -class voidbinder2nd - : public unary_function { -protected: - _Operation _M_op; - typename _Operation::second_argument_type value; -public: - voidbinder2nd(const _Operation& __x, - const typename _Operation::second_argument_type& __y) - : _M_op(__x), value(__y) {} - typename _Operation::result_type - operator()(const typename _Operation::first_argument_type& __x) const { - _M_op(__x, value); - } -}; - -template -inline voidbinder2nd<_Operation> -voidbind2nd(const _Operation& __fn, const _Tp& __x) -{ - typedef typename _Operation::second_argument_type _Arg2_type; - return voidbinder2nd<_Operation>(__fn, _Arg2_type(__x)); -} - -_STLP_END_NAMESPACE - -#endif - -#endif +// ********************************************************************** +// +// Copyright (c) 2001 +// Mutable Realms, Inc. +// Huntsville, AL, USA +// +// All Rights Reserved +// +// ********************************************************************** + +#ifndef ICE_UTIL_FUNCTIONAL_H +#define ICE_UTIL_FUNCTIONAL_H + +#include +#include + +namespace IceUtilInternal +{ + +// ---------------------------------------------------------------------- +// Various function objects that work with handles instead of plain +// pointers. +// ---------------------------------------------------------------------- + +template +class MemFun : public std::unary_function +{ + typedef R (T::*MemberFN)(void); + MemberFN _mfn; + +public: + + explicit MemFun(MemberFN p) : _mfn(p) { } + R operator()(H handle) const + { + return (handle.get() ->* _mfn)(); + } +}; + +template +class MemFun1 : public std::binary_function +{ + typedef R (T::*MemberFN)(A); + MemberFN _mfn; + +public: + + explicit MemFun1(MemberFN p) : _mfn(p) { } + R operator()(H handle, A arg) const + { + return (handle.get() ->* _mfn)(arg); + } +}; + +template +class VoidMemFun : public std::unary_function +{ + typedef void (T::*MemberFN)(void); + MemberFN _mfn; + +public: + + explicit VoidMemFun(MemberFN p) : _mfn(p) { } + void operator()(H handle) const + { + (handle.get() ->* _mfn)(); + } +}; + +template +class VoidMemFun1 : public std::binary_function +{ + typedef void (T::*MemberFN)(A); + MemberFN _mfn; + +public: + + explicit VoidMemFun1(MemberFN p) : _mfn(p) { } + void operator()(H handle, A arg) const + { + (handle.get() ->* _mfn)(arg); + } +}; + +template +class SecondMemFun : public std::unary_function, R> +{ + typedef R (T::*MemberFN)(void); + MemberFN _mfn; + +public: + + explicit SecondMemFun(MemberFN p) : _mfn(p) { } + R operator()(std::pair pair) const + { + return (pair.second.get() ->* _mfn)(); + } +}; + +template +class SecondMemFun1 : public std::binary_function, A, R> +{ + typedef R (T::*MemberFN)(A); + MemberFN _mfn; + +public: + + explicit SecondMemFun1(MemberFN p) : _mfn(p) { } + R operator()(std::pair pair, A arg) const + { + return (pair.second.get() ->* _mfn)(arg); + } +}; + +template +class SecondVoidMemFun : public std::unary_function, void> +{ + typedef void (T::*MemberFN)(void); + MemberFN _mfn; + +public: + + explicit SecondVoidMemFun(MemberFN p) : _mfn(p) { } + void operator()(std::pair pair) const + { + (pair.second.get() ->* _mfn)(); + } +}; + +template +class SecondVoidMemFun1 : public std::binary_function, A, void> +{ + typedef void (T::*MemberFN)(A); + MemberFN _mfn; + +public: + + explicit SecondVoidMemFun1(MemberFN p) : _mfn(p) { } + void operator()(std::pair pair, A arg) const + { + (pair.second.get() ->* _mfn)(arg); + } +}; + +template +class ConstMemFun : public std::unary_function +{ + typedef R (T::*MemberFN)(void) const; + MemberFN _mfn; + +public: + + explicit ConstMemFun(MemberFN p) : _mfn(p) { } + R operator()(H handle) const + { + return (handle.get() ->* _mfn)(); + } +}; + +template +class ConstMemFun1 : public std::binary_function +{ + typedef R (T::*MemberFN)(A) const; + MemberFN _mfn; + +public: + + explicit ConstMemFun1(MemberFN p) : _mfn(p) { } + R operator()(H handle, A arg) const + { + return (handle.get() ->* _mfn)(arg); + } +}; + +template +class ConstVoidMemFun : public std::unary_function +{ + typedef void (T::*MemberFN)(void) const; + MemberFN _mfn; + +public: + + explicit ConstVoidMemFun(MemberFN p) : _mfn(p) { } + void operator()(H handle) const + { + (handle.get() ->* _mfn)(); + } +}; + +template +class ConstVoidMemFun1 : public std::binary_function +{ + typedef void (T::*MemberFN)(A) const; + MemberFN _mfn; + +public: + + explicit ConstVoidMemFun1(MemberFN p) : _mfn(p) { } + void operator()(H handle, A arg) const + { + (handle.get() ->* _mfn)(arg); + } +}; + +template +class SecondConstMemFun : public std::unary_function, R> +{ + typedef R (T::*MemberFN)(void) const; + MemberFN _mfn; + +public: + + explicit SecondConstMemFun(MemberFN p) : _mfn(p) { } + R operator()(std::pair pair) const + { + return (pair.second.get() ->* _mfn)(); + } +}; + +template +class SecondConstMemFun1 : public std::binary_function, A, R> +{ + typedef R (T::*MemberFN)(A) const; + MemberFN _mfn; + +public: + + explicit SecondConstMemFun1(MemberFN p) : _mfn(p) { } + R operator()(std::pair pair, A arg) const + { + return (pair.second.get() ->* _mfn)(arg); + } +}; + +template +class SecondConstVoidMemFun : public std::unary_function, void> +{ + typedef void (T::*MemberFN)(void) const; + MemberFN _mfn; + +public: + + explicit SecondConstVoidMemFun(MemberFN p) : _mfn(p) { } + void operator()(std::pair pair) const + { + (pair.second.get() ->* _mfn)(); + } +}; + +template +class SecondConstVoidMemFun1 : public std::binary_function, A, void> +{ + typedef void (T::*MemberFN)(A) const; + MemberFN _mfn; + +public: + + explicit SecondConstVoidMemFun1(MemberFN p) : _mfn(p) { } + void operator()(std::pair pair, A arg) const + { + (pair.second.get() ->* _mfn)(arg); + } +}; + +} + +// ---------------------------------------------------------------------- +// Inline functions that return function objects that work with +// IceUtil::Handle +// ---------------------------------------------------------------------- + +namespace IceUtil +{ + +template +inline ::IceUtilInternal::MemFun > +memFun(R (T::*p)(void)) +{ + return ::IceUtilInternal::MemFun >(p); +} + +template +inline ::IceUtilInternal::MemFun1, A> +memFun1(R (T::*p)(A)) +{ + return ::IceUtilInternal::MemFun1, A>(p); +} + +template +inline ::IceUtilInternal::VoidMemFun > +voidMemFun(void (T::*p)(void)) +{ + return ::IceUtilInternal::VoidMemFun >(p); +} + +template +inline ::IceUtilInternal::VoidMemFun1, A> +voidMemFun1(void (T::*p)(A)) +{ + return ::IceUtilInternal::VoidMemFun1, A>(p); +} + +template +inline ::IceUtilInternal::SecondMemFun > +secondMemFun(R (T::*p)(void)) +{ + return ::IceUtilInternal::SecondMemFun >(p); +} + +template +inline ::IceUtilInternal::SecondMemFun1, A> +secondMemFun1(R (T::*p)(A)) +{ + return ::IceUtilInternal::SecondMemFun1, A>(p); +} + +template +inline ::IceUtilInternal::SecondVoidMemFun > +secondVoidMemFun(void (T::*p)(void)) +{ + return ::IceUtilInternal::SecondVoidMemFun >(p); +} + +template +inline ::IceUtilInternal::SecondVoidMemFun1, A> +secondVoidMemFun1(void (T::*p)(A)) +{ + return ::IceUtilInternal::SecondVoidMemFun1, A>(p); +} + +template +inline ::IceUtilInternal::ConstMemFun > +constMemFun(R (T::*p)(void) const) +{ + return ::IceUtilInternal::ConstMemFun >(p); +} + +template +inline ::IceUtilInternal::ConstMemFun1, A> +constMemFun1(R (T::*p)(A) const) +{ + return ::IceUtilInternal::ConstMemFun1, A>(p); +} + +template +inline ::IceUtilInternal::ConstVoidMemFun > +constVoidMemFun(void (T::*p)(void) const) +{ + return ::IceUtilInternal::ConstVoidMemFun >(p); +} + +template +inline ::IceUtilInternal::ConstVoidMemFun1, A> +constVoidMemFun1(void (T::*p)(A) const) +{ + return ::IceUtilInternal::ConstVoidMemFun1, A>(p); +} + +template +inline ::IceUtilInternal::SecondConstMemFun > +secondConstMemFun(R (T::*p)(void) const) +{ + return ::IceUtilInternal::SecondConstMemFun >(p); +} + +template +inline ::IceUtilInternal::SecondConstMemFun1, A> +secondConstMemFun1(R (T::*p)(A) const) +{ + return ::IceUtilInternal::SecondConstMemFun1, A>(p); +} + +template +inline ::IceUtilInternal::SecondConstVoidMemFun > +secondConstVoidMemFun(void (T::*p)(void) const) +{ + return ::IceUtilInternal::SecondConstVoidMemFun >(p); +} + +template +inline ::IceUtilInternal::SecondConstVoidMemFun1, A> +secondConstVoidMemFun1(void (T::*p)(A) const) +{ + return ::IceUtilInternal::SecondConstVoidMemFun1, A>(p); +} + +} + +// ---------------------------------------------------------------------- +// Extension for STLport: Special versions for bind1st and bind2nd for +// operations that do not return anything (i.e., return void). Needed +// for broken compilers, such as Visual C++ +// ---------------------------------------------------------------------- + +#ifdef _STLP_BEGIN_NAMESPACE + +_STLP_BEGIN_NAMESPACE + +template +class voidbinder1st : + public unary_function { +protected: + _Operation _M_op; + typename _Operation::first_argument_type _M_value; +public: + voidbinder1st(const _Operation& __x, + const typename _Operation::first_argument_type& __y) + : _M_op(__x), _M_value(__y) {} + typename _Operation::result_type + operator()(const typename _Operation::second_argument_type& __x) const { + _M_op(_M_value, __x); + } +}; + +template +inline voidbinder1st<_Operation> +voidbind1st(const _Operation& __fn, const _Tp& __x) +{ + typedef typename _Operation::first_argument_type _Arg1_type; + return voidbinder1st<_Operation>(__fn, _Arg1_type(__x)); +} + +template +class voidbinder2nd + : public unary_function { +protected: + _Operation _M_op; + typename _Operation::second_argument_type value; +public: + voidbinder2nd(const _Operation& __x, + const typename _Operation::second_argument_type& __y) + : _M_op(__x), value(__y) {} + typename _Operation::result_type + operator()(const typename _Operation::first_argument_type& __x) const { + _M_op(__x, value); + } +}; + +template +inline voidbinder2nd<_Operation> +voidbind2nd(const _Operation& __fn, const _Tp& __x) +{ + typedef typename _Operation::second_argument_type _Arg2_type; + return voidbinder2nd<_Operation>(__fn, _Arg2_type(__x)); +} + +_STLP_END_NAMESPACE + +#endif + +#endif diff --git a/cpp/include/IceUtil/Handle.h b/cpp/include/IceUtil/Handle.h index b9b625ac1bd..de901a65835 100644 --- a/cpp/include/IceUtil/Handle.h +++ b/cpp/include/IceUtil/Handle.h @@ -1,231 +1,231 @@ -// ********************************************************************** -// -// Copyright (c) 2001 -// Mutable Realms, Inc. -// Huntsville, AL, USA -// -// All Rights Reserved -// -// ********************************************************************** - -#ifndef ICE_UTIL_HANDLE_H -#define ICE_UTIL_HANDLE_H - -#include -#include - -// -// "Handle" or "smart pointer" class for classes derived from -// IceUtil::Shared or IceUtil::SimpleShared. -// -namespace IceUtil -{ - -template -class HandleBase -{ -public: - - typedef T element_type; - - T* get() const - { - return _ptr; - } - - T* operator->() const - { - if(!_ptr) - { - throw NullHandleException(__FILE__, __LINE__); - } - - return _ptr; - } - - operator bool() const - { - return _ptr ? true : false; - } - - void swap(HandleBase& other) - { - std::swap(_ptr, other._ptr); - } - - T* _ptr; -}; - -template -inline bool operator==(const HandleBase& lhs, const HandleBase& rhs) -{ - T* l = lhs.get(); - U* r = rhs.get(); - if(l && r) - { - return *l == *r; - } - else - { - return !l && !r; - } -} - -template -inline bool operator!=(const HandleBase& lhs, const HandleBase& rhs) -{ - T* l = lhs.get(); - U* r = rhs.get(); - if(l && r) - { - return *l != *r; - } - else - { - return l || r; - } -} - -template -inline bool operator<(const HandleBase& lhs, const HandleBase& rhs) -{ - T* l = lhs.get(); - U* r = rhs.get(); - if(l && r) - { - return *l < *r; - } - else - { - return !l && r; - } -} - -template -class Handle : public HandleBase -{ -public: - - Handle(T* p = 0) - { - _ptr = p; - - if(_ptr) - { - _ptr->__incRef(); - } - } - - template - Handle(const Handle& r) - { - _ptr = r._ptr; - - if(_ptr) - { - _ptr->__incRef(); - } - } - -#ifdef _WIN32 // COMPILERBUG: Is VC++ or GNU C++ right here??? - template<> - Handle(const Handle& r) -#else - Handle(const Handle& r) -#endif - { - _ptr = r._ptr; - - if(_ptr) - { - _ptr->__incRef(); - } - } - - ~Handle() - { - if(_ptr) - { - _ptr->__decRef(); - } - } - - Handle& operator=(T* p) - { - if(_ptr != p) - { - if(p) - { - p->__incRef(); - } - - if(_ptr) - { - _ptr->__decRef(); - } - - _ptr = p; - } - return *this; - } - - template - Handle& operator=(const Handle& r) - { - if(_ptr != r._ptr) - { - if(r._ptr) - { - r._ptr->__incRef(); - } - - if(_ptr) - { - _ptr->__decRef(); - } - - _ptr = r._ptr; - } - return *this; - } - -#ifdef _WIN32 // COMPILERBUG: Is VC++ or GNU C++ right here??? - template<> - Handle& operator=(const Handle& r) -#else - Handle& operator=(const Handle& r) -#endif - { - if(_ptr != r._ptr) - { - if(r._ptr) - { - r._ptr->__incRef(); - } - - if(_ptr) - { - _ptr->__decRef(); - } - - _ptr = r._ptr; - } - return *this; - } - - template - static Handle dynamicCast(const HandleBase& r) - { - return Handle(dynamic_cast(r._ptr)); - } - - template - static Handle dynamicCast(Y* p) - { - return Handle(dynamic_cast(p)); - } -}; - -} - -#endif +// ********************************************************************** +// +// Copyright (c) 2001 +// Mutable Realms, Inc. +// Huntsville, AL, USA +// +// All Rights Reserved +// +// ********************************************************************** + +#ifndef ICE_UTIL_HANDLE_H +#define ICE_UTIL_HANDLE_H + +#include +#include + +// +// "Handle" or "smart pointer" class for classes derived from +// IceUtil::Shared or IceUtil::SimpleShared. +// +namespace IceUtil +{ + +template +class HandleBase +{ +public: + + typedef T element_type; + + T* get() const + { + return _ptr; + } + + T* operator->() const + { + if(!_ptr) + { + throw NullHandleException(__FILE__, __LINE__); + } + + return _ptr; + } + + operator bool() const + { + return _ptr ? true : false; + } + + void swap(HandleBase& other) + { + std::swap(_ptr, other._ptr); + } + + T* _ptr; +}; + +template +inline bool operator==(const HandleBase& lhs, const HandleBase& rhs) +{ + T* l = lhs.get(); + U* r = rhs.get(); + if(l && r) + { + return *l == *r; + } + else + { + return !l && !r; + } +} + +template +inline bool operator!=(const HandleBase& lhs, const HandleBase& rhs) +{ + T* l = lhs.get(); + U* r = rhs.get(); + if(l && r) + { + return *l != *r; + } + else + { + return l || r; + } +} + +template +inline bool operator<(const HandleBase& lhs, const HandleBase& rhs) +{ + T* l = lhs.get(); + U* r = rhs.get(); + if(l && r) + { + return *l < *r; + } + else + { + return !l && r; + } +} + +template +class Handle : public HandleBase +{ +public: + + Handle(T* p = 0) + { + _ptr = p; + + if(_ptr) + { + _ptr->__incRef(); + } + } + + template + Handle(const Handle& r) + { + _ptr = r._ptr; + + if(_ptr) + { + _ptr->__incRef(); + } + } + +#ifdef _WIN32 // COMPILERBUG: Is VC++ or GNU C++ right here??? + template<> + Handle(const Handle& r) +#else + Handle(const Handle& r) +#endif + { + _ptr = r._ptr; + + if(_ptr) + { + _ptr->__incRef(); + } + } + + ~Handle() + { + if(_ptr) + { + _ptr->__decRef(); + } + } + + Handle& operator=(T* p) + { + if(_ptr != p) + { + if(p) + { + p->__incRef(); + } + + if(_ptr) + { + _ptr->__decRef(); + } + + _ptr = p; + } + return *this; + } + + template + Handle& operator=(const Handle& r) + { + if(_ptr != r._ptr) + { + if(r._ptr) + { + r._ptr->__incRef(); + } + + if(_ptr) + { + _ptr->__decRef(); + } + + _ptr = r._ptr; + } + return *this; + } + +#ifdef _WIN32 // COMPILERBUG: Is VC++ or GNU C++ right here??? + template<> + Handle& operator=(const Handle& r) +#else + Handle& operator=(const Handle& r) +#endif + { + if(_ptr != r._ptr) + { + if(r._ptr) + { + r._ptr->__incRef(); + } + + if(_ptr) + { + _ptr->__decRef(); + } + + _ptr = r._ptr; + } + return *this; + } + + template + static Handle dynamicCast(const HandleBase& r) + { + return Handle(dynamic_cast(r._ptr)); + } + + template + static Handle dynamicCast(Y* p) + { + return Handle(dynamic_cast(p)); + } +}; + +} + +#endif diff --git a/cpp/include/IceUtil/IceUtil.h b/cpp/include/IceUtil/IceUtil.h index 64497d6a393..5821455d840 100644 --- a/cpp/include/IceUtil/IceUtil.h +++ b/cpp/include/IceUtil/IceUtil.h @@ -1,32 +1,32 @@ -// ********************************************************************** -// -// Copyright (c) 2001 -// Mutable Realms, Inc. -// Huntsville, AL, USA -// -// All Rights Reserved -// -// ********************************************************************** - -#ifndef ICE_UTIL_ICE_UTIL_H -#define ICE_UTIL_ICE_UTIL_H - -// -// This file must include *all* other headers of IceUtil. -// - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#endif +// ********************************************************************** +// +// Copyright (c) 2001 +// Mutable Realms, Inc. +// Huntsville, AL, USA +// +// All Rights Reserved +// +// ********************************************************************** + +#ifndef ICE_UTIL_ICE_UTIL_H +#define ICE_UTIL_ICE_UTIL_H + +// +// This file must include *all* other headers of IceUtil. +// + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#endif diff --git a/cpp/include/IceUtil/InputUtil.h b/cpp/include/IceUtil/InputUtil.h index 6de10f0d966..ed95e84bbfe 100644 --- a/cpp/include/IceUtil/InputUtil.h +++ b/cpp/include/IceUtil/InputUtil.h @@ -1,65 +1,65 @@ -// ********************************************************************** -// -// Copyright (c) 2001 -// Mutable Realms, Inc. -// Huntsville, AL, USA -// -// All Rights Reserved -// -// ********************************************************************** - -#ifndef ICE_UTIL_INPUT_UTIL_H -#define ICE_UTIL_INPUT_UTIL_H - -#include -#include -#include - -namespace IceUtil -{ - -// -// strToInt64() is drop-in replacement for UNIX strtoll() -// -ICE_UTIL_API Int64 strToInt64(const char*, char**, int); - -// -// stringToInt64 converts a string into a signed 64-bit integer. -// -// bool stringToInt64(const std::string& stringToParse, Int64& result, std::string::size_type& pos); -// -// Semantics: -// -// - Ignore leading and trailing whitespace -// -// - If the string starts with '0', parse as octal -// -// - If the string starts with "0x" or "0X", parse as hexadecimal -// -// - Otherwise, parse as decimal -// -// - return value == true indicates a successful conversion and result contains the converted value -// -// - if pos == string::npos, there are no trailing non-whitespace characters following the converted string -// -// - if pos != string::npos, there are trailing non-whitespace characters following the converted string; -// pos indicates the first such character -// -// - return value == false indicates an unsuccessful conversion: -// -// - result == 0 indicates that no digits were available for conversion -// -// - result == INT64MIN or result == INT64MAX indicate underflow or overflow. -// -// - if pos == string::npos, the string did not contain trailing non-whitespace characters -// -// - if pos != string::npos, the string contained trailing non-whitespace characters following the -// digits and pos indicates the first such character. (Note that all digits up to the first -// non-digit, non-whitespace character are consumed, regardless of how far into the digit string -// an overflow is detected.) -// -ICE_UTIL_API bool stringToInt64(const std::string&, Int64&, std::string::size_type&); - -} - -#endif +// ********************************************************************** +// +// Copyright (c) 2001 +// Mutable Realms, Inc. +// Huntsville, AL, USA +// +// All Rights Reserved +// +// ********************************************************************** + +#ifndef ICE_UTIL_INPUT_UTIL_H +#define ICE_UTIL_INPUT_UTIL_H + +#include +#include +#include + +namespace IceUtil +{ + +// +// strToInt64() is drop-in replacement for UNIX strtoll() +// +ICE_UTIL_API Int64 strToInt64(const char*, char**, int); + +// +// stringToInt64 converts a string into a signed 64-bit integer. +// +// bool stringToInt64(const std::string& stringToParse, Int64& result, std::string::size_type& pos); +// +// Semantics: +// +// - Ignore leading and trailing whitespace +// +// - If the string starts with '0', parse as octal +// +// - If the string starts with "0x" or "0X", parse as hexadecimal +// +// - Otherwise, parse as decimal +// +// - return value == true indicates a successful conversion and result contains the converted value +// +// - if pos == string::npos, there are no trailing non-whitespace characters following the converted string +// +// - if pos != string::npos, there are trailing non-whitespace characters following the converted string; +// pos indicates the first such character +// +// - return value == false indicates an unsuccessful conversion: +// +// - result == 0 indicates that no digits were available for conversion +// +// - result == INT64MIN or result == INT64MAX indicate underflow or overflow. +// +// - if pos == string::npos, the string did not contain trailing non-whitespace characters +// +// - if pos != string::npos, the string contained trailing non-whitespace characters following the +// digits and pos indicates the first such character. (Note that all digits up to the first +// non-digit, non-whitespace character are consumed, regardless of how far into the digit string +// an overflow is detected.) +// +ICE_UTIL_API bool stringToInt64(const std::string&, Int64&, std::string::size_type&); + +} + +#endif diff --git a/cpp/include/IceUtil/Lock.h b/cpp/include/IceUtil/Lock.h index c22d08d3f62..13f8d5fa2c7 100644 --- a/cpp/include/IceUtil/Lock.h +++ b/cpp/include/IceUtil/Lock.h @@ -1,72 +1,72 @@ -// ********************************************************************** -// -// Copyright (c) 2001 -// Mutable Realms, Inc. -// Huntsville, AL, USA -// -// All Rights Reserved -// -// ********************************************************************** - -#ifndef ICE_UTIL_LOCK_H -#define ICE_UTIL_LOCK_H - -#include - -namespace IceUtil -{ - -// -// Forward declarations. -// -class Cond; - -template -class Lock -{ -public: - - Lock(const T& mutex) : - _mutex(mutex) - { - _mutex.lock(); - } - - ~Lock() - { - _mutex.unlock(); - } - -private: - - const T& _mutex; - - friend class Cond; -}; - -template -class TryLock -{ -public: - - TryLock(const T& mutex) : - _mutex(mutex) - { - _mutex.trylock(); - } - - ~TryLock() - { - _mutex.unlock(); - } - -private: - - const T& _mutex; - - friend class Cond; -}; - -} // End namespace IceUtil - -#endif +// ********************************************************************** +// +// Copyright (c) 2001 +// Mutable Realms, Inc. +// Huntsville, AL, USA +// +// All Rights Reserved +// +// ********************************************************************** + +#ifndef ICE_UTIL_LOCK_H +#define ICE_UTIL_LOCK_H + +#include + +namespace IceUtil +{ + +// +// Forward declarations. +// +class Cond; + +template +class Lock +{ +public: + + Lock(const T& mutex) : + _mutex(mutex) + { + _mutex.lock(); + } + + ~Lock() + { + _mutex.unlock(); + } + +private: + + const T& _mutex; + + friend class Cond; +}; + +template +class TryLock +{ +public: + + TryLock(const T& mutex) : + _mutex(mutex) + { + _mutex.trylock(); + } + + ~TryLock() + { + _mutex.unlock(); + } + +private: + + const T& _mutex; + + friend class Cond; +}; + +} // End namespace IceUtil + +#endif diff --git a/cpp/include/IceUtil/Monitor.h b/cpp/include/IceUtil/Monitor.h index 429b595889b..3fe6e76d943 100644 --- a/cpp/include/IceUtil/Monitor.h +++ b/cpp/include/IceUtil/Monitor.h @@ -1,235 +1,235 @@ -// ********************************************************************** -// -// Copyright (c) 2001 -// Mutable Realms, Inc. -// Huntsville, AL, USA -// -// All Rights Reserved -// -// ********************************************************************** - -#ifndef ICE_UTIL_MONITOR_H -#define ICE_UTIL_MONITOR_H - -#include -#include -#include - -namespace IceUtil -{ - -// -// This monitor implements the Mesa monitor semantics. That is any -// calls to notify() or notifyAll() are delayed until the monitor is -// unlocked. -// -template -class ICE_UTIL_API Monitor -{ -public: - - typedef Lock > Lock; - typedef TryLock > TryLock; - - Monitor(); - ~Monitor(); - - // - // Note that lock/trylock & unlock in general should not be used - // directly. Instead use Lock & TryLock. - // - void lock() const; - void unlock() const; - void trylock() const; - - void wait() const; - bool timedWait(const Time&) const; - void notify(); - void notifyAll(); - -private: - - // noncopyable - Monitor(const Monitor&); - void operator=(const Monitor&); - - void notifyImpl(int) const; - - mutable Cond _cond; - T _mutex; - mutable int _nnotify; -}; - -} // End namespace IceUtil - -// -// Since this monitor implements the Mesa monitor semantics calls to -// notify() or notifyAll() are delayed until the monitor is -// unlocked. This can happen either due to a call to unlock(), or a -// call to wait(). The _nnotify flag keeps track of the number of -// pending notification calls. -1 indicates a broadcast, a positive -// number indicates calls to notify(). The _nnotify flag is reset -// upon initial acquisition of the monitor lock (either through a call -// to lock(), or a return from wait(). -// - -template inline -IceUtil::Monitor::Monitor() : - _nnotify(0) -{ -} - -template inline -IceUtil::Monitor::~Monitor() -{ -} - -template inline void -IceUtil::Monitor::lock() const -{ - if(_mutex.lock()) - { - // - // On the first mutex acquisition reset the number pending - // notifications. - // - _nnotify = 0; - } -} - -template inline void -IceUtil::Monitor::unlock() const -{ - int nnotify = _nnotify; - if(_mutex.unlock()) - { - // - // Perform any pending notifications. - // - notifyImpl(nnotify); - } -} - -template inline void -IceUtil::Monitor::trylock() const -{ - if(_mutex.trylock()) - { - // - // On the first mutex acquisition reset the number pending - // notifications. - // - _nnotify = 0; - } -} - -template inline void -IceUtil::Monitor::wait() const -{ - // - // Perform any pending notifies - // - notifyImpl(_nnotify); - - // - // Wait for a notification - // - try - { - _cond.waitImpl(_mutex); - // - // Reset the nnotify count once wait() returns. - // - } - catch(...) - { - _nnotify = 0; - throw; - } - _nnotify = 0; -} - -template inline bool -IceUtil::Monitor::timedWait(const Time& timeout) const -{ - // - // Perform any pending notifies. - // - notifyImpl(_nnotify); - - bool rc; - // - // Wait for a notification. - // - try - { - rc = _cond.timedWaitImpl(_mutex, timeout); - - // - // Reset the nnotify count once wait() returns. - // - } - catch(...) - { - _nnotify = 0; - throw; - } - - _nnotify = 0; - return rc; -} - -template inline void -IceUtil::Monitor::notify() -{ - // - // Increment the _nnotify flag, unless a broadcast has already - // been requested. - // - if(_nnotify != -1) - { - ++_nnotify; - } -} - -template inline void -IceUtil::Monitor::notifyAll() -{ - // - // -1 (indicates broadcast) - // - _nnotify = -1; -} - - -template inline void -IceUtil::Monitor::notifyImpl(int nnotify) const -{ - // - // Zero indicates no notifies. - // - if(nnotify != 0) - { - // - // -1 means notifyAll. - // - if(nnotify == -1) - { - _cond.broadcast(); - return; - } - else - { - // - // Otherwise notify n times. - // - while(nnotify > 0) - { - _cond.signal(); - --nnotify; - } - } - } -} - -#endif +// ********************************************************************** +// +// Copyright (c) 2001 +// Mutable Realms, Inc. +// Huntsville, AL, USA +// +// All Rights Reserved +// +// ********************************************************************** + +#ifndef ICE_UTIL_MONITOR_H +#define ICE_UTIL_MONITOR_H + +#include +#include +#include + +namespace IceUtil +{ + +// +// This monitor implements the Mesa monitor semantics. That is any +// calls to notify() or notifyAll() are delayed until the monitor is +// unlocked. +// +template +class ICE_UTIL_API Monitor +{ +public: + + typedef Lock > Lock; + typedef TryLock > TryLock; + + Monitor(); + ~Monitor(); + + // + // Note that lock/trylock & unlock in general should not be used + // directly. Instead use Lock & TryLock. + // + void lock() const; + void unlock() const; + void trylock() const; + + void wait() const; + bool timedWait(const Time&) const; + void notify(); + void notifyAll(); + +private: + + // noncopyable + Monitor(const Monitor&); + void operator=(const Monitor&); + + void notifyImpl(int) const; + + mutable Cond _cond; + T _mutex; + mutable int _nnotify; +}; + +} // End namespace IceUtil + +// +// Since this monitor implements the Mesa monitor semantics calls to +// notify() or notifyAll() are delayed until the monitor is +// unlocked. This can happen either due to a call to unlock(), or a +// call to wait(). The _nnotify flag keeps track of the number of +// pending notification calls. -1 indicates a broadcast, a positive +// number indicates calls to notify(). The _nnotify flag is reset +// upon initial acquisition of the monitor lock (either through a call +// to lock(), or a return from wait(). +// + +template inline +IceUtil::Monitor::Monitor() : + _nnotify(0) +{ +} + +template inline +IceUtil::Monitor::~Monitor() +{ +} + +template inline void +IceUtil::Monitor::lock() const +{ + if(_mutex.lock()) + { + // + // On the first mutex acquisition reset the number pending + // notifications. + // + _nnotify = 0; + } +} + +template inline void +IceUtil::Monitor::unlock() const +{ + int nnotify = _nnotify; + if(_mutex.unlock()) + { + // + // Perform any pending notifications. + // + notifyImpl(nnotify); + } +} + +template inline void +IceUtil::Monitor::trylock() const +{ + if(_mutex.trylock()) + { + // + // On the first mutex acquisition reset the number pending + // notifications. + // + _nnotify = 0; + } +} + +template inline void +IceUtil::Monitor::wait() const +{ + // + // Perform any pending notifies + // + notifyImpl(_nnotify); + + // + // Wait for a notification + // + try + { + _cond.waitImpl(_mutex); + // + // Reset the nnotify count once wait() returns. + // + } + catch(...) + { + _nnotify = 0; + throw; + } + _nnotify = 0; +} + +template inline bool +IceUtil::Monitor::timedWait(const Time& timeout) const +{ + // + // Perform any pending notifies. + // + notifyImpl(_nnotify); + + bool rc; + // + // Wait for a notification. + // + try + { + rc = _cond.timedWaitImpl(_mutex, timeout); + + // + // Reset the nnotify count once wait() returns. + // + } + catch(...) + { + _nnotify = 0; + throw; + } + + _nnotify = 0; + return rc; +} + +template inline void +IceUtil::Monitor::notify() +{ + // + // Increment the _nnotify flag, unless a broadcast has already + // been requested. + // + if(_nnotify != -1) + { + ++_nnotify; + } +} + +template inline void +IceUtil::Monitor::notifyAll() +{ + // + // -1 (indicates broadcast) + // + _nnotify = -1; +} + + +template inline void +IceUtil::Monitor::notifyImpl(int nnotify) const +{ + // + // Zero indicates no notifies. + // + if(nnotify != 0) + { + // + // -1 means notifyAll. + // + if(nnotify == -1) + { + _cond.broadcast(); + return; + } + else + { + // + // Otherwise notify n times. + // + while(nnotify > 0) + { + _cond.signal(); + --nnotify; + } + } + } +} + +#endif diff --git a/cpp/include/IceUtil/Mutex.h b/cpp/include/IceUtil/Mutex.h index 63de085e751..e6ce737d4e3 100644 --- a/cpp/include/IceUtil/Mutex.h +++ b/cpp/include/IceUtil/Mutex.h @@ -1,250 +1,250 @@ -// ********************************************************************** -// -// Copyright (c) 2001 -// Mutable Realms, Inc. -// Huntsville, AL, USA -// -// All Rights Reserved -// -// ********************************************************************** - -#ifndef ICE_UTIL_MUTEX_H -#define ICE_UTIL_MUTEX_H - -#include -#include // Necessary for inline functions -#include - -namespace IceUtil -{ - -// -// Forward declaration for friend. -// -class Cond; - -// -// Simple non-recursive Mutex implementation. -// -// Don't use noncopyable otherwise you end up with warnings like this: -// -// In file included from Connection.cpp:20: -// ../../include/Ice/Outgoing.h:88: warning: direct base -// `IceUtil::noncopyable' inaccessible in `IceInternal::Outgoing' due -// to ambiguity -// -class ICE_UTIL_API Mutex -{ -public: - - // - // Lock & TryLock typedefs. - // - typedef Lock Lock; - typedef TryLock TryLock; - - Mutex(); - ~Mutex(); - - // - // Note that lock/trylock & unlock in general should not be used - // directly. Instead use Lock & TryLock. - // - - // - // The boolean values are for the Monitor implementation which - // needs to know whether the Mutex has been locked for the first - // time, or unlocked for the last time (that is another thread is - // able to acquire the mutex). - // - - // - // Return true if the mutex has been locked for the first time. - // - bool lock() const; - - // - // Throw LockedException in the case that the lock call would - // block (that is the mutex is already owned by some other - // thread). Returns true if the mutex has been locked for the - // first time. - // - bool trylock() const; - - // - // Returns true if the mutex has been unlocked for the last time - // (false otherwise). - // - bool unlock() const; - -private: - - // noncopyable - Mutex(const Mutex&); - void operator=(const Mutex&); - - // - // LockState and the lock/unlock variations are for use by the - // Condition variable implementation. - // -#ifdef _WIN32 - struct LockState - { - }; -#else - struct LockState - { - pthread_mutex_t* mutex; - }; -#endif - - void unlock(LockState&) const; - void lock(LockState&) const; - - friend class Cond; - -#ifdef _WIN32 - mutable CRITICAL_SECTION _mutex; -#else - mutable pthread_mutex_t _mutex; -#endif -}; - -// -// For performance reasons the following functions are inlined. -// - -#ifdef _WIN32 - -inline -Mutex::Mutex() -{ - InitializeCriticalSection(&_mutex); -} - -inline -Mutex::~Mutex() -{ - DeleteCriticalSection(&_mutex); -} - -inline bool -Mutex::lock() const -{ - EnterCriticalSection(&_mutex); - // - // If necessary this can be removed and replaced with a _count - // member (like the UNIX implementation of RecMutex). - // - assert(_mutex.RecursionCount == 1); - return true; -} - -inline bool -Mutex::trylock() const -{ - if(!TryEnterCriticalSection(&_mutex)) - { - throw LockedException(__FILE__, __LINE__); - } - if(_mutex.RecursionCount > 1) - { - LeaveCriticalSection(&_mutex); - throw LockedException(__FILE__, __LINE__); - } - return true; -} - -inline bool -Mutex::unlock() const -{ - assert(_mutex.RecursionCount == 1); - LeaveCriticalSection(&_mutex); - return true; -} - -inline void -Mutex::unlock(LockState& state) const -{ - LeaveCriticalSection(&_mutex); -} - -inline void -Mutex::lock(LockState&) const -{ - EnterCriticalSection(&_mutex); -} - -#else - -inline -Mutex::Mutex() -{ - int rc = pthread_mutex_init(&_mutex, 0); - if(rc != 0) - { - throw SyscallException(strerror(rc), __FILE__, __LINE__); - } -} - -inline -Mutex::~Mutex() -{ - int rc = 0; - rc = pthread_mutex_destroy(&_mutex); - assert(rc == 0); -} - -inline bool -Mutex::lock() const -{ - int rc = pthread_mutex_lock(&_mutex); - if(rc != 0) - { - throw SyscallException(strerror(rc), __FILE__, __LINE__); - } - return true; -} - -inline bool -Mutex::trylock() const -{ - int rc = pthread_mutex_trylock(&_mutex); - if(rc != 0) - { - if(rc == EBUSY) - { - throw LockedException(__FILE__, __LINE__); - } - throw SyscallException(strerror(rc), __FILE__, __LINE__); - } - return true; -} - -inline bool -Mutex::unlock() const -{ - int rc = pthread_mutex_unlock(&_mutex); - if(rc != 0) - { - throw SyscallException(strerror(rc), __FILE__, __LINE__); - } - return true; -} - -inline void -Mutex::unlock(LockState& state) const -{ - state.mutex = &_mutex; -} - -inline void -Mutex::lock(LockState&) const -{ -} - -#endif - -} // End namespace IceUtil - -#endif +// ********************************************************************** +// +// Copyright (c) 2001 +// Mutable Realms, Inc. +// Huntsville, AL, USA +// +// All Rights Reserved +// +// ********************************************************************** + +#ifndef ICE_UTIL_MUTEX_H +#define ICE_UTIL_MUTEX_H + +#include +#include +#include + +namespace IceUtil +{ + +// +// Forward declaration for friend. +// +class Cond; + +// +// Simple non-recursive Mutex implementation. +// +// Don't use noncopyable otherwise you end up with warnings like this: +// +// In file included from Connection.cpp:20: +// ../../include/Ice/Outgoing.h:88: warning: direct base +// `IceUtil::noncopyable' inaccessible in `IceInternal::Outgoing' due +// to ambiguity +// +class ICE_UTIL_API Mutex +{ +public: + + // + // Lock & TryLock typedefs. + // + typedef Lock Lock; + typedef TryLock TryLock; + + Mutex(); + ~Mutex(); + + // + // Note that lock/trylock & unlock in general should not be used + // directly. Instead use Lock & TryLock. + // + + // + // The boolean values are for the Monitor implementation which + // needs to know whether the Mutex has been locked for the first + // time, or unlocked for the last time (that is another thread is + // able to acquire the mutex). + // + + // + // Return true if the mutex has been locked for the first time. + // + bool lock() const; + + // + // Throw ThreadLockedException in the case that the lock call would + // block (that is the mutex is already owned by some other + // thread). Returns true if the mutex has been locked for the + // first time. + // + bool trylock() const; + + // + // Returns true if the mutex has been unlocked for the last time + // (false otherwise). + // + bool unlock() const; + +private: + + // noncopyable + Mutex(const Mutex&); + void operator=(const Mutex&); + + // + // LockState and the lock/unlock variations are for use by the + // Condition variable implementation. + // +#ifdef _WIN32 + struct LockState + { + }; +#else + struct LockState + { + pthread_mutex_t* mutex; + }; +#endif + + void unlock(LockState&) const; + void lock(LockState&) const; + + friend class Cond; + +#ifdef _WIN32 + mutable CRITICAL_SECTION _mutex; +#else + mutable pthread_mutex_t _mutex; +#endif +}; + +// +// For performance reasons the following functions are inlined. +// + +#ifdef _WIN32 + +inline +Mutex::Mutex() +{ + InitializeCriticalSection(&_mutex); +} + +inline +Mutex::~Mutex() +{ + DeleteCriticalSection(&_mutex); +} + +inline bool +Mutex::lock() const +{ + EnterCriticalSection(&_mutex); + // + // If necessary this can be removed and replaced with a _count + // member (like the UNIX implementation of RecMutex). + // + assert(_mutex.RecursionCount == 1); + return true; +} + +inline bool +Mutex::trylock() const +{ + if(!TryEnterCriticalSection(&_mutex)) + { + throw ThreadLockedException(__FILE__, __LINE__); + } + if(_mutex.RecursionCount > 1) + { + LeaveCriticalSection(&_mutex); + throw ThreadLockedException(__FILE__, __LINE__); + } + return true; +} + +inline bool +Mutex::unlock() const +{ + assert(_mutex.RecursionCount == 1); + LeaveCriticalSection(&_mutex); + return true; +} + +inline void +Mutex::unlock(LockState& state) const +{ + LeaveCriticalSection(&_mutex); +} + +inline void +Mutex::lock(LockState&) const +{ + EnterCriticalSection(&_mutex); +} + +#else + +inline +Mutex::Mutex() +{ + int rc = pthread_mutex_init(&_mutex, 0); + if(rc != 0) + { + throw ThreadSyscallException(strerror(rc), __FILE__, __LINE__); + } +} + +inline +Mutex::~Mutex() +{ + int rc = 0; + rc = pthread_mutex_destroy(&_mutex); + assert(rc == 0); +} + +inline bool +Mutex::lock() const +{ + int rc = pthread_mutex_lock(&_mutex); + if(rc != 0) + { + throw ThreadSyscallException(strerror(rc), __FILE__, __LINE__); + } + return true; +} + +inline bool +Mutex::trylock() const +{ + int rc = pthread_mutex_trylock(&_mutex); + if(rc != 0) + { + if(rc == EBUSY) + { + throw ThreadLockedException(__FILE__, __LINE__); + } + throw ThreadSyscallException(strerror(rc), __FILE__, __LINE__); + } + return true; +} + +inline bool +Mutex::unlock() const +{ + int rc = pthread_mutex_unlock(&_mutex); + if(rc != 0) + { + throw ThreadSyscallException(strerror(rc), __FILE__, __LINE__); + } + return true; +} + +inline void +Mutex::unlock(LockState& state) const +{ + state.mutex = &_mutex; +} + +inline void +Mutex::lock(LockState&) const +{ +} + +#endif + +} // End namespace IceUtil + +#endif diff --git a/cpp/include/IceUtil/OutputUtil.h b/cpp/include/IceUtil/OutputUtil.h index 4b0e321b64b..8b2ed0996bd 100644 --- a/cpp/include/IceUtil/OutputUtil.h +++ b/cpp/include/IceUtil/OutputUtil.h @@ -1,325 +1,325 @@ -// ********************************************************************** -// -// Copyright (c) 2001 -// Mutable Realms, Inc. -// Huntsville, AL, USA -// -// All Rights Reserved -// -// ********************************************************************** - -#ifndef ICE_UTIL_OUTPUT_UTIL_H -#define ICE_UTIL_OUTPUT_UTIL_H - -#include -#include -#include - -namespace IceUtil -{ - -// ---------------------------------------------------------------------- -// OutputBase -// ---------------------------------------------------------------------- - -// -// Technically it's not necessary to have print() & nl() as virtual -// since the opeator<< functions are specific to each OutputBase -// derivative. However, since it's possible to call print() & nl() -// manually I've decided to leave them as virtual. -// - -class ICE_UTIL_API OutputBase : public ::IceUtil::noncopyable -{ -public: - - OutputBase(); - OutputBase(std::ostream&); - OutputBase(const char*); - virtual ~OutputBase(); - - void setIndent(int); // What is the indent level? - void setUseTab(bool); // Should we output tabs? - - void open(const char*); // Open output stream. - - virtual void print(const char*); // Print a string. - - void inc(); // Increment indentation level. - void dec(); // Decrement indentation level. - - void useCurrentPosAsIndent(); // Save the current position as indentation. - void zeroIndent(); // Use zero identation. - void restoreIndent(); // Restore indentation. - - virtual void nl(); // Print newline. - void sp(); // Print separator. - - bool operator!() const; // Check whether the output state is ok. - - std::streamsize width() const; - std::streamsize width(std::streamsize newWidth); - - std::ios_base::fmtflags flags() const; - std::ios_base::fmtflags flags(std::ios_base::fmtflags newFlags); - - std::ostream::char_type fill() const; - std::ostream::char_type fill(std::ostream::char_type newFill); - -protected: - - std::ofstream _fout; - std::ostream& _out; - int _pos; - int _indent; - int _indentSize; - std::stack _indentSave; - bool _useTab; - bool _separator; -}; - -class ICE_UTIL_API NextLine -{ -}; -extern ICE_UTIL_API NextLine nl; - -class ICE_UTIL_API Separator -{ -}; -extern ICE_UTIL_API Separator sp; - -// ---------------------------------------------------------------------- -// Output -// ---------------------------------------------------------------------- - -class ICE_UTIL_API Output : public OutputBase -{ -public: - - Output(); - Output(std::ostream&); - Output(const char*); - - void setBeginBlock(const char *); // what do we use at block starts? - void setEndBlock(const char *); // what do we use the block end? - - void sb(); // Start a block. - void eb(); // End a block. - -private: - - std::string _blockStart; - std::string _blockEnd; -}; - -template -Output& -operator<<(Output& out, const T& val) -{ - std::ostringstream s; - s << val; - out.print(s.str().c_str()); - return out; -} - -template<> -inline Output& -operator<<(Output& o, const NextLine&) -{ - o.nl(); - return o; -} - -template<> -inline Output& -operator<<(Output& o, const Separator&) -{ - o.sp(); - return o; -} - -class ICE_UTIL_API StartBlock -{ -}; -extern ICE_UTIL_API StartBlock sb; - -template<> -inline Output& -operator<<(Output& o, const StartBlock&) -{ - o.sb(); - return o; -} - -class ICE_UTIL_API EndBlock -{ -}; -extern ICE_UTIL_API EndBlock eb; - -template<> -inline Output& -operator<<(Output& o, const EndBlock&) -{ - o.eb(); - return o; -} - -ICE_UTIL_API Output& operator<<(Output&, std::ios_base& (*)(std::ios_base&)); - -// ---------------------------------------------------------------------- -// XMLOutput -// ---------------------------------------------------------------------- - -class ICE_UTIL_API XMLOutput : public OutputBase -{ -public: - - XMLOutput(); - XMLOutput(std::ostream&); - XMLOutput(const char*); - - void setSGML(bool); - virtual void print(const char*); // Print a string. - - virtual void nl(); // Print newline. - - void se(const std::string&); // Start an element. - void ee(); // End an element. - void attr(const std::string&, const std::string&); // Add an attribute to an element. - - void startEscapes(); - void endEscapes(); - - std::string currentElement() const; - -private: - - ::std::string escape(const ::std::string&) const; - - std::stack _elementStack; - - bool _se; - bool _text; - - bool _sgml; - bool _escape; -}; - -template -XMLOutput& -operator<<(XMLOutput& out, const T& val) -{ - std::ostringstream s; - s << val; - out.print(s.str().c_str()); - return out; -} - -template<> -inline XMLOutput& -operator<<(XMLOutput& o, const NextLine&) -{ - o.nl(); - return o; -} - -template<> -inline XMLOutput& -operator<<(XMLOutput& o, const Separator&) -{ - o.sp(); - return o; -} - -class ICE_UTIL_API EndElement -{ -}; -extern ICE_UTIL_API EndElement ee; - -template<> -inline XMLOutput& -operator<<(XMLOutput& o, const EndElement&) -{ - o.ee(); - return o; -} - -class ICE_UTIL_API StartElement -{ -public: - - StartElement(const std::string&); - - const std::string& getName() const; - -private: - - const std::string _name; -}; - -typedef StartElement se; - -template<> -inline XMLOutput& -operator<<(XMLOutput& o, const StartElement& e) -{ - o.se(e.getName()); - return o; -} - -class ICE_UTIL_API Attribute -{ -public: - - Attribute(const ::std::string&, const ::std::string&); - - const ::std::string& getName() const; - const ::std::string& getValue() const; - -private: - - const ::std::string _name; - const ::std::string _value; -}; - -typedef Attribute attr; - -template<> -inline XMLOutput& -operator<<(XMLOutput& o, const Attribute& e) -{ - o.attr(e.getName(), e.getValue()); - return o; -} - -class ICE_UTIL_API StartEscapes -{ -}; -extern ICE_UTIL_API StartEscapes startEscapes; - -class ICE_UTIL_API EndEscapes -{ -}; -extern ICE_UTIL_API EndEscapes endEscapes; - -template<> -inline XMLOutput& -operator<<(XMLOutput& o, const StartEscapes&) -{ - o.startEscapes(); - return o; -} - -template<> -inline XMLOutput& -operator<<(XMLOutput& o, const EndEscapes&) -{ - o.endEscapes(); - return o; -} - -ICE_UTIL_API XMLOutput& operator<<(XMLOutput&, std::ios_base& (*)(std::ios_base&)); - -} - -#endif +// ********************************************************************** +// +// Copyright (c) 2001 +// Mutable Realms, Inc. +// Huntsville, AL, USA +// +// All Rights Reserved +// +// ********************************************************************** + +#ifndef ICE_UTIL_OUTPUT_UTIL_H +#define ICE_UTIL_OUTPUT_UTIL_H + +#include +#include +#include + +namespace IceUtil +{ + +// ---------------------------------------------------------------------- +// OutputBase +// ---------------------------------------------------------------------- + +// +// Technically it's not necessary to have print() & nl() as virtual +// since the opeator<< functions are specific to each OutputBase +// derivative. However, since it's possible to call print() & nl() +// manually I've decided to leave them as virtual. +// + +class ICE_UTIL_API OutputBase : public ::IceUtil::noncopyable +{ +public: + + OutputBase(); + OutputBase(std::ostream&); + OutputBase(const char*); + virtual ~OutputBase(); + + void setIndent(int); // What is the indent level? + void setUseTab(bool); // Should we output tabs? + + void open(const char*); // Open output stream. + + virtual void print(const char*); // Print a string. + + void inc(); // Increment indentation level. + void dec(); // Decrement indentation level. + + void useCurrentPosAsIndent(); // Save the current position as indentation. + void zeroIndent(); // Use zero identation. + void restoreIndent(); // Restore indentation. + + virtual void nl(); // Print newline. + void sp(); // Print separator. + + bool operator!() const; // Check whether the output state is ok. + + std::streamsize width() const; + std::streamsize width(std::streamsize newWidth); + + std::ios_base::fmtflags flags() const; + std::ios_base::fmtflags flags(std::ios_base::fmtflags newFlags); + + std::ostream::char_type fill() const; + std::ostream::char_type fill(std::ostream::char_type newFill); + +protected: + + std::ofstream _fout; + std::ostream& _out; + int _pos; + int _indent; + int _indentSize; + std::stack _indentSave; + bool _useTab; + bool _separator; +}; + +class ICE_UTIL_API NextLine +{ +}; +extern ICE_UTIL_API NextLine nl; + +class ICE_UTIL_API Separator +{ +}; +extern ICE_UTIL_API Separator sp; + +// ---------------------------------------------------------------------- +// Output +// ---------------------------------------------------------------------- + +class ICE_UTIL_API Output : public OutputBase +{ +public: + + Output(); + Output(std::ostream&); + Output(const char*); + + void setBeginBlock(const char *); // what do we use at block starts? + void setEndBlock(const char *); // what do we use the block end? + + void sb(); // Start a block. + void eb(); // End a block. + +private: + + std::string _blockStart; + std::string _blockEnd; +}; + +template +Output& +operator<<(Output& out, const T& val) +{ + std::ostringstream s; + s << val; + out.print(s.str().c_str()); + return out; +} + +template<> +inline Output& +operator<<(Output& o, const NextLine&) +{ + o.nl(); + return o; +} + +template<> +inline Output& +operator<<(Output& o, const Separator&) +{ + o.sp(); + return o; +} + +class ICE_UTIL_API StartBlock +{ +}; +extern ICE_UTIL_API StartBlock sb; + +template<> +inline Output& +operator<<(Output& o, const StartBlock&) +{ + o.sb(); + return o; +} + +class ICE_UTIL_API EndBlock +{ +}; +extern ICE_UTIL_API EndBlock eb; + +template<> +inline Output& +operator<<(Output& o, const EndBlock&) +{ + o.eb(); + return o; +} + +ICE_UTIL_API Output& operator<<(Output&, std::ios_base& (*)(std::ios_base&)); + +// ---------------------------------------------------------------------- +// XMLOutput +// ---------------------------------------------------------------------- + +class ICE_UTIL_API XMLOutput : public OutputBase +{ +public: + + XMLOutput(); + XMLOutput(std::ostream&); + XMLOutput(const char*); + + void setSGML(bool); + virtual void print(const char*); // Print a string. + + virtual void nl(); // Print newline. + + void se(const std::string&); // Start an element. + void ee(); // End an element. + void attr(const std::string&, const std::string&); // Add an attribute to an element. + + void startEscapes(); + void endEscapes(); + + std::string currentElement() const; + +private: + + ::std::string escape(const ::std::string&) const; + + std::stack _elementStack; + + bool _se; + bool _text; + + bool _sgml; + bool _escape; +}; + +template +XMLOutput& +operator<<(XMLOutput& out, const T& val) +{ + std::ostringstream s; + s << val; + out.print(s.str().c_str()); + return out; +} + +template<> +inline XMLOutput& +operator<<(XMLOutput& o, const NextLine&) +{ + o.nl(); + return o; +} + +template<> +inline XMLOutput& +operator<<(XMLOutput& o, const Separator&) +{ + o.sp(); + return o; +} + +class ICE_UTIL_API EndElement +{ +}; +extern ICE_UTIL_API EndElement ee; + +template<> +inline XMLOutput& +operator<<(XMLOutput& o, const EndElement&) +{ + o.ee(); + return o; +} + +class ICE_UTIL_API StartElement +{ +public: + + StartElement(const std::string&); + + const std::string& getName() const; + +private: + + const std::string _name; +}; + +typedef StartElement se; + +template<> +inline XMLOutput& +operator<<(XMLOutput& o, const StartElement& e) +{ + o.se(e.getName()); + return o; +} + +class ICE_UTIL_API Attribute +{ +public: + + Attribute(const ::std::string&, const ::std::string&); + + const ::std::string& getName() const; + const ::std::string& getValue() const; + +private: + + const ::std::string _name; + const ::std::string _value; +}; + +typedef Attribute attr; + +template<> +inline XMLOutput& +operator<<(XMLOutput& o, const Attribute& e) +{ + o.attr(e.getName(), e.getValue()); + return o; +} + +class ICE_UTIL_API StartEscapes +{ +}; +extern ICE_UTIL_API StartEscapes startEscapes; + +class ICE_UTIL_API EndEscapes +{ +}; +extern ICE_UTIL_API EndEscapes endEscapes; + +template<> +inline XMLOutput& +operator<<(XMLOutput& o, const StartEscapes&) +{ + o.startEscapes(); + return o; +} + +template<> +inline XMLOutput& +operator<<(XMLOutput& o, const EndEscapes&) +{ + o.endEscapes(); + return o; +} + +ICE_UTIL_API XMLOutput& operator<<(XMLOutput&, std::ios_base& (*)(std::ios_base&)); + +} + +#endif diff --git a/cpp/include/IceUtil/RWRecMutex.h b/cpp/include/IceUtil/RWRecMutex.h index 23eba24b62d..cc09ab4113e 100644 --- a/cpp/include/IceUtil/RWRecMutex.h +++ b/cpp/include/IceUtil/RWRecMutex.h @@ -1,256 +1,256 @@ -// ********************************************************************** -// -// Copyright (c) 2001 -// Mutable Realms, Inc. -// Huntsville, AL, USA -// -// All Rights Reserved -// -// ********************************************************************** - -#ifndef ICE_UTIL_RW_REC_MUTEX_H -#define ICE_UTIL_RW_REC_MUTEX_H - -#include -#include -#include - -namespace IceUtil -{ - -template -class RLock -{ -public: - - RLock(const T& mutex) : - _mutex(mutex) - { - _mutex.readlock(); - } - - ~RLock() - { - _mutex.unlock(); - } - - void - upgrade() - { - _mutex.upgrade(); - } - - void - timedUpgrade(const Time& timeout) - { - _mutex.timedUpgrade(timeout); - } - -private: - - const T& _mutex; -}; - -template -class TryRLock -{ -public: - - TryRLock(const T& mutex) : - _mutex(mutex) - { - _mutex.tryReadlock(); - } - - TryRLock(const T& mutex, const Time& timeout) : - _mutex(mutex) - { - _mutex.timedTryReadlock(timeout); - } - - ~TryRLock() - { - _mutex.unlock(); - } - - void - upgrade() - { - _mutex.upgrade(); - } - - void - timedUpgrade(const Time& timeout) - { - _mutex.timedUpgrade(timeout); - } - -private: - - const T& _mutex; -}; - -template -class WLock -{ -public: - - WLock(const T& mutex) : - _mutex(mutex) - { - _mutex.writelock(); - } - - ~WLock() - { - _mutex.unlock(); - } - -private: - - const T& _mutex; -}; - -template -class TryWLock -{ -public: - - TryWLock(const T& mutex) : - _mutex(mutex) - { - _mutex.tryWritelock(); - } - - TryWLock(const T& mutex, const Time& timeout) : - _mutex(mutex) - { - _mutex.timedTryWritelock(timeout); - } - - ~TryWLock() - { - _mutex.unlock(); - } - -private: - - const T& _mutex; -}; - -// -// Concurrency primitive that allows many readers & one writer access -// to a data structure. Writers have priority over readers. The -// structure is not strictly fair in that there is no absolute queue -// of waiting writers - that is managed by a condition variable. -// -// Both Reader & Writer mutexes can be recursively locked. Calling -// WLock (or TryWLock) while holding a read lock promotes the reader -// to a writer lock. -// -class ICE_UTIL_API RWRecMutex -{ -public: - - // - // RLock (reader) & WLock (writer) typedefs. - // - typedef RLock RLock; - typedef TryRLock TryRLock; - typedef WLock WLock; - typedef TryWLock TryWLock; - - RWRecMutex(); - ~RWRecMutex(); - - // - // Note that readlock/writelock & unlock in general should not be - // used directly. Instead use RLock & WLock. - // - - // - // Acquire a read lock. - // - void readlock() const; - - // - // Try to acquire a read lock. - // - void tryReadlock() const; - - // - // Try to acquire a read lock for upto the given timeout. - // - void timedTryReadlock(const Time&) const; - - // - // Acquire a write lock. - // - void writelock() const; - - // - // Acquire a write lock. - // - void tryWritelock() const; - - // - // Acquire a write lock for up to the given timeout. - // - void timedTryWritelock(const Time&) const; - - // - // Unlock the reader/writer lock. - // - void unlock() const; - - // - // Upgrade the read lock to a writer lock. Note that this method - // can only be called if the reader lock is not held recursively. - // - void upgrade() const; - - // - // Upgrade the read lock to a writer lock for up to the given - // timeout Note that this method can only be called if the reader - // lock is not held recursively. - // - void timedUpgrade(const Time&) const; - -private: - - // noncopyable - RWRecMutex(const RWRecMutex&); - void operator=(const RWRecMutex&); - - // - // Number of readers holding the lock. A positive number indicates - // readers are active. A negative number means that a writer is - // active. - // - mutable int _count; - - // - // If there is an active writer this is a control for thread. - // - mutable ThreadControl _writerControl; - - // - // Number of waiting writers. - // - mutable unsigned int _waitingWriters; - - // - // Internal mutex. - // - Mutex _mutex; - - // - // Two condition variables for waiting readers & writers. - // - mutable Cond _readers; - mutable Cond _writers; -}; - -} // End namespace IceUtil - -#endif +// ********************************************************************** +// +// Copyright (c) 2001 +// Mutable Realms, Inc. +// Huntsville, AL, USA +// +// All Rights Reserved +// +// ********************************************************************** + +#ifndef ICE_UTIL_RW_REC_MUTEX_H +#define ICE_UTIL_RW_REC_MUTEX_H + +#include +#include +#include + +namespace IceUtil +{ + +template +class RLock +{ +public: + + RLock(const T& mutex) : + _mutex(mutex) + { + _mutex.readlock(); + } + + ~RLock() + { + _mutex.unlock(); + } + + void + upgrade() + { + _mutex.upgrade(); + } + + void + timedUpgrade(const Time& timeout) + { + _mutex.timedUpgrade(timeout); + } + +private: + + const T& _mutex; +}; + +template +class TryRLock +{ +public: + + TryRLock(const T& mutex) : + _mutex(mutex) + { + _mutex.tryReadlock(); + } + + TryRLock(const T& mutex, const Time& timeout) : + _mutex(mutex) + { + _mutex.timedTryReadlock(timeout); + } + + ~TryRLock() + { + _mutex.unlock(); + } + + void + upgrade() + { + _mutex.upgrade(); + } + + void + timedUpgrade(const Time& timeout) + { + _mutex.timedUpgrade(timeout); + } + +private: + + const T& _mutex; +}; + +template +class WLock +{ +public: + + WLock(const T& mutex) : + _mutex(mutex) + { + _mutex.writelock(); + } + + ~WLock() + { + _mutex.unlock(); + } + +private: + + const T& _mutex; +}; + +template +class TryWLock +{ +public: + + TryWLock(const T& mutex) : + _mutex(mutex) + { + _mutex.tryWritelock(); + } + + TryWLock(const T& mutex, const Time& timeout) : + _mutex(mutex) + { + _mutex.timedTryWritelock(timeout); + } + + ~TryWLock() + { + _mutex.unlock(); + } + +private: + + const T& _mutex; +}; + +// +// Concurrency primitive that allows many readers & one writer access +// to a data structure. Writers have priority over readers. The +// structure is not strictly fair in that there is no absolute queue +// of waiting writers - that is managed by a condition variable. +// +// Both Reader & Writer mutexes can be recursively locked. Calling +// WLock (or TryWLock) while holding a read lock promotes the reader +// to a writer lock. +// +class ICE_UTIL_API RWRecMutex +{ +public: + + // + // RLock (reader) & WLock (writer) typedefs. + // + typedef RLock RLock; + typedef TryRLock TryRLock; + typedef WLock WLock; + typedef TryWLock TryWLock; + + RWRecMutex(); + ~RWRecMutex(); + + // + // Note that readlock/writelock & unlock in general should not be + // used directly. Instead use RLock & WLock. + // + + // + // Acquire a read lock. + // + void readlock() const; + + // + // Try to acquire a read lock. + // + void tryReadlock() const; + + // + // Try to acquire a read lock for upto the given timeout. + // + void timedTryReadlock(const Time&) const; + + // + // Acquire a write lock. + // + void writelock() const; + + // + // Acquire a write lock. + // + void tryWritelock() const; + + // + // Acquire a write lock for up to the given timeout. + // + void timedTryWritelock(const Time&) const; + + // + // Unlock the reader/writer lock. + // + void unlock() const; + + // + // Upgrade the read lock to a writer lock. Note that this method + // can only be called if the reader lock is not held recursively. + // + void upgrade() const; + + // + // Upgrade the read lock to a writer lock for up to the given + // timeout Note that this method can only be called if the reader + // lock is not held recursively. + // + void timedUpgrade(const Time&) const; + +private: + + // noncopyable + RWRecMutex(const RWRecMutex&); + void operator=(const RWRecMutex&); + + // + // Number of readers holding the lock. A positive number indicates + // readers are active. A negative number means that a writer is + // active. + // + mutable int _count; + + // + // If there is an active writer this is a control for thread. + // + mutable ThreadControl _writerControl; + + // + // Number of waiting writers. + // + mutable unsigned int _waitingWriters; + + // + // Internal mutex. + // + Mutex _mutex; + + // + // Two condition variables for waiting readers & writers. + // + mutable Cond _readers; + mutable Cond _writers; +}; + +} // End namespace IceUtil + +#endif diff --git a/cpp/include/IceUtil/RecMutex.h b/cpp/include/IceUtil/RecMutex.h index 974652cea50..8aab8c48a21 100644 --- a/cpp/include/IceUtil/RecMutex.h +++ b/cpp/include/IceUtil/RecMutex.h @@ -1,111 +1,112 @@ -// ********************************************************************** -// -// Copyright (c) 2001 -// Mutable Realms, Inc. -// Huntsville, AL, USA -// -// All Rights Reserved -// -// ********************************************************************** - -#ifndef ICE_UTIL_RMUTEX_H -#define ICE_UTIL_RMUTEX_H - -#include -#include - -namespace IceUtil -{ - -// -// Forward declarations for friend. -// -class Cond; - -// -// Recursive Mutex implementation. -// -class ICE_UTIL_API RecMutex -{ -public: - - // - // Lock & TryLock typedefs. - // - typedef Lock Lock; - typedef TryLock TryLock; - - RecMutex(); - ~RecMutex(); - - // - // Note that lock/trylock & unlock in general should not be used - // directly. Instead use Lock & TryLock. - // - - // - // The boolean values are for the Monitor implementation which - // needs to know whether the Mutex has been locked for the first - // time, or unlocked for the last time (that is another thread is - // able to acquire the mutex). - // - - // - // Return true if the mutex has been locked for the first time. - // - bool lock() const; - - // - // Throw LockedException in the case that the lock call would - // block (that is the mutex is already owned by some other - // thread). Returns true if the mutex has been locked for the - // first time. - // - bool trylock() const; - - // - // Returns true if the mutex has been unlocked for the last time - // (false otherwise). - // - bool unlock() const; - -private: - - // noncopyable - RecMutex(const RecMutex&); - void operator=(const RecMutex&); - - // - // LockState and the lock/unlock variations are for use by the - // Condition variable implementation. - // -#ifdef _WIN32 - struct LockState - { - int count; - }; -#else - struct LockState - { - pthread_mutex_t* mutex; - int count; - }; -#endif - - void unlock(LockState&) const; - void lock(LockState&) const; - - friend class Cond; - -#ifdef _WIN32 - mutable CRITICAL_SECTION _mutex; -#else - mutable pthread_mutex_t _mutex; -#endif - - mutable int _count; -}; - -} // End namespace IceUtil - -#endif +// ********************************************************************** +// +// Copyright (c) 2001 +// Mutable Realms, Inc. +// Huntsville, AL, USA +// +// All Rights Reserved +// +// ********************************************************************** + +#ifndef ICE_UTIL_RMUTEX_H +#define ICE_UTIL_RMUTEX_H + +#include +#include +#include + +namespace IceUtil +{ + +// +// Forward declarations for friend. +// +class Cond; + +// +// Recursive Mutex implementation. +// +class ICE_UTIL_API RecMutex +{ +public: + + // + // Lock & TryLock typedefs. + // + typedef Lock Lock; + typedef TryLock TryLock; + + RecMutex(); + ~RecMutex(); + + // + // Note that lock/trylock & unlock in general should not be used + // directly. Instead use Lock & TryLock. + // + + // + // The boolean values are for the Monitor implementation which + // needs to know whether the Mutex has been locked for the first + // time, or unlocked for the last time (that is another thread is + // able to acquire the mutex). + // + + // + // Return true if the mutex has been locked for the first time. + // + bool lock() const; + + // + // Throw ThreadLockedException in the case that the lock call would + // block (that is the mutex is already owned by some other + // thread). Returns true if the mutex has been locked for the + // first time. + // + bool trylock() const; + + // + // Returns true if the mutex has been unlocked for the last time + // (false otherwise). + // + bool unlock() const; + +private: + + // noncopyable + RecMutex(const RecMutex&); + void operator=(const RecMutex&); + + // + // LockState and the lock/unlock variations are for use by the + // Condition variable implementation. + // +#ifdef _WIN32 + struct LockState + { + int count; + }; +#else + struct LockState + { + pthread_mutex_t* mutex; + int count; + }; +#endif + + void unlock(LockState&) const; + void lock(LockState&) const; + + friend class Cond; + +#ifdef _WIN32 + mutable CRITICAL_SECTION _mutex; +#else + mutable pthread_mutex_t _mutex; +#endif + + mutable int _count; +}; + +} // End namespace IceUtil + +#endif diff --git a/cpp/include/IceUtil/Shared.h b/cpp/include/IceUtil/Shared.h index b9cc3c3d265..38c72dd343b 100644 --- a/cpp/include/IceUtil/Shared.h +++ b/cpp/include/IceUtil/Shared.h @@ -1,364 +1,364 @@ -// ********************************************************************** -// -// Copyright (c) 2001 -// Mutable Realms, Inc. -// Huntsville, AL, USA -// -// All Rights Reserved -// -// ********************************************************************** - -#ifndef ICE_UTIL_SHARED_H -#define ICE_UTIL_SHARED_H - -#include - -// -// The inline assembler causes problems with shared libraries. -// -#if defined(__ICC) && !defined(_WIN32) -# define ICE_USE_MUTEX_SHARED -#endif - -#ifdef ICE_USE_MUTEX_SHARED -# include -#endif - -#if !defined(_WIN32) && !defined(ICE_USE_MUTEX_SHARED) - -// -// Linux only. Unfortunately, asm/atomic.h builds non-SMP safe code -// with non-SMP kernels. This means that executables compiled with a -// non-SMP kernel would fail randomly due to concurrency errors with -// reference counting on SMP hosts. Therefore the relevent pieces of -// atomic.h are more-or-less duplicated. -// - -/* - * Make sure gcc doesn't try to be clever and move things around - * on us. We need to use _exactly_ the address the user gave us, - * not some alias that contains the same information. - */ -struct ice_atomic_t -{ - volatile int counter; -}; - -/* - * ice_atomic_set - set ice_atomic variable - * @v: pointer of type ice_atomic_t - * @i: required value - * - * Atomically sets the value of @v to @i. Note that the guaranteed - * useful range of an ice_atomic_t is only 24 bits. - */ -inline void ice_atomic_set(ice_atomic_t* v, int i) -{ - v->counter = i; -} - -/* - * ice_atomic_inc - increment ice_atomic variable - * @v: pointer of type ice_atomic_t - * - * Atomically increments @v by 1. Note that the guaranteed useful - * range of an ice_atomic_t is only 24 bits. - * - * Inlined because this operation is performance critical. - */ -inline void ice_atomic_inc(ice_atomic_t *v) -{ - __asm__ __volatile__( - "lock ; incl %0" - :"=m" (v->counter) - :"m" (v->counter)); -} - -/** - * ice_atomic_dec_and_test - decrement and test - * @v: pointer of type ice_atomic_t - * - * Atomically decrements @v by 1 and returns true if the result is 0, - * or false for all other cases. Note that the guaranteed useful - * range of an ice_atomic_t is only 24 bits. - * - * Inlined because this operation is performance critical. - */ -inline int ice_atomic_dec_and_test(ice_atomic_t *v) -{ - unsigned char c; - __asm__ __volatile__( - "lock ; decl %0; sete %1" - :"=m" (v->counter), "=qm" (c) - :"m" (v->counter) : "memory"); - return c != 0; -} - -/** - * ice_atomic_exchange_add - same as InterlockedExchangeAdd. This - * didn't come from atomic.h (the code was derived from similar code - * in /usr/include/asm/rwsem.h) - * - * Inlined because this operation is performance critical. - */ -inline int ice_atomic_exchange_add(int i, ice_atomic_t* v) -{ - int tmp = i; - __asm__ __volatile__( - "lock ; xadd %0,(%2)" - :"+r"(tmp), "=m"(v->counter) - :"r"(v), "m"(v->counter) - : "memory"); - return tmp + i; -} - -#endif - -// -// Base classes for reference counted types. The IceUtil::Handle -// template can be used for smart pointers to types derived from these -// bases. -// -// IceUtil::SimpleShared -// ===================== -// -// A non thread-safe base class for reference-counted types. -// -// IceUtil::Shared -// =============== -// -// A thread-safe base class for reference-counted types. -// -namespace IceUtil -{ - -// -// TODO: Not all operations in this class are performance critical, -// thus not all of them should be inlined. -// - -class SimpleShared : public noncopyable -{ -public: - - SimpleShared() : - _ref(0), - _noDelete(false) - { - } - - virtual ~SimpleShared() - { - } - - void __incRef() - { - assert(_ref >= 0); - ++_ref; - } - - void __decRef() - { - assert(_ref > 0); - if(--_ref == 0) - { - if(!_noDelete) - { - delete this; - } - } - } - - int __getRef() const - { - return _ref; - } - - void __setNoDelete(bool b) - { - _noDelete = b; - } - -private: - - int _ref; - bool _noDelete; -}; - -class Shared : public noncopyable -{ -public: - - Shared(); - virtual ~Shared(); - void __incRef(); - void __decRef(); - int __getRef() const; - void __setNoDelete(bool); - -private: - -#ifdef ICE_USE_MUTEX_SHARED - int _ref; - Mutex _mutex; -#elif defined(_WIN32) - LONG _ref; -#else - ice_atomic_t _ref; -#endif - bool _noDelete; -}; - -// -// TODO: Not all operations below are performance critical, thus not -// all of them should be inlined. -// - -#ifdef ICE_USE_MUTEX_SHARED - -inline -Shared::Shared() : - _ref(0), - _noDelete(false) -{ -} - -inline -Shared::~Shared() -{ -} - -inline void -Shared::__incRef() -{ - _mutex.lock(); - assert(_ref >= 0); - ++_ref; - _mutex.unlock(); -} - -inline void -Shared::__decRef() -{ - _mutex.lock(); - bool doDelete = false; - assert(_ref > 0); - if(--_ref == 0) - { - doDelete = !_noDelete; - } - _mutex.unlock(); - if(doDelete) - { - delete this; - } -} - -inline int -Shared::__getRef() const -{ - _mutex.lock(); - int ref = _ref; - _mutex.unlock(); - return ref; -} - -inline void -Shared::__setNoDelete(bool b) -{ - _mutex.lock(); - _noDelete = b; - _mutex.unlock(); -} - -#elif defined(_WIN32) - -inline -Shared::Shared() : - _ref(0), - _noDelete(false) -{ -} - -inline -Shared::~Shared() -{ -} - -inline void -Shared::__incRef() -{ - assert(InterlockedExchangeAdd(&_ref, 0) >= 0); - InterlockedIncrement(&_ref); -} - -inline void -Shared::__decRef() -{ - assert(InterlockedExchangeAdd(&_ref, 0) > 0); - if(InterlockedDecrement(&_ref) == 0 && !_noDelete) - { - delete this; - } -} - -inline int -Shared::__getRef() const -{ - return InterlockedExchangeAdd(const_cast(&_ref), 0); -} - -inline void -Shared::__setNoDelete(bool b) -{ - _noDelete = b; -} - -#else - -inline -Shared::Shared() : - _noDelete(false) -{ - ice_atomic_set(&_ref, 0); -} - -inline -Shared::~Shared() -{ -} - -inline void -Shared::__incRef() -{ - assert(ice_atomic_exchange_add(0, &_ref) >= 0); - ice_atomic_inc(&_ref); -} - -inline void -Shared::__decRef() -{ - assert(ice_atomic_exchange_add(0, &_ref) > 0); - if(ice_atomic_dec_and_test(&_ref) && !_noDelete) - { - delete this; - } -} - -inline int -Shared::__getRef() const -{ - return ice_atomic_exchange_add(0, const_cast(&_ref)); -} - -inline void -Shared::__setNoDelete(bool b) -{ - _noDelete = b; -} - -#endif - -} - -#endif +// ********************************************************************** +// +// Copyright (c) 2001 +// Mutable Realms, Inc. +// Huntsville, AL, USA +// +// All Rights Reserved +// +// ********************************************************************** + +#ifndef ICE_UTIL_SHARED_H +#define ICE_UTIL_SHARED_H + +#include + +// +// The inline assembler causes problems with shared libraries. +// +#if defined(__ICC) && !defined(_WIN32) +# define ICE_USE_MUTEX_SHARED +#endif + +#ifdef ICE_USE_MUTEX_SHARED +# include +#endif + +#if !defined(_WIN32) && !defined(ICE_USE_MUTEX_SHARED) + +// +// Linux only. Unfortunately, asm/atomic.h builds non-SMP safe code +// with non-SMP kernels. This means that executables compiled with a +// non-SMP kernel would fail randomly due to concurrency errors with +// reference counting on SMP hosts. Therefore the relevent pieces of +// atomic.h are more-or-less duplicated. +// + +/* + * Make sure gcc doesn't try to be clever and move things around + * on us. We need to use _exactly_ the address the user gave us, + * not some alias that contains the same information. + */ +struct ice_atomic_t +{ + volatile int counter; +}; + +/* + * ice_atomic_set - set ice_atomic variable + * @v: pointer of type ice_atomic_t + * @i: required value + * + * Atomically sets the value of @v to @i. Note that the guaranteed + * useful range of an ice_atomic_t is only 24 bits. + */ +inline void ice_atomic_set(ice_atomic_t* v, int i) +{ + v->counter = i; +} + +/* + * ice_atomic_inc - increment ice_atomic variable + * @v: pointer of type ice_atomic_t + * + * Atomically increments @v by 1. Note that the guaranteed useful + * range of an ice_atomic_t is only 24 bits. + * + * Inlined because this operation is performance critical. + */ +inline void ice_atomic_inc(ice_atomic_t *v) +{ + __asm__ __volatile__( + "lock ; incl %0" + :"=m" (v->counter) + :"m" (v->counter)); +} + +/** + * ice_atomic_dec_and_test - decrement and test + * @v: pointer of type ice_atomic_t + * + * Atomically decrements @v by 1 and returns true if the result is 0, + * or false for all other cases. Note that the guaranteed useful + * range of an ice_atomic_t is only 24 bits. + * + * Inlined because this operation is performance critical. + */ +inline int ice_atomic_dec_and_test(ice_atomic_t *v) +{ + unsigned char c; + __asm__ __volatile__( + "lock ; decl %0; sete %1" + :"=m" (v->counter), "=qm" (c) + :"m" (v->counter) : "memory"); + return c != 0; +} + +/** + * ice_atomic_exchange_add - same as InterlockedExchangeAdd. This + * didn't come from atomic.h (the code was derived from similar code + * in /usr/include/asm/rwsem.h) + * + * Inlined because this operation is performance critical. + */ +inline int ice_atomic_exchange_add(int i, ice_atomic_t* v) +{ + int tmp = i; + __asm__ __volatile__( + "lock ; xadd %0,(%2)" + :"+r"(tmp), "=m"(v->counter) + :"r"(v), "m"(v->counter) + : "memory"); + return tmp + i; +} + +#endif + +// +// Base classes for reference counted types. The IceUtil::Handle +// template can be used for smart pointers to types derived from these +// bases. +// +// IceUtil::SimpleShared +// ===================== +// +// A non thread-safe base class for reference-counted types. +// +// IceUtil::Shared +// =============== +// +// A thread-safe base class for reference-counted types. +// +namespace IceUtil +{ + +// +// TODO: Not all operations in this class are performance critical, +// thus not all of them should be inlined. +// + +class SimpleShared : public noncopyable +{ +public: + + SimpleShared() : + _ref(0), + _noDelete(false) + { + } + + virtual ~SimpleShared() + { + } + + void __incRef() + { + assert(_ref >= 0); + ++_ref; + } + + void __decRef() + { + assert(_ref > 0); + if(--_ref == 0) + { + if(!_noDelete) + { + delete this; + } + } + } + + int __getRef() const + { + return _ref; + } + + void __setNoDelete(bool b) + { + _noDelete = b; + } + +private: + + int _ref; + bool _noDelete; +}; + +class Shared : public noncopyable +{ +public: + + Shared(); + virtual ~Shared(); + void __incRef(); + void __decRef(); + int __getRef() const; + void __setNoDelete(bool); + +private: + +#ifdef ICE_USE_MUTEX_SHARED + int _ref; + Mutex _mutex; +#elif defined(_WIN32) + LONG _ref; +#else + ice_atomic_t _ref; +#endif + bool _noDelete; +}; + +// +// TODO: Not all operations below are performance critical, thus not +// all of them should be inlined. +// + +#ifdef ICE_USE_MUTEX_SHARED + +inline +Shared::Shared() : + _ref(0), + _noDelete(false) +{ +} + +inline +Shared::~Shared() +{ +} + +inline void +Shared::__incRef() +{ + _mutex.lock(); + assert(_ref >= 0); + ++_ref; + _mutex.unlock(); +} + +inline void +Shared::__decRef() +{ + _mutex.lock(); + bool doDelete = false; + assert(_ref > 0); + if(--_ref == 0) + { + doDelete = !_noDelete; + } + _mutex.unlock(); + if(doDelete) + { + delete this; + } +} + +inline int +Shared::__getRef() const +{ + _mutex.lock(); + int ref = _ref; + _mutex.unlock(); + return ref; +} + +inline void +Shared::__setNoDelete(bool b) +{ + _mutex.lock(); + _noDelete = b; + _mutex.unlock(); +} + +#elif defined(_WIN32) + +inline +Shared::Shared() : + _ref(0), + _noDelete(false) +{ +} + +inline +Shared::~Shared() +{ +} + +inline void +Shared::__incRef() +{ + assert(InterlockedExchangeAdd(&_ref, 0) >= 0); + InterlockedIncrement(&_ref); +} + +inline void +Shared::__decRef() +{ + assert(InterlockedExchangeAdd(&_ref, 0) > 0); + if(InterlockedDecrement(&_ref) == 0 && !_noDelete) + { + delete this; + } +} + +inline int +Shared::__getRef() const +{ + return InterlockedExchangeAdd(const_cast(&_ref), 0); +} + +inline void +Shared::__setNoDelete(bool b) +{ + _noDelete = b; +} + +#else + +inline +Shared::Shared() : + _noDelete(false) +{ + ice_atomic_set(&_ref, 0); +} + +inline +Shared::~Shared() +{ +} + +inline void +Shared::__incRef() +{ + assert(ice_atomic_exchange_add(0, &_ref) >= 0); + ice_atomic_inc(&_ref); +} + +inline void +Shared::__decRef() +{ + assert(ice_atomic_exchange_add(0, &_ref) > 0); + if(ice_atomic_dec_and_test(&_ref) && !_noDelete) + { + delete this; + } +} + +inline int +Shared::__getRef() const +{ + return ice_atomic_exchange_add(0, const_cast(&_ref)); +} + +inline void +Shared::__setNoDelete(bool b) +{ + _noDelete = b; +} + +#endif + +} + +#endif diff --git a/cpp/include/IceUtil/Thread.h b/cpp/include/IceUtil/Thread.h index 5facd15aafb..172c411c18c 100644 --- a/cpp/include/IceUtil/Thread.h +++ b/cpp/include/IceUtil/Thread.h @@ -1,117 +1,117 @@ -// ********************************************************************** -// -// Copyright (c) 2001 -// Mutable Realms, Inc. -// Huntsville, AL, USA -// -// All Rights Reserved -// -// ********************************************************************** - -#ifndef ICE_UTIL_THREAD_H -#define ICE_UTIL_THREAD_H - -#include -#include - -namespace IceUtil -{ - -class Time; - -#ifdef _WIN32 -struct HandleWrapper : public Shared -{ - // Inline for performance reasons. - HandleWrapper(HANDLE h) : - handle(h) - { - } - - // Inline for performance reasons. - virtual ~HandleWrapper() - { - if(handle != 0) - { - CloseHandle(handle); - } - } - - HANDLE handle; -}; - -typedef Handle HandleWrapperPtr; -#endif - -class ICE_UTIL_API ThreadControl -{ -public: - - ThreadControl(); - -#ifdef _WIN32 - ThreadControl(const HandleWrapperPtr&, unsigned); -#else - ThreadControl(pthread_t); -#endif - - bool operator==(const ThreadControl&) const; - bool operator!=(const ThreadControl&) const; - bool operator<(const ThreadControl&) const; - - // - // Wait until the controlled thread terminates. The call has POSIX - // semantics. - // - // At most one thread can wait for the termination of a given - // thread.C alling join on a thread on which another thread is - // already waiting for termination results in undefined behaviour. - // - void join(); - - static void sleep(const Time&); - static void yield(); - -private: - -#ifdef _WIN32 - HandleWrapperPtr _handle; - unsigned _id; -#else - pthread_t _id; -#endif -}; - -class ICE_UTIL_API Thread : virtual public IceUtil::Shared -{ -public: - - Thread(); - virtual ~Thread(); - - virtual void run() = 0; - - ThreadControl start(); - - ThreadControl getThreadControl(); - - bool operator==(const Thread&) const; - bool operator!=(const Thread&) const; - bool operator<(const Thread&) const; - -private: - -#ifdef _WIN32 - unsigned _id; - HandleWrapperPtr _handle; -#else - pthread_t _id; -#endif -}; - -typedef Handle ThreadPtr; - -} // End namespace IceUtil - -#endif - +// ********************************************************************** +// +// Copyright (c) 2001 +// Mutable Realms, Inc. +// Huntsville, AL, USA +// +// All Rights Reserved +// +// ********************************************************************** + +#ifndef ICE_UTIL_THREAD_H +#define ICE_UTIL_THREAD_H + +#include +#include + +namespace IceUtil +{ + +class Time; + +#ifdef _WIN32 +struct HandleWrapper : public Shared +{ + // Inline for performance reasons. + HandleWrapper(HANDLE h) : + handle(h) + { + } + + // Inline for performance reasons. + virtual ~HandleWrapper() + { + if(handle) + { + CloseHandle(handle); + } + } + + HANDLE handle; +}; + +typedef Handle HandleWrapperPtr; +#endif + +class ICE_UTIL_API ThreadControl +{ +public: + + ThreadControl(); + +#ifdef _WIN32 + ThreadControl(const HandleWrapperPtr&, unsigned); +#else + ThreadControl(pthread_t); +#endif + + bool operator==(const ThreadControl&) const; + bool operator!=(const ThreadControl&) const; + bool operator<(const ThreadControl&) const; + + // + // Wait until the controlled thread terminates. The call has POSIX + // semantics. + // + // At most one thread can wait for the termination of a given + // thread.C alling join on a thread on which another thread is + // already waiting for termination results in undefined behaviour. + // + void join(); + + static void sleep(const Time&); + static void yield(); + +private: + +#ifdef _WIN32 + HandleWrapperPtr _handle; + unsigned _id; +#else + pthread_t _id; +#endif +}; + +class ICE_UTIL_API Thread : virtual public IceUtil::Shared +{ +public: + + Thread(); + virtual ~Thread(); + + virtual void run() = 0; + + ThreadControl start(); + + ThreadControl getThreadControl(); + + bool operator==(const Thread&) const; + bool operator!=(const Thread&) const; + bool operator<(const Thread&) const; + +private: + +#ifdef _WIN32 + unsigned _id; + HandleWrapperPtr _handle; +#else + pthread_t _id; +#endif +}; + +typedef Handle ThreadPtr; + +} + +#endif + diff --git a/cpp/include/IceUtil/ThreadException.h b/cpp/include/IceUtil/ThreadException.h new file mode 100644 index 00000000000..9d4cdc9ad6d --- /dev/null +++ b/cpp/include/IceUtil/ThreadException.h @@ -0,0 +1,47 @@ +// ********************************************************************** +// +// Copyright (c) 2001 +// Mutable Realms, Inc. +// Huntsville, AL, USA +// +// All Rights Reserved +// +// ********************************************************************** + +#ifndef ICE_UTIL_THREAD_EXCEPTION_H +#define ICE_UTIL_THREAD_EXCEPTION_H + +#include + +namespace IceUtil +{ + +class ICE_UTIL_API ThreadSyscallException : public Exception +{ +public: + + ThreadSyscallException(const char*, int); + virtual std::string ice_name() const; + virtual void ice_print(std::ostream&) const; + virtual Exception* ice_clone() const; + virtual void ice_throw() const; + +private: + + const int _error; +}; + +class ICE_UTIL_API ThreadLockedException : public Exception +{ +public: + + ThreadLockedException(const char*, int); + virtual std::string ice_name() const; + virtual Exception* ice_clone() const; + virtual void ice_throw() const; +}; + +} + +#endif + diff --git a/cpp/include/IceUtil/Time.h b/cpp/include/IceUtil/Time.h index ad59dd847b6..241919dbb8a 100644 --- a/cpp/include/IceUtil/Time.h +++ b/cpp/include/IceUtil/Time.h @@ -1,63 +1,63 @@ -// ********************************************************************** -// -// Copyright (c) 2001 -// Mutable Realms, Inc. -// Huntsville, AL, USA -// -// All Rights Reserved -// -// ********************************************************************** - -#ifndef ICE_UTIL_TIME_H -#define ICE_UTIL_TIME_H - -#include - -namespace IceUtil -{ - -class ICE_UTIL_API Time -{ -public: - - Time(); - - // No copy constructor and assignment operator necessary. The - // automatically generated copy constructor and assignment - // operator do the right thing. - - static Time now(); - static Time seconds(long); - static Time milliSeconds(long); -#ifdef _WIN32 - static Time microSeconds(__int64); -#else - static Time microSeconds(long long); -#endif - - Time operator-() const; - Time operator-(const Time&) const; - Time operator+(const Time&) const; - Time& operator+=(const Time&); - Time& operator-=(const Time&); - - bool operator<(const Time&) const; - bool operator<=(const Time&) const; - bool operator>(const Time&) const; - bool operator>=(const Time&) const; - bool operator==(const Time&) const; - bool operator!=(const Time&) const; - - operator timeval() const; - operator double() const; - -private: - - Time(Int64); - - Int64 _usec; -}; - -} // End namespace IceUtil - -#endif +// ********************************************************************** +// +// Copyright (c) 2001 +// Mutable Realms, Inc. +// Huntsville, AL, USA +// +// All Rights Reserved +// +// ********************************************************************** + +#ifndef ICE_UTIL_TIME_H +#define ICE_UTIL_TIME_H + +#include + +namespace IceUtil +{ + +class ICE_UTIL_API Time +{ +public: + + Time(); + + // No copy constructor and assignment operator necessary. The + // automatically generated copy constructor and assignment + // operator do the right thing. + + static Time now(); + static Time seconds(long); + static Time milliSeconds(long); +#ifdef _WIN32 + static Time microSeconds(__int64); +#else + static Time microSeconds(long long); +#endif + + Time operator-() const; + Time operator-(const Time&) const; + Time operator+(const Time&) const; + Time& operator+=(const Time&); + Time& operator-=(const Time&); + + bool operator<(const Time&) const; + bool operator<=(const Time&) const; + bool operator>(const Time&) const; + bool operator>=(const Time&) const; + bool operator==(const Time&) const; + bool operator!=(const Time&) const; + + operator timeval() const; + operator double() const; + +private: + + Time(Int64); + + Int64 _usec; +}; + +} // End namespace IceUtil + +#endif diff --git a/cpp/include/IceUtil/UUID.h b/cpp/include/IceUtil/UUID.h index 2de0c61718f..0c6ee035c08 100644 --- a/cpp/include/IceUtil/UUID.h +++ b/cpp/include/IceUtil/UUID.h @@ -1,23 +1,23 @@ -// ********************************************************************** -// -// Copyright (c) 2001 -// Mutable Realms, Inc. -// Huntsville, AL, USA -// -// All Rights Reserved -// -// ********************************************************************** - -#ifndef ICE_UTIL_UUID_H -#define ICE_UTIL_UUID_H - -#include - -namespace IceUtil -{ - -ICE_UTIL_API std::string generateUUID(); - -} - -#endif +// ********************************************************************** +// +// Copyright (c) 2001 +// Mutable Realms, Inc. +// Huntsville, AL, USA +// +// All Rights Reserved +// +// ********************************************************************** + +#ifndef ICE_UTIL_UUID_H +#define ICE_UTIL_UUID_H + +#include + +namespace IceUtil +{ + +ICE_UTIL_API std::string generateUUID(); + +} + +#endif diff --git a/cpp/include/IceUtil/Unicode.h b/cpp/include/IceUtil/Unicode.h index ca4cd774750..6fb8e6304cd 100644 --- a/cpp/include/IceUtil/Unicode.h +++ b/cpp/include/IceUtil/Unicode.h @@ -1,24 +1,24 @@ -// ********************************************************************** -// -// Copyright (c) 2001 -// Mutable Realms, Inc. -// Huntsville, AL, USA -// -// All Rights Reserved -// -// ********************************************************************** - -#ifndef ICE_UTIL_UNICODE_H -#define ICE_UTIL_UNICODE_H - -#include - -namespace IceUtil -{ - -ICE_UTIL_API std::string wstringToString(const std::wstring&); -ICE_UTIL_API std::wstring stringToWstring(const std::string&); - -} - -#endif +// ********************************************************************** +// +// Copyright (c) 2001 +// Mutable Realms, Inc. +// Huntsville, AL, USA +// +// All Rights Reserved +// +// ********************************************************************** + +#ifndef ICE_UTIL_UNICODE_H +#define ICE_UTIL_UNICODE_H + +#include + +namespace IceUtil +{ + +ICE_UTIL_API std::string wstringToString(const std::wstring&); +ICE_UTIL_API std::wstring stringToWstring(const std::string&); + +} + +#endif -- cgit v1.2.3