![]() ![]() |
![]() |
File: [Pegasus] / pegasus / src / Pegasus / Common / Attic / IPC.h
(download)
Revision: 1.53, Wed Aug 9 20:12:42 2006 UTC (17 years, 10 months ago) by mike Branch: MAIN CVS Tags: TASK-PEP362_RestfulService-merged_out_from_trunk, TASK-PEP348_SCMO-merged_out_from_trunk, TASK-PEP317_pullop-merged_out_from_trunk, TASK-PEP317_pullop-merged_in_to_trunk, TASK-PEP311_WSMan-root, TASK-PEP311_WSMan-branch, HPUX_TEST, HEAD Changes since 1.52: +0 -0 lines FILE REMOVED BUG#: 5314 TITLE: IPC Refactoring DESCRIPTION: This patch cleans up the IPC related classes. It (1) reorganizes related classes into their own headers, (2) makes the mutex class recursive to eliminate recursive lock exclusion logic, (3) reimplements condition variables, renames dozens of global functions. |
//%2006//////////////////////////////////////////////////////////////////////// // // Copyright (c) 2000, 2001, 2002 BMC Software; Hewlett-Packard Development // Company, L.P.; IBM Corp.; The Open Group; Tivoli Systems. // Copyright (c) 2003 BMC Software; Hewlett-Packard Development Company, L.P.; // IBM Corp.; EMC Corporation, The Open Group. // Copyright (c) 2004 BMC Software; Hewlett-Packard Development Company, L.P.; // IBM Corp.; EMC Corporation; VERITAS Software Corporation; The Open Group. // Copyright (c) 2005 Hewlett-Packard Development Company, L.P.; IBM Corp.; // EMC Corporation; VERITAS Software Corporation; The Open Group. // Copyright (c) 2006 Hewlett-Packard Development Company, L.P.; IBM Corp.; // EMC Corporation; Symantec Corporation; The Open Group. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to // deal in the Software without restriction, including without limitation the // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or // sell copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // THE ABOVE COPYRIGHT NOTICE AND THIS PERMISSION NOTICE SHALL BE INCLUDED IN // ALL COPIES OR SUBSTANTIAL PORTIONS OF THE SOFTWARE. THE SOFTWARE IS PROVIDED // "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT // LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR // PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // //============================================================================== // // Author: Mike Day (mdday@us.ibm.com) // // Modified By: Markus Mueller // Ramnath Ravindran (Ramnath.Ravindran@compaq.com) // David Eger (dteger@us.ibm.com) // Amit K Arora, IBM (amita@in.ibm.com) for PEP#101 // Sean Keenan, Hewlett-Packard Company (sean.keenan@hp.com) // Roger Kumpf, Hewlett-Packard Company (roger_kumpf@hp.com) // David Dillard, VERITAS Software Corp. // (david.dillard@veritas.com) // Aruran, IBM (ashanmug@in.ibm.com) for BUG# 3518, 4067 // //%///////////////////////////////////////////////////////////////////////////// #ifndef Pegasus_IPC_h #define Pegasus_IPC_h #include <Pegasus/Common/Config.h> #include <Pegasus/Common/Network.h> #include <Pegasus/Common/Linkage.h> #include <Pegasus/Common/AutoPtr.h> #include <Pegasus/Common/IPCTypes.h> #include <Pegasus/Common/Mutex.h> #include <Pegasus/Common/AtomicInt.h> #define PEG_SEM_READ 1 #define PEG_SEM_WRITE 2 #include <Pegasus/Common/List.h> PEGASUS_NAMESPACE_BEGIN int timeval_subtract (struct timeval *result, struct timeval *x, struct timeval *y); //%///////////////// ----- IPC related functions ------- ////////////////////// // ----- NOTE - these functions are PRIMITIVES that MUST be implemented // by the platform. e.g., see IPCUnix.cpp void PEGASUS_COMMON_LINKAGE disable_cancel(); void PEGASUS_COMMON_LINKAGE enable_cancel(); //void PEGASUS_COMMON_LINKAGE native_cleanup_push( void (*)(void *), void * ); void PEGASUS_COMMON_LINKAGE native_cleanup_pop(Boolean execute); #ifdef PEGASUS_NEED_CRITICAL_TYPE void PEGASUS_COMMON_LINKAGE init_crit(PEGASUS_CRIT_TYPE *crit); void PEGASUS_COMMON_LINKAGE enter_crit(PEGASUS_CRIT_TYPE *crit); void PEGASUS_COMMON_LINKAGE try_crit(PEGASUS_CRIT_TYPE *crit); void PEGASUS_COMMON_LINKAGE destroy_crit(PEGASUS_CRIT_TYPE *crit); void PEGASUS_COMMON_LINKAGE exit_crit(PEGASUS_CRIT_TYPE *crit); #endif PEGASUS_THREAD_TYPE PEGASUS_COMMON_LINKAGE pegasus_thread_self(); void PEGASUS_COMMON_LINKAGE exit_thread(PEGASUS_THREAD_RETURN rc); void PEGASUS_COMMON_LINKAGE pegasus_sleep(int ms); void PEGASUS_COMMON_LINKAGE destroy_thread(PEGASUS_THREAD_TYPE th, PEGASUS_THREAD_RETURN rc); //%//////// -------- IPC Exception Classes -------- /////////////////////////////// class PEGASUS_COMMON_LINKAGE IPCException { public: IPCException(PEGASUS_THREAD_TYPE owner): _owner(owner) { } inline PEGASUS_THREAD_TYPE get_owner() { return(_owner); } private: PEGASUS_THREAD_TYPE _owner; }; class PEGASUS_COMMON_LINKAGE Deadlock: public IPCException { public: Deadlock(PEGASUS_THREAD_TYPE owner) : IPCException(owner) {} private: Deadlock(); }; class PEGASUS_COMMON_LINKAGE AlreadyLocked: public IPCException { public: AlreadyLocked(PEGASUS_THREAD_TYPE owner) : IPCException(owner) {} private: AlreadyLocked(); }; class PEGASUS_COMMON_LINKAGE TimeOut: public IPCException { public: TimeOut(PEGASUS_THREAD_TYPE owner) : IPCException(owner) {} private: TimeOut(); }; class PEGASUS_COMMON_LINKAGE Permission: public IPCException { public: Permission(PEGASUS_THREAD_TYPE owner) : IPCException(owner) {} private: Permission(); }; class PEGASUS_COMMON_LINKAGE WaitFailed: public IPCException { public: WaitFailed(PEGASUS_THREAD_TYPE owner) : IPCException(owner) {} private: WaitFailed(); }; class PEGASUS_COMMON_LINKAGE WaitInterrupted: public IPCException { public: WaitInterrupted(PEGASUS_THREAD_TYPE owner) : IPCException(owner) {} private: WaitInterrupted(); }; class PEGASUS_COMMON_LINKAGE TooManyReaders: public IPCException { public: TooManyReaders(PEGASUS_THREAD_TYPE owner) : IPCException(owner) { } private: TooManyReaders(); }; class PEGASUS_COMMON_LINKAGE ListFull: public IPCException { public: ListFull(Uint32 count) : IPCException(pegasus_thread_self()) { _capacity = count; } Uint32 get_capacity() const throw() { return _capacity; } private: ListFull(); Uint32 _capacity; }; class PEGASUS_COMMON_LINKAGE ListClosed: public IPCException { public: ListClosed() : IPCException(pegasus_thread_self()) { } }; class PEGASUS_COMMON_LINKAGE ModuleClosed: public IPCException { public: ModuleClosed() : IPCException(pegasus_thread_self()) { } }; //%////////////////////////////////////////////////////////////// // AutoMutex - use when you could lose scope due to an exception ///////////////////////////////////////////////////////////////// class PEGASUS_COMMON_LINKAGE AutoMutex { public: AutoMutex(Mutex& mutex, Boolean autoLock = true) : _mutex(mutex), _locked(autoLock) { if (autoLock) { _mutex.lock(pegasus_thread_self()); } } ~AutoMutex() { try { if (_locked) { unlock(); } } catch (...) { // Do not propagate exception from destructor } } void lock() { if (_locked) { throw AlreadyLocked(pegasus_thread_self()); } _mutex.lock(pegasus_thread_self()); _locked = true; } void unlock() { if (!_locked) { throw Permission(pegasus_thread_self()); } _mutex.unlock(); _locked = false; } Boolean isLocked() const { return _locked; } private: AutoMutex(); // Unimplemented AutoMutex(const AutoMutex& x); // Unimplemented AutoMutex& operator=(const AutoMutex& x); // Unimplemented Mutex& _mutex; Boolean _locked; }; //%//////////////////////////////////////////////////////////////////////////// class PEGASUS_COMMON_LINKAGE Semaphore { public: /** Creates a semaphore and sets its initial value as specified. @param initial The initial value for the Semaphore (defaults to 1). */ Semaphore(Uint32 initial = 1); ~Semaphore(); /** Blocks until this Semaphore is in a signalled state. @param ignoreInterrupt Indicates whether the wait operation should continue (true) or an exception should be thrown (false) when an interrupt is received. @exception WaitFailed If unable to block on the semaphore. @exception WaitInterrupted If the operation is interrupted. */ void wait(Boolean ignoreInterrupt = true); /** Checks whether the Semaphore is signalled without waiting. This method returns normally if the Semaphore has a non-zero count. @exception WaitFailed If the wait operation does not immediately succeed. */ void try_wait(); /** Waits for the Semaphore to be signalled for a specified time interval. This method returns normally if the Semaphore has a non-zero count or it is signalled during the specified time interval. @param milliseconds The time interval to wait (in milliseconds). @exception TimeOut If the wait operation does not succeed within the specified time interval. */ void time_wait(Uint32 milliseconds); /** Increments the count of the semaphore. */ void signal(); /** Return the count of the semaphore. */ int count() const; private: Semaphore(const Semaphore& x); // Unimplemented Semaphore& operator=(const Semaphore& x); // Unimplemented mutable PEGASUS_SEM_HANDLE _semaphore; // may not need to use the _count member on // platforms that allow you to ask the semaphore for // its count mutable int _count; //------------------------------------------------------------------------------ // // AtomicInt inclusion: // //------------------------------------------------------------------------------ friend class Condition; }; PEGASUS_NAMESPACE_END #include <Pegasus/Common/AtomicInt.h> PEGASUS_NAMESPACE_BEGIN //----------------------------------------------------------------- /// Generic definition of read/write semaphore //----------------------------------------------------------------- #ifndef PEGASUS_READWRITE_NATIVE typedef struct pegasus_rwlock { Semaphore _rlock; Mutex _wlock; Mutex _internal_lock; PEGASUS_THREAD_TYPE _owner; pegasus_rwlock() : _rlock(10), _wlock(), _internal_lock(), _owner(pegasus_thread_self()) { } } PEGASUS_RWLOCK_HANDLE; #endif class PEGASUS_COMMON_LINKAGE ReadWriteSem { public: ReadWriteSem(); ~ReadWriteSem(); // @exception Deadlock // @exception Permission // @exception WaitFailed inline void wait_read(PEGASUS_THREAD_TYPE caller) { wait(PEG_SEM_READ, caller ); } // @exception Deadlock // @exception Permission // @exception WaitFailed inline void wait_write(PEGASUS_THREAD_TYPE caller) { wait(PEG_SEM_WRITE, caller); } // @exception Deadlock // @exception Permission // @exception AlreadyLocked // @exception WaitFailed inline void try_wait_read(PEGASUS_THREAD_TYPE caller) { try_wait(PEG_SEM_READ, caller); } // @exception Deadlock // @exception Permission // @exception AlreadyLocked // @exception WaitFailed inline void try_wait_write(PEGASUS_THREAD_TYPE caller) { try_wait(PEG_SEM_WRITE, caller); } // @exception Deadlock // @exception Permission // @exception TimeOut // @exception WaitFailed inline void timed_wait_read(PEGASUS_THREAD_TYPE caller, int milliseconds) { timed_wait(PEG_SEM_READ, caller, milliseconds); } // @exception Deadlock // @exception Permission // @exception TimeOut // @exception WaitFailed inline void timed_wait_write(PEGASUS_THREAD_TYPE caller, int milliseconds) { timed_wait(PEG_SEM_WRITE, caller, milliseconds); } // @exception Permission inline void unlock_read(PEGASUS_THREAD_TYPE caller) { unlock(PEG_SEM_READ, caller); } // @exception Permission inline void unlock_write(PEGASUS_THREAD_TYPE caller) { unlock(PEG_SEM_WRITE, caller); } int read_count() const; int write_count() const; // @exception Deadlock // @exception Permission // @exception WaitFailed // @exception TooManyReaders void wait(Uint32 mode, PEGASUS_THREAD_TYPE caller); // @exception Deadlock // @exception Permission // @exception WaitFailed // @exception TooManyReaders void try_wait(Uint32 mode, PEGASUS_THREAD_TYPE caller); // @exception Timeout // @exception Deadlock // @exception Permission // @exception WaitFailed // @exception TooManyReaders void timed_wait(Uint32 mode, PEGASUS_THREAD_TYPE caller, int milliseconds); // @exception Permission void unlock(Uint32 mode, PEGASUS_THREAD_TYPE caller); private: AtomicInt _readers; AtomicInt _writers; PEGASUS_RWLOCK_HANDLE _rwlock; friend void extricate_read_write(void *); }; // Classes used for safe locking of ReadWriteSem class ReadLock { public: ReadLock(ReadWriteSem & rwsem) : _rwsem(rwsem) { _rwsem.wait_read(pegasus_thread_self()); } ~ReadLock() { _rwsem.unlock_read(pegasus_thread_self()); } private: ReadWriteSem & _rwsem; }; class WriteLock { public: WriteLock(ReadWriteSem & rwsem) : _rwsem(rwsem) { _rwsem.wait_write(pegasus_thread_self()); } ~WriteLock() { _rwsem.unlock_write(pegasus_thread_self()); } private: ReadWriteSem & _rwsem; }; //----------------------------------------------------------------- /// Generic definition of conditional semaphore //----------------------------------------------------------------- #ifndef PEGASUS_CONDITIONAL_NATIVE // typedef PEGASUS_SEMAPHORE_TYPE PEGASUS_COND_TYPE; class PEGASUS_COMMON_LINKAGE cond_waiter : public Linkable { public: cond_waiter( PEGASUS_THREAD_TYPE caller, Sint32 time = -1) : waiter(caller), signalled(0) { } ~cond_waiter() { signalled.signal(); } private: cond_waiter(); PEGASUS_THREAD_TYPE waiter; Semaphore signalled; friend class Condition; }; typedef struct peg_condition{ List<cond_waiter, NullLock> _waiters; Mutex _spin; peg_condition() : _waiters(), _spin() { } } PEGASUS_COND_TYPE; #endif class PEGASUS_COMMON_LINKAGE Condition { public: // create the condition variable Condition(); ~Condition(); Condition(Mutex& mutex); // signal the condition variable // @exception IPCException void signal(PEGASUS_THREAD_TYPE caller); // @exception IPCException void lock_object(PEGASUS_THREAD_TYPE caller); // @exception IPCException void try_lock_object(PEGASUS_THREAD_TYPE caller); // @exception IPCException void wait_lock_object(PEGASUS_THREAD_TYPE caller, int milliseconds); void unlock_object(); // without pthread_mutex_lock/unlock // @exception IPCException void unlocked_wait(PEGASUS_THREAD_TYPE caller); // @exception IPCException void unlocked_timed_wait(int milliseconds, PEGASUS_THREAD_TYPE caller); // @exception IPCException void unlocked_signal(PEGASUS_THREAD_TYPE caller); void set_owner(PEGASUS_THREAD_TYPE caller) { _cond_mutex->_set_owner(caller); } void disallow() { _disallow++; } void reallow() { if(_disallow.get() > 0) _disallow--; } Boolean is_shutdown() const { if(_disallow.get() > 0) return true; return false; } private: AtomicInt _disallow; // don't allow any further waiters Boolean _destroy_mut; PEGASUS_COND_TYPE _condition; // special type to control execution flow AutoPtr<Mutex> _cond_mutex; // the conditional mutex //PEP101 friend void extricate_condition(void *); // Hide the copy constructor and assignment operator to avoid implicit // use of the defaults implementations. Condition(const Condition& original); Condition& operator=(const Condition& original); }; #if defined(PEGASUS_PLATFORM_WIN32_IX86_MSVC) # include "IPCWindows_inline.h" #elif defined(PEGASUS_PLATFORM_LINUX_GENERIC_GNU) # include "IPCUnix_inline.h" #elif defined(PEGASUS_PLATFORM_HPUX_ACC) # include "IPCUnix_inline.h" #elif defined(PEGASUS_PLATFORM_SOLARIS_SPARC_GNU) # include "IPCUnix_inline.h" #elif defined(PEGASUS_PLATFORM_SOLARIS_SPARC_CC) # include "IPCUnix_inline.h" #elif defined(PEGASUS_PLATFORM_AIX_RS_IBMCXX) # include "IPCUnix_inline.h" #elif defined(PEGASUS_PLATFORM_ZOS_ZSERIES_IBM) # include "IPCUnix_inline.h" #elif defined(PEGASUS_PLATFORM_TRU64_ALPHA_DECCXX) # include "IPCUnix_inline.h" #elif defined(PEGASUS_PLATFORM_OS400_ISERIES_IBM) # include "IPCUnix_inline.h" #elif defined(PEGASUS_PLATFORM_DARWIN_PPC_GNU) # include "IPCUnix_inline.h" #elif defined(PEGASUS_OS_VMS) # include "IPCVms_inline.h" #endif PEGASUS_NAMESPACE_END #endif /* Pegasus_IPC_h */
No CVS admin address has been configured |
Powered by ViewCVS 0.9.2 |