summaryrefslogtreecommitdiff
path: root/ace
diff options
context:
space:
mode:
authorschmidt <douglascraigschmidt@users.noreply.github.com>1996-12-22 22:06:04 +0000
committerschmidt <douglascraigschmidt@users.noreply.github.com>1996-12-22 22:06:04 +0000
commitaa56341042bf18dfb4754e0910113e8e059acc82 (patch)
tree147fc294556751cc24df552768b29a173a22c924 /ace
parentf13a60d21d6b6971654b1b2737dd09fafdbef944 (diff)
downloadATCD-aa56341042bf18dfb4754e0910113e8e059acc82.tar.gz
foo
Diffstat (limited to 'ace')
-rw-r--r--ace/Acceptor.cpp14
-rw-r--r--ace/Local_Name_Space_T.cpp87
-rw-r--r--ace/Local_Name_Space_T.h2
-rw-r--r--ace/Malloc_T.cpp3
-rw-r--r--ace/Naming_Context.cpp2
-rw-r--r--ace/OS.cpp117
-rw-r--r--ace/OS.h145
-rw-r--r--ace/OS.i150
-rw-r--r--ace/Proactor.cpp8
-rw-r--r--ace/Proactor.h12
-rw-r--r--ace/README3
-rw-r--r--ace/ReactorEx.cpp29
-rw-r--r--ace/ReactorEx.h93
-rw-r--r--ace/ReactorEx.i7
-rw-r--r--ace/SV_Semaphore_Complex.cpp7
-rw-r--r--ace/SV_Semaphore_Simple.cpp26
-rw-r--r--ace/SV_Semaphore_Simple.i3
-rw-r--r--ace/Signal.cpp7
-rw-r--r--ace/Signal.h1
-rw-r--r--ace/Synch.cpp33
-rw-r--r--ace/Synch.h32
-rw-r--r--ace/Synch_T.cpp217
-rw-r--r--ace/Thread.h4
-rw-r--r--ace/Thread.i4
-rw-r--r--ace/config-aix-4.1.x.h1
-rw-r--r--ace/config-hpux-10.x.h1
-rw-r--r--ace/config-irix6.2-sgic++.h1
-rw-r--r--ace/config-linux-lxpthreads.h104
-rw-r--r--ace/config-linux-pthread.h4
-rw-r--r--ace/config-m88k.h6
-rw-r--r--ace/config-mvs.h2
-rw-r--r--ace/config-osf1-4.0-g++.h4
-rw-r--r--ace/config-osf1-4.0.h2
-rw-r--r--ace/config-vxworks-ghs-1.8.h2
-rw-r--r--ace/config-vxworks5.2-g++.h2
-rw-r--r--ace/config-win32-msvc2.0.h2
-rw-r--r--ace/config-win32-msvc4.0.h2
37 files changed, 792 insertions, 347 deletions
diff --git a/ace/Acceptor.cpp b/ace/Acceptor.cpp
index d770af37146..79ad80fd9ae 100644
--- a/ace/Acceptor.cpp
+++ b/ace/Acceptor.cpp
@@ -170,6 +170,14 @@ ACE_Acceptor<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::handle_close (ACE_HANDLE,
this->reactor_->remove_handler
(handle, ACE_Event_Handler::READ_MASK | ACE_Event_Handler::DONT_CALL);
+
+ // Shut down the listen socket to recycle the handles.
+ if (this->peer_acceptor_.close () == -1)
+ ACE_ERROR ((LM_ERROR, "close\n"));
+
+ // Set the Reactor to 0 so that we don't try to close down
+ // again.
+ this->reactor (0);
}
return 0;
}
@@ -484,7 +492,7 @@ ACE_Strategy_Acceptor<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::handle_close (ACE_HANDL
{
ACE_TRACE ("ACE_Strategy_Acceptor<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::handle_close");
// Guard against multiple closes.
- if (this->creation_strategy_ != 0)
+ if (this->reactor () != 0)
{
ACE_HANDLE handle = this->get_handle ();
@@ -513,6 +521,10 @@ ACE_Strategy_Acceptor<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::handle_close (ACE_HANDL
this->reactor ()->remove_handler
(handle, ACE_Event_Handler::READ_MASK | ACE_Event_Handler::DONT_CALL);
+
+ // Set the Reactor to 0 so that we don't try to close down
+ // again.
+ this->reactor (0);
}
return 0;
}
diff --git a/ace/Local_Name_Space_T.cpp b/ace/Local_Name_Space_T.cpp
index 0f6c66f651b..821ee3797d6 100644
--- a/ace/Local_Name_Space_T.cpp
+++ b/ace/Local_Name_Space_T.cpp
@@ -211,7 +211,7 @@ ACE_Local_Name_Space<ACE_MEM_POOL_2, LOCK>::unbind_i (const ACE_WString &name)
{
ACE_TRACE ("ACE_Local_Name_Space::unbind");
- ACE_WRITE_GUARD_RETURN (ACE_RW_Process_Mutex, ace_mon, this->lock_, -1);
+ ACE_WRITE_GUARD_RETURN (ACE_RW_Process_Mutex, ace_mon, *this->lock_, -1);
ACE_NS_String ns_name (name);
ACE_NS_Internal ns_internal;
if (this->name_space_map_->unbind (ns_name, ns_internal, this->allocator_) != 0)
@@ -233,7 +233,7 @@ ACE_Local_Name_Space<ACE_MEM_POOL_2, LOCK>::bind (const ACE_WString &name,
const char *type)
{
ACE_TRACE ("ACE_Local_Name_Space::bind");
- ACE_WRITE_GUARD_RETURN (ACE_RW_Process_Mutex, ace_mon, this->lock_, -1);
+ ACE_WRITE_GUARD_RETURN (ACE_RW_Process_Mutex, ace_mon, *this->lock_, -1);
return this->shared_bind (name, value, type, 0);
}
@@ -244,7 +244,7 @@ ACE_Local_Name_Space<ACE_MEM_POOL_2, LOCK>::rebind (const ACE_WString &name,
const char *type)
{
ACE_TRACE ("ACE_Local_Name_Space::rebind");
- ACE_WRITE_GUARD_RETURN (ACE_RW_Process_Mutex, ace_mon, this->lock_, -1);
+ ACE_WRITE_GUARD_RETURN (ACE_RW_Process_Mutex, ace_mon, *this->lock_, -1);
return this->shared_bind (name, value, type, 1);
}
@@ -273,7 +273,7 @@ ACE_Local_Name_Space<ACE_MEM_POOL_2, LOCK>::resolve_i (const ACE_WString &name,
char *&type)
{
ACE_TRACE ("ACE_Local_Name_Space::resolve");
- ACE_READ_GUARD_RETURN (ACE_RW_Process_Mutex, ace_mon, this->lock_, -1);
+ ACE_READ_GUARD_RETURN (ACE_RW_Process_Mutex, ace_mon, *this->lock_, -1);
ACE_NS_String ns_name (name);
ACE_NS_Internal ns_internal;
@@ -337,8 +337,9 @@ ACE_Local_Name_Space<ACE_MEM_POOL_2, LOCK>::~ACE_Local_Name_Space (void)
{
ACE_TRACE ("ACE_Local_Name_Space::~ACE_Local_Name_Space");
- // Remove the map
+ // Remove the map.
delete this->allocator_;
+ delete this->lock_;
}
template <ACE_MEM_POOL_1, class LOCK> int
@@ -378,15 +379,29 @@ ACE_Local_Name_Space<ACE_MEM_POOL_2, LOCK>::create_manager_i (void)
ACE_OS::strcat (this->context_file_, ACE_DIRECTORY_SEPARATOR_STR);
ACE_OS::strcat (this->context_file_, this->name_options_->database ());
- // ACE_DEBUG ((LM_DEBUG, "contextfile is %s\n", this->context_file_));
-
ACE_MEM_POOL_OPTIONS options (this->name_options_->base_address ());
+ TCHAR lock_name_for_local_name_space [MAXNAMELEN];
+ TCHAR lock_name_for_backing_store [MAXNAMELEN];
+ LPCTSTR prefix = ACE::basename (this->context_file_,
+ ACE_DIRECTORY_SEPARATOR_CHAR);
+
+ ACE_OS::strcpy (lock_name_for_local_name_space , prefix);
+ ACE_OS::strcat (lock_name_for_local_name_space, "_name_space");
+
+ ACE_OS::strcpy (lock_name_for_backing_store, prefix);
+ ACE_OS::strcat (lock_name_for_backing_store, "_backing_store");
+
// Create the allocator with the appropriate options.
- ACE_NEW_RETURN (this->allocator_, ALLOCATOR (this->context_file_, 0, &options), -1);
+ ACE_NEW_RETURN (this->allocator_,
+ ALLOCATOR (this->context_file_,
+ lock_name_for_backing_store,
+ &options), -1);
if (ACE_LOG_MSG->op_status ())
ACE_ERROR_RETURN ((LM_ERROR, "Allocator::Allocator\n"), -1);
+
+ ACE_NEW_RETURN (this->lock_, LOCK (lock_name_for_local_name_space), -1);
// Now check if the backing store has been created successfully
if (ACE_OS::access (this->context_file_, F_OK) != 0)
@@ -404,31 +419,33 @@ ACE_Local_Name_Space<ACE_MEM_POOL_2, LOCK>::create_manager_i (void)
}
// This is the hard part since we have to avoid potential race
- // conditions...
+ // conditions... We will use the double check here
else
{
- size_t map_size = sizeof *this->name_space_map_;
- ns_map = this->allocator_->malloc (map_size);
-
- // Initialize the map into its memory location (e.g., shared memory).
- ACE_NEW_RETURN (this->name_space_map_,
- (ns_map) ACE_Name_Space_Map <ALLOCATOR> (this->allocator_),
- -1);
+ ACE_GUARD_RETURN (ACE_RW_Process_Mutex, ace_mon, *this->lock_, -1);
- // Don't allow duplicates (atomically return existing int_id, if
- // there is one).
- if (this->allocator_->trybind (ACE_NAME_SERVER_MAP, ns_map) == 1)
+ // This is the easy case since if we find the Name Server Map
+ // Manager we know it's already initialized.
+ if (this->allocator_->find (ACE_NAME_SERVER_MAP, ns_map) == 0)
{
- // We're not the first one in, so free up the map and assign
- // the map to the pointer that was allocated by the caller
- // that was the first time in!
- this->name_space_map_->close (this->allocator_);
-
- // Note that we can't free <map> since that was overwritten
- // in the call to bind()!
- this->allocator_->free ((void *) this->name_space_map_);
this->name_space_map_ = (ACE_Name_Space_Map <ALLOCATOR> *) ns_map;
+ ACE_DEBUG ((LM_DEBUG, "name_space_map_ = %d, ns_map = %d\n",
+ this->name_space_map_, ns_map));
+ }
+ else
+ {
+ size_t map_size = sizeof *this->name_space_map_;
+ ns_map = this->allocator_->malloc (map_size);
+
+ // Initialize the map into its memory location (e.g., shared memory).
+ ACE_NEW_RETURN (this->name_space_map_,
+ (ns_map) ACE_Name_Space_Map <ALLOCATOR> (this->allocator_),
+ -1);
+
+ if (this->allocator_->bind (ACE_NAME_SERVER_MAP, ns_map) == -1)
+ ACE_ERROR_RETURN ((LM_ERROR, "create_manager\n"), -1);
}
+
ACE_DEBUG ((LM_DEBUG, "name_space_map_ = %d, ns_map = %d\n",
this->name_space_map_, ns_map));
}
@@ -436,12 +453,13 @@ ACE_Local_Name_Space<ACE_MEM_POOL_2, LOCK>::create_manager_i (void)
return 0;
}
+
template <ACE_MEM_POOL_1, class LOCK> int
ACE_Local_Name_Space<ACE_MEM_POOL_2, LOCK>::list_names (ACE_PWSTRING_SET &set,
const ACE_WString &pattern)
{
ACE_TRACE ("ACE_Local_Name_Space::list_names");
- ACE_READ_GUARD_RETURN (ACE_RW_Process_Mutex, ace_mon, this->lock_, -1);
+ ACE_READ_GUARD_RETURN (ACE_RW_Process_Mutex, ace_mon, *this->lock_, -1);
MAP_ITERATOR map_iterator (*this->name_space_map_);
MAP_ENTRY *map_entry;
@@ -474,7 +492,7 @@ ACE_Local_Name_Space<ACE_MEM_POOL_2, LOCK>::list_values (ACE_PWSTRING_SET &set,
const ACE_WString &pattern)
{
ACE_TRACE ("ACE_Local_Name_Space::list_values");
- ACE_READ_GUARD_RETURN (ACE_RW_Process_Mutex, ace_mon, this->lock_, -1);
+ ACE_READ_GUARD_RETURN (ACE_RW_Process_Mutex, ace_mon, *this->lock_, -1);
MAP_ITERATOR map_iterator (*this->name_space_map_);
MAP_ENTRY *map_entry;
@@ -507,7 +525,7 @@ ACE_Local_Name_Space<ACE_MEM_POOL_2, LOCK>::list_types (ACE_PWSTRING_SET &set,
const ACE_WString &pattern)
{
ACE_TRACE ("ACE_Local_Name_Space::list_types");
- ACE_READ_GUARD_RETURN (ACE_RW_Process_Mutex, ace_mon, this->lock_, -1);
+ ACE_READ_GUARD_RETURN (ACE_RW_Process_Mutex, ace_mon, *this->lock_, -1);
MAP_ITERATOR map_iterator (*this->name_space_map_);
MAP_ENTRY *map_entry;
@@ -569,7 +587,7 @@ ACE_Local_Name_Space <ACE_MEM_POOL_2, LOCK>::list_name_entries (ACE_BINDING_SET
const ACE_WString &pattern)
{
ACE_TRACE ("ACE_Local_Name_Space::list_name_entries");
- ACE_READ_GUARD_RETURN (ACE_RW_Process_Mutex, ace_mon, this->lock_, -1);
+ ACE_READ_GUARD_RETURN (ACE_RW_Process_Mutex, ace_mon, *this->lock_, -1);
MAP_ITERATOR map_iterator (*this->name_space_map_);
MAP_ENTRY *map_entry;
@@ -597,7 +615,7 @@ ACE_Local_Name_Space<ACE_MEM_POOL_2, LOCK>::list_value_entries (ACE_BINDING_SET
const ACE_WString &pattern)
{
ACE_TRACE ("ACE_Local_Name_Space::list_value_entries");
- ACE_READ_GUARD_RETURN (ACE_RW_Process_Mutex, ace_mon, this->lock_, -1);
+ ACE_READ_GUARD_RETURN (ACE_RW_Process_Mutex, ace_mon, *this->lock_, -1);
MAP_ITERATOR map_iterator (*this->name_space_map_);
MAP_ENTRY *map_entry;
@@ -624,7 +642,7 @@ ACE_Local_Name_Space<ACE_MEM_POOL_2, LOCK>::list_type_entries (ACE_BINDING_SET &
const ACE_WString &pattern)
{
ACE_TRACE ("ACE_Local_Name_Space::list_type_entries");
- ACE_READ_GUARD_RETURN (ACE_RW_Process_Mutex, ace_mon, this->lock_, -1);
+ ACE_READ_GUARD_RETURN (ACE_RW_Process_Mutex, ace_mon, *this->lock_, -1);
MAP_ITERATOR map_iterator (*this->name_space_map_);
MAP_ENTRY *map_entry;
@@ -703,6 +721,3 @@ ACE_Local_Name_Space<ACE_MEM_POOL_2, LOCK>::dump (void) const
}
#endif /* ACE_LOCAL_NAME_SPACE_T_C */
-
-
-
diff --git a/ace/Local_Name_Space_T.h b/ace/Local_Name_Space_T.h
index 6745738e044..616019884a9 100644
--- a/ace/Local_Name_Space_T.h
+++ b/ace/Local_Name_Space_T.h
@@ -212,7 +212,7 @@ private:
TCHAR context_file_[MAXNAMELEN];
// Name of the file used as the backing store.
- LOCK lock_;
+ LOCK *lock_;
// Synchronization variable.
};
diff --git a/ace/Malloc_T.cpp b/ace/Malloc_T.cpp
index 3685c4a42ac..4a45dbcb3cb 100644
--- a/ace/Malloc_T.cpp
+++ b/ace/Malloc_T.cpp
@@ -164,7 +164,8 @@ ACE_Malloc<ACE_MEM_POOL_2, LOCK>::ACE_Malloc (LPCTSTR pool_name,
LPCTSTR lock_name,
const ACE_MEM_POOL_OPTIONS *options)
: memory_pool_ (pool_name, options),
- lock_ (lock_name)
+ lock_ (lock_name != 0 ? lock_name : ACE::basename (pool_name,
+ ACE_DIRECTORY_SEPARATOR_CHAR))
{
ACE_TRACE ("ACE_Malloc<ACE_MEM_POOL_2, LOCK>::ACE_Malloc");
this->open ();
diff --git a/ace/Naming_Context.cpp b/ace/Naming_Context.cpp
index 90048ca5353..12779536a7d 100644
--- a/ace/Naming_Context.cpp
+++ b/ace/Naming_Context.cpp
@@ -347,7 +347,7 @@ ACE_Name_Options::ACE_Name_Options (void)
nameserver_host_ (ACE_OS::strdup (ACE_DEFAULT_SERVER_HOST)),
namespace_dir_ (ACE_OS::strdup (ACE_DEFAULT_NAMESPACE_DIR)),
process_name_ (0),
- database_ (0),
+ database_ (ACE_OS::strdup (ACE_DEFAULT_LOCALNAME)),
base_address_ (ACE_DEFAULT_BASE_ADDR)
{
ACE_TRACE ("ACE_Name_Options::ACE_Name_Options");
diff --git a/ace/OS.cpp b/ace/OS.cpp
index f52c5639c40..2a8b83b75cd 100644
--- a/ace/OS.cpp
+++ b/ace/OS.cpp
@@ -696,6 +696,7 @@ ACE_OS::thr_create (ACE_THR_FUNC func,
size = PTHREAD_STACK_MIN;
#endif /* PTHREAD_STACK_MIN */
+#if !defined (ACE_LACKS_THREAD_STACK_SIZE) // JCEJ 12/17/96
if (::pthread_attr_setstacksize (&attr, size) != 0)
{
#if defined (ACE_HAS_SETKIND_NP)
@@ -706,6 +707,7 @@ ACE_OS::thr_create (ACE_THR_FUNC func,
return -1;
}
}
+#endif /* !ACE_LACKS_THREAD_STACK_SIZE */
#if !defined (ACE_LACKS_THREAD_STACK_ADDR)
if (stack != 0)
@@ -919,17 +921,17 @@ ACE_OS::thr_create (ACE_THR_FUNC func,
if (ACE_BIT_ENABLED (flags, THR_USE_AFX))
{
CWinThread *cwin_thread =
- ::AfxBeginThread (ACE_THR_C_FUNC (&ace_thread_adapter)),
+ ::AfxBeginThread ((AFX_THREADPROC) &ace_thread_adapter),
thread_args, priority, 0, flags | THR_SUSPENDED);
// Have to duplicate the handle because
// CWinThread::~CWinThread() closes the original handle.
- *thr_handle = ::DuplicateHandle (::GetCurrentProcess (),
- cwin_thread->m_hThread,
- ::GetCurrentProcess (),
- thr_handle,
- 0,
- TRUE,
- DUPLICATE_SAME_ACCESS);
+ (void) ::DuplicateHandle (::GetCurrentProcess (),
+ cwin_thread->m_hThread,
+ ::GetCurrentProcess (),
+ thr_handle,
+ 0,
+ TRUE,
+ DUPLICATE_SAME_ACCESS);
*thr_id = cwin_thread->m_nThreadID;
@@ -1115,7 +1117,11 @@ ACE_OS::thr_keyfree (ACE_thread_key_t key)
int
ACE_OS::thr_keycreate (ACE_thread_key_t *key,
+#if defined (ACE_HAS_THR_C_DEST)
+ ACE_THR_C_DEST dest,
+#else
ACE_THR_DEST dest,
+#endif /* ACE_HAS_THR_C_DEST */
void *inst)
{
// ACE_TRACE ("ACE_OS::thr_keycreate");
@@ -1392,62 +1398,59 @@ int sys_nerr = ERRMAX + 1;
#include /**/ <usrLib.h> /* for ::sp() */
-// This global function can be used from the VxWorks shell to
-// pass arguments to a C main () function.
-// usage: -> spa main, "arg1", "arg2"
-// All arguments must be quoted, even numbers.
+// This global function can be used from the VxWorks shell to pass
+// arguments to a C main () function. usage: -> spa main, "arg1",
+// "arg2" All arguments must be quoted, even numbers.
int
spa (FUNCPTR entry, ...)
{
- static const unsigned int MAX_ARGS = 10;
- static char *argv[MAX_ARGS];
- va_list pvar;
- int argc;
-
- // Hardcode a program name because the real one isn't available
- // through the VxWorks shell.
- argv[0] = "spa ():t";
-
- // Peel off arguments to spa () and put into argv. va_arg ()
- // isn't necessarily supposed to return 0 when done, though
- // since the VxWorks shell uses a fixed number (10) of arguments,
- // it might 0 the unused ones.
- // This function could be used to increase that limit, but then
- // it couldn't depend on the trailing 0. So, the number of arguments
- // would have to be passed.
- va_start (pvar, entry);
- for (argc = 1; argc <= MAX_ARGS; ++argc)
- {
- argv[argc] = va_arg (pvar, char *);
- if (argv[argc] == 0)
- break;
- }
+ static const unsigned int MAX_ARGS = 10;
+ static char *argv[MAX_ARGS];
+ va_list pvar;
+ int argc;
+
+ // Hardcode a program name because the real one isn't available
+ // through the VxWorks shell.
+ argv[0] = "spa ():t";
+
+ // Peel off arguments to spa () and put into argv. va_arg () isn't
+ // necessarily supposed to return 0 when done, though since the
+ // VxWorks shell uses a fixed number (10) of arguments, it might 0
+ // the unused ones. This function could be used to increase that
+ // limit, but then it couldn't depend on the trailing 0. So, the
+ // number of arguments would have to be passed.
+ va_start (pvar, entry);
+
+ for (argc = 1; argc <= MAX_ARGS; ++argc)
+ {
+ argv[argc] = va_arg (pvar, char *);
- if (argc > MAX_ARGS && argv[argc-1] != 0)
- {
- // try to read another arg, and warn user if the limit was exceeded
- if (va_arg (pvar, char *) != 0)
- fprintf (stderr, "spa(): number of arguments limited to %d\n",
- MAX_ARGS);
- }
- else
- {
- // fill unused argv slots with 0 to get rid of leftovers
- // from previous invocations
- for ( int i = argc; i <= MAX_ARGS; ++i)
- {
- argv[i] = 0;
- }
- }
+ if (argv[argc] == 0)
+ break;
+ }
+
+ if (argc > MAX_ARGS && argv[argc-1] != 0)
+ {
+ // try to read another arg, and warn user if the limit was exceeded
+ if (va_arg (pvar, char *) != 0)
+ fprintf (stderr, "spa(): number of arguments limited to %d\n",
+ MAX_ARGS);
+ }
+ else
+ {
+ // fill unused argv slots with 0 to get rid of leftovers
+ // from previous invocations
+ for (int i = argc; i <= MAX_ARGS; ++i)
+ argv[i] = 0;
+ }
- int ret = ::sp (entry, argc, (int) argv, 0, 0, 0, 0, 0, 0, 0);
- va_end (pvar);
+ int ret = ::sp (entry, argc, (int) argv, 0, 0, 0, 0, 0, 0, 0);
+ va_end (pvar);
- // ::sp () returns the taskID on success: return 0 instead
- // if successful
- return ret > 0 ? 0 : ret;
+ // ::sp () returns the taskID on success: return 0 instead if
+ // successful
+ return ret > 0 ? 0 : ret;
}
-
#endif /* VXWORKS */
#if !defined (ACE_HAS_SIGINFO_T)
diff --git a/ace/OS.h b/ace/OS.h
index 7d64b9f0d77..42da1acbf94 100644
--- a/ace/OS.h
+++ b/ace/OS.h
@@ -644,7 +644,6 @@ typedef pthread_mutex_t ACE_thread_mutex_t;
#define THR_SCOPE_PROCESS 0x00200000
#define THR_INHERIT_SCHED 0x00400000
#define THR_EXPLICIT_SCHED 0x00800000
-#define THR_USE_AFX 0x01000000
#if !defined (ACE_HAS_STHREADS)
#if !defined (ACE_HAS_POSIX_SEM)
@@ -663,28 +662,6 @@ struct ACE_sema_t
};
#endif /* !ACE_HAS_POSIX_SEM */
-// This is used to implement readers/writer locks for POSIX pthreads.
-struct ACE_rwlock_t
-{
- 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.
-};
#else
// If we are on Solaris we can just reuse the existing implementations
// of these synchronization types.
@@ -751,59 +728,6 @@ typedef char * ACE_thread_t;
typedef int ACE_hthread_t;
typedef int ACE_thread_key_t;
-struct ACE_cond_t
- // = TITLE
- // This structure is used to implement condition variables on VxWorks
- //
- // = DESCRIPTION
- // At the current time, this stuff only works for threads
- // within the same process, which there's only one of on VxWorks.
-{
- long waiters_;
- // Number of waiting threads.
-
- ACE_thread_mutex_t waiters_lock_;
- // Serialize access to the waiters count.
-
- ACE_sema_t sema_;
- // Queue up threads waiting for the condition to become signaled.
-
- ACE_event_t waiters_done_;
- // An auto reset event used by the broadcast/signal thread to wait
- // for the waiting thread(s) to wake up and get a chance at the
- // semaphore.
-
- size_t was_broadcast_;
- // Keeps track of whether we were broadcasting or just signaling.
-};
-
-struct ACE_rwlock_t
- // = TITLE
- // This is used to implement readers/writer locks on VxWorks
- //
- // = DESCRIPTION
- // At the current time, this stuff only works for threads
- // within the same process, which there's only one of on VxWorks.
-{
- 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.
-};
#elif defined (ACE_HAS_WTHREADS)
typedef CRITICAL_SECTION ACE_thread_mutex_t;
typedef struct
@@ -817,28 +741,59 @@ typedef struct
} ACE_mutex_t;
typedef HANDLE ACE_sema_t;
+// 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
+#define THR_USE_AFX 0x01000000
+#endif /* ACE_HAS_DCETHREADS || ACE_HAS_PTHREADS */
+
+#if defined (ACE_LACKS_COND_T)
struct ACE_cond_t
// = TITLE
- // This structure is used to implement condition variables on NT.
+ // This structure is used to implement condition variables on
+ // VxWorks and Win32.
//
// = DESCRIPTION
- // At the current time, this stuff only works for threads
- // within the same process.
+ // At the current time, this stuff only works for threads
+ // within the same process.
{
- DWORD waiters_;
+ long waiters_;
// Number of waiting threads.
+ ACE_thread_mutex_t waiters_lock_;
+ // Serialize access to the waiters count.
+
ACE_sema_t sema_;
// Queue up threads waiting for the condition to become signaled.
+
+ ACE_event_t waiters_done_;
+ // An auto reset event used by the broadcast/signal thread to wait
+ // for the waiting thread(s) to wake up and get a chance at the
+ // semaphore.
+
+ size_t was_broadcast_;
+ // Keeps track of whether we were broadcasting or just signaling.
};
+#endif /* ACE_LACKS_COND_T */
+#if defined (ACE_LACKS_RWLOCK_T)
struct ACE_rwlock_t
// = TITLE
- // This is used to implement readers/writer locks on NT.
+ // This is used to implement readers/writer locks on NT,
+ // VxWorks, and POSIX pthreads.
//
// = DESCRIPTION
- // At the current time, this stuff only works for threads
- // within the same process.
+ // At the current time, this stuff only works for threads
+ // within the same process.
{
ACE_mutex_t lock_;
// Serialize access to internal state.
@@ -859,20 +814,8 @@ struct ACE_rwlock_t
// Value is -1 if writer has the lock, else this keeps track of the
// number of readers holding the lock.
};
+#endif /* ACE_LACKS_RWLOCK_T */
-// 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
-#endif /* ACE_HAS_DCETHREADS || ACE_HAS_PTHREADS */
#else /* !ACE_HAS_THREADS, i.e., the OS/platform doesn't support threading. */
// Give these things some reasonable value...
#define THR_CANCEL_DISABLE 0
@@ -1806,14 +1749,10 @@ typedef FUNCPTR ACE_THR_FUNC; // where typedef int (*FUNCPTR) (...)
typedef void *(*ACE_THR_FUNC)(void *);
#endif /* VXWORKS */
-#if defined (ACE_HAS_THR_C_DEST)
-// Needed for frigging MVS C++...
extern "C" {
-typedef void (*ACE_THR_DEST)(void *);
+typedef void (*ACE_THR_C_DEST)(void *);
}
-#else
typedef void (*ACE_THR_DEST)(void *);
-#endif /* ACE_HAS_THR_C_DEST */
extern "C"
{
@@ -2422,7 +2361,11 @@ public:
static int thr_getspecific (ACE_thread_key_t key, void **data);
static int thr_keyfree (ACE_thread_key_t key);
static int thr_key_detach (void *inst);
+#if defined (ACE_HAS_THR_C_DEST)
+ static int thr_keycreate (ACE_thread_key_t *key, ACE_THR_C_DEST, void *inst = 0);
+#else
static int thr_keycreate (ACE_thread_key_t *key, ACE_THR_DEST, void *inst = 0);
+#endif /* ACE_HAS_THR_C_DEST */
static int thr_key_used (ACE_thread_key_t key);
static size_t thr_min_stack (void);
static int thr_setconcurrency (int hint);
diff --git a/ace/OS.i b/ace/OS.i
index 7def262f4cd..6dd0503996a 100644
--- a/ace/OS.i
+++ b/ace/OS.i
@@ -743,9 +743,15 @@ ACE_OS::mutex_init (ACE_mutex_t *m,
int result = -1;
#if defined (ACE_HAS_SETKIND_NP)
+#if defined (ACE_HAS_DCETHREADS)
+ if (::pthread_mutexattr_create (&attributes) == 0
+ && ::pthread_mutexattr_setkind_np (&attributes, type) == 0
+ && ::pthread_mutex_init (m, attributes) == 0)
+#else
if (::pthread_mutexattr_init (&attributes) == 0
&& ::pthread_mutexattr_setkind_np (&attributes, type) == 0
&& ::pthread_mutex_init (m, &attributes) == 0)
+#endif /* ACE_HAS_DCETHREADS */
#else
if (::pthread_mutexattr_init (&attributes) == 0
#if defined (ACE_HAS_PTHREAD_MUTEXATTR_SETKIND_NP)
@@ -1074,8 +1080,13 @@ ACE_OS::cond_init (ACE_cond_t *cv, int type, LPCTSTR name, void *arg)
int result = -1;
#if defined (ACE_HAS_SETKIND_NP)
+#if defined (ACE_HAS_DCETHREADS)
+ if (::pthread_condattr_create (&attributes) == 0
+ && ::pthread_cond_init (cv, attributes) == 0
+#else
if (::pthread_condattr_init (&attributes) == 0
&& ::pthread_cond_init (cv, &attributes) == 0
+#endif /* ACE_HAS_DCETHREADS */
#if defined (ACE_HAS_PTHREAD_CONDATTR_SETKIND_NP)
&& ::pthread_condattr_setkind_np (&attributes, type) == 0
#endif /* ACE_HAS_PTHREAD_CONDATTR_SETKIND_NP */
@@ -1275,7 +1286,6 @@ ACE_OS::cond_timedwait (ACE_cond_t *cv,
// ACE_TRACE ("ACE_OS::cond_timedwait");
#if defined (ACE_HAS_THREADS)
#if defined (ACE_HAS_WTHREADS)
-
// Handle the easy case first.
if (timeout == 0)
return ACE_OS::cond_wait (cv, external_mutex);
@@ -1391,41 +1401,71 @@ ACE_OS::cond_timedwait (ACE_cond_t *cv,
// ACE_TRACE ("ACE_OS::cond_timedwait");
#if defined (ACE_HAS_THREADS)
#if defined (ACE_HAS_WTHREADS)
- cv->waiters_++;
-
- if (ACE_OS::thread_mutex_unlock (external_mutex) != 0)
- return -1;
-
- DWORD result;
-
+ // Handle the easy case first.
if (timeout == 0)
- // Wait forever.
- result = ::WaitForSingleObject (cv->sema_, INFINITE);
- else if (timeout->sec () == 0 && timeout->usec () == 0)
- // Do a "poll".
- result = ::WaitForSingleObject (cv->sema_, 0);
+ return ACE_OS::cond_wait (cv, external_mutex);
+
+ // It's ok to increment this because the <external_mutex> must be
+ // locked by the caller.
+ cv->waiters_++;
+
+ int result = 0;
+ int error = 0;
+ int msec_timeout;
+
+ if (timeout->sec () == 0 && timeout->usec () == 0)
+ msec_timeout = 0; // Do a "poll."
else
{
- // Wait for upto <relative_time> number of milliseconds. Note
- // that we must convert between absolute time (which is passed
- // as a parameter) and relative time (which is what
+ // Note that we must convert between absolute time (which is
+ // passed as a parameter) and relative time (which is what
// WaitForSingleObjects() expects).
ACE_Time_Value relative_time (*timeout - ACE_OS::gettimeofday ());
- result = ::WaitForSingleObject (cv->sema_, relative_time.msec ());
+ msec_timeout = relative_time.msec ();
}
- ACE_OS::thread_mutex_lock (external_mutex);
-
- cv->waiters_--;
+ // We keep the lock held just long enough to increment the count of
+ // waiters by one. Note that we can't keep it held across the call
+ // to WaitForSingleObject since that will deadlock other calls to
+ // ACE_OS::cond_signal().
+ if (ACE_OS::thread_mutex_unlock (external_mutex) != 0)
+ return -1;
- if (result == WAIT_OBJECT_0)
- return 0;
- else
+ // Wait to be awakened by a ACE_OS::signal() or ACE_OS::broadcast().
+ result = ::WaitForSingleObject (cv->sema_, msec_timeout);
+
+ if (result != WAIT_OBJECT_0)
+ // This is a hack, we need to find an appropriate mapping...
+ error = result == WAIT_TIMEOUT ? ETIME : ::GetLastError ();
+ else
{
- errno = result == WAIT_TIMEOUT ? ETIME : ::GetLastError ();
- // This is a hack, we need to find an appropriate mapping...
- return -1;
+ // If we are broadcasting, then we need to be smarter about
+ // locking since there can now be multiple threadsd in the
+ // crtical section. If we are signaling, however, we don't have
+ // to worry since there will just be 1 thread here.
+ if (cv->was_broadcast_)
+ {
+ if (ACE_OS::thread_mutex_lock (cv->waiters_lock_) != -1)
+ {
+ // By making the waiter responsible for decrementing its count we
+ // don't have to worry about having an internal mutex. Thanks to
+ // Karlheinz for recognizing this optimization.
+ cv->waiters_--;
+ // Release the signaler/broadcaster if we're the last waiter.
+ if (cv->waiters_ == 0)
+ ::SetEvent (cv->waiters_done_);
+ ACE_OS::thread_mutex_unlock (cv->internal_mutex_);
+ }
+ }
+ else
+ cv->waiters_--;
}
+ // We must always regain the external mutex, even when errors
+ // occur because that's the guarantee that we give to our
+ // callers.
+ ACE_OS::thread_mutex_lock (external_mutex);
+ errno = error;
+ return result;
#endif /* ACE_HAS_WTHREADS */
#else
ACE_NOTSUP_RETURN (-1);
@@ -1439,29 +1479,58 @@ ACE_OS::cond_wait (ACE_cond_t *cv,
// ACE_TRACE ("ACE_OS::cond_wait");
#if defined (ACE_HAS_THREADS)
#if defined (ACE_HAS_WTHREADS)
+ // It's ok to increment this because the <external_mutex> must be
+ // locked by the caller.
cv->waiters_++;
+ int result = 0;
+ int error = 0;
+
+ // We keep the lock held just long enough to increment the count of
+ // waiters by one. Note that we can't keep it held across the call
+ // to ACE_OS::sema_wait() since that will deadlock other calls to
+ // ACE_OS::cond_signal().
if (ACE_OS::thread_mutex_unlock (external_mutex) != 0)
return -1;
- int result = 0;
- int error = 0;
+ // Wait to be awakened by a ACE_OS::cond_signal() or
+ // ACE_OS::cond_broadcast().
+ result = ::WaitForSingleObject (cv->sema_, INFINITE);
- if (ACE_OS::sema_wait (&cv->sema_) != 0)
+ if (result != WAIT_OBJECT_0)
+ // This is a hack, we need to find an appropriate mapping...
+ error = result == WAIT_TIMEOUT ? ETIME : ::GetLastError ();
+ else
{
- result = -1;
- error = errno;
+ // If we are broadcasting, then we need to be smarter about
+ // locking since there can now be multiple threadsd in the
+ // crtical section. If we are signaling, however, we don't have
+ // to worry since there will just be 1 thread here.
+ if (cv->was_broadcast_)
+ {
+ if (ACE_OS::thread_mutex_lock (cv->waiters_lock_) != -1)
+ {
+ // By making the waiter responsible for decrementing its count we
+ // don't have to worry about having an internal mutex. Thanks to
+ // Karlheinz for recognizing this optimization.
+ cv->waiters_--;
+ // Release the signaler/broadcaster if we're the last waiter.
+ if (cv->waiters_ == 0)
+ ::SetEvent (cv->waiters_done_);
+ ACE_OS::thread_mutex_unlock (cv->internal_mutex_);
+ }
+ }
+ else
+ cv->waiters_--;
}
-
- // We must always regain the mutex, even when errors occur.
+ // We must always regain the external mutex, even when errors
+ // occur because that's the guarantee that we give to our
+ // callers.
ACE_OS::thread_mutex_lock (external_mutex);
- cv->waiters_--;
-
// Reset errno in case mutex_lock() also fails...
errno = error;
return result;
-
#endif /* ACE_HAS_STHREADS */
#else
ACE_NOTSUP_RETURN (-1);
@@ -3467,7 +3536,7 @@ ACE_OS::thr_sigsetmask (int how,
ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::pthread_sigmask (how, nsm, osm),
ace_result_), int, -1);
#elif defined (ACE_HAS_PTHREADS) && !defined (ACE_HAS_FSU_PTHREADS)
-#if defined (ACE_HAS_IRIX62_THREADS)
+#if defined (ACE_HAS_IRIX62_THREADS) || defined (ACE_HAS_PTHREADS_XAVIER)
ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::pthread_sigmask (how, nsm, osm),
ace_result_),int, -1);
#else
@@ -3592,7 +3661,9 @@ ACE_OS::thr_self (ACE_hthread_t &self)
{
// ACE_TRACE ("ACE_OS::thr_self");
#if defined (ACE_HAS_THREADS)
-#if defined (ACE_HAS_THREAD_SELF)
+#if defined (ACE_HAS_DCETHREADS)
+ self = ::pthread_self ();
+#elif defined (ACE_HAS_THREAD_SELF)
self = ::thread_self ();
#elif defined (ACE_HAS_PTHREADS) || defined (ACE_HAS_SETKIND_NP)
self = ::pthread_self ();
@@ -3662,8 +3733,9 @@ ACE_OS::thr_setprio (ACE_hthread_t thr_id, int prio)
#elif (defined (ACE_HAS_DCETHREADS) || defined (ACE_HAS_PTHREADS)) && !defined (ACE_LACKS_SETSCHED)
struct sched_param param;
int result;
+ int policy = 0;
- ACE_OSCALL (ACE_ADAPT_RETVAL (::pthread_setschedparam (thr_id, policy, &param), result), int, -1, result);
+ ACE_OSCALL (ACE_ADAPT_RETVAL (::pthread_setschedparam (thr_id, &policy, &param), result), int, -1, result);
prio = param.sched_priority;
return result;
ACE_NOTSUP_RETURN (-1);
diff --git a/ace/Proactor.cpp b/ace/Proactor.cpp
index 0484a7e31b7..7229d2ac8c4 100644
--- a/ace/Proactor.cpp
+++ b/ace/Proactor.cpp
@@ -245,14 +245,14 @@ ACE_Proactor::schedule_timer (ACE_Event_Handler *handler,
#define ACE_TIMEOUT_OCCURRED 258
int
-ACE_Proactor::handle_events (ACE_Time_Value *how_long)
+ACE_Proactor::handle_events (ACE_Time_Value *max_wait_time)
{
// Stash the current time -- the destructor of this object will
// automatically compute how much time elapsed since this method was
// called.
- ACE_Countdown_Time countdown (how_long);
+ ACE_Countdown_Time countdown (max_wait_time);
- how_long = timer_queue_->calculate_timeout (how_long);
+ max_wait_time = timer_queue_->calculate_timeout (max_wait_time);
ACE_Overlapped_IO *overlapped = 0;
u_long bytes_transferred = 0;
@@ -260,7 +260,7 @@ ACE_Proactor::handle_events (ACE_Time_Value *how_long)
int error = 0;
#if defined (ACE_WIN32)
ACE_HANDLE io_handle = ACE_INVALID_HANDLE;
- int timeout = how_long == 0 ? INFINITE : how_long->msec ();
+ int timeout = max_wait_time == 0 ? INFINITE : max_wait_time->msec ();
BOOL result = 0;
diff --git a/ace/Proactor.h b/ace/Proactor.h
index 7d85e12fd03..af2431cc1eb 100644
--- a/ace/Proactor.h
+++ b/ace/Proactor.h
@@ -64,7 +64,7 @@ public:
// = Initialization and termination methods.
ACE_Proactor (size_t number_of_threads = 0, ACE_Timer_Queue *tq = 0);
- // Initialize a proactor. -number_of_threads- is passed to
+ // Initialize a proactor. <number_of_threads> is passed to
// CreateIoCompletionPort.
~ACE_Proactor (void);
@@ -83,15 +83,15 @@ public:
// integrate I/O completion ports with the ReactorEx.
// = Event loop methods.
- virtual int handle_events (ACE_Time_Value *how_long = 0);
- virtual int handle_events (ACE_Time_Value &how_long);
- // Main event loop driver that blocks for -how_long- before
+ virtual int handle_events (ACE_Time_Value *max_wait_time = 0);
+ virtual int handle_events (ACE_Time_Value &max_wait_time);
+ // Main event loop driver that blocks for <max_wait_time> before
// returning (will return earlier if I/O or signal events occur).
- // Note that -how_long- can be 0, in which case this method blocks
+ // Note that <max_wait_time> can be 0, in which case this method blocks
// until I/O events or signals occur. handle_events just blocks
// on GetQueuedCompletionStatus at completion_port_. When I/O
// completions arrive, it calls back the Event_Handler associated
- // with completed I/O operation. Returns 0 if -how_long- elapses
+ // with completed I/O operation. Returns 0 if <max_wait_time> elapses
// before an event occurs, 1 when if an event occured, and -1 on
// failure.
diff --git a/ace/README b/ace/README
index 01b65c546cb..a5be0ad87dc 100644
--- a/ace/README
+++ b/ace/README
@@ -132,6 +132,7 @@ ACE_HAS_XLI Platform has the XLI version of TLI
ACE_HAS_XT Platform has Xt and Motif
ACE_HAS_YIELD_VOID_PTR Platform requires pthread_yield() to take a NULL.
ACE_LACKS_CONST_TIMESPEC_PTR Platform forgot const in cond_timewait (e.g., HP/UX).
+ACE_LACKS_COND_T Platform lacks condition variables (e.g., Win32 and VxWorks)
ACE_LACKS_CONDATTR_PSHARED Platform has no implementation of pthread_condattr_setpshared(), even though it supports pthreads!
ACE_LACKS_MADVISE Platform lacks madvise() (e.g., Linux)
ACE_LACKS_MALLOC_H Platform lacks malloc.h
@@ -146,6 +147,7 @@ ACE_LACKS_POSIX_PROTO Platform lacks POSIX prototypes for certain System V fun
ACE_LACKS_PTHREAD_THR_SIGSETMASK Platform lacks pthread_thr_sigsetmask (e.g., MVS, HP/UX, and OSF/1 3.2)
ACE_LACKS_RECVMSG Platform lacks recvmsg() (e.g., Linux)
ACE_LACKS_RPC_H Platform lacks the ONC RPC header files.
+ACE_LACKS_RWLOCK_T Platform lacks readers/writer locks.
ACE_LACKS_SBRK Platform lacks a working sbrk() (e.g., Win32 and VxWorks)
ACE_LACKS_SEMBUF_T Platform lacks struct sembuf (e.g., Win32 and VxWorks)
ACE_LACKS_SETDETACH Platform lacks pthread_attr_setdetachstate() (e.g., HP/UX 10.x)
@@ -161,6 +163,7 @@ ACE_LACKS_STRRECVFD Platform doesn't define struct strrecvfd.
ACE_LACKS_SYSCALL Platform doesn't have syscall() prototype
ACE_LACKS_SYSV_MSQ_PROTOS Platform doesn't have prototypes for Sys V msg()* queues.
ACE_LACKS_T_ERRNO Header files lack t_errno for TLI
+ACE_LACKS_THREAD_STACK_SIZE Platform lacks pthread_attr_setstacksize() (e.g., Linux pthreads)
ACE_LACKS_UCONTEXT_H Platform lacks the ucontext.h file
ACE_LACKS_UNIX_DOMAIN_SOCKETS ACE platform has no UNIX domain sockets
ACE_LACKS_UTSNAME_T Platform lacks struct utsname (e.g., Win32 and VxWorks)
diff --git a/ace/ReactorEx.cpp b/ace/ReactorEx.cpp
index 21bcc46f161..9215d3d815e 100644
--- a/ace/ReactorEx.cpp
+++ b/ace/ReactorEx.cpp
@@ -120,18 +120,19 @@ ACE_ReactorEx::schedule_timer (ACE_Event_Handler *handler,
}
// Waits for and dispatches all events. Returns -1 on error, 0 if
-// how_long expired, and 1 if events were dispatched.
+// max_wait_time expired, and 1 if events were dispatched.
int
-ACE_ReactorEx::handle_events (ACE_Time_Value *how_long,
+ACE_ReactorEx::handle_events (ACE_Time_Value *max_wait_time,
int wait_all,
- ACE_Event_Handler *wait_all_callback)
+ ACE_Event_Handler *wait_all_callback,
+ int alertable)
{
ACE_TRACE ("ACE_ReactorEx::handle_events");
// Stash the current time -- the destructor of this object will
// automatically compute how much time elapsed since this method was
// called.
- ACE_Countdown_Time countdown (how_long);
+ ACE_Countdown_Time countdown (max_wait_time);
#if defined (ACE_MT_SAFE)
ACE_GUARD_RETURN (ACE_ReactorEx_Token, ace_mon, this->token_, -1);
@@ -148,16 +149,26 @@ ACE_ReactorEx::handle_events (ACE_Time_Value *how_long,
}
// Check for pending timeout events.
- ACE_Time_Value *wait_time = timer_queue_->calculate_timeout (how_long);
+ ACE_Time_Value *wait_time = timer_queue_->calculate_timeout (max_wait_time);
// Translate into Win32 time value.
int timeout = wait_time == 0 ? INFINITE : wait_time->msec ();
+ DWORD wait_status;
// Wait for any of handles_ to be active, or until timeout expires.
// If wait_all is true, then wait for all handles_ to be active.
- DWORD wait_status = ::WaitForMultipleObjects (active_handles_,
- handles_,
- wait_all,
- timeout);
+
+ if (alertable)
+ // Allow asynchronous completion of ReadFileEx and WriteFileEx
+ // operations.
+ wait_status= ::WaitForMultipleObjectsEx (active_handles_,
+ handles_,
+ wait_all,
+ timeout);
+ else
+ wait_status= ::WaitForMultipleObjects (active_handles_,
+ handles_,
+ wait_all,
+ timeout);
// Expire all pending timers.
this->timer_queue_->expire ();
diff --git a/ace/ReactorEx.h b/ace/ReactorEx.h
index 6c4ec881b8a..ef72259970f 100644
--- a/ace/ReactorEx.h
+++ b/ace/ReactorEx.h
@@ -61,11 +61,10 @@ private:
class ACE_Export ACE_ReactorEx_Notify : public ACE_Event_Handler
// = TITLE
- // Unblock the <ACE_ReactorEx> from its event loop, passing it an
- // optional <ACE_Event_Handler> to dispatch.
+ // Unblock the <ACE_ReactorEx> from its event loop, passing it an
+ // optional <ACE_Event_Handler> to dispatch.
//
// = DESCRIPTION
- //
// This implementation is necessary for cases where the
// <ACE_ReactorEx> is run in a multi-threaded program. In this
// case, we need to be able to unblock WaitForMultipleObjects()
@@ -130,61 +129,73 @@ public:
virtual ~ACE_ReactorEx (void);
// Close down the ReactorEx and release all of its resources.
- // = Event loop drivers. Main event loop driver that blocks for
- // -how_long- before returning (will return earlier if I/O or signal
- // events occur). Note that -how_long- can be 0, in which case this
- // method blocks until I/O events or signals occur. Returns 0 if
- // timed out, 1 if an event occurred, and -1 if an error occured.
- // -how_long- is decremented to reflect how much time the call to
- // handle_events took. For instance, if a time value of 3 seconds
- // is passed to handle_events and an event occurs after 2 seconds,
- // -how_long- will equal 1 second. This can be used if an
- // application wishes to handle events for some fixed amount of
- // time. If wait_all is TRUE, then handle_events will only dispatch
- // the handlers if *all* handles become active. If a timeout
- // occurs, then no handlers will be dispatched. If
- // <wait_all_callback> is NULL then we dispatch the <handle_signal>
- // method on each and every HANDLE in the dispatch array.
- // Otherwise, we just call back the <handle_signal> method of the
- // <wait_all_callback> object, after first assigning the siginfo_t
- // <si_handles_> argument to point to the array of signaled handles.
- virtual int handle_events (ACE_Time_Value *how_long = 0,
+ // = Event loop drivers.
+
+ virtual int handle_events (ACE_Time_Value *max_wait_time = 0,
int wait_all = 0,
- ACE_Event_Handler *wait_all_callback = 0);
- virtual int handle_events (ACE_Time_Value &how_long,
+ ACE_Event_Handler *wait_all_callback = 0,
+ int alertable = 0);
+ // This event loop driver blocks for up to <max_wait_time> for I/O
+ // or signaled events occur. Note that <max_wait_time> can be 0, in
+ // which case this method blocks until I/O events or signaled events
+ // occur. Returns 0 if timed out, 1 if an event occurred, and -1 if
+ // an error occured. <max_wait_time> is decremented to reflect how
+ // much time this call took. For instance, if a time value of 3
+ // seconds is passed to handle_events and an event occurs after 2
+ // seconds, <max_wait_time> will equal 1 second. This can be used
+ // if an application wishes to handle events for some fixed amount
+ // of time.
+ //
+ // If <wait_all> is TRUE, then handle_events will only dispatch the
+ // handlers if *all* handles become active. If a timeout occurs,
+ // then no handlers will be dispatched. If <wait_all_callback> is 0
+ // then we dispatch the <handle_signal> method on each and every
+ // registered HANDLE. Otherwise, we just call back the
+ // <handle_signal> method of the <wait_all_callback> object, after
+ // first assigning the siginfo_t <si_handles_> argument to point to
+ // the array of signaled handles.
+ //
+ // If <alertable> is true, then <WaitForMultipleObjectsEx> is used
+ // as the demultiplexing call, otherwise <WaitForMultipleObjects> is
+ // used.
+
+ virtual int handle_events (ACE_Time_Value &max_wait_time,
int wait_all = 0,
- ACE_Event_Handler *wait_all_callback = 0);
+ ACE_Event_Handler *wait_all_callback = 0,
+ int alertable = 0);
+ // This method is just like the one above, except the <max_wait_time>
+ // value is a reference and must therefore never be NULL.
// = Register and remove Handlers.
virtual int register_handler (ACE_Event_Handler *eh,
ACE_HANDLE handle = ACE_INVALID_HANDLE);
- // Register an Event_Handler -eh-. If handle == ACE_INVALID_HANDLE
- // the ReactorEx will call eh->get_handle() to extract the
- // underlying I/O handle).
+ // Register an Event_Handler <eh>. If handle == ACE_INVALID_HANDLE
+ // the <ReactorEx> will call the <get_handle> method of <eh> to
+ // extract the underlying I/O handle.
virtual int remove_handler (ACE_Event_Handler *eh,
ACE_Reactor_Mask mask = 0);
- // Removes -eh- from the ReactorEx. Note that the ReactorEx will
- // call eh->get_handle() to extract the underlying I/O handle. If
- // -mask- == ACE_Event_Handler::DONT_CALL then the -handle_close-
- // method of the -eh- is not invoked.
+ // Removes <eh> from the ReactorEx. Note that the ReactorEx will
+ // call the <get_handle> method of <eh> to extract the underlying
+ // I/O handle. If <mask> == ACE_Event_Handler::DONT_CALL then the
+ // <handle_close> method of the <eh> is not invoked.
int notify (ACE_Event_Handler * = 0,
ACE_Reactor_Mask = ACE_Event_Handler::EXCEPT_MASK);
// Wakeup <ACE_ReactorEx> if currently blocked in
- // WaitForMultipleObjects().
+ // <WaitForMultipleObjects>.
// = Timer management.
virtual int schedule_timer (ACE_Event_Handler *eh,
const void *arg,
const ACE_Time_Value &delta,
const ACE_Time_Value &interval = ACE_Time_Value::zero);
- // Schedule an Event Handler -eh- that will expire after -delta-
- // amount of time. If it expires then -arg- is passed in as the
- // value to eh->handle_timeout. If -interval- is != to
- // ACE_Time_Value::zero then it is used to reschedule -eh-
+ // Schedule an Event Handler <eh> that will expire after <delta>
+ // amount of time. If it expires then <arg> is passed in as the
+ // value to <handle_timeout> method call on <eh>. If <interval> is
+ // != to ACE_Time_Value::zero then it is used to reschedule <eh>
// automatically. This method returns a timer handle that uniquely
- // identifies the -eh- in an internal list. This timer handle can
+ // identifies the <eh> in an internal list. This timer handle can
// be used to cancel an Event_Handler before it expires. The
// cancellation ensures that timer_ids are unique up to values of
// greater than 2 billion timers. As long as timers don't stay
@@ -193,10 +204,10 @@ public:
virtual int cancel_timer (ACE_Event_Handler *event_handler);
// Cancel all Event_Handlers that match the address of
- // -event_handler-.
+ // <event_handler>.
virtual int cancel_timer (int timer_id, const void **arg = 0);
- // Cancel the single Event_Handler that matches the -timer_id- value
+ // Cancel the single Event_Handler that matches the <timer_id> value
// (which was returned from the schedule method). If arg is
// non-NULL then it will be set to point to the ``magic cookie''
// argument passed in when the Event_Handler was registered. This
@@ -210,7 +221,7 @@ public:
protected:
int dispatch (size_t index);
- // Dispatches any active handles from handles_[-index-] to
+ // Dispatches any active handles from handles_[<index>] to
// handles_[active_handles_] using <WaitForMultipleObjects> to poll
// through our handle set looking for active handles.
diff --git a/ace/ReactorEx.i b/ace/ReactorEx.i
index fda66981674..a5cd53034a2 100644
--- a/ace/ReactorEx.i
+++ b/ace/ReactorEx.i
@@ -20,9 +20,12 @@ ACE_ReactorEx::cancel_timer (int timer_id,
ACE_INLINE int
ACE_ReactorEx::handle_events (ACE_Time_Value &how_long,
- int wait_all)
+ int wait_all,
+ ACE_Event_Handler *wait_all_callback,
+ int alertable)
{
- return this->handle_events (&how_long, wait_all);
+ return this->handle_events (&how_long, wait_all,
+ wait_all_callback, alertable);
}
#endif /* ACE_WIN32 */
diff --git a/ace/SV_Semaphore_Complex.cpp b/ace/SV_Semaphore_Complex.cpp
index 09aac60b0bf..1bcd3d64cec 100644
--- a/ace/SV_Semaphore_Complex.cpp
+++ b/ace/SV_Semaphore_Complex.cpp
@@ -103,12 +103,11 @@ ACE_SV_Semaphore_Complex::open (key_t k,
// Get the value of the process counter. If it equals 0, then no
// one has initialized the ACE_SV_Semaphore yet.
- int semval;
+ int semval = ACE_SV_Semaphore_Simple::control (GETVAL, 0, 1);
- if ((semval = ACE_SV_Semaphore_Simple::control (GETVAL, 0, 1)) < 0)
+ if (semval == -1)
return this->init ();
-
- if (semval == 0)
+ else if (semval == 0)
{
// We should initialize by doing a SETALL, but that would
// clear the adjust value that we set when we locked the
diff --git a/ace/SV_Semaphore_Simple.cpp b/ace/SV_Semaphore_Simple.cpp
index 29d97dfa8a3..f7a6809dbb2 100644
--- a/ace/SV_Semaphore_Simple.cpp
+++ b/ace/SV_Semaphore_Simple.cpp
@@ -121,26 +121,26 @@ ACE_SV_Semaphore_Simple::name_2_key (const char *name)
{
ACE_TRACE ("ACE_SV_Semaphore_Simple::name_2_key");
- if (name == 0 || !isalpha (*name))
+ if (name == 0)
{
errno = EINVAL;
return ACE_INVALID_SEM_KEY;
}
-
- // The key is the character value of the first LUSED chars from name
- // placed in proto.
+ else
+ {
+ // Basically "hash" the values in the <name>. This won't
+ // necessarily guarantee uniqueness of all keys.
- u_long proto = 0;
+ u_long proto = 0;
- for (int i = 0; i < LUSED; ++i)
- {
- if (*name == '\0')
- break;
- proto <<= 8;
- proto |= *name++ & 0xff;
- }
+ for (int i = 0; name[i] != '\0'; ++i)
+ {
+ proto <<= 8;
+ proto |= *name++ & 0xff;
+ }
- return (key_t) proto;
+ return (key_t) proto;
+ }
}
// Open or create a ACE_SV_Semaphore. We return 1 if all is OK, else
diff --git a/ace/SV_Semaphore_Simple.i b/ace/SV_Semaphore_Simple.i
index 1e159f36604..a66806507f2 100644
--- a/ace/SV_Semaphore_Simple.i
+++ b/ace/SV_Semaphore_Simple.i
@@ -6,9 +6,6 @@
#include "ace/SV_Semaphore_Simple.h"
#include "ace/Trace.h"
-#undef LUSED
-#define LUSED 4 /* # of chars used from name */
-
inline int
ACE_SV_Semaphore_Simple::control (int cmd,
semun arg,
diff --git a/ace/Signal.cpp b/ace/Signal.cpp
index 50071e83619..bceff59af42 100644
--- a/ace/Signal.cpp
+++ b/ace/Signal.cpp
@@ -29,7 +29,10 @@ static ACE_SignalHandler ace_signal_handler_dispatcher = ACE_SignalHandler (ace_
static ACE_SignalHandler ace_signal_handlers_dispatcher = ACE_SignalHandler (ace_sig_handlers_dispatch);
#else
static ACE_SignalHandler ace_signal_handler_dispatcher = ACE_SignalHandler (ACE_Sig_Handler::dispatch);
+
+#if !defined (HPUX)
static ACE_SignalHandler ace_signal_handlers_dispatcher = ACE_SignalHandler (ACE_Sig_Handlers::dispatch);
+#endif /* HPUX */
#endif /* ACE_HAS_SIG_C_FUNC */
#if defined (ACE_MT_SAFE)
@@ -331,9 +334,9 @@ ACE_Sig_Adapter::handle_signal (int signum,
// ----------------------------------------
// The following classes are local to this file.
-// HPUX sucks big time!
+// There are bugs with HP/UX's C++ compiler that prevents this stuff
+// from compiling...
#if !defined (HPUX)
-// This needs to be fixed...
#define ACE_MAX_SIGNAL_HANDLERS size_t (20)
// Keeps track of the id that uniquely identifies each registered
diff --git a/ace/Signal.h b/ace/Signal.h
index f627bd73222..f95703de081 100644
--- a/ace/Signal.h
+++ b/ace/Signal.h
@@ -271,7 +271,6 @@ private:
// This is a normal C function.
};
-// HPUX sucks big time!
#if !defined (HPUX)
class ACE_Export ACE_Sig_Handlers : public ACE_Sig_Handler
// = TITLE
diff --git a/ace/Synch.cpp b/ace/Synch.cpp
index c8fb75545ab..b163eecc7a6 100644
--- a/ace/Synch.cpp
+++ b/ace/Synch.cpp
@@ -16,9 +16,36 @@
ACE_ALLOC_HOOK_DEFINE(ACE_Null_Mutex)
ACE_ALLOC_HOOK_DEFINE(ACE_File_Lock)
ACE_ALLOC_HOOK_DEFINE(ACE_RW_Process_Mutex)
-
ACE_ALLOC_HOOK_DEFINE(ACE_Process_Mutex)
+ACE_TSS_Adapter::ACE_TSS_Adapter (void *object, ACE_THR_DEST f)
+ : ts_obj_ (object),
+ func_ (f)
+{
+ // ACE_TRACE ("ACE_TSS_Adapter::ACE_TSS_Adapter");
+}
+
+void
+ACE_TSS_Adapter::cleanup (void)
+{
+ // ACE_TRACE ("ACE_TSS_Adapter::~ACE_TSS_Adapter");
+ (*this->func_)(this->ts_obj_); // call cleanup routine for ts_obj_
+}
+
+extern "C" void
+ACE_TSS_C_cleanup (void *object)
+{
+ // ACE_TRACE ("ACE_TSS_C_cleanup");
+ if (object != 0)
+ {
+ ACE_TSS_Adapter *tss_adapter = (ACE_TSS_Adapter *) object;
+ // Perform cleanup on the real TS object.
+ tss_adapter->cleanup ();
+ // Delete the adapter object.
+ delete tss_adapter;
+ }
+}
+
void
ACE_Process_Mutex::dump (void) const
{
@@ -297,8 +324,6 @@ ACE_Mutex::~ACE_Mutex (void)
ACE_ERROR ((LM_ERROR, "%p\n", "ACE_Mutex::~ACE_Mutex"));
}
-#if defined (ACE_HAS_THREADS)
-
ACE_Event::ACE_Event (int manual_reset,
int initial_state,
int type,
@@ -406,6 +431,8 @@ ACE_Auto_Event::dump (void) const
ACE_Event::dump ();
}
+#if defined (ACE_HAS_THREADS)
+
ACE_ALLOC_HOOK_DEFINE(ACE_Recursive_Thread_Mutex)
ACE_ALLOC_HOOK_DEFINE(ACE_Thread_Mutex_Guard)
diff --git a/ace/Synch.h b/ace/Synch.h
index 0e2aba63078..1c0c5335b87 100644
--- a/ace/Synch.h
+++ b/ace/Synch.h
@@ -490,7 +490,35 @@ protected:
ACE_Null_Mutex_Guard (const ACE_Null_Mutex_Guard &) {}
};
-#if defined (ACE_HAS_THREADS) /* ACE platform supports some form of threading. */
+class ACE_TSS_Adapter
+ // = TITLE
+ // This class encapsulates a TSS object and its associated
+ // C++ destructor function. It is used by the ACE_TSS...
+ // methods (in Synch_T.cpp) in order to allow an extern
+ // "C" cleanup routine to be used. Needed by the "frigging"
+ // MVS C++ compiler.
+ //
+ // = DESCRIPTION
+ // Objects of this class are stored in thread specific
+ // storage. ts_obj_ points to the "real" object and
+ // func_ is a pointer to the C++ cleanup function for ts_obj_.
+ //
+{
+public:
+ ACE_TSS_Adapter (void *object, ACE_THR_DEST f);
+ // Initialize the adapter.
+
+ void cleanup (void);
+ // Perform the cleanup operation.
+
+//private:
+
+ void *ts_obj_;
+ // The real TS object.
+
+ ACE_THR_DEST func_;
+ // The real cleanup routine for ts_obj;
+};
class ACE_Export ACE_Event
// = TITLE
@@ -610,6 +638,8 @@ public:
// Declare the dynamic allocation hooks
};
+#if defined (ACE_HAS_THREADS) /* ACE platform supports some form of threading. */
+
class ACE_Export ACE_Thread_Mutex
// = TITLE
// ACE_Thread_Mutex wrapper (only valid for threads in the same
diff --git a/ace/Synch_T.cpp b/ace/Synch_T.cpp
index 4357c9702a3..60e0b02908f 100644
--- a/ace/Synch_T.cpp
+++ b/ace/Synch_T.cpp
@@ -246,6 +246,13 @@ ACE_TSS<TYPE>::dump (void) const
}
#if defined (ACE_HAS_THREADS) && defined (ACE_HAS_THREAD_SPECIFIC_STORAGE)
+template <class TYPE> void
+ACE_TSS<TYPE>::cleanup (void *ptr)
+{
+ // Cast this to the concrete TYPE * so the destructor gets called.
+ delete (TYPE *) ptr;
+}
+
template <class TYPE>
ACE_TSS<TYPE>::ACE_TSS (TYPE *ts_obj)
: once_ (0),
@@ -262,7 +269,11 @@ ACE_TSS<TYPE>::ACE_TSS (TYPE *ts_obj)
ACE_ASSERT (this->once_ == 0);
if (ACE_Thread::keycreate (&this->key_,
- &ACE_TSS<TYPE>::cleanup,
+#if defined (ACE_HAS_THR_C_DEST)
+ &ACE_TSS_C_cleanup,
+#else
+ &ACE_TSS<TYPE>::cleanup,
+#endif /* ACE_HAS_THR_C_DEST */
(void *) this) != 0)
{
int errnum = errno;
@@ -274,8 +285,22 @@ ACE_TSS<TYPE>::ACE_TSS (TYPE *ts_obj)
this->once_ = 1;
+#if defined (ACE_HAS_THR_C_DEST)
+ // Encapsulate a ts_obj and it's destructor in an ACE_TSS_Adapter
+ ACE_TSS_Adapter *tss_adapter;
+ ACE_NEW (tss_adapter,
+ ACE_TSS_Adapter ((void *)ts_obj, ACE_TSS<TYPE>::cleanup));
+
+ // Put the adapter in thread specific storage
+ if (ACE_Thread::setspecific (this->key_, (void *) tss_adapter) != 0)
+ {
+ delete tss_adapter;
+ ACE_ERROR ((LM_ERROR, "%p\n", "ACE_Thread::setspecific() failed!"));
+ }
+#else
if (ACE_Thread::setspecific (this->key_, (void *) ts_obj) != 0)
- ACE_ERROR ((LM_ERROR, "%p\n", "ACE_Thread::setspecific() failed!"));
+ ACE_ERROR ((LM_ERROR, "%p\n", "ACE_Thread::setspecific() failed!"));
+#endif /* ACE_HAS_THR_C_DEST */
}
}
@@ -293,8 +318,12 @@ ACE_TSS<TYPE>::ts_get (void) const
if (this->once_ == 0)
{
if (ACE_Thread::keycreate ((ACE_thread_key_t *) &this->key_,
- &ACE_TSS<TYPE>::cleanup,
- (void *) this) != 0)
+#if defined (ACE_HAS_THR_C_DEST)
+ &ACE_TSS_C_cleanup,
+#else
+ &ACE_TSS<TYPE>::cleanup,
+#endif /* ACE_HAS_THR_C_DEST */
+ (void *) this) != 0)
return 0; // Major problems, this should *never* happen!
else
// This *must* come last to avoid race conditions! Note
@@ -305,6 +334,16 @@ ACE_TSS<TYPE>::ts_get (void) const
TYPE *ts_obj = 0;
+#if defined (ACE_HAS_THR_C_DEST)
+ ACE_TSS_Adapter *tss_adapter = 0;
+
+ // Get the adapter from thread-specific storage
+ if (ACE_Thread::getspecific (this->key_, (void **) &tss_adapter) == -1)
+ return 0; // This should not happen!
+
+ // Check to see if this is the first time in for this thread.
+ if (tss_adapter == 0)
+#else
// Get the ts_obj from thread-specific storage. Note that no locks
// are required here...
if (ACE_Thread::getspecific (this->key_, (void **) &ts_obj) == -1)
@@ -312,6 +351,7 @@ ACE_TSS<TYPE>::ts_get (void) const
// Check to see if this is the first time in for this thread.
if (ts_obj == 0)
+#endif /* ACE_HAS_THR_C_DEST */
{
// Allocate memory off the heap and store it in a pointer in
// thread-specific storage (on the stack...).
@@ -321,6 +361,19 @@ ACE_TSS<TYPE>::ts_get (void) const
if (ts_obj == 0)
return 0;
+#if defined (ACE_HAS_THR_C_DEST)
+ // Encapsulate a ts_obj and it's destructor in an ACE_TSS_Adapter
+ ACE_NEW_RETURN (tss_adapter,
+ ACE_TSS_Adapter (ts_obj, ACE_TSS<TYPE>::cleanup), 0);
+
+ // Put the adapter in thread specific storage
+ if (ACE_Thread::setspecific (this->key_, (void *) tss_adapter) != 0)
+ {
+ delete tss_adapter;
+ delete ts_obj;
+ return 0; // Major problems, this should *never* happen!
+ }
+#else
// Store the dynamically allocated pointer in thread-specific
// storage.
if (ACE_Thread::setspecific (this->key_, (void *) ts_obj) != 0)
@@ -328,9 +381,14 @@ ACE_TSS<TYPE>::ts_get (void) const
delete ts_obj;
return 0; // Major problems, this should *never* happen!
}
+#endif /* ACE_HAS_THR_C_DEST */
}
+#if defined (ACE_HAS_THR_C_DEST)
+ return (TYPE *) tss_adapter->ts_obj_; // return the underlying ts object
+#else
return ts_obj;
+#endif /* ACE_HAS_THR_C_DEST */
}
// Get the thread-specific object for the key associated with this
@@ -348,11 +406,20 @@ ACE_TSS<TYPE>::ts_object (void) const
else
{
TYPE *ts_obj = 0;
+#if defined (ACE_HAS_THR_C_DEST)
+ ACE_TSS_Adapter *tss_adapter = 0;
+ // Get the tss adapter from thread-specific storage
+ if (ACE_Thread::getspecific (this->key_, (void **) &tss_adapter) == -1)
+ return 0; // This should not happen!
+ else if (tss_adapter != 0)
+ // Extract the real TS object.
+ ts_obj = (TYPE *) tss_adapter->ts_obj_;
+#else
if (ACE_Thread::getspecific (this->key_, (void **) &ts_obj) == -1)
return 0; // This should not happen!
- else
- return ts_obj;
+#endif /* ACE_HAS_THR_C_DEST */
+ return ts_obj;
}
}
@@ -368,23 +435,38 @@ ACE_TSS<TYPE>::ts_object (TYPE *new_ts_obj)
{
TYPE *ts_obj = 0;
+#if defined (ACE_HAS_THR_C_DEST)
+ ACE_TSS_Adapter *tss_adapter = 0;
+
+ if (ACE_Thread::getspecific (this->key_, (void **) &tss_adapter) == -1)
+ return 0; // This should not happen!
+
+ if (tss_adapter != 0)
+ {
+ ts_obj = (TYPE *) tss_adapter->ts_obj_;
+ delete tss_adapter; // don't need this anymore
+ }
+
+ ACE_NEW_RETURN (tss_adapter,
+ ACE_TSS_Adapter ((void *)new_ts_obj, ACE_TSS<TYPE>::cleanup),
+ 0);
+
+ if (ACE_Thread::setspecific (this->key_, (void *) tss_adapter) == -1)
+ {
+ delete tss_adapter;
+ return ts_obj; // This should not happen!
+ }
+#else
if (ACE_Thread::getspecific (this->key_, (void **) &ts_obj) == -1)
- return 0; // This should not happen!
+ return 0; // This should not happen!
if (ACE_Thread::setspecific (this->key_, (void *) new_ts_obj) == -1)
- return ts_obj; // This should not happen!
+ return ts_obj; // This should not happen!
+#endif /* ACE_HAS_THR_C_DEST */
else
return ts_obj;
}
}
-/* static */
-template <class TYPE> void
-ACE_TSS<TYPE>::cleanup (void *ptr)
-{
- // This cast is necessary to invoke the destructor (if necessary).
- delete (TYPE *) ptr;
-}
-
ACE_ALLOC_HOOK_DEFINE(ACE_TSS_Guard)
template <class LOCK> void
@@ -405,7 +487,11 @@ ACE_TSS_Guard<LOCK>::init_key (void)
this->key_ = ACE_OS::NULL_key;
ACE_Thread::keycreate (&this->key_,
+#if defined (ACE_HAS_THR_C_DEST)
+ &ACE_TSS_C_cleanup,
+#else
&ACE_TSS_Guard<LOCK>::cleanup,
+#endif /* ACE_HAS_THR_C_DEST */
(void *) this);
}
@@ -422,7 +508,15 @@ ACE_TSS_Guard<LOCK>::release (void)
// ACE_TRACE ("ACE_TSS_Guard<LOCK>::release");
ACE_Guard<LOCK> *guard = 0;
+
+#if defined (ACE_HAS_THR_C_DEST)
+ ACE_TSS_Adapter *tss_adapter = 0;
+ ACE_Thread::getspecific (this->key_, (void **) &tss_adapter);
+ guard = (ACE_Guard<LOCK> *)tss_adapter->ts_obj_;
+#else
ACE_Thread::getspecific (this->key_, (void **) &guard);
+#endif /* ACE_HAS_THR_C_DEST */
+
return guard->release ();
}
@@ -432,7 +526,15 @@ ACE_TSS_Guard<LOCK>::remove (void)
// ACE_TRACE ("ACE_TSS_Guard<LOCK>::remove");
ACE_Guard<LOCK> *guard = 0;
+
+#if defined (ACE_HAS_THR_C_DEST)
+ ACE_TSS_Adapter *tss_adapter = 0;
+ ACE_Thread::getspecific (this->key_, (void **) &tss_adapter);
+ guard = (ACE_Guard<LOCK> *)tss_adapter->ts_obj_;
+#else
ACE_Thread::getspecific (this->key_, (void **) &guard);
+#endif /* ACE_HAS_THR_C_DEST */
+
return guard->remove ();
}
@@ -442,7 +544,15 @@ ACE_TSS_Guard<LOCK>::~ACE_TSS_Guard (void)
// ACE_TRACE ("ACE_TSS_Guard<LOCK>::~ACE_TSS_Guard");
ACE_Guard<LOCK> *guard = 0;
+
+#if defined (ACE_HAS_THR_C_DEST)
+ ACE_TSS_Adapter *tss_adapter = 0;
+ ACE_Thread::getspecific (this->key_, (void **) &tss_adapter);
+ guard = (ACE_Guard<LOCK> *)tss_adapter->ts_obj_;
+#else
ACE_Thread::getspecific (this->key_, (void **) &guard);
+#endif /* ACE_HAS_THR_C_DEST */
+
// Make sure that this pointer is NULL when we shut down...
ACE_Thread::setspecific (this->key_, 0);
ACE_Thread::keyfree (this->key_);
@@ -467,7 +577,16 @@ ACE_TSS_Guard<LOCK>::ACE_TSS_Guard (LOCK &lock, int block)
this->init_key ();
ACE_Guard<LOCK> *guard;
ACE_NEW (guard, ACE_Guard<LOCK> (lock, block));
+
+#if defined (ACE_HAS_THR_C_DEST)
+ ACE_TSS_Adapter *tss_adapter;
+ ACE_NEW (tss_adapter,
+ ACE_TSS_Adapter ((void *) guard,
+ ACE_TSS_Guard<LOCK>::cleanup));
+ ACE_Thread::setspecific (this->key_, (void *) tss_adapter);
+#else
ACE_Thread::setspecific (this->key_, (void *) guard);
+#endif /* ACE_HAS_THR_C_DEST */
}
template <class LOCK> int
@@ -476,7 +595,15 @@ ACE_TSS_Guard<LOCK>::acquire (void)
// ACE_TRACE ("ACE_TSS_Guard<LOCK>::acquire");
ACE_Guard<LOCK> *guard = 0;
+
+#if defined (ACE_HAS_THR_C_DEST)
+ ACE_TSS_Adapter *tss_adapter = 0;
+ ACE_Thread::getspecific (this->key_, (void **) &tss_adapter);
+ guard = (ACE_Guard<LOCK> *) tss_adapter->ts_obj_;
+#else
ACE_Thread::getspecific (this->key_, (void **) &guard);
+#endif /* ACE_HAS_THR_C_DEST */
+
return guard->acquire ();
}
@@ -486,7 +613,15 @@ ACE_TSS_Guard<LOCK>::tryacquire (void)
// ACE_TRACE ("ACE_TSS_Guard<LOCK>::tryacquire");
ACE_Guard<LOCK> *guard = 0;
+
+#if defined (ACE_HAS_THR_C_DEST)
+ ACE_TSS_Adapter *tss_adapter = 0;
+ ACE_Thread::getspecific (this->key_, (void **) &tss_adapter);
+ guard = (ACE_Guard<LOCK> *) tss_adapter->ts_obj_;
+#else
ACE_Thread::getspecific (this->key_, (void **) &guard);
+#endif /* ACE_HAS_THR_C_DEST */
+
return guard->tryacquire ();
}
@@ -498,7 +633,16 @@ ACE_TSS_Write_Guard<LOCK>::ACE_TSS_Write_Guard (LOCK &lock, int block)
this->init_key ();
ACE_Guard<LOCK> *guard;
ACE_NEW (guard, ACE_Write_Guard<LOCK> (lock, block));
+
+#if defined (ACE_HAS_THR_C_DEST)
+ ACE_TSS_Adapter *tss_adapter;
+ ACE_NEW (tss_adapter,
+ ACE_TSS_Adapter ((void *) guard,
+ ACE_TSS_Guard<LOCK>::cleanup));
+ ACE_Thread::setspecific (this->key_, (void *) tss_adapter);
+#else
ACE_Thread::setspecific (this->key_, (void *) guard);
+#endif /* ACE_HAS_THR_C_DEST */
}
template <class LOCK> int
@@ -507,7 +651,15 @@ ACE_TSS_Write_Guard<LOCK>::acquire (void)
// ACE_TRACE ("ACE_TSS_Write_Guard<LOCK>::acquire");
ACE_Write_Guard<LOCK> *guard = 0;
+
+#if defined (ACE_HAS_THR_C_DEST)
+ ACE_TSS_Adapter *tss_adapter = 0;
+ ACE_Thread::getspecific (this->key_, (void **) &tss_adapter);
+ guard = (ACE_Guard<LOCK> *) tss_adapter->ts_obj_;
+#else
ACE_Thread::getspecific (this->key_, (void **) &guard);
+#endif /* ACE_HAS_THR_C_DEST */
+
return guard->acquire_write ();
}
@@ -517,7 +669,15 @@ ACE_TSS_Write_Guard<LOCK>::tryacquire (void)
// ACE_TRACE ("ACE_TSS_Write_Guard<LOCK>::tryacquire");
ACE_Write_Guard<LOCK> *guard = 0;
+
+#if defined (ACE_HAS_THR_C_DEST)
+ ACE_TSS_Adapter *tss_adapter = 0;
+ ACE_Thread::getspecific (this->key_, (void **) &tss_adapter);
+ guard = (ACE_Guard<LOCK> *) tss_adapter->ts_obj_;
+#else
ACE_Thread::getspecific (this->key_, (void **) &guard);
+#endif /* ACE_HAS_THR_C_DEST */
+
return guard->tryacquire_write ();
}
@@ -552,7 +712,16 @@ ACE_TSS_Read_Guard<LOCK>::ACE_TSS_Read_Guard (LOCK &lock, int block)
this->init_key ();
ACE_Guard<LOCK> *guard;
ACE_NEW (guard, ACE_Read_Guard<LOCK> (lock, block));
+
+#if defined (ACE_HAS_THR_C_DEST)
+ ACE_TSS_Adapter *tss_adapter;
+ ACE_NEW (tss_adapter,
+ ACE_TSS_Adapter ((void *)guard,
+ ACE_TSS_Guard<LOCK>::cleanup));
+ ACE_Thread::setspecific (this->key_, (void *) tss_adapter);
+#else
ACE_Thread::setspecific (this->key_, (void *) guard);
+#endif /* ACE_HAS_THR_C_DEST */
}
template <class LOCK> int
@@ -561,7 +730,15 @@ ACE_TSS_Read_Guard<LOCK>::acquire (void)
// ACE_TRACE ("ACE_TSS_Read_Guard<LOCK>::acquire");
ACE_Read_Guard<LOCK> *guard = 0;
+
+#if defined (ACE_HAS_THR_C_DEST)
+ ACE_TSS_Adapter *tss_adapter = 0;
+ ACE_Thread::getspecific (this->key_, (void **) &tss_adapter);
+ guard = (ACE_Guard<LOCK> *)tss_adapter->ts_obj_;
+#else
ACE_Thread::getspecific (this->key_, (void **) &guard);
+#endif /* ACE_HAS_THR_C_DEST */
+
return guard->acquire_read ();
}
@@ -571,7 +748,15 @@ ACE_TSS_Read_Guard<LOCK>::tryacquire (void)
// ACE_TRACE ("ACE_TSS_Read_Guard<LOCK>::tryacquire");
ACE_Read_Guard<LOCK> *guard = 0;
+
+#if defined (ACE_HAS_THR_C_DEST)
+ ACE_TSS_Adapter *tss_adapter = 0;
+ ACE_Thread::getspecific (this->key_, (void **) &tss_adapter);
+ guard = (ACE_Guard<LOCK> *) tss_adapter->ts_obj_;
+#else
ACE_Thread::getspecific (this->key_, (void **) &guard);
+#endif /* ACE_HAS_THR_C_DEST */
+
return guard->tryacquire_read ();
}
diff --git a/ace/Thread.h b/ace/Thread.h
index 8d71fb8a29d..bb5411e8b95 100644
--- a/ace/Thread.h
+++ b/ace/Thread.h
@@ -132,7 +132,11 @@ public:
// Change and/or examine calling thread's signal mask.
static int keycreate (ACE_thread_key_t *keyp,
+#if defined (ACE_HAS_THR_C_DEST)
+ ACE_THR_C_DEST destructor,
+#else
ACE_THR_DEST destructor,
+#endif /* ACE_HAS_THR_C_DEST */
void * = 0);
// Allocates a <keyp> that is used to identify data that is specific
// to each thread in the process. The key is global to all threads
diff --git a/ace/Thread.i b/ace/Thread.i
index 1a5e2746f65..1684c0c7f14 100644
--- a/ace/Thread.i
+++ b/ace/Thread.i
@@ -9,7 +9,11 @@
ACE_INLINE int
ACE_Thread::keycreate (ACE_thread_key_t *keyp,
+#if defined (ACE_HAS_THR_C_DEST)
+ ACE_THR_C_DEST destructor,
+#else
ACE_THR_DEST destructor,
+#endif /* ACE_HAS_THR_C_DEST */
void *inst)
{
ACE_TRACE ("ACE_Thread::keycreate");
diff --git a/ace/config-aix-4.1.x.h b/ace/config-aix-4.1.x.h
index 6ee505fc0bf..04b6529e0f7 100644
--- a/ace/config-aix-4.1.x.h
+++ b/ace/config-aix-4.1.x.h
@@ -95,6 +95,7 @@
// EYE assume it does for now.
#define ACE_LACKS_PTHREAD_THR_SIGSETMASK
#define ACE_HAS_PTHREADS
+#define ACE_LACKS_RWLOCK_T
#define ACE_PTHREADS_MAP
// include there
diff --git a/ace/config-hpux-10.x.h b/ace/config-hpux-10.x.h
index 83ff5c4eafb..b40b27c39ea 100644
--- a/ace/config-hpux-10.x.h
+++ b/ace/config-hpux-10.x.h
@@ -58,6 +58,7 @@
#define ACE_HAS_THREADS
#define ACE_HAS_PTHREADS
+#define ACE_LACKS_RWLOCK_T
#define ACE_MT_SAFE
#define ACE_HAS_SIGINFO_T
#define ACE_LACKS_PTHREAD_THR_SIGSETMASK
diff --git a/ace/config-irix6.2-sgic++.h b/ace/config-irix6.2-sgic++.h
index c35f452cb17..47076738861 100644
--- a/ace/config-irix6.2-sgic++.h
+++ b/ace/config-irix6.2-sgic++.h
@@ -42,6 +42,7 @@
// IRIX 6.2 supports some variant of POSIX Pthreads, is it stock DCE?
#define ACE_HAS_PTHREADS
+#define ACE_LACKS_RWLOCK_T
// Platform/compiler has the sigwait(2) prototype
#define ACE_HAS_SIGWAIT
diff --git a/ace/config-linux-lxpthreads.h b/ace/config-linux-lxpthreads.h
new file mode 100644
index 00000000000..66dab145a99
--- /dev/null
+++ b/ace/config-linux-lxpthreads.h
@@ -0,0 +1,104 @@
+/* -*- C++ -*- */
+// $Id$
+
+// The following configuration file is designed to work for Linux
+// platforms using GNU C++ and L. Xavier's pthreads package.
+
+#if !defined (ACE_CONFIG_H)
+#define ACE_CONFIG_H
+
+// Fixes a problem with new versions of Linux...
+#ifndef msg_accrights
+#undef msg_control
+#define msg_accrights msg_control
+#endif
+
+#ifndef msg_accrightslen
+#undef msg_controllen
+#define msg_accrightslen msg_controllen
+#endif
+
+#define ACE_HAS_POSIX_TIME
+#define ACE_LACKS_STRRECVFD
+
+// Platform supports System V IPC (most versions of UNIX, but not Win32)
+#define ACE_HAS_SYSV_IPC
+
+// Compiler/platform contains the <sys/syscall.h> file.
+#define ACE_HAS_SYSCALL_H
+
+#define ACE_HAS_CONSISTENT_SIGNAL_PROTOTYPES
+
+// Platforms lacks UNIX domain sockets.
+//#define ACE_LACKS_UNIX_DOMAIN_SOCKETS
+
+// Compiler/platform supports alloca().
+#define ACE_HAS_ALLOCA
+
+//#define ACE_LACKS_SENDMSG
+//#define ACE_LACKS_RECVMSG
+#define ACE_LACKS_MSYNC
+#define ACE_LACKS_MADVISE
+
+// Compiler/platform has <alloca.h>
+#define ACE_HAS_ALLOCA_H
+
+// Compiler/platform has the getrusage() system call.
+#define ACE_HAS_GETRUSAGE
+
+// Compiler/platform defines the sig_atomic_t typedef.
+#define ACE_HAS_SIG_ATOMIC_T
+
+// Compiler/platform supports sys_siglist array.
+#define ACE_HAS_SYS_SIGLIST
+
+// Compiler/platform defines a union semun for SysV shared memory.
+#define ACE_HAS_SEMUN
+
+// Compiler supports the ssize_t typedef.
+#define ACE_HAS_SSIZE_T
+
+// Compiler/platform supports strerror ().
+#define ACE_HAS_STRERROR
+
+// Defines the page size of the system.
+#define ACE_PAGE_SIZE 4096
+
+#define ACE_HAS_SUNOS4_GETTIMEOFDAY
+#define LINUX 1.2.10
+
+// Turns off the tracing feature.
+#if !defined (ACE_NTRACE)
+#define ACE_NTRACE 1
+#endif /* ACE_NTRACE */
+
+// Linux defines struct msghdr in /usr/include/socket.h
+#define ACE_HAS_MSG
+
+// TDN - adapted from file for SunOS4 platforms using the GNU g++ compiler
+// Compiler's template mechanism must see source code (i.e., .C files).
+#define ACE_TEMPLATES_REQUIRE_SOURCE
+
+#define ACE_TEMPLATES_REQUIRE_SPECIALIZATION
+
+// Compiler doesn't support static data member templates.
+#define ACE_LACKS_STATIC_DATA_MEMBER_TEMPLATES
+
+// Yes, we do have threads.
+#define ACE_HAS_THREADS
+// And they're even POSIX pthreads (MIT implementation)
+#define ACE_HAS_PTHREADS
+#define ACE_MT_SAFE
+#define ACE_HAS_THREAD_SPECIFIC_STORAGE
+#define ACE_HAS_PTHREADS_XAVIER // JCEJ 12/19/96
+#define ACE_HAS_SIGWAIT
+#define ACE_LACKS_CONDATTR_PSHARED
+#define ACE_LACKS_THREAD_STACK_ADDR // JCEJ 12/17/96
+#define ACE_LACKS_THREAD_STACK_SIZE // JCEJ 12/17/96
+
+// To use pthreads on Linux you'll need to use the MIT version, for
+// now...
+#define _MIT_POSIX_THREADS 1
+#include /**/ <pthread.h>
+
+#endif /* ACE_CONFIG_H */
diff --git a/ace/config-linux-pthread.h b/ace/config-linux-pthread.h
index 1b43cbbe68f..0cb01d1fbf0 100644
--- a/ace/config-linux-pthread.h
+++ b/ace/config-linux-pthread.h
@@ -86,8 +86,12 @@
// Yes, we do have threads.
#define ACE_HAS_THREADS
+
+#define ACE_HAS_THREAD_SPECIFIC_STORAGE
+#define ACE_MT_SAFE
// And they're even POSIX pthreads (MIT implementation)
#define ACE_HAS_PTHREADS
+#define ACE_LACKS_RWLOCK_T
#define ACE_HAS_SIGWAIT
#define ACE_LACKS_CONDATTR_PSHARED
diff --git a/ace/config-m88k.h b/ace/config-m88k.h
index 212a0869c53..d5b2ac928dc 100644
--- a/ace/config-m88k.h
+++ b/ace/config-m88k.h
@@ -177,12 +177,8 @@ struct ip_mreq
// Compile using multi-thread libraries.
#define ACE_MT_SAFE
-#if !defined (m88k)
-// Platform supports Solaris threads.
-#define ACE_HAS_STHREADS
-#else
#define ACE_HAS_PTHREADS
-#endif /* m88k */
+#define ACE_LACKS_RWLOCK_T
// Platform supports threads.
#define ACE_HAS_THREADS
diff --git a/ace/config-mvs.h b/ace/config-mvs.h
index 7ead2fc5488..c6f13364a32 100644
--- a/ace/config-mvs.h
+++ b/ace/config-mvs.h
@@ -61,6 +61,8 @@
// Platform supports POSIX threads
#define ACE_HAS_PTHREADS
+#define ACE_LACKS_RWLOCK_T
+
// Platform has pthread_condattr_setkind_np()
#define ACE_HAS_PTHREAD_CONDATTR_SETKIND_NP
diff --git a/ace/config-osf1-4.0-g++.h b/ace/config-osf1-4.0-g++.h
index f60a6e2577b..4564aa8234b 100644
--- a/ace/config-osf1-4.0-g++.h
+++ b/ace/config-osf1-4.0-g++.h
@@ -109,7 +109,11 @@
// DJT modified 6/5/96
// ACE supports POSIX Pthreads.
//#define ACE_HAS_DCETHREADS
+
#define ACE_HAS_PTHREADS
+
+#define ACE_LACKS_RWLOCK_T
+
// DJT 6/6/96 added
// IEEE Std 1003.1c-1995, POSIX System Application Program Interface
#define ACE_HAS_PTHREADS_1003_DOT_1C
diff --git a/ace/config-osf1-4.0.h b/ace/config-osf1-4.0.h
index 5a8f4a565a0..711e3f5c547 100644
--- a/ace/config-osf1-4.0.h
+++ b/ace/config-osf1-4.0.h
@@ -88,6 +88,8 @@
// ACE supports POSIX Pthreads.
//#define ACE_HAS_DCETHREADS
#define ACE_HAS_PTHREADS
+
+#define ACE_LACKS_RWLOCK_T
// DJT 6/6/96 added
// IEEE Std 1003.1c-1995, POSIX System Application Program Interface
#define ACE_HAS_PTHREADS_1003_DOT_1C
diff --git a/ace/config-vxworks-ghs-1.8.h b/ace/config-vxworks-ghs-1.8.h
index 02b3c8f0b72..bc20ffd918f 100644
--- a/ace/config-vxworks-ghs-1.8.h
+++ b/ace/config-vxworks-ghs-1.8.h
@@ -7,6 +7,8 @@
#if !defined (ACE_CONFIG_H)
#define ACE_CONFIG_H
+#define ACE_LACKS_COND_T
+#define ACE_LACKS_RWLOCK_T
#define ACE_HAS_BROKEN_SENDMSG
#define ACE_HAS_BROKEN_WRITEV
#define ACE_HAS_CHARPTR_SOCKOPT
diff --git a/ace/config-vxworks5.2-g++.h b/ace/config-vxworks5.2-g++.h
index 842c11d723d..82a6efd8440 100644
--- a/ace/config-vxworks5.2-g++.h
+++ b/ace/config-vxworks5.2-g++.h
@@ -7,6 +7,8 @@
#if !defined (ACE_CONFIG_H)
#define ACE_CONFIG_H
+#define ACE_LACKS_COND_T
+#define ACE_LACKS_RWLOCK_T
#define ACE_HAS_BROKEN_SENDMSG
#define ACE_HAS_BROKEN_WRITEV
#define ACE_HAS_CHARPTR_SOCKOPT
diff --git a/ace/config-win32-msvc2.0.h b/ace/config-win32-msvc2.0.h
index 357201c7caa..e68ead2d81f 100644
--- a/ace/config-win32-msvc2.0.h
+++ b/ace/config-win32-msvc2.0.h
@@ -220,4 +220,6 @@ inline void *operator new (unsigned int, void *p) { return p; }
// Compiler/Platform supports the "using" keyword.
// #define ACE_HAS_USING_KEYWORD
+#define ACE_LACKS_COND_T
+#define ACE_LACKS_RWLOCK_T
#endif /* ACE_CONFIG_H */
diff --git a/ace/config-win32-msvc4.0.h b/ace/config-win32-msvc4.0.h
index 62d41a93a30..97856aeacc3 100644
--- a/ace/config-win32-msvc4.0.h
+++ b/ace/config-win32-msvc4.0.h
@@ -226,4 +226,6 @@
// Compiler/Platform supports the "using" keyword.
#define ACE_HAS_USING_KEYWORD
+#define ACE_LACKS_COND_T
+#define ACE_LACKS_RWLOCK_T
#endif /* ACE_CONFIG_H */