diff options
-rw-r--r-- | ChangeLog-96b | 55 | ||||
-rw-r--r-- | README | 3 | ||||
-rw-r--r-- | ace/ACE.cpp | 16 | ||||
-rw-r--r-- | ace/Module.cpp | 152 | ||||
-rw-r--r-- | ace/Module.h | 65 | ||||
-rw-r--r-- | ace/OS.cpp | 9 | ||||
-rw-r--r-- | ace/OS.h | 169 | ||||
-rw-r--r-- | ace/OS.i | 4 | ||||
-rw-r--r-- | ace/Signal.cpp | 4 | ||||
-rw-r--r-- | ace/Stream.cpp | 6 | ||||
-rw-r--r-- | ace/Stream.h | 10 | ||||
-rw-r--r-- | ace/Svc_Conf_y.cpp | 4 | ||||
-rw-r--r-- | ace/Synch.cpp | 162 | ||||
-rw-r--r-- | ace/Synch.h | 586 | ||||
-rw-r--r-- | ace/Synch.i | 166 | ||||
-rw-r--r-- | ace/Synch_T.cpp | 4 | ||||
-rw-r--r-- | ace/Task.cpp | 7 | ||||
-rw-r--r-- | ace/Task.h | 12 | ||||
-rw-r--r-- | ace/Task_T.i | 4 | ||||
-rw-r--r-- | ace/Thread_Manager.cpp | 7 | ||||
-rw-r--r-- | ace/config-mvs.h | 7 | ||||
-rw-r--r-- | tests/Process_Mutex_Test.cpp | 26 |
22 files changed, 825 insertions, 653 deletions
diff --git a/ChangeLog-96b b/ChangeLog-96b index bd4b412ed2f..dbe9247aa1d 100644 --- a/ChangeLog-96b +++ b/ChangeLog-96b @@ -1,4 +1,59 @@ +Sat Dec 7 16:55:37 1996 Douglas C. Schmidt <schmidt@tango.cs.wustl.edu> + + * ace/Thread_Manager.cpp: Because thread_descriptor_i() only returns + 0 or -1 on failure the code for + ACE_Thread_Manager::thr_self(ACE_hthread_t &) should read: + + if (-1 == this->thread_descriptor_i (id, td)) + return -1; + handle = &td.thr_handle_; + + Thanks to Matthias for reporting this. + + * ace/OS: Added a new static instance of ACE_thread_key_t to work + around the pthreads implementation on MVS (which doesn't store + TSS keys as ints!). Thanks to Chuck Gehr for reporting this. + + * ace/config-mvs.h: Added #define ACE_TEMPLATES_REQUIRE_SOURCE for + MVS C++. Thanks to Chuck Gehr for reporting this. + + * ace/Signal.cpp: ace_dispatcher was being set to + ace_signal_handlers_dispatch() which calls + ACE_Sig_Handlers::dispatch (when ACE_HAS_SIC_C_FUNC is defined), + whereas it was set to ACE_SigHanlder::dispatch (no s) if not + defined. I intended to set this to ace_signal_handler_dispatch + (no s). Thanks to Chuck Gehr for reporting this. + + * ace/Makefile: Fixed a small typo where I wasn't matching char + *getenv in the sed regular expression. + + * ace/{OS,Synch}: Moved various classes around so that things will + compile correctly when ACE_WIN32 is defined but ACE_HAS_THREADS + is *not* defined. Thanks to Robert Lyng + <RLyng@msmail.hsii.ccare.com> for reporting this. + +Sat Dec 7 16:55:37 1996 Matthias Kerkhoff <make@cs.tu-berlin.de> + + * ace/Module: Added some values to the enum so Module clients + can decide whether the reader, the writer or both should be + automatically deleted. + + * ace/{Stream,Module,Task}: Changed some function arguments + from u_long to int (because enums are represented as ints). + + * ace/Task: Added a new virtual function to ACE_Task_Base + (module_closed), which by default calls + ACE_Task_Base::close(1). Please note the changed flags + argument. This allows clients to differ between calls + originated from a Module and/or Stream from those which + result from ~ACE_Task_Exit(). ~ACE_Task_Exit() calls + ACE_Task_Base::close(0). This may be or not be a problem to + existing applications. It may (hopefully not) + be neccessary to change ACE_Task_Base::module_close back to + calling ACE_Task_Base::close(0). + Fri Dec 06 14:44:20 1996 David L. Levine <levine@cs.wustl.edu> + * ace/OS.cpp: added ::spa () function to allow command line args to be passed to programs in VxWorks @@ -145,7 +145,7 @@ The following subdirectories are included in C++_wrappers.tar.gz file: . ace -- the source code and binaries for C++ components (note that all of these are at the same "level" in order to work around - deficiencies with Windows NT...) + Windows NT lack of symbolic links...) . ASX -- higher-level C++ network programming framework based on System V STREAMs . Collections -- stacks, sets, strings, etc. @@ -665,6 +665,7 @@ James Michael Dwyer <jdwyer@knox.edu> Arun Katkere <katkere@praja.com> Bob Dunmire <bobd@titan.com> Sandro Doro <alex@aureus.sublink.org> +Robert Lyng <RLyng@msmail.hsii.ccare.com> I would particularly like to thank Paul Stephenson, who worked with me at Ericsson and is now at ObjectSpace. Paul devised the recursive diff --git a/ace/ACE.cpp b/ace/ACE.cpp index 5445829bc32..cb581916ba4 100644 --- a/ace/ACE.cpp +++ b/ace/ACE.cpp @@ -475,14 +475,14 @@ ACE::timestamp (char date_and_time[], int date_and_timelen) SYSTEMTIME local; ::GetLocalTime (&local); - ACE_OS::sprintf (date_and_time, "%02d/%02d/%04d%02d.%02d.%02d.%06d", - (int) local.wMonth, // new, also the %02d in sprintf - (int) local.wDay, // new, also the %02d in sprintf - (int) local.wYear, // new, also the %02d in sprintf - (int) local.wHour, - (int) local.wMinute, - (int) local.wSecond, - (int) local.wMilliseconds * 1000); + ::sprintf (date_and_time, "%02d/%02d/%04d %02d.%02d.%02d.%06d" + (int) local.wMonth, // new, also the %02d in sprintf + (int) local.wDay, // new, also the %02d in sprintf + (int) local.wYear, // new, also the %02d in sprintf + (int) local.wHour, + (int) local.wMinute, + (int) local.wSecond, + (int) local.wMilliseconds * 1000); #else // UNIX char timebuf[26]; // This magic number is based on the ctime(3c) man page. ACE_Time_Value cur_time = ACE_OS::gettimeofday (); diff --git a/ace/Module.cpp b/ace/Module.cpp index 35db70ee7ac..09b562497ab 100644 --- a/ace/Module.cpp +++ b/ace/Module.cpp @@ -21,21 +21,37 @@ ACE_Module<ACE_SYNCH_2>::dump (void) const } template <ACE_SYNCH_1> void -ACE_Module<ACE_SYNCH_2>::writer (ACE_Task<ACE_SYNCH_2> *q) +ACE_Module<ACE_SYNCH_2>::writer (ACE_Task<ACE_SYNCH_2> *q, + int flags /* = M_DELETE_WRITER */) { ACE_TRACE ("ACE_Module<ACE_SYNCH_2>::writer"); + + // Close and maybe delete old writer + this->close_i (1); + this->q_pair_[1] = q; if (q != 0) ACE_CLR_BITS (q->flags_, ACE_Task_Flags::ACE_READER); + + // don't allow the caller to change the reader status + ACE_SET_BITS (flags_, (flags & M_DELETE_WRITER)); } template <ACE_SYNCH_1> void -ACE_Module<ACE_SYNCH_2>::reader (ACE_Task<ACE_SYNCH_2> *q) +ACE_Module<ACE_SYNCH_2>::reader (ACE_Task<ACE_SYNCH_2> *q, + int flags /* = M_DELETE_READER */) { ACE_TRACE ("ACE_Module<ACE_SYNCH_2>::reader"); + + // Close and maybe delete old writer + this->close_i (0); + this->q_pair_[0] = q; if (q != 0) ACE_SET_BITS (q->flags_, ACE_Task_Flags::ACE_READER); + + // don't allow the caller to change the reader status + ACE_SET_BITS (flags_, (flags & M_DELETE_READER)); } // Link this ACE_Module on top of ACE_Module M. @@ -53,32 +69,58 @@ template <ACE_SYNCH_1> int ACE_Module<ACE_SYNCH_2>::open (const char *mod_name, ACE_Task<ACE_SYNCH_2> *writer_q, ACE_Task<ACE_SYNCH_2> *reader_q, - void *arg) + void *arg, + int flags /* = M_DELETE */) { ACE_TRACE ("ACE_Module<ACE_SYNCH_2>::open"); this->name (mod_name); this->arg_ = arg; - if (writer_q == 0) + // we may already have readers and/or writers + if (this->reader ()) + this->close_i (0); + + if (this->writer ()) + this->close_i (1); + + + if (writer_q == 0) { writer_q = new ACE_Thru_Task<ACE_SYNCH_2>; - if (reader_q == 0) + ACE_SET_BITS (flags, M_DELETE_WRITER); + } + + if (reader_q == 0) { reader_q = new ACE_Thru_Task<ACE_SYNCH_2>; + ACE_SET_BITS (flags, M_DELETE_READER); + } + + this->reader (reader_q); + this->writer (writer_q); + + // Setup back pointers. + reader_q->mod_ = this; + writer_q->mod_ = this; + + // Save the flags + ACE_SET_BITS (flags_, flags); // Make sure that the memory is allocated before proceding. if (writer_q == 0 || reader_q == 0) { + this->close_i (0); + this->close_i (1); + + // Reset back pointers. + reader_q->mod_ = NULL; + writer_q->mod_ = NULL; + delete writer_q; delete reader_q; + errno = ENOMEM; return -1; } - this->reader (reader_q); - this->writer (writer_q); - - // Setup back pointers. - reader_q->mod_ = this; - writer_q->mod_ = this; return 0; } @@ -104,14 +146,13 @@ ACE_Module<ACE_SYNCH_2>::ACE_Module (void) // Do nothing... } -// Should never be called... template <ACE_SYNCH_1> ACE_INLINE ACE_Module<ACE_SYNCH_2>::~ACE_Module (void) { ACE_TRACE ("ACE_Module<ACE_SYNCH_2>::~ACE_Module"); // Only close down if we haven't already done so. - if (this->reader () != 0 || this->writer () != 0) + if (this->reader () || this->writer ()) this->close (); } @@ -119,52 +160,77 @@ template <ACE_SYNCH_1> ACE_INLINE ACE_Module<ACE_SYNCH_2>::ACE_Module (const char *mod_name, ACE_Task<ACE_SYNCH_2> *writer_q, ACE_Task<ACE_SYNCH_2> *reader_q, - void *flags) + void *args, + int flags /* = M_DELETE */) { ACE_TRACE ("ACE_Module<ACE_SYNCH_2>::ACE_Module"); - if (this->open (mod_name, writer_q, reader_q, flags) == -1) + + this->q_pair_[0] = 0; + this->q_pair_[1] = 0; + + if (this->open (mod_name, writer_q, reader_q, args, flags) == -1) ACE_ERROR ((LM_ERROR, "%p\n", "ACE_Module")); } template <ACE_SYNCH_1> int -ACE_Module<ACE_SYNCH_2>::close (u_long flags) +ACE_Module<ACE_SYNCH_2>::close (int flags /* = M_DELETE_NONE */) { ACE_TRACE ("ACE_Module<ACE_SYNCH_2>::close"); + ACE_Task<ACE_SYNCH_2> *reader_q = this->reader (); ACE_Task<ACE_SYNCH_2> *writer_q = this->writer (); + int result = 0; - if (reader_q != 0) - { - if (reader_q->close () == -1) - result = -1; - reader_q->flush (); - reader_q->next (0); - } + ACE_SET_BITS (flags_, flags); - if (writer_q != 0) - { - if (writer_q->close () == -1) - result = -1; - writer_q->flush (); - writer_q->next (0); - } + if (this->close_i (0) == -1) + result = -1; - if (ACE_BIT_ENABLED (flags, ACE_Module<ACE_SYNCH_2>::M_DELETE)) - { - // Only delete the Tasks if there aren't any more threads - // running in them. - if (reader_q->thr_count () == 0) - delete reader_q; - if (writer_q->thr_count () == 0) - delete writer_q; - } + if (this->close_i (1) == -1) + result = -1; - // Set the reader and writers to NULL so that we don't try to close() - // this object again if the destructor gets called. - this->reader (0); - this->writer (0); return result; } +template <ACE_SYNCH_1> int +ACE_Module<ACE_SYNCH_2>::close_i (int which) +{ + ACE_TRACE ("ACE_Module<ACE_SYNCH_2>::close_i"); + + if (this->q_pair_[which] == NULL) + return 0; + + // Copy task pointer to prevent problems when ACE_Task::close + // changes the task pointer + ACE_Task<ACE_SYNCH_2> *task = this->q_pair_[which]; + + // Change so that close doesn't get called again from the task base. + + // Now close the task + int result = 0; + + if (task->module_closed() == -1) + result = -1; + + task->flush (); + task->next (0); + + // Should we also delete it ? + if (ACE_BIT_ENABLED (flags_, which+1) ) { + // Only delete the Tasks if there aren't any more threads + // running in them. + if (task->thr_count() == 0) + delete task; + } + + // Set the tasks pointer to NULL so that we don't try to close() + // this object again if the destructor gets called. + this->q_pair_[which] = NULL; + + // Finally remove the delete bit. + ACE_CLR_BITS (flags_, which + 1); + + return result; +} #endif /* ACE_MODULE_C */ diff --git a/ace/Module.h b/ace/Module.h index 6f459afeb5f..a1221241628 100644 --- a/ace/Module.h +++ b/ace/Module.h @@ -37,9 +37,19 @@ class ACE_Module public: enum { - M_DELETE = 1 - // Indicates that close() deletes the Tasks. Don't change this - // value without updating the same enum in class ACE_Stream... + M_DELETE_NONE = 0, + // Indicates that close() should not delete any tasks. + + M_DELETE_READER = 1, + // Indicates that close() should delete the writer thread. + + M_DELETE_WRITER = 2, + // Indicates that close() should delete the reader thread. + + M_DELETE = 3 + // Indicates that close() deletes the Tasks. Don't change this + // value without updating the same enum in class ACE_Stream... + // The above flags may be or'ed together. }; // = Initialization and termination methods. @@ -52,31 +62,50 @@ public: ACE_Module (const char *module_name, ACE_Task<ACE_SYNCH_2> *writer = 0, ACE_Task<ACE_SYNCH_2> *reader = 0, - void *a = 0); + void *args = 0, + int flags = M_DELETE); // Create an initialized module with <module_name> as its identity // and <reader> and <writer> as its tasks. int open (const char *module_name, ACE_Task<ACE_SYNCH_2> *writer = 0, ACE_Task<ACE_SYNCH_2> *reader = 0, - void *a = 0); + void *a = 0, + int flags = M_DELETE); // Create an initialized module with <module_name> as its identity // and <reader> and <writer> as its tasks. - - int close (u_long flags = M_DELETE); - // Close down the Module and its Tasks. If the <M_DELETE> argument - // is given then delete all the memory too. - + // Previously register reader or writers or closed down and deleted + // according to the value of flags_. + // Should not be called from within ACE_Task::module_closed() + + int close (int flags = M_DELETE_NONE); + // Close down the Module and its Tasks. The flags argument can be + // used to override the default behaviour, which depends on + // previous <flags> values in calls to c'tor(), open(), reader() and + // writer(). + // A previous value M_DELETE[_XXX] can not be overridden. + // Should not be called from within ACE_Task::module_closed() + // = ACE_Task manipulation routines ACE_Task<ACE_SYNCH_2> *writer (void); // Get the writer task. - void writer (ACE_Task<ACE_SYNCH_2> *q); - // Set the writer task. + + void writer (ACE_Task<ACE_SYNCH_2> *q, int flags = M_DELETE_WRITER); + // Set the writer task. <flags> can be used to indicate that the + // module should delete the writer during a call to close or + // to the destructor. If a previous writer exists, it is closed. + // It may also be deleted, depending on the old flags_ value. + // Should not be called from within ACE_Task::module_closed() ACE_Task<ACE_SYNCH_2> *reader (void); // Get the reader task. - void reader (ACE_Task<ACE_SYNCH_2> *q); - // Set the reader task. + + void reader (ACE_Task<ACE_SYNCH_2> *q, int flags = M_DELETE_READER); + // Set the reader task. <flags> can be used to indicate that the + // module should delete the reader during a call to close or + // to the destructor. If a previous reader exists, it is closed. + // It may also be deleted, depending on the old flags_ value. + // Should not be called from within ACE_Task::module_closed() ACE_Task<ACE_SYNCH_2> *sibling (ACE_Task<ACE_SYNCH_2> *orig); // Set and get pointer to sibling ACE_Task in ACE_Module @@ -110,6 +139,10 @@ public: // Declare the dynamic allocation hooks. private: + int close_i(int which); + // Implements the close operation for either the reader + // or the writer task (depending on <which>) + ACE_Task<ACE_SYNCH_2> *q_pair_[2]; // Pair of Tasks that form the "read-side" and "write-side" of the // ACE_Module partitioning. @@ -123,6 +156,10 @@ private: void *arg_; // Argument passed through to the reader and writer task when they // are opened. + + int flags_; + // Holds flags which are used to determine if the reader and writer + // task have to be deleted on exit }; #if defined (__ACE_INLINE__) diff --git a/ace/OS.cpp b/ace/OS.cpp index 210e58b88b6..1bf65517830 100644 --- a/ace/OS.cpp +++ b/ace/OS.cpp @@ -48,10 +48,12 @@ ACE_OS::mutex_lock_cleanup (void *mutex) // = Static initialization. // This is necessary to deal with POSIX pthreads insanity. This -// guarantees that we've got a "zero'd" thread id even when ACE_thread_t -// is implemented as a structure... +// guarantees that we've got a "zero'd" thread id even when +// ACE_thread_t, ACE_hthread_t, and ACE_thread_key_t are implemented +// as structures... ACE_thread_t ACE_OS::NULL_thread; ACE_hthread_t ACE_OS::NULL_hthread; +ACE_thread_key_t ACE_OS::NULL_key ACE_OS::ACE_OS (void) { @@ -1102,9 +1104,6 @@ ACE_OS::thr_keycreate (ACE_thread_key_t *key, if (*key != ACE_SYSCALL_FAILED) { - // if TlsAlloc succeeded, TlsSetValue also succeeds. - // ::TlsSetValue (*key, inst); - // Extract out the thread-specific table instance and stash away // the key and destructor so that we can free it up later on... return ACE_TSS_Cleanup::instance ()->insert (*key, dest, inst); @@ -778,6 +778,74 @@ struct ACE_rwlock_t }; #endif /* ACE_HAS_DCETHREADS || ACE_HAS_PTHREADS */ +#elif defined (ACE_HAS_WTHREADS) +typedef CRITICAL_SECTION ACE_thread_mutex_t; +typedef struct +{ + int type_; // Either USYNC_THREAD or USYNC_PROCESS + union + { + HANDLE proc_mutex_; + CRITICAL_SECTION thr_mutex_; + }; +} ACE_mutex_t; +typedef HANDLE ACE_sema_t; + +struct ACE_cond_t + // = TITLE + // This structure is used to implement condition variables on NT. + // + // = DESCRIPTION + // At the current time, this stuff only works for threads + // within the same process. +{ + DWORD waiters_; + // Number of waiting threads. + + ACE_sema_t sema_; + // Queue up threads waiting for the condition to become signaled. +}; + +struct ACE_rwlock_t + // = TITLE + // This is used to implement readers/writer locks on NT. + // + // = DESCRIPTION + // At the current time, this stuff only works for threads + // within the same process. +{ + ACE_mutex_t lock_; + // Serialize access to internal state. + + ACE_cond_t waiting_readers_; + // Reader threads waiting to acquire the lock. + + int num_waiting_readers_; + // Number of waiting readers. + + ACE_cond_t waiting_writers_; + // Writer threads waiting to acquire the lock. + + int num_waiting_writers_; + // Number of waiting writers. + + int ref_count_; + // Value is -1 if writer has the lock, else this keeps track of the + // number of readers holding the lock. +}; + +// These need to be different values, neither of which can be 0... +#define USYNC_THREAD 1 +#define USYNC_PROCESS 2 + +#define THR_CANCEL_DISABLE 0 +#define THR_CANCEL_ENABLE 0 +#define THR_CANCEL_DEFERRED 0 +#define THR_CANCEL_ASYNCHRONOUS 0 +#define THR_DETACHED 0 // ?? ignore in most places +#define THR_BOUND 0 // ?? ignore in most places +#define THR_NEW_LWP 0 // ?? ignore in most places +#define THR_SUSPENDED CREATE_SUSPENDED #else /* !ACE_HAS_THREADS, i.e., the OS/platform doesn't support threading. */ // Give these things some reasonable value... #define THR_CANCEL_DISABLE 0 @@ -1100,68 +1168,24 @@ inline DWORD ACE_LOW_DWORD (ACE_QWORD q) { return (DWORD) q; } inline DWORD ACE_HIGH_DWORD (ACE_QWORD q) { return (DWORD) (q >> 32); } #endif /* !defined (_MSC_VER) */ -// Win32 dummys to help compilation +// Win32 dummies to help compilation. typedef void *sigset_t; // Who knows? typedef int mode_t; -typedef CRITICAL_SECTION ACE_thread_mutex_t; -typedef struct -{ - int type_; // Either USYNC_THREAD or USYNC_PROCESS - union - { - HANDLE proc_mutex_; - CRITICAL_SECTION thr_mutex_; - }; -} ACE_mutex_t; -typedef HANDLE ACE_sema_t; typedef int uid_t; typedef int gid_t; typedef int hrtime_t; typedef char *caddr_t; - -struct ACE_cond_t - // = TITLE - // This structure is used to implement condition variables on NT. - // - // = DESCRIPTION - // At the current time, this stuff only works for threads - // within the same process. -{ - DWORD waiters_; - // Number of waiting threads. - - ACE_sema_t sema_; - // Queue up threads waiting for the condition to become signaled. -}; - -struct ACE_rwlock_t - // = TITLE - // This is used to implement readers/writer locks on NT. - // - // = DESCRIPTION - // At the current time, this stuff only works for threads - // within the same process. -{ - ACE_mutex_t lock_; - // Serialize access to internal state. - - ACE_cond_t waiting_readers_; - // Reader threads waiting to acquire the lock. - - int num_waiting_readers_; - // Number of waiting readers. - - ACE_cond_t waiting_writers_; - // Writer threads waiting to acquire the lock. - - int num_waiting_writers_; - // Number of waiting writers. - - int ref_count_; - // Value is -1 if writer has the lock, else this keeps track of the - // number of readers holding the lock. -}; +struct rlimit { }; +struct t_call { }; +struct t_bind { }; +struct t_info { }; +struct t_optmgmt { }; +struct t_discon { }; +struct t_unitdata { }; +struct t_uderr { }; +struct netbuf { }; +struct flock { }; // not used with Win32 locking... // Wrapper for NT Events. typedef HANDLE ACE_event_t; @@ -1175,19 +1199,6 @@ typedef SOCKET ACE_SOCKET; #define ACE_INVALID_HANDLE INVALID_HANDLE_VALUE #define ACE_SYSCALL_FAILED 0xFFFFFFFF -// These need to be different values, neither of which can be 0... -#define USYNC_THREAD 1 -#define USYNC_PROCESS 2 - -#define THR_CANCEL_DISABLE 0 -#define THR_CANCEL_ENABLE 0 -#define THR_CANCEL_DEFERRED 0 -#define THR_CANCEL_ASYNCHRONOUS 0 -#define THR_DETACHED 0 // ?? ignore in most places -#define THR_BOUND 0 // ?? ignore in most places -#define THR_NEW_LWP 0 // ?? ignore in most places -#define THR_SUSPENDED CREATE_SUSPENDED - // Needed to map calls to NT transparently. #define MS_ASYNC 0 #define MS_INVALIDATE 0 @@ -1215,20 +1226,6 @@ struct iovec size_t iov_len; // byte count to read/write }; -struct rlimit { }; -struct t_call { }; -struct t_bind { }; -struct t_info { }; -struct t_optmgmt { }; -struct t_discon { }; -struct t_unitdata { }; -struct t_uderr { }; -struct netbuf { }; -struct flock { }; // not used with Win32 locking... - -// Deal with whatever UNICODE mapping the application is compiling -// with! - #else /* !defined (ACE_WIN32) */ // We're some kind of UNIX... @@ -1878,10 +1875,10 @@ public: static int cond_signal (ACE_cond_t *cv); static int cond_timedwait (ACE_cond_t *cv, ACE_mutex_t *m, ACE_Time_Value *); static int cond_wait (ACE_cond_t *cv, ACE_mutex_t *m); -#if defined (ACE_WIN32) +#if defined (ACE_WIN32) && defined (ACE_HAS_WTHREADS) static int cond_timedwait (ACE_cond_t *cv, ACE_thread_mutex_t *m, ACE_Time_Value *); static int cond_wait (ACE_cond_t *cv, ACE_thread_mutex_t *m); -#endif /* ACE_WIN32 */ +#endif /* ACE_WIN32 && ACE_HAS_WTHREADS */ // = A set of wrappers for determining config info. static char *cuserid (char *user, size_t maxlen = 32); @@ -2312,6 +2309,10 @@ public: // This is necessary to deal with POSIX pthreads and their use of // structures for thread handles. + static ACE_thread_key_t NULL_key; + // This is necessary to deal with POSIX pthreads and their use of + // structures for TSS keys. + #if defined (ACE_WIN32) static int socket_initialized_; // Keeps track of whether we've already initialized WinSock... @@ -1278,7 +1278,7 @@ ACE_OS::cond_timedwait (ACE_cond_t *cv, #endif /* ACE_HAS_THREADS */ } -#if defined (ACE_WIN32) +#if defined (ACE_WIN32) && defined (ACE_HAS_WTHREADS) ACE_INLINE int ACE_OS::cond_timedwait (ACE_cond_t *cv, ACE_thread_mutex_t *external_mutex, @@ -1363,7 +1363,7 @@ ACE_OS::cond_wait (ACE_cond_t *cv, ACE_NOTSUP_RETURN (-1); #endif /* ACE_HAS_THREADS */ } -#endif /* ACE_WIN32 */ +#endif /* ACE_WIN32 && ACE_HAS_WTHREADS */ ACE_INLINE int ACE_OS::rw_rdlock (ACE_rwlock_t *rw) diff --git a/ace/Signal.cpp b/ace/Signal.cpp index a9a5957fe29..e41b8647284 100644 --- a/ace/Signal.cpp +++ b/ace/Signal.cpp @@ -19,13 +19,13 @@ ace_signal_handler_dispatch (int signum, siginfo_t *info, ucontext_t *context) } extern "C" void -ace_signal_handlers_dispatch (int, siginfo_t *, ucontext_t *) +ace_signal_handlers_dispatch (int signum, siginfo_t *info, ucontext_t *context) { ACE_TRACE ("ace_signal_handlers_dispatch"); ACE_Sig_Handlers::dispatch (signum, info, context); } -static ACE_SignalHandler ace_dispatcher = ACE_SignalHandler (ace_signal_handlers_dispatch); +static ACE_SignalHandler ace_dispatcher = ACE_SignalHandler (ace_signal_handler_dispatch); #else static ACE_SignalHandler ace_dispatcher = ACE_SignalHandler (ACE_Sig_Handler::dispatch); #endif /* ACE_HAS_SIG_C_FUNC */ diff --git a/ace/Stream.cpp b/ace/Stream.cpp index 3c338d1bcee..f65a29a4a41 100644 --- a/ace/Stream.cpp +++ b/ace/Stream.cpp @@ -110,7 +110,7 @@ ACE_Stream<ACE_SYNCH_2>::top (ACE_Module<ACE_SYNCH_2> *&m) // stream_head. template <ACE_SYNCH_1> int -ACE_Stream<ACE_SYNCH_2>::pop (u_long flags) +ACE_Stream<ACE_SYNCH_2>::pop (int flags) { ACE_TRACE ("ACE_Stream<ACE_SYNCH_2>::pop"); if (this->stream_head_->next () == this->stream_tail_) @@ -139,7 +139,7 @@ ACE_Stream<ACE_SYNCH_2>::pop (u_long flags) // ACE_Stream. template <ACE_SYNCH_1> int -ACE_Stream<ACE_SYNCH_2>::remove (const char *name, u_long flags) +ACE_Stream<ACE_SYNCH_2>::remove (const char *name, int flags) { ACE_TRACE ("ACE_Stream<ACE_SYNCH_2>::remove"); ACE_Module<ACE_SYNCH_2> *prev = 0; @@ -286,7 +286,7 @@ ACE_Stream<ACE_SYNCH_2>::open (void *a, } template <ACE_SYNCH_1> int -ACE_Stream<ACE_SYNCH_2>::close (u_long flags) +ACE_Stream<ACE_SYNCH_2>::close (int flags) { ACE_TRACE ("ACE_Stream<ACE_SYNCH_2>::close"); ACE_GUARD_RETURN (ACE_SYNCH_MUTEX, ace_mon, this->lock_, -1); diff --git a/ace/Stream.h b/ace/Stream.h index 0eeac5fc837..cd50967ceb7 100644 --- a/ace/Stream.h +++ b/ace/Stream.h @@ -44,7 +44,7 @@ friend class ACE_Stream_Iterator<ACE_SYNCH_2>; public: enum { - M_DELETE = 1 + M_DELETE = 3 // Indicates that close() deletes the Tasks. Don't change this // value without updating the same enum in class ACE_Module... }; @@ -66,9 +66,9 @@ public: // <ACE_Stream_Head> and <ACE_Stream_Tail> are used, respectively. // <arg> is the value past in to the open() methods of the tasks. - int close (u_long flags = M_DELETE); + int close (int flags = M_DELETE); // Close down the stream and release all the resources. - + ~ACE_Stream (void); // Close down the stream and release all the resources. @@ -77,14 +77,14 @@ public: int push (ACE_Module<ACE_SYNCH_2> *mod); // Add a new module <mod> right below the Stream head. - int pop (u_long flags = M_DELETE); + int pop (int flags = M_DELETE); // Remove the <mod> right below the Stream head and close it down. int top (ACE_Module<ACE_SYNCH_2> *&mod); // Return the top module on the stream (right below the stream // head). - int remove (const char *mod, u_long flags = M_DELETE); + int remove (const char *mod, int flags = M_DELETE); // Remove the named module <mod> from the stream. This bypasses the // strict LIFO ordering of push() and pop(). diff --git a/ace/Svc_Conf_y.cpp b/ace/Svc_Conf_y.cpp index f0415eef51c..8c15cc567ba 100644 --- a/ace/Svc_Conf_y.cpp +++ b/ace/Svc_Conf_y.cpp @@ -489,7 +489,7 @@ int ace_yyindent; #endif /* YYDEBUG_SHIFT_ERROR_LEXEME */ #endif /* YYDEBUG */ #ifdef __cplusplus -extern "C" { extern char *getenv(const char *); } +extern "C" { extern char *ace_foo(const char *); } #endif int ace_yyparse() @@ -498,7 +498,7 @@ ace_yyparse() #if YYDEBUG register char *ace_yys; #ifndef __cplusplus - extern char *getenv(); + extern char *ace_foo(); #endif if (ace_yys = ACE_OS::getenv("YYDEBUG")) diff --git a/ace/Synch.cpp b/ace/Synch.cpp index 8c1598a72ea..8b5afb515cf 100644 --- a/ace/Synch.cpp +++ b/ace/Synch.cpp @@ -114,6 +114,60 @@ ACE_RW_Process_Mutex::dump (void) const } void +ACE_RW_Mutex::dump (void) const +{ +// ACE_TRACE ("ACE_RW_Mutex::dump"); + + ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this)); + ACE_DEBUG ((LM_DEBUG, "\n")); + ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); +} + +ACE_RW_Mutex::ACE_RW_Mutex (int type, LPCTSTR name, void *arg) +{ +// ACE_TRACE ("ACE_RW_Mutex::ACE_RW_Mutex"); + if (ACE_OS::rwlock_init (&this->lock_, type, name, arg) != 0) + ACE_ERROR ((LM_ERROR, "%p\n", "ACE_RW_Mutex::~ACE_RW_Mutex")); +} + +ACE_RW_Mutex::~ACE_RW_Mutex (void) +{ +// ACE_TRACE ("ACE_RW_Mutex::~ACE_RW_Mutex"); + if (this->remove () == -1) + ACE_ERROR ((LM_ERROR, "%p\n", "ACE_RW_Mutex::~ACE_RW_Mutex")); +} + +ACE_ALLOC_HOOK_DEFINE(ACE_Semaphore) + +void +ACE_Semaphore::dump (void) const +{ +// ACE_TRACE ("ACE_Semaphore::dump"); + + ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this)); + ACE_DEBUG ((LM_DEBUG, "\n")); + ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); +} + +ACE_Semaphore::ACE_Semaphore (u_int count, + int type, + LPCTSTR name, + void *arg, + int max) +{ +// ACE_TRACE ("ACE_Semaphore::ACE_Semaphore"); + if (ACE_OS::sema_init (&this->semaphore_, count, type, + name, arg, max) != 0) + ACE_ERROR ((LM_ERROR, "%p\n", "ACE_Semaphore::ACE_Semaphore")); +} + +ACE_Semaphore::~ACE_Semaphore (void) +{ +// ACE_TRACE ("ACE_Semaphore::~ACE_Semaphore"); + this->remove (); +} + +void ACE_File_Lock::dump (void) const { // ACE_TRACE ("ACE_File_Lock::dump"); @@ -216,6 +270,33 @@ ACE_Process_Semaphore::release (void) return this->lock_.release (); } +ACE_ALLOC_HOOK_DEFINE(ACE_Mutex) + +void +ACE_Mutex::dump (void) const +{ +// ACE_TRACE ("ACE_Mutex::dump"); + + ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this)); + ACE_DEBUG ((LM_DEBUG, "\n")); + ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); +} + +ACE_Mutex::ACE_Mutex (int type, LPCTSTR name, void *arg) +{ +// ACE_TRACE ("ACE_Mutex::ACE_Mutex"); + + if (ACE_OS::mutex_init (&this->lock_, type, name, arg) != 0) + ACE_ERROR ((LM_ERROR, "%p\n", "ACE_Mutex::ACE_Mutex")); +} + +ACE_Mutex::~ACE_Mutex (void) +{ +// ACE_TRACE ("ACE_Mutex::~ACE_Mutex"); + if (this->remove () != 0) + ACE_ERROR ((LM_ERROR, "%p\n", "ACE_Mutex::~ACE_Mutex")); +} + #if defined (ACE_HAS_THREADS) ACE_Event::ACE_Event (int manual_reset, @@ -327,18 +408,6 @@ ACE_Auto_Event::dump (void) const ACE_ALLOC_HOOK_DEFINE(ACE_Recursive_Thread_Mutex) ACE_ALLOC_HOOK_DEFINE(ACE_Thread_Mutex_Guard) -ACE_ALLOC_HOOK_DEFINE(ACE_Mutex) -ACE_ALLOC_HOOK_DEFINE(ACE_Semaphore) - -void -ACE_Semaphore::dump (void) const -{ -// ACE_TRACE ("ACE_Semaphore::dump"); - - ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this)); - ACE_DEBUG ((LM_DEBUG, "\n")); - ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); -} void ACE_Thread_Semaphore::dump (void) const @@ -348,18 +417,6 @@ ACE_Thread_Semaphore::dump (void) const ACE_Semaphore::dump (); } -ACE_Semaphore::ACE_Semaphore (u_int count, - int type, - LPCTSTR name, - void *arg, - int max) -{ -// ACE_TRACE ("ACE_Semaphore::ACE_Semaphore"); - if (ACE_OS::sema_init (&this->semaphore_, count, type, - name, arg, max) != 0) - ACE_ERROR ((LM_ERROR, "%p\n", "ACE_Semaphore::ACE_Semaphore")); -} - ACE_Thread_Semaphore::ACE_Thread_Semaphore (u_int count, LPCTSTR name, void *arg, @@ -369,12 +426,6 @@ ACE_Thread_Semaphore::ACE_Thread_Semaphore (u_int count, // ACE_TRACE ("ACE_Thread_Semaphore::ACE_Thread_Semaphore"); } -ACE_Semaphore::~ACE_Semaphore (void) -{ -// ACE_TRACE ("ACE_Semaphore::~ACE_Semaphore"); - this->remove (); -} - void ACE_Thread_Mutex_Guard::dump (void) const { @@ -385,31 +436,6 @@ ACE_Thread_Mutex_Guard::dump (void) const ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); } -void -ACE_Mutex::dump (void) const -{ -// ACE_TRACE ("ACE_Mutex::dump"); - - ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this)); - ACE_DEBUG ((LM_DEBUG, "\n")); - ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); -} - -ACE_Mutex::ACE_Mutex (int type, LPCTSTR name, void *arg) -{ -// ACE_TRACE ("ACE_Mutex::ACE_Mutex"); - - if (ACE_OS::mutex_init (&this->lock_, type, name, arg) != 0) - ACE_ERROR ((LM_ERROR, "%p\n", "ACE_Mutex::ACE_Mutex")); -} - -ACE_Mutex::~ACE_Mutex (void) -{ -// ACE_TRACE ("ACE_Mutex::~ACE_Mutex"); - if (this->remove () != 0) - ACE_ERROR ((LM_ERROR, "%p\n", "ACE_Mutex::~ACE_Mutex")); -} - ACE_thread_t ACE_Recursive_Thread_Mutex::get_thread_id (void) { @@ -795,7 +821,7 @@ ACE_Thread_Mutex::ACE_Thread_Mutex (LPCTSTR name, void *arg) // ACE_TRACE ("ACE_Thread_Mutex::ACE_Thread_Mutex"); if (ACE_OS::thread_mutex_init (&this->lock_, USYNC_THREAD, name, arg) != 0) - ACE_ERROR ((LM_ERROR, "%p\n", "ACE_Mutex::ACE_Mutex")); + ACE_ERROR ((LM_ERROR, "%p\n", "ACE_Thread_Mutex::ACE_Thread_Mutex")); } ACE_ALLOC_HOOK_DEFINE(ACE_RW_Thread_Mutex) @@ -808,35 +834,11 @@ ACE_RW_Thread_Mutex::ACE_RW_Thread_Mutex (LPCTSTR name, } void -ACE_RW_Mutex::dump (void) const -{ -// ACE_TRACE ("ACE_RW_Mutex::dump"); - - ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this)); - ACE_DEBUG ((LM_DEBUG, "\n")); - ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); -} - -void ACE_RW_Thread_Mutex::dump (void) const { // ACE_TRACE ("ACE_RW_Thread_Mutex::dump"); ACE_RW_Mutex::dump (); } -ACE_RW_Mutex::ACE_RW_Mutex (int type, LPCTSTR name, void *arg) -{ -// ACE_TRACE ("ACE_RW_Mutex::ACE_RW_Mutex"); - if (ACE_OS::rwlock_init (&this->lock_, type, name, arg) != 0) - ACE_ERROR ((LM_ERROR, "%p\n", "ACE_RW_Mutex::~ACE_RW_Mutex")); -} - -ACE_RW_Mutex::~ACE_RW_Mutex (void) -{ -// ACE_TRACE ("ACE_RW_Mutex::~ACE_RW_Mutex"); - if (this->remove () == -1) - ACE_ERROR ((LM_ERROR, "%p\n", "ACE_RW_Mutex::~ACE_RW_Mutex")); -} - #endif /* ACE_HAS_THREADS */ #endif /* ACE_SYNCH_C */ diff --git a/ace/Synch.h b/ace/Synch.h index 2c19f277b4b..cfca61333ba 100644 --- a/ace/Synch.h +++ b/ace/Synch.h @@ -197,6 +197,299 @@ private: #endif /* ACE_WIN32 */ }; +class ACE_Export ACE_RW_Mutex + // = TITLE + // Wrapper for readers/writer locks. + // + // = DESCRIPTION + // These are most useful for applications that have many more + // parallel readers than writers... +{ +public: + ACE_RW_Mutex (int type = USYNC_THREAD, + LPCTSTR name = 0, + void *arg = 0); + // Initialize a readers/writer lock. + + ~ACE_RW_Mutex (void); + // Implicitly destroy a readers/writer lock + + int remove (void); + // Explicitly destroy a readers/writer lock. + + int acquire_read (void); + // Acquire a read lock, but block if a writer hold the lock. + + int acquire_write (void); + // Acquire a write lock, but block if any readers or a + // writer hold the lock. + + int tryacquire_read (void); + // Conditionally acquire a read lock (i.e., won't block). + + int tryacquire_write (void); + // Conditionally acquire a write lock (i.e., won't block). + + int acquire (void); + // Note, for interface uniformity with other synchronization + // wrappers we include the <acquire> method. This is implemented as + // a write-lock to be on the safe-side... + + int tryacquire (void); + // Note, for interface uniformity with other synchronization + // wrappers we include the <tryacquire> method. This is implemented + // as a write-lock to be on the safe-side... + + int release (void); + // Unlock a readers/writer lock. + + const ACE_rwlock_t &lock (void) const; + // Return the underlying lock. + + void dump (void) const; + // Dump the state of an object. + + ACE_ALLOC_HOOK_DECLARE; + // Declare the dynamic allocation hooks. + +private: + ACE_rwlock_t lock_; + // Readers/writer lock. + + // = Prevent assignment and initialization. + void operator= (const ACE_RW_Mutex &) {} + ACE_RW_Mutex (const ACE_RW_Mutex &) {} +}; + +class ACE_Export ACE_Mutex + // = TITLE + // ACE_Mutex wrapper (valid in same process or across processes + // (depending on TYPE flag)) +{ +public: + ACE_Mutex (int type = USYNC_THREAD, + LPCTSTR name = 0, + void *arg = 0); + // Initialize the mutex. + + ~ACE_Mutex (void); + // Implicitly destroy the mutex. + + int remove (void); + // Explicitly destroy the mutex. + + int acquire (void); + // Acquire lock ownership (wait on priority queue if necessary). + + int tryacquire (void); + // Conditionally acquire lock (i.e., don't wait on queue). + + int release (void); + // Release lock and unblock a thread at head of priority queue. + + int acquire_read (void); + // Acquire lock ownership (wait on priority queue if necessary). + + int acquire_write (void); + // Acquire lock ownership (wait on priority queue if necessary). + + int tryacquire_read (void); + // Conditionally acquire a lock (i.e., won't block). + + int tryacquire_write (void); + // Conditionally acquire a lock (i.e., won't block). + + const ACE_mutex_t &lock (void) const; + // Return the underlying mutex. + + void dump (void) const; + // Dump the state of an object. + + ACE_ALLOC_HOOK_DECLARE; + // Declare the dynamic allocation hooks. + +//private: + ACE_mutex_t lock_; + // Mutex type supported by the OS. + +private: + // = Prevent assignment and initialization. + void operator= (const ACE_Mutex &) {} + ACE_Mutex (const ACE_Mutex &) {} +}; + +class ACE_Export ACE_Process_Mutex + // = TITLE + // ACE_Mutex wrapper (valid in same process, as well as across + // processes). +{ +public: + ACE_Process_Mutex (LPCTSTR name = ACE_DEFAULT_MUTEX, void *arg = 0); + // Create a Process_Mutex, passing in the optional <name>. + + ~ACE_Process_Mutex (void); + + int remove (void); + // Explicitly destroy the mutex. + + int acquire (void); + // Acquire lock ownership (wait on priority queue if necessary). + + int tryacquire (void); + // Conditionally acquire lock (i.e., don't wait on queue). + + int release (void); + // Release lock and unblock a thread at head of priority queue. + + int acquire_read (void); + // Acquire lock ownership (wait on priority queue if necessary). + + int acquire_write (void); + // Acquire lock ownership (wait on priority queue if necessary). + + int tryacquire_read (void); + // Conditionally acquire a lock (i.e., won't block). + + int tryacquire_write (void); + // Conditionally acquire a lock (i.e., won't block). + + void dump (void) const; + // Dump the state of an object. + + ACE_ALLOC_HOOK_DECLARE; + // Declare the dynamic allocation hooks. + +#if defined (ACE_WIN32) || defined (ACE_HAS_POSIX_SEM) + ACE_Mutex lock_; +#else + ACE_SV_Semaphore_Complex lock_; + // We need this to get the right semantics... +#endif /* ACE_WIN32 */ +}; + +class ACE_Export ACE_RW_Process_Mutex : public ACE_Process_Mutex + // = TITLE + // Wrapper for readers/writer locks that exist across processes. +{ +public: + ACE_RW_Process_Mutex (LPCTSTR name = ACE_DEFAULT_MUTEX, + void *arg = 0); + + void dump (void) const; + // Dump the state of an object. + + ACE_ALLOC_HOOK_DECLARE; + // Declare the dynamic allocation hooks. +}; + +class ACE_Null_Barrier + // = TITLE + // Implements "NULL barrier synchronization". +{ +public: + ACE_Null_Barrier (u_int, + const char * = 0, + void * = 0) {} + // Initialize the barrier to synchronize <count> threads. + + int wait (void) { return 0; } + // Block the caller until all <count> threads have called <wait> and + // then allow all the caller threads to continue in parallel. + + void dump (void) const {} + // Dump the state of an object. + + ACE_ALLOC_HOOK_DECLARE; + // Declare the dynamic allocation hooks. + +private: + + // = Prevent assignment and initialization. + void operator= (const ACE_Null_Barrier &) {} + ACE_Null_Barrier (const ACE_Null_Barrier &) {} +}; + +class ACE_Export ACE_Null_Mutex + // = TITLE + // Implement a do nothing <ACE_Mutex>, i.e., all the methods are + // no ops. +{ +public: + ACE_Null_Mutex (LPCTSTR = 0) {} + ~ACE_Null_Mutex (void) {} + int remove (void) { return 0; } + + int acquire (void) { return 0; } + int tryacquire (void) { return 0; } + int release (void) { return 0; } + int acquire_write (void) { return 0; } + int tryacquire_write (void) { return 0; } + int acquire_read (void) { return 0; } + int tryacquire_read (void) { return 0; } + + void dump (void) const { } + // Dump the state of an object. + + ACE_ALLOC_HOOK_DECLARE; + // Declare the dynamic allocation hooks. +}; + +class ACE_Export ACE_Null_Condition_Mutex + // = TITLE + // Implement a do nothing <ACE_Condition> variable wrapper, i.e., + // all methods are no ops. This class is necessary since some + // C++ compilers are *very* lame... +{ +public: + ACE_Null_Condition_Mutex (ACE_Null_Mutex &m, int = 0, + LPCTSTR = 0, void * = 0): mutex_ (m) {} + ~ACE_Null_Condition_Mutex (void) {} + int remove (void) { return 0; } + int wait (ACE_Time_Value * = 0) { errno = ETIME; return -1; } + int signal (void) { return 0; } + int broadcast (void) { return 0; } + ACE_Null_Mutex &mutex (void) { return this->mutex_; } + + void dump (void) const {} + // Dump the state of an object. + + // ACE_ALLOC_HOOK_DECLARE; + // Declare the dynamic allocation hooks. + +private: + ACE_Null_Mutex &mutex_; // Reference to mutex lock. + + // = Prevent assignment and initialization. + void operator= (const ACE_Null_Condition_Mutex &) {} + ACE_Null_Condition_Mutex (const ACE_Null_Condition_Mutex &c): mutex_ (c.mutex_) {} +}; + +class ACE_Export ACE_Null_Mutex_Guard + // = TITLE + // This data structure is meant to be used within a method or + // function... It performs automatic aquisition and release of + // an ACE_Null_Mutex. + // + // = DESCRIPTION + // This should be a specialization of ACE_Guard, but compiler + // bugs preclude this... +{ +public: + ACE_Null_Mutex_Guard (ACE_Null_Mutex &) {} + ~ACE_Null_Mutex_Guard (void) {} + int remove (void) { return 0; } + int locked (void) { return 1; } + int acquire (void) { return 0; } + int tryacquire (void) { return 0; } + int release (void) { return 0; } + void dump (void) const { } + +protected: + // = Prevent assignment and initialization. + void operator= (const ACE_Null_Mutex_Guard &) {} + ACE_Null_Mutex_Guard (const ACE_Null_Mutex_Guard &) {} +}; + #if defined (ACE_HAS_THREADS) // ACE platform supports some form of threading. class ACE_Export ACE_Event @@ -317,63 +610,6 @@ public: // Declare the dynamic allocation hooks }; -class ACE_Export ACE_Mutex - // = TITLE - // ACE_Mutex wrapper (valid in same process or across processes - // (depending on TYPE flag)) -{ -public: - ACE_Mutex (int type = USYNC_THREAD, - LPCTSTR name = 0, - void *arg = 0); - // Initialize the mutex. - - ~ACE_Mutex (void); - // Implicitly destroy the mutex. - - int remove (void); - // Explicitly destroy the mutex. - - int acquire (void); - // Acquire lock ownership (wait on priority queue if necessary). - - int tryacquire (void); - // Conditionally acquire lock (i.e., don't wait on queue). - - int release (void); - // Release lock and unblock a thread at head of priority queue. - - int acquire_read (void); - // Acquire lock ownership (wait on priority queue if necessary). - - int acquire_write (void); - // Acquire lock ownership (wait on priority queue if necessary). - - int tryacquire_read (void); - // Conditionally acquire a lock (i.e., won't block). - - int tryacquire_write (void); - // Conditionally acquire a lock (i.e., won't block). - - const ACE_mutex_t &lock (void) const; - // Return the underlying mutex. - - void dump (void) const; - // Dump the state of an object. - - ACE_ALLOC_HOOK_DECLARE; - // Declare the dynamic allocation hooks. - -//private: - ACE_mutex_t lock_; - // Mutex type supported by the OS. - -private: - // = Prevent assignment and initialization. - void operator= (const ACE_Mutex &) {} - ACE_Mutex (const ACE_Mutex &) {} -}; - class ACE_Export ACE_Thread_Mutex // = TITLE // ACE_Thread_Mutex wrapper (only valid for threads in the same @@ -625,70 +861,6 @@ private: ACE_Recursive_Thread_Mutex (const ACE_Recursive_Thread_Mutex &); }; -class ACE_Export ACE_RW_Mutex - // = TITLE - // Wrapper for readers/writer locks. - // - // = DESCRIPTION - // These are most useful for applications that have many more - // parallel readers than writers... -{ -public: - ACE_RW_Mutex (int type = USYNC_THREAD, - LPCTSTR name = 0, - void *arg = 0); - // Initialize a readers/writer lock. - - ~ACE_RW_Mutex (void); - // Implicitly destroy a readers/writer lock - - int remove (void); - // Explicitly destroy a readers/writer lock. - - int acquire_read (void); - // Acquire a read lock, but block if a writer hold the lock. - - int acquire_write (void); - // Acquire a write lock, but block if any readers or a - // writer hold the lock. - - int tryacquire_read (void); - // Conditionally acquire a read lock (i.e., won't block). - - int tryacquire_write (void); - // Conditionally acquire a write lock (i.e., won't block). - - int acquire (void); - // Note, for interface uniformity with other synchronization - // wrappers we include the <acquire> method. This is implemented as - // a write-lock to be on the safe-side... - - int tryacquire (void); - // Note, for interface uniformity with other synchronization - // wrappers we include the <tryacquire> method. This is implemented - // as a write-lock to be on the safe-side... - - int release (void); - // Unlock a readers/writer lock. - - const ACE_rwlock_t &lock (void) const; - // Return the underlying lock. - - void dump (void) const; - // Dump the state of an object. - - ACE_ALLOC_HOOK_DECLARE; - // Declare the dynamic allocation hooks. - -private: - ACE_rwlock_t lock_; - // Readers/writer lock. - - // = Prevent assignment and initialization. - void operator= (const ACE_RW_Mutex &) {} - ACE_RW_Mutex (const ACE_RW_Mutex &) {} -}; - class ACE_Export ACE_RW_Thread_Mutex : public ACE_RW_Mutex // = TITLE // Wrapper for readers/writer locks that exist within a process. @@ -840,178 +1012,6 @@ public: #endif /* ACE_HAS_THREADS */ -class ACE_Export ACE_Process_Mutex - // = TITLE - // ACE_Mutex wrapper (valid in same process, as well as across - // processes). -{ -public: - ACE_Process_Mutex (LPCTSTR name = ACE_DEFAULT_MUTEX, void *arg = 0); - // Create a Process_Mutex, passing in the optional <name>. - - ~ACE_Process_Mutex (void); - - int remove (void); - // Explicitly destroy the mutex. - - int acquire (void); - // Acquire lock ownership (wait on priority queue if necessary). - - int tryacquire (void); - // Conditionally acquire lock (i.e., don't wait on queue). - - int release (void); - // Release lock and unblock a thread at head of priority queue. - - int acquire_read (void); - // Acquire lock ownership (wait on priority queue if necessary). - - int acquire_write (void); - // Acquire lock ownership (wait on priority queue if necessary). - - int tryacquire_read (void); - // Conditionally acquire a lock (i.e., won't block). - - int tryacquire_write (void); - // Conditionally acquire a lock (i.e., won't block). - - void dump (void) const; - // Dump the state of an object. - - ACE_ALLOC_HOOK_DECLARE; - // Declare the dynamic allocation hooks. - -#if defined (ACE_WIN32) || defined (ACE_HAS_POSIX_SEM) - ACE_Mutex lock_; -#else - ACE_SV_Semaphore_Complex lock_; - // We need this to get the right semantics... -#endif /* ACE_WIN32 */ -}; - -class ACE_Export ACE_RW_Process_Mutex : public ACE_Process_Mutex - // = TITLE - // Wrapper for readers/writer locks that exist across processes. -{ -public: - ACE_RW_Process_Mutex (LPCTSTR name = ACE_DEFAULT_MUTEX, - void *arg = 0); - - void dump (void) const; - // Dump the state of an object. - - ACE_ALLOC_HOOK_DECLARE; - // Declare the dynamic allocation hooks. -}; - -class ACE_Null_Barrier - // = TITLE - // Implements "NULL barrier synchronization". -{ -public: - ACE_Null_Barrier (u_int, - const char * = 0, - void * = 0) {} - // Initialize the barrier to synchronize <count> threads. - - int wait (void) { return 0; } - // Block the caller until all <count> threads have called <wait> and - // then allow all the caller threads to continue in parallel. - - void dump (void) const {} - // Dump the state of an object. - - ACE_ALLOC_HOOK_DECLARE; - // Declare the dynamic allocation hooks. - -private: - - // = Prevent assignment and initialization. - void operator= (const ACE_Null_Barrier &) {} - ACE_Null_Barrier (const ACE_Null_Barrier &) {} -}; - -class ACE_Export ACE_Null_Mutex - // = TITLE - // Implement a do nothing <ACE_Mutex>, i.e., all the methods are - // no ops. -{ -public: - ACE_Null_Mutex (LPCTSTR = 0) {} - ~ACE_Null_Mutex (void) {} - int remove (void) { return 0; } - - int acquire (void) { return 0; } - int tryacquire (void) { return 0; } - int release (void) { return 0; } - int acquire_write (void) { return 0; } - int tryacquire_write (void) { return 0; } - int acquire_read (void) { return 0; } - int tryacquire_read (void) { return 0; } - - void dump (void) const { } - // Dump the state of an object. - - ACE_ALLOC_HOOK_DECLARE; - // Declare the dynamic allocation hooks. -}; - -class ACE_Export ACE_Null_Condition_Mutex - // = TITLE - // Implement a do nothing <ACE_Condition> variable wrapper, i.e., - // all methods are no ops. This class is necessary since some - // C++ compilers are *very* lame... -{ -public: - ACE_Null_Condition_Mutex (ACE_Null_Mutex &m, int = 0, - LPCTSTR = 0, void * = 0): mutex_ (m) {} - ~ACE_Null_Condition_Mutex (void) {} - int remove (void) { return 0; } - int wait (ACE_Time_Value * = 0) { errno = ETIME; return -1; } - int signal (void) { return 0; } - int broadcast (void) { return 0; } - ACE_Null_Mutex &mutex (void) { return this->mutex_; } - - void dump (void) const {} - // Dump the state of an object. - - // ACE_ALLOC_HOOK_DECLARE; - // Declare the dynamic allocation hooks. - -private: - ACE_Null_Mutex &mutex_; // Reference to mutex lock. - - // = Prevent assignment and initialization. - void operator= (const ACE_Null_Condition_Mutex &) {} - ACE_Null_Condition_Mutex (const ACE_Null_Condition_Mutex &c): mutex_ (c.mutex_) {} -}; - -class ACE_Export ACE_Null_Mutex_Guard - // = TITLE - // This data structure is meant to be used within a method or - // function... It performs automatic aquisition and release of - // an ACE_Null_Mutex. - // - // = DESCRIPTION - // This should be a specialization of ACE_Guard, but compiler - // bugs preclude this... -{ -public: - ACE_Null_Mutex_Guard (ACE_Null_Mutex &) {} - ~ACE_Null_Mutex_Guard (void) {} - int remove (void) { return 0; } - int locked (void) { return 1; } - int acquire (void) { return 0; } - int tryacquire (void) { return 0; } - int release (void) { return 0; } - void dump (void) const { } - -protected: - // = Prevent assignment and initialization. - void operator= (const ACE_Null_Mutex_Guard &) {} - ACE_Null_Mutex_Guard (const ACE_Null_Mutex_Guard &) {} -}; - #if defined (__ACE_INLINE__) #include "ace/Synch.i" #endif /* __ACE_INLINE__ */ diff --git a/ace/Synch.i b/ace/Synch.i index 03f72d67af2..3bc15d21e39 100644 --- a/ace/Synch.i +++ b/ace/Synch.i @@ -74,41 +74,67 @@ ACE_File_Lock::set_handle (ACE_HANDLE h) this->lock_.handle_ = h; } -#if defined (ACE_HAS_THREADS) - -ACE_INLINE const ACE_sema_t & -ACE_Semaphore::lock (void) const +ACE_INLINE const ACE_rwlock_t & +ACE_RW_Mutex::lock (void) const { -// ACE_TRACE ("ACE_Semaphore::lock"); - return this->semaphore_; +// ACE_TRACE ("ACE_RW_Mutex::lock"); + return this->lock_; } ACE_INLINE int -ACE_Semaphore::remove (void) +ACE_RW_Mutex::remove (void) { -// ACE_TRACE ("ACE_Semaphore::remove"); - return ACE_OS::sema_destroy (&this->semaphore_); +// ACE_TRACE ("ACE_RW_Mutex::remove"); + return ACE_OS::rwlock_destroy (&this->lock_); } ACE_INLINE int -ACE_Semaphore::acquire (void) +ACE_RW_Mutex::acquire_read (void) { -// ACE_TRACE ("ACE_Semaphore::acquire"); - return ACE_OS::sema_wait (&this->semaphore_); +// ACE_TRACE ("ACE_RW_Mutex::acquire_read"); + return ACE_OS::rw_rdlock (&this->lock_); +} + +ACE_INLINE int +ACE_RW_Mutex::acquire_write (void) +{ +// ACE_TRACE ("ACE_RW_Mutex::acquire_write"); + return ACE_OS::rw_wrlock (&this->lock_); } -ACE_INLINE int -ACE_Semaphore::tryacquire (void) +ACE_INLINE int +ACE_RW_Mutex::acquire (void) { -// ACE_TRACE ("ACE_Semaphore::tryacquire"); - return ACE_OS::sema_trywait (&this->semaphore_); +// ACE_TRACE ("ACE_RW_Mutex::acquire"); + return ACE_OS::rw_wrlock (&this->lock_); } -ACE_INLINE int -ACE_Semaphore::release (void) +ACE_INLINE int +ACE_RW_Mutex::tryacquire_read (void) { -// ACE_TRACE ("ACE_Semaphore::release"); - return ACE_OS::sema_post (&this->semaphore_); +// ACE_TRACE ("ACE_RW_Mutex::tryacquire_read"); + return ACE_OS::rw_tryrdlock (&this->lock_); +} + +ACE_INLINE int +ACE_RW_Mutex::tryacquire_write (void) +{ +// ACE_TRACE ("ACE_RW_Mutex::tryacquire_write"); + return ACE_OS::rw_trywrlock (&this->lock_); +} + +ACE_INLINE int +ACE_RW_Mutex::tryacquire (void) +{ +// ACE_TRACE ("ACE_RW_Mutex::tryacquire"); + return this->tryacquire_write (); +} + +ACE_INLINE int +ACE_RW_Mutex::release (void) +{ +// ACE_TRACE ("ACE_RW_Mutex::release"); + return ACE_OS::rw_unlock (&this->lock_); } ACE_INLINE int @@ -174,6 +200,43 @@ ACE_Mutex::remove (void) return ACE_OS::mutex_destroy (&this->lock_); } +ACE_INLINE const ACE_sema_t & +ACE_Semaphore::lock (void) const +{ +// ACE_TRACE ("ACE_Semaphore::lock"); + return this->semaphore_; +} + +ACE_INLINE int +ACE_Semaphore::remove (void) +{ +// ACE_TRACE ("ACE_Semaphore::remove"); + return ACE_OS::sema_destroy (&this->semaphore_); +} + +ACE_INLINE int +ACE_Semaphore::acquire (void) +{ +// ACE_TRACE ("ACE_Semaphore::acquire"); + return ACE_OS::sema_wait (&this->semaphore_); +} + +ACE_INLINE int +ACE_Semaphore::tryacquire (void) +{ +// ACE_TRACE ("ACE_Semaphore::tryacquire"); + return ACE_OS::sema_trywait (&this->semaphore_); +} + +ACE_INLINE int +ACE_Semaphore::release (void) +{ +// ACE_TRACE ("ACE_Semaphore::release"); + return ACE_OS::sema_post (&this->semaphore_); +} + +#if defined (ACE_HAS_THREADS) + ACE_INLINE const ACE_thread_mutex_t & ACE_Thread_Mutex::lock (void) const { @@ -359,68 +422,5 @@ ACE_Recursive_Thread_Mutex::set_nesting_level (int d) this->nesting_level_ = d; } -ACE_INLINE const ACE_rwlock_t & -ACE_RW_Mutex::lock (void) const -{ -// ACE_TRACE ("ACE_RW_Mutex::lock"); - return this->lock_; -} - -ACE_INLINE int -ACE_RW_Mutex::remove (void) -{ -// ACE_TRACE ("ACE_RW_Mutex::remove"); - return ACE_OS::rwlock_destroy (&this->lock_); -} - -ACE_INLINE int -ACE_RW_Mutex::acquire_read (void) -{ -// ACE_TRACE ("ACE_RW_Mutex::acquire_read"); - return ACE_OS::rw_rdlock (&this->lock_); -} - -ACE_INLINE int -ACE_RW_Mutex::acquire_write (void) -{ -// ACE_TRACE ("ACE_RW_Mutex::acquire_write"); - return ACE_OS::rw_wrlock (&this->lock_); -} - -ACE_INLINE int -ACE_RW_Mutex::acquire (void) -{ -// ACE_TRACE ("ACE_RW_Mutex::acquire"); - return ACE_OS::rw_wrlock (&this->lock_); -} - -ACE_INLINE int -ACE_RW_Mutex::tryacquire_read (void) -{ -// ACE_TRACE ("ACE_RW_Mutex::tryacquire_read"); - return ACE_OS::rw_tryrdlock (&this->lock_); -} - -ACE_INLINE int -ACE_RW_Mutex::tryacquire_write (void) -{ -// ACE_TRACE ("ACE_RW_Mutex::tryacquire_write"); - return ACE_OS::rw_trywrlock (&this->lock_); -} - -ACE_INLINE int -ACE_RW_Mutex::tryacquire (void) -{ -// ACE_TRACE ("ACE_RW_Mutex::tryacquire"); - return this->tryacquire_write (); -} - -ACE_INLINE int -ACE_RW_Mutex::release (void) -{ -// ACE_TRACE ("ACE_RW_Mutex::release"); - return ACE_OS::rw_unlock (&this->lock_); -} - #endif /* ACE_HAS_THREADS */ diff --git a/ace/Synch_T.cpp b/ace/Synch_T.cpp index 6e371199365..cf6219502eb 100644 --- a/ace/Synch_T.cpp +++ b/ace/Synch_T.cpp @@ -272,7 +272,7 @@ ACE_TSS<TYPE>::ts_get (void) const template <class TYPE> ACE_TSS<TYPE>::ACE_TSS (TYPE *ts_obj) : once_ (0), - key_ (0) + key_ (ACE_OS::NULL_key) { // If caller has passed us a non-NULL TYPE *, then we'll just use // this to initialize the thread-specific value. Thus, subsequent @@ -426,7 +426,7 @@ ACE_TSS_Guard<LOCK>::init_key (void) { // ACE_TRACE ("ACE_TSS_Guard<LOCK>::init_key"); - this->key_ = 0; + this->key_ = ACE_OS::NULL_key; ACE_Thread::keycreate (&this->key_, &ACE_TSS_Guard<LOCK>::cleanup, (void *) this); diff --git a/ace/Task.cpp b/ace/Task.cpp index b61699c8213..8152f66fe9d 100644 --- a/ace/Task.cpp +++ b/ace/Task.cpp @@ -232,4 +232,11 @@ ACE_Task_Base::svc_run (void *args) /* NOTREACHED */ } +// Forward the call to close() so that existing +// applications don't break. +int +ACE_Task_Base::module_closed (void) +{ + return this->close (1); +} diff --git a/ace/Task.h b/ace/Task.h index 0d642cfc1ec..0b11f6ead24 100644 --- a/ace/Task.h +++ b/ace/Task.h @@ -62,7 +62,17 @@ public: // information into <open>. virtual int close (u_long flags = 0) = 0; - // Hook called to close a Task. + // Hook called from ACE_Task_Exit when during thread exit and from + // the default implemenation of module_closed(). + + virtual int module_closed (void); + // Hook called during ACE_Module::close(). The default + // implementation calls forwards the call to close(1). Please + // notice the changed value of the default argument of close(). + // This allows tasks to differ between the call has been originated + // from ACE_Task_Exit or from module_closed(). Be aware that + // close(0) will be also called when a thread associated with the + // ACE_Task instance exits. // = Immediate and deferred processing methods, respectively. virtual int put (ACE_Message_Block *, ACE_Time_Value * = 0) = 0; diff --git a/ace/Task_T.i b/ace/Task_T.i index d3ebf97f8f0..9f5ba06054e 100644 --- a/ace/Task_T.i +++ b/ace/Task_T.i @@ -57,10 +57,6 @@ template <ACE_SYNCH_1> ACE_INLINE void ACE_Task<ACE_SYNCH_2>::msg_queue (ACE_Message_Queue<ACE_SYNCH_2> *mq) { ACE_TRACE ("ACE_Task<ACE_SYNCH_2>::msg_queue"); - if (this->delete_msg_queue_) - delete this->msg_queue_; - - this->delete_msg_queue_ = 0; this->msg_queue_ = mq; } diff --git a/ace/Thread_Manager.cpp b/ace/Thread_Manager.cpp index 1573e94ed26..fa2267a443c 100644 --- a/ace/Thread_Manager.cpp +++ b/ace/Thread_Manager.cpp @@ -98,11 +98,10 @@ ACE_Thread_Manager::thr_self (ACE_hthread_t &self) ACE_Thread_Descriptor td; ACE_thread_t id = ACE_OS::thr_self (); - int i = this->thread_descriptor_i (id, td); + if (this->thread_descriptor_i (id, td) == -1) + return -1; - if (i == -1) - return -1; - handle = &this->thr_table_[i].thr_handle_; + handle = &td.thr_handle_; // Update the TSS cache. ACE_LOG_MSG->thr_handle (handle); diff --git a/ace/config-mvs.h b/ace/config-mvs.h index 506f35a03a3..ed12fa4f6c2 100644 --- a/ace/config-mvs.h +++ b/ace/config-mvs.h @@ -13,6 +13,9 @@ #define fd_mask __fd_mask #define MAXNAMLEN __DIR_NAME_MAX +// Compiler must see template source. +#define ACE_TEMPLATES_REQUIRE_SOURCE + // Compiler/platform uses macro for ctime #define ACE_HAS_BROKEN_CTIME @@ -103,10 +106,6 @@ // Platform supports System V IPC #define ACE_HAS_SYSV_IPC -// Compiler implements templates that support typedefs inside -// of classes used as formal arguments -//#define ACE_HAS_TEMPLATE_TYPEDEFS - // Platform/compiler supports timezone * as second parameter to gettimeofday() #define ACE_HAS_TIMEZONE_GETTIMEOFDAY diff --git a/tests/Process_Mutex_Test.cpp b/tests/Process_Mutex_Test.cpp index 7314e9e71f8..cfbec7bf50d 100644 --- a/tests/Process_Mutex_Test.cpp +++ b/tests/Process_Mutex_Test.cpp @@ -46,13 +46,13 @@ parse_args (int argc, char *argv[]) switch (c) { case 'd': - ::release_mutex = 0; + release_mutex = 0; break; case 'c': - ::child_process = 1; + child_process = 1; break; case 'n': - ::mutex_name = get_opt.optarg; + mutex_name = get_opt.optarg; break; default: print_usage_and_die (); @@ -61,21 +61,21 @@ parse_args (int argc, char *argv[]) } static void -doit () +acquire_release (void) { - ACE_Process_Mutex mutex (::mutex_name); + ACE_Process_Mutex mutex (mutex_name); // Make sure the constructor succeeded ACE_ASSERT (ACE_LOG_MSG->op_status () == 0); // Grab the lock ACE_ASSERT (mutex.acquire () == 0); - ACE_DEBUG ((LM_DEBUG, "(%P) Mutex acquired %s\n", ::mutex_name)); + ACE_DEBUG ((LM_DEBUG, "(%P) Mutex acquired %s\n", mutex_name)); ACE_DEBUG ((LM_DEBUG, "(%P) Working....\n")); // work ACE_OS::sleep (2); // Check if we need to release the mutex - if (::release_mutex == 1) + if (release_mutex == 1) { - ACE_DEBUG ((LM_DEBUG, "(%P) Releasing the mutex %s\n", ::mutex_name)); + ACE_DEBUG ((LM_DEBUG, "(%P) Releasing the mutex %s\n", mutex_name)); ACE_ASSERT (mutex.release () == 0); } } @@ -83,13 +83,13 @@ doit () int main (int argc, char *argv[]) { - ::parse_args (argc, argv); + parse_args (argc, argv); // Child process code - if (::child_process) + if (child_process) { ACE_APPEND_LOG ("Process_Mutex_Test-children"); - ::doit (); + acquire_release (); ACE_END_LOG; } else @@ -101,8 +101,8 @@ main (int argc, char *argv[]) s_argv[0] = "Process_Mutex_Test" ACE_PLATFORM_EXE_SUFFIX; s_argv[1] = "-c"; // child/slave process s_argv[2] = "-n"; - s_argv[3] = ::mutex_name; - if (::release_mutex == 0) + s_argv[3] = mutex_name; + if (release_mutex == 0) s_argv[4] = "-d"; else s_argv[4] = 0; |