summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorstorri <storri@ae88bc3d-4319-0410-8dbf-d08b4c9d3795>2002-01-09 20:11:32 +0000
committerstorri <storri@ae88bc3d-4319-0410-8dbf-d08b4c9d3795>2002-01-09 20:11:32 +0000
commitf59c183b282a3ca8e04f1bc32b7f0d8e8493282b (patch)
tree465636084dd7e23da4f5c45dbee1d6f324676ea7
parent8d49128ebb34db33df6ea493843238a191b8ba52 (diff)
downloadATCD-f59c183b282a3ca8e04f1bc32b7f0d8e8493282b.tar.gz
libACE_OS
Initial Entry
-rw-r--r--ace/OS/Base_Thread_Adapter.cpp125
-rw-r--r--ace/OS/Base_Thread_Adapter.h167
-rw-r--r--ace/OS/Base_Thread_Adapter.inl34
-rw-r--r--ace/OS/Basic_Types.cpp130
-rw-r--r--ace/OS/Basic_Types.h610
-rw-r--r--ace/OS/Basic_Types.i477
-rw-r--r--ace/OS/Date_Time.cpp10
-rw-r--r--ace/OS/Date_Time.h105
-rw-r--r--ace/OS/Date_Time.i162
-rw-r--r--ace/OS/Global_Macros.h115
-rw-r--r--ace/OS/Handle_Gobbler.h66
-rw-r--r--ace/OS/Handle_Gobbler.i88
-rw-r--r--ace/OS/Handle_Ops.cpp41
-rw-r--r--ace/OS/Handle_Ops.h43
-rw-r--r--ace/OS/Handle_Ops.i1
-rw-r--r--ace/OS/Handle_Set.cpp558
-rw-r--r--ace/OS/Handle_Set.h229
-rw-r--r--ace/OS/Handle_Set.i176
-rw-r--r--ace/OS/Init_ACE.cpp44
-rw-r--r--ace/OS/Init_ACE.h65
-rw-r--r--ace/OS/Init_ACE.i1
-rw-r--r--ace/OS/Makefile69
-rw-r--r--ace/OS/OS.cpp7972
-rw-r--r--ace/OS/OS.h7529
-rw-r--r--ace/OS/OS.i11666
-rw-r--r--ace/OS/OS_Dirent.cpp235
-rw-r--r--ace/OS/OS_Dirent.h130
-rw-r--r--ace/OS/OS_Dirent.inl201
-rw-r--r--ace/OS/OS_Errno.cpp33
-rw-r--r--ace/OS/OS_Errno.h143
-rw-r--r--ace/OS/OS_Errno.inl87
-rw-r--r--ace/OS/OS_Export.h46
-rw-r--r--ace/OS/OS_Log_Msg_Attributes.cpp9
-rw-r--r--ace/OS/OS_Log_Msg_Attributes.h89
-rw-r--r--ace/OS/OS_Log_Msg_Attributes.inl6
-rw-r--r--ace/OS/OS_Memory.cpp13
-rw-r--r--ace/OS/OS_Memory.h123
-rw-r--r--ace/OS/OS_Memory.inl50
-rw-r--r--ace/OS/OS_QoS.cpp471
-rw-r--r--ace/OS/OS_QoS.h386
-rw-r--r--ace/OS/OS_String.cpp1023
-rw-r--r--ace/OS/OS_String.h596
-rw-r--r--ace/OS/OS_String.inl731
-rw-r--r--ace/OS/OS_TLI.cpp13
-rw-r--r--ace/OS/OS_TLI.h195
-rw-r--r--ace/OS/OS_TLI.inl343
-rw-r--r--ace/OS/OS_Thread_Adapter.cpp178
-rw-r--r--ace/OS/OS_Thread_Adapter.h78
-rw-r--r--ace/OS/OS_Thread_Adapter.inl1
-rw-r--r--ace/OS/Sched_Params.cpp321
-rw-r--r--ace/OS/Sched_Params.h225
-rw-r--r--ace/OS/Sched_Params.i136
-rw-r--r--ace/OS/Thread_Hook.cpp25
-rw-r--r--ace/OS/Thread_Hook.h56
-rw-r--r--ace/OS/gethrtime.cpp58
55 files changed, 36484 insertions, 0 deletions
diff --git a/ace/OS/Base_Thread_Adapter.cpp b/ace/OS/Base_Thread_Adapter.cpp
new file mode 100644
index 00000000000..dbe48fe4eb0
--- /dev/null
+++ b/ace/OS/Base_Thread_Adapter.cpp
@@ -0,0 +1,125 @@
+// $Id$
+
+#include "Base_Thread_Adapter.h"
+#include "OS.h"
+
+ACE_RCSID(ace, Base_Thread_Adapter, "$Id$")
+
+#if !defined (ACE_HAS_INLINED_OSCALLS)
+# include "Base_Thread_Adapter.inl"
+#endif /* ACE_HAS_INLINED_OS_CALLS */
+
+ACE_INIT_LOG_MSG_HOOK ACE_Base_Thread_Adapter::init_log_msg_hook_ = 0;
+ACE_INHERIT_LOG_MSG_HOOK ACE_Base_Thread_Adapter::inherit_log_msg_hook_ = 0;
+ACE_CLOSE_LOG_MSG_HOOK ACE_Base_Thread_Adapter::close_log_msg_hook_ = 0;
+ACE_SYNC_LOG_MSG_HOOK ACE_Base_Thread_Adapter::sync_log_msg_hook_ = 0;
+ACE_THR_DESC_LOG_MSG_HOOK ACE_Base_Thread_Adapter::thr_desc_log_msg_hook_ = 0;
+
+ACE_Base_Thread_Adapter::ACE_Base_Thread_Adapter (
+ ACE_THR_FUNC user_func,
+ void *arg,
+ ACE_THR_C_FUNC entry_point,
+ ACE_OS_Thread_Descriptor *td
+#if defined (ACE_HAS_WIN32_STRUCTURAL_EXCEPTIONS)
+ , ACE_SEH_EXCEPT_HANDLER selector
+ , ACE_SEH_EXCEPT_HANDLER handler
+#endif /* ACE_HAS_WIN32_STRUCTURAL_EXCEPTIONS */
+ )
+ : user_func_ (user_func)
+ , arg_ (arg)
+ , entry_point_ (entry_point)
+ , thr_desc_ (td)
+{
+ ACE_OS_TRACE ("ACE_Base_Thread_Adapter::ACE_Base_Thread_Adapter");
+
+ if (ACE_Base_Thread_Adapter::init_log_msg_hook_ != 0)
+ (*ACE_Base_Thread_Adapter::init_log_msg_hook_) (
+ this->log_msg_attributes_
+# if defined (ACE_HAS_WIN32_STRUCTURAL_EXCEPTIONS)
+ , selector
+ , handler
+# endif /* ACE_HAS_WIN32_STRUCTURAL_EXCEPTIONS */
+ );
+}
+
+ACE_Base_Thread_Adapter::~ACE_Base_Thread_Adapter (void)
+{
+}
+
+void
+ACE_Base_Thread_Adapter::inherit_log_msg (void)
+{
+ if (ACE_Base_Thread_Adapter::inherit_log_msg_hook_ != 0)
+ (*ACE_Base_Thread_Adapter::inherit_log_msg_hook_)(
+ this->thr_desc_,
+ this->log_msg_attributes_);
+}
+
+void
+ACE_Base_Thread_Adapter::close_log_msg (void)
+{
+ if (ACE_Base_Thread_Adapter::close_log_msg_hook_ != 0)
+ (*ACE_Base_Thread_Adapter::close_log_msg_hook_) ();
+}
+
+void
+ACE_Base_Thread_Adapter::sync_log_msg (const ACE_TCHAR *prg)
+{
+ if (ACE_Base_Thread_Adapter::sync_log_msg_hook_ != 0)
+ (*ACE_Base_Thread_Adapter::sync_log_msg_hook_) (prg);
+}
+
+ACE_OS_Thread_Descriptor *
+ACE_Base_Thread_Adapter::thr_desc_log_msg (void)
+{
+ if (ACE_Base_Thread_Adapter::thr_desc_log_msg_hook_ != 0)
+ return (*ACE_Base_Thread_Adapter::thr_desc_log_msg_hook_) ();
+ return 0;
+}
+
+// Run the thread entry point for the <ACE_Thread_Adapter>. This must
+// be an extern "C" to make certain compilers happy...
+
+#if defined (ACE_PSOS)
+extern "C" void
+ace_thread_adapter (unsigned long args)
+{
+ ACE_OS_TRACE ("ace_thread_adapter");
+
+#if defined (ACE_HAS_TSS_EMULATION)
+ // As early as we can in the execution of the new thread, allocate
+ // its local TS storage. Allocate it on the stack, to save dynamic
+ // allocation/dealloction.
+ void *ts_storage[ACE_TSS_Emulation::ACE_TSS_THREAD_KEYS_MAX];
+ ACE_TSS_Emulation::tss_open (ts_storage);
+#endif /* ACE_HAS_TSS_EMULATION */
+
+ ACE_Base_Thread_Adapter *thread_args =
+ ACE_static_cast(ACE_Base_Thread_Adapter *, args);
+
+ // Invoke the user-supplied function with the args.
+ thread_args->invoke ();
+}
+#else /* ! defined (ACE_PSOS) */
+extern "C" void *
+ace_thread_adapter (void *args)
+{
+ ACE_OS_TRACE ("ace_thread_adapter");
+
+#if defined (ACE_HAS_TSS_EMULATION)
+ // As early as we can in the execution of the new thread, allocate
+ // its local TS storage. Allocate it on the stack, to save dynamic
+ // allocation/dealloction.
+ void *ts_storage[ACE_TSS_Emulation::ACE_TSS_THREAD_KEYS_MAX];
+ ACE_TSS_Emulation::tss_open (ts_storage);
+#endif /* ACE_HAS_TSS_EMULATION */
+
+ ACE_Base_Thread_Adapter *thread_args =
+ ACE_static_cast (ACE_Base_Thread_Adapter *, args);
+
+ // Invoke the user-supplied function with the args.
+ void *status = thread_args->invoke ();
+
+ return status;
+}
+#endif /* ACE_PSOS */
diff --git a/ace/OS/Base_Thread_Adapter.h b/ace/OS/Base_Thread_Adapter.h
new file mode 100644
index 00000000000..5993ebf418d
--- /dev/null
+++ b/ace/OS/Base_Thread_Adapter.h
@@ -0,0 +1,167 @@
+//=============================================================================
+/**
+ * @file Base_Thread_Adapter.h
+ *
+ * $Id$
+ *
+ * @author Nanbor Wang <nanbor@cs.wustl.edu>
+ */
+//=============================================================================
+
+#ifndef ACE_BASE_THREAD_ADAPTER_H
+#define ACE_BASE_THREAD_ADAPTER_H
+#include "ace/pre.h"
+
+#include "OS_Log_Msg_Attributes.h"
+
+#if !defined (ACE_LACKS_PRAGMA_ONCE)
+# pragma once
+#endif /* ACE_LACKS_PRAGMA_ONCE */
+
+#include "OS_Export.h"
+
+// Run the thread entry point for the <ACE_Thread_Adapter>. This must
+// be an extern "C" to make certain compilers happy...
+#if defined (ACE_PSOS)
+extern "C" void ace_thread_adapter (unsigned long args);
+#else /* ! defined (ACE_PSOS) */
+extern "C" ACE_OS_Export void *ace_thread_adapter (void *args);
+#endif /* ACE_PSOS */
+
+/**
+ * @class ACE_OS_Thread_Descriptor
+ *
+ * @brief Parent class of all ACE_Thread_Descriptor classes.
+ * =
+ * Container for ACE_Thread_Descriptor members that are
+ * used in ACE_OS.
+ */
+class ACE_OS_Export ACE_OS_Thread_Descriptor
+{
+public:
+ /// Get the thread creation flags.
+ long flags (void) const;
+
+protected:
+ /// For use by ACE_Thread_Descriptor.
+ ACE_OS_Thread_Descriptor (long flags = 0);
+
+ /**
+ * Keeps track of whether this thread was created "detached" or not.
+ * If a thread is *not* created detached then if someone calls
+ * <ACE_Thread_Manager::wait>, we need to join with that thread (and
+ * close down the handle).
+ */
+ long flags_;
+};
+
+/**
+ * @class ACE_Base_Thread_Adapter
+ *
+ * @brief Base class for all the Thread_Adapters.
+ *
+ * Converts a C++ function into a function <ace_thread_adapter>
+ * function that can be called from a thread creation routine
+ * (e.g., <pthread_create> or <_beginthreadex>) that expects an
+ * extern "C" entry point. This class also makes it possible to
+ * transparently provide hooks to register a thread with an
+ * <ACE_Thread_Manager>.
+ * This class is used in <ACE_OS::thr_create>. In general, the
+ * thread that creates an object of this class is different from
+ * the thread that calls <invoke> on this object. Therefore,
+ * the <invoke> method is responsible for deleting itself.
+ */
+class ACE_OS_Export ACE_Base_Thread_Adapter
+{
+public:
+ ACE_Base_Thread_Adapter (ACE_THR_FUNC user_func,
+ void *arg,
+ ACE_THR_C_FUNC entry_point = (ACE_THR_C_FUNC) ace_thread_adapter,
+ ACE_OS_Thread_Descriptor *td = 0
+# if defined (ACE_HAS_WIN32_STRUCTURAL_EXCEPTIONS)
+ , ACE_SEH_EXCEPT_HANDLER selector = 0
+ , ACE_SEH_EXCEPT_HANDLER handler = 0
+# endif /* ACE_HAS_WIN32_STRUCTURAL_EXCEPTIONS */
+ /// Constructor.
+ );
+
+ /// Virtual method invoked by the thread entry point.
+ virtual void *invoke (void) = 0;
+
+ /// Accessor for the C entry point function to the OS thread creation
+ /// routine.
+ ACE_THR_C_FUNC entry_point (void);
+
+ /// Invoke the close_log_msg_hook, if it is present
+ static void close_log_msg (void);
+
+ /// Invoke the sync_log_msg_hook, if it is present
+ static void sync_log_msg (const ACE_TCHAR *prog_name);
+
+ /// Invoke the thr_desc_log_msg_hook, if it is present
+ static ACE_OS_Thread_Descriptor *thr_desc_log_msg (void);
+
+protected:
+ /// Destructor, making it private ensures that objects of this class
+ /// are allocated on the heap.
+ virtual ~ACE_Base_Thread_Adapter (void);
+
+ /// Inherit the logging features if the parent thread has an
+ /// <ACE_Log_Msg>.
+ void inherit_log_msg (void);
+
+private:
+ /// The hooks to inherit and cleanup the Log_Msg attributes
+ static ACE_INIT_LOG_MSG_HOOK init_log_msg_hook_;
+ static ACE_INHERIT_LOG_MSG_HOOK inherit_log_msg_hook_;
+ static ACE_CLOSE_LOG_MSG_HOOK close_log_msg_hook_;
+ static ACE_SYNC_LOG_MSG_HOOK sync_log_msg_hook_;
+ static ACE_THR_DESC_LOG_MSG_HOOK thr_desc_log_msg_hook_;
+
+ /// Set the Log_Msg hooks
+ static void set_log_msg_hooks (ACE_INIT_LOG_MSG_HOOK init_hook,
+ ACE_INHERIT_LOG_MSG_HOOK inherit_hook,
+ ACE_CLOSE_LOG_MSG_HOOK close_hook,
+ ACE_SYNC_LOG_MSG_HOOK sync_hook,
+ ACE_THR_DESC_LOG_MSG_HOOK thr_desc);
+
+ /// Allow the ACE_Log_Msg class to set its hooks.
+ friend class ACE_Log_Msg;
+
+protected:
+ /// Thread startup function passed in by the user (C++ linkage).
+ ACE_THR_FUNC user_func_;
+
+ /// Argument to thread startup function.
+ void *arg_;
+
+ /// Entry point to the underlying OS thread creation call (C
+ /// linkage).
+ ACE_THR_C_FUNC entry_point_;
+
+ /**
+ * Optional thread descriptor. Passing this pointer in will force
+ * the spawned thread to cache this location in <Log_Msg> and wait
+ * until <Thread_Manager> fills in all information in thread
+ * descriptor.
+ */
+ ACE_OS_Thread_Descriptor *thr_desc_;
+
+ /// The ACE_Log_Msg attributes.
+ ACE_OS_Log_Msg_Attributes log_msg_attributes_;
+
+ /// Friend declaration to avoid compiler warning: only defines a private
+ /// destructor and has no friends.
+ friend class ACE_Thread_Adapter_Has_Private_Destructor;
+};
+
+# if defined (ACE_HAS_INLINED_OSCALLS)
+# if defined (ACE_INLINE)
+# undef ACE_INLINE
+# endif /* ACE_INLINE */
+# define ACE_INLINE inline
+# include "Base_Thread_Adapter.inl"
+# endif /* ACE_HAS_INLINED_OSCALLS */
+
+#include "ace/post.h"
+#endif /* ACE_BASE_THREAD_ADAPTER_H */
diff --git a/ace/OS/Base_Thread_Adapter.inl b/ace/OS/Base_Thread_Adapter.inl
new file mode 100644
index 00000000000..1d0d6ba7a49
--- /dev/null
+++ b/ace/OS/Base_Thread_Adapter.inl
@@ -0,0 +1,34 @@
+// $Id$
+
+ACE_INLINE long
+ACE_OS_Thread_Descriptor::flags (void) const
+{
+ return flags_;
+}
+
+ACE_INLINE
+ACE_OS_Thread_Descriptor::ACE_OS_Thread_Descriptor (long flags)
+ : flags_ (flags)
+{
+}
+
+ACE_INLINE void
+ACE_Base_Thread_Adapter::set_log_msg_hooks (
+ ACE_INIT_LOG_MSG_HOOK init_hook,
+ ACE_INHERIT_LOG_MSG_HOOK inherit_hook,
+ ACE_CLOSE_LOG_MSG_HOOK close_hook,
+ ACE_SYNC_LOG_MSG_HOOK sync_hook,
+ ACE_THR_DESC_LOG_MSG_HOOK thr_desc_hook)
+{
+ ACE_Base_Thread_Adapter::init_log_msg_hook_ = init_hook;
+ ACE_Base_Thread_Adapter::inherit_log_msg_hook_ = inherit_hook;
+ ACE_Base_Thread_Adapter::close_log_msg_hook_ = close_hook;
+ ACE_Base_Thread_Adapter::sync_log_msg_hook_ = sync_hook;
+ ACE_Base_Thread_Adapter::thr_desc_log_msg_hook_ = thr_desc_hook;
+}
+
+ACE_INLINE ACE_THR_C_FUNC
+ACE_Base_Thread_Adapter::entry_point (void)
+{
+ return this->entry_point_;
+}
diff --git a/ace/OS/Basic_Types.cpp b/ace/OS/Basic_Types.cpp
new file mode 100644
index 00000000000..15c23a402b0
--- /dev/null
+++ b/ace/OS/Basic_Types.cpp
@@ -0,0 +1,130 @@
+// $Id$
+
+#include "OS.h"
+#if !defined (__ACE_INLINE__)
+# include "Basic_Types.i"
+#endif /* ! __ACE_INLINE__ */
+
+ACE_RCSID(ace, Basic_Types, "$Id$")
+
+#if 0
+#if defined (ACE_LACKS_LONGLONG_T)
+#include "ace/Log_Msg.h"
+#if !defined (ACE_LACKS_IOSTREAM_TOTALLY)
+# include "ace/streams.h"
+#endif /* ! ACE_LACKS_IOSTREAM_TOTALLY */
+#endif
+
+void
+ACE_U_LongLong::output (FILE *file) const
+{
+ if (h_ () > 0)
+ ACE_OS::fprintf (file, "0x%lx%0*lx", h_ (), 2 * sizeof l_ (), l_ ());
+ else
+ ACE_OS::fprintf (file, "0x%lx", l_ ());
+}
+
+
+ACE_TCHAR *
+ACE_U_LongLong::as_string (ACE_TCHAR *output,
+ u_int base,
+ u_int uppercase) const
+{
+ if (*this == 0)
+ {
+ ACE_OS::strcpy(output, "0");
+ }
+ else
+ {
+ switch(base)
+ {
+ case 8:
+ {
+ u_int index = 0;
+ int bshift = 31;
+ while(bshift >= 1)
+ {
+ u_int sval = (this->h_ () >> bshift) & 7;
+ if (sval > 0 || index != 0)
+ {
+ output[index] = sval + '0';
+ index++;
+ }
+ bshift -= 3;
+ }
+ bshift = 30;
+ while(bshift >= 0)
+ {
+ u_int sval = (this->l_ () >> bshift) & 7;
+ // Combine the last bit of hi with the first 3-bit digit
+ if (bshift == 30)
+ {
+ sval |= (this->h_ () & 1) << 2;
+ }
+ if (sval > 0 || index != 0)
+ {
+ output[index] = sval + '0';
+ index++;
+ }
+ bshift -= 3;
+ }
+ output[index] = '\0';
+ break;
+ }
+ case 10:
+ {
+ ACE_OS::sprintf(output, "%.0f", *this / 1.0);
+ break;
+ }
+ case 16:
+ {
+ if (this->h_ () != 0)
+ {
+ ACE_OS::sprintf(output,
+ (uppercase ? "%lX%0*lX" : "%lx%0*lx"),
+ this->h_ (), 2 * sizeof this->l_ (),
+ this->l_ ());
+ }
+ else
+ {
+ ACE_OS::sprintf(output,
+ (uppercase ? "%lX" : "%lx"), this->l_ ());
+
+ }
+ break;
+ }
+ default:
+ {
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_LIB_TEXT ("Unsupported base = %u\n"), base));
+ output[0] = '\0';
+ }
+ }
+ }
+
+ return output;
+}
+
+
+#if !defined (ACE_LACKS_IOSTREAM_TOTALLY)
+ostream&
+operator<< (ostream& os, const ACE_U_LongLong& ll)
+{
+ unsigned long flags = os.setf(0);
+ char buffer[32];
+
+ if ((flags & ios::oct) != 0)
+ os << ll.as_string (buffer, 8);
+ else if ((flags & ios::hex) != 0)
+ os << ll.as_string (buffer, 16, (flags & ios::uppercase));
+ else
+ os << ll.as_string (buffer);
+ return os;
+}
+#endif
+
+
+#endif /* ACE_LACKS_LONGLONG_T */
+
+// Explicit template instantiation file
+#include "ace/Template_Instantiations.cpp"
diff --git a/ace/OS/Basic_Types.h b/ace/OS/Basic_Types.h
new file mode 100644
index 00000000000..fedec0cb74d
--- /dev/null
+++ b/ace/OS/Basic_Types.h
@@ -0,0 +1,610 @@
+// -*- C++ -*-
+
+//=============================================================================
+/**
+ * @file Basic_Types.h
+ *
+ * $Id$
+ *
+ * @author David L. Levine
+ *
+ * #defines the list of preprocessor macros below. The config.h file can
+ * pre-define any of these to short-cut the definitions. This is usually
+ * only necessary if the preprocessor does all of its math using integers.
+ *
+ * Sizes of built-in types:
+ * - ACE_SIZEOF_CHAR
+ * - ACE_SIZEOF_WCHAR
+ * - ACE_SIZEOF_SHORT
+ * - ACE_SIZEOF_INT
+ * - ACE_SIZEOF_LONG
+ * - ACE_SIZEOF_LONG_LONG
+ * - ACE_SIZEOF_VOID_P
+ * - ACE_SIZEOF_FLOAT
+ * - ACE_SIZEOF_DOUBLE
+ * - ACE_SIZEOF_LONG_DOUBLE
+ *
+ * Wrappers for built-in types of specific sizes:
+ * - ACE_USHORT16 (For backward compatibility. Use ACE_UINT16 instead.)
+ * - ACE_INT16
+ * - ACE_UINT16
+ * - ACE_INT32
+ * - ACE_UINT32
+ * - ACE_UINT64
+ * (Note: ACE_INT64 is not defined, because there is no ACE_LongLong for
+ * platforms that don't have a native 8-byte integer type.)
+ *
+ * Byte-order (endian-ness) determination:
+ * ACE_BYTE_ORDER, to either ACE_BIG_ENDIAN or ACE_LITTLE_ENDIAN
+ *
+ *
+ */
+//=============================================================================
+
+
+#ifndef ACE_BASIC_TYPES_H
+# define ACE_BASIC_TYPES_H
+
+# include "ace/pre.h"
+
+# include "ace/config-all.h"
+
+# if !defined (ACE_LACKS_PRAGMA_ONCE)
+# pragma once
+# endif /* ACE_LACKS_PRAGMA_ONCE */
+
+// Pull in definitions
+# include /**/ <limits.h> // Integer limits
+# include /**/ <float.h> // Floating point limits
+# include /**/ <stdlib.h> // Other types
+
+# if defined(ACE_LACKS_LONGLONG_T)
+# include /**/ <stdarg.h> // LynxOS requires this before stdio.h
+# include /**/ <stdio.h> // For long long emulation
+# endif /* ACE_LACKS_LONGLONG_T */
+
+# if !defined (ACE_LACKS_SYS_TYPES_H)
+# include /**/ <sys/types.h>
+# endif /* ACE_LACKS_SYS_TYPES_H */
+
+# include "ace/ACE_export.h"
+
+// A char always has 1 byte, by definition.
+# define ACE_SIZEOF_CHAR 1
+
+// Unfortunately, there isn't a portable way to determine the size of a wchar.
+// So we just define them on a platform basis.
+# if defined (ACE_HAS_WCHAR)
+# if !defined (ACE_SIZEOF_WCHAR)
+# if defined (ACE_HAS_XPG4_MULTIBYTE_CHAR)
+# define ACE_SIZEOF_WCHAR sizeof (wchar_t)
+# else
+// 0 so the Basic_Types test will catch this.
+# define ACE_SIZEOF_WCHAR 0
+# endif /* ACE_HAS_XPG4_MULTIBYTE_CHAR */
+# endif /* !ACE_SIZEOF_WCHAR */
+# endif /* ACE_HAS_WCHAR */
+
+// The number of bytes in a short.
+# if !defined (ACE_SIZEOF_SHORT)
+# if (USHRT_MAX) == 255U
+# define ACE_SIZEOF_SHORT 1
+# elif (USHRT_MAX) == 65535U
+# define ACE_SIZEOF_SHORT 2
+# elif (USHRT_MAX) == 4294967295U
+# define ACE_SIZEOF_SHORT 4
+# elif (USHRT_MAX) == 18446744073709551615U
+# define ACE_SIZEOF_SHORT 8
+# else
+# error: unsupported short size, must be updated for this platform!
+# endif /* USHRT_MAX */
+# endif /* !defined (ACE_SIZEOF_SHORT) */
+
+// The number of bytes in an int.
+# if !defined (ACE_SIZEOF_INT)
+# if (UINT_MAX) == 65535U
+# define ACE_SIZEOF_INT 2
+# elif (UINT_MAX) == 4294967295U
+# define ACE_SIZEOF_INT 4
+# elif (UINT_MAX) == 18446744073709551615U
+# define ACE_SIZEOF_INT 8
+# else
+# error: unsupported int size, must be updated for this platform!
+# endif /* UINT_MAX */
+# endif /* !defined (ACE_SIZEOF_INT) */
+
+// The number of bytes in a long.
+// NOTE - since preprocessors only need to do integer math, this is a likely
+// place for a preprocessor to not properly support being able to figure out
+// the proper size. HP aC++ and GNU gcc have this difficulty so watch out.
+# if !defined (ACE_SIZEOF_LONG)
+# if (ULONG_MAX) == 65535UL
+# define ACE_SIZEOF_LONG 2
+# elif ((ULONG_MAX) == 4294967295UL)
+# define ACE_SIZEOF_LONG 4
+# elif ((ULONG_MAX) == 18446744073709551615UL)
+# define ACE_SIZEOF_LONG 8
+# else
+# error: unsupported long size, must be updated for this platform!
+# endif /* ULONG_MAX */
+# endif /* !defined (ACE_SIZEOF_LONG) */
+
+// The number of bytes in a long long.
+# if !defined (ACE_SIZEOF_LONG_LONG)
+# if defined (ACE_LACKS_LONGLONG_T)
+# define ACE_SIZEOF_LONG_LONG 8
+# else /* ! ACE_WIN32 && ! ACE_LACKS_LONGLONG_T */
+# if ACE_SIZEOF_LONG == 8
+# define ACE_SIZEOF_LONG_LONG 8
+ typedef unsigned long ACE_UINT64;
+# elif defined (ULLONG_MAX) && !defined (__GNUG__)
+ // Some compilers use ULLONG_MAX and others, e.g. Irix, use
+ // ULONGLONG_MAX.
+# if (ULLONG_MAX) == 18446744073709551615ULL
+# define ACE_SIZEOF_LONG_LONG 8
+# elif (ULLONG_MAX) == 4294967295ULL
+# define ACE_SIZEOF_LONG_LONG 4
+# else
+# error Unsupported long long size needs to be updated for this platform
+# endif
+ typedef unsigned long long ACE_UINT64;
+# elif defined (ULONGLONG_MAX) && !defined (__GNUG__)
+ // Irix 6.x, for example.
+# if (ULONGLONG_MAX) == 18446744073709551615ULL
+# define ACE_SIZEOF_LONG_LONG 8
+# elif (ULONGLONG_MAX) == 4294967295ULL
+# define ACE_SIZEOF_LONG_LONG 4
+# else
+# error Unsupported long long size needs to be updated for this platform
+# endif
+ typedef unsigned long long ACE_UINT64;
+# else
+ // ACE_SIZEOF_LONG_LONG is not yet known, but the platform doesn't
+ // claim ACE_LACKS_LONGLONG_T, so assume it has 8-byte long longs.
+# define ACE_SIZEOF_LONG_LONG 8
+# if defined (sun) && !defined (ACE_LACKS_U_LONGLONG_T)
+ // sun #defines u_longlong_t, maybe other platforms do also.
+ // Use it, at least with g++, so that its -pedantic doesn't
+ // complain about no ANSI C++ long long.
+ typedef u_longlong_t ACE_UINT64;
+# else
+ // LynxOS 2.5.0 and Linux don't have u_longlong_t.
+ typedef unsigned long long ACE_UINT64;
+# endif /* sun */
+# endif /* ULLONG_MAX && !__GNUG__ */
+# endif /* ! ACE_WIN32 && ! ACE_LACKS_LONGLONG_T */
+# endif /* !defined (ACE_SIZEOF_LONG_LONG) */
+
+// The sizes of the commonly implemented types are now known. Set up
+// typedefs for whatever we can. Some of these are needed for certain cases
+// of ACE_UINT64, so do them before the 64-bit stuff.
+
+# if ACE_SIZEOF_SHORT == 2
+ typedef short ACE_INT16;
+ typedef unsigned short ACE_UINT16;
+# elif ACE_SIZEOF_INT == 2
+ typedef int ACE_INT16;
+ typedef unsigned int ACE_UINT16;
+# elif (ACE_SIZEOF_SHORT) == 4 && defined(_CRAYMPP)
+ // mpp cray - uses Alpha processors
+ // Use the real 32-bit quantity for ACE_INT32's, and use a "long"
+ // for ACE_INT16's. This gets around conflicts with size_t in some ACE
+ // method signatures, among other things.
+ typedef long ACE_INT16;
+ typedef unsigned long ACE_UINT16;
+ typedef short ACE_INT32;
+ typedef unsigned short ACE_UINT32;
+# elif (ACE_SIZEOF_SHORT) == 8 && defined(_UNICOS)
+ // vector cray - hard 64-bit, all 64 bit types
+ typedef short ACE_INT16;
+ typedef unsigned short ACE_UINT16;
+# else
+# error Have to add to the ACE_UINT16 type setting
+# endif
+
+typedef ACE_UINT16 ACE_USHORT16;
+
+// Define a pseudo wide character type when wchar is not supported so we
+// can support basic wide character string operations.
+
+# if defined (ACE_HAS_WCHAR)
+# define ACE_WINT_T wint_t
+# define ACE_WCHAR_T wchar_t
+# else
+# define ACE_WINT_T ACE_USHORT16
+# define ACE_WCHAR_T ACE_USHORT16
+# endif /* ACE_HAS_WCHAR */
+
+# if ACE_SIZEOF_INT == 4
+ typedef int ACE_INT32;
+ typedef unsigned int ACE_UINT32;
+# if defined (__KCC) && !defined (ACE_LACKS_LONGLONG_T)
+ typedef unsigned long long ACE_UINT64;
+# endif /* __KCC */
+# elif ACE_SIZEOF_LONG == 4
+ typedef long ACE_INT32;
+ typedef unsigned long ACE_UINT32;
+# elif (ACE_SIZEOF_INT) == 8 && defined(_UNICOS)
+ // vector cray - hard 64-bit, all 64 bit types
+# if !defined(_CRAYMPP)
+ typedef int ACE_INT32;
+ typedef unsigned int ACE_UINT32;
+# endif
+ typedef unsigned long long ACE_UINT64;
+# else
+# error Have to add to the ACE_UINT32 type setting
+# endif
+
+// The number of bytes in a void *.
+# ifndef ACE_SIZEOF_VOID_P
+# define ACE_SIZEOF_VOID_P ACE_SIZEOF_LONG
+# endif /* ACE_SIZEOF_VOID_P */
+
+// Type for doing arithmetic on pointers ... as elsewhere, we assume
+// that unsigned versions of a type are the same size as the signed
+// version of the same type.
+#if ACE_SIZEOF_VOID_P == ACE_SIZEOF_INT
+# if defined (__SUNPRO_CC)
+ // For unknown reasons, Sun CC 5.0 won't allow a reintepret cast
+ // of a 64-bit pointer to a 64-bit int.
+ typedef u_long ptr_arith_t;
+# else /* ! __SUNPRO_CC */
+ typedef u_int ptr_arith_t;
+# endif /* ! __SUNPRO_CC */
+#elif ACE_SIZEOF_VOID_P == ACE_SIZEOF_LONG
+ typedef u_long ptr_arith_t;
+#elif ACE_SIZEOF_VOID_P == ACE_SIZEOF_LONG_LONG
+ typedef u_long long ptr_arith_t;
+#else
+# error "Can't find a suitable type for doing pointer arithmetic."
+#endif /* ACE_SIZEOF_VOID_P */
+
+#if defined (ACE_LACKS_LONGLONG_T)
+ // This throws away the high 32 bits. It's very unlikely that a
+ // pointer will be more than 32 bits wide if the platform does not
+ // support 64-bit integers.
+# define ACE_LONGLONG_TO_PTR(PTR_TYPE, L) \
+ ACE_reinterpret_cast (PTR_TYPE, L.lo ())
+#else /* ! ACE_LACKS_LONGLONG_T */
+# define ACE_LONGLONG_TO_PTR(PTR_TYPE, L) \
+ ACE_reinterpret_cast (PTR_TYPE, ACE_static_cast (ptr_arith_t, L))
+#endif /* ! ACE_LACKS_LONGLONG_T */
+
+// If the platform lacks a long long, define one.
+# if defined (ACE_LACKS_LONGLONG_T)
+# if defined (ACE_HAS_MINIMUM_IOSTREAMH_INCLUSION)
+// Forward declaration for streams
+# include "ace/iosfwd.h"
+# else /* ACE_HAS_MINIMUM_IOSTREAMH_INCLUSION */
+// Else they will get all the stream header files
+# include "ace/streams.h"
+# endif /* ACE_HAS_MINIMUM_IOSTREAMH_INCLUSION */
+
+/**
+ * @class ACE_U_LongLong
+ *
+ * @brief Unsigned long long for platforms that don't have one.
+ *
+ * Provide our own unsigned long long. This is intended to be
+ * use with ACE_High_Res_Timer, so the division operator assumes
+ * that the quotient fits into a u_long.
+ * Please note that the constructor takes (optionally) two values.
+ * The high one contributes 0x100000000 times its value. So,
+ * for example, (0, 2) is _not_ 20000000000, but instead
+ * 0x200000000. To emphasize this, the default values are expressed
+ * in hex, and output () dumps the value in hex.
+ */
+ class ACE_Export ACE_U_LongLong
+ {
+ public:
+ // = Initialization and termination methods.
+ ACE_U_LongLong (const ACE_UINT32 lo = 0x0, const ACE_UINT32 hi = 0x0);
+ ACE_U_LongLong (const ACE_U_LongLong &);
+ ACE_U_LongLong &operator= (const ACE_U_LongLong &);
+ ~ACE_U_LongLong (void);
+
+ // = Overloaded relation operators.
+ int operator== (const ACE_U_LongLong &) const;
+ int operator== (const ACE_UINT32) const;
+ int operator!= (const ACE_U_LongLong &) const;
+ int operator!= (const ACE_UINT32) const;
+ int operator< (const ACE_U_LongLong &) const;
+ int operator< (const ACE_UINT32) const;
+ int operator<= (const ACE_U_LongLong &) const;
+ int operator<= (const ACE_UINT32) const;
+ int operator> (const ACE_U_LongLong &) const;
+ int operator> (const ACE_UINT32) const;
+ int operator>= (const ACE_U_LongLong &) const;
+ int operator>= (const ACE_UINT32) const;
+
+ ACE_U_LongLong operator+ (const ACE_U_LongLong &) const;
+ ACE_U_LongLong operator+ (const ACE_UINT32) const;
+ ACE_U_LongLong operator- (const ACE_U_LongLong &) const;
+ ACE_U_LongLong operator- (const ACE_UINT32) const;
+ ACE_U_LongLong operator* (const ACE_UINT32) const;
+ ACE_U_LongLong &operator*= (const ACE_UINT32);
+
+ ACE_U_LongLong operator<< (const u_int) const;
+ ACE_U_LongLong &operator<<= (const u_int);
+ ACE_U_LongLong operator>> (const u_int) const;
+ ACE_U_LongLong &operator>>= (const u_int);
+
+ double operator/ (const double) const;
+
+ ACE_U_LongLong &operator+= (const ACE_U_LongLong &);
+ ACE_U_LongLong &operator+= (const ACE_UINT32);
+ ACE_U_LongLong &operator-= (const ACE_U_LongLong &);
+ ACE_U_LongLong &operator-= (const ACE_UINT32);
+ ACE_U_LongLong &operator++ ();
+ ACE_U_LongLong &operator-- ();
+ ACE_U_LongLong &operator|= (const ACE_U_LongLong);
+ ACE_U_LongLong &operator|= (const ACE_UINT32);
+ ACE_U_LongLong &operator&= (const ACE_U_LongLong);
+ ACE_U_LongLong &operator&= (const ACE_UINT32);
+
+ // Note that the following take ACE_UINT32 arguments. These are
+ // typical use cases, and easy to implement. But, they limit the
+ // return values to 32 bits as well. There are no checks for
+ // overflow.
+ ACE_UINT32 operator/ (const ACE_UINT32) const;
+ ACE_UINT32 operator% (const ACE_UINT32) const;
+
+ // The following only operate on the lower 32 bits (they take only
+ // 32 bit arguments).
+ ACE_UINT32 operator| (const ACE_INT32) const;
+ ACE_UINT32 operator& (const ACE_INT32) const;
+
+ // The following operators convert their arguments to
+ // ACE_UINT32. So, there may be information loss if they are
+ // used.
+ ACE_U_LongLong operator* (const ACE_INT32) const;
+ ACE_U_LongLong &operator*= (const ACE_INT32);
+ ACE_UINT32 operator/ (const ACE_INT32) const;
+# if ACE_SIZEOF_INT == 4
+ ACE_UINT32 operator/ (const u_long) const;
+ ACE_UINT32 operator/ (const long) const;
+# else /* ACE_SIZEOF_INT != 4 */
+ ACE_UINT32 operator/ (const u_int) const;
+ ACE_UINT32 operator/ (const int) const;
+# endif /* ACE_SIZEOF_INT != 4 */
+
+ // = Helper methods.
+ /// Outputs the value to the FILE, in hex.
+ void output (FILE * = stdout) const;
+
+ ACE_TCHAR *as_string (ACE_TCHAR *string,
+ u_int base = 10,
+ u_int uppercase = 0) const;
+
+ ACE_UINT32 hi (void) const;
+ ACE_UINT32 lo (void) const;
+
+ void hi (const ACE_UINT32 hi);
+ void lo (const ACE_UINT32 lo);
+
+ private:
+ union
+ {
+ struct
+ {
+ ACE_UINT32 hi_;
+ // High 32 bits.
+
+ ACE_UINT32 lo_;
+ // Low 32 bits.
+ } data_;
+ // To ensure alignment on 8-byte boundary.
+
+ // double isn't usually usable with ACE_LACKS_FLOATING_POINT,
+ // but this seems OK.
+ double for_alignment_;
+ // To ensure alignment on 8-byte boundary.
+ };
+
+ // NOTE: the following four accessors are inlined here in
+ // order to minimize the extent of the data_ struct. It's
+ // only used here; the .i and .cpp files use the accessors.
+
+ /// Internal utility function to hide access through struct.
+ const ACE_UINT32 &h_ () const { return data_.hi_; }
+
+ /// Internal utility function to hide access through struct.
+ ACE_UINT32 &h_ () { return data_.hi_; }
+
+ /// Internal utility function to hide access through struct.
+ const ACE_UINT32 &l_ () const { return data_.lo_; }
+
+ /// Internal utility function to hide access through struct.
+ ACE_UINT32 &l_ () { return data_.lo_; }
+
+ // NOTE: the above four accessors are inlined here in
+ // order to minimize the extent of the data_ struct. It's
+ // only used here; the .i and .cpp files use the accessors.
+
+ /// These functions are used to implement multiplication.
+ ACE_UINT32 ul_shift (ACE_UINT32 a,
+ ACE_UINT32 c_in,
+ ACE_UINT32 *c_out) const;
+ ACE_U_LongLong ull_shift (ACE_U_LongLong a,
+ ACE_UINT32 c_in,
+ ACE_UINT32 *c_out) const;
+ ACE_U_LongLong ull_add (ACE_U_LongLong a,
+ ACE_U_LongLong b,
+ ACE_UINT32 *carry) const;
+ ACE_U_LongLong ull_mult (ACE_U_LongLong a,
+ ACE_UINT32 b,
+ ACE_UINT32 *carry) const;
+ };
+
+ typedef ACE_U_LongLong ACE_UINT64;
+
+#if !defined (ACE_LACKS_IOSTREAM_TOTALLY)
+ ostream &operator<< (ostream &, const ACE_U_LongLong &);
+#endif /* ! ACE_LACKS_IOSTREAM_TOTALLY */
+
+# endif /* ACE_LACKS_LONGLONG_T */
+
+// Conversions from ACE_UINT64 to ACE_UINT32. ACE_CU64_TO_CU32 should
+// be used on const ACE_UINT64's.
+# if defined (ACE_LACKS_LONGLONG_T)
+# define ACE_U64_TO_U32(n) ((n).lo ())
+# define ACE_CU64_TO_CU32(n) ((n).lo ())
+# else /* ! ACE_LACKS_LONGLONG_T */
+# define ACE_U64_TO_U32(n) (ACE_static_cast (ACE_UINT32, (n)))
+# define ACE_CU64_TO_CU32(n) \
+ (ACE_static_cast (ACE_CAST_CONST ACE_UINT32, (n)))
+# endif /* ! ACE_LACKS_LONGLONG_T */
+
+// 64-bit literals require special marking on some platforms.
+# if defined (ACE_LACKS_LONGLONG_T)
+ // Can only specify 32-bit arguments.
+# define ACE_UINT64_LITERAL(n) (ACE_U_LongLong (n))
+ // This one won't really work, but it'll keep
+ // some compilers happy until we have better support
+# define ACE_INT64_LITERAL(n) (ACE_U_LongLong (n))
+# elif defined (ACE_WIN32)
+# if defined (__IBMCPP__) && (__IBMCPP__ >= 400)
+# define ACE_UINT64_LITERAL(n) n ## LL
+# define ACE_INT64_LITERAL(n) n ## LL
+# elif defined (__MINGW32__)
+# define ACE_UINT64_LITERAL(n) n ## ull
+# define ACE_INT64_LITERAL(n) n ## ll
+# else
+# define ACE_UINT64_LITERAL(n) n ## ui64
+# define ACE_INT64_LITERAL(n) n ## i64
+# endif /* defined (__IBMCPP__) && (__IBMCPP__ >= 400) */
+# else /* ! ACE_WIN32 && ! ACE_LACKS_LONGLONG_T */
+# define ACE_UINT64_LITERAL(n) n ## ull
+# define ACE_INT64_LITERAL(n) n ## ll
+# endif /* ! ACE_WIN32 && ! ACE_LACKS_LONGLONG_T */
+
+#if !defined (ACE_UINT64_FORMAT_SPECIFIER)
+# define ACE_UINT64_FORMAT_SPECIFIER ACE_LIB_TEXT ("%llu")
+#endif /* ACE_UINT64_FORMAT_SPECIFIER */
+
+#if !defined (ACE_INT64_FORMAT_SPECIFIER)
+# define ACE_INT64_FORMAT_SPECIFIER ACE_LIB_TEXT ("%lld")
+#endif /* ACE_INT64_FORMAT_SPECIFIER */
+
+#if !defined (ACE_SSIZE_T_FORMAT_SPECIFIER)
+# define ACE_SSIZE_T_FORMAT_SPECIFIER ACE_LIB_TEXT ("%d")
+#endif /* ACE_SSIZE_T_FORMAT_SPECIFIER */
+
+#if !defined (ACE_SIZE_T_FORMAT_SPECIFIER)
+# define ACE_SIZE_T_FORMAT_SPECIFIER ACE_LIB_TEXT ("%u")
+#endif /* ACE_SIZE_T_FORMAT_SPECIFIER */
+
+// Cast from UINT64 to a double requires an intermediate cast to INT64
+// on some platforms.
+# if defined (ACE_LACKS_LONGLONG_T)
+ // Only use the low 32 bits.
+# define ACE_UINT64_DBLCAST_ADAPTER(n) ACE_U64_TO_U32 (n)
+# elif defined (ACE_WIN32)
+# define ACE_UINT64_DBLCAST_ADAPTER(n) ACE_static_cast (__int64, n)
+# else /* ! ACE_WIN32 && ! ACE_LACKS_LONGLONG_T */
+# define ACE_UINT64_DBLCAST_ADAPTER(n) (n)
+# endif /* ! ACE_WIN32 && ! ACE_LACKS_LONGLONG_T */
+
+
+// The number of bytes in a float.
+# ifndef ACE_SIZEOF_FLOAT
+# if FLT_MAX_EXP == 128
+# define ACE_SIZEOF_FLOAT 4
+# elif FLT_MAX_EXP == 1024
+# define ACE_SIZEOF_FLOAT 8
+# else
+# error: unsupported float size, must be updated for this platform!
+# endif /* FLT_MAX_EXP */
+# endif /* ACE_SIZEOF_FLOAT */
+
+// The number of bytes in a double.
+# ifndef ACE_SIZEOF_DOUBLE
+# if DBL_MAX_EXP == 128
+# define ACE_SIZEOF_DOUBLE 4
+# elif DBL_MAX_EXP == 1024
+# define ACE_SIZEOF_DOUBLE 8
+# else
+# error: unsupported double size, must be updated for this platform!
+# endif /* DBL_MAX_EXP */
+# endif /* ACE_SIZEOF_DOUBLE */
+
+// The number of bytes in a long double.
+# ifndef ACE_SIZEOF_LONG_DOUBLE
+# if LDBL_MAX_EXP == 128
+# define ACE_SIZEOF_LONG_DOUBLE 4
+# elif LDBL_MAX_EXP == 1024
+# define ACE_SIZEOF_LONG_DOUBLE 8
+# elif LDBL_MAX_EXP == 16384
+# if defined (LDBL_DIG) && LDBL_DIG == 18
+# if defined (__ia64)
+# define ACE_SIZEOF_LONG_DOUBLE 16
+# else /* ! __ia64 */
+# define ACE_SIZEOF_LONG_DOUBLE 12
+# endif /* __ia64 */
+# else /* ! LDBL_DIG || LDBL_DIG != 18 */
+# define ACE_SIZEOF_LONG_DOUBLE 16
+# endif /* ! LDBL_DIG || LDBL_DIG != 18 */
+# else
+# error: unsupported double size, must be updated for this platform!
+# endif /* LDBL_MAX_EXP */
+# endif /* ACE_SIZEOF_LONG_DOUBLE */
+
+// Max and min sizes for the ACE integer types.
+#define ACE_CHAR_MAX 0x7F
+#define ACE_CHAR_MIN -(ACE_CHAR_MAX)-1
+#define ACE_OCTET_MAX 0xFF
+#define ACE_INT16_MAX 0x7FFF
+#define ACE_INT16_MIN -(ACE_INT16_MAX)-1
+#define ACE_UINT16_MAX 0xFFFF
+#define ACE_WCHAR_MAX ACE_UINT16_MAX
+#define ACE_INT32_MAX 0x7FFFFFFF
+#define ACE_INT32_MIN -(ACE_INT32_MAX)-1
+#define ACE_UINT32_MAX 0xFFFFFFFF
+#define ACE_INT64_MAX ACE_INT64_LITERAL(0x7FFFFFFFFFFFFFFF)
+#define ACE_INT64_MIN -(ACE_INT64_MAX)-1
+#define ACE_UINT64_MAX ACE_UINT64_LITERAL(0xFFFFFFFFFFFFFFFF)
+// These use ANSI/IEEE format.
+#define ACE_FLT_MAX 3.402823466e+38F
+#define ACE_DBL_MAX 1.7976931348623158e+308
+
+// Byte-order (endian-ness) determination.
+# if defined (BYTE_ORDER)
+# if (BYTE_ORDER == LITTLE_ENDIAN)
+# define ACE_LITTLE_ENDIAN 0x0123
+# define ACE_BYTE_ORDER ACE_LITTLE_ENDIAN
+# elif (BYTE_ORDER == BIG_ENDIAN)
+# define ACE_BIG_ENDIAN 0x3210
+# define ACE_BYTE_ORDER ACE_BIG_ENDIAN
+# else
+# error: unknown BYTE_ORDER!
+# endif /* BYTE_ORDER */
+# elif defined (__BYTE_ORDER)
+# if (__BYTE_ORDER == __LITTLE_ENDIAN)
+# define ACE_LITTLE_ENDIAN 0x0123
+# define ACE_BYTE_ORDER ACE_LITTLE_ENDIAN
+# elif (__BYTE_ORDER == __BIG_ENDIAN)
+# define ACE_BIG_ENDIAN 0x3210
+# define ACE_BYTE_ORDER ACE_BIG_ENDIAN
+# else
+# error: unknown __BYTE_ORDER!
+# endif /* __BYTE_ORDER */
+# else /* ! BYTE_ORDER && ! __BYTE_ORDER */
+ // We weren't explicitly told, so we have to figure it out . . .
+# if defined (i386) || defined (__i386__) || defined (_M_IX86) || \
+ defined (vax) || defined (__alpha) || defined (__LITTLE_ENDIAN__)
+ // We know these are little endian.
+# define ACE_LITTLE_ENDIAN 0x0123
+# define ACE_BYTE_ORDER ACE_LITTLE_ENDIAN
+# else
+ // Otherwise, we assume big endian.
+# define ACE_BIG_ENDIAN 0x3210
+# define ACE_BYTE_ORDER ACE_BIG_ENDIAN
+# endif
+# endif /* ! BYTE_ORDER && ! __BYTE_ORDER */
+
+# if defined (__ACE_INLINE__)
+# include "Basic_Types.i"
+# endif /* __ACE_INLINE__ */
+
+# include "ace/post.h"
+#endif /* ACE_BASIC_TYPES_H */
diff --git a/ace/OS/Basic_Types.i b/ace/OS/Basic_Types.i
new file mode 100644
index 00000000000..f5a0b0837d4
--- /dev/null
+++ b/ace/OS/Basic_Types.i
@@ -0,0 +1,477 @@
+/* -*- C++ -*- */
+// $Id$
+
+#if defined (ACE_LACKS_LONGLONG_T)
+
+ACE_INLINE
+ACE_U_LongLong::ACE_U_LongLong (const ACE_UINT32 lo, const ACE_UINT32 hi)
+{
+ h_ () = hi;
+ l_ () = lo;
+}
+
+ACE_INLINE ACE_UINT32
+ACE_U_LongLong::hi (void) const
+{
+ return h_ ();
+}
+
+ACE_INLINE ACE_UINT32
+ACE_U_LongLong::lo (void) const
+{
+ return l_ ();
+}
+
+ACE_INLINE void
+ACE_U_LongLong::hi (const ACE_UINT32 hi)
+{
+ h_ () = hi;
+}
+
+ACE_INLINE void
+ACE_U_LongLong::lo (const ACE_UINT32 lo)
+{
+ l_ () = lo;
+}
+
+ACE_INLINE
+ACE_U_LongLong::~ACE_U_LongLong (void)
+{
+}
+
+ACE_INLINE int
+ACE_U_LongLong::operator== (const ACE_U_LongLong &n) const
+{
+ return h_ () == n.h_ () && l_ () == n.l_ ();
+}
+
+ACE_INLINE int
+ACE_U_LongLong::operator== (const ACE_UINT32 n) const
+{
+ return h_ () == 0 && l_ () == n;
+}
+
+ACE_INLINE int
+ACE_U_LongLong::operator!= (const ACE_U_LongLong &n) const
+{
+ return ! (*this == n);
+}
+
+ACE_INLINE int
+ACE_U_LongLong::operator!= (const ACE_UINT32 n) const
+{
+ return ! (*this == n);
+}
+
+ACE_INLINE int
+ACE_U_LongLong::operator< (const ACE_U_LongLong &n) const
+{
+ return h_ () < n.h_ () ? 1
+ : h_ () > n.h_ () ? 0
+ : l_ () < n.l_ ();
+}
+
+ACE_INLINE int
+ACE_U_LongLong::operator< (const ACE_UINT32 n) const
+{
+ return operator< (ACE_static_cast (const ACE_U_LongLong, n));
+}
+
+ACE_INLINE int
+ACE_U_LongLong::operator<= (const ACE_U_LongLong &n) const
+{
+ return h_ () < n.h_ () ? 1
+ : h_ () > n.h_ () ? 0
+ : l_ () <= n.l_ ();
+}
+
+ACE_INLINE int
+ACE_U_LongLong::operator<= (const ACE_UINT32 n) const
+{
+ return operator<= (ACE_static_cast (const ACE_U_LongLong, n));
+}
+
+ACE_INLINE int
+ACE_U_LongLong::operator> (const ACE_U_LongLong &n) const
+{
+ return h_ () > n.h_ () ? 1
+ : h_ () < n.h_ () ? 0
+ : l_ () > n.l_ ();
+}
+
+ACE_INLINE int
+ACE_U_LongLong::operator> (const ACE_UINT32 n) const
+{
+ return operator> (ACE_static_cast (const ACE_U_LongLong, n));
+}
+
+ACE_INLINE int
+ACE_U_LongLong::operator>= (const ACE_U_LongLong &n) const
+{
+ return h_ () > n.h_ () ? 1
+ : h_ () < n.h_ () ? 0
+ : l_ () >= n.l_ ();
+}
+
+ACE_INLINE int
+ACE_U_LongLong::operator>= (const ACE_UINT32 n) const
+{
+ return operator>= (ACE_static_cast (const ACE_U_LongLong, n));
+}
+
+ACE_INLINE
+ACE_U_LongLong::ACE_U_LongLong (const ACE_U_LongLong &n)
+{
+ h_ () = n.h_ ();
+ l_ () = n.l_ ();
+}
+
+ACE_INLINE ACE_U_LongLong &
+ACE_U_LongLong::operator= (const ACE_U_LongLong &n)
+{
+ h_ () = n.h_ ();
+ l_ () = n.l_ ();
+
+ return *this;
+}
+
+ACE_INLINE ACE_U_LongLong
+ACE_U_LongLong::operator+ (const ACE_U_LongLong &n) const
+{
+ ACE_U_LongLong ret (l_ () + n.l_ (), h_ () + n.h_ ());
+ if (ret.l_ () < n.l_ ()) /* carry */ ++ret.h_ ();
+
+ return ret;
+}
+
+ACE_INLINE ACE_U_LongLong
+ACE_U_LongLong::operator+ (const ACE_UINT32 n) const
+{
+ return operator+ (ACE_static_cast (const ACE_U_LongLong, n));
+}
+
+ACE_INLINE ACE_U_LongLong
+ACE_U_LongLong::operator- (const ACE_U_LongLong &n) const
+{
+ ACE_U_LongLong ret (l_ () - n.l_ (), h_ () - n.h_ ());
+ if (l_ () < n.l_ ()) /* borrow */ --ret.h_ ();
+
+ return ret;
+}
+
+ACE_INLINE ACE_U_LongLong
+ACE_U_LongLong::operator- (const ACE_UINT32 n) const
+{
+ return operator- (ACE_static_cast (const ACE_U_LongLong, n));
+}
+
+ACE_INLINE ACE_U_LongLong
+ACE_U_LongLong::operator<< (const u_int n) const
+{
+ const ACE_UINT32 carry_mask = l_ () >> (32 - n);
+ ACE_U_LongLong ret (n < 32 ? l_ () << n : 0,
+ n < 32 ? (h_ () << n) | carry_mask : carry_mask);
+
+ return ret;
+}
+
+ACE_INLINE ACE_U_LongLong &
+ACE_U_LongLong::operator<<= (const u_int n)
+{
+ const ACE_UINT32 carry_mask = l_ () >> (32 - n);
+ h_ () = n < 32 ? (h_ () << n) | carry_mask : carry_mask;
+
+ // g++ 2.7.2.3/Solaris 2.5.1 doesn't modify l_ () if shifted by 32.
+ l_ () = n < 32 ? l_ () << n : 0;
+
+ return *this;
+}
+
+ACE_INLINE ACE_U_LongLong
+ACE_U_LongLong::operator>> (const u_int n) const
+{
+ const ACE_UINT32 carry_mask = h_ () << (32 - n);
+ ACE_U_LongLong ret (n < 32 ? (l_ () >> n) | carry_mask : 0,
+ n < 32 ? h_ () >> n : 0);
+
+ return ret;
+}
+
+ACE_INLINE ACE_U_LongLong &
+ACE_U_LongLong::operator>>= (const u_int n)
+{
+ const ACE_UINT32 carry_mask = h_ () << (32 - n);
+ l_ () = n < 32 ? (l_ () >> n) | carry_mask : carry_mask;
+ h_ () = n < 32 ? h_ () >> n : 0;
+
+ return *this;
+}
+
+ACE_INLINE double
+ACE_U_LongLong::operator/ (const double n) const
+{
+ // See the derivation above in operator/ (const ACE_UINT32).
+
+ return ((double) 0xffffffffu - n + 1.0) / n * h_ () +
+ (double) h_ () + (double) l_ () / n;
+}
+
+ACE_INLINE ACE_U_LongLong &
+ACE_U_LongLong::operator+= (const ACE_U_LongLong &n)
+{
+ h_ () += n.h_ ();
+ l_ () += n.l_ ();
+ if (l_ () < n.l_ ()) /* carry */ ++h_ ();
+
+ return *this;
+}
+
+ACE_INLINE ACE_U_LongLong &
+ACE_U_LongLong::operator+= (const ACE_UINT32 n)
+{
+ return operator+= (ACE_static_cast (const ACE_U_LongLong, n));
+}
+
+#define ACE_HIGHBIT (~(~0UL >> 1))
+
+ACE_INLINE ACE_UINT32
+ACE_U_LongLong::ul_shift (ACE_UINT32 a, ACE_UINT32 c_in, ACE_UINT32 *c_out) const
+{
+ const ACE_UINT32 b = (a << 1) | c_in;
+ *c_out = (*c_out << 1) + ((a & ACE_HIGHBIT) > 0);
+
+ return b;
+}
+
+ACE_INLINE ACE_U_LongLong
+ACE_U_LongLong::ull_shift (ACE_U_LongLong a,
+ ACE_UINT32 c_in,
+ ACE_UINT32 *c_out) const
+{
+ ACE_U_LongLong b;
+
+ b.l_ () = (a.l_ () << 1) | c_in;
+ c_in = ((a.l_ () & ACE_HIGHBIT) > 0);
+ b.h_ () = (a.h_ () << 1) | c_in;
+ *c_out = (*c_out << 1) + ((a.h_ () & ACE_HIGHBIT) > 0);
+
+ return b;
+}
+
+ACE_INLINE ACE_U_LongLong
+ACE_U_LongLong::ull_add (ACE_U_LongLong a, ACE_U_LongLong b, ACE_UINT32 *carry) const
+{
+ ACE_U_LongLong r (0, 0);
+ ACE_UINT32 c1, c2, c3, c4;
+
+ c1 = a.l_ () % 2;
+ c2 = b.l_ () % 2;
+ c3 = 0;
+
+ r.l_ () = a.l_ ()/2 + b.l_ ()/2 + (c1+c2)/2;
+ r.l_ () = ul_shift (r.l_ (), (c1+c2)%2, &c3);
+
+ c1 = a.h_ () % 2;
+ c2 = b.h_ () % 2;
+ c4 = 0;
+
+ r.h_ () = a.h_ ()/2 + b.h_ ()/2 + (c1+c2+c3)/2;
+ r.h_ () = ul_shift (r.h_ (), (c1+c2+c3)%2, &c4);
+
+ *carry = c4;
+
+ return r;
+}
+
+ACE_INLINE ACE_U_LongLong
+ACE_U_LongLong::ull_mult (ACE_U_LongLong a, ACE_UINT32 b, ACE_UINT32 *carry) const
+{
+ register ACE_UINT32 mask = ACE_HIGHBIT;
+ const ACE_U_LongLong zero (0, 0);
+ ACE_U_LongLong accum (0, 0);
+ ACE_UINT32 c;
+
+ *carry = 0;
+ if (b > 0)
+ do
+ {
+ accum = ull_shift (accum, 0U, carry);
+ if (b & mask)
+ accum = ull_add (accum, a, &c);
+ else
+ accum = ull_add (accum, zero, &c);
+ *carry += c;
+ mask >>= 1;
+ }
+ while (mask > 0);
+
+ return accum;
+}
+
+ACE_INLINE ACE_U_LongLong
+ACE_U_LongLong::operator* (const ACE_UINT32 n) const
+{
+ ACE_UINT32 carry; // will throw the carry away
+
+ return ull_mult (*this, n, &carry);
+}
+
+ACE_INLINE ACE_U_LongLong &
+ACE_U_LongLong::operator*= (const ACE_UINT32 n)
+{
+ ACE_UINT32 carry; // will throw the carry away
+
+ return *this = ull_mult (*this, n, &carry);
+}
+
+ACE_INLINE ACE_U_LongLong &
+ACE_U_LongLong::operator-= (const ACE_U_LongLong &n)
+{
+ h_ () -= n.h_ ();
+ if (l_ () < n.l_ ()) /* borrow */ --h_ ();
+ l_ () -= n.l_ ();
+
+ return *this;
+}
+
+ACE_INLINE ACE_U_LongLong &
+ACE_U_LongLong::operator-= (const ACE_UINT32 n)
+{
+ return operator-= (ACE_static_cast (const ACE_U_LongLong, n));
+}
+
+ACE_INLINE ACE_U_LongLong &
+ACE_U_LongLong::operator++ ()
+{
+ ++l_ ();
+ if (l_ () == 0) /* carry */ ++h_ ();
+
+ return *this;
+}
+
+ACE_INLINE ACE_U_LongLong &
+ACE_U_LongLong::operator-- ()
+{
+ if (l_ () == 0) /* borrow */ --h_ ();
+ --l_ ();
+
+ return *this;
+}
+
+ACE_INLINE ACE_U_LongLong &
+ACE_U_LongLong::operator|= (const ACE_U_LongLong n)
+{
+ l_ () |= n.l_ ();
+ h_ () |= n.h_ ();
+
+ return *this;
+}
+
+ACE_INLINE ACE_U_LongLong &
+ACE_U_LongLong::operator|= (const ACE_UINT32 n)
+{
+ return operator|= (ACE_static_cast (const ACE_U_LongLong, n));
+}
+
+ACE_INLINE ACE_U_LongLong &
+ACE_U_LongLong::operator&= (const ACE_U_LongLong n)
+{
+ l_ () &= n.l_ ();
+ h_ () &= n.h_ ();
+
+ return *this;
+}
+
+ACE_INLINE ACE_U_LongLong &
+ACE_U_LongLong::operator&= (const ACE_UINT32 n)
+{
+ return operator&= (ACE_static_cast (const ACE_U_LongLong, n));
+}
+
+ACE_INLINE ACE_UINT32
+ACE_U_LongLong::operator/ (const ACE_UINT32 n) const
+{
+ // This takes advantage of the fact that the return type has only 32
+ // bits. Replace 0x100000000 with 0xffffffff + 1 because the former
+ // has 33 bits.
+ // Quotient = (0x100000000u * hi_ + lo_) / n
+ // = ((0x100000000u - n + n) * hi_ + lo_) / n
+ // = ((0x100000000u - n) / n * hi_ + hi_ * n / n + lo_ / n
+ // = (0x100000000u - n) / n * hi_ + hi_ + lo_ / n
+ // = (0xffffffffu - n + 1) / n * hi_ + hi_ + lo_ / n
+
+ return (0xffffffffu - n + 1) / n * h_ () + h_ () + l_ () / n;
+}
+
+ACE_INLINE ACE_UINT32
+ACE_U_LongLong::operator% (const ACE_UINT32 n) const
+{
+ // Because the argument is an ACE_UINT32, the result can never be
+ // bigger than 32 bits. Replace 0x100000000 with 0xffffffff + 1
+ // because the former has 33 bits.
+ // Mod = (0x100000000u * hi_ + lo_) % n
+ // = (0x100000000u % n * hi_ + lo_ % n) % n
+ // = ((0x100000000u - n) % n * hi_ + lo_ % n) % n
+ // = ((0xffffffffu - n + 1) % n * hi_ + lo_ % n) % n
+
+ return ((0xffffffff - n + 1) % n * h_ () + l_ () % n) % n;
+}
+
+ACE_INLINE ACE_UINT32
+ACE_U_LongLong::operator| (const ACE_INT32 n) const
+{
+ return l_ () | n;
+}
+
+ACE_INLINE ACE_UINT32
+ACE_U_LongLong::operator& (const ACE_INT32 n) const
+{
+ return l_ () & n;
+}
+
+ACE_INLINE ACE_U_LongLong
+ACE_U_LongLong::operator* (const ACE_INT32 n) const
+{
+ return operator* ((ACE_UINT32) n);
+}
+
+ACE_INLINE ACE_U_LongLong &
+ACE_U_LongLong::operator*= (const ACE_INT32 n)
+{
+ return operator*= ((ACE_UINT32) n);
+}
+
+ACE_INLINE ACE_UINT32
+ACE_U_LongLong::operator/ (const ACE_INT32 n) const
+{
+ return operator/ ((ACE_UINT32) n);
+}
+
+#if ACE_SIZEOF_INT == 4
+ACE_INLINE ACE_UINT32
+ACE_U_LongLong::operator/ (const u_long n) const
+{
+ return operator/ ((ACE_UINT32) n);
+}
+
+ACE_INLINE ACE_UINT32
+ACE_U_LongLong::operator/ (const long n) const
+{
+ return operator/ ((ACE_UINT32) n);
+}
+
+#else /* ACE_SIZEOF_INT != 4 */
+ACE_INLINE ACE_UINT32
+ACE_U_LongLong::operator/ (const u_int n) const
+{
+ return operator/ ((ACE_UINT32) n);
+}
+
+ACE_INLINE ACE_UINT32
+ACE_U_LongLong::operator/ (const int n) const
+{
+ return operator/ ((ACE_UINT32) n);
+}
+#endif /* ACE_SIZEOF_INT != 4 */
+
+#endif /* ACE_LACKS_LONGLONG_T */
diff --git a/ace/OS/Date_Time.cpp b/ace/OS/Date_Time.cpp
new file mode 100644
index 00000000000..22b6532c610
--- /dev/null
+++ b/ace/OS/Date_Time.cpp
@@ -0,0 +1,10 @@
+// Date_Time.cpp
+// $Id$
+
+#include "Date_Time.h"
+
+#if defined (ACE_LACKS_INLINE_FUNCTIONS)
+#include "Date_Time.i"
+#endif
+
+ACE_RCSID(ace, Date_Time, "$Id$")
diff --git a/ace/OS/Date_Time.h b/ace/OS/Date_Time.h
new file mode 100644
index 00000000000..52d42ec3f89
--- /dev/null
+++ b/ace/OS/Date_Time.h
@@ -0,0 +1,105 @@
+/* -*- C++ -*- */
+
+//=============================================================================
+/**
+ * @file Date_Time.h
+ *
+ * $Id$
+ *
+ * @author Tim Harrison (harrison@cs.wustl.edu) (and he's darn proud of this ;-))
+ *
+ */
+//=============================================================================
+
+#ifndef ACE_DATE_TIME_H
+#define ACE_DATE_TIME_H
+#include "ace/pre.h"
+
+#include "ace/ACE.h"
+
+#if !defined (ACE_LACKS_PRAGMA_ONCE)
+# pragma once
+#endif /* ACE_LACKS_PRAGMA_ONCE */
+
+/**
+ * @class ACE_Date_Time
+ *
+ * @brief System independent representation of date and time.
+ */
+class ACE_Export ACE_Date_Time
+{
+public:
+ /// Constructor initializes current time/date info.
+ ACE_Date_Time (void);
+
+ /// Constructor with init values, no check for validy
+ /// Set/get portions of ACE_Date_Time, no check for validity.
+ ACE_Date_Time (long day,
+ long month = 0,
+ long year = 0,
+ long hour = 0,
+ long minute = 0,
+ long second = 0,
+ long microsec = 0);
+
+ /// Update to the current time/date.
+ void update (void);
+
+ /// Get day.
+ long day (void) const;
+
+ /// Set day.
+ void day (long day);
+
+ /// Get month.
+ long month (void) const;
+
+ /// Set month.
+ void month (long month);
+
+ /// Get year.
+ long year (void) const;
+
+ /// Set year.
+ void year (long year);
+
+ /// Get hour.
+ long hour (void) const;
+
+ /// Set hour.
+ void hour (long hour);
+
+ /// Get minute.
+ long minute (void) const;
+
+ /// Set minute.
+ void minute (long minute);
+
+ /// Get second.
+ long second (void) const;
+
+ /// Set second.
+ void second (long second);
+
+ /// Get microsec.
+ long microsec (void) const;
+
+ /// Set microsec.
+ void microsec (long microsec);
+
+private:
+ long day_;
+ long month_;
+ long year_;
+ long hour_;
+ long minute_;
+ long second_;
+ long microsec_;
+};
+
+#if !defined (ACE_LACKS_INLINE_FUNCTIONS)
+#include "Date_Time.i"
+#endif
+
+#include "ace/post.h"
+#endif /* ACE_DATE_TIME_H */
diff --git a/ace/OS/Date_Time.i b/ace/OS/Date_Time.i
new file mode 100644
index 00000000000..9913f129327
--- /dev/null
+++ b/ace/OS/Date_Time.i
@@ -0,0 +1,162 @@
+/* -*- C++ -*- */
+// $Id$
+
+// Date_Time.i
+
+ASYS_INLINE void
+ACE_Date_Time::update (void)
+{
+ ACE_TRACE ("ACE_Date_Time::update");
+
+ ACE_Time_Value now = ACE_OS::gettimeofday ();
+ time_t time = now.sec ();
+ struct tm *tm_time = ACE_OS::localtime (&time);
+ this->day_ = tm_time->tm_mday;
+ this->month_ = tm_time->tm_mon + 1; // localtime's months are 0-11
+ this->year_ = tm_time->tm_year + 1900; // localtime reports years since 1900
+ this->hour_ = tm_time->tm_hour;
+ this->minute_ = tm_time->tm_min;
+ this->second_ = tm_time->tm_sec;
+ this->microsec_ = now.usec ();
+}
+
+ASYS_INLINE
+ACE_Date_Time::ACE_Date_Time (void)
+{
+ ACE_TRACE ("ACE_Date_Time::ACE_Date_Time");
+ this->update ();
+}
+
+// Constructor with init values, no check for validy
+ASYS_INLINE
+ACE_Date_Time::ACE_Date_Time (long day,
+ long month,
+ long year,
+ long hour,
+ long minute,
+ long second,
+ long microsec)
+ : day_ (day),
+ month_ (month),
+ year_ (year),
+ hour_ (hour),
+ minute_ (minute),
+ second_ (second),
+ microsec_ (microsec)
+{
+ ACE_TRACE ("ACE_Date_Time::ACE_Date_Time");
+}
+
+// set/get portions of ACE_Date_Time, no check for validy
+
+// get day
+ASYS_INLINE long
+ACE_Date_Time::day (void) const
+{
+ ACE_TRACE ("ACE_Date_Time::day");
+ return day_;
+}
+
+// set day
+ASYS_INLINE void
+ACE_Date_Time::day (long day)
+{
+ ACE_TRACE ("ACE_Date_Time::day");
+ day_ = day;
+}
+
+// get month
+ASYS_INLINE long
+ACE_Date_Time::month (void) const
+{
+ ACE_TRACE ("ACE_Date_Time::month");
+ return month_;
+}
+
+// set month
+ASYS_INLINE void
+ACE_Date_Time::month (long month)
+{
+ ACE_TRACE ("ACE_Date_Time::month");
+ month_ = month;
+}
+
+// get year
+ASYS_INLINE long
+ACE_Date_Time::year (void) const
+{
+ ACE_TRACE ("ACE_Date_Time::year");
+ return year_;
+}
+
+// set year
+ASYS_INLINE void
+ACE_Date_Time::year (long year)
+{
+ ACE_TRACE ("ACE_Date_Time::year");
+ year_ = year;
+}
+
+// get hour
+ASYS_INLINE long
+ACE_Date_Time::hour (void) const
+{
+ ACE_TRACE ("ACE_Date_Time::hour");
+ return hour_;
+}
+
+// set hour
+ASYS_INLINE void
+ACE_Date_Time::hour (long hour)
+{
+ ACE_TRACE ("ACE_Date_Time::hour");
+ hour_ = hour;
+}
+
+// get minute
+ASYS_INLINE long
+ACE_Date_Time::minute (void) const
+{
+ ACE_TRACE ("ACE_Date_Time::minute");
+ return minute_;
+}
+
+// set minute
+ASYS_INLINE void
+ACE_Date_Time::minute (long minute)
+{
+ ACE_TRACE ("ACE_Date_Time::minute");
+ minute_ = minute;
+}
+
+// get second
+ASYS_INLINE long
+ACE_Date_Time::second (void) const
+{
+ ACE_TRACE ("ACE_Date_Time::second");
+ return second_;
+}
+
+// set second
+ASYS_INLINE void
+ACE_Date_Time::second (long second)
+{
+ ACE_TRACE ("ACE_Date_Time::second");
+ second_ = second;
+}
+
+// get microsec
+ASYS_INLINE long
+ACE_Date_Time::microsec (void) const
+{
+ ACE_TRACE ("ACE_Date_Time::microsec");
+ return microsec_;
+}
+
+// set microsec
+ASYS_INLINE void
+ACE_Date_Time::microsec (long microsec)
+{
+ ACE_TRACE ("ACE_Date_Time::microsec");
+ microsec_ = microsec;
+}
diff --git a/ace/OS/Global_Macros.h b/ace/OS/Global_Macros.h
new file mode 100644
index 00000000000..7715199b128
--- /dev/null
+++ b/ace/OS/Global_Macros.h
@@ -0,0 +1,115 @@
+// -*- C++ -*-
+
+//=============================================================================
+/**
+ * @file Global_Macros.h
+ *
+ * $Id$
+ *
+ * @author Douglas C. Schmidt <schmidt@cs.wustl.edu>
+ * @author Jesper S. M|ller<stophph@diku.dk>
+ * @author and a cast of thousands...
+ * @This one is split from the famous OS.h
+ */
+//=============================================================================
+
+#ifndef ACE_GLOBAL_MACROS_H
+#define ACE_GLOBAL_MACROS_H
+#include "ace/pre.h"
+
+// Included just keep compilers that see #pragma dierctive first
+// happy.
+#include "ace/config-all.h"
+
+#if !defined (ACE_LACKS_PRAGMA_ONCE)
+# pragma once
+#endif /* ACE_LACKS_PRAGMA_ONCE */
+
+
+// Start Global Macros
+# define ACE_BEGIN_DUMP ACE_LIB_TEXT ("\n====\n(%P|%t|%x)")
+# define ACE_END_DUMP ACE_LIB_TEXT ("====\n")
+
+
+
+# if defined (ACE_NDEBUG)
+# define ACE_DB(X)
+# else
+# define ACE_DB(X) X
+# endif /* ACE_NDEBUG */
+
+// ACE_NO_HEAP_CHECK macro can be used to suppress false report of
+// memory leaks. It turns off the built-in heap checking until the
+// block is left. The old state will then be restored Only used for
+// Win32 (in the moment).
+# if defined (ACE_WIN32)
+
+# if defined (_DEBUG) && !defined (ACE_HAS_WINCE) && !defined (__BORLANDC__)
+# include /**/ <crtdbg.h>
+
+class ACE_OS_Export ACE_No_Heap_Check
+{
+public:
+ ACE_No_Heap_Check (void)
+ : old_state (_CrtSetDbgFlag (_CRTDBG_REPORT_FLAG))
+ { _CrtSetDbgFlag (old_state & ~_CRTDBG_ALLOC_MEM_DF);}
+ ~ACE_No_Heap_Check (void) { _CrtSetDbgFlag (old_state);}
+private:
+ int old_state;
+};
+# define ACE_NO_HEAP_CHECK ACE_No_Heap_Check ____no_heap;
+# else /* !_DEBUG */
+# define ACE_NO_HEAP_CHECK
+# endif /* _DEBUG */
+# else /* !ACE_WIN32 */
+# define ACE_NO_HEAP_CHECK
+# endif /* ACE_WIN32 */
+
+// Turn a number into a string.
+# define ACE_ITOA(X) #X
+
+// Create a string of a server address with a "host:port" format.
+# define ACE_SERVER_ADDRESS(H,P) H":"P
+
+// A couple useful inline functions for checking whether bits are
+// enabled or disabled.
+
+// Efficiently returns the least power of two >= X...
+# define ACE_POW(X) (((X) == 0)?1:(X-=1,X|=X>>1,X|=X>>2,X|=X>>4,X|=X>>8,X|=X>>16,(++X)))
+# define ACE_EVEN(NUM) (((NUM) & 1) == 0)
+# define ACE_ODD(NUM) (((NUM) & 1) == 1)
+# define ACE_BIT_ENABLED(WORD, BIT) (((WORD) & (BIT)) != 0)
+# define ACE_BIT_DISABLED(WORD, BIT) (((WORD) & (BIT)) == 0)
+# define ACE_BIT_CMP_MASK(WORD, BIT, MASK) (((WORD) & (BIT)) == MASK)
+# define ACE_SET_BITS(WORD, BITS) (WORD |= (BITS))
+# define ACE_CLR_BITS(WORD, BITS) (WORD &= ~(BITS))
+
+# if !defined (ACE_ENDLESS_LOOP)
+# define ACE_ENDLESS_LOOP
+# endif /* ! ACE_ENDLESS_LOOP */
+
+# if defined (ACE_NEEDS_FUNC_DEFINITIONS)
+ // It just evaporated ;-) Not pleasant.
+# define ACE_UNIMPLEMENTED_FUNC(f)
+# else
+# define ACE_UNIMPLEMENTED_FUNC(f) f;
+# endif /* ACE_NEEDS_FUNC_DEFINITIONS */
+
+// Easy way to designate that a class is used as a pseudo-namespace.
+// Insures that g++ "friendship" anamolies are properly handled.
+# define ACE_CLASS_IS_NAMESPACE(CLASSNAME) \
+private: \
+CLASSNAME (void); \
+CLASSNAME (const CLASSNAME&); \
+friend class ace_dewarn_gplusplus
+
+
+# if (ACE_NTRACE == 1)
+# define ACE_TRACE(X)
+# else
+# define ACE_TRACE(X) ACE_Trace ____ (ACE_LIB_TEXT (X), __LINE__, ACE_LIB_TEXT (__FILE__))
+# endif /* ACE_NTRACE */
+
+
+#include "ace/post.h"
+#endif /*ACE_GLOBAL_MACROS_H*/
diff --git a/ace/OS/Handle_Gobbler.h b/ace/OS/Handle_Gobbler.h
new file mode 100644
index 00000000000..f007f2f0e96
--- /dev/null
+++ b/ace/OS/Handle_Gobbler.h
@@ -0,0 +1,66 @@
+
+//=============================================================================
+/**
+ * @file Handle_Gobbler.h
+ *
+ * $Id$
+ *
+ * @author Kirthika Parameswaran <kirthika@cs.wustl.edu>
+ * @author Irfan Pyarali <irfan@cs.wustl.edu>
+ */
+//=============================================================================
+
+
+#ifndef ACE_HANDLE_GOBBLER_H
+#define ACE_HANDLE_GOBBLER_H
+#include "ace/pre.h"
+
+#include "OS.h"
+
+#if !defined (ACE_LACKS_PRAGMA_ONCE)
+# pragma once
+#endif /* ACE_LACKS_PRAGMA_ONCE */
+
+#include "ace/Unbounded_Set.h"
+
+/**
+ * @class ACE_Handle_Gobbler
+ *
+ * @brief This class gobbles up handles.
+ *
+ * This is useful when we need to control the number of handles
+ * available for a process. This class is mostly used for
+ * testing purposes.
+ */
+class ACE_Handle_Gobbler
+{
+public:
+
+ /// Destructor. Cleans up any remaining handles.
+ inline ~ACE_Handle_Gobbler (void);
+
+ /**
+ * Handles are opened continously until the process runs out of
+ * them, and then <n_handles_to_keep_available> handles are closed
+ * (freed) thereby making them usable in the future.
+ */
+ inline int consume_handles (size_t n_handles_to_keep_available);
+
+ /// Free up <n_handles>.
+ inline int free_handles (size_t n_handles);
+
+ /// All remaining handles are closed.
+ inline void close_remaining_handles (void);
+
+private:
+
+ typedef ACE_Unbounded_Set<ACE_HANDLE> HANDLE_SET;
+
+ /// The container which holds the open descriptors.
+ HANDLE_SET handle_set_;
+};
+
+#include "Handle_Gobbler.i"
+
+#include "ace/post.h"
+#endif /* ACE_HANDLE_GOBBLER_H */
diff --git a/ace/OS/Handle_Gobbler.i b/ace/OS/Handle_Gobbler.i
new file mode 100644
index 00000000000..f4af340a012
--- /dev/null
+++ b/ace/OS/Handle_Gobbler.i
@@ -0,0 +1,88 @@
+// $Id$
+
+// Since this is only included in Handle_Gobbler.h, these should be
+// inline, not ACE_INLINE.
+// FUZZ: disable check_for_inline
+
+inline void
+ACE_Handle_Gobbler::close_remaining_handles (void)
+{
+ HANDLE_SET::iterator iterator =
+ this->handle_set_.begin ();
+
+ HANDLE_SET::iterator end =
+ this->handle_set_.end ();
+
+ for (;
+ iterator != end;
+ ++iterator)
+ {
+ ACE_OS::close (*iterator);
+ }
+}
+
+inline
+ACE_Handle_Gobbler::~ACE_Handle_Gobbler (void)
+{
+ this->close_remaining_handles ();
+}
+
+inline int
+ACE_Handle_Gobbler::free_handles (size_t n_handles)
+{
+ HANDLE_SET::iterator iterator =
+ this->handle_set_.begin ();
+
+ HANDLE_SET::iterator end =
+ this->handle_set_.end ();
+
+ for (;
+ iterator != end && n_handles > 0;
+ ++iterator, --n_handles)
+ {
+ int result = ACE_OS::close (*iterator);
+ if (result != 0)
+ return result;
+ }
+
+ return 0;
+}
+
+inline int
+ACE_Handle_Gobbler::consume_handles (size_t n_handles_to_keep_available)
+{
+ int result = 0;
+
+#if defined(ACE_WIN32)
+ // On Win32, this style of gobbling doesn't seem to work.
+ ACE_UNUSED_ARG(n_handles_to_keep_available);
+
+#else
+
+ while (1)
+ {
+ ACE_HANDLE handle = ACE_OS::open (ACE_DEV_NULL, O_WRONLY);
+
+ if (handle == ACE_INVALID_HANDLE)
+ {
+ if (ACE::out_of_handles (errno))
+ {
+ result = this->free_handles (n_handles_to_keep_available);
+ break;
+ }
+ else
+ {
+ result = -1;
+ break;
+ }
+ }
+
+ result = this->handle_set_.insert (handle);
+ if (result == -1)
+ break;
+ }
+
+#endif /* ACE_WIN32 */
+
+ return result;
+}
diff --git a/ace/OS/Handle_Ops.cpp b/ace/OS/Handle_Ops.cpp
new file mode 100644
index 00000000000..81ff14423aa
--- /dev/null
+++ b/ace/OS/Handle_Ops.cpp
@@ -0,0 +1,41 @@
+// $Id$
+
+#include "Handle_Ops.h"
+
+#if defined (ACE_LACKS_INLINE_FUNCTIONS)
+#include "Handle_Ops.i"
+#endif /* ACE_LACKS_INLINE_FUNCTIONS */
+
+ACE_RCSID(ace, Handle_Ops, "$Id$")
+
+ACE_HANDLE
+ACE_Handle_Ops::handle_timed_open (ACE_Time_Value *timeout,
+ const ACE_TCHAR *name,
+ int flags,
+ int perms)
+{
+ ACE_TRACE ("ACE_Handle_Ops::handle_timed_open");
+
+ if (timeout != 0)
+ {
+#if !defined (ACE_WIN32)
+ // On Win32, ACE_NONBLOCK gets recognized as O_WRONLY so we
+ // don't use it there
+ flags |= ACE_NONBLOCK;
+#endif /* ACE_WIN32 */
+
+ // Open the named pipe or file using non-blocking mode...
+ ACE_HANDLE handle = ACE_OS::open (name,
+ flags,
+ perms);
+ if (handle == ACE_INVALID_HANDLE
+ && (errno == EWOULDBLOCK
+ && (timeout->sec () > 0 || timeout->usec () > 0)))
+ // This expression checks if we were polling.
+ errno = ETIMEDOUT;
+
+ return handle;
+ }
+ else
+ return ACE_OS::open (name, flags, perms);
+}
diff --git a/ace/OS/Handle_Ops.h b/ace/OS/Handle_Ops.h
new file mode 100644
index 00000000000..f89af054d99
--- /dev/null
+++ b/ace/OS/Handle_Ops.h
@@ -0,0 +1,43 @@
+
+//=============================================================================
+/**
+ * @file Handle_Ops.h
+ *
+ * $Id$
+ *
+ * This class consolidates the operations on the Handles.
+ *
+ *
+ * @author Priyanka Gontla <pgontla@ece.uci.edu>
+ */
+//=============================================================================
+
+
+#ifndef ACE_HANDLE_OPS_H
+#define ACE_HANDLE_OPS_H
+#include "ace/pre.h"
+
+#include "OS.h"
+
+class ACE_Export ACE_Handle_Ops
+{
+public:
+ // = Operations on HANDLEs.
+
+ /**
+ * Wait up to <timeout> amount of time to actively open a device.
+ * This method doesn't perform the <connect>, it just does the timed
+ * wait...
+ */
+ static ACE_HANDLE handle_timed_open (ACE_Time_Value *timeout,
+ const ACE_TCHAR *name,
+ int flags,
+ int perms);
+};
+
+#if !defined (ACE_LACKS_INLINE_FUNCTIONS)
+#include "Handle_Ops.i"
+#endif /* ACE_LACKS_INLINE_FUNCTIONS */
+
+#include "ace/post.h"
+#endif /* ACE_HANDLE_OPS_H */
diff --git a/ace/OS/Handle_Ops.i b/ace/OS/Handle_Ops.i
new file mode 100644
index 00000000000..cfa1da318d3
--- /dev/null
+++ b/ace/OS/Handle_Ops.i
@@ -0,0 +1 @@
+// $Id$
diff --git a/ace/OS/Handle_Set.cpp b/ace/OS/Handle_Set.cpp
new file mode 100644
index 00000000000..9528a2feff1
--- /dev/null
+++ b/ace/OS/Handle_Set.cpp
@@ -0,0 +1,558 @@
+// Handle_Set.cpp
+// $Id$
+
+#include "Handle_Set.h"
+
+#if 0
+#include "ace/Logging/Log_Msg.h"
+#endif
+
+#if !defined (__ACE_INLINE__)
+#include "Handle_Set.i"
+#endif /* __ACE_INLINE__ */
+
+ACE_RCSID(ace, Handle_Set, "$Id$")
+
+ACE_ALLOC_HOOK_DEFINE(ACE_Handle_Set)
+
+#if defined (linux) && __GLIBC__ > 1 && __GLIBC_MINOR__ >= 1 && !defined (_XOPEN_SOURCE)
+ // XPG4.2 requires the fds_bits member name, so it is not enabled by
+ // default on Linux/glibc-2.1.x systems. Instead use "__fds_bits."
+ // Ugly, but "what are you going to do?" 8-)
+#define fds_bits __fds_bits
+#endif /* linux && __GLIBC__ > 1 && __GLIBC_MINOR__ >= 1 && !_GNU_SOURCE */
+
+#if 0
+void
+ACE_Handle_Set::dump (void) const
+{
+ ACE_TRACE ("ACE_Handle_Set::dump");
+
+ ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this));
+
+ ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("\nsize_ = %d"), this->size_));
+ ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("\nmax_handle_ = %d"), this->max_handle_));
+ ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("\n[ ")));
+
+#if defined (ACE_WIN32)
+ for (size_t i = 0; i < (size_t) this->mask_.fd_count + 1; i++)
+ ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT (" %x "), this->mask_.fd_array[i]));
+#else /* !ACE_WIN32 */
+ for (ACE_HANDLE i = 0; i < this->max_handle_ + 1; i++)
+ if (this->is_set (i))
+ ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT (" %d "), i));
+#endif /* ACE_WIN32 */
+
+ ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT (" ]\n")));
+ ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP));
+}
+#endif
+
+// Table that maps bytes to counts of the enabled bits in each value
+// from 0 to 255,
+//
+// nbits_[0] == 0
+//
+// because there are no bits enabled for the value 0.
+//
+// nbits_[5] == 2
+//
+// because there are 2 bits enabled in the value 5, i.e., it's
+// 101 in binary.
+
+const char ACE_Handle_Set::nbits_[256] =
+{
+ 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4,
+ 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
+ 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
+ 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
+ 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
+ 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
+ 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
+ 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
+ 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
+ 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
+ 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
+ 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
+ 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
+ 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
+ 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
+ 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8};
+
+// Constructor, initializes the bitmask to all 0s.
+
+ACE_Handle_Set::ACE_Handle_Set (void)
+{
+ ACE_TRACE ("ACE_Handle_Set::ACE_Handle_Set");
+ this->reset ();
+}
+
+ACE_Handle_Set::ACE_Handle_Set (const ACE_FD_SET_TYPE &fd_mask)
+{
+ ACE_TRACE ("ACE_Handle_Set::ACE_Handle_Set");
+ this->reset ();
+ ACE_OS::memcpy ((void *) &this->mask_,
+ (void *) &fd_mask,
+ sizeof this->mask_);
+#if !defined (ACE_WIN32)
+ this->sync (ACE_Handle_Set::MAXSIZE);
+#if defined (ACE_HAS_BIG_FD_SET)
+ this->min_handle_ = 0;
+#endif /* ACE_HAS_BIG_FD_SET */
+#endif /* !ACE_WIN32 */
+}
+
+// Counts the number of bits enabled in N. Uses a table lookup to
+// speed up the count.
+
+int
+ACE_Handle_Set::count_bits (u_long n)
+{
+
+ ACE_TRACE ("ACE_Handle_Set::count_bits");
+#if defined (ACE_HAS_HANDLE_SET_OPTIMIZED_FOR_SELECT)
+ register int rval = 0;
+
+ // Count the number of enabled bits in <n>. This algorithm is very
+ // fast, i.e., O(enabled bits in n).
+
+ for (register u_long m = n;
+ m != 0;
+ m &= m - 1)
+ rval++;
+
+ return rval;
+#else
+ return (ACE_Handle_Set::nbits_[n & 0xff]
+ + ACE_Handle_Set::nbits_[(n >> 8) & 0xff]
+ + ACE_Handle_Set::nbits_[(n >> 16) & 0xff]
+ + ACE_Handle_Set::nbits_[(n >> 24) & 0xff]);
+#endif /* ACE_HAS_HANDLE_SET_OPTIMIZED_FOR_SELECT */
+}
+
+#if defined (ACE_HAS_BIG_FD_SET)
+// Find the bit position counting from right to left worst case
+// (1<<31) is 8.
+
+int
+ACE_Handle_Set::bitpos (u_long bit)
+{
+ register int l = 0;
+ register u_long n = bit - 1;
+
+ // This is a fast count method when have the most significative bit.
+
+ while (n >> 8)
+ {
+ n >>= 8;
+ l += 8;
+ }
+
+ // Is greater than 15?
+ if (n & 16)
+ {
+ n >>= 4;
+ l += 4;
+ }
+
+ // Count number remaining bits.
+ while (n != 0)
+ {
+ n &= n - 1;
+ l++;
+ }
+ return l;
+}
+#endif /* ACE_HAS_BIG_FD_SET */
+
+// Synchronize the underlying FD_SET with the MAX_FD and the SIZE.
+
+#if defined (ACE_USE_SHIFT_FOR_EFFICIENCY)
+// These don't work because shifting right 3 bits is not the same as
+// dividing by 3, e.g., dividing by 8 requires shifting right 3 bits.
+// In order to do the shift, we need to calculate the number of bits
+// at some point.
+#define ACE_DIV_BY_WORDSIZE(x) ((x) >> ((int) ACE_Handle_Set::WORDSIZE))
+#define ACE_MULT_BY_WORDSIZE(x) ((x) << ((int) ACE_Handle_Set::WORDSIZE))
+#else
+#define ACE_DIV_BY_WORDSIZE(x) ((x) / ((int) ACE_Handle_Set::WORDSIZE))
+#define ACE_MULT_BY_WORDSIZE(x) ((x) * ((int) ACE_Handle_Set::WORDSIZE))
+#endif /* ACE_USE_SHIFT_FOR_EFFICIENCY */
+
+void
+ACE_Handle_Set::sync (ACE_HANDLE max)
+{
+ ACE_TRACE ("ACE_Handle_Set::sync");
+#if !defined (ACE_WIN32)
+ fd_mask *maskp = (fd_mask *)(this->mask_.fds_bits);
+ this->size_ = 0;
+
+ for (int i = ACE_DIV_BY_WORDSIZE (max - 1);
+ i >= 0;
+ i--)
+ this->size_ += ACE_Handle_Set::count_bits (maskp[i]);
+
+ this->set_max (max);
+#else
+ ACE_UNUSED_ARG (max);
+#endif /* !ACE_WIN32 */
+}
+
+// Resets the MAX_FD after a clear of the original MAX_FD.
+
+void
+ACE_Handle_Set::set_max (ACE_HANDLE current_max)
+{
+ ACE_TRACE ("ACE_Handle_Set::set_max");
+#if !defined(ACE_WIN32)
+ fd_mask * maskp = (fd_mask *)(this->mask_.fds_bits);
+
+ if (this->size_ == 0)
+ this->max_handle_ = ACE_INVALID_HANDLE;
+ else
+ {
+ int i;
+
+ for (i = ACE_DIV_BY_WORDSIZE (current_max - 1);
+ maskp[i] == 0;
+ i--)
+ continue;
+
+#if defined (ACE_PSOS)
+ this->max_handle_ = ACE_MULT_BY_WORDSIZE (i);
+ for (fd_mask val = maskp[i];
+ (val & ACE_MSB_MASK) != 0;
+ val = (val << 1))
+ this->max_handle_++;
+#elif 1 /* !defined(ACE_HAS_BIG_FD_SET) */
+ this->max_handle_ = ACE_MULT_BY_WORDSIZE (i);
+ for (fd_mask val = maskp[i];
+ (val & ~1) != 0; // This obscure code is needed since "bit 0" is in location 1...
+ val = (val >> 1) & ACE_MSB_MASK)
+ this->max_handle_++;
+#else
+ register u_long val = this->mask_.fds_bits[i];
+ this->max_handle_ = ACE_MULT_BY_WORDSIZE (i)
+ + ACE_Handle_Set::bitpos(val & ~(val - 1));
+#endif /* 1 */
+ }
+
+ // Do some sanity checking...
+ if (this->max_handle_ >= ACE_Handle_Set::MAXSIZE)
+ this->max_handle_ = ACE_Handle_Set::MAXSIZE - 1;
+#else
+ ACE_UNUSED_ARG (current_max);
+#endif /* !ACE_WIN32 */
+}
+
+ACE_ALLOC_HOOK_DEFINE(ACE_Handle_Set_Iterator)
+
+#if 0
+void
+ACE_Handle_Set_Iterator::dump (void) const
+{
+ ACE_TRACE ("ACE_Handle_Set_Iterator::dump");
+
+ ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this));
+#if defined(ACE_WIN32) || !defined(ACE_HAS_BIG_FD_SET)
+ ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("\nhandle_index_ = %d"), this->handle_index_));
+#elif defined(ACE_HAS_BIG_FD_SET)
+ ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("\nword_max_ = %d"), this->word_max_));
+ ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("\nword_val_ = %d"), this->word_val_));
+#endif
+ ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("\nword_num_ = %d"), this->word_num_));
+ ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP));
+}
+#endif
+
+ACE_HANDLE
+ACE_Handle_Set_Iterator::operator () (void)
+{
+ ACE_TRACE ("ACE_Handle_Set_Iterator::operator");
+#if defined (ACE_WIN32)
+ if (this->handle_index_ < this->handles_.mask_.fd_count)
+ // Return the handle and advance the iterator.
+ return (ACE_HANDLE) this->handles_.mask_.fd_array[this->handle_index_++];
+ else
+ return ACE_INVALID_HANDLE;
+
+#elif !defined (ACE_HAS_BIG_FD_SET) /* !ACE_WIN32 */
+ // No sense searching further than the max_handle_ + 1;
+ ACE_HANDLE maxhandlep1 = this->handles_.max_handle_ + 1;
+
+ // HP-UX 11 plays some games with the fd_mask type - fd_mask is
+ // defined as an int_32t, but the fds_bits is an array of longs.
+ // This makes plainly indexing through the array by hand tricky,
+ // since the FD_* macros treat the array as int32_t. So the bits
+ // are in the right place for int32_t, even though the array is
+ // long. This, they say, is to preserve the same in-memory layout
+ // for 32-bit and 64-bit processes. So, we play the same game as
+ // the FD_* macros to get the bits right. On all other systems,
+ // this amounts to practically a NOP, since this is what would have
+ // been done anyway, without all this type jazz.
+ fd_mask * maskp = (fd_mask *)(this->handles_.mask_.fds_bits);
+
+ if (this->handle_index_ >= maxhandlep1)
+ // We've seen all the handles we're interested in seeing for this
+ // iterator.
+ return ACE_INVALID_HANDLE;
+ else
+ {
+ ACE_HANDLE result = this->handle_index_;
+
+ // Increment the iterator and advance to the next bit in this
+ // word.
+ this->handle_index_++;
+# if defined (ACE_PSOS)
+ this->word_val_ = (this->word_val_ << 1);
+# else
+ this->word_val_ = (this->word_val_ >> 1) & ACE_MSB_MASK;
+# endif /* ACE_PSOS */
+
+ // If we've examined all the bits in this word, we'll go onto
+ // the next word.
+
+ if (this->word_val_ == 0)
+ {
+ // Start the handle_index_ at the beginning of the next word
+ // and then loop until we've found the first non-zero bit or
+ // we run past the <maxhandlep1> of the bitset.
+
+ for (this->handle_index_ = ACE_MULT_BY_WORDSIZE(++this->word_num_);
+ this->handle_index_ < maxhandlep1
+ && maskp[this->word_num_] == 0;
+ this->word_num_++)
+ this->handle_index_ += ACE_Handle_Set::WORDSIZE;
+
+ // If the bit index becomes >= the maxhandlep1 that means
+ // there weren't any more bits set that we want to consider.
+ // Therefore, we'll just store the maxhandlep1, which will
+ // cause <operator()> to return <ACE_INVALID_HANDLE>
+ // immediately next time it's called.
+ if (this->handle_index_ >= maxhandlep1)
+ {
+ this->handle_index_ = maxhandlep1;
+ return result;
+ }
+ else
+ // Load the bits of the next word.
+ this->word_val_ = maskp[this->word_num_];
+ }
+
+ // Loop until we get <word_val_> to have its least significant
+ // bit enabled, keeping track of which <handle_index> this
+ // represents (this information is used by subsequent calls to
+ // <operator()>).
+
+# if defined (ACE_PSOS) // bits are in reverse order, MSB (sign bit) = bit 0.
+ for (;
+ this->word_val_ > 0;
+ this->word_val_ = (this->word_val_ << 1))
+ this->handle_index_++;
+# else
+ for (;
+ ACE_BIT_DISABLED (this->word_val_, 1);
+ this->handle_index_++)
+ this->word_val_ = (this->word_val_ >> 1) & ACE_MSB_MASK;
+# endif /* ACE_PSOS */
+
+ return result;
+ }
+#else /* !ACE_HAS_BIG_FD_SET */
+ // Find the first word in fds_bits with bit on
+ register u_long lsb = this->word_val_;
+
+ if (lsb == 0)
+ {
+ do
+ {
+ // We have exceeded the word count in Handle_Set?
+ if (++this->word_num_ >= this->word_max_)
+ return ACE_INVALID_HANDLE;
+
+ lsb = this->handles_.mask_.fds_bits[this->word_num_];
+ }
+ while (lsb == 0);
+
+ // Set index to word boundary.
+ this->handle_index_ = ACE_MULT_BY_WORDSIZE(this->word_num_);
+
+ // Put new word_val.
+ this->word_val_ = lsb;
+
+ // Find the least significative bit.
+ lsb &= ~(lsb - 1);
+
+ // Remove least significative bit.
+ this->word_val_ ^= lsb;
+
+ // Save to calculate bit distance.
+ this->oldlsb_ = lsb;
+
+ // Move index to least significative bit.
+ while (lsb >>= 1)
+ this->handle_index_++;
+ }
+ else
+ {
+ // Find the least significative bit.
+ lsb &= ~(lsb - 1);
+
+ // Remove least significative bit.
+ this->word_val_ ^= lsb;
+
+ register u_long n = lsb - this->oldlsb_;
+
+ // Move index to bit distance between new lsb and old lsb.
+ do
+ {
+ this->handle_index_++;
+ n &= n >> 1;
+ }
+ while (n != 0);
+
+ this->oldlsb_ = lsb;
+ }
+
+ return this->handle_index_;
+#endif /* ACE_WIN32 */
+}
+
+void
+ACE_Handle_Set_Iterator::operator++ (void)
+{
+ ACE_TRACE ("ACE_Handle_Set_Iterator::operator++");
+
+ // This is now a no-op.
+}
+
+ACE_Handle_Set_Iterator::ACE_Handle_Set_Iterator (const ACE_Handle_Set &hs)
+ : handles_ (hs),
+#if !defined (ACE_HAS_BIG_FD_SET) || defined (ACE_WIN32)
+ handle_index_ (0),
+ word_num_ (-1)
+#elif defined (ACE_HAS_BIG_FD_SET)
+ oldlsb_ (0),
+ word_max_ (hs.max_handle_ == ACE_INVALID_HANDLE
+ ? 0
+ : ((ACE_DIV_BY_WORDSIZE (hs.max_handle_)) + 1))
+#endif /* ACE_HAS_BIG_FD_SET */
+{
+ ACE_TRACE ("ACE_Handle_Set_Iterator::ACE_Handle_Set_Iterator");
+#if !defined (ACE_WIN32) && !defined (ACE_HAS_BIG_FD_SET)
+ // No sense searching further than the max_handle_ + 1;
+ ACE_HANDLE maxhandlep1 =
+ this->handles_.max_handle_ + 1;
+
+ fd_mask *maskp =
+ (fd_mask *)(this->handles_.mask_.fds_bits);
+
+ // Loop until we've found the first non-zero bit or we run past the
+ // <maxhandlep1> of the bitset.
+ while (this->handle_index_ < maxhandlep1
+ && maskp[++this->word_num_] == 0)
+ this->handle_index_ += ACE_Handle_Set::WORDSIZE;
+
+ // If the bit index becomes >= the maxhandlep1 that means there
+ // weren't any bits set. Therefore, we'll just store the
+ // maxhandlep1, which will cause <operator()> to return
+ // <ACE_INVALID_HANDLE> immediately.
+ if (this->handle_index_ >= maxhandlep1)
+ this->handle_index_ = maxhandlep1;
+ else
+ // Loop until we get <word_val_> to have its least significant bit
+ // enabled, keeping track of which <handle_index> this represents
+ // (this information is used by <operator()>).
+# if defined (ACE_PSOS) // bits are in reverse order, MSB (sign bit) = bit 0.
+ for (this->word_val_ = maskp[this->word_num_];
+ this->word_val_ > 0;
+ this->word_val_ = (this->word_val_ << 1))
+ this->handle_index_++;
+# else
+ for (this->word_val_ = maskp[this->word_num_];
+ ACE_BIT_DISABLED (this->word_val_, 1)
+ && this->handle_index_ < maxhandlep1;
+ this->handle_index_++)
+ this->word_val_ = (this->word_val_ >> 1) & ACE_MSB_MASK;
+# endif /* ACE_PSOS */
+#elif !defined (ACE_WIN32) && defined (ACE_HAS_BIG_FD_SET)
+ if (this->word_max_==0)
+ {
+ this->word_num_ = -1;
+ this->word_val_ = 0;
+ }
+ else
+ {
+ this->word_num_ =
+ ACE_DIV_BY_WORDSIZE (this->handles_.min_handle_) - 1;
+ this->word_val_ = 0;
+ }
+#endif /* !ACE_WIN32 && !ACE_HAS_BIG_FD_SET */
+}
+
+
+void
+ACE_Handle_Set_Iterator::reset_state (void)
+{
+ ACE_TRACE ("ACE_Handle_Set_Iterator::reset_state");
+
+#if !defined (ACE_HAS_BIG_FD_SET) || defined (ACE_WIN32)
+ this->handle_index_ = 0;
+ this->word_num_ = -1;
+#elif defined (ACE_HAS_BIG_FD_SET)
+ this->oldlsb_ = 0;
+ this->word_max_ =
+ this->handles_.max_handle_ == ACE_INVALID_HANDLE ? 0
+ : ((ACE_DIV_BY_WORDSIZE (this->handles_.max_handle_)) + 1);
+#endif /* ACE_HAS_BIG_FD_SET */
+
+#if !defined (ACE_WIN32) && !defined (ACE_HAS_BIG_FD_SET)
+ // No sense searching further than the max_handle_ + 1;
+ ACE_HANDLE maxhandlep1 =
+ this->handles_.max_handle_ + 1;
+
+ fd_mask *maskp =
+ (fd_mask *)(this->handles_.mask_.fds_bits);
+
+ // Loop until we've found the first non-zero bit or we run past the
+ // <maxhandlep1> of the bitset.
+ while (this->handle_index_ < maxhandlep1
+ && maskp[++this->word_num_] == 0)
+ this->handle_index_ += ACE_Handle_Set::WORDSIZE;
+
+ // If the bit index becomes >= the maxhandlep1 that means there
+ // weren't any bits set. Therefore, we'll just store the
+ // maxhandlep1, which will cause <operator()> to return
+ // <ACE_INVALID_HANDLE> immediately.
+ if (this->handle_index_ >= maxhandlep1)
+ this->handle_index_ = maxhandlep1;
+ else
+ // Loop until we get <word_val_> to have its least significant bit
+ // enabled, keeping track of which <handle_index> this represents
+ // (this information is used by <operator()>).
+# if defined (ACE_PSOS) // bits are in reverse order, MSB (sign bit) = bit 0.
+ for (this->word_val_ = maskp[this->word_num_];
+ this->word_val_ > 0;
+ this->word_val_ = (this->word_val_ << 1))
+ this->handle_index_++;
+# else
+ for (this->word_val_ = maskp[this->word_num_];
+ ACE_BIT_DISABLED (this->word_val_, 1)
+ && this->handle_index_ < maxhandlep1;
+ this->handle_index_++)
+ this->word_val_ = (this->word_val_ >> 1) & ACE_MSB_MASK;
+# endif /* ACE_PSOS */
+#elif !defined (ACE_WIN32) && defined (ACE_HAS_BIG_FD_SET)
+ if (this->word_max_==0)
+ {
+ this->word_num_ = -1;
+ this->word_val_ = 0;
+ }
+ else
+ {
+ this->word_num_ =
+ ACE_DIV_BY_WORDSIZE (this->handles_.min_handle_) - 1;
+ this->word_val_ = 0;
+ }
+#endif /* !ACE_WIN32 && !ACE_HAS_BIG_FD_SET */
+}
diff --git a/ace/OS/Handle_Set.h b/ace/OS/Handle_Set.h
new file mode 100644
index 00000000000..a9a0d35a84d
--- /dev/null
+++ b/ace/OS/Handle_Set.h
@@ -0,0 +1,229 @@
+/* -*- C++ -*- */
+
+//=============================================================================
+/**
+ * @file Handle_Set.h
+ *
+ * $Id$
+ *
+ * @author Douglas C. Schmidt <schmidt@cs.wustl.edu>
+ */
+//=============================================================================
+
+#ifndef ACE_HANDLE_SET_H
+#define ACE_HANDLE_SET_H
+#include "ace/pre.h"
+
+#include "OS.h"
+
+#if !defined (ACE_LACKS_PRAGMA_ONCE)
+# pragma once
+#endif /* ACE_LACKS_PRAGMA_ONCE */
+
+/**
+ * @class ACE_Handle_Set
+ *
+ * @brief C++ wrapper facade for the socket <fd_set> abstraction.
+ *
+ * This abstraction is a very efficient wrapper facade over
+ * <fd_set>. In particular, no range checking is performed, so
+ * it's important not to set or clear bits that are outside the
+ * <ACE_DEFAULT_SELECT_REACTOR_SIZE>.
+ */
+class ACE_Export ACE_Handle_Set
+{
+public:
+ friend class ACE_Handle_Set_Iterator;
+
+ // = Initialization and termination.
+
+ enum
+ {
+ MAXSIZE = ACE_DEFAULT_SELECT_REACTOR_SIZE
+ };
+
+ // = Initialization methods.
+ /// Constructor, initializes the bitmask to all 0s.
+ ACE_Handle_Set (void);
+
+ /**
+ * Constructor, initializes the handle set from a given mask.
+ * <ACE_FD_SET_TYPE> is a <typedef> based on the platform's native
+ * type used for masks passed to <select>.
+ */
+ ACE_Handle_Set (const ACE_FD_SET_TYPE &mask);
+
+#if defined (ACE_HAS_WINCE)
+ /// Default dtor.
+ ~ACE_Handle_Set (void);
+#endif /* ACE_HAS_WINCE */
+
+ // = Methods for manipulating bitsets.
+ /// Initialize the bitmask to all 0s and reset the associated fields.
+ void reset (void);
+
+ /**
+ * Checks whether <handle> is enabled. No range checking is
+ * performed so <handle> must be less than
+ * <ACE_DEFAULT_SELECT_REACTOR_SIZE>.
+ */
+ int is_set (ACE_HANDLE handle) const;
+
+ /// Enables the <handle>. No range checking is performed so <handle>
+ /// must be less than <ACE_DEFAULT_SELECT_REACTOR_SIZE>.
+ void set_bit (ACE_HANDLE handle);
+
+ /// Disables the <handle>. No range checking is performed so
+ /// <handle> must be less than <ACE_DEFAULT_SELECT_REACTOR_SIZE>.
+ void clr_bit (ACE_HANDLE handle);
+
+ /// Returns a count of the number of enabled bits.
+ int num_set (void) const;
+
+ /// Returns the number of the large bit.
+ ACE_HANDLE max_set (void) const;
+
+ /**
+ * Rescan the underlying <fd_set> up to handle <max> to find the new
+ * <max_handle> (highest bit set) and <size> (how many bits set) values.
+ * This is useful for evaluating the changes after the handle set has
+ * been manipulated in some way other than member functions; for example,
+ * after <select> modifies the <fd_set>.
+ */
+ void sync (ACE_HANDLE max);
+
+ /// Returns a pointer to the underlying <fd_set>. Returns 0 if
+ /// there are no handle bits set (<size_> == 0).
+ operator fd_set *();
+
+ /// Returns a pointer to the underlying <fd_set>. Returns 0 if
+ /// there are no handle bits set (<size_> == 0).
+ fd_set *fdset (void);
+
+#if defined (ACE_HAS_BIG_FD_SET)
+ /// Assignment operator optimizes for cases where <size_> == 0.
+ ACE_Handle_Set & operator= (const ACE_Handle_Set &);
+#endif /* ACE_HAS_BIG_FD_SET */
+
+ /// Dump the state of an object.
+ void dump (void) const;
+
+ /// Declare the dynamic allocation hooks.
+ ACE_ALLOC_HOOK_DECLARE;
+
+private:
+ /// Size of the set, i.e., a count of the number of enabled bits.
+ int size_;
+
+ /// Current max handle.
+ ACE_HANDLE max_handle_;
+
+#if defined (ACE_HAS_BIG_FD_SET)
+ /// Current min handle.
+ ACE_HANDLE min_handle_;
+#endif /* ACE_HAS_BIG_FD_SET */
+
+ /// Bitmask.
+ fd_set mask_;
+
+ enum
+ {
+ WORDSIZE = NFDBITS,
+#if !defined (ACE_WIN32)
+ NUM_WORDS = howmany (MAXSIZE, NFDBITS),
+#endif /* ACE_WIN32 */
+ NBITS = 256
+ };
+
+ /// Counts the number of bits enabled in N. Uses a table lookup to
+ /// speed up the count.
+ static int count_bits (u_long n);
+
+#if defined (ACE_HAS_BIG_FD_SET)
+ /// Find the position of the bit counting from right to left.
+ static int bitpos (u_long bit);
+#endif /* ACE_HAS_BIG_FD_SET */
+
+ /// Resets the <max_handle_> after a clear of the original
+ /// <max_handle_>.
+ void set_max (ACE_HANDLE max);
+
+ /// Table that maps bytes to counts of the enabled bits in each value
+ /// from 0 to 255.
+ static const char nbits_[NBITS];
+};
+
+/**
+ * @class ACE_Handle_Set_Iterator
+ *
+ * @brief Iterator for the <ACE_Handle_Set> abstraction.
+ */
+class ACE_Export ACE_Handle_Set_Iterator
+{
+public:
+ /// Constructor.
+ ACE_Handle_Set_Iterator (const ACE_Handle_Set &hs);
+
+ /// Default dtor.
+ ~ACE_Handle_Set_Iterator (void);
+
+ /// Reset the state of the iterator by reinitializing the state
+ /// that we maintain.
+ void reset_state (void);
+
+ /**
+ * "Next" operator. Returns the next unseen <ACE_HANDLE> in the
+ * <Handle_Set> up to <handle_set_.max_handle_>). When all the
+ * handles have been seen returns <ACE_INVALID_HANDLE>. Advances
+ * the iterator automatically, so you need not call <operator++>
+ * (which is now obsolete).
+ */
+ ACE_HANDLE operator () (void);
+
+ /// This is a no-op and no longer does anything. It's only here for
+ /// backwards compatibility.
+ void operator++ (void);
+
+ /// Dump the state of an object.
+ void dump (void) const;
+
+ /// Declare the dynamic allocation hooks.
+ ACE_ALLOC_HOOK_DECLARE;
+
+private:
+ /// The <Handle_Set> we are iterating through.
+ const ACE_Handle_Set &handles_;
+
+#if defined (ACE_WIN32)
+ u_int handle_index_;
+#elif !defined (ACE_HAS_BIG_FD_SET)
+ int handle_index_;
+#elif defined (ACE_HAS_BIG_FD_SET)
+ int handle_index_;
+ u_long oldlsb_;
+#endif /* ACE_WIN32 */
+ // Index of the bit we're examining in the current <word_num_> word.
+
+ /// Number of the word we're iterating over (typically between 0..7).
+ int word_num_;
+
+#if defined (ACE_HAS_BIG_FD_SET)
+ /// Number max of the words with a possible bit on.
+ int word_max_;
+#endif /* ACE_HAS_BIG_FD_SET */
+
+#if !defined (ACE_WIN32) && !defined (ACE_HAS_BIG_FD_SET)
+ /// Value of the bits in the word we're iterating on.
+ fd_mask word_val_;
+#elif !defined (ACE_WIN32) && defined (ACE_HAS_BIG_FD_SET)
+ /// Value of the bits in the word we're iterating on.
+ u_long word_val_;
+#endif /* !ACE_WIN32 && !ACE_HAS_BIG_FD_SET */
+};
+
+#if defined (__ACE_INLINE__)
+#include "Handle_Set.i"
+#endif /* __ACE_INLINE__ */
+
+#include "ace/post.h"
+#endif /* ACE_HANDLE_SET */
diff --git a/ace/OS/Handle_Set.i b/ace/OS/Handle_Set.i
new file mode 100644
index 00000000000..ce845d95279
--- /dev/null
+++ b/ace/OS/Handle_Set.i
@@ -0,0 +1,176 @@
+/* -*- C++ -*- */
+// $Id$
+
+// Handle_Set.i
+
+// Initialize the bitmask to all 0s and reset the associated fields.
+
+#if defined (ACE_HAS_WINCE)
+ACE_INLINE
+ACE_Handle_Set::~ACE_Handle_Set (void)
+{
+ ACE_TRACE ("ACE_Handle_Set::~ACE_Handle_Set");
+}
+#endif /* ACE_HAS_WINCE */
+
+ACE_INLINE void
+ACE_Handle_Set::reset (void)
+{
+ ACE_TRACE ("ACE_Handle_Set::reset");
+ this->max_handle_ =
+ ACE_INVALID_HANDLE;
+#if defined (ACE_HAS_BIG_FD_SET)
+ this->min_handle_ =
+ NUM_WORDS * WORDSIZE;
+#endif /* ACE_HAS_BIG_FD_SET */
+ this->size_ = 0;
+ // #if !defined (ACE_HAS_BIG_FD_SET) Why is this here? -Steve Huston
+ FD_ZERO (&this->mask_);
+ // #endif /* ACE_HAS_BIG_FD_SET */
+}
+
+#if defined (ACE_HAS_BIG_FD_SET)
+ACE_INLINE ACE_Handle_Set &
+ACE_Handle_Set::operator = (const ACE_Handle_Set &rhs)
+{
+ ACE_TRACE ("ACE_Handle_Set::operator =");
+
+ if (rhs.size_ > 0)
+ {
+ this->size_ =
+ rhs.size_;
+ this->max_handle_ =
+ rhs.max_handle_;
+ this->min_handle_ =
+ rhs.min_handle_;
+ this->mask_ =
+ rhs.mask_;
+ }
+ else
+ this->reset ();
+
+ return *this;
+}
+#endif /* ACE_HAS_BIG_FD_SET */
+
+// Returns the number of the large bit.
+
+ACE_INLINE ACE_HANDLE
+ACE_Handle_Set::max_set (void) const
+{
+ ACE_TRACE ("ACE_Handle_Set::max_set");
+ return this->max_handle_;
+}
+
+// Checks whether handle is enabled.
+
+ACE_INLINE int
+ACE_Handle_Set::is_set (ACE_HANDLE handle) const
+{
+ ACE_TRACE ("ACE_Handle_Set::is_set");
+#if defined (ACE_HAS_BIG_FD_SET)
+ return FD_ISSET (handle,
+ &this->mask_)
+ && this->size_ > 0;
+#else
+ return FD_ISSET (handle,
+ &this->mask_);
+#endif /* ACE_HAS_BIG_FD_SET */
+}
+
+// Enables the handle.
+
+ACE_INLINE void
+ACE_Handle_Set::set_bit (ACE_HANDLE handle)
+{
+ ACE_TRACE ("ACE_Handle_Set::set_bit");
+ if ((handle != ACE_INVALID_HANDLE)
+ && (!this->is_set (handle)))
+ {
+#if defined (ACE_WIN32)
+ FD_SET ((SOCKET) handle,
+ &this->mask_);
+ this->size_++;
+#else /* ACE_WIN32 */
+#if defined (ACE_HAS_BIG_FD_SET)
+ if (this->size_ == 0)
+ FD_ZERO (&this->mask_);
+
+ if (handle < this->min_handle_)
+ this->min_handle_ = handle;
+#endif /* ACE_HAS_BIG_FD_SET */
+
+ FD_SET (handle,
+ &this->mask_);
+ this->size_++;
+
+ if (handle > this->max_handle_)
+ this->max_handle_ = handle;
+#endif /* ACE_WIN32 */
+ }
+}
+
+// Disables the handle.
+
+ACE_INLINE void
+ACE_Handle_Set::clr_bit (ACE_HANDLE handle)
+{
+ ACE_TRACE ("ACE_Handle_Set::clr_bit");
+
+ if ((handle != ACE_INVALID_HANDLE) &&
+ (this->is_set (handle)))
+ {
+ FD_CLR ((ACE_SOCKET) handle,
+ &this->mask_);
+ this->size_--;
+
+#if !defined (ACE_WIN32)
+ if (handle == this->max_handle_)
+ this->set_max (this->max_handle_);
+#endif /* !ACE_WIN32 */
+ }
+}
+
+// Returns a count of the number of enabled bits.
+
+ACE_INLINE int
+ACE_Handle_Set::num_set (void) const
+{
+ ACE_TRACE ("ACE_Handle_Set::num_set");
+#if defined (ACE_WIN32)
+ return this->mask_.fd_count;
+#else /* !ACE_WIN32 */
+ return this->size_;
+#endif /* ACE_WIN32 */
+}
+
+// Returns a pointer to the underlying fd_set.
+
+ACE_INLINE
+ACE_Handle_Set::operator fd_set *()
+{
+ ACE_TRACE ("ACE_Handle_Set::operator fd_set *");
+
+ if (this->size_ > 0)
+ return (fd_set *) &this->mask_;
+ else
+ return (fd_set *) NULL;
+}
+
+// Returns a pointer to the underlying fd_set.
+
+ACE_INLINE fd_set *
+ACE_Handle_Set::fdset (void)
+{
+ ACE_TRACE ("ACE_Handle_Set::fdset");
+
+ if (this->size_ > 0)
+ return (fd_set *) &this->mask_;
+ else
+ return (fd_set *) NULL;
+}
+
+ACE_INLINE
+ACE_Handle_Set_Iterator::~ACE_Handle_Set_Iterator (void)
+{
+}
diff --git a/ace/OS/Init_ACE.cpp b/ace/OS/Init_ACE.cpp
new file mode 100644
index 00000000000..d40ba6fbfb9
--- /dev/null
+++ b/ace/OS/Init_ACE.cpp
@@ -0,0 +1,44 @@
+// $Id$
+
+#include "Init_ACE.h"
+
+#include "ace/Utils/Object_Manager.h"
+
+#if defined (ACE_LACKS_INLINE_FUNCTIONS)
+#include "Init_ACE.i"
+#endif /* ACE_LACKS_INLINE_FUNCTIONS */
+
+ACE_RCSID(ace, Init_ACE, "$Id$")
+
+ // Static data members.
+ u_int ACE_Init_ACE::init_fini_count_ = 0;
+int
+ACE_Init_ACE::init (void)
+{
+ // Don't use ACE_TRACE, because Object_Manager might not have been
+ // instantiated yet.
+ // ACE_TRACE ("ACE_Init_ACE::init");
+
+ ++init_fini_count_;
+
+ return ACE_Object_Manager::instance ()->init ();
+}
+
+int
+ACE_Init_ACE::fini (void)
+{
+ ACE_TRACE ("ACE_Init_ACE::fini");
+
+ if (init_fini_count_ > 0)
+ {
+ if (--init_fini_count_ == 0)
+ return ACE_Object_Manager::instance ()->fini ();
+ else
+ // Wait for remaining fini () calls.
+ return 1;
+ }
+ else
+ // More ACE_Init_ACE::fini () calls than ACE_Init_ACE::init () calls. Bad
+ // application!
+ return -1;
+}
diff --git a/ace/OS/Init_ACE.h b/ace/OS/Init_ACE.h
new file mode 100644
index 00000000000..b383faf799d
--- /dev/null
+++ b/ace/OS/Init_ACE.h
@@ -0,0 +1,65 @@
+
+//=============================================================================
+/**
+ * @file Init_ACE.h
+ *
+ * $Id$
+ *
+ * This class consolidates the operations on the Handles.
+ *
+ *
+ * @author Priyanka Gontla <pgontla@ece.uci.edu>
+ */
+//=============================================================================
+
+
+#ifndef ACE_INIT_ACE_H
+#define ACE_INIT_ACE_H
+#include "ace/pre.h"
+
+#include "OS.h"
+
+#if !defined (ACE_LACKS_PRAGMA_ONCE)
+# pragma once
+#endif /* ACE_LACKS_PRAGMA_ONCE */
+
+/**
+ * @class ACE_Init_ACE
+ *
+ * @brief Initialize ACE library services. Can be called only once
+ * per program invocation.
+ *
+ */
+class ACE_Export ACE_Init_ACE
+{
+public:
+ /// Returns 0 on success, -1 on failure, and 1 if it had already been called.
+ /**
+ * This class implements the fucntions for the initialization and
+ * shutting down ACE. These functions are called only once per ACE
+ * invokation.
+ */
+ static int init (void);
+
+ /// Returns 0 on success, -1 on failure, and 1 if it had already been called.
+ /**
+ * Shut down ACE library services. Can be called only once per
+ * program invocation.
+ */
+ static int fini (void);
+
+private:
+ /**
+ * Counter to match <init>/<fini> calls. <init> must increment it;
+ * <fini> must decrement it. <fini> then does nothing until it
+ * reaches 0.
+ */
+ static u_int init_fini_count_;
+};
+
+#if !defined (ACE_LACKS_INLINE_FUNCTIONS)
+#include "Init_ACE.i"
+#endif /* ACE_LACKS_INLINE_FUNCTIONS */
+
+#include "ace/post.h"
+#endif /* ACE_INIT_ACE_H */
diff --git a/ace/OS/Init_ACE.i b/ace/OS/Init_ACE.i
new file mode 100644
index 00000000000..cfa1da318d3
--- /dev/null
+++ b/ace/OS/Init_ACE.i
@@ -0,0 +1 @@
+// $Id$
diff --git a/ace/OS/Makefile b/ace/OS/Makefile
new file mode 100644
index 00000000000..72d06ca2e30
--- /dev/null
+++ b/ace/OS/Makefile
@@ -0,0 +1,69 @@
+# $Id$
+
+#----------------------------------------------------------------------------
+# Makefile for the libACE_OS
+#----------------------------------------------------------------------------
+
+MAKEFILE = Makefile
+LIBOS = libACE_OS
+LIB = $(LIBOS).a
+SHLIB = $(LIBOS).$(SOEXT)
+
+
+OS_FILES = \
+ Base_Thread_Adapter\
+ Basic_Types\
+ Date_Time\
+ gethrtime\
+ Handle_Ops\
+ Handle_Set\
+ Init_ACE\
+ OS\
+ OS_Dirent\
+ OS_Errno\
+ OS_Log_Msg_Attributes\
+ OS_Memory\
+ OS_QoS\
+ OS_String\
+ OS_Thread_Adapter\
+ OS_TLI\
+ Sched_Params\
+ Thread_Hook
+
+#----------------------------------------------------------------------------
+# Include macros and targets
+#----------------------------------------------------------------------------
+
+include $(ACE_ROOT)/include/makeinclude/wrapper_macros.GNU
+
+####
+#### ACE_COMPONENTS support.
+####
+FILES += $(OS_FILES)
+
+LSRC = $(addsuffix .cpp,$(FILES))
+
+include $(ACE_ROOT)/include/makeinclude/macros.GNU
+include $(ACE_ROOT)/include/makeinclude/rules.common.GNU
+include $(ACE_ROOT)/include/makeinclude/rules.nested.GNU
+include $(ACE_ROOT)/include/makeinclude/rules.lib.GNU
+include $(ACE_ROOT)/include/makeinclude/rules.local.GNU
+
+INSTALL =
+
+clean:
+ $(RM) -f libACE_OS.a libACE_OS.so
+
+#----------------------------------------------------------------------------
+# Local targets
+#----------------------------------------------------------------------------
+
+
+
+#----------------------------------------------------------------------------
+# Dependencies
+#----------------------------------------------------------------------------
+# DO NOT DELETE THIS LINE -- g++dep uses it.
+# DO NOT PUT ANYTHING AFTER THIS LINE, IT WILL GO AWAY.
+
+
diff --git a/ace/OS/OS.cpp b/ace/OS/OS.cpp
new file mode 100644
index 00000000000..3aa48fb3ef6
--- /dev/null
+++ b/ace/OS/OS.cpp
@@ -0,0 +1,7972 @@
+// $Id$
+
+#include "OS.h"
+#include "Sched_Params.h"
+#include "OS_Thread_Adapter.h"
+#include "OS_QoS.h"
+
+// Perhaps we should *always* include ace/OS.i in order to make sure
+// we can always link against the OS symbols?
+#if !defined (ACE_HAS_INLINED_OSCALLS)
+# include "OS.i"
+#endif /* ACE_HAS_INLINED_OS_CALLS */
+
+ACE_RCSID(ace, OS, "$Id$")
+
+#if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0)
+# if defined (ACE_HAS_WINCE)
+const wchar_t *ACE_OS::day_of_week_name[] = {ACE_LIB_TEXT ("Sun"), ACE_LIB_TEXT ("Mon"),
+ ACE_LIB_TEXT ("Tue"), ACE_LIB_TEXT ("Wed"),
+ ACE_LIB_TEXT ("Thu"), ACE_LIB_TEXT ("Fri"),
+ ACE_LIB_TEXT ("Sat")};
+const wchar_t *ACE_OS::month_name[] = {ACE_LIB_TEXT ("Jan"), ACE_LIB_TEXT ("Feb"),
+ ACE_LIB_TEXT ("Mar"), ACE_LIB_TEXT ("Apr"),
+ ACE_LIB_TEXT ("May"), ACE_LIB_TEXT ("Jun"),
+ ACE_LIB_TEXT ("Jul"), ACE_LIB_TEXT ("Aug"),
+ ACE_LIB_TEXT ("Sep"), ACE_LIB_TEXT ("Oct"),
+ ACE_LIB_TEXT ("Nov"), ACE_LIB_TEXT ("Dec") };
+
+static const ACE_TCHAR *ACE_OS_CTIME_R_FMTSTR = ACE_LIB_TEXT ("%3s %3s %02d %02d:%02d:%02d %04d\n");
+# endif /* ACE_HAS_WINCE */
+
+# if defined (ACE_WIN32)
+OSVERSIONINFO ACE_OS::win32_versioninfo_;
+// Cached win32 version information.
+
+HINSTANCE ACE_OS::win32_resource_module_;
+
+# if defined (ACE_OS_HAS_DLL) && (ACE_OS_HAS_DLL == 1) && !defined (ACE_HAS_WINCE)
+// This function is called by the OS when the ACE DLL is loaded. We
+// use it to determine the default module containing ACE's resources.
+BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID)
+{
+ if (reason == DLL_PROCESS_ATTACH)
+ ACE_OS::set_win32_resource_module(instance);
+ return TRUE;
+}
+# endif /* ACE_OS_HAS_DLL && ACE_OS_HAS_DLL == 1 */
+# endif /* ACE_WIN32 */
+
+class ACE_OS_Thread_Mutex_Guard
+{
+ // = TITLE
+ // This data structure is meant to be used within an ACE_OS
+ // function. It performs automatic aquisition and release of
+ // an ACE_thread_mutex_t.
+ //
+ // = DESCRIPTION
+ // For internal use only by ACE_OS.
+public:
+ ACE_OS_Thread_Mutex_Guard (ACE_thread_mutex_t &m);
+ // Implicitly and automatically acquire the lock.
+
+ ~ACE_OS_Thread_Mutex_Guard (void);
+ // Implicitly release the lock.
+
+ int acquire (void);
+ // Explicitly acquire the lock.
+
+ int release (void);
+ // Explicitly release the lock.
+
+protected:
+ ACE_thread_mutex_t &lock_;
+ // Reference to the mutex.
+
+ int owner_;
+ // Keeps track of whether we acquired the lock or failed.
+
+ // = Prevent assignment and initialization.
+ ACE_OS_Thread_Mutex_Guard &operator= (const ACE_OS_Thread_Mutex_Guard &);
+ ACE_OS_Thread_Mutex_Guard (const ACE_OS_Thread_Mutex_Guard &);
+};
+
+#if defined (ACE_IS_SPLITTING)
+# define ACE_SPECIAL_INLINE
+#else
+# define ACE_SPECIAL_INLINE inline
+#endif
+
+ACE_SPECIAL_INLINE
+int
+ACE_OS_Thread_Mutex_Guard::acquire (void)
+{
+ return owner_ = ACE_OS::thread_mutex_lock (&lock_);
+}
+
+ACE_SPECIAL_INLINE
+int
+ACE_OS_Thread_Mutex_Guard::release (void)
+{
+ if (owner_ == -1)
+ return 0;
+ else
+ {
+ owner_ = -1;
+ return ACE_OS::thread_mutex_unlock (&lock_);
+ }
+}
+
+ACE_SPECIAL_INLINE
+ACE_OS_Thread_Mutex_Guard::ACE_OS_Thread_Mutex_Guard (ACE_thread_mutex_t &m)
+ : lock_ (m)
+{
+ acquire ();
+}
+
+ACE_OS_Thread_Mutex_Guard::~ACE_OS_Thread_Mutex_Guard ()
+{
+ release ();
+}
+
+class ACE_OS_Recursive_Thread_Mutex_Guard
+{
+ // = TITLE
+ // This data structure is meant to be used within an ACE_OS
+ // function. It performs automatic aquisition and release of
+ // an ACE_recursive_thread_mutex_t.
+ //
+ // = DESCRIPTION
+ // For internal use only by ACE_OS.
+public:
+ ACE_OS_Recursive_Thread_Mutex_Guard (ACE_recursive_thread_mutex_t &m);
+ // Implicitly and automatically acquire the lock.
+
+ ~ACE_OS_Recursive_Thread_Mutex_Guard (void);
+ // Implicitly release the lock.
+
+ int acquire (void);
+ // Explicitly acquire the lock.
+
+ int release (void);
+ // Explicitly release the lock.
+
+protected:
+ ACE_recursive_thread_mutex_t &lock_;
+ // Reference to the mutex.
+
+ int owner_;
+ // Keeps track of whether we acquired the lock or failed.
+
+ // = Prevent assignment and initialization.
+ ACE_OS_Recursive_Thread_Mutex_Guard &operator= (
+ const ACE_OS_Recursive_Thread_Mutex_Guard &);
+ ACE_OS_Recursive_Thread_Mutex_Guard (
+ const ACE_OS_Recursive_Thread_Mutex_Guard &);
+};
+
+ACE_SPECIAL_INLINE
+int
+ACE_OS_Recursive_Thread_Mutex_Guard::acquire (void)
+{
+ return owner_ = ACE_OS::recursive_mutex_lock (&lock_);
+}
+
+ACE_SPECIAL_INLINE
+int
+ACE_OS_Recursive_Thread_Mutex_Guard::release (void)
+{
+ if (owner_ == -1)
+ return 0;
+ else
+ {
+ owner_ = -1;
+ return ACE_OS::recursive_mutex_unlock (&lock_);
+ }
+}
+
+ACE_SPECIAL_INLINE
+ACE_OS_Recursive_Thread_Mutex_Guard::ACE_OS_Recursive_Thread_Mutex_Guard (
+ ACE_recursive_thread_mutex_t &m)
+ : lock_ (m),
+ owner_ (-1)
+{
+ acquire ();
+}
+
+ACE_OS_Recursive_Thread_Mutex_Guard::~ACE_OS_Recursive_Thread_Mutex_Guard ()
+{
+ release ();
+}
+
+#define ACE_OS_GUARD \
+ ACE_OS_Thread_Mutex_Guard ace_os_guard__ (*(ACE_thread_mutex_t *) \
+ ACE_OS_Object_Manager::preallocated_object[ \
+ ACE_OS_Object_Manager::ACE_OS_MONITOR_LOCK]);
+
+#define ACE_TSS_CLEANUP_GUARD \
+ ACE_OS_Recursive_Thread_Mutex_Guard ace_tss_cleanup_guard__ (*(ACE_recursive_thread_mutex_t *) \
+ ACE_OS_Object_Manager::preallocated_object[ \
+ ACE_OS_Object_Manager::ACE_TSS_CLEANUP_LOCK]);
+
+#define ACE_TSS_BASE_GUARD \
+ ACE_OS_Recursive_Thread_Mutex_Guard ace_tss_base_guard__ (*(ACE_recursive_thread_mutex_t *) \
+ ACE_OS_Object_Manager::preallocated_object[ \
+ ACE_OS_Object_Manager::ACE_TSS_BASE_LOCK]);
+
+
+# if defined (ACE_LACKS_NETDB_REENTRANT_FUNCTIONS)
+int
+ACE_OS::netdb_acquire (void)
+{
+ return ACE_OS::thread_mutex_lock ((ACE_thread_mutex_t *)
+ ACE_OS_Object_Manager::preallocated_object[
+ ACE_OS_Object_Manager::ACE_OS_MONITOR_LOCK]);
+}
+
+int
+ACE_OS::netdb_release (void)
+{
+ return ACE_OS::thread_mutex_unlock ((ACE_thread_mutex_t *)
+ ACE_OS_Object_Manager::preallocated_object[
+ ACE_OS_Object_Manager::ACE_OS_MONITOR_LOCK]);
+}
+# endif /* defined (ACE_LACKS_NETDB_REENTRANT_FUNCTIONS) */
+#else /* ! ACE_MT_SAFE */
+# define ACE_OS_GUARD
+# define ACE_TSS_CLEANUP_GUARD
+# define ACE_TSS_BASE_GUARD
+#endif /* ! ACE_MT_SAFE */
+
+ACE_EXIT_HOOK ACE_OS::exit_hook_ = 0;
+
+// Static constant representing `zero-time'.
+// Note: this object requires static construction.
+const ACE_Time_Value ACE_Time_Value::zero;
+
+// Constant for maximum time representable. Note that this time
+// is not intended for use with select () or other calls that may
+// have *their own* implementation-specific maximum time representations.
+// Its primary use is in time computations such as those used by the
+// dynamic subpriority strategies in the ACE_Dynamic_Message_Queue class.
+// Note: this object requires static construction.
+const ACE_Time_Value ACE_Time_Value::max_time (LONG_MAX,
+ ACE_ONE_SECOND_IN_USECS - 1);
+
+ACE_ALLOC_HOOK_DEFINE(ACE_Time_Value)
+
+// Increment microseconds (the only reason this is here is to allow
+// the use of ACE_Atomic_Op with ACE_Time_Value).
+
+ACE_Time_Value
+ACE_Time_Value::operator ++ (int)
+{
+ ACE_OS_TRACE ("ACE_Time_Value::operator ++ (int)");
+ usec (usec () + 1);
+ normalize ();
+ return *this;
+}
+
+ACE_Time_Value &
+ACE_Time_Value::operator ++ (void)
+{
+ ACE_OS_TRACE ("ACE_Time_Value::operator ++ (void)");
+ usec (usec () + 1);
+ normalize ();
+ return *this;
+}
+
+// Decrement microseconds (the only reason this is here is / to allow
+// the use of ACE_Atomic_Op with ACE_Time_Value).
+
+ACE_Time_Value
+ACE_Time_Value::operator -- (int)
+{
+ ACE_OS_TRACE ("ACE_Time_Value::operator -- (int)");
+ usec (usec () - 1);
+ normalize ();
+ return *this;
+}
+
+ACE_Time_Value &
+ACE_Time_Value::operator -- (void)
+{
+ ACE_OS_TRACE ("ACE_Time_Value::operator -- (void)");
+ usec (usec () - 1);
+ normalize ();
+ return *this;
+}
+
+#if defined (ACE_WIN32)
+// Static constant to remove time skew between FILETIME and POSIX
+// time. POSIX and Win32 use different epochs (Jan. 1, 1970 v.s.
+// Jan. 1, 1601). The following constant defines the difference
+// in 100ns ticks.
+//
+// In the beginning (Jan. 1, 1601), there was no time and no computer.
+// And Bill said: "Let there be time," and there was time....
+# if defined (ACE_LACKS_LONGLONG_T)
+const ACE_U_LongLong ACE_Time_Value::FILETIME_to_timval_skew =
+ACE_U_LongLong (0xd53e8000, 0x19db1de);
+# else
+const DWORDLONG ACE_Time_Value::FILETIME_to_timval_skew =
+ACE_INT64_LITERAL (0x19db1ded53e8000);
+# endif
+
+// Initializes the ACE_Time_Value object from a Win32 FILETIME
+
+ACE_Time_Value::ACE_Time_Value (const FILETIME &file_time)
+{
+ // ACE_OS_TRACE ("ACE_Time_Value::ACE_Time_Value");
+ this->set (file_time);
+}
+
+void ACE_Time_Value::set (const FILETIME &file_time)
+{
+ // Initializes the ACE_Time_Value object from a Win32 FILETIME
+#if defined (ACE_LACKS_LONGLONG_T)
+ ACE_U_LongLong LL_100ns(file_time.dwLowDateTime, file_time.dwHighDateTime);
+ LL_100ns -= ACE_Time_Value::FILETIME_to_timval_skew;
+ // Convert 100ns units to seconds;
+ this->tv_.tv_sec = (long) (LL_100ns / ((double) (10000 * 1000)));
+ // Convert remainder to microseconds;
+ this->tv_.tv_usec = (long)((LL_100ns % ((ACE_UINT32)(10000 * 1000))) / 10);
+#else
+ // Don't use a struct initializer, gcc don't like it.
+ ULARGE_INTEGER _100ns;
+ _100ns.LowPart = file_time.dwLowDateTime;
+ _100ns.HighPart = file_time.dwHighDateTime;
+
+ _100ns.QuadPart -= ACE_Time_Value::FILETIME_to_timval_skew;
+
+ // Convert 100ns units to seconds;
+ this->tv_.tv_sec = (long) (_100ns.QuadPart / (10000 * 1000));
+ // Convert remainder to microseconds;
+ this->tv_.tv_usec = (long) ((_100ns.QuadPart % (10000 * 1000)) / 10);
+#endif // ACE_LACKS_LONGLONG_T
+}
+
+// Returns the value of the object as a Win32 FILETIME.
+
+ACE_Time_Value::operator FILETIME () const
+{
+ FILETIME file_time;
+ ACE_OS_TRACE ("ACE_Time_Value::operator FILETIME");
+
+#if defined (ACE_LACKS_LONGLONG_T)
+ ACE_U_LongLong LL_sec(this->tv_.tv_sec);
+ ACE_U_LongLong LL_usec(this->tv_.tv_usec);
+ ACE_U_LongLong LL_100ns = LL_sec * (ACE_UINT32)(10000 * 1000) +
+ LL_usec * (ACE_UINT32)10 +
+ ACE_Time_Value::FILETIME_to_timval_skew;
+ file_time.dwLowDateTime = LL_100ns.lo();
+ file_time.dwHighDateTime = LL_100ns.hi();
+#else
+ ULARGE_INTEGER _100ns;
+ _100ns.QuadPart = (((DWORDLONG) this->tv_.tv_sec * (10000 * 1000) +
+ this->tv_.tv_usec * 10) +
+ ACE_Time_Value::FILETIME_to_timval_skew);
+
+ file_time.dwLowDateTime = _100ns.LowPart;
+ file_time.dwHighDateTime = _100ns.HighPart;
+#endif //ACE_LACKS_LONGLONG_T
+
+ return file_time;
+}
+
+#endif /* ACE_WIN32 */
+
+ACE_Cleanup_Info::ACE_Cleanup_Info (void)
+ : object_ (0),
+ cleanup_hook_ (0),
+ param_ (0)
+{
+}
+
+int
+ACE_Cleanup_Info::operator== (const ACE_Cleanup_Info &o) const
+{
+ return o.object_ == this->object_
+ && o.cleanup_hook_ == this->cleanup_hook_
+ && o.param_ == this->param_;
+}
+
+int
+ACE_Cleanup_Info::operator!= (const ACE_Cleanup_Info &o) const
+{
+ return !(*this == o);
+}
+
+class ACE_Cleanup_Info_Node
+{
+ // = TITLE
+ // For maintaining a list of ACE_Cleanup_Info items.
+ //
+ // = DESCRIPTION
+ // For internal use by ACE_Object_Manager.
+public:
+ ACE_Cleanup_Info_Node (void);
+ ACE_Cleanup_Info_Node (const ACE_Cleanup_Info &new_info,
+ ACE_Cleanup_Info_Node *next);
+ ~ACE_Cleanup_Info_Node (void);
+ ACE_Cleanup_Info_Node *insert (const ACE_Cleanup_Info &);
+private:
+ ACE_Cleanup_Info cleanup_info_;
+ ACE_Cleanup_Info_Node *next_;
+
+ friend class ACE_OS_Exit_Info;
+};
+
+ACE_Cleanup_Info_Node::ACE_Cleanup_Info_Node (void)
+ : cleanup_info_ (),
+ next_ (0)
+{
+}
+
+ACE_Cleanup_Info_Node::ACE_Cleanup_Info_Node (const ACE_Cleanup_Info &new_info,
+ ACE_Cleanup_Info_Node *next)
+ : cleanup_info_ (new_info),
+ next_ (next)
+{
+}
+
+ACE_Cleanup_Info_Node::~ACE_Cleanup_Info_Node (void)
+{
+ delete next_;
+}
+
+ACE_Cleanup_Info_Node *
+ACE_Cleanup_Info_Node::insert (const ACE_Cleanup_Info &new_info)
+{
+ ACE_Cleanup_Info_Node *new_node;
+
+ ACE_NEW_RETURN (new_node,
+ ACE_Cleanup_Info_Node (new_info, this),
+ 0);
+
+ return new_node;
+}
+
+ACE_OS_Exit_Info::ACE_OS_Exit_Info (void)
+{
+ ACE_NEW (registered_objects_, ACE_Cleanup_Info_Node);
+}
+
+ACE_OS_Exit_Info::~ACE_OS_Exit_Info (void)
+{
+ delete registered_objects_;
+ registered_objects_ = 0;
+}
+
+int
+ACE_OS_Exit_Info::at_exit_i (void *object,
+ ACE_CLEANUP_FUNC cleanup_hook,
+ void *param)
+{
+ ACE_Cleanup_Info new_info;
+ new_info.object_ = object;
+ new_info.cleanup_hook_ = cleanup_hook;
+ new_info.param_ = param;
+
+ // Return -1 and sets errno if unable to allocate storage. Enqueue
+ // at the head and dequeue from the head to get LIFO ordering.
+
+ ACE_Cleanup_Info_Node *new_node;
+
+ if ((new_node = registered_objects_->insert (new_info)) == 0)
+ return -1;
+ else
+ {
+ registered_objects_ = new_node;
+ return 0;
+ }
+}
+
+int
+ACE_OS_Exit_Info::find (void *object)
+{
+ // Check for already in queue, and return 1 if so.
+ for (ACE_Cleanup_Info_Node *iter = registered_objects_;
+ iter && iter->next_ != 0;
+ iter = iter->next_)
+ {
+ if (iter->cleanup_info_.object_ == object)
+ {
+ // The object has already been registered.
+ return 1;
+ }
+ }
+
+ return 0;
+}
+
+void
+ACE_OS_Exit_Info::call_hooks ()
+{
+ // Call all registered cleanup hooks, in reverse order of
+ // registration.
+ for (ACE_Cleanup_Info_Node *iter = registered_objects_;
+ iter && iter->next_ != 0;
+ iter = iter->next_)
+ {
+ ACE_Cleanup_Info &info = iter->cleanup_info_;
+ if (info.cleanup_hook_ == ACE_reinterpret_cast (ACE_CLEANUP_FUNC,
+ ace_cleanup_destroyer))
+ // The object is an ACE_Cleanup.
+ ace_cleanup_destroyer (ACE_reinterpret_cast (ACE_Cleanup *,
+ info.object_),
+ info.param_);
+ else if (info.object_ == &ace_exit_hook_marker)
+ // The hook is an ACE_EXIT_HOOK.
+ (* ACE_reinterpret_cast (ACE_EXIT_HOOK, info.cleanup_hook_)) ();
+ else
+ (*info.cleanup_hook_) (info.object_, info.param_);
+ }
+}
+
+void
+ACE_Time_Value::dump (void) const
+{
+ ACE_OS_TRACE ("ACE_Time_Value::dump");
+#if 0
+ ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this));
+ ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("\ntv_sec_ = %d"), this->tv_.tv_sec));
+ ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("\ntv_usec_ = %d\n"), this->tv_.tv_usec));
+ ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP));
+#endif /* 0 */
+}
+
+void
+ACE_Time_Value::normalize (void)
+{
+ // ACE_OS_TRACE ("ACE_Time_Value::normalize");
+ // New code from Hans Rohnert...
+
+ if (this->tv_.tv_usec >= ACE_ONE_SECOND_IN_USECS)
+ {
+ do
+ {
+ this->tv_.tv_sec++;
+ this->tv_.tv_usec -= ACE_ONE_SECOND_IN_USECS;
+ }
+ while (this->tv_.tv_usec >= ACE_ONE_SECOND_IN_USECS);
+ }
+ else if (this->tv_.tv_usec <= -ACE_ONE_SECOND_IN_USECS)
+ {
+ do
+ {
+ this->tv_.tv_sec--;
+ this->tv_.tv_usec += ACE_ONE_SECOND_IN_USECS;
+ }
+ while (this->tv_.tv_usec <= -ACE_ONE_SECOND_IN_USECS);
+ }
+
+ if (this->tv_.tv_sec >= 1 && this->tv_.tv_usec < 0)
+ {
+ this->tv_.tv_sec--;
+ this->tv_.tv_usec += ACE_ONE_SECOND_IN_USECS;
+ }
+ else if (this->tv_.tv_sec < 0 && this->tv_.tv_usec > 0)
+ {
+ this->tv_.tv_sec++;
+ this->tv_.tv_usec -= ACE_ONE_SECOND_IN_USECS;
+ }
+}
+
+ACE_Countdown_Time::ACE_Countdown_Time (ACE_Time_Value *max_wait_time)
+ : max_wait_time_ (max_wait_time),
+ stopped_ (0)
+{
+ this->start ();
+}
+
+ACE_Countdown_Time::~ACE_Countdown_Time (void)
+{
+ this->stop ();
+}
+
+#if defined (ACE_HAS_POWERPC_TIMER) && defined (ghs)
+void
+ACE_OS::readPPCTimeBase (u_long &most, u_long &least)
+{
+ ACE_OS_TRACE ("ACE_OS::readPPCTimeBase");
+
+ // This function can't be inline because it depends on the arguments
+ // being in particular registers (r3 and r4), in conformance with the
+ // EABI standard. It would be nice if we knew how to put the variable
+ // names directly into the assembler instructions . . .
+ asm("aclock:");
+ asm("mftb r5,TBU");
+ asm("mftb r6,TBL");
+ asm("mftb r7,TBU");
+ asm("cmpw r5,r7");
+ asm("bne aclock");
+
+ asm("stw r5, 0(r3)");
+ asm("stw r6, 0(r4)");
+}
+#elif defined (ACE_HAS_POWERPC_TIMER) && defined (__GNUG__)
+void
+ACE_OS::readPPCTimeBase (u_long &most, u_long &least)
+{
+ ACE_OS_TRACE ("ACE_OS::readPPCTimeBase");
+
+ // This function can't be inline because it defines a symbol,
+ // aclock. If there are multiple calls to the function in a
+ // compilation unit, then that symbol would be multiply defined if
+ // the function was inline.
+ asm volatile ("aclock:\n"
+ "mftbu 5\n" /* upper time base register */
+ "mftb 6\n" /* lower time base register */
+ "mftbu 7\n" /* upper time base register */
+ "cmpw 5,7\n" /* check for rollover of upper */
+ "bne aclock\n"
+ "stw 5,%0\n" /* most */
+ "stw 6,%1" /* least */
+ : "=m" (most), "=m" (least) /* outputs */
+ : /* no inputs */
+ : "5", "6", "7", "memory" /* constraints */);
+}
+#endif /* ACE_HAS_POWERPC_TIMER && (ghs or __GNUG__) */
+
+#if defined (ACE_WIN32) || defined (VXWORKS) || defined (CHORUS) || defined (ACE_PSOS)
+// Don't inline on those platforms because this function contains
+// string literals, and some compilers, e.g., g++, don't handle those
+// efficiently in unused inline functions.
+int
+ACE_OS::uname (ACE_utsname *name)
+{
+ ACE_OS_TRACE ("ACE_OS::uname");
+# if defined (ACE_WIN32)
+ size_t maxnamelen = sizeof name->nodename;
+ ACE_OS::strcpy (name->sysname,
+ ACE_LIB_TEXT ("Win32"));
+
+ OSVERSIONINFO vinfo;
+ vinfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
+ ::GetVersionEx (&vinfo);
+
+ SYSTEM_INFO sinfo;
+# if defined (ACE_HAS_PHARLAP)
+ // PharLap doesn't do GetSystemInfo. What's really wanted is the
+ // CPU architecture, so we can get that with EtsGetSystemInfo. Fill
+ // in what's wanted in the SYSTEM_INFO structure, and carry on. Note
+ // that the CPU type values in EK_KERNELINFO have the same values
+ // are the ones defined for SYSTEM_INFO.
+ EK_KERNELINFO ets_kern;
+ EK_SYSTEMINFO ets_sys;
+ EtsGetSystemInfo (&ets_kern, &ets_sys);
+ sinfo.wProcessorLevel = ACE_static_cast (WORD, ets_kern.CpuType);
+ sinfo.wProcessorArchitecture = PROCESSOR_ARCHITECTURE_INTEL;
+ sinfo.dwProcessorType = ets_kern.CpuType * 100 + 86;
+# else
+ ::GetSystemInfo(&sinfo);
+
+ ACE_OS::strcpy (name->sysname, ACE_LIB_TEXT ("Win32"));
+# endif /* ACE_HAS_PHARLAP */
+
+ const ACE_TCHAR* unknown = ACE_LIB_TEXT ("???");
+
+ if (vinfo.dwPlatformId == VER_PLATFORM_WIN32_NT)
+ {
+ // Get information from the two structures
+ ACE_OS::sprintf (name->release,
+# if defined (ACE_HAS_WINCE)
+ ACE_LIB_TEXT ("Windows CE %d.%d"),
+# else
+ ACE_LIB_TEXT ("Windows NT %d.%d"),
+# endif /* ACE_HAS_WINCE */
+ (int) vinfo.dwMajorVersion,
+ (int) vinfo.dwMinorVersion);
+ ACE_OS::sprintf (name->version,
+ ACE_LIB_TEXT ("Build %d %s"),
+ (int) vinfo.dwBuildNumber,
+ vinfo.szCSDVersion);
+
+ // We have to make sure that the size of (processor + subtype)
+ // is not greater than the size of name->machine. So we give
+ // half the space to the processor and half the space to
+ // subtype. The -1 is necessary for because of the space
+ // between processor and subtype in the machine name.
+ const int bufsize = ((sizeof (name->machine) / sizeof (ACE_TCHAR)) / 2) - 1;
+ ACE_TCHAR processor[bufsize] = ACE_LIB_TEXT ("Unknown");
+ ACE_TCHAR subtype[bufsize] = ACE_LIB_TEXT ("Unknown");
+
+# if defined (ghs)
+ WORD arch = sinfo.u.s.wProcessorArchitecture;
+# else
+ WORD arch = sinfo.wProcessorArchitecture;
+# endif
+
+ switch (arch)
+ {
+ case PROCESSOR_ARCHITECTURE_INTEL:
+ ACE_OS::strcpy (processor, ACE_LIB_TEXT ("Intel"));
+ if (sinfo.wProcessorLevel == 3)
+ ACE_OS::strcpy (subtype, ACE_LIB_TEXT ("80386"));
+ else if (sinfo.wProcessorLevel == 4)
+ ACE_OS::strcpy (subtype, ACE_LIB_TEXT ("80486"));
+ else if (sinfo.wProcessorLevel == 5)
+ ACE_OS::strcpy (subtype, ACE_LIB_TEXT ("Pentium"));
+ else if (sinfo.wProcessorLevel == 6)
+ ACE_OS::strcpy (subtype, ACE_LIB_TEXT ("Pentium Pro"));
+ else if (sinfo.wProcessorLevel == 7) // I'm guessing here
+ ACE_OS::strcpy (subtype, ACE_LIB_TEXT ("Pentium II"));
+ break;
+ case PROCESSOR_ARCHITECTURE_MIPS:
+ ACE_OS::strcpy (processor, ACE_LIB_TEXT ("MIPS"));
+ ACE_OS::strcpy (subtype, ACE_LIB_TEXT ("R4000"));
+ break;
+ case PROCESSOR_ARCHITECTURE_ALPHA:
+ ACE_OS::strcpy (processor, ACE_LIB_TEXT ("Alpha"));
+ ACE_OS::sprintf (subtype, ACE_LIB_TEXT ("%d"), sinfo.wProcessorLevel);
+ break;
+ case PROCESSOR_ARCHITECTURE_PPC:
+ ACE_OS::strcpy (processor, ACE_LIB_TEXT ("PPC"));
+ if (sinfo.wProcessorLevel == 1)
+ ACE_OS::strcpy (subtype, ACE_LIB_TEXT ("601"));
+ else if (sinfo.wProcessorLevel == 3)
+ ACE_OS::strcpy (subtype, ACE_LIB_TEXT ("603"));
+ else if (sinfo.wProcessorLevel == 4)
+ ACE_OS::strcpy (subtype, ACE_LIB_TEXT ("604"));
+ else if (sinfo.wProcessorLevel == 6)
+ ACE_OS::strcpy (subtype, ACE_LIB_TEXT ("603+"));
+ else if (sinfo.wProcessorLevel == 9)
+ ACE_OS::strcpy (subtype, ACE_LIB_TEXT ("804+"));
+ else if (sinfo.wProcessorLevel == 20)
+ ACE_OS::strcpy (subtype, ACE_LIB_TEXT ("620"));
+ break;
+ case PROCESSOR_ARCHITECTURE_UNKNOWN:
+ default:
+ // @@ We could provide WinCE specific info here. But let's
+ // defer that to some later point.
+ ACE_OS::strcpy (processor, ACE_LIB_TEXT ("Unknown"));
+ break;
+ }
+ ACE_OS::sprintf (name->machine,
+ ACE_LIB_TEXT ("%s %s"),
+ processor, subtype);
+ }
+ else if (vinfo.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS)
+ {
+ if (vinfo.dwMajorVersion == 4 && vinfo.dwMinorVersion == 0)
+ {
+ ACE_OS::strcpy (name->release, ACE_LIB_TEXT ("Windows 95"));
+ if (vinfo.szCSDVersion[1] == 'C')
+ ACE_OS::strcat (name->release, ACE_LIB_TEXT (" OSR2"));
+ }
+ else if (vinfo.dwMajorVersion == 4 && vinfo.dwMinorVersion == 10)
+ {
+ ACE_OS::strcpy (name->release, ACE_LIB_TEXT ("Windows 98"));
+ if (vinfo.szCSDVersion[1] == 'A')
+ ACE_OS::strcat (name->release, ACE_LIB_TEXT (" SE"));
+ }
+ else if (vinfo.dwMajorVersion == 4 && vinfo.dwMinorVersion == 90)
+ {
+ ACE_OS::strcpy (name->release, ACE_LIB_TEXT ("Windows Me"));
+ }
+ else
+ {
+ ACE_OS::strcpy (name->release, unknown);
+ }
+
+ ACE_OS::sprintf (name->version, ACE_LIB_TEXT ("%d"),
+ LOWORD (vinfo.dwBuildNumber));
+ if (sinfo.dwProcessorType == PROCESSOR_INTEL_386)
+ ACE_OS::strcpy (name->machine, ACE_LIB_TEXT ("Intel 80386"));
+ else if (sinfo.dwProcessorType == PROCESSOR_INTEL_486)
+ ACE_OS::strcpy (name->machine, ACE_LIB_TEXT ("Intel 80486"));
+ else if (sinfo.dwProcessorType == PROCESSOR_INTEL_PENTIUM)
+ ACE_OS::strcpy (name->machine, ACE_LIB_TEXT ("Intel Pentium"));
+ else
+ ACE_OS::strcpy (name->machine, unknown);
+ }
+ else
+ {
+ // We don't know what this is!
+
+ ACE_OS::strcpy (name->release, unknown);
+ ACE_OS::strcpy (name->version, unknown);
+ ACE_OS::strcpy (name->machine, unknown);
+ }
+
+# if defined (ACE_LACKS_HOSTNAME)
+ return 0;
+# else /* ACE_LACKS_HOSTNAME */
+ return ACE_OS::hostname (name->nodename, maxnamelen);
+# endif /* ACE_LACKS_HOSTNAME */
+
+# elif defined (VXWORKS)
+ size_t maxnamelen = sizeof name->nodename;
+ ACE_OS::strcpy (name->sysname, "VxWorks");
+ ACE_OS::strcpy (name->release, "???");
+ ACE_OS::strcpy (name->version, sysBspRev ());
+ ACE_OS::strcpy (name->machine, sysModel ());
+
+ return ACE_OS::hostname (name->nodename, maxnamelen);
+# elif defined (CHORUS)
+ size_t maxnamelen = sizeof name->nodename;
+ ACE_OS::strcpy (name->sysname, "CHORUS/ClassiX");
+ ACE_OS::strcpy (name->release, "???");
+ ACE_OS::strcpy (name->version, "???");
+ ACE_OS::strcpy (name->machine, "???");
+
+ return ACE_OS::hostname (name->nodename, maxnamelen);
+#elif defined (ACE_PSOS)
+ const unsigned long buflen(64);
+ char buf[buflen];
+ unsigned long len;
+ sys_info(PSOS_VERSION,(void *)buf,buflen,&len);
+ ACE_OS::strcpy (name->sysname, "pSOS");
+ ACE_OS::strcpy (name->release, "???");
+ ACE_OS::strcpy (name->version, buf);
+ ACE_OS::strcpy (name->machine, "PPC 405"); // a bit of a hack
+
+#endif /* ACE_WIN32 */
+}
+#endif /* ACE_WIN32 || VXWORKS */
+
+
+#if defined (VXWORKS)
+struct hostent *
+ACE_OS::gethostbyname (const char *name)
+{
+ ACE_OS_TRACE ("ACE_OS::gethostbyname");
+
+ // not thread safe!
+ static hostent ret;
+ static int first_addr;
+ static char *hostaddr[2];
+ static char *aliases[1];
+
+ ACE_OSCALL (::hostGetByName ((char *) name), int, -1, first_addr);
+ if (first_addr == -1)
+ return 0;
+
+ hostaddr[0] = (char *) &first_addr;
+ hostaddr[1] = 0;
+ aliases[0] = 0;
+
+ // Might not be official: just echo input arg.
+ ret.h_name = (char *) name;
+ ret.h_addrtype = AF_INET;
+ ret.h_length = 4; // VxWorks 5.2/3 doesn't define IP_ADDR_LEN;
+ ret.h_addr_list = hostaddr;
+ ret.h_aliases = aliases;
+
+ return &ret;
+}
+
+struct hostent *
+ACE_OS::gethostbyaddr (const char *addr, int length, int type)
+{
+ ACE_OS_TRACE ("ACE_OS::gethostbyaddr");
+
+ if (length != 4 || type != AF_INET)
+ {
+ errno = EINVAL;
+ return 0;
+ }
+
+ // not thread safe!
+ static hostent ret;
+ static char name [MAXNAMELEN + 1];
+ static char *hostaddr[2];
+ static char *aliases[1];
+
+ if (::hostGetByAddr (*(int *) addr, name) != 0)
+ {
+ // errno will have been set to S_hostLib_UNKNOWN_HOST.
+ return 0;
+ }
+
+ // Might not be official: just echo input arg.
+ hostaddr[0] = (char *) addr;
+ hostaddr[1] = 0;
+ aliases[0] = 0;
+
+ ret.h_name = name;
+ ret.h_addrtype = AF_INET;
+ ret.h_length = 4; // VxWorks 5.2/3 doesn't define IP_ADDR_LEN;
+ ret.h_addr_list = hostaddr;
+ ret.h_aliases = aliases;
+
+ return &ret;
+}
+
+struct hostent *
+ACE_OS::gethostbyaddr_r (const char *addr, int length, int type,
+ hostent *result, ACE_HOSTENT_DATA buffer,
+ int *h_errnop)
+{
+ ACE_OS_TRACE ("ACE_OS::gethostbyaddr_r");
+ if (length != 4 || type != AF_INET)
+ {
+ errno = EINVAL;
+ return 0;
+ }
+
+ if (ACE_OS::netdb_acquire ())
+ return 0;
+ else
+ {
+ // buffer layout:
+ // buffer[0-3]: h_addr_list[0], the first (and only) addr.
+ // buffer[4-7]: h_addr_list[1], the null terminator for the h_addr_list.
+ // buffer[8]: the name of the host, null terminated.
+
+ // Call ::hostGetByAddr (), which puts the (one) hostname into
+ // buffer.
+ if (::hostGetByAddr (*(int *) addr, &buffer[8]) == 0)
+ {
+ // Store the return values in result.
+ result->h_name = &buffer[8]; // null-terminated host name
+ result->h_addrtype = AF_INET;
+ result->h_length = 4; // VxWorks 5.2/3 doesn't define IP_ADDR_LEN.
+
+ result->h_addr_list = (char **) buffer;
+ // Might not be official: just echo input arg.
+ result->h_addr_list[0] = (char *) addr;
+ // Null-terminate the list of addresses.
+ result->h_addr_list[1] = 0;
+ // And no aliases, so null-terminate h_aliases.
+ result->h_aliases = &result->h_addr_list[1];
+ }
+ else
+ {
+ // errno will have been set to S_hostLib_UNKNOWN_HOST.
+ result = 0;
+ }
+ }
+
+ ACE_OS::netdb_release ();
+ *h_errnop = errno;
+ return result;
+}
+
+struct hostent *
+ACE_OS::gethostbyname_r (const char *name, hostent *result,
+ ACE_HOSTENT_DATA buffer,
+ int *h_errnop)
+{
+ ACE_OS_TRACE ("ACE_OS::gethostbyname_r");
+
+ if (ACE_OS::netdb_acquire ())
+ return 0;
+ else
+ {
+ int addr;
+ ACE_OSCALL (::hostGetByName ((char *) name), int, -1, addr);
+
+ if (addr == -1)
+ {
+ // errno will have been set to S_hostLib_UNKNOWN_HOST
+ result = 0;
+ }
+ else
+ {
+ // Might not be official: just echo input arg.
+ result->h_name = (char *) name;
+ result->h_addrtype = AF_INET;
+ result->h_length = 4; // VxWorks 5.2/3 doesn't define IP_ADDR_LEN;
+
+ // buffer layout:
+ // buffer[0-3]: h_addr_list[0], pointer to the addr.
+ // buffer[4-7]: h_addr_list[1], null terminator for the h_addr_list.
+ // buffer[8-11]: the first (and only) addr.
+
+ // Store the address list in buffer.
+ result->h_addr_list = (char **) buffer;
+ // Store the actual address _after_ the address list.
+ result->h_addr_list[0] = (char *) &result->h_addr_list[2];
+ result->h_addr_list[2] = (char *) addr;
+ // Null-terminate the list of addresses.
+ result->h_addr_list[1] = 0;
+ // And no aliases, so null-terminate h_aliases.
+ result->h_aliases = &result->h_addr_list[1];
+ }
+ }
+
+ ACE_OS::netdb_release ();
+ *h_errnop = errno;
+ return result;
+}
+#endif /* VXWORKS */
+
+void
+ACE_OS::ace_flock_t::dump (void) const
+{
+ ACE_OS_TRACE ("ACE_OS::ace_flock_t::dump");
+
+#if 0
+ ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this));
+ ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("handle_ = %u"), this->handle_));
+#if defined (ACE_WIN32)
+ ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("\nInternal = %d"), this->overlapped_.Internal));
+ ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("\nInternalHigh = %d"), this->overlapped_.InternalHigh));
+ ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("\nOffsetHigh = %d"), this->overlapped_.OffsetHigh));
+ ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("\nhEvent = %d"), this->overlapped_.hEvent));
+#elif !defined (CHORUS)
+ ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("\nl_whence = %d"), this->lock_.l_whence));
+ ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("\nl_start = %d"), this->lock_.l_start));
+ ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("\nl_len = %d"), this->lock_.l_len));
+ ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("\nl_type = %d"), this->lock_.l_type));
+#endif /* ACE_WIN32 */
+ ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP));
+#endif /* 0 */
+}
+
+void
+ACE_OS::mutex_lock_cleanup (void *mutex)
+{
+ ACE_OS_TRACE ("ACE_OS::mutex_lock_cleanup");
+#if defined (ACE_HAS_PACE) && !defined (ACE_WIN32)
+ pace_pthread_mutex_t *p_lock = (pace_pthread_mutex_t *) mutex;
+ pace_pthread_mutex_unlock (p_lock);
+# elif defined (ACE_HAS_THREADS)
+# if defined (ACE_HAS_PTHREADS)
+ ACE_mutex_t *p_lock = (ACE_mutex_t *) mutex;
+ ACE_OS::mutex_unlock (p_lock);
+# else
+ ACE_UNUSED_ARG (mutex);
+# endif /* ACE_HAS_PTHREADS */
+# else
+ ACE_UNUSED_ARG (mutex);
+# endif /* ACE_HAS_PACE && !ACE_WIN32 */
+}
+
+#if defined (ACE_HAS_WINCE)
+FILE *
+ACE_OS::fopen (const ACE_TCHAR *filename,
+ const ACE_TCHAR *mode)
+{
+ return ::_wfopen (filename, mode);
+}
+
+#elif defined (ACE_WIN32)
+FILE *
+ACE_OS::fopen (const ACE_TCHAR *filename,
+ const ACE_TCHAR *mode)
+{
+ ACE_OS_TRACE ("ACE_OS::fopen");
+ int hmode = _O_TEXT;
+
+ for (const ACE_TCHAR *mode_ptr = mode; *mode_ptr != 0; mode_ptr++)
+ ACE_OS::fopen_mode_to_open_mode_converter (*mode_ptr, hmode);
+
+ ACE_HANDLE handle = ACE_OS::open (filename, hmode);
+ if (handle != ACE_INVALID_HANDLE)
+ {
+ hmode &= _O_TEXT | _O_RDONLY | _O_APPEND;
+ int fd = _open_osfhandle ((long) handle, hmode);
+ if (fd != -1)
+ {
+# if defined (__BORLANDC__) && !defined (ACE_USES_WCHAR)
+ FILE *fp = ::_fdopen (fd, ACE_const_cast (char *, mode));
+# elif defined (__BORLANDC__) && defined (ACE_USES_WCHAR)
+ FILE *fp = ::_wfdopen (fd, ACE_const_cast (wchar_t *, mode));
+# elif defined (ACE_USES_WCHAR)
+ FILE *fp = ::_wfdopen (fd, mode);
+# else
+ FILE *fp = ::fdopen (fd, mode);
+# endif /* defined(__BORLANDC__) && !defined (ACE_USES_WCHAR)) */
+ if (fp != NULL)
+ return fp;
+ _close (fd);
+ }
+ ACE_OS::close (handle);
+ }
+ return NULL;
+}
+#endif /* ACE_WIN32 */
+
+// The following *printf functions aren't inline because
+// they use varargs.
+
+int
+ACE_OS::fprintf (FILE *fp, const char *format, ...)
+{
+ ACE_OS_TRACE ("ACE_OS::fprintf");
+#if defined (ACE_HAS_WINCE)
+ ACE_NOTSUP_RETURN (-1);
+# else /* ACE_HAS_WINCE */
+ int result = 0;
+ va_list ap;
+ va_start (ap, format);
+# if defined (ACE_HAS_PACE)
+ ACE_OSCALL (::pace_vfprintf (fp, format, ap), int, -1, result);
+# else
+ ACE_OSCALL (::vfprintf (fp, format, ap), int, -1, result);
+# endif /* ACE_HAS_PACE */
+ va_end (ap);
+ return result;
+# endif /* ACE_HAS_WINCE */
+}
+
+#if defined (ACE_HAS_WCHAR)
+int
+ACE_OS::fprintf (FILE *fp, const wchar_t *format, ...)
+{
+ ACE_OS_TRACE ("ACE_OS::fprintf");
+
+# if !defined (ACE_HAS_VFWPRINTF)
+ ACE_UNUSED_ARG (fp);
+ ACE_UNUSED_ARG (format);
+ ACE_NOTSUP_RETURN (-1);
+
+# else
+ int result = 0;
+ va_list ap;
+ va_start (ap, format);
+ ACE_OSCALL (::vfwprintf (fp, format, ap), int, -1, result);
+ va_end (ap);
+ return result;
+
+# endif /* ACE_HAS_VFWPRINTF */
+}
+#endif /* ACE_HAS_WCHAR */
+
+int
+ACE_OS::printf (const char *format, ...)
+{
+ ACE_OS_TRACE ("ACE_OS::printf");
+ int result;
+ va_list ap;
+ va_start (ap, format);
+#if defined (ACE_HAS_PACE)
+ ACE_OSCALL (::pace_vprintf (format, ap), int, -1, result);
+#else
+ ACE_OSCALL (::vprintf (format, ap), int, -1, result);
+#endif /* ACE_HAS_PACE */
+ va_end (ap);
+ return result;
+}
+
+int
+ACE_OS::sprintf (char *buf, const char *format, ...)
+{
+ // ACE_OS_TRACE ("ACE_OS::sprintf");
+
+ int result;
+ va_list ap;
+ va_start (ap, format);
+#if defined (ACE_HAS_PACE)
+ ACE_OSCALL (ACE_SPRINTF_ADAPTER (::pace_vsprintf (buf, format, ap)), int, -1, result);
+#else
+ ACE_OSCALL (ACE_SPRINTF_ADAPTER (::vsprintf (buf, format, ap)), int, -1, result);
+#endif /* ACE_HAS_PACE */
+ va_end (ap);
+ return result;
+}
+
+#if defined (ACE_HAS_WCHAR)
+int
+ACE_OS::sprintf (wchar_t *buf, const wchar_t *format, ...)
+{
+ ACE_OS_TRACE ("ACE_OS::sprintf");
+
+# if defined (ACE_HAS_VSWPRINTF)
+
+ int result;
+ va_list ap;
+ va_start (ap, format);
+ ACE_OSCALL (::vswprintf (buf, format, ap), int, -1, result);
+ va_end (ap);
+ return result;
+
+# else
+
+ ACE_UNUSED_ARG (buf);
+ ACE_UNUSED_ARG (format);
+ ACE_NOTSUP_RETURN (-1);
+
+# endif /* ACE_HAS_VSWPRINTF */
+}
+#endif /* ACE_HAS_WCHAR */
+
+char *
+ACE_OS::gets (char *str, int n)
+{
+ ACE_OS_TRACE ("ACE_OS::gets");
+#if defined (ACE_HAS_PACE)
+ return pace_fgets (str, n, stdin);
+#else
+ int c;
+ char *s = str;
+
+ if (str == 0 || n < 0) n = 0;
+ if (n == 0) str = 0;
+ else n--;
+
+ while ((c = getchar ()) != '\n')
+ {
+
+ if (c == EOF && errno == EINTR)
+ {
+# if defined (ACE_HAS_SIGNAL_SAFE_OS_CALLS)
+ continue;
+# else
+ break;
+# endif /* ACE_HAS_SIGNAL_SAFE_OS_CALLS */
+ }
+
+ if (c == EOF)
+ break;
+
+ if (n > 0)
+ n--, *s++ = c;
+ }
+ if (s) *s = '\0';
+
+ return (c == EOF) ? 0 : str;
+#endif /* ACE_HAS_PACE */
+}
+
+int
+ACE_OS::execl (const char * /* path */, const char * /* arg0 */, ...)
+{
+ ACE_OS_TRACE ("ACE_OS::execl");
+#if defined (ACE_WIN32) || defined (VXWORKS)
+ ACE_NOTSUP_RETURN (-1);
+#else
+ ACE_NOTSUP_RETURN (-1);
+ // Need to write this code.
+ // ACE_OSCALL_RETURN (::execv (path, argv), int, -1);
+#endif /* ACE_WIN32 */
+}
+
+int
+ACE_OS::execle (const char * /* path */, const char * /* arg0 */, ...)
+{
+ ACE_OS_TRACE ("ACE_OS::execle");
+#if defined (ACE_WIN32) || defined (VXWORKS)
+ ACE_NOTSUP_RETURN (-1);
+#else
+ ACE_NOTSUP_RETURN (-1);
+ // Need to write this code.
+ // ACE_OSCALL_RETURN (::execve (path, argv, envp), int, -1);
+#endif /* ACE_WIN32 */
+}
+
+int
+ACE_OS::execlp (const char * /* file */, const char * /* arg0 */, ...)
+{
+ ACE_OS_TRACE ("ACE_OS::execlp");
+#if defined (ACE_WIN32) || defined (VXWORKS)
+ ACE_NOTSUP_RETURN (-1);
+#else
+ ACE_NOTSUP_RETURN (-1);
+ // Need to write this code.
+ // ACE_OSCALL_RETURN (::execvp (file, argv), int, -1);
+#endif /* ACE_WIN32 */
+}
+
+int
+ACE_OS::scheduling_class (const char *class_name, ACE_id_t &id)
+{
+#if defined (ACE_HAS_PRIOCNTL)
+ // Get the priority class ID.
+ pcinfo_t pcinfo;
+ // The following is just to avoid Purify warnings about unitialized
+ // memory reads.
+ ACE_OS::memset (&pcinfo, 0, sizeof pcinfo);
+
+ ACE_OS::strcpy (pcinfo.pc_clname, class_name);
+ if (ACE_OS::priority_control (P_ALL /* ignored */,
+ P_MYID /* ignored */,
+ PC_GETCID,
+ (char *) &pcinfo) == -1)
+ {
+ return -1;
+ }
+ else
+ {
+ id = pcinfo.pc_cid;
+ return 0;
+ }
+#else /* ! ACE_HAS_PRIOCNTL */
+ ACE_UNUSED_ARG (class_name);
+ ACE_UNUSED_ARG (id);
+ ACE_NOTSUP_RETURN (-1);
+#endif /* ! ACE_HAS_PRIOCNTL */
+}
+
+int
+ACE_OS::set_scheduling_params (const ACE_Sched_Params &sched_params,
+ ACE_id_t id)
+{
+#if defined (ACE_HAS_PRIOCNTL)
+ // Set priority class, priority, and quantum of this LWP or process as
+ // specified in sched_params.
+
+ // Get the priority class ID.
+ ACE_id_t class_id;
+ if (ACE_OS::scheduling_class (sched_params.policy() == ACE_SCHED_OTHER ?
+ "TS" :
+ "RT", class_id) == -1)
+ {
+ return -1;
+ }
+
+ pcparms_t pcparms;
+ // The following is just to avoid Purify warnings about unitialized
+ // memory reads.
+ ACE_OS::memset (&pcparms, 0, sizeof pcparms);
+
+ pcparms.pc_cid = class_id;
+
+ if (sched_params.policy () == ACE_SCHED_OTHER &&
+ sched_params.quantum () == ACE_Time_Value::zero)
+ // SunOS doesn't support non-zero quantums in time-sharing class: use
+ // real-time class instead.
+ {
+ tsparms_t tsparms;
+ // The following is just to avoid Purify warnings about unitialized
+ // memory reads.
+ ACE_OS::memset (&tsparms, 0, sizeof tsparms);
+
+ // Don't change ts_uprilim (user priority limit)
+ tsparms.ts_uprilim = TS_NOCHANGE;
+ tsparms.ts_upri = sched_params.priority ();
+
+ // Package up the TS class ID and parameters for the
+ // priority_control () call.
+ ACE_OS::memcpy (pcparms.pc_clparms, &tsparms, sizeof tsparms);
+ }
+ else if (sched_params.policy () == ACE_SCHED_FIFO ||
+ (sched_params.policy () == ACE_SCHED_RR &&
+ sched_params.quantum () != ACE_Time_Value::zero))
+ // must have non-zero quantum for RR, to make it meaningful
+ // A zero quantum with FIFO has special significance: it actually
+ // means infinite time quantum, i.e., run-to-completion.
+ {
+ rtparms_t rtparms;
+ // The following is just to avoid Purify warnings about unitialized
+ // memory reads.
+ ACE_OS::memset (&rtparms, 0, sizeof rtparms);
+
+ rtparms.rt_pri = sched_params.priority ();
+
+ if (sched_params.quantum () == ACE_Time_Value::zero)
+ {
+ // rtparms.rt_tqsecs is ignored with RT_TQINF
+ rtparms.rt_tqnsecs = RT_TQINF;
+ }
+ else
+ {
+ rtparms.rt_tqsecs = (ulong) sched_params.quantum ().sec ();
+ rtparms.rt_tqnsecs = sched_params.quantum ().usec () * 1000;
+ }
+
+ // Package up the RT class ID and parameters for the
+ // priority_control () call.
+ ACE_OS::memcpy (pcparms.pc_clparms, &rtparms, sizeof rtparms);
+ }
+ else
+ {
+ errno = EINVAL;
+ return -1;
+ }
+
+ if (ACE_OS::priority_control ((idtype_t) (sched_params.scope () == ACE_SCOPE_THREAD
+ ? ACE_SCOPE_PROCESS
+ : sched_params.scope ()),
+ id,
+ PC_SETPARMS,
+ (char *) &pcparms) < 0)
+ {
+ return ACE_OS::last_error ();
+ }
+
+ return 0;
+#else /* ! ACE_HAS_PRIOCNTL */
+ ACE_UNUSED_ARG (sched_params);
+ ACE_UNUSED_ARG (id);
+ ACE_NOTSUP_RETURN (-1);
+#endif /* ! ACE_HAS_PRIOCNTL */
+}
+
+int
+ACE_OS::thr_setprio (const ACE_Sched_Priority prio)
+{
+ // Set the thread priority on the current thread.
+ ACE_hthread_t my_thread_id;
+ ACE_OS::thr_self (my_thread_id);
+
+ int status = ACE_OS::thr_setprio (my_thread_id, prio);
+
+# if defined (ACE_NEEDS_LWP_PRIO_SET)
+ // If the thread is in the RT class, then set the priority on its
+ // LWP. (Instead of doing this if the thread is in the RT class, it
+ // should be done for all bound threads. But, there doesn't appear
+ // to be an easy way to determine if the thread is bound.)
+
+ if (status == 0)
+ {
+ // Find what scheduling class the thread's LWP is in.
+ ACE_Sched_Params sched_params (ACE_SCHED_OTHER, 0);
+ if (ACE_OS::lwp_getparams (sched_params) == -1)
+ {
+ return -1;
+ }
+ else if (sched_params.policy () == ACE_SCHED_FIFO ||
+ sched_params.policy () == ACE_SCHED_RR)
+ {
+ // This thread's LWP is in the RT class, so we need to set
+ // its priority.
+ sched_params.priority (prio);
+ return ACE_OS::lwp_setparams (sched_params);
+ }
+ // else this is not an RT thread. Nothing more needs to be
+ // done.
+ }
+# endif /* ACE_NEEDS_LWP_PRIO_SET */
+
+ return status;
+}
+
+int
+ACE_OS::sched_params (const ACE_Sched_Params &sched_params,
+ ACE_id_t id)
+{
+ ACE_OS_TRACE ("ACE_OS::sched_params");
+#if defined (ACE_HAS_PACE) && !defined (ACE_WIN32)
+ ACE_UNUSED_ARG (id);
+ if (sched_params.quantum () != ACE_Time_Value::zero)
+ {
+ // quantums not supported
+ errno = EINVAL;
+ return -1;
+ }
+
+ // Thanks to Thilo Kielmann <kielmann@informatik.uni-siegen.de> for
+ // providing this code for 1003.1c PThreads. Please note that this
+ // has only been tested for POSIX 1003.1c threads, and may cause problems
+ // with other PThreads flavors!
+
+ struct sched_param param;
+ param.sched_priority = sched_params.priority ();
+
+ if (sched_params.scope () == ACE_SCOPE_PROCESS)
+ return pace_sched_setscheduler (0, // this process
+ sched_params.policy (),
+ &param) == -1 ? -1 : 0;
+ else if (sched_params.scope () == ACE_SCOPE_THREAD)
+ {
+ ACE_thread_t thr_id = ACE_OS::thr_self ();
+ return pace_pthread_setschedparam (thr_id,
+ sched_params.policy (),
+ &param);
+ }
+#if defined (sun)
+ // We need to be able to set LWP priorities on Suns, even without
+ // ACE_HAS_STHREADS, to obtain preemption.
+ else if (sched_params.scope () == ACE_SCOPE_LWP)
+ return ACE_OS::set_scheduling_params (sched_params, id);
+#endif /* sun */
+ else // sched_params.scope () == ACE_SCOPE_LWP, which isn't POSIX
+ {
+ errno = EINVAL;
+ return -1;
+ }
+# elif defined (CHORUS)
+ ACE_UNUSED_ARG (id);
+ int result;
+ struct sched_param param;
+ ACE_thread_t thr_id = ACE_OS::thr_self ();
+
+ param.sched_priority = sched_params.priority ();
+
+ ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::pthread_setschedparam (thr_id,
+ sched_params.policy (),
+ &param),
+ result),
+ int, -1);
+# elif defined (ACE_HAS_STHREADS)
+ return ACE_OS::set_scheduling_params (sched_params, id);
+# elif defined (ACE_HAS_PTHREADS) && !defined (ACE_LACKS_SETSCHED)
+ ACE_UNUSED_ARG (id);
+ if (sched_params.quantum () != ACE_Time_Value::zero)
+ {
+ // quantums not supported
+ errno = EINVAL;
+ return -1;
+ }
+
+ // Thanks to Thilo Kielmann <kielmann@informatik.uni-siegen.de> for
+ // providing this code for 1003.1c PThreads. Please note that this
+ // has only been tested for POSIX 1003.1c threads, and may cause
+ // problems with other PThreads flavors!
+
+ struct sched_param param;
+ param.sched_priority = sched_params.priority ();
+
+ if (sched_params.scope () == ACE_SCOPE_PROCESS)
+ {
+ int result = ::sched_setscheduler (0, // this process
+ sched_params.policy (),
+ &param) == -1 ? -1 : 0;
+# if defined (DIGITAL_UNIX)
+ return result == 0
+ ? // Use priocntl (2) to set the process in the RT class,
+ // if using an RT policy.
+ ACE_OS::set_scheduling_params (sched_params)
+ : result;
+# else /* ! DIGITAL_UNIX */
+ return result;
+# endif /* ! DIGITAL_UNIX */
+ }
+ else if (sched_params.scope () == ACE_SCOPE_THREAD)
+ {
+ ACE_thread_t thr_id = ACE_OS::thr_self ();
+
+# if defined (ACE_HAS_PTHREADS_DRAFT4)
+ return (::pthread_setscheduler (thr_id,
+ sched_params.policy (),
+ sched_params.priority()) == -1 ? -1 : 0);
+# else
+ int result;
+ ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::pthread_setschedparam (thr_id,
+ sched_params.policy (),
+ &param),
+ result),
+ int, -1);
+# endif /* ACE_HAS_PTHREADS_DRAFT4 */
+ }
+#if defined (sun)
+ // We need to be able to set LWP priorities on Suns, even without
+ // ACE_HAS_STHREADS, to obtain preemption.
+ else if (sched_params.scope () == ACE_SCOPE_LWP)
+ return ACE_OS::set_scheduling_params (sched_params, id);
+#endif /* sun */
+ else // sched_params.scope () == ACE_SCOPE_LWP, which isn't POSIX
+ {
+ errno = EINVAL;
+ return -1;
+ }
+
+# elif defined (ACE_WIN32) && !defined (ACE_HAS_WINCE)
+
+ // PharLap ETS can act on the current thread - it can set the
+ // quantum also, unlike Win32. All this only works on the RT
+ // version.
+# if defined (ACE_HAS_PHARLAP_RT)
+ if (id != ACE_SELF)
+ ACE_NOTSUP_RETURN (-1);
+
+ if (sched_params.quantum() != ACE_Time_Value::zero)
+ EtsSetTimeSlice (sched_params.quantum().msec());
+
+# else
+ ACE_UNUSED_ARG (id);
+
+ if (sched_params.scope () != ACE_SCOPE_PROCESS
+ || sched_params.quantum () != ACE_Time_Value::zero)
+ {
+ // Win32 only allows setting priority class (therefore, policy)
+ // at the process level. I don't know of a way to set the
+ // quantum.
+ errno = EINVAL;
+ return -1;
+ }
+
+ // Set the priority class of this process to the REALTIME process class
+ // _if_ the policy is ACE_SCHED_FIFO. Otherwise, set to NORMAL.
+ if (!::SetPriorityClass (::GetCurrentProcess (),
+ sched_params.policy () == ACE_SCHED_FIFO
+ ? REALTIME_PRIORITY_CLASS
+ : NORMAL_PRIORITY_CLASS))
+ {
+ ACE_OS::set_errno_to_last_error ();
+ return -1;
+ }
+# endif /* ACE_HAS_PHARLAP_RT */
+
+ // Set the thread priority on the current thread.
+ return ACE_OS::thr_setprio (sched_params.priority ());
+
+# elif defined (VXWORKS) || defined (ACE_PSOS)
+ ACE_UNUSED_ARG (id);
+
+ // There is only one class of priorities on VxWorks, and no time
+ // quanta. So, just set the current thread's priority.
+
+ if (sched_params.policy () != ACE_SCHED_FIFO
+ || sched_params.scope () != ACE_SCOPE_PROCESS
+ || sched_params.quantum () != ACE_Time_Value::zero)
+ {
+ errno = EINVAL;
+ return -1;
+ }
+
+ // Set the thread priority on the current thread.
+ return ACE_OS::thr_setprio (sched_params.priority ());
+#else
+ ACE_UNUSED_ARG (sched_params);
+ ACE_UNUSED_ARG (id);
+ ACE_NOTSUP_RETURN (-1);
+#endif /* ACE_HAS_PACE && !ACE_WIN32 */
+}
+
+// = 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, ACE_hthread_t, and ACE_thread_key_t are implemented
+// as structures... Under no circumstances should these be given
+// initial values.
+// Note: these three objects require static construction.
+ACE_thread_t ACE_OS::NULL_thread;
+ACE_hthread_t ACE_OS::NULL_hthread;
+#if defined (ACE_HAS_TSS_EMULATION) || (defined (ACE_PSOS) && defined (ACE_PSOS_HAS_TSS))
+ ACE_thread_key_t ACE_OS::NULL_key = ACE_static_cast (ACE_thread_key_t, -1);
+#else /* ! ACE_HAS_TSS_EMULATION */
+ ACE_thread_key_t ACE_OS::NULL_key;
+#endif /* ! ACE_HAS_TSS_EMULATION */
+
+#if defined (CHORUS)
+KnCap ACE_OS::actorcaps_[ACE_CHORUS_MAX_ACTORS];
+// This is used to map an actor's id into a KnCap for killing and
+// waiting actors.
+#endif /* CHORUS */
+
+#if defined (ACE_WIN32)
+
+// = Static initialization.
+
+// Keeps track of whether we've initialized the WinSock DLL.
+int ACE_OS::socket_initialized_;
+
+#endif /* WIN32 */
+
+#if defined (ACE_WIN32) || defined (ACE_HAS_TSS_EMULATION) || (defined (ACE_PSOS) && defined (ACE_PSOS_HAS_TSS))
+
+// Moved class ACE_TSS_Ref declaration to OS.h so it can be visible to
+// the single file of template instantiations.
+
+ACE_TSS_Ref::ACE_TSS_Ref (ACE_thread_t id)
+ : tid_(id)
+{
+ ACE_OS_TRACE ("ACE_TSS_Ref::ACE_TSS_Ref");
+}
+
+ACE_TSS_Ref::ACE_TSS_Ref (void)
+{
+ ACE_OS_TRACE ("ACE_TSS_Ref::ACE_TSS_Ref");
+}
+
+// Check for equality.
+int
+ACE_TSS_Ref::operator== (const ACE_TSS_Ref &info) const
+{
+ ACE_OS_TRACE ("ACE_TSS_Ref::operator==");
+
+ return this->tid_ == info.tid_;
+}
+
+// Check for inequality.
+ACE_SPECIAL_INLINE
+int
+ACE_TSS_Ref::operator != (const ACE_TSS_Ref &tss_ref) const
+{
+ ACE_OS_TRACE ("ACE_TSS_Ref::operator !=");
+
+ return !(*this == tss_ref);
+}
+
+// moved class ACE_TSS_Info declaration
+// to OS.h so it can be visible to the
+// single file of template instantiations
+
+ACE_TSS_Info::ACE_TSS_Info (ACE_thread_key_t key,
+ void (*dest)(void *),
+ void *tss_inst)
+ : key_ (key),
+ destructor_ (dest),
+ tss_obj_ (tss_inst),
+ thread_count_ (-1)
+{
+ ACE_OS_TRACE ("ACE_TSS_Info::ACE_TSS_Info");
+}
+
+ACE_TSS_Info::ACE_TSS_Info (void)
+ : key_ (ACE_OS::NULL_key),
+ destructor_ (0),
+ tss_obj_ (0),
+ thread_count_ (-1)
+{
+ ACE_OS_TRACE ("ACE_TSS_Info::ACE_TSS_Info");
+}
+
+# if defined (ACE_HAS_NONSCALAR_THREAD_KEY_T)
+static inline int operator== (const ACE_thread_key_t &lhs,
+ const ACE_thread_key_t &rhs)
+{
+ return ! ACE_OS::memcmp (&lhs, &rhs, sizeof (ACE_thread_key_t));
+}
+
+static inline int operator!= (const ACE_thread_key_t &lhs,
+ const ACE_thread_key_t &rhs)
+{
+ return ! (lhs == rhs);
+}
+# endif /* ACE_HAS_NONSCALAR_THREAD_KEY_T */
+
+// Check for equality.
+int
+ACE_TSS_Info::operator== (const ACE_TSS_Info &info) const
+{
+ ACE_OS_TRACE ("ACE_TSS_Info::operator==");
+
+ return this->key_ == info.key_;
+}
+
+// Check for inequality.
+int
+ACE_TSS_Info::operator != (const ACE_TSS_Info &info) const
+{
+ ACE_OS_TRACE ("ACE_TSS_Info::operator !=");
+
+ return !(*this == info);
+}
+
+void
+ACE_TSS_Info::dump (void)
+{
+ // ACE_OS_TRACE ("ACE_TSS_Info::dump");
+
+#if 0
+ ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this));
+ ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("key_ = %u\n"), this->key_));
+ ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("destructor_ = %u\n"), this->destructor_));
+ ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("tss_obj_ = %u\n"), this->tss_obj_));
+ ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP));
+#endif /* 0 */
+}
+
+// Moved class ACE_TSS_Keys declaration to OS.h so it can be visible
+// to the single file of template instantiations.
+
+ACE_TSS_Keys::ACE_TSS_Keys (void)
+{
+ for (u_int i = 0; i < ACE_WORDS; ++i)
+ {
+ key_bit_words_[i] = 0;
+ }
+}
+
+ACE_SPECIAL_INLINE
+void
+ACE_TSS_Keys::find (const u_int key, u_int &word, u_int &bit)
+{
+ word = key / ACE_BITS_PER_WORD;
+ bit = key % ACE_BITS_PER_WORD;
+}
+
+int
+ACE_TSS_Keys::test_and_set (const ACE_thread_key_t key)
+{
+ ACE_KEY_INDEX (key_index, key);
+ u_int word, bit;
+ find (key_index, word, bit);
+
+ if (ACE_BIT_ENABLED (key_bit_words_[word], 1 << bit))
+ {
+ return 1;
+ }
+ else
+ {
+ ACE_SET_BITS (key_bit_words_[word], 1 << bit);
+ return 0;
+ }
+}
+
+int
+ACE_TSS_Keys::test_and_clear (const ACE_thread_key_t key)
+{
+ ACE_KEY_INDEX (key_index, key);
+ u_int word, bit;
+ find (key_index, word, bit);
+
+ if (ACE_BIT_ENABLED (key_bit_words_[word], 1 << bit))
+ {
+ ACE_CLR_BITS (key_bit_words_[word], 1 << bit);
+ return 0;
+ }
+ else
+ {
+ return 1;
+ }
+}
+
+int
+ACE_TSS_Keys::is_set (const ACE_thread_key_t key) const
+{
+ ACE_KEY_INDEX (key_index, key);
+ u_int word, bit;
+ find (key_index, word, bit);
+
+ return ACE_BIT_ENABLED (key_bit_words_[word], 1 << bit);
+}
+
+
+class ACE_TSS_Cleanup
+ // = TITLE
+ // Singleton that knows how to clean up all the thread-specific
+ // resources for Win32.
+ //
+ // = DESCRIPTION
+ // All this nonsense is required since Win32 doesn't
+ // automatically cleanup thread-specific storage on thread exit,
+ // unlike real operating systems... ;-)
+{
+public:
+ static ACE_TSS_Cleanup *instance (void);
+
+ ~ACE_TSS_Cleanup (void);
+
+ void exit (void *status);
+ // Cleanup the thread-specific objects. Does _NOT_ exit the thread.
+
+ int insert (ACE_thread_key_t key, void (*destructor)(void *), void *inst);
+ // Insert a <key, destructor> tuple into the table.
+
+ int remove (ACE_thread_key_t key);
+ // Remove a <key, destructor> tuple from the table.
+
+ int detach (void *inst);
+ // Detaches a tss_instance from its key.
+
+ void key_used (ACE_thread_key_t key);
+ // Mark a key as being used by this thread.
+
+ int free_all_keys_left (void);
+ // Free all keys left in the table before destruction.
+
+ static int lockable () { return instance_ != 0; }
+ // Indication of whether the ACE_TSS_CLEANUP_LOCK is usable, and
+ // therefore whether we are in static constructor/destructor phase
+ // or not.
+
+protected:
+ void dump (void);
+
+ ACE_TSS_Cleanup (void);
+ // Ensure singleton.
+
+private:
+ // Array of <ACE_TSS_Info> objects.
+ typedef ACE_TSS_Info ACE_TSS_TABLE[ACE_DEFAULT_THREAD_KEYS];
+ typedef ACE_TSS_Info *ACE_TSS_TABLE_ITERATOR;
+
+ ACE_TSS_TABLE table_;
+ // Table of <ACE_TSS_Info>'s.
+
+ ACE_thread_key_t in_use_;
+ // Key for the thread-specific array of whether each TSS key is in use.
+
+ ACE_TSS_Keys *tss_keys ();
+ // Accessor for this threads ACE_TSS_Keys instance.
+
+#if defined (ACE_HAS_TSS_EMULATION)
+ ACE_thread_key_t in_use_key_;
+ // Key that is used by in_use_. We save this key so that we know
+ // not to call its destructor in free_all_keys_left ().
+#endif /* ACE_HAS_TSS_EMULATION */
+
+ // = Static data.
+ static ACE_TSS_Cleanup *instance_;
+ // Pointer to the singleton instance.
+};
+
+// = Static object initialization.
+
+// Pointer to the singleton instance.
+ACE_TSS_Cleanup *ACE_TSS_Cleanup::instance_ = 0;
+
+ACE_TSS_Cleanup::~ACE_TSS_Cleanup (void)
+{
+ // Zero out the instance pointer to support lockable () accessor.
+ ACE_TSS_Cleanup::instance_ = 0;
+}
+
+void
+ACE_TSS_Cleanup::exit (void * /* status */)
+{
+ ACE_OS_TRACE ("ACE_TSS_Cleanup::exit");
+
+ ACE_TSS_TABLE_ITERATOR key_info = table_;
+ ACE_TSS_Info info_arr[ACE_DEFAULT_THREAD_KEYS];
+ int info_ix = 0;
+
+ // While holding the lock, we only collect the ACE_TSS_Info objects
+ // in an array without invoking the according destructors.
+ {
+ ACE_TSS_CLEANUP_GUARD
+
+ // Iterate through all the thread-specific items and free them all
+ // up.
+
+ for (unsigned int i = 0;
+ i < ACE_DEFAULT_THREAD_KEYS;
+ ++key_info, ++i)
+ {
+ if (key_info->key_ == ACE_OS::NULL_key ||
+ ! key_info->key_in_use ()) continue;
+
+ // If the key's ACE_TSS_Info in-use bit for this thread was set,
+ // unset it and decrement the key's thread_count_.
+ if (! tss_keys ()->test_and_clear (key_info->key_))
+ {
+ --key_info->thread_count_;
+ }
+
+ void *tss_info = 0;
+
+ if (key_info->destructor_
+ && ACE_OS::thr_getspecific (key_info->key_, &tss_info) == 0
+ && tss_info)
+ {
+ info_arr[info_ix].key_ = key_info->key_;
+ info_arr[info_ix].destructor_ = key_info->destructor_;
+ info_arr[info_ix++].tss_obj_ = key_info->tss_obj_;
+ }
+ }
+ }
+
+ // Now we have given up the ACE_TSS_Cleanup::lock_ and we start
+ // invoking destructors, in the reverse order of creation.
+ for (int i = info_ix - 1; i >= 0; --i)
+ {
+ void *tss_info = 0;
+
+ ACE_OS::thr_getspecific (info_arr[i].key_, &tss_info);
+
+ if (tss_info != 0)
+ {
+ // Only call the destructor if the value is non-zero for this
+ // thread.
+ (*info_arr[i].destructor_)(tss_info);
+ }
+ }
+
+ // Acquire the ACE_TSS_CLEANUP_LOCK, then free TLS keys and remove
+ // entries from ACE_TSS_Info table.
+ {
+ ACE_TSS_CLEANUP_GUARD
+
+# if 0
+ // We shouldn't free the key and remove it from the table here
+ // because if we do and some thread ends before other threads
+ // even get started (or their TSS object haven't been created yet,)
+ // it's entry will be removed from the table and we are in big chaos.
+ // For TSS object, these have been done in ACE_TSS_Cleanup::detach.
+ // Two other use cases will be user managed TSS'es and system wide
+ // TSS, ones are users responsibilities and the others should be
+ // persistant system wide.
+ for (int i = 0; i < index; i++)
+ {
+# if defined (ACE_WIN32) || (defined (ACE_PSOS) && defined (ACE_PSOS_HAS_TSS))
+ // Calling thr_keyfree here ensure the key
+ // gets removed appropriately. Notice that
+ // a key should be removed before freeing it.
+ ACE_OS::thr_keyfree (key_info->key_);
+# else
+ // don't bother to free the key
+ this->remove (key_info->key_);
+# endif /* ACE_WIN32 */
+ }
+# endif /* 0 */
+ }
+}
+
+int
+ACE_TSS_Cleanup::free_all_keys_left (void)
+ // This is called from ACE_OS::cleanup_tss (). When this gets
+ // called, all threads should have exited except the main thread.
+ // No key should be freed from this routine. It there's any,
+ // something might be wrong.
+{
+ ACE_thread_key_t key_arr[ACE_DEFAULT_THREAD_KEYS];
+ ACE_TSS_TABLE_ITERATOR key_info = table_;
+ unsigned int idx = 0;
+ unsigned int i;
+
+ for (i = 0;
+ i < ACE_DEFAULT_THREAD_KEYS;
+ ++key_info, ++i)
+#if defined (ACE_HAS_TSS_EMULATION)
+ if (key_info->key_ != in_use_key_)
+#endif /* ACE_HAS_TSS_EMULATION */
+ // Don't call ACE_OS::thr_keyfree () on ACE_TSS_Cleanup's own
+ // key. See the comments in ACE_OS::thr_key_detach (): the key
+ // doesn't get detached, so it will be in the table here.
+ // However, there's no resource associated with it, so we don't
+ // need to keyfree it. The dynamic memory associated with it
+ // was already deleted by ACE_TSS_Cleanup::exit (), so we don't
+ // want to access it again.
+ key_arr [idx++] = key_info->key_;
+
+ for (i = 0; i < idx; i++)
+ if (key_arr[i] != ACE_OS::NULL_key)
+#if defined (ACE_HAS_TSS_EMULATION)
+ ACE_OS::thr_keyfree (key_arr[i]);
+#elif defined (ACE_PSOS) && defined (ACE_PSOS_HAS_TSS)
+ // Don't call ACE_OS::thr_keyfree here. It will try to use
+ // <in_use_> which has already been cleaned up here.
+ ::tsd_delete (key_arr[i]);
+#else /* ACE_WIN32 */
+ // Don't call ACE_OS::thr_keyfree here. It will try to use
+ // <in_use_> which has already been cleaned up here.
+ TlsFree (key_arr[i]);
+#endif /* ACE_HAS_TSS_EMULATION */
+
+ return 0;
+}
+
+extern "C" void
+ACE_TSS_Cleanup_keys_destroyer (void *tss_keys)
+{
+ delete ACE_reinterpret_cast (ACE_TSS_Keys *, tss_keys);
+}
+
+ACE_TSS_Cleanup::ACE_TSS_Cleanup (void)
+ : in_use_ (ACE_OS::NULL_key)
+#if defined (ACE_HAS_TSS_EMULATION)
+ // ACE_TSS_Emulation::total_keys () provides the value of the next
+ // key to be created.
+ , in_use_key_ (ACE_TSS_Emulation::total_keys ())
+#endif /* ACE_HAS_TSS_EMULATION */
+{
+ ACE_OS_TRACE ("ACE_TSS_Cleanup::ACE_TSS_Cleanup");
+}
+
+ACE_TSS_Cleanup *
+ACE_TSS_Cleanup::instance (void)
+{
+ ACE_OS_TRACE ("ACE_TSS_Cleanup::instance");
+
+ // Create and initialize thread-specific key.
+ if (ACE_TSS_Cleanup::instance_ == 0)
+ {
+ // Insure that we are serialized!
+ ACE_TSS_CLEANUP_GUARD
+
+ // Now, use the Double-Checked Locking pattern to make sure we
+ // only create the ACE_TSS_Cleanup instance once.
+ if (ACE_TSS_Cleanup::instance_ == 0)
+ ACE_NEW_RETURN (ACE_TSS_Cleanup::instance_,
+ ACE_TSS_Cleanup,
+ 0);
+ }
+
+ return ACE_TSS_Cleanup::instance_;
+}
+
+int
+ACE_TSS_Cleanup::insert (ACE_thread_key_t key,
+ void (*destructor)(void *),
+ void *inst)
+{
+ ACE_OS_TRACE ("ACE_TSS_Cleanup::insert");
+ ACE_TSS_CLEANUP_GUARD
+
+ ACE_KEY_INDEX (key_index, key);
+ if (key_index < ACE_DEFAULT_THREAD_KEYS)
+ {
+ table_[key_index] = ACE_TSS_Info (key, destructor, inst);
+ return 0;
+ }
+ else
+ {
+ return -1;
+ }
+}
+
+int
+ACE_TSS_Cleanup::remove (ACE_thread_key_t key)
+{
+ ACE_OS_TRACE ("ACE_TSS_Cleanup::remove");
+ ACE_TSS_CLEANUP_GUARD
+
+ ACE_KEY_INDEX (key_index, key);
+ if (key_index < ACE_DEFAULT_THREAD_KEYS)
+ {
+ // "Remove" the TSS_Info table entry by zeroing out its key_ and
+ // destructor_ fields. Also, keep track of the number threads
+ // using the key.
+ ACE_TSS_Info &info = this->table_ [key_index];
+
+ // Don't bother to check <in_use_> if the program is shutting
+ // down. Doing so will cause a new ACE_TSS object getting
+ // created again.
+ if (!ACE_OS_Object_Manager::shutting_down ()
+ && ! tss_keys ()->test_and_clear (info.key_))
+ --info.thread_count_;
+
+ info.key_ = ACE_OS::NULL_key;
+ info.destructor_ = 0;
+ return 0;
+ }
+ else
+ return -1;
+}
+
+int
+ACE_TSS_Cleanup::detach (void *inst)
+{
+ ACE_TSS_CLEANUP_GUARD
+
+ ACE_TSS_TABLE_ITERATOR key_info = table_;
+ int success = 0;
+ int ref_cnt = 0;
+
+ // Mark the key as detached in the TSS_Info table.
+ // It only works for the first key that "inst" owns.
+ // I don't know why.
+ for (unsigned int i = 0;
+ i < ACE_DEFAULT_THREAD_KEYS;
+ ++key_info, ++i)
+ {
+ if (key_info->tss_obj_ == inst)
+ {
+ key_info->tss_obj_ = 0;
+ ref_cnt = key_info->thread_count_;
+ success = 1;
+ break;
+ }
+ }
+
+ if (success == 0)
+ return -1;
+ else if (ref_cnt == 0)
+ {
+ // Mark the key as no longer being used.
+ key_info->key_in_use (0);
+# if defined (ACE_WIN32) || (defined (ACE_PSOS) && defined (ACE_PSOS_HAS_TSS))
+ ACE_thread_key_t temp_key = key_info->key_;
+# endif /* ACE_WIN32 */
+ int retv = this->remove (key_info->key_);
+
+# if defined (ACE_WIN32)
+ ::TlsFree (temp_key);
+# elif defined (ACE_PSOS) && defined (ACE_PSOS_HAS_TSS)
+ ::tsd_delete (temp_key);
+# endif /* ACE_WIN32 */
+ return retv;
+ }
+
+ return 0;
+}
+
+void
+ACE_TSS_Cleanup::key_used (ACE_thread_key_t key)
+{
+ // If the key's ACE_TSS_Info in-use bit for this thread is not set,
+ // set it and increment the key's thread_count_.
+ if (! tss_keys ()->test_and_set (key))
+ {
+ ACE_TSS_CLEANUP_GUARD
+
+ // Retrieve the key's ACE_TSS_Info and increment its thread_count_.
+ ACE_KEY_INDEX (key_index, key);
+ ACE_TSS_Info &key_info = this->table_ [key_index];
+ if (key_info.thread_count_ == -1)
+ key_info.key_in_use (1);
+ else
+ ++key_info.thread_count_;
+ }
+}
+
+void
+ACE_TSS_Cleanup::dump (void)
+{
+ // Iterate through all the thread-specific items and dump them all.
+
+ ACE_TSS_TABLE_ITERATOR key_info = table_;
+ for (unsigned int i = 0;
+ i < ACE_DEFAULT_THREAD_KEYS;
+ ++key_info, ++i)
+ key_info->dump ();
+}
+
+ACE_TSS_Keys *
+ACE_TSS_Cleanup::tss_keys ()
+{
+ if (in_use_ == ACE_OS::NULL_key)
+ {
+ ACE_TSS_CLEANUP_GUARD
+ // Double-check;
+ if (in_use_ == ACE_OS::NULL_key)
+ {
+ // Initialize in_use_ with a new key.
+ if (ACE_OS::thr_keycreate (&in_use_,
+ &ACE_TSS_Cleanup_keys_destroyer))
+ return 0; // Major problems, this should *never* happen!
+ }
+ }
+
+ ACE_TSS_Keys *ts_keys = 0;
+ if (ACE_OS::thr_getspecific (in_use_,
+ ACE_reinterpret_cast (void **, &ts_keys)) == -1)
+ return 0; // This should not happen!
+
+ if (ts_keys == 0)
+ {
+ ACE_NEW_RETURN (ts_keys,
+ ACE_TSS_Keys,
+ 0);
+ // Store the dynamically allocated pointer in thread-specific
+ // storage.
+ if (ACE_OS::thr_setspecific (in_use_,
+ ACE_reinterpret_cast (void *,
+ ts_keys)) == -1)
+ {
+ delete ts_keys;
+ return 0; // Major problems, this should *never* happen!
+ }
+ }
+
+ return ts_keys;
+}
+
+# if defined (ACE_HAS_TSS_EMULATION)
+u_int ACE_TSS_Emulation::total_keys_ = 0;
+
+ACE_TSS_Keys ACE_TSS_Emulation::tss_keys_used_;
+
+ACE_TSS_Emulation::ACE_TSS_DESTRUCTOR
+ACE_TSS_Emulation::tss_destructor_[ACE_TSS_Emulation::ACE_TSS_THREAD_KEYS_MAX]
+ = { 0 };
+
+# if defined (ACE_HAS_THREAD_SPECIFIC_STORAGE)
+
+int ACE_TSS_Emulation::key_created_ = 0;
+
+ACE_OS_thread_key_t ACE_TSS_Emulation::native_tss_key_;
+
+/* static */
+# if defined (ACE_HAS_THR_C_FUNC)
+extern "C"
+void
+ACE_TSS_Emulation_cleanup (void *ptr)
+{
+ ACE_UNUSED_ARG (ptr);
+ // Really this must be used for ACE_TSS_Emulation code to make the TSS
+ // cleanup
+}
+#else
+void
+ACE_TSS_Emulation_cleanup (void *ptr)
+{
+ ACE_UNUSED_ARG (ptr);
+ // Really this must be used for ACE_TSS_Emulation code to make the TSS
+ // cleanup
+}
+# endif /* ACE_HAS_THR_C_FUNC */
+
+void **
+ACE_TSS_Emulation::tss_base (void* ts_storage[], u_int *ts_created)
+{
+ // TSS Singleton implementation.
+
+ // Create the one native TSS key, if necessary.
+ if (key_created_ == 0)
+ {
+ // Double-checked lock . . .
+ ACE_TSS_BASE_GUARD
+
+ if (key_created_ == 0)
+ {
+ ACE_NO_HEAP_CHECK;
+ if (ACE_OS::thr_keycreate (&native_tss_key_,
+ &ACE_TSS_Emulation_cleanup) != 0)
+ {
+ return 0; // Major problems, this should *never* happen!
+ }
+ key_created_ = 1;
+ }
+ }
+
+ void **old_ts_storage = 0;
+
+ // Get the tss_storage from thread-OS specific storage.
+ if (ACE_OS::thr_getspecific (native_tss_key_,
+ (void **) &old_ts_storage) == -1)
+ return 0; // This should not happen!
+
+ // Check to see if this is the first time in for this thread.
+ // This block can also be entered after a fork () in the child process,
+ // at least on Pthreads Draft 4 platforms.
+ if (old_ts_storage == 0)
+ {
+ if (ts_created)
+ *ts_created = 1u;
+
+ // Use the ts_storage passed as argument, if non-zero. It is
+ // possible that this has been implemented in the stack. At the
+ // moment, this is unknown. The cleanup must not do nothing.
+ // If ts_storage is zero, allocate (and eventually leak) the
+ // storage array.
+ if (ts_storage == 0)
+ {
+ ACE_NO_HEAP_CHECK;
+
+ ACE_NEW_RETURN (ts_storage,
+ void*[ACE_TSS_THREAD_KEYS_MAX],
+ 0);
+
+ // Zero the entire TSS array. Do it manually instead of
+ // using memset, for optimum speed. Though, memset may be
+ // faster :-)
+ void **tss_base_p = ts_storage;
+
+ for (u_int i = 0;
+ i < ACE_TSS_THREAD_KEYS_MAX;
+ ++i)
+ *tss_base_p++ = 0;
+ }
+
+ // Store the pointer in thread-specific storage. It gets
+ // deleted via the ACE_TSS_Emulation_cleanup function when the
+ // thread terminates.
+ if (ACE_OS::thr_setspecific (native_tss_key_,
+ (void *) ts_storage) != 0)
+ return 0; // Major problems, this should *never* happen!
+ }
+ else
+ if (ts_created)
+ ts_created = 0;
+
+ return ts_storage ? ts_storage : old_ts_storage;
+}
+# endif /* ACE_HAS_THREAD_SPECIFIC_STORAGE */
+
+u_int
+ACE_TSS_Emulation::total_keys ()
+{
+ ACE_OS_Recursive_Thread_Mutex_Guard (
+ *ACE_static_cast (ACE_recursive_thread_mutex_t *,
+ ACE_OS_Object_Manager::preallocated_object[
+ ACE_OS_Object_Manager::ACE_TSS_KEY_LOCK]));
+
+ return total_keys_;
+}
+
+int
+ACE_TSS_Emulation::next_key (ACE_thread_key_t &key)
+{
+ ACE_OS_Recursive_Thread_Mutex_Guard (
+ *ACE_static_cast (ACE_recursive_thread_mutex_t *,
+ ACE_OS_Object_Manager::preallocated_object[
+ ACE_OS_Object_Manager::ACE_TSS_KEY_LOCK]));
+
+ if (total_keys_ < ACE_TSS_THREAD_KEYS_MAX)
+ {
+ u_int counter = 0;
+ // Loop through all possible keys and check whether a key is free
+ for ( ;counter < ACE_TSS_THREAD_KEYS_MAX; counter++)
+ {
+ ACE_thread_key_t localkey;
+# if defined (ACE_HAS_NONSCALAR_THREAD_KEY_T)
+ ACE_OS::memset (&localkey, 0, sizeof (ACE_thread_key_t));
+ ACE_OS::memcpy (&localkey, &counter_, sizeof (u_int));
+# else
+ localkey = counter;
+# endif /* ACE_HAS_NONSCALAR_THREAD_KEY_T */
+ // If the key is not set as used, we can give out this key, if not
+ // we have to search further
+ if (tss_keys_used_.is_set(localkey) == 0)
+ {
+ tss_keys_used_.test_and_set(localkey);
+ key = localkey;
+ break;
+ }
+ }
+
+ ++total_keys_;
+ return 0;
+ }
+ else
+ {
+ key = ACE_OS::NULL_key;
+ return -1;
+ }
+}
+
+int
+ACE_TSS_Emulation::release_key (ACE_thread_key_t key)
+{
+ ACE_OS_Recursive_Thread_Mutex_Guard (
+ *ACE_static_cast (ACE_recursive_thread_mutex_t *,
+ ACE_OS_Object_Manager::preallocated_object[
+ ACE_OS_Object_Manager::ACE_TSS_KEY_LOCK]));
+
+ if (tss_keys_used_.test_and_clear (key) == 0)
+ {
+ --total_keys_;
+ return 0;
+ }
+ return 1;
+}
+
+void *
+ACE_TSS_Emulation::tss_open (void *ts_storage[ACE_TSS_THREAD_KEYS_MAX])
+{
+# if defined (ACE_PSOS)
+ u_long tss_base;
+
+ // Use the supplied array for this thread's TSS.
+ tss_base = (u_long) ts_storage;
+ t_setreg (0, PSOS_TASK_REG_TSS, tss_base);
+
+ // Zero the entire TSS array.
+ void **tss_base_p = ts_storage;
+ for (u_int i = 0; i < ACE_TSS_THREAD_KEYS_MAX; ++i, ++tss_base_p)
+ {
+ *tss_base_p = 0;
+ }
+
+ return (void *) tss_base;
+# else /* ! ACE_PSOS */
+# if defined (ACE_HAS_THREAD_SPECIFIC_STORAGE)
+ // On VxWorks, in particular, don't check to see if the field
+ // is 0. It isn't always, specifically, when a program is run
+ // directly by the shell (without spawning a new task) after
+ // another program has been run.
+
+ u_int ts_created = 0;
+ tss_base (ts_storage, &ts_created);
+ if (ts_created)
+ {
+# else /* ! ACE_HAS_THREAD_SPECIFIC_STORAGE */
+ tss_base () = ts_storage;
+# endif
+
+ // Zero the entire TSS array. Do it manually instead of using
+ // memset, for optimum speed. Though, memset may be faster :-)
+ void **tss_base_p = tss_base ();
+ for (u_int i = 0; i < ACE_TSS_THREAD_KEYS_MAX; ++i, ++tss_base_p)
+ {
+ *tss_base_p = 0;
+ }
+
+ return tss_base ();
+# if defined (ACE_HAS_THREAD_SPECIFIC_STORAGE)
+ }
+ else
+ {
+ return 0;
+ }
+# endif /* ACE_HAS_THREAD_SPECIFIC_STORAGE */
+# endif /* ! ACE_PSOS */
+}
+
+void
+ACE_TSS_Emulation::tss_close ()
+{
+#if defined (ACE_HAS_THREAD_SPECIFIC_STORAGE)
+ // Free native_tss_key_ here.
+#endif /* ACE_HAS_THREAD_SPECIFIC_STORAGE */
+}
+
+# endif /* ACE_HAS_TSS_EMULATION */
+
+#endif /* WIN32 || ACE_HAS_TSS_EMULATION */
+
+void
+ACE_OS::cleanup_tss (const u_int main_thread)
+{
+#if defined (ACE_HAS_TSS_EMULATION) || defined (ACE_WIN32) || (defined (ACE_PSOS) && defined (ACE_PSOS_HAS_TSS))
+ // Call TSS destructors for current thread.
+ ACE_TSS_Cleanup::instance ()->exit (0);
+#endif /* ACE_HAS_TSS_EMULATION || ACE_WIN32 || ACE_PSOS_HAS_TSS */
+
+ if (main_thread)
+ {
+#if !defined (ACE_HAS_TSS_EMULATION) && !defined (ACE_HAS_MINIMAL_ACE_OS)
+ // Just close the ACE_Log_Msg for the current (which should be
+ // main) thread. We don't have TSS emulation; if there's native
+ // TSS, it should call its destructors when the main thread
+ // exits.
+ ACE_Base_Thread_Adapter::close_log_msg ();
+#endif /* ! ACE_HAS_TSS_EMULATION && ! ACE_HAS_MINIMAL_ACE_OS */
+
+#if defined (ACE_WIN32) || defined (ACE_HAS_TSS_EMULATION) || (defined (ACE_PSOS) && defined (ACE_PSOS_HAS_TSS))
+#if ! defined (ACE_HAS_TSS_EMULATION)
+ // Don't do this with TSS_Emulation, because the the
+ // ACE_TSS_Cleanup::instance () has already exited (). We can't
+ // safely access the TSS values that were created by the main
+ // thread.
+
+ // Remove all TSS_Info table entries.
+ ACE_TSS_Cleanup::instance ()->free_all_keys_left ();
+#endif /* ! ACE_HAS_TSS_EMULATION */
+
+ // Finally, free up the ACE_TSS_Cleanup instance. This method gets
+ // called by the ACE_Object_Manager.
+ delete ACE_TSS_Cleanup::instance ();
+#endif /* WIN32 || ACE_HAS_TSS_EMULATION || ACE_PSOS_HAS_TSS */
+
+#if defined (ACE_HAS_TSS_EMULATION)
+ ACE_TSS_Emulation::tss_close ();
+#endif /* ACE_HAS_TSS_EMULATION */
+ }
+}
+
+#if !defined(ACE_WIN32) && defined (__IBMCPP__) && (__IBMCPP__ >= 400)
+#define ACE_BEGINTHREADEX(STACK, STACKSIZE, ENTRY_POINT, ARGS, FLAGS, THR_ID) \
+ (*THR_ID = ::_beginthreadex ((void(_Optlink*)(void*))ENTRY_POINT, STACK, STACKSIZE, ARGS), *THR_ID)
+#elif defined(ACE_WIN32) && defined (__IBMCPP__) && (__IBMCPP__ >= 400)
+
+struct __IBMCPP__thread_params {
+ __IBMCPP__thread_params(ACE_THR_C_FUNC e, LPVOID a)
+ :entry_point(e),args(a) {}
+ ACE_THR_C_FUNC entry_point;
+ LPVOID args;
+};
+
+#pragma handler(initThread)
+extern "C" DWORD __stdcall __IBMCPP__initThread(void *arg)
+{
+ // Must reset 387 since using CreateThread
+ _fpreset();
+
+ // Dispatch user function...
+ auto_ptr<__IBMCPP__thread_params> parms((__IBMCPP__thread_params *)arg);
+ (*parms->entry_point)(parms->args);
+ _endthread();
+ return 0;
+}
+
+HANDLE WINAPI __IBMCPP__beginthreadex(void *stack,
+ DWORD stacksize,
+ ACE_THR_C_FUNC entry_point,
+ LPVOID args,
+ DWORD flags,
+ LPDWORD thr_id)
+{
+ return CreateThread(NULL,
+ stacksize,
+ (LPTHREAD_START_ROUTINE)__IBMCPP__initThread,
+ new __IBMCPP__thread_params(entry_point, args),
+ flags,
+ thr_id);
+}
+
+#define ACE_BEGINTHREADEX(STACK, STACKSIZE, ENTRY_POINT, ARGS, FLAGS, THR_ID) \
+ __IBMCPP__beginthreadex(STACK, STACKSIZE, ENTRY_POINT, ARGS, FLAGS, THR_ID)
+
+#elif defined (ACE_HAS_WINCE) && defined (UNDER_CE) && (UNDER_CE >= 211)
+#define ACE_BEGINTHREADEX(STACK, STACKSIZE, ENTRY_POINT, ARGS, FLAGS, THR_ID) \
+ CreateThread (NULL, STACKSIZE, (unsigned long (__stdcall *) (void *)) ENTRY_POINT, ARGS, (FLAGS) & CREATE_SUSPENDED, (unsigned long *) THR_ID)
+#elif defined(ACE_HAS_WTHREADS)
+ // Green Hills compiler gets confused when __stdcall is imbedded in
+ // parameter list, so we define the type ACE_WIN32THRFUNC_T and use it
+ // instead.
+ typedef unsigned (__stdcall *ACE_WIN32THRFUNC_T)(void*);
+#define ACE_BEGINTHREADEX(STACK, STACKSIZE, ENTRY_POINT, ARGS, FLAGS, THR_ID) \
+ ::_beginthreadex (STACK, STACKSIZE, (ACE_WIN32THRFUNC_T) ENTRY_POINT, ARGS, FLAGS, (unsigned int *) THR_ID)
+#endif /* defined (__IBMCPP__) && (__IBMCPP__ >= 400) */
+
+#if defined (ACE_HAS_WIN32_STRUCTURAL_EXCEPTIONS)
+int ACE_SEH_Default_Exception_Selector (void *)
+{
+#if 0
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_LIB_TEXT ("(%t) Win32 structured exception exiting thread\n")));
+#endif /* 0 */
+ return (DWORD) ACE_SEH_DEFAULT_EXCEPTION_HANDLING_ACTION;
+}
+
+int ACE_SEH_Default_Exception_Handler (void *)
+{
+ return 0;
+}
+#endif /* ACE_HAS_WIN32_STRUCTURAL_EXCEPTIONS */
+
+extern "C" void
+ace_cleanup_destroyer (ACE_Cleanup *object, void *param)
+{
+ object->cleanup (param);
+}
+
+int
+ACE_OS::thr_create (ACE_THR_FUNC func,
+ void *args,
+ long flags,
+ ACE_thread_t *thr_id,
+ ACE_hthread_t *thr_handle,
+ long priority,
+ void *stack,
+ size_t stacksize,
+ ACE_Base_Thread_Adapter *thread_adapter)
+{
+ ACE_OS_TRACE ("ACE_OS::thr_create");
+
+ if (ACE_BIT_DISABLED (flags, THR_DETACHED) &&
+ ACE_BIT_DISABLED (flags, THR_JOINABLE))
+ ACE_SET_BITS (flags, THR_JOINABLE);
+
+# if defined (ACE_NO_THREAD_ADAPTER)
+# define ACE_THREAD_FUNCTION func
+# define ACE_THREAD_ARGUMENT args
+# else /* ! defined (ACE_NO_THREAD_ADAPTER) */
+# if defined (ACE_PSOS)
+# define ACE_THREAD_FUNCTION (PSOS_TASK_ENTRY_POINT) thread_args->entry_point ()
+# else
+# define ACE_THREAD_FUNCTION thread_args->entry_point ()
+# endif /* defined (ACE_PSOS) */
+# define ACE_THREAD_ARGUMENT thread_args
+# endif /* ! defined (ACE_NO_THREAD_ADAPTER) */
+
+#if defined (ACE_HAS_PACE) && !defined (ACE_WIN32)
+ ACE_Base_Thread_Adapter *thread_args;
+ if (thread_adapter == 0)
+ ACE_NEW_RETURN (thread_args,
+ ACE_OS_Thread_Adapter (func, args,
+ (ACE_THR_C_FUNC) ace_thread_adapter),
+ -1);
+ else
+ thread_args = thread_adapter;
+
+# if defined (ACE_NEEDS_HUGE_THREAD_STACKSIZE)
+ if (stacksize < ACE_NEEDS_HUGE_THREAD_STACKSIZE)
+ stacksize = ACE_NEEDS_HUGE_THREAD_STACKSIZE;
+# endif /* ACE_NEEDS_HUGE_THREAD_STACKSIZE */
+
+ ACE_thread_t tmp_thr;
+
+ if (thr_id == 0)
+ thr_id = &tmp_thr;
+
+ ACE_hthread_t tmp_handle;
+ if (thr_handle == 0)
+ thr_handle = &tmp_handle;
+
+ int result = 0;
+ pace_pthread_attr_t attr;
+ if (::pace_pthread_attr_init (&attr) != 0)
+ return -1;
+
+ if (stacksize != 0)
+ {
+ size_t size = stacksize;
+# if defined (PACE_PTHREAD_STACK_MIN)
+ if (size < ACE_static_cast (pace_size_t, PACE_PTHREAD_STACK_MIN))
+ size = PACE_PTHREAD_STACK_MIN;
+# endif /* PACE_PTHREAD_STACK_MIN */
+
+ if (ACE_ADAPT_RETVAL(::pace_pthread_attr_setstacksize (&attr, size), result) == -1)
+ {
+ ::pace_pthread_attr_destroy (&attr);
+ return -1;
+ }
+ }
+
+ // *** Set Stack Address
+ if (stack != 0)
+ {
+ if (::pace_pthread_attr_setstackaddr (&attr, stack) != 0)
+ {
+ ::pace_pthread_attr_destroy (&attr);
+ return -1;
+ }
+ }
+
+ // *** Deal with various attributes
+ if (flags != 0)
+ {
+ // *** Set Detach state
+ if (ACE_BIT_ENABLED (flags, THR_DETACHED)
+ || ACE_BIT_ENABLED (flags, THR_JOINABLE))
+ {
+ int dstate = PACE_PTHREAD_CREATE_JOINABLE;
+
+ if (ACE_BIT_ENABLED (flags, THR_DETACHED))
+ dstate = PACE_PTHREAD_CREATE_DETACHED;
+ if (ACE_ADAPT_RETVAL(::pace_pthread_attr_setdetachstate (&attr, dstate),
+ result) != 0)
+ {
+ ::pace_pthread_attr_destroy (&attr);
+ return -1;
+ }
+ }
+
+ // *** Set Policy
+ // If we wish to set the priority explicitly, we have to enable
+ // explicit scheduling, and a policy, too.
+ if (priority != ACE_DEFAULT_THREAD_PRIORITY)
+ {
+ ACE_SET_BITS (flags, THR_EXPLICIT_SCHED);
+ if (ACE_BIT_DISABLED (flags, THR_SCHED_FIFO)
+ && ACE_BIT_DISABLED (flags, THR_SCHED_RR)
+ && ACE_BIT_DISABLED (flags, THR_SCHED_DEFAULT))
+ ACE_SET_BITS (flags, THR_SCHED_DEFAULT);
+ }
+
+ if (ACE_BIT_ENABLED (flags, THR_SCHED_FIFO)
+ || ACE_BIT_ENABLED (flags, THR_SCHED_RR)
+ || ACE_BIT_ENABLED (flags, THR_SCHED_DEFAULT))
+ {
+ int spolicy;
+
+# if defined (ACE_HAS_ONLY_SCHED_OTHER)
+ // SunOS, thru version 5.6, only supports SCHED_OTHER.
+ spolicy = SCHED_OTHER;
+# else
+ // Make sure to enable explicit scheduling, in case we didn't
+ // enable it above (for non-default priority).
+ ACE_SET_BITS (flags, THR_EXPLICIT_SCHED);
+
+ if (ACE_BIT_ENABLED (flags, THR_SCHED_DEFAULT))
+ spolicy = SCHED_OTHER;
+ else if (ACE_BIT_ENABLED (flags, THR_SCHED_FIFO))
+ spolicy = SCHED_FIFO;
+# if defined (SCHED_IO)
+ else if (ACE_BIT_ENABLED (flags, THR_SCHED_IO))
+ spolicy = SCHED_IO;
+# else
+ else if (ACE_BIT_ENABLED (flags, THR_SCHED_IO))
+ {
+ errno = ENOSYS;
+ return -1;
+ }
+# endif /* SCHED_IO */
+ else
+ spolicy = SCHED_RR;
+
+ ACE_ADAPT_RETVAL(::pace_pthread_attr_setschedpolicy (&attr, spolicy),
+ result);
+ if (result != 0)
+ {
+ ::pace_pthread_attr_destroy (&attr);
+ return -1;
+ }
+ }
+
+ // *** Set Priority (use reasonable default priorities)
+# if defined(ACE_HAS_PTHREADS_STD)
+ // If we wish to explicitly set a scheduling policy, we also
+ // have to specify a priority. We choose a "middle" priority as
+ // default. Maybe this is also necessary on other POSIX'ish
+ // implementations?
+ if ((ACE_BIT_ENABLED (flags, THR_SCHED_FIFO)
+ || ACE_BIT_ENABLED (flags, THR_SCHED_RR)
+ || ACE_BIT_ENABLED (flags, THR_SCHED_DEFAULT))
+ && priority == ACE_DEFAULT_THREAD_PRIORITY)
+ {
+ if (ACE_BIT_ENABLED (flags, THR_SCHED_FIFO))
+ priority = ACE_THR_PRI_FIFO_DEF;
+ else if (ACE_BIT_ENABLED (flags, THR_SCHED_RR))
+ priority = ACE_THR_PRI_RR_DEF;
+ else // THR_SCHED_DEFAULT
+ priority = ACE_THR_PRI_OTHER_DEF;
+ }
+# endif /* ACE_HAS_PTHREADS_STD */
+ if (priority != ACE_DEFAULT_THREAD_PRIORITY)
+ {
+ pace_sched_param sparam;
+ ACE_OS::memset ((void *) &sparam, 0, sizeof sparam);
+ sparam.sched_priority = priority;
+# if defined (sun) && defined (ACE_HAS_ONLY_SCHED_OTHER)
+ // SunOS, through 5.6, POSIX only allows priorities > 0 to
+ // ::pthread_attr_setschedparam. If a priority of 0 was
+ // requested, set the thread priority after creating it, below.
+ if (priority > 0)
+# endif /* sun && ACE_HAS_ONLY_SCHED_OTHER */
+ {
+ ACE_ADAPT_RETVAL(::pace_pthread_attr_setschedparam (&attr, &sparam),
+ result);
+ if (result != 0)
+ {
+ ::pace_pthread_attr_destroy (&attr);
+ return -1;
+ }
+ }
+ }
+
+ if (ACE_BIT_ENABLED (flags, THR_INHERIT_SCHED)
+ || ACE_BIT_ENABLED (flags, THR_EXPLICIT_SCHED))
+ {
+ int sched = PTHREAD_EXPLICIT_SCHED;
+ if (ACE_BIT_ENABLED (flags, THR_INHERIT_SCHED))
+ sched = PTHREAD_INHERIT_SCHED;
+ if (::pace_pthread_attr_setinheritsched (&attr, sched) != 0)
+ {
+ ::pace_pthread_attr_destroy (&attr);
+ return -1;
+ }
+ }
+
+ // *** Set Scope
+# if !defined (ACE_LACKS_THREAD_PROCESS_SCOPING)
+ if (ACE_BIT_ENABLED (flags, THR_SCOPE_SYSTEM)
+ || ACE_BIT_ENABLED (flags, THR_SCOPE_PROCESS))
+ {
+# if defined (ACE_CONFIG_LINUX_H)
+ // LinuxThreads do not have support for PTHREAD_SCOPE_PROCESS.
+ int scope = PTHREAD_SCOPE_SYSTEM;
+# else /* ACE_CONFIG_LINUX_H */
+ int scope = PTHREAD_SCOPE_PROCESS;
+# endif /* ACE_CONFIG_LINUX_H */
+ if (ACE_BIT_ENABLED (flags, THR_SCOPE_SYSTEM))
+ scope = PTHREAD_SCOPE_SYSTEM;
+
+ if (::pace_pthread_attr_setscope (&attr, scope) != 0)
+ {
+ ::pace_pthread_attr_destroy (&attr);
+ return -1;
+ }
+ }
+# endif /* !ACE_LACKS_THREAD_PROCESS_SCOPING */
+
+ if (ACE_BIT_ENABLED (flags, THR_NEW_LWP))
+ {
+ // Increment the number of LWPs by one to emulate the
+ // SunOS semantics.
+ int lwps = ACE_OS::thr_getconcurrency ();
+ if (lwps == -1)
+ {
+ if (errno == ENOTSUP)
+ // Suppress the ENOTSUP because it's harmless.
+ errno = 0;
+ else
+ // This should never happen on SunOS:
+ // ::thr_getconcurrency () should always succeed.
+ return -1;
+ }
+ else if (ACE_OS::thr_setconcurrency (lwps + 1) == -1)
+ {
+ if (errno == ENOTSUP)
+ {
+ // Unlikely: ::thr_getconcurrency () is supported
+ // but ::thr_setconcurrency () is not?
+ }
+ else
+ return -1;
+ }
+ }
+ }
+
+ ACE_OSCALL (ACE_ADAPT_RETVAL (::pace_pthread_create (thr_id,
+ &attr,
+ PACE_THR_ENTRY_CAST (void * (*)(void *)) thread_args->entry_point (),
+ thread_args),
+ result),
+ int, -1, result);
+ ::pace_pthread_attr_destroy (&attr);
+# endif /* ACE_HAS_PTHREADS_DRAFT4 */
+
+ // This is a SunOS or POSIX implementation of pthreads,
+ // where we assume that ACE_thread_t and ACE_hthread_t are the same.
+ // If this *isn't* correct on some platform, please let us know.
+ if (result != -1)
+ *thr_handle = *thr_id;
+
+# if defined (sun) && defined (ACE_HAS_ONLY_SCHED_OTHER)
+ // SunOS prior to 5.7:
+
+ // If the priority is 0, then we might have to set it now
+ // because we couldn't set it with
+ // ::pthread_attr_setschedparam, as noted above. This doesn't
+ // provide strictly correct behavior, because the thread was
+ // created (above) with the priority of its parent. (That
+ // applies regardless of the inherit_sched attribute: if it
+ // was PTHREAD_INHERIT_SCHED, then it certainly inherited its
+ // parent's priority. If it was PTHREAD_EXPLICIT_SCHED, then
+ // "attr" was initialized by the SunOS ::pthread_attr_init
+ // () to contain NULL for the priority, which indicated to
+ // SunOS ::pthread_create () to inherit the parent
+ // priority.)
+ if (priority == 0)
+ {
+ // Check the priority of this thread, which is the parent
+ // of the newly created thread. If it is 0, then the
+ // newly created thread will have inherited the priority
+ // of 0, so there's no need to explicitly set it.
+ struct sched_param sparam;
+ int policy = 0;
+ ACE_OSCALL (ACE_ADAPT_RETVAL (::pace_pthread_getschedparam (thr_self (),
+ &policy,
+ &sparam),
+ result), int,
+ -1, result);
+
+ // The only policy supported by by SunOS, thru version 5.6,
+ // is SCHED_OTHER, so that's hard-coded here.
+ policy = ACE_SCHED_OTHER;
+
+ if (sparam.sched_priority != 0)
+ {
+ ACE_OS::memset ((void *) &sparam, 0, sizeof sparam);
+ // The memset to 0 sets the priority to 0, so we don't need
+ // to explicitly set sparam.sched_priority.
+
+ ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::pace_pthread_setschedparam (
+ *thr_id,
+ policy,
+ &sparam),
+ result),
+ int, -1);
+ }
+ }
+# endif /* sun && ACE_HAS_ONLY_SCHED_OTHER */
+ return result;
+
+#else /* ACE_HAS_PACE && !ACE_WIN32 */
+
+ ACE_Base_Thread_Adapter *thread_args;
+ if (thread_adapter == 0)
+
+# if defined (ACE_HAS_WIN32_STRUCTURAL_EXCEPTIONS)
+ ACE_NEW_RETURN (thread_args,
+ ACE_OS_Thread_Adapter (func, args,
+ (ACE_THR_C_FUNC) ace_thread_adapter,
+ ACE_OS_Object_Manager::seh_except_selector(),
+ ACE_OS_Object_Manager::seh_except_handler()),
+ -1);
+# else
+ ACE_NEW_RETURN (thread_args,
+ ACE_OS_Thread_Adapter (func, args,
+ (ACE_THR_C_FUNC) ace_thread_adapter),
+ -1);
+
+# endif /* ACE_HAS_WIN32_STRUCTURAL_EXCEPTIONS */
+ else
+ thread_args = thread_adapter;
+
+# if defined (ACE_HAS_THREADS)
+
+ // *** Set Stack Size
+# if defined (ACE_NEEDS_HUGE_THREAD_STACKSIZE)
+ if (stacksize < ACE_NEEDS_HUGE_THREAD_STACKSIZE)
+ stacksize = ACE_NEEDS_HUGE_THREAD_STACKSIZE;
+# endif /* ACE_NEEDS_HUGE_THREAD_STACKSIZE */
+
+# if !defined (VXWORKS)
+ // On VxWorks, the OS will provide a task name if the user doesn't.
+ // So, we don't need to create a tmp_thr. If the caller of this
+ // member function is the Thread_Manager, than thr_id will be non-zero
+ // anyways.
+ ACE_thread_t tmp_thr;
+
+ if (thr_id == 0)
+ thr_id = &tmp_thr;
+# endif /* ! VXWORKS */
+
+ ACE_hthread_t tmp_handle;
+ if (thr_handle == 0)
+ thr_handle = &tmp_handle;
+
+# if defined (ACE_HAS_PTHREADS)
+
+ int result;
+ pthread_attr_t attr;
+# if defined (ACE_HAS_PTHREADS_DRAFT4)
+ if (::pthread_attr_create (&attr) != 0)
+# else /* ACE_HAS_PTHREADS_DRAFT4 */
+ if (::pthread_attr_init (&attr) != 0)
+# endif /* ACE_HAS_PTHREADS_DRAFT4 */
+ return -1;
+
+# if defined (CHORUS)
+ // If it is a super actor, we can't set stacksize. But for the time
+ // being we are all non-super actors. Should be fixed to take care
+ // of super actors!!!
+ if (stacksize == 0)
+ stacksize = ACE_CHORUS_DEFAULT_MIN_STACK_SIZE;
+ else if (stacksize < ACE_CHORUS_DEFAULT_MIN_STACK_SIZE)
+ stacksize = ACE_CHORUS_DEFAULT_MIN_STACK_SIZE;
+# endif /*CHORUS */
+
+ if (stacksize != 0)
+ {
+ size_t size = stacksize;
+
+# if defined (PTHREAD_STACK_MIN)
+ if (size < ACE_static_cast (size_t, PTHREAD_STACK_MIN))
+ size = PTHREAD_STACK_MIN;
+# endif /* PTHREAD_STACK_MIN */
+
+# if !defined (ACE_LACKS_THREAD_STACK_SIZE) // JCEJ 12/17/96
+# if defined (ACE_HAS_PTHREADS_DRAFT4) || defined (ACE_HAS_PTHREADS_DRAFT6)
+ if (::pthread_attr_setstacksize (&attr, size) != 0)
+# else
+ if (ACE_ADAPT_RETVAL(pthread_attr_setstacksize (&attr, size), result) == -1)
+# endif /* ACE_HAS_PTHREADS_DRAFT4, 6 */
+ {
+# if defined (ACE_HAS_PTHREADS_DRAFT4)
+ ::pthread_attr_delete (&attr);
+# else /* ACE_HAS_PTHREADS_DRAFT4 */
+ ::pthread_attr_destroy (&attr);
+# endif /* ACE_HAS_PTHREADS_DRAFT4 */
+ return -1;
+ }
+# else
+ ACE_UNUSED_ARG (size);
+# endif /* !ACE_LACKS_THREAD_STACK_SIZE */
+ }
+
+ // *** Set Stack Address
+# if !defined (ACE_LACKS_THREAD_STACK_ADDR)
+ if (stack != 0)
+ {
+ if (::pthread_attr_setstackaddr (&attr, stack) != 0)
+ {
+# if defined (ACE_HAS_PTHREADS_DRAFT4)
+ ::pthread_attr_delete (&attr);
+# else /* ACE_HAS_PTHREADS_DRAFT4 */
+ ::pthread_attr_destroy (&attr);
+# endif /* ACE_HAS_PTHREADS_DRAFT4 */
+ return -1;
+ }
+ }
+# else
+ ACE_UNUSED_ARG (stack);
+# endif /* !ACE_LACKS_THREAD_STACK_ADDR */
+
+ // *** Deal with various attributes
+ if (flags != 0)
+ {
+ // *** Set Detach state
+# if !defined (ACE_LACKS_SETDETACH)
+ if (ACE_BIT_ENABLED (flags, THR_DETACHED)
+ || ACE_BIT_ENABLED (flags, THR_JOINABLE))
+ {
+ int dstate = PTHREAD_CREATE_JOINABLE;
+
+ if (ACE_BIT_ENABLED (flags, THR_DETACHED))
+ dstate = PTHREAD_CREATE_DETACHED;
+
+# if defined (ACE_HAS_PTHREADS_DRAFT4)
+ if (::pthread_attr_setdetach_np (&attr, dstate) != 0)
+# else /* ACE_HAS_PTHREADS_DRAFT4 */
+# if defined (ACE_HAS_PTHREADS_DRAFT6)
+ if (::pthread_attr_setdetachstate (&attr, &dstate) != 0)
+# else
+ if (ACE_ADAPT_RETVAL(::pthread_attr_setdetachstate (&attr, dstate),
+ result) != 0)
+# endif /* ACE_HAS_PTHREADS_DRAFT6 */
+# endif /* ACE_HAS_PTHREADS_DRAFT4 */
+ {
+# if defined (ACE_HAS_PTHREADS_DRAFT4)
+ ::pthread_attr_delete (&attr);
+# else /* ACE_HAS_PTHREADS_DRAFT4 */
+ ::pthread_attr_destroy (&attr);
+# endif /* ACE_HAS_PTHREADS_DRAFT4 */
+ return -1;
+ }
+ }
+
+ // Note: if ACE_LACKS_SETDETACH and THR_DETACHED is enabled, we
+ // call ::pthread_detach () below. If THR_DETACHED is not
+ // enabled, we call ::pthread_detach () in the Thread_Manager,
+ // after joining with the thread.
+# endif /* ACE_LACKS_SETDETACH */
+
+ // *** Set Policy
+# if !defined (ACE_LACKS_SETSCHED)
+ // If we wish to set the priority explicitly, we have to enable
+ // explicit scheduling, and a policy, too.
+ if (priority != ACE_DEFAULT_THREAD_PRIORITY)
+ {
+ ACE_SET_BITS (flags, THR_EXPLICIT_SCHED);
+ if (ACE_BIT_DISABLED (flags, THR_SCHED_FIFO)
+ && ACE_BIT_DISABLED (flags, THR_SCHED_RR)
+ && ACE_BIT_DISABLED (flags, THR_SCHED_DEFAULT))
+ ACE_SET_BITS (flags, THR_SCHED_DEFAULT);
+ }
+
+ if (ACE_BIT_ENABLED (flags, THR_SCHED_FIFO)
+ || ACE_BIT_ENABLED (flags, THR_SCHED_RR)
+ || ACE_BIT_ENABLED (flags, THR_SCHED_DEFAULT))
+ {
+ int spolicy;
+
+# if defined (ACE_HAS_ONLY_SCHED_OTHER)
+ // SunOS, thru version 5.6, only supports SCHED_OTHER.
+ spolicy = SCHED_OTHER;
+# else
+ // Make sure to enable explicit scheduling, in case we didn't
+ // enable it above (for non-default priority).
+ ACE_SET_BITS (flags, THR_EXPLICIT_SCHED);
+
+ if (ACE_BIT_ENABLED (flags, THR_SCHED_DEFAULT))
+ spolicy = SCHED_OTHER;
+ else if (ACE_BIT_ENABLED (flags, THR_SCHED_FIFO))
+ spolicy = SCHED_FIFO;
+# if defined (SCHED_IO)
+ else if (ACE_BIT_ENABLED (flags, THR_SCHED_IO))
+ spolicy = SCHED_IO;
+# else
+ else if (ACE_BIT_ENABLED (flags, THR_SCHED_IO))
+ {
+ errno = ENOSYS;
+ return -1;
+ }
+# endif /* SCHED_IO */
+ else
+ spolicy = SCHED_RR;
+
+# if defined (ACE_HAS_FSU_PTHREADS)
+ int ret;
+ switch (spolicy)
+ {
+ case SCHED_FIFO:
+ case SCHED_RR:
+ ret = 0;
+ break;
+ default:
+ ret = 22;
+ break;
+ }
+ if (ret != 0)
+ {
+ ::pthread_attr_destroy (&attr);
+ return -1;
+ }
+# endif /* ACE_HAS_FSU_PTHREADS */
+
+# endif /* ACE_HAS_ONLY_SCHED_OTHER */
+
+# if defined (ACE_HAS_PTHREADS_DRAFT4)
+ result = ::pthread_attr_setsched (&attr, spolicy);
+# elif defined (ACE_HAS_PTHREADS_DRAFT6)
+ result = ::pthread_attr_setschedpolicy (&attr, spolicy);
+# else /* draft 7 or std */
+ ACE_ADAPT_RETVAL(::pthread_attr_setschedpolicy (&attr, spolicy),
+ result);
+# endif /* ACE_HAS_PTHREADS_DRAFT4 */
+ if (result != 0)
+ {
+# if defined (ACE_HAS_PTHREADS_DRAFT4)
+ ::pthread_attr_delete (&attr);
+# else /* ACE_HAS_PTHREADS_DRAFT4 */
+ ::pthread_attr_destroy (&attr);
+# endif /* ACE_HAS_PTHREADS_DRAFT4 */
+ return -1;
+ }
+ }
+
+ // *** Set Priority (use reasonable default priorities)
+# if defined(ACE_HAS_PTHREADS_STD)
+ // If we wish to explicitly set a scheduling policy, we also
+ // have to specify a priority. We choose a "middle" priority as
+ // default. Maybe this is also necessary on other POSIX'ish
+ // implementations?
+ if ((ACE_BIT_ENABLED (flags, THR_SCHED_FIFO)
+ || ACE_BIT_ENABLED (flags, THR_SCHED_RR)
+ || ACE_BIT_ENABLED (flags, THR_SCHED_DEFAULT))
+ && priority == ACE_DEFAULT_THREAD_PRIORITY)
+ {
+ if (ACE_BIT_ENABLED (flags, THR_SCHED_FIFO))
+ priority = ACE_THR_PRI_FIFO_DEF;
+ else if (ACE_BIT_ENABLED (flags, THR_SCHED_RR))
+ priority = ACE_THR_PRI_RR_DEF;
+ else // THR_SCHED_DEFAULT
+ priority = ACE_THR_PRI_OTHER_DEF;
+ }
+# endif /* ACE_HAS_PTHREADS_STD */
+ if (priority != ACE_DEFAULT_THREAD_PRIORITY)
+ {
+ struct sched_param sparam;
+ ACE_OS::memset ((void *) &sparam, 0, sizeof sparam);
+
+# if defined (ACE_HAS_IRIX62_THREADS)
+ sparam.sched_priority = ACE_MIN (priority,
+ (long) PTHREAD_MAX_PRIORITY);
+# elif defined (PTHREAD_MAX_PRIORITY) && !defined(ACE_HAS_PTHREADS_STD)
+ /* For MIT pthreads... */
+ sparam.prio = ACE_MIN (priority, PTHREAD_MAX_PRIORITY);
+# elif defined(ACE_HAS_PTHREADS_STD) && !defined (ACE_HAS_STHREADS)
+ // The following code forces priority into range.
+ if (ACE_BIT_ENABLED (flags, THR_SCHED_FIFO))
+ sparam.sched_priority =
+ ACE_MIN (ACE_THR_PRI_FIFO_MAX,
+ ACE_MAX (ACE_THR_PRI_FIFO_MIN, priority));
+ else if (ACE_BIT_ENABLED(flags, THR_SCHED_RR))
+ sparam.sched_priority =
+ ACE_MIN (ACE_THR_PRI_RR_MAX,
+ ACE_MAX (ACE_THR_PRI_RR_MIN, priority));
+ else // Default policy, whether set or not
+ sparam.sched_priority =
+ ACE_MIN (ACE_THR_PRI_OTHER_MAX,
+ ACE_MAX (ACE_THR_PRI_OTHER_MIN, priority));
+# elif defined (PRIORITY_MAX)
+ sparam.sched_priority = ACE_MIN (priority,
+ (long) PRIORITY_MAX);
+# else
+ sparam.sched_priority = priority;
+# endif /* ACE_HAS_IRIX62_THREADS */
+
+# if defined (ACE_HAS_FSU_PTHREADS)
+ if (sparam.sched_priority >= PTHREAD_MIN_PRIORITY
+ && sparam.sched_priority <= PTHREAD_MAX_PRIORITY)
+ attr.prio = sparam.sched_priority;
+ else
+ {
+ pthread_attr_destroy (&attr);
+ errno = EINVAL;
+ return -1;
+ }
+# else
+ {
+# if defined (sun) && defined (ACE_HAS_ONLY_SCHED_OTHER)
+ // SunOS, through 5.6, POSIX only allows priorities > 0 to
+ // ::pthread_attr_setschedparam. If a priority of 0 was
+ // requested, set the thread priority after creating it, below.
+ if (priority > 0)
+# endif /* sun && ACE_HAS_ONLY_SCHED_OTHER */
+ {
+# if defined (ACE_HAS_PTHREADS_DRAFT4) || defined (ACE_HAS_PTHREADS_DRAFT6)
+ result = ::pthread_attr_setprio (&attr,
+ sparam.sched_priority);
+# else /* this is draft 7 or std */
+ ACE_ADAPT_RETVAL(::pthread_attr_setschedparam (&attr, &sparam),
+ result);
+# endif /* ACE_HAS_PTHREADS_DRAFT4, 6 */
+ if (result != 0)
+ {
+# if defined (ACE_HAS_PTHREADS_DRAFT4)
+ ::pthread_attr_delete (&attr);
+# else /* ACE_HAS_PTHREADS_DRAFT4 */
+ ::pthread_attr_destroy (&attr);
+# endif /* ACE_HAS_PTHREADS_DRAFT4 */
+ return -1;
+ }
+ }
+ }
+# endif /* ACE_HAS_FSU_PTHREADS */
+ }
+
+ // *** Set scheduling explicit or inherited
+ if (ACE_BIT_ENABLED (flags, THR_INHERIT_SCHED)
+ || ACE_BIT_ENABLED (flags, THR_EXPLICIT_SCHED))
+ {
+# if defined (ACE_HAS_PTHREADS_DRAFT4)
+ int sched = PTHREAD_DEFAULT_SCHED;
+# else /* ACE_HAS_PTHREADS_DRAFT4 */
+ int sched = PTHREAD_EXPLICIT_SCHED;
+# endif /* ACE_HAS_PTHREADS_DRAFT4 */
+ if (ACE_BIT_ENABLED (flags, THR_INHERIT_SCHED))
+ sched = PTHREAD_INHERIT_SCHED;
+ if (::pthread_attr_setinheritsched (&attr, sched) != 0)
+ {
+# if defined (ACE_HAS_PTHREADS_DRAFT4)
+ ::pthread_attr_delete (&attr);
+# else /* ACE_HAS_PTHREADS_DRAFT4 */
+ ::pthread_attr_destroy (&attr);
+# endif /* ACE_HAS_PTHREADS_DRAFT4 */
+ return -1;
+ }
+ }
+# else /* ACE_LACKS_SETSCHED */
+ ACE_UNUSED_ARG (priority);
+# endif /* ACE_LACKS_SETSCHED */
+
+ // *** Set Scope
+# if !defined (ACE_LACKS_THREAD_PROCESS_SCOPING)
+ if (ACE_BIT_ENABLED (flags, THR_SCOPE_SYSTEM)
+ || ACE_BIT_ENABLED (flags, THR_SCOPE_PROCESS))
+ {
+# if defined (ACE_CONFIG_LINUX_H) || defined (HPUX)
+ // LinuxThreads do not have support for PTHREAD_SCOPE_PROCESS.
+ // Neither does HPUX (up to HP-UX 11.00, as far as I know).
+ int scope = PTHREAD_SCOPE_SYSTEM;
+# else /* ACE_CONFIG_LINUX_H */
+ int scope = PTHREAD_SCOPE_PROCESS;
+# endif /* ACE_CONFIG_LINUX_H */
+ if (ACE_BIT_ENABLED (flags, THR_SCOPE_SYSTEM))
+ scope = PTHREAD_SCOPE_SYSTEM;
+
+ if (::pthread_attr_setscope (&attr, scope) != 0)
+ {
+# if defined (ACE_HAS_PTHREADS_DRAFT4)
+ ::pthread_attr_delete (&attr);
+# else /* ACE_HAS_PTHREADS_DRAFT4 */
+ ::pthread_attr_destroy (&attr);
+# endif /* ACE_HAS_PTHREADS_DRAFT4 */
+ return -1;
+ }
+ }
+# endif /* !ACE_LACKS_THREAD_PROCESS_SCOPING */
+
+ if (ACE_BIT_ENABLED (flags, THR_NEW_LWP))
+ {
+ // Increment the number of LWPs by one to emulate the
+ // SunOS semantics.
+ int lwps = ACE_OS::thr_getconcurrency ();
+ if (lwps == -1)
+ {
+ if (errno == ENOTSUP)
+ // Suppress the ENOTSUP because it's harmless.
+ errno = 0;
+ else
+ // This should never happen on SunOS:
+ // ::thr_getconcurrency () should always succeed.
+ return -1;
+ }
+ else if (ACE_OS::thr_setconcurrency (lwps + 1) == -1)
+ {
+ if (errno == ENOTSUP)
+ {
+ // Unlikely: ::thr_getconcurrency () is supported but
+ // ::thr_setconcurrency () is not?
+ }
+ else
+ return -1;
+ }
+ }
+ }
+
+# if defined (ACE_HAS_PTHREADS_DRAFT4)
+ ACE_OSCALL (::pthread_create (thr_id, attr,
+ thread_args->entry_point (),
+ thread_args),
+ int, -1, result);
+
+# if defined (ACE_LACKS_SETDETACH)
+ if (ACE_BIT_ENABLED (flags, THR_DETACHED))
+ {
+# if defined (HPUX_10)
+ // HP-UX DCE threads' pthread_detach will smash thr_id if it's
+ // just given as an argument. This will cause
+ // ACE_Thread_Manager (if it's doing this create) to lose track
+ // of the new thread since the ID will be passed back equal to
+ // 0. So give pthread_detach a junker to scribble on.
+ ACE_thread_t junker;
+ cma_handle_assign(thr_id, &junker);
+ ::pthread_detach (&junker);
+# else
+ ::pthread_detach (thr_id);
+# endif /* HPUX_10 */
+ }
+# endif /* ACE_LACKS_SETDETACH */
+
+ ::pthread_attr_delete (&attr);
+
+# elif defined (ACE_HAS_PTHREADS_DRAFT6)
+ ACE_OSCALL (::pthread_create (thr_id, &attr,
+ thread_args->entry_point (),
+ thread_args),
+ int, -1, result);
+ ::pthread_attr_destroy (&attr);
+
+# else /* this is draft 7 or std */
+ ACE_OSCALL (ACE_ADAPT_RETVAL (::pthread_create (thr_id,
+ &attr,
+ thread_args->entry_point (),
+ thread_args),
+ result),
+ int, -1, result);
+ ::pthread_attr_destroy (&attr);
+# endif /* ACE_HAS_PTHREADS_DRAFT4 */
+
+ // This is a SunOS or POSIX implementation of pthreads, where we
+ // assume that ACE_thread_t and ACE_hthread_t are the same. If this
+ // *isn't* correct on some platform, please let us know.
+ if (result != -1)
+ *thr_handle = *thr_id;
+
+# if defined (sun) && defined (ACE_HAS_ONLY_SCHED_OTHER)
+ // SunOS prior to 5.7:
+
+ // If the priority is 0, then we might have to set it now because we
+ // couldn't set it with ::pthread_attr_setschedparam, as noted
+ // above. This doesn't provide strictly correct behavior, because
+ // the thread was created (above) with the priority of its parent.
+ // (That applies regardless of the inherit_sched attribute: if it
+ // was PTHREAD_INHERIT_SCHED, then it certainly inherited its
+ // parent's priority. If it was PTHREAD_EXPLICIT_SCHED, then "attr"
+ // was initialized by the SunOS ::pthread_attr_init () to contain
+ // NULL for the priority, which indicated to SunOS ::pthread_create
+ // () to inherit the parent priority.)
+ if (priority == 0)
+ {
+ // Check the priority of this thread, which is the parent
+ // of the newly created thread. If it is 0, then the
+ // newly created thread will have inherited the priority
+ // of 0, so there's no need to explicitly set it.
+ struct sched_param sparam;
+ int policy = 0;
+ ACE_OSCALL (ACE_ADAPT_RETVAL (::pthread_getschedparam (thr_self (),
+ &policy,
+ &sparam),
+ result), int,
+ -1, result);
+
+ // The only policy supported by by SunOS, thru version 5.6,
+ // is SCHED_OTHER, so that's hard-coded here.
+ policy = ACE_SCHED_OTHER;
+
+ if (sparam.sched_priority != 0)
+ {
+ ACE_OS::memset ((void *) &sparam, 0, sizeof sparam);
+ // The memset to 0 sets the priority to 0, so we don't need
+ // to explicitly set sparam.sched_priority.
+
+ ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::pthread_setschedparam (*thr_id,
+ policy,
+ &sparam),
+ result),
+ int, -1);
+ }
+ }
+
+# if defined (ACE_NEEDS_LWP_PRIO_SET)
+# if 0
+ // It would be useful if we could make this work. But, it requires
+ // a mechanism for determining the ID of an LWP to which another
+ // thread is bound. Is there a way to do that? Instead, just rely
+ // on the code in ACE_Thread_Adapter::invoke () to set the LWP
+ // priority.
+
+ // If the thread is bound, then set the priority on its LWP.
+ if (ACE_BIT_ENABLED (flags, THR_BOUND))
+ {
+ ACE_Sched_Params sched_params (ACE_BIT_ENABLED (flags, THR_SCHED_FIFO) ||
+ ACE_BIT_ENABLED (flags, THR_SCHED_RR) ?
+ ACE_SCHED_FIFO :
+ ACE_SCHED_OTHER,
+ priority);
+ result = ACE_OS::lwp_setparams (sched_params,
+ /* ? How do we find the ID of the LWP
+ to which *thr_id is bound? */);
+ }
+# endif /* 0 */
+# endif /* ACE_NEEDS_LWP_PRIO_SET */
+
+# endif /* sun && ACE_HAS_ONLY_SCHED_OTHER */
+ return result;
+# elif defined (ACE_HAS_STHREADS)
+ int result;
+ int start_suspended = ACE_BIT_ENABLED (flags, THR_SUSPENDED);
+
+ if (priority != ACE_DEFAULT_THREAD_PRIORITY)
+ // If we need to set the priority, then we need to start the
+ // thread in a suspended mode.
+ ACE_SET_BITS (flags, THR_SUSPENDED);
+
+ ACE_OSCALL (ACE_ADAPT_RETVAL (::thr_create (stack, stacksize,
+ thread_args->entry_point (),
+ thread_args,
+ flags, thr_id), result),
+ int, -1, result);
+
+ if (result != -1)
+ {
+ // With SunOS threads, ACE_thread_t and ACE_hthread_t are the same.
+ *thr_handle = *thr_id;
+
+ if (priority != ACE_DEFAULT_THREAD_PRIORITY)
+ {
+ // Set the priority of the new thread and then let it
+ // continue, but only if the user didn't start it suspended
+ // in the first place!
+ if ((result = ACE_OS::thr_setprio (*thr_id, priority)) != 0)
+ {
+ errno = result;
+ return -1;
+ }
+
+ if (start_suspended == 0)
+ {
+ if ((result = ACE_OS::thr_continue (*thr_id)) != 0)
+ {
+ errno = result;
+ return -1;
+ }
+ }
+ }
+ }
+ return result;
+# elif defined (ACE_HAS_WTHREADS)
+ ACE_UNUSED_ARG (stack);
+# if defined (ACE_HAS_MFC) && (ACE_HAS_MFC != 0)
+ if (ACE_BIT_ENABLED (flags, THR_USE_AFX))
+ {
+ CWinThread *cwin_thread =
+ ::AfxBeginThread ((AFX_THREADPROC) thread_args->entry_point (),
+ thread_args,
+ priority,
+ 0,
+ flags | THR_SUSPENDED);
+ // Have to duplicate the handle because
+ // CWinThread::~CWinThread() closes the original handle.
+# if !defined (ACE_HAS_WINCE)
+ (void) ::DuplicateHandle (::GetCurrentProcess (),
+ cwin_thread->m_hThread,
+ ::GetCurrentProcess (),
+ thr_handle,
+ 0,
+ TRUE,
+ DUPLICATE_SAME_ACCESS);
+# endif /* ! ACE_HAS_WINCE */
+ *thr_id = cwin_thread->m_nThreadID;
+
+ if (ACE_BIT_ENABLED (flags, THR_SUSPENDED) == 0)
+ cwin_thread->ResumeThread ();
+ // cwin_thread will be deleted in AfxThreadExit()
+ // Warning: If AfxThreadExit() is called from within the
+ // thread, ACE_TSS_Cleanup->exit() never gets called !
+ }
+ else
+# endif /* ACE_HAS_MFC */
+ {
+ int start_suspended = ACE_BIT_ENABLED (flags, THR_SUSPENDED);
+
+ if (priority != ACE_DEFAULT_THREAD_PRIORITY)
+ // If we need to set the priority, then we need to start the
+ // thread in a suspended mode.
+ ACE_SET_BITS (flags, THR_SUSPENDED);
+
+ *thr_handle = (void *) ACE_BEGINTHREADEX (0,
+ stacksize,
+ thread_args->entry_point (),
+ thread_args,
+ flags,
+ thr_id);
+
+ if (priority != ACE_DEFAULT_THREAD_PRIORITY && *thr_handle != 0)
+ {
+ // Set the priority of the new thread and then let it
+ // continue, but only if the user didn't start it suspended
+ // in the first place!
+ ACE_OS::thr_setprio (*thr_handle, priority);
+
+ if (start_suspended == 0)
+ ACE_OS::thr_continue (*thr_handle);
+ }
+ }
+# if 0
+ *thr_handle = ::CreateThread
+ (0,
+ stacksize,
+ LPTHREAD_START_ROUTINE (thread_args->entry_point ()),
+ thread_args,
+ flags,
+ thr_id);
+# endif /* 0 */
+
+ // Close down the handle if no one wants to use it.
+ if (thr_handle == &tmp_handle)
+ ::CloseHandle (tmp_handle);
+
+ if (*thr_handle != 0)
+ return 0;
+ else
+ ACE_FAIL_RETURN (-1);
+ /* NOTREACHED */
+
+# elif defined (ACE_PSOS)
+
+ // stack is created in the task's memory region 0
+ ACE_UNUSED_ARG (stack);
+
+ // task creation and start flags are fixed
+ ACE_UNUSED_ARG (flags);
+
+ // lowest priority is reserved for the IDLE pSOS+ system daemon,
+ // highest are reserved for high priority pSOS+ system daemons
+ if (priority < PSOS_TASK_MIN_PRIORITY)
+ {
+ priority = PSOS_TASK_MIN_PRIORITY;
+ }
+ else if (priority > PSOS_TASK_MAX_PRIORITY)
+ {
+ priority = PSOS_TASK_MAX_PRIORITY;
+ }
+
+ // set the stacksize to a default value if no size is specified
+ if (stacksize == 0)
+ stacksize = ACE_PSOS_DEFAULT_STACK_SIZE;
+
+ ACE_hthread_t tid;
+ *thr_handle = 0;
+
+ // create the thread
+ if (t_create ((char *) thr_id, // task name
+ priority, // (possibly adjusted) task priority
+ stacksize, // passed stack size is used for supervisor stack
+ 0, // no user stack: tasks run strictly in supervisor mode
+ T_LOCAL, // local to the pSOS+ node (does not support pSOS+m)
+ &tid) // receives task id
+ != 0)
+ {
+ return -1;
+ }
+
+ // pSOS tasks are passed an array of 4 u_longs
+ u_long targs[4];
+ targs[0] = (u_long) ACE_THREAD_ARGUMENT;
+ targs[1] = 0;
+ targs[2] = 0;
+ targs[3] = 0;
+
+ // start the thread
+ if (t_start (tid,
+ T_PREEMPT | // Task can be preempted
+ // T_NOTSLICE | // Task is not timesliced with other tasks at same priority
+ T_TSLICE | // Task is timesliced with other tasks at same priority
+ T_NOASR | // Task level signals disabled
+ T_SUPV | // Task runs strictly in supervisor mode
+ T_ISR, // Hardware interrupts are enabled
+ ACE_THREAD_FUNCTION, // Task entry point
+ targs) // Task argument(s)
+ != 0)
+ {
+ return -1;
+ }
+
+ // store the task id in the handle and return success
+ *thr_handle = tid;
+ return 0;
+
+# elif defined (VXWORKS)
+ // The hard-coded values below are what ::sp () would use. (::sp ()
+ // hardcodes priority to 100, flags to VX_FP_TASK, and stacksize to
+ // 20,000.) stacksize should be an even integer. If a stack is not
+ // specified, ::taskSpawn () is used so that we can set the
+ // priority, flags, and stacksize. If a stack is specified,
+ // ::taskInit ()/::taskActivate() are used.
+
+ // If called with thr_create() defaults, use same default values as ::sp ():
+ if (priority == ACE_DEFAULT_THREAD_PRIORITY) priority = 100;
+ // Assumes that there is a floating point coprocessor. As noted
+ // above, ::sp () hardcodes this, so we should be safe with it.
+ if (flags == 0) flags = VX_FP_TASK;
+ if (stacksize == 0) stacksize = 20000;
+
+ const u_int thr_id_provided =
+ thr_id && *thr_id && (*thr_id)[0] != ACE_THR_ID_ALLOCATED;
+
+ ACE_hthread_t tid;
+# if 0 /* Don't support setting of stack, because it doesn't seem to work. */
+ if (stack == 0)
+ {
+# else
+ ACE_UNUSED_ARG (stack);
+# endif /* 0 */
+ // The call below to ::taskSpawn () causes VxWorks to assign a
+ // unique task name of the form: "t" + an integer, because the
+ // first argument is 0.
+ tid = ::taskSpawn (thr_id_provided ? *thr_id : 0,
+ priority,
+ (int) flags,
+ (int) stacksize,
+ thread_args->entry_point (),
+ (int) thread_args,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0);
+# if 0 /* Don't support setting of stack, because it doesn't seem to work. */
+ }
+ else
+ {
+ // If a task name (thr_id) was not supplied, then the task will
+ // not have a unique name. That's VxWorks' behavior.
+
+ // Carve out a TCB at the beginning of the stack space. The TCB
+ // occupies 400 bytes with VxWorks 5.3.1/I386.
+ WIND_TCB *tcb = (WIND_TCB *) stack;
+
+ // The TID is defined to be the address of the TCB.
+ int status = ::taskInit (tcb,
+ thr_id_provided ? *thr_id : 0,
+ priority,
+ (int) flags,
+ (char *) stack + sizeof (WIND_TCB),
+ (int) (stacksize - sizeof (WIND_TCB)),
+ thread_args->entry_point (),
+ (int) thread_args,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0);
+
+ if (status == OK)
+ {
+ // The task was successfully initialized, now activate it.
+ status = ::taskActivate ((ACE_hthread_t) tcb);
+ }
+
+ tid = status == OK ? (ACE_hthread_t) tcb : ERROR;
+ }
+# endif /* 0 */
+
+ if (tid == ERROR)
+ return -1;
+ else
+ {
+ if (! thr_id_provided && thr_id)
+ {
+ if (*thr_id && (*thr_id)[0] == ACE_THR_ID_ALLOCATED)
+ // *thr_id was allocated by the Thread_Manager. ::taskTcb
+ // (int tid) returns the address of the WIND_TCB (task
+ // control block). According to the ::taskSpawn()
+ // documentation, the name of the new task is stored at
+ // pStackBase, but is that of the current task? If so, it
+ // might be a bit quicker than this extraction of the tcb
+ // . . .
+ ACE_OS::strsncpy (*thr_id + 1, ::taskTcb (tid)->name, 10);
+ else
+ // *thr_id was not allocated by the Thread_Manager.
+ // Pass back the task name in the location pointed to
+ // by thr_id.
+ *thr_id = ::taskTcb (tid)->name;
+ }
+ // else if the thr_id was provided, there's no need to overwrite
+ // it with the same value (string). If thr_id is 0, then we can't
+ // pass the task name back.
+
+ if (thr_handle)
+ *thr_handle = tid;
+
+ return 0;
+ }
+
+# endif /* ACE_HAS_STHREADS */
+# else
+ ACE_UNUSED_ARG (func);
+ ACE_UNUSED_ARG (args);
+ ACE_UNUSED_ARG (flags);
+ ACE_UNUSED_ARG (thr_id);
+ ACE_UNUSED_ARG (thr_handle);
+ ACE_UNUSED_ARG (priority);
+ ACE_UNUSED_ARG (stack);
+ ACE_UNUSED_ARG (stacksize);
+ ACE_NOTSUP_RETURN (-1);
+# endif /* ACE_HAS_THREADS */
+#endif /* ACE_HAS_PACE && !ACE_WIN32 */
+}
+
+void
+ACE_OS::thr_exit (void *status)
+{
+ ACE_OS_TRACE ("ACE_OS::thr_exit");
+#if defined (ACE_HAS_PACE) && !defined (ACE_WIN32)
+ ::pace_pthread_exit (status);
+# elif defined (ACE_HAS_THREADS)
+# if defined (ACE_HAS_PTHREADS)
+ ::pthread_exit (status);
+# elif defined (ACE_HAS_STHREADS)
+ ::thr_exit (status);
+# elif defined (ACE_HAS_WTHREADS)
+ // Can't call it here because on NT, the thread is exited
+ // directly by ACE_Thread_Adapter::invoke ().
+ // ACE_TSS_Cleanup::instance ()->exit (status);
+
+# if defined (ACE_HAS_MFC) && (ACE_HAS_MFC != 0)
+ int using_afx = -1;
+ // An ACE_Thread_Descriptor really is an ACE_OS_Thread_Descriptor.
+ // But without #including ace/Thread_Manager.h, we don't know that.
+ ACE_OS_Thread_Descriptor *td =
+ ACE_Base_Thread_Adapter::thr_desc_log_msg ();
+ if (td)
+ using_afx = ACE_BIT_ENABLED (td->flags (), THR_USE_AFX);
+# endif /* ACE_HAS_MFC && (ACE_HAS_MFC != 0) */
+
+ // Call TSS destructors.
+ ACE_OS::cleanup_tss (0 /* not main thread */);
+
+ // Exit the thread.
+ // Allow CWinThread-destructor to be invoked from AfxEndThread.
+ // _endthreadex will be called from AfxEndThread so don't exit the
+ // thread now if we are running an MFC thread.
+# if defined (ACE_HAS_MFC) && (ACE_HAS_MFC != 0)
+ if (using_afx != -1)
+ {
+ if (using_afx)
+ ::AfxEndThread ((DWORD)status);
+ else
+ ACE_ENDTHREADEX (status);
+ }
+ else
+ {
+ // Not spawned by ACE_Thread_Manager, use the old buggy
+ // version. You should seriously consider using
+ // ACE_Thread_Manager to spawn threads. The following code is
+ // know to cause some problem.
+ CWinThread *pThread = ::AfxGetThread ();
+ if (!pThread || pThread->m_nThreadID != ACE_OS::thr_self ())
+ ACE_ENDTHREADEX (status);
+ else
+ ::AfxEndThread ((DWORD)status);
+ }
+# else
+ ACE_ENDTHREADEX (status);
+# endif /* ACE_HAS_MFC && ACE_HAS_MFS != 0*/
+
+# elif defined (VXWORKS)
+ ACE_hthread_t tid;
+ ACE_OS::thr_self (tid);
+ *((int *) status) = ::taskDelete (tid);
+# elif defined (ACE_PSOS)
+ ACE_hthread_t tid;
+ ACE_OS::thr_self (tid);
+
+# if defined (ACE_PSOS) && defined (ACE_PSOS_HAS_TSS)
+ // Call TSS destructors.
+ ACE_OS::cleanup_tss (0 /* not main thread */);
+# endif /* ACE_PSOS && ACE_PSOS_HAS_TSS */
+
+ *((u_long *) status) = ::t_delete (tid);
+# endif /* ACE_HAS_PTHREADS */
+# else
+ ACE_UNUSED_ARG (status);
+# endif /* ACE_HAS_PACE && !ACE_WIN32 */
+}
+
+int
+ACE_OS::lwp_getparams (ACE_Sched_Params &sched_params)
+{
+# if defined (ACE_HAS_STHREADS) || defined (sun)
+ // Get the class TS and RT class IDs.
+ ACE_id_t rt_id;
+ ACE_id_t ts_id;
+ if (ACE_OS::scheduling_class ("RT", rt_id) == -1
+ || ACE_OS::scheduling_class ("TS", ts_id) == -1)
+ return -1;
+
+ // Get this LWP's scheduling parameters.
+ pcparms_t pcparms;
+ // The following is just to avoid Purify warnings about unitialized
+ // memory reads.
+ ACE_OS::memset (&pcparms, 0, sizeof pcparms);
+ pcparms.pc_cid = PC_CLNULL;
+
+ if (ACE_OS::priority_control (P_LWPID,
+ P_MYID,
+ PC_GETPARMS,
+ (char *) &pcparms) == -1)
+ return -1;
+ else if (pcparms.pc_cid == rt_id)
+ {
+ // RT class.
+ rtparms_t rtparms;
+ ACE_OS::memcpy (&rtparms, pcparms.pc_clparms, sizeof rtparms);
+
+ sched_params.policy (ACE_SCHED_FIFO);
+ sched_params.priority (rtparms.rt_pri);
+ sched_params.scope (ACE_SCOPE_THREAD);
+ ACE_Time_Value quantum (rtparms.rt_tqsecs,
+ rtparms.rt_tqnsecs == RT_TQINF
+ ? 0 : rtparms.rt_tqnsecs * 1000);
+ sched_params.quantum (quantum);
+ return 0;
+ }
+ else if (pcparms.pc_cid == ts_id)
+ {
+ /* TS class */
+ tsparms_t tsparms;
+ ACE_OS::memcpy (&tsparms, pcparms.pc_clparms, sizeof tsparms);
+
+ sched_params.policy (ACE_SCHED_OTHER);
+ sched_params.priority (tsparms.ts_upri);
+ sched_params.scope (ACE_SCOPE_THREAD);
+ return 0;
+ }
+ else
+ return -1;
+
+# else /* ! ACE_HAS_STHREADS && ! sun */
+ ACE_UNUSED_ARG (sched_params);
+ ACE_NOTSUP_RETURN (-1);
+# endif /* ! ACE_HAS_STHREADS && ! sun */
+}
+
+int
+ACE_OS::lwp_setparams (const ACE_Sched_Params &sched_params)
+{
+# if defined (ACE_HAS_STHREADS) || defined (sun)
+ ACE_Sched_Params lwp_params (sched_params);
+ lwp_params.scope (ACE_SCOPE_LWP);
+ return ACE_OS::sched_params (lwp_params);
+# else /* ! ACE_HAS_STHREADS && ! sun */
+ ACE_UNUSED_ARG (sched_params);
+ ACE_NOTSUP_RETURN (-1);
+# endif /* ! ACE_HAS_STHREADS && ! sun */
+}
+
+# if defined (ACE_HAS_TSS_EMULATION) && defined (ACE_HAS_THREAD_SPECIFIC_STORAGE)
+int
+ACE_OS::thr_setspecific (ACE_OS_thread_key_t key, void *data)
+{
+ // ACE_OS_TRACE ("ACE_OS::thr_setspecific");
+# if defined (ACE_HAS_THREADS)
+# if defined (ACE_HAS_PTHREADS)
+# if defined (ACE_HAS_FSU_PTHREADS)
+ // Call pthread_init() here to initialize threads package. FSU
+ // threads need an initialization before the first thread constructor.
+ // This seems to be the one; however, a segmentation fault may
+ // indicate that another pthread_init() is necessary, perhaps in
+ // Synch.cpp or Synch_T.cpp. FSU threads will not reinit if called
+ // more than once, so another call to pthread_init will not adversely
+ // affect existing threads.
+ pthread_init ();
+# endif /* ACE_HAS_FSU_PTHREADS */
+ ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::pthread_setspecific (key, data), ace_result_), int, -1);
+# elif defined (ACE_HAS_STHREADS)
+ ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::thr_setspecific (key, data), ace_result_), int, -1);
+# elif defined (ACE_HAS_WTHREADS)
+ ::TlsSetValue (key, data);
+ return 0;
+# endif /* ACE_HAS_STHREADS */
+# else
+ ACE_UNUSED_ARG (key);
+ ACE_UNUSED_ARG (data);
+ ACE_NOTSUP_RETURN (-1);
+# endif /* ACE_HAS_THREADS */
+}
+# endif /* ACE_HAS_TSS_EMULATION && ACE_HAS_THREAD_SPECIFIC_STORAGE */
+
+int
+ACE_OS::thr_setspecific (ACE_thread_key_t key, void *data)
+{
+ // ACE_OS_TRACE ("ACE_OS::thr_setspecific");
+ // If we are using TSS emulation then we shuld use ACE's implementation
+ // of it and not make any PACE calls.
+#if defined (ACE_HAS_PACE) && !defined (ACE_HAS_TSS_EMULATION) && !defined (ACE_WIN32)
+ ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::pace_pthread_setspecific (key, data),
+ ace_result_),
+ int, -1);
+# elif defined (ACE_HAS_THREADS)
+# if defined (ACE_HAS_TSS_EMULATION)
+ ACE_KEY_INDEX (key_index, key);
+
+ if (key_index >= ACE_TSS_Emulation::total_keys ())
+ {
+ errno = EINVAL;
+ data = 0;
+ return -1;
+ }
+ else
+ {
+ ACE_TSS_Emulation::ts_object (key) = data;
+ ACE_TSS_Cleanup::instance ()->key_used (key);
+
+ return 0;
+ }
+# elif defined (ACE_HAS_PTHREADS)
+# if defined (ACE_HAS_FSU_PTHREADS)
+ // Call pthread_init() here to initialize threads package. FSU
+ // threads need an initialization before the first thread constructor.
+ // This seems to be the one; however, a segmentation fault may
+ // indicate that another pthread_init() is necessary, perhaps in
+ // Synch.cpp or Synch_T.cpp. FSU threads will not reinit if called
+ // more than once, so another call to pthread_init will not adversely
+ // affect existing threads.
+ pthread_init ();
+# endif /* ACE_HAS_FSU_PTHREADS */
+
+# if defined (ACE_HAS_PTHREADS_DRAFT4) || defined (ACE_HAS_PTHREADS_DRAFT6)
+ ACE_OSCALL_RETURN (::pthread_setspecific (key, data), int, -1);
+# else
+ ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::pthread_setspecific (key, data),
+ ace_result_),
+ int, -1);
+# endif /* ACE_HAS_PTHREADS_DRAFT4, 6 */
+
+# elif defined (ACE_HAS_STHREADS)
+ ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::thr_setspecific (key, data), ace_result_), int, -1);
+# elif defined (ACE_PSOS) && defined (ACE_PSOS_HAS_TSS)
+ ACE_hthread_t tid;
+ ACE_OS::thr_self (tid);
+ if (::tsd_setval (key, tid, data) != 0)
+ return -1;
+ ACE_TSS_Cleanup::instance ()->key_used (key);
+ return 0;
+# elif defined (ACE_HAS_WTHREADS)
+ ::TlsSetValue (key, data);
+ ACE_TSS_Cleanup::instance ()->key_used (key);
+ return 0;
+# else
+ ACE_UNUSED_ARG (key);
+ ACE_UNUSED_ARG (data);
+ ACE_NOTSUP_RETURN (-1);
+# endif /* ACE_HAS_STHREADS */
+# else
+ ACE_UNUSED_ARG (key);
+ ACE_UNUSED_ARG (data);
+ ACE_NOTSUP_RETURN (-1);
+# endif /* ACE_HAS_PACE && !ACE_HAS_TSS_EMULATION && !ACE_WIN32 */
+}
+
+int
+ACE_OS::thr_keyfree (ACE_thread_key_t key)
+{
+ ACE_OS_TRACE ("ACE_OS::thr_keyfree");
+ // If we are using TSS emulation then we should use ACE's implementation
+ // of it and not make any PACE calls.
+# if defined (ACE_HAS_PACE) && !defined (ACE_HAS_TSS_EMULATION) && !defined (ACE_WIN32)
+ return ::pace_pthread_key_delete (key);
+# elif defined (ACE_HAS_THREADS)
+# if defined (ACE_HAS_TSS_EMULATION)
+ // Release the key in the TSS_Emulation administration
+ ACE_TSS_Emulation::release_key (key);
+ return ACE_TSS_Cleanup::instance ()->remove (key);
+# elif defined (ACE_HAS_PTHREADS_DRAFT4) || defined (ACE_HAS_PTHREADS_DRAFT6)
+ ACE_UNUSED_ARG (key);
+ ACE_NOTSUP_RETURN (-1);
+# elif defined (ACE_HAS_PTHREADS)
+ return ::pthread_key_delete (key);
+# elif defined (ACE_HAS_THR_KEYDELETE)
+ return ::thr_keydelete (key);
+# elif defined (ACE_HAS_STHREADS)
+ ACE_UNUSED_ARG (key);
+ ACE_NOTSUP_RETURN (-1);
+# elif defined (ACE_HAS_WTHREADS)
+ // Extract out the thread-specific table instance and free up
+ // the key and destructor.
+ ACE_TSS_Cleanup::instance ()->remove (key);
+ ACE_WIN32CALL_RETURN (ACE_ADAPT_RETVAL (::TlsFree (key), ace_result_), int, -1);
+# elif defined (ACE_PSOS) && defined (ACE_PSOS_HAS_TSS)
+ // Extract out the thread-specific table instance and free up
+ // the key and destructor.
+ ACE_TSS_Cleanup::instance ()->remove (key);
+ return (::tsd_delete (key) == 0) ? 0 : -1;
+# else
+ ACE_UNUSED_ARG (key);
+ ACE_NOTSUP_RETURN (-1);
+# endif /* ACE_HAS_TSS_EMULATION */
+# else
+ ACE_UNUSED_ARG (key);
+ ACE_NOTSUP_RETURN (-1);
+# endif /* ACE_HAS_PACE && !ACE_HAS_TSS_EMULATION && !ACE_WIN32 */
+}
+
+# if defined (ACE_HAS_TSS_EMULATION) && defined (ACE_HAS_THREAD_SPECIFIC_STORAGE)
+int
+ACE_OS::thr_keycreate (ACE_OS_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_OS_TRACE ("ACE_OS::thr_keycreate");
+# if defined (ACE_HAS_PACE) && !defined (ACE_WIN32)
+ ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::pace_pthread_key_create (key, dest),
+ ace_result_),
+ int, -1);
+
+# elif defined (ACE_HAS_THREADS)
+# if defined (ACE_HAS_PTHREADS)
+ ACE_UNUSED_ARG (inst);
+
+
+# if defined (ACE_HAS_PTHREADS_DRAFT4)
+# if defined (ACE_HAS_STDARG_THR_DEST)
+ ACE_OSCALL_RETURN (::pthread_keycreate (key, (void (*)(...)) dest), int, -1);
+# else /* ! ACE_HAS_STDARG_THR_DEST */
+ ACE_OSCALL_RETURN (::pthread_keycreate (key, dest), int, -1);
+# endif /* ! ACE_HAS_STDARG_THR_DEST */
+# elif defined (ACE_HAS_PTHREADS_DRAFT6)
+ ACE_OSCALL_RETURN (::pthread_key_create (key, dest), int, -1);
+# else
+ ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::pthread_key_create (key, dest),
+ ace_result_),
+ int, -1);
+# endif /* ACE_HAS_PTHREADS_DRAFT4 */
+# elif defined (ACE_HAS_STHREADS)
+ ACE_UNUSED_ARG (inst);
+ ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::thr_keycreate (key, dest),
+ ace_result_),
+ int, -1);
+# elif defined (ACE_HAS_WTHREADS)
+ *key = ::TlsAlloc ();
+
+ if (*key != ACE_SYSCALL_FAILED)
+ {
+ // 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);
+ }
+ else
+ ACE_FAIL_RETURN (-1);
+ /* NOTREACHED */
+# endif /* ACE_HAS_STHREADS */
+# else
+ ACE_UNUSED_ARG (key);
+ ACE_UNUSED_ARG (dest);
+ ACE_UNUSED_ARG (inst);
+ ACE_NOTSUP_RETURN (-1);
+# endif /* ACE_HAS_PACE && !ACE_WIN32 */
+}
+# endif /* ACE_HAS_TSS_EMULATION && ACE_HAS_THREAD_SPECIFIC_STORAGE */
+
+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_OS_TRACE ("ACE_OS::thr_keycreate");
+ // If we are using TSS emulation then we shuld use ACE's implementation
+ // of it and not make any PACE calls.
+#if defined (ACE_HAS_PACE) && !defined (ACE_HAS_TSS_EMULATION) && !defined (ACE_WIN32)
+ ACE_UNUSED_ARG (inst);
+# if defined (ACE_WIN32)
+ int ace_result_ = 0;
+# endif /* ACE_WIN32 */
+ ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::pace_pthread_key_create (key, dest),
+ ace_result_),
+ int, -1);
+# elif defined (ACE_HAS_THREADS)
+# if defined (ACE_HAS_TSS_EMULATION)
+ if (ACE_TSS_Emulation::next_key (*key) == 0)
+ {
+ ACE_TSS_Emulation::tss_destructor (*key, dest);
+
+ // 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);
+ }
+ else
+ {
+ errno = EAGAIN;
+ return -1;
+ }
+# elif defined (ACE_HAS_PTHREADS)
+ ACE_UNUSED_ARG (inst);
+
+# if defined (ACE_HAS_PTHREADS_DRAFT4)
+# if defined (ACE_HAS_STDARG_THR_DEST)
+ ACE_OSCALL_RETURN (::pthread_keycreate (key, (void (*)(...)) dest), int, -1);
+# else /* ! ACE_HAS_STDARG_THR_DEST */
+ ACE_OSCALL_RETURN (::pthread_keycreate (key, dest), int, -1);
+# endif /* ! ACE_HAS_STDARG_THR_DEST */
+# elif defined (ACE_HAS_PTHREADS_DRAFT6)
+ ACE_OSCALL_RETURN (::pthread_key_create (key, dest), int, -1);
+# else
+ ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::pthread_key_create (key, dest),
+ ace_result_),
+ int, -1);
+# endif /* ACE_HAS_PTHREADS_DRAFT4 */
+
+# elif defined (ACE_HAS_STHREADS)
+ ACE_UNUSED_ARG (inst);
+ ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::thr_keycreate (key, dest),
+ ace_result_),
+ int, -1);
+# elif defined (ACE_PSOS) && defined (ACE_PSOS_HAS_TSS)
+
+ static u_long unique_name = 0;
+ void *tsdanchor;
+
+ ++unique_name;
+ if (::tsd_create (ACE_reinterpret_cast (char *, unique_name),
+ 0,
+ TSD_NOALLOC,
+ (void ****) &tsdanchor,
+ key) != 0)
+ {
+ return -1;
+ }
+
+ return ACE_TSS_Cleanup::instance ()->insert (*key, dest, inst);
+# elif defined (ACE_HAS_WTHREADS)
+ *key = ::TlsAlloc ();
+
+ if (*key != ACE_SYSCALL_FAILED)
+ {
+ // 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);
+ }
+ else
+ ACE_FAIL_RETURN (-1);
+ /* NOTREACHED */
+# else
+ ACE_UNUSED_ARG (key);
+ ACE_UNUSED_ARG (dest);
+ ACE_UNUSED_ARG (inst);
+ ACE_NOTSUP_RETURN (-1);
+# endif /* ACE_HAS_TSS_EMULATION */
+# else
+ ACE_UNUSED_ARG (key);
+ ACE_UNUSED_ARG (dest);
+ ACE_UNUSED_ARG (inst);
+ ACE_NOTSUP_RETURN (-1);
+# endif /* ACE_HAS_PACE && !ACE_HAS_TSS_EMULATION && !ACE_WIN32 */
+}
+
+int
+ACE_OS::thr_key_used (ACE_thread_key_t key)
+{
+# if defined (ACE_WIN32) || defined (ACE_HAS_TSS_EMULATION) || (defined (ACE_PSOS) && defined (ACE_PSOS_HAS_TSS))
+ ACE_TSS_Cleanup::instance ()->key_used (key);
+ return 0;
+# else
+ ACE_UNUSED_ARG (key);
+ ACE_NOTSUP_RETURN (-1);
+# endif /* ACE_WIN32 || ACE_HAS_TSS_EMULATION || ACE_PSOS_HAS_TSS */
+}
+
+int
+ACE_OS::thr_key_detach (void *inst)
+{
+# if defined (ACE_WIN32) || defined (ACE_HAS_TSS_EMULATION) || (defined (ACE_PSOS) && defined (ACE_PSOS_HAS_TSS))
+ if (ACE_TSS_Cleanup::lockable ())
+ return ACE_TSS_Cleanup::instance()->detach (inst);
+ else
+ // We're in static constructor/destructor phase. Don't
+ // try to use the ACE_TSS_Cleanup instance because its lock
+ // might not have been constructed yet, or might have been
+ // destroyed already. Just leak the key . . .
+ return -1;
+# else
+ ACE_UNUSED_ARG (inst);
+ ACE_NOTSUP_RETURN (-1);
+# endif /* ACE_WIN32 || ACE_HAS_TSS_EMULATION */
+}
+
+void
+ACE_OS::unique_name (const void *object,
+ ACE_TCHAR *name,
+ size_t length)
+{
+ // The process ID will provide uniqueness between processes on the
+ // same machine. The "this" pointer of the <object> will provide
+ // uniqueness between other "live" objects in the same process. The
+ // uniqueness of this name is therefore only valid for the life of
+ // <object>.
+ ACE_TCHAR temp_name[ACE_UNIQUE_NAME_LEN];
+ ACE_OS::sprintf (temp_name,
+ ACE_LIB_TEXT ("%lx%d"),
+ ACE_reinterpret_cast (long, object),
+ ACE_static_cast (int, ACE_OS::getpid ()));
+ ACE_OS::strsncpy (name,
+ temp_name,
+ length);
+}
+
+int
+ACE_OS::argv_to_string (ACE_TCHAR **argv,
+ ACE_TCHAR *&buf,
+ int substitute_env_args)
+{
+ if (argv == 0 || argv[0] == 0)
+ return 0;
+
+ int buf_len = 0;
+
+ // Determine the length of the buffer.
+
+ for (int i = 0; argv[i] != 0; i++)
+ {
+ ACE_TCHAR *temp = 0;
+
+#if !defined (ACE_LACKS_ENV)
+ // Account for environment variables.
+ if (substitute_env_args
+ && (argv[i][0] == '$'
+ && (temp = ACE_OS::getenv (&argv[i][1])) != 0))
+ buf_len += ACE_OS::strlen (temp);
+ else
+#endif /* ACE_LACKS_ENV */
+ buf_len += ACE_OS::strlen (argv[i]);
+
+ // Add one for the extra space between each string.
+ buf_len++;
+ }
+
+ // Step through all argv params and copy each one into buf; separate
+ // each param with white space.
+
+ ACE_NEW_RETURN (buf,
+ ACE_TCHAR[buf_len + 1],
+ 0);
+
+ // Initial null charater to make it a null string.
+ buf[0] = '\0';
+ ACE_TCHAR *end = buf;
+ int j;
+
+ for (j = 0; argv[j] != 0; j++)
+ {
+ ACE_TCHAR *temp = 0;
+
+# if !defined (ACE_LACKS_ENV)
+ // Account for environment variables.
+ if (substitute_env_args
+ && (argv[j][0] == '$'
+ && (temp = ACE_OS::getenv (&argv[j][1])) != 0))
+ end = ACE_OS::strecpy (end, temp);
+ else
+#endif /* ACE_LACKS_ENV */
+ end = ACE_OS::strecpy (end, argv[j]);
+
+ // Replace the null char that strecpy put there with white
+ // space.
+ end[-1] = ' ';
+ }
+
+ // Null terminate the string.
+ *end = '\0';
+ // The number of arguments.
+ return j;
+}
+
+int
+ACE_OS::string_to_argv (ACE_TCHAR *buf,
+ size_t &argc,
+ ACE_TCHAR **&argv,
+ int substitute_env_args)
+{
+ // Reset the number of arguments
+ argc = 0;
+
+ if (buf == 0)
+ return -1;
+
+ ACE_TCHAR *cp = buf;
+
+ // First pass: count arguments.
+
+ // '#' is the start-comment token..
+ while (*cp != '\0' && *cp != '#')
+ {
+ // Skip whitespace..
+ while (ACE_OS::ace_isspace (*cp))
+ cp++;
+
+ // Increment count and move to next whitespace..
+ if (*cp != '\0')
+ argc++;
+
+ while (*cp != '\0' && !ACE_OS::ace_isspace (*cp))
+ {
+ // Grok quotes....
+ if (*cp == '\'' || *cp == '"')
+ {
+ ACE_TCHAR quote = *cp;
+
+ // Scan past the string..
+ for (cp++; *cp != '\0' && *cp != quote; cp++)
+ continue;
+
+ // '\0' implies unmatched quote..
+ if (*cp == '\0')
+ {
+ argc--;
+ break;
+ }
+ else
+ cp++;
+ }
+ else
+ cp++;
+ }
+ }
+
+ // Second pass: copy arguments.
+ ACE_TCHAR arg[ACE_DEFAULT_ARGV_BUFSIZ];
+ ACE_TCHAR *argp = arg;
+
+ // Make sure that the buffer we're copying into is always large
+ // enough.
+ if (cp - buf >= ACE_DEFAULT_ARGV_BUFSIZ)
+ ACE_NEW_RETURN (argp,
+ ACE_TCHAR[cp - buf + 1],
+ -1);
+
+ // Make a new argv vector of argc + 1 elements.
+ ACE_NEW_RETURN (argv,
+ ACE_TCHAR *[argc + 1],
+ -1);
+
+ ACE_TCHAR *ptr = buf;
+
+ for (size_t i = 0; i < argc; i++)
+ {
+ // Skip whitespace..
+ while (ACE_OS::ace_isspace (*ptr))
+ ptr++;
+
+ // Copy next argument and move to next whitespace..
+ cp = argp;
+ while (*ptr != '\0' && !ACE_OS::ace_isspace (*ptr))
+ if (*ptr == '\'' || *ptr == '"')
+ {
+ ACE_TCHAR quote = *ptr++;
+
+ while (*ptr != '\0' && *ptr != quote)
+ *cp++ = *ptr++;
+
+ if (*ptr == quote)
+ ptr++;
+ }
+ else
+ *cp++ = *ptr++;
+
+ *cp = '\0';
+
+#if !defined (ACE_LACKS_ENV)
+ // Check for environment variable substitution here.
+ if (substitute_env_args) {
+ argv[i] = ACE_OS::strenvdup(argp);
+
+ if (argv[i] == 0)
+ {
+ if (argp != arg)
+ delete [] argp;
+ errno = ENOMEM;
+ return -1;
+ }
+ }
+ else
+#endif /* ACE_LACKS_ENV */
+ {
+ argv[i] = ACE_OS::strdup(argp);
+
+ if (argv[i] == 0)
+ {
+ if (argp != arg)
+ delete [] argp;
+ errno = ENOMEM;
+ return -1;
+ }
+ }
+ }
+
+ if (argp != arg)
+ delete [] argp;
+
+ argv[argc] = 0;
+ return 0;
+}
+
+// Create a contiguous command-line argument buffer with each arg
+// separated by spaces.
+
+pid_t
+ACE_OS::fork_exec (ACE_TCHAR *argv[])
+{
+# if defined (ACE_WIN32)
+ ACE_TCHAR *buf;
+
+ if (ACE_OS::argv_to_string (argv, buf) != -1)
+ {
+ PROCESS_INFORMATION process_info;
+# if !defined (ACE_HAS_WINCE)
+ ACE_TEXT_STARTUPINFO startup_info;
+ ACE_OS::memset ((void *) &startup_info,
+ 0,
+ sizeof startup_info);
+ startup_info.cb = sizeof startup_info;
+
+ if (ACE_TEXT_CreateProcess (0,
+ buf,
+ 0, // No process attributes.
+ 0, // No thread attributes.
+ TRUE, // Allow handle inheritance.
+ 0, // Don't create a new console window.
+ 0, // No environment.
+ 0, // No current directory.
+ &startup_info,
+ &process_info))
+# else
+ if (ACE_TEXT_CreateProcess (0,
+ buf,
+ 0, // No process attributes.
+ 0, // No thread attributes.
+ FALSE, // Can's inherit handles on CE
+ 0, // Don't create a new console window.
+ 0, // No environment.
+ 0, // No current directory.
+ 0, // Can't use startup info on CE
+ &process_info))
+# endif /* ! ACE_HAS_WINCE */
+ {
+ // Free resources allocated in kernel.
+ ACE_OS::close (process_info.hThread);
+ ACE_OS::close (process_info.hProcess);
+ // Return new process id.
+ delete [] buf;
+ return process_info.dwProcessId;
+ }
+ }
+
+ // CreateProcess failed.
+ return -1;
+# elif defined (CHORUS)
+ return ACE_OS::execv (argv[0], argv);
+# else
+ pid_t result = ACE_OS::fork ();
+
+ switch (result)
+ {
+ case -1:
+ // Error.
+ return -1;
+ case 0:
+ // Child process.
+ if (ACE_OS::execv (argv[0], argv) == -1)
+ {
+ // The OS layer should not print stuff out
+ // ACE_ERROR ((LM_ERROR,
+ // "%p Exec failed\n"));
+
+ // If the execv fails, this child needs to exit.
+ ACE_OS::exit (errno);
+ }
+ default:
+ // Server process. The fork succeeded.
+ return result;
+ }
+# endif /* ACE_WIN32 */
+}
+
+ssize_t
+ACE_OS::read_n (ACE_HANDLE handle,
+ void *buf,
+ size_t len,
+ size_t *bt)
+{
+ size_t temp;
+ size_t &bytes_transferred = bt == 0 ? temp : *bt;
+ ssize_t n;
+
+ for (bytes_transferred = 0;
+ bytes_transferred < len;
+ bytes_transferred += n)
+ {
+ n = ACE_OS::read (handle,
+ (char *) buf + bytes_transferred,
+ len - bytes_transferred);
+
+ if (n == -1 || n == 0)
+ return n;
+ }
+
+ return bytes_transferred;
+}
+
+// Write <len> bytes from <buf> to <handle> (uses the <write>
+// system call on UNIX and the <WriteFile> call on Win32).
+
+ssize_t
+ACE_OS::write_n (ACE_HANDLE handle,
+ const void *buf,
+ size_t len,
+ size_t *bt)
+{
+ size_t temp;
+ size_t &bytes_transferred = bt == 0 ? temp : *bt;
+ ssize_t n;
+
+ for (bytes_transferred = 0;
+ bytes_transferred < len;
+ bytes_transferred += n)
+ {
+ n = ACE_OS::write (handle,
+ (char *) buf + bytes_transferred,
+ len - bytes_transferred);
+
+ if (n == -1 || n == 0)
+ return n;
+ }
+
+ return bytes_transferred;
+}
+
+# if defined (ACE_LACKS_WRITEV)
+
+// "Fake" writev for operating systems without it. Note that this is
+// thread-safe.
+
+int
+ACE_OS::writev_emulation (ACE_HANDLE handle, ACE_WRITEV_TYPE iov[], int n)
+{
+ ACE_OS_TRACE ("ACE_OS::writev_emulation");
+
+ size_t length = 0;
+ int i;
+
+ // Determine the total length of all the buffers in <iov>.
+ for (i = 0; i < n; i++)
+ if (ACE_static_cast (int, iov[i].iov_len) < 0)
+ return -1;
+ else
+ length += iov[i].iov_len;
+
+ char *buf;
+
+# if defined (ACE_HAS_ALLOCA)
+ buf = (char *) alloca (length);
+# else
+ ACE_NEW_RETURN (buf,
+ char[length],
+ -1);
+# endif /* !defined (ACE_HAS_ALLOCA) */
+
+ char *ptr = buf;
+
+ for (i = 0; i < n; i++)
+ {
+ ACE_OS::memcpy (ptr, iov[i].iov_base, iov[i].iov_len);
+ ptr += iov[i].iov_len;
+ }
+
+ ssize_t result = ACE_OS::write (handle, buf, length);
+# if !defined (ACE_HAS_ALLOCA)
+ delete [] buf;
+# endif /* !defined (ACE_HAS_ALLOCA) */
+ return result;
+}
+# endif /* ACE_LACKS_WRITEV */
+
+# if defined (ACE_LACKS_READV)
+
+// "Fake" readv for operating systems without it. Note that this is
+// thread-safe.
+
+ssize_t
+ACE_OS::readv_emulation (ACE_HANDLE handle,
+ ACE_READV_TYPE *iov,
+ int n)
+{
+ ACE_OS_TRACE ("ACE_OS::readv_emulation");
+
+ ssize_t length = 0;
+ int i;
+
+ for (i = 0; i < n; i++)
+ if (ACE_static_cast (int, iov[i].iov_len) < 0)
+ return -1;
+ else
+ length += iov[i].iov_len;
+
+ char *buf;
+# if defined (ACE_HAS_ALLOCA)
+ buf = (char *) alloca (length);
+# else
+ ACE_NEW_RETURN (buf,
+ char[length],
+ -1);
+# endif /* !defined (ACE_HAS_ALLOCA) */
+
+ length = ACE_OS::read (handle, buf, length);
+
+ if (length != -1)
+ {
+ char *ptr = buf;
+ int copyn = length;
+
+ for (i = 0;
+ i < n && copyn > 0;
+ i++)
+ {
+ ACE_OS::memcpy (iov[i].iov_base, ptr,
+ // iov_len is int on some platforms, size_t on others
+ copyn > (int) iov[i].iov_len
+ ? (size_t) iov[i].iov_len
+ : (size_t) copyn);
+ ptr += iov[i].iov_len;
+ copyn -= iov[i].iov_len;
+ }
+ }
+
+# if !defined (ACE_HAS_ALLOCA)
+ delete [] buf;
+# endif /* !defined (ACE_HAS_ALLOCA) */
+ return length;
+}
+# endif /* ACE_LACKS_READV */
+
+# if defined (ACE_NEEDS_FTRUNCATE)
+extern "C" int
+ftruncate (ACE_HANDLE handle, long len)
+{
+ struct flock fl;
+ fl.l_whence = 0;
+ fl.l_len = 0;
+ fl.l_start = len;
+ fl.l_type = F_WRLCK;
+
+ return ACE_OS::fcntl (handle, F_FREESP, ACE_reinterpret_cast (long, &fl));
+}
+# endif /* ACE_NEEDS_FTRUNCATE */
+
+# if defined (ACE_LACKS_MKTEMP)
+ACE_TCHAR *
+ACE_OS::mktemp (ACE_TCHAR *s)
+{
+ ACE_OS_TRACE ("ACE_OS::mktemp");
+ if (s == 0)
+ // check for null template string failed!
+ return 0;
+ else
+ {
+ ACE_TCHAR *xxxxxx = ACE_OS::strstr (s, ACE_LIB_TEXT ("XXXXXX"));
+
+ if (xxxxxx == 0)
+ // the template string doesn't contain "XXXXXX"!
+ return s;
+ else
+ {
+ ACE_TCHAR unique_letter = ACE_LIB_TEXT ('a');
+ ACE_stat sb;
+
+ // Find an unused filename for this process. It is assumed
+ // that the user will open the file immediately after
+ // getting this filename back (so, yes, there is a race
+ // condition if multiple threads in a process use the same
+ // template). This appears to match the behavior of the
+ // SunOS 5.5 mktemp().
+ ACE_OS::sprintf (xxxxxx,
+ ACE_LIB_TEXT ("%05d%c"),
+ ACE_OS::getpid (),
+ unique_letter);
+ while (ACE_OS::stat (s, &sb) >= 0)
+ {
+ if (++unique_letter <= ACE_LIB_TEXT ('z'))
+ ACE_OS::sprintf (xxxxxx,
+ ACE_LIB_TEXT ("%05d%c"),
+ ACE_OS::getpid (),
+ unique_letter);
+ else
+ {
+ // maximum of 26 unique files per template, per process
+ ACE_OS::sprintf (xxxxxx, ACE_LIB_TEXT ("%s"), ACE_LIB_TEXT (""));
+ return s;
+ }
+ }
+ }
+ return s;
+ }
+}
+# endif /* ACE_LACKS_MKTEMP */
+
+int
+ACE_OS::socket_init (int version_high, int version_low)
+{
+# if defined (ACE_WIN32)
+ if (ACE_OS::socket_initialized_ == 0)
+ {
+ WORD version_requested = MAKEWORD (version_high, version_low);
+ WSADATA wsa_data;
+ int error = WSAStartup (version_requested, &wsa_data);
+
+ if (error != 0)
+# if defined (ACE_HAS_WINCE)
+ {
+ wchar_t fmt[] = ACE_LIB_TEXT ("%s failed, WSAGetLastError returned %d");
+ wchar_t buf[80]; // @@ Eliminate magic number.
+ ACE_OS::sprintf (buf, fmt, ACE_LIB_TEXT ("WSAStartup"), error);
+ ::MessageBox (NULL, buf, ACE_LIB_TEXT ("WSAStartup failed!"), MB_OK);
+ }
+# else
+ ACE_OS::fprintf (stderr,
+ "ACE_OS::socket_init; WSAStartup failed, "
+ "WSAGetLastError returned %d\n",
+ error);
+# endif /* ACE_HAS_WINCE */
+
+ ACE_OS::socket_initialized_ = 1;
+ }
+# else
+ ACE_UNUSED_ARG (version_high);
+ ACE_UNUSED_ARG (version_low);
+# endif /* ACE_WIN32 */
+ return 0;
+}
+
+int
+ACE_OS::socket_fini (void)
+{
+# if defined (ACE_WIN32)
+ if (ACE_OS::socket_initialized_ != 0)
+ {
+ if (WSACleanup () != 0)
+ {
+ int error = ::WSAGetLastError ();
+# if defined (ACE_HAS_WINCE)
+ wchar_t fmt[] = ACE_LIB_TEXT ("%s failed, WSAGetLastError returned %d");
+ wchar_t buf[80]; // @@ Eliminate magic number.
+ ACE_OS::sprintf (buf, fmt, ACE_LIB_TEXT ("WSACleanup"), error);
+ ::MessageBox (NULL, buf , ACE_LIB_TEXT ("WSACleanup failed!"), MB_OK);
+# else
+ ACE_OS::fprintf (stderr,
+ "ACE_OS::socket_fini; WSACleanup failed, "
+ "WSAGetLastError returned %d\n",
+ error);
+# endif /* ACE_HAS_WINCE */
+ }
+ ACE_OS::socket_initialized_ = 0;
+ }
+# endif /* ACE_WIN32 */
+ return 0;
+}
+
+# if defined (ACE_LACKS_SYS_NERR)
+# if defined (__rtems__)
+int sys_nerr = EWOULDBLOCK + 1; // definitely a hack.
+# else
+ int sys_nerr = ERRMAX + 1;
+# endif /* __rtems__ */
+# endif /* ACE_LACKS_SYS_NERR */
+
+# if defined (VXWORKS)
+# 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.
+int
+spa (FUNCPTR entry, ...)
+{
+ static const unsigned int MAX_ARGS = 10;
+ static char *argv[MAX_ARGS];
+ va_list pvar;
+ unsigned int argc;
+
+ // Hardcode a program name because the real one isn't available
+ // through the VxWorks shell.
+ argv[0] = "ace_main";
+
+ // 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;
+ }
+
+ 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)
+ ACE_OS::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 (unsigned int i = argc; i <= MAX_ARGS; ++i)
+ argv[i] = 0;
+ }
+
+ // The hard-coded options are what ::sp () uses, except for the
+ // larger stack size (instead of ::sp ()'s 20000).
+ const int ret = ::taskSpawn (argv[0], // task name
+ 100, // task priority
+ VX_FP_TASK, // task options
+ ACE_NEEDS_HUGE_THREAD_STACKSIZE, // stack size
+ entry, // entry point
+ argc, // first argument to main ()
+ (int) argv, // second argument to main ()
+ 0, 0, 0, 0, 0, 0, 0, 0);
+ va_end (pvar);
+
+ // ::taskSpawn () returns the taskID on success: return 0 instead if
+ // successful
+ return ret > 0 ? 0 : ret;
+}
+
+
+
+// A helper function for the extended spa functions
+static void
+add_to_argv (int& argc, char** argv, int max_args, char* string)
+{
+ char indouble = 0;
+ size_t previous = 0;
+ size_t length = ACE_OS_String::strlen (string);
+
+ // We use <= to make sure that we get the last argument
+ for (size_t i = 0; i <= length; i++)
+ {
+ // Is it a double quote that hasn't been escaped?
+ if (string[i] == '\"' && (i == 0 || string[i - 1] != '\\'))
+ {
+ indouble ^= 1;
+ if (indouble)
+ {
+ // We have just entered a double quoted string, so
+ // save the starting position of the contents.
+ previous = i + 1;
+ }
+ else
+ {
+ // We have just left a double quoted string, so
+ // zero out the ending double quote.
+ string[i] = '\0';
+ }
+ }
+ else if (string[i] == '\\') // Escape the next character
+ {
+ // The next character is automatically
+ // skipped because of the strcpy
+ ACE_OS_String::strcpy (string + i, string + i + 1);
+ length--;
+ }
+ else if (!indouble &&
+ (ACE_OS::ace_isspace (string[i]) || string[i] == '\0'))
+ {
+ string[i] = '\0';
+ if (argc < max_args)
+ {
+ argv[argc] = string + previous;
+ argc++;
+ }
+ else
+ {
+ ACE_OS::fprintf (stderr, "spae(): number of arguments "
+ "limited to %d\n", max_args);
+ }
+
+ // Skip over whitespace in between arguments
+ for(++i; i < length && ACE_OS::ace_isspace (string[i]); ++i)
+ {
+ }
+
+ // Save the starting point for the next time around
+ previous = i;
+
+ // Make sure we don't skip over a character due
+ // to the above loop to skip over whitespace
+ i--;
+ }
+ }
+}
+
+// This global function can be used from the VxWorks shell to pass
+// arguments to a C main () function.
+//
+// usage: -> spae main, "arg1 arg2 \"arg3 with spaces\""
+//
+// All arguments must be within double quotes, even numbers.
+int
+spae (FUNCPTR entry, ...)
+{
+ static const int WINDSH_ARGS = 10;
+ static const int MAX_ARGS = 128;
+ static char* argv[MAX_ARGS] = { "ace_main", 0 };
+ va_list pvar;
+ int argc = 1;
+
+ // 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.
+ va_start (pvar, entry);
+
+ int i = 0;
+ for (char* str = va_arg (pvar, char*);
+ str != 0 && i < WINDSH_ARGS; str = va_arg (pvar, char*), ++i)
+ {
+ add_to_argv(argc, argv, MAX_ARGS, str);
+ }
+
+ // fill unused argv slots with 0 to get rid of leftovers
+ // from previous invocations
+ for (i = argc; i < MAX_ARGS; ++i)
+ argv[i] = 0;
+
+ // The hard-coded options are what ::sp () uses, except for the
+ // larger stack size (instead of ::sp ()'s 20000).
+ const int ret = ::taskSpawn (argv[0], // task name
+ 100, // task priority
+ VX_FP_TASK, // task options
+ ACE_NEEDS_HUGE_THREAD_STACKSIZE, // stack size
+ entry, // entry point
+ argc, // first argument to main ()
+ (int) argv, // second argument to main ()
+ 0, 0, 0, 0, 0, 0, 0, 0);
+ va_end (pvar);
+
+ // ::taskSpawn () returns the taskID on success: return 0 instead if
+ // successful
+ return ret > 0 ? 0 : ret;
+}
+
+
+// This global function can be used from the VxWorks shell to pass
+// arguments to a C main () function. The function will be run
+// within the shells task.
+//
+// usage: -> spaef main, "arg1 arg2 \"arg3 with spaces\""
+//
+// All arguments must be within double quotes, even numbers.
+// Unlike the spae function, this fuction executes the supplied
+// routine in the foreground, rather than spawning it in a separate
+// task.
+int
+spaef (FUNCPTR entry, ...)
+{
+ static const int WINDSH_ARGS = 10;
+ static const int MAX_ARGS = 128;
+ static char* argv[MAX_ARGS] = { "ace_main", 0 };
+ va_list pvar;
+ int argc = 1;
+
+ // 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.
+ va_start (pvar, entry);
+
+ int i = 0;
+ for (char* str = va_arg (pvar, char*);
+ str != 0 && i < WINDSH_ARGS; str = va_arg (pvar, char*), ++i)
+ {
+ add_to_argv(argc, argv, MAX_ARGS, str);
+ }
+
+ // fill unused argv slots with 0 to get rid of leftovers
+ // from previous invocations
+ for (i = argc; i < MAX_ARGS; ++i)
+ argv[i] = 0;
+
+ int ret = entry (argc, argv);
+
+ va_end (pvar);
+
+ // Return the return value of the invoked ace_main routine.
+ return ret;
+}
+# endif /* VXWORKS */
+
+# if !defined (ACE_HAS_SIGINFO_T)
+# if !defined (ACE_HAS_PACE) || !defined (ACE_WIN32)
+siginfo_t::siginfo_t (ACE_HANDLE handle)
+ : si_handle_ (handle),
+ si_handles_ (&handle)
+{
+}
+
+siginfo_t::siginfo_t (ACE_HANDLE *handles)
+ : si_handle_ (handles[0]),
+ si_handles_ (handles)
+{
+}
+# endif /* ! ACE_HAS_PACE || ! ACE_WIN32 */
+# endif /* ACE_HAS_SIGINFO_T */
+
+pid_t
+ACE_OS::fork (const ACE_TCHAR *program_name)
+{
+ ACE_OS_TRACE ("ACE_OS::fork");
+# if defined (ACE_LACKS_FORK)
+ ACE_UNUSED_ARG (program_name);
+ ACE_NOTSUP_RETURN (pid_t (-1));
+# else
+ pid_t pid =
+# if defined (ACE_HAS_STHREADS)
+ ::fork1 ();
+#else
+ ::fork ();
+#endif /* ACE_HAS_STHREADS */
+
+#if !defined (ACE_HAS_MINIMAL_ACE_OS)
+ if (pid == 0)
+ ACE_Base_Thread_Adapter::sync_log_msg (program_name);
+#endif /* ! ACE_HAS_MINIMAL_ACE_OS */
+
+ return pid;
+# endif /* ACE_WIN32 */
+}
+
+void
+ACE_Cleanup::cleanup (void *)
+{
+ delete this;
+}
+
+
+ACE_Cleanup::~ACE_Cleanup (void)
+{
+}
+
+// This is necessary to work around nasty problems with MVS C++.
+
+extern "C" void
+ace_mutex_lock_cleanup_adapter (void *args)
+{
+ ACE_OS::mutex_lock_cleanup (args);
+}
+
+ACE_Thread_ID::ACE_Thread_ID (ACE_thread_t thread_id,
+ ACE_hthread_t thread_handle)
+ : thread_id_ (thread_id),
+ thread_handle_ (thread_handle)
+{
+}
+
+ACE_Thread_ID::ACE_Thread_ID (const ACE_Thread_ID &id)
+ : thread_id_ (id.thread_id_),
+ thread_handle_ (id.thread_handle_)
+{
+}
+
+ACE_thread_t
+ACE_Thread_ID::id (void)
+{
+ return this->thread_id_;
+}
+
+void
+ACE_Thread_ID::id (ACE_thread_t thread_id)
+{
+ this->thread_id_ = thread_id;
+}
+
+ACE_hthread_t
+ACE_Thread_ID::handle (void)
+{
+ return this->thread_handle_;
+}
+
+void
+ACE_Thread_ID::handle (ACE_hthread_t thread_handle)
+{
+ this->thread_handle_ = thread_handle;
+}
+
+int
+ACE_Thread_ID::operator== (const ACE_Thread_ID &rhs) const
+{
+ return ACE_OS::thr_cmp (this->thread_handle_, rhs.thread_handle_) == 0
+ && ACE_OS::thr_equal (this->thread_id_, rhs.thread_id_) == 0;
+}
+
+int
+ACE_Thread_ID::operator!= (const ACE_Thread_ID &rhs) const
+{
+ return !(*this == rhs);
+}
+
+// All other platforms have this inlined in OS.i
+#if defined (ACE_PSOS)
+char *
+ACE_OS::inet_ntoa (const struct in_addr addr)
+{
+ ACE_OS_TRACE ("ACE_OS::inet_ntoa");
+
+ static char addrstr[INET_ADDRSTRLEN + 1] = { 0 };
+ ACE_UINT32 ipaddr = ntohl (addr.s_addr);
+ //printf("Socket address %X, IP address %X.\n",addr.s_addr,ipaddr);
+ sprintf(addrstr, "%d.%d.%d.%d",
+ ((ipaddr & 0xff000000) >> 24) & 0x000000ff,
+ (ipaddr & 0x00ff0000) >> 16,
+ (ipaddr & 0x0000ff00) >> 8,
+ (ipaddr & 0x000000ff));
+ return addrstr;
+}
+#endif /* defined (ACE_PSOS) */
+
+int
+ACE_OS::inet_aton (const char *host_name, struct in_addr *addr)
+{
+#if defined (ACE_LACKS_INET_ATON)
+ ACE_UINT32 ip_addr = ACE_OS::inet_addr (host_name);
+
+ if (ip_addr == INADDR_NONE
+ // Broadcast addresses are weird...
+ && ACE_OS::strcmp (host_name, "255.255.255.255") != 0)
+ return 0;
+ else if (addr == 0)
+ return 0;
+ else
+ {
+ addr->s_addr = ip_addr; // Network byte ordered
+ return 1;
+ }
+#else
+ // inet_aton() returns 0 upon failure, not -1 since -1 is a valid
+ // address (255.255.255.255).
+ ACE_OSCALL_RETURN (::inet_aton (host_name, addr), int, 0);
+#endif /* ACE_LACKS_INET_ATON */
+}
+
+struct tm *
+ACE_OS::localtime_r (const time_t *t, struct tm *res)
+{
+ ACE_OS_TRACE ("ACE_OS::localtime_r");
+#if defined (ACE_HAS_REENTRANT_FUNCTIONS)
+# if defined (DIGITAL_UNIX)
+ ACE_OSCALL_RETURN (::_Plocaltime_r (t, res), struct tm *, 0);
+# elif defined (HPUX_10)
+ return (::localtime_r (t, res) == 0 ? res : (struct tm *)0);
+# else
+ ACE_OSCALL_RETURN (::localtime_r (t, res), struct tm *, 0);
+# endif /* DIGITAL_UNIX */
+#elif !defined (ACE_HAS_WINCE) && !defined(ACE_PSOS) || defined (ACE_PSOS_HAS_TIME)
+ ACE_OS_GUARD
+
+ ACE_UNUSED_ARG (res);
+ struct tm * res_ptr;
+ ACE_OSCALL (::localtime (t), struct tm *, 0, res_ptr);
+ if (res_ptr == 0)
+ return 0;
+ else
+ {
+ *res = *res_ptr;
+ return res;
+ }
+#else
+ // @@ Same as ACE_OS::localtime (), you need to implement it
+ // yourself.
+ ACE_UNUSED_ARG (t);
+ ACE_UNUSED_ARG (res);
+ ACE_NOTSUP_RETURN (0);
+#endif /* ACE_HAS_REENTRANT_FUNCTIONS */
+}
+
+ssize_t
+ACE_OS::pread (ACE_HANDLE handle,
+ void *buf,
+ size_t nbytes,
+ off_t offset)
+{
+# if defined (ACE_HAS_P_READ_WRITE)
+# if defined (ACE_WIN32)
+
+ ACE_OS_GUARD
+
+ // Remember the original file pointer position
+ DWORD original_position = ::SetFilePointer (handle,
+ 0,
+ NULL,
+ FILE_CURRENT);
+
+ if (original_position == 0xFFFFFFFF)
+ return -1;
+
+ // Go to the correct position
+ DWORD altered_position = ::SetFilePointer (handle,
+ offset,
+ NULL,
+ FILE_BEGIN);
+ if (altered_position == 0xFFFFFFFF)
+ return -1;
+
+ DWORD bytes_read;
+
+# if defined (ACE_HAS_WINNT4) && (ACE_HAS_WINNT4 != 0)
+
+ OVERLAPPED overlapped;
+ overlapped.Internal = 0;
+ overlapped.InternalHigh = 0;
+ overlapped.Offset = offset;
+ overlapped.OffsetHigh = 0;
+ overlapped.hEvent = 0;
+
+ BOOL result = ::ReadFile (handle,
+ buf,
+ nbytes,
+ &bytes_read,
+ &overlapped);
+
+ if (result == FALSE)
+ {
+ if (::GetLastError () != ERROR_IO_PENDING)
+ return -1;
+
+ else
+ {
+ result = ::GetOverlappedResult (handle,
+ &overlapped,
+ &bytes_read,
+ TRUE);
+ if (result == FALSE)
+ return -1;
+ }
+ }
+
+# else /* ACE_HAS_WINNT4 && (ACE_HAS_WINNT4 != 0) */
+
+ BOOL result = ::ReadFile (handle,
+ buf,
+ nbytes,
+ &bytes_read,
+ NULL);
+ if (result == FALSE)
+ return -1;
+
+# endif /* ACE_HAS_WINNT4 && (ACE_HAS_WINNT4 != 0) */
+
+ // Reset the original file pointer position
+ if (::SetFilePointer (handle,
+ original_position,
+ NULL,
+ FILE_BEGIN) == 0xFFFFFFFF)
+ return -1;
+
+ return (ssize_t) bytes_read;
+
+# else /* ACE_WIN32 */
+
+ return ::pread (handle, buf, nbytes, offset);
+
+# endif /* ACE_WIN32 */
+
+# else /* ACE_HAS_P_READ_WRITE */
+
+ ACE_OS_GUARD
+
+ // Remember the original file pointer position
+ off_t original_position = ACE_OS::lseek (handle,
+ 0,
+ SEEK_CUR);
+
+ if (original_position == -1)
+ return -1;
+
+ // Go to the correct position
+ off_t altered_position = ACE_OS::lseek (handle,
+ offset,
+ SEEK_SET);
+
+ if (altered_position == -1)
+ return -1;
+
+ ssize_t bytes_read = ACE_OS::read (handle,
+ buf,
+ nbytes);
+
+ if (bytes_read == -1)
+ return -1;
+
+ if (ACE_OS::lseek (handle,
+ original_position,
+ SEEK_SET) == -1)
+ return -1;
+
+ return bytes_read;
+
+# endif /* ACE_HAD_P_READ_WRITE */
+}
+
+ssize_t
+ACE_OS::pwrite (ACE_HANDLE handle,
+ const void *buf,
+ size_t nbytes,
+ off_t offset)
+{
+# if defined (ACE_HAS_P_READ_WRITE)
+# if defined (ACE_WIN32)
+
+ ACE_OS_GUARD
+
+ // Remember the original file pointer position
+ DWORD original_position = ::SetFilePointer (handle,
+ 0,
+ NULL,
+ FILE_CURRENT);
+
+ if (original_position == 0xFFFFFFFF)
+ return -1;
+
+ // Go to the correct position
+ DWORD altered_position = ::SetFilePointer (handle,
+ offset,
+ NULL,
+ FILE_BEGIN);
+ if (altered_position == 0xFFFFFFFF)
+ return -1;
+
+ DWORD bytes_written;
+
+# if defined (ACE_HAS_WINNT4) && (ACE_HAS_WINNT4 != 0)
+
+ OVERLAPPED overlapped;
+ overlapped.Internal = 0;
+ overlapped.InternalHigh = 0;
+ overlapped.Offset = offset;
+ overlapped.OffsetHigh = 0;
+ overlapped.hEvent = 0;
+
+ BOOL result = ::WriteFile (handle,
+ buf,
+ nbytes,
+ &bytes_written,
+ &overlapped);
+
+ if (result == FALSE)
+ {
+ if (::GetLastError () != ERROR_IO_PENDING)
+ return -1;
+
+ else
+ {
+ result = ::GetOverlappedResult (handle,
+ &overlapped,
+ &bytes_written,
+ TRUE);
+ if (result == FALSE)
+ return -1;
+ }
+ }
+
+# else /* ACE_HAS_WINNT4 && (ACE_HAS_WINNT4 != 0) */
+
+ BOOL result = ::WriteFile (handle,
+ buf,
+ nbytes,
+ &bytes_written,
+ NULL);
+ if (result == FALSE)
+ return -1;
+
+# endif /* ACE_HAS_WINNT4 && (ACE_HAS_WINNT4 != 0) */
+
+ // Reset the original file pointer position
+ if (::SetFilePointer (handle,
+ original_position,
+ NULL,
+ FILE_BEGIN) == 0xFFFFFFFF)
+ return -1;
+
+ return (ssize_t) bytes_written;
+
+# else /* ACE_WIN32 */
+
+ return ::pwrite (handle, buf, nbytes, offset);
+# endif /* ACE_WIN32 */
+# else /* ACE_HAS_P_READ_WRITE */
+
+ ACE_OS_GUARD
+
+ // Remember the original file pointer position
+ off_t original_position = ACE_OS::lseek (handle,
+ 0,
+ SEEK_CUR);
+ if (original_position == -1)
+ return -1;
+
+ // Go to the correct position
+ off_t altered_position = ACE_OS::lseek (handle,
+ offset,
+ SEEK_SET);
+ if (altered_position == -1)
+ return -1;
+
+ ssize_t bytes_written = ACE_OS::write (handle,
+ buf,
+ nbytes);
+ if (bytes_written == -1)
+ return -1;
+
+ if (ACE_OS::lseek (handle,
+ original_position,
+ SEEK_SET) == -1)
+ return -1;
+
+ return bytes_written;
+# endif /* ACE_HAD_P_READ_WRITE */
+}
+
+ACE_HANDLE
+ACE_OS::open (const char *filename,
+ int mode,
+ int perms,
+ LPSECURITY_ATTRIBUTES sa)
+{
+ ACE_OS_TRACE ("ACE_OS::open");
+
+#if defined (ACE_WIN32)
+ DWORD access = GENERIC_READ;
+ if (ACE_BIT_ENABLED (mode, O_WRONLY))
+ access = GENERIC_WRITE;
+ else if (ACE_BIT_ENABLED (mode, O_RDWR))
+ access = GENERIC_READ | GENERIC_WRITE;
+
+ DWORD creation = OPEN_EXISTING;
+
+ if ((mode & (_O_CREAT | _O_EXCL)) == (_O_CREAT | _O_EXCL))
+ creation = CREATE_NEW;
+ else if ((mode & (_O_CREAT | _O_TRUNC)) == (_O_CREAT | _O_TRUNC))
+ creation = CREATE_ALWAYS;
+ else if (ACE_BIT_ENABLED (mode, _O_CREAT))
+ creation = OPEN_ALWAYS;
+ else if (ACE_BIT_ENABLED (mode, _O_TRUNC))
+ creation = TRUNCATE_EXISTING;
+
+ DWORD flags = 0;
+
+ if (ACE_BIT_ENABLED (mode, _O_TEMPORARY))
+ flags |= FILE_FLAG_DELETE_ON_CLOSE | FILE_ATTRIBUTE_TEMPORARY;
+
+ if (ACE_BIT_ENABLED (mode, FILE_FLAG_WRITE_THROUGH))
+ flags |= FILE_FLAG_WRITE_THROUGH;
+ if (ACE_BIT_ENABLED (mode, FILE_FLAG_OVERLAPPED))
+ flags |= FILE_FLAG_OVERLAPPED;
+ if (ACE_BIT_ENABLED (mode, FILE_FLAG_NO_BUFFERING))
+ flags |= FILE_FLAG_NO_BUFFERING;
+ if (ACE_BIT_ENABLED (mode, FILE_FLAG_RANDOM_ACCESS))
+ flags |= FILE_FLAG_RANDOM_ACCESS;
+ if (ACE_BIT_ENABLED (mode, FILE_FLAG_SEQUENTIAL_SCAN))
+ flags |= FILE_FLAG_SEQUENTIAL_SCAN;
+ if (ACE_BIT_ENABLED (mode, FILE_FLAG_DELETE_ON_CLOSE))
+ flags |= FILE_FLAG_DELETE_ON_CLOSE;
+ if (ACE_BIT_ENABLED (mode, FILE_FLAG_BACKUP_SEMANTICS))
+ flags |= FILE_FLAG_BACKUP_SEMANTICS;
+ if (ACE_BIT_ENABLED (mode, FILE_FLAG_POSIX_SEMANTICS))
+ flags |= FILE_FLAG_POSIX_SEMANTICS;
+
+ ACE_MT (ACE_thread_mutex_t *ace_os_monitor_lock = 0;)
+
+ if (ACE_BIT_ENABLED (mode, _O_APPEND))
+ {
+ ACE_MT
+ (
+ ace_os_monitor_lock = (ACE_thread_mutex_t *)
+ ACE_OS_Object_Manager::preallocated_object[
+ ACE_OS_Object_Manager::ACE_OS_MONITOR_LOCK];
+ ACE_OS::thread_mutex_lock (ace_os_monitor_lock);
+ )
+ }
+
+ DWORD shared_mode = perms;
+
+#if defined (ACE_HAS_WINCE)
+ ACE_HANDLE h = ::CreateFileW (ACE_Ascii_To_Wide (filename).wchar_rep (), access,
+ shared_mode,
+ ACE_OS::default_win32_security_attributes (sa),
+ creation,
+ flags,
+ 0);
+#else /* ACE_HAS_WINCE */
+ ACE_HANDLE h = ::CreateFileA (filename, access,
+ shared_mode,
+ ACE_OS::default_win32_security_attributes (sa),
+ creation,
+ flags,
+ 0);
+#endif /* ACE_HAS_WINCE */
+
+ if (ACE_BIT_ENABLED (mode, _O_APPEND))
+ {
+ if (h != ACE_INVALID_HANDLE)
+ {
+ ::SetFilePointer (h, 0, 0, FILE_END);
+ }
+
+ ACE_MT (ACE_OS::thread_mutex_unlock (ace_os_monitor_lock);)
+ }
+
+ if (h == ACE_INVALID_HANDLE)
+ ACE_FAIL_RETURN (h);
+ else
+ return h;
+#elif defined (ACE_PSOS)
+ ACE_UNUSED_ARG (perms);
+ ACE_UNUSED_ARG (sa);
+# if defined (ACE_PSOS_LACKS_PHILE)
+ ACE_UNUSED_ARG (filename);
+ return 0;
+# else
+ unsigned long result, handle;
+ result = ::open_f (&handle, ACE_const_cast(char *, filename), 0);
+ if (result != 0)
+ {
+ // We need to clean this up...not 100% correct!
+ // To correct we should handle all the cases of TRUNC and CREAT
+ if ((result == 0x200B) && (ACE_BIT_ENABLED (mode, O_CREAT)))
+ {
+ result = ::create_f(ACE_const_cast(char *, filename),1,0);
+ if (result != 0)
+ {
+ errno = result;
+ return ACE_static_cast (ACE_HANDLE, -1);
+ }
+ else //File created...try to open it again
+ {
+ result = ::open_f (&handle, ACE_const_cast(char *, filename), 0);
+ if (result != 0)
+ {
+ errno = result;
+ return ACE_static_cast (ACE_HANDLE, -1);
+ }
+
+ }
+ }
+ else
+ {
+ errno = result;
+ return ACE_static_cast (ACE_HANDLE, -1);
+ }
+ }
+ return ACE_static_cast (ACE_HANDLE, handle);
+# endif /* defined (ACE_PSOS_LACKS_PHILE) */
+#else
+ ACE_UNUSED_ARG (sa);
+ ACE_OSCALL_RETURN (::open (filename, mode, perms), ACE_HANDLE, -1);
+#endif /* ACE_WIN32 */
+}
+
+#if defined (ACE_HAS_WCHAR)
+ACE_HANDLE
+ACE_OS::open (const wchar_t *filename,
+ int mode,
+ int perms,
+ LPSECURITY_ATTRIBUTES sa)
+{
+#if defined (ACE_WIN32)
+ // @@ (brunsch) Yuck, maybe there is a way to combine the code
+ // here with the char version
+
+ DWORD access = GENERIC_READ;
+ if (ACE_BIT_ENABLED (mode, O_WRONLY))
+ access = GENERIC_WRITE;
+ else if (ACE_BIT_ENABLED (mode, O_RDWR))
+ access = GENERIC_READ | GENERIC_WRITE;
+
+ DWORD creation = OPEN_EXISTING;
+
+ if ((mode & (_O_CREAT | _O_EXCL)) == (_O_CREAT | _O_EXCL))
+ creation = CREATE_NEW;
+ else if ((mode & (_O_CREAT | _O_TRUNC)) == (_O_CREAT | _O_TRUNC))
+ creation = CREATE_ALWAYS;
+ else if (ACE_BIT_ENABLED (mode, _O_CREAT))
+ creation = OPEN_ALWAYS;
+ else if (ACE_BIT_ENABLED (mode, _O_TRUNC))
+ creation = TRUNCATE_EXISTING;
+
+ DWORD flags = 0;
+
+ if (ACE_BIT_ENABLED (mode, _O_TEMPORARY))
+ flags |= FILE_FLAG_DELETE_ON_CLOSE | FILE_ATTRIBUTE_TEMPORARY;
+
+ if (ACE_BIT_ENABLED (mode, FILE_FLAG_WRITE_THROUGH))
+ flags |= FILE_FLAG_WRITE_THROUGH;
+ if (ACE_BIT_ENABLED (mode, FILE_FLAG_OVERLAPPED))
+ flags |= FILE_FLAG_OVERLAPPED;
+ if (ACE_BIT_ENABLED (mode, FILE_FLAG_NO_BUFFERING))
+ flags |= FILE_FLAG_NO_BUFFERING;
+ if (ACE_BIT_ENABLED (mode, FILE_FLAG_RANDOM_ACCESS))
+ flags |= FILE_FLAG_RANDOM_ACCESS;
+ if (ACE_BIT_ENABLED (mode, FILE_FLAG_SEQUENTIAL_SCAN))
+ flags |= FILE_FLAG_SEQUENTIAL_SCAN;
+ if (ACE_BIT_ENABLED (mode, FILE_FLAG_DELETE_ON_CLOSE))
+ flags |= FILE_FLAG_DELETE_ON_CLOSE;
+ if (ACE_BIT_ENABLED (mode, FILE_FLAG_BACKUP_SEMANTICS))
+ flags |= FILE_FLAG_BACKUP_SEMANTICS;
+ if (ACE_BIT_ENABLED (mode, FILE_FLAG_POSIX_SEMANTICS))
+ flags |= FILE_FLAG_POSIX_SEMANTICS;
+
+ ACE_MT (ACE_thread_mutex_t *ace_os_monitor_lock = 0;)
+
+ if (ACE_BIT_ENABLED (mode, _O_APPEND))
+ {
+ ACE_MT
+ (
+ ace_os_monitor_lock = (ACE_thread_mutex_t *)
+ ACE_OS_Object_Manager::preallocated_object[
+ ACE_OS_Object_Manager::ACE_OS_MONITOR_LOCK];
+ ACE_OS::thread_mutex_lock (ace_os_monitor_lock);
+ )
+ }
+
+ DWORD shared_mode = perms;
+
+ ACE_HANDLE h = ::CreateFileW (filename,
+ access,
+ shared_mode,
+ ACE_OS::default_win32_security_attributes (sa),
+ creation,
+ flags,
+ 0);
+
+ if (ACE_BIT_ENABLED (mode, _O_APPEND))
+ {
+ if (h != ACE_INVALID_HANDLE)
+ {
+ ::SetFilePointer (h, 0, 0, FILE_END);
+ }
+
+ ACE_MT (ACE_OS::thread_mutex_unlock (ace_os_monitor_lock);)
+ }
+
+ if (h == ACE_INVALID_HANDLE)
+ ACE_FAIL_RETURN (h);
+ else
+ return h;
+#else /* ACE_WIN32 */
+ // Just emulate with ascii version
+ return ACE_OS::open (ACE_Wide_To_Ascii (filename).char_rep (),
+ mode,
+ perms,
+ sa);
+#endif /* ACE_WIN32 */
+}
+#endif /* ACE_HAS_WCHAR */
+
+# if defined (ACE_LACKS_DIFFTIME)
+double
+ACE_OS::difftime (time_t t1, time_t t0)
+{
+ /* return t1 - t0 in seconds */
+ struct tm tms[2], *ptms[2], temp;
+ double seconds;
+ double days;
+ int swap = 0;
+
+ /* extract the tm structure from time_t */
+ ptms[1] = gmtime_r (&t1, &tms[1]);
+ if (ptms[1] == 0) return 0.0;
+
+ ptms[0] = gmtime_r (&t0, &tms[0]);
+ if (ptms[0] == 0) return 0.0;
+
+ /* make sure t1 is > t0 */
+ if (tms[1].tm_year < tms[0].tm_year)
+ swap = 1;
+ else if (tms[1].tm_year == tms[0].tm_year)
+ {
+ if (tms[1].tm_yday < tms[0].tm_yday)
+ swap = 1;
+ else if (tms[1].tm_yday == tms[0].tm_yday)
+ {
+ if (tms[1].tm_hour < tms[0].tm_hour)
+ swap = 1;
+ else if (tms[1].tm_hour == tms[0].tm_hour)
+ {
+ if (tms[1].tm_min < tms[0].tm_min)
+ swap = 1;
+ else if (tms[1].tm_min == tms[0].tm_min)
+ {
+ if (tms[1].tm_sec < tms[0].tm_sec)
+ swap = 1;
+ }
+ }
+ }
+ }
+
+ if (swap)
+ temp = tms[0], tms[0] = tms[1], tms[1] = temp;
+
+ seconds = 0.0;
+ if (tms[1].tm_year > tms[0].tm_year)
+ {
+ // Accumulate the time until t[0] catches up to t[1]'s year.
+ seconds = 60 - tms[0].tm_sec;
+ tms[0].tm_sec = 0;
+ tms[0].tm_min += 1;
+ seconds += 60 * (60 - tms[0].tm_min);
+ tms[0].tm_min = 0;
+ tms[0].tm_hour += 1;
+ seconds += 60*60 * (24 - tms[0].tm_hour);
+ tms[0].tm_hour = 0;
+ tms[0].tm_yday += 1;
+
+# define ISLEAPYEAR(y) ((y)&3u?0:(y)%25u?1:(y)/25u&12?0:1)
+
+ if (ISLEAPYEAR(tms[0].tm_year))
+ seconds += 60*60*24 * (366 - tms[0].tm_yday);
+ else
+ seconds += 60*60*24 * (365 - tms[0].tm_yday);
+
+ tms[0].tm_yday = 0;
+ tms[0].tm_year += 1;
+
+ while (tms[1].tm_year > tms[0].tm_year)
+ {
+ if (ISLEAPYEAR(tms[0].tm_year))
+ seconds += 60*60*24 * 366;
+ else
+ seconds += 60*60*24 * 365;
+
+ tms[0].tm_year += 1;
+ }
+
+# undef ISLEAPYEAR
+
+ }
+ else
+ {
+ // Normalize
+ if (tms[1].tm_sec < tms[0].tm_sec)
+ {
+ if (tms[1].tm_min == 0)
+ {
+ if (tms[1].tm_hour == 0)
+ {
+ tms[1].tm_yday -= 1;
+ tms[1].tm_hour += 24;
+ }
+ tms[1].tm_hour -= 1;
+ tms[1].tm_min += 60;
+ }
+ tms[1].tm_min -= 1;
+ tms[1].tm_sec += 60;
+ }
+ tms[1].tm_sec -= tms[0].tm_sec;
+
+ if (tms[1].tm_min < tms[0].tm_min)
+ {
+ if (tms[1].tm_hour == 0)
+ {
+ tms[1].tm_yday -= 1;
+ tms[1].tm_hour += 24;
+ }
+ tms[1].tm_hour -= 1;
+ tms[1].tm_min += 60;
+ }
+ tms[1].tm_min -= tms[0].tm_min;
+
+ if (tms[1].tm_hour < tms[0].tm_hour)
+ {
+ tms[1].tm_yday -= 1;
+ tms[1].tm_hour += 24;
+ }
+ tms[1].tm_hour -= tms[0].tm_hour;
+
+ tms[1].tm_yday -= tms[0].tm_yday;
+ }
+
+ // accumulate the seconds
+ seconds += tms[1].tm_sec;
+ seconds += 60 * tms[1].tm_min;
+ seconds += 60*60 * tms[1].tm_hour;
+ seconds += 60*60*24 * tms[1].tm_yday;
+
+ return seconds;
+}
+# endif /* ACE_LACKS_DIFFTIME */
+
+# if defined (ACE_HAS_WINCE)
+ACE_TCHAR *
+ACE_OS::ctime_r (const time_t *clock, ACE_TCHAR *buf, int buflen)
+{
+ // buflen must be at least 26 wchar_t long.
+ if (buflen < 26) // Again, 26 is a magic number.
+ return 0;
+ // This is really stupid, converting FILETIME to timeval back and
+ // forth. It assumes FILETIME and DWORDLONG are the same structure
+ // internally.
+ ULARGE_INTEGER _100ns;
+ _100ns.QuadPart = (DWORDLONG) *clock * 10000 * 1000
+ + ACE_Time_Value::FILETIME_to_timval_skew;
+ FILETIME file_time;
+ file_time.dwLowDateTime = _100ns.LowPart;
+ file_time.dwHighDateTime = _100ns.HighPart;
+
+ FILETIME localtime;
+ SYSTEMTIME systime;
+ FileTimeToLocalFileTime (&file_time, &localtime);
+ FileTimeToSystemTime (&localtime, &systime);
+ ACE_OS::sprintf (buf, ACE_OS_CTIME_R_FMTSTR,
+ ACE_OS::day_of_week_name[systime.wDayOfWeek],
+ ACE_OS::month_name[systime.wMonth - 1],
+ systime.wDay,
+ systime.wHour,
+ systime.wMinute,
+ systime.wSecond,
+ systime.wYear);
+ return buf;
+}
+# endif /* ACE_HAS_WINCE */
+
+# if !defined (ACE_HAS_WINCE)
+time_t
+ACE_OS::mktime (struct tm *t)
+{
+ ACE_OS_TRACE ("ACE_OS::mktime");
+# if defined (ACE_PSOS) && ! defined (ACE_PSOS_HAS_TIME)
+ ACE_UNUSED_ARG (t);
+ ACE_NOTSUP_RETURN (-1);
+# else
+# if defined (ACE_HAS_THREADS) && !defined (ACE_HAS_MT_SAFE_MKTIME)
+ ACE_OS_GUARD
+# endif /* ACE_HAS_THREADS && ! ACE_HAS_MT_SAFE_MKTIME */
+
+ ACE_OSCALL_RETURN (::mktime (t), time_t, (time_t) -1);
+# endif /* ACE_PSOS && ! ACE_PSOS_HAS_TIME */
+}
+# endif /* !ACE_HAS_WINCE */
+
+# if !defined (ACE_HAS_THREADS) || defined (ACE_LACKS_RWLOCK_T)
+int
+ACE_OS::rwlock_init (ACE_rwlock_t *rw,
+ int type,
+ const ACE_TCHAR *name,
+ void *arg)
+{
+ // ACE_OS_TRACE ("ACE_OS::rwlock_init");
+# if defined (ACE_HAS_THREADS) && defined (ACE_LACKS_RWLOCK_T)
+ // NT, POSIX, and VxWorks don't support this natively.
+ ACE_UNUSED_ARG (name);
+ int result = -1;
+
+ // Since we cannot use the user specified name for all three
+ // objects, we will create three completely new names.
+ ACE_TCHAR name1[ACE_UNIQUE_NAME_LEN];
+ ACE_TCHAR name2[ACE_UNIQUE_NAME_LEN];
+ ACE_TCHAR name3[ACE_UNIQUE_NAME_LEN];
+ ACE_TCHAR name4[ACE_UNIQUE_NAME_LEN];
+
+ ACE_OS::unique_name ((const void *) &rw->lock_,
+ name1,
+ ACE_UNIQUE_NAME_LEN);
+ ACE_OS::unique_name ((const void *) &rw->waiting_readers_,
+ name2,
+ ACE_UNIQUE_NAME_LEN);
+ ACE_OS::unique_name ((const void *) &rw->waiting_writers_,
+ name3,
+ ACE_UNIQUE_NAME_LEN);
+ ACE_OS::unique_name ((const void *) &rw->waiting_important_writer_,
+ name4,
+ ACE_UNIQUE_NAME_LEN);
+
+ ACE_condattr_t attributes;
+ if (ACE_OS::condattr_init (attributes, type) == 0)
+ {
+ if (ACE_OS::mutex_init (&rw->lock_, type, name1,
+ (ACE_mutexattr_t *) arg) == 0
+ && ACE_OS::cond_init (&rw->waiting_readers_,
+ attributes, name2, arg) == 0
+ && ACE_OS::cond_init (&rw->waiting_writers_,
+ attributes, name3, arg) == 0
+ && ACE_OS::cond_init (&rw->waiting_important_writer_,
+ attributes, name4, arg) == 0)
+ {
+ // Success!
+ rw->ref_count_ = 0;
+ rw->num_waiting_writers_ = 0;
+ rw->num_waiting_readers_ = 0;
+ rw->important_writer_ = 0;
+ result = 0;
+ }
+ ACE_OS::condattr_destroy (attributes);
+ }
+
+ if (result == -1)
+ {
+ // Save/restore errno.
+ ACE_Errno_Guard error (errno);
+ ACE_OS::mutex_destroy (&rw->lock_);
+ ACE_OS::cond_destroy (&rw->waiting_readers_);
+ ACE_OS::cond_destroy (&rw->waiting_writers_);
+ ACE_OS::cond_destroy (&rw->waiting_important_writer_);
+ }
+ return result;
+# else
+ ACE_UNUSED_ARG (rw);
+ ACE_UNUSED_ARG (type);
+ ACE_UNUSED_ARG (name);
+ ACE_UNUSED_ARG (arg);
+ ACE_NOTSUP_RETURN (-1);
+# endif /* ACE_HAS_THREADS */
+}
+# endif /* ! ACE_HAS_THREADS || ACE_LACKS_RWLOCK_T */
+
+// If we're using PACE then we don't want this method (since PACE
+// takes care of it) unless we're on Windows. Win32 mutexes, semaphores,
+// and condition variables are not yet supported in PACE.
+#if defined (ACE_LACKS_COND_T) && ! defined (ACE_PSOS_DIAB_MIPS) && ! (defined (ACE_HAS_PACE) && ! defined (ACE_WIN32))
+// NOTE: The ACE_OS::cond_* functions for some non-Unix platforms are
+// defined here either because they're too big to be inlined, or
+// to avoid use before definition if they were inline.
+
+int
+ACE_OS::cond_destroy (ACE_cond_t *cv)
+{
+ ACE_OS_TRACE ("ACE_OS::cond_destroy");
+# if defined (ACE_HAS_THREADS)
+# if defined (ACE_HAS_WTHREADS)
+ ACE_OS::event_destroy (&cv->waiters_done_);
+# elif defined (VXWORKS) || defined (ACE_PSOS)
+ ACE_OS::sema_destroy (&cv->waiters_done_);
+# endif /* VXWORKS */
+ ACE_OS::thread_mutex_destroy (&cv->waiters_lock_);
+ return ACE_OS::sema_destroy (&cv->sema_);
+# else
+ ACE_UNUSED_ARG (cv);
+ ACE_NOTSUP_RETURN (-1);
+# endif /* ACE_HAS_THREADS */
+}
+
+// @@ The following functions could be inlined if i could figure where
+// to put it among the #ifdefs!
+int
+ACE_OS::condattr_init (ACE_condattr_t &attributes,
+ int type)
+{
+ attributes.type = type;
+ return 0;
+}
+
+int
+ACE_OS::condattr_destroy (ACE_condattr_t &)
+{
+ return 0;
+}
+
+int
+ACE_OS::cond_init (ACE_cond_t *cv,
+ ACE_condattr_t &attributes,
+ const char *name, void *arg)
+{
+ return ACE_OS::cond_init (cv, attributes.type, name, arg);
+}
+
+#if defined (ACE_HAS_WCHAR)
+int
+ACE_OS::cond_init (ACE_cond_t *cv,
+ ACE_condattr_t &attributes,
+ const wchar_t *name, void *arg)
+{
+ return ACE_OS::cond_init (cv, attributes.type, name, arg);
+}
+#endif /* ACE_HAS_WCHAR */
+
+int
+ACE_OS::cond_init (ACE_cond_t *cv, short type, const char *name, void *arg)
+{
+ ACE_OS_TRACE ("ACE_OS::cond_init");
+# if defined (ACE_HAS_THREADS)
+ cv->waiters_ = 0;
+ cv->was_broadcast_ = 0;
+
+ int result = 0;
+ if (ACE_OS::sema_init (&cv->sema_, 0, type, name, arg) == -1)
+ result = -1;
+ else if (ACE_OS::thread_mutex_init (&cv->waiters_lock_) == -1)
+ result = -1;
+# if defined (VXWORKS) || defined (ACE_PSOS)
+ else if (ACE_OS::sema_init (&cv->waiters_done_, 0, type) == -1)
+# else
+ else if (ACE_OS::event_init (&cv->waiters_done_) == -1)
+# endif /* VXWORKS */
+ result = -1;
+ return result;
+# else
+ ACE_UNUSED_ARG (cv);
+ ACE_UNUSED_ARG (type);
+ ACE_UNUSED_ARG (name);
+ ACE_UNUSED_ARG (arg);
+ ACE_NOTSUP_RETURN (-1);
+# endif /* ACE_HAS_THREADS */
+}
+
+#if defined (ACE_HAS_WCHAR)
+int
+ACE_OS::cond_init (ACE_cond_t *cv, short type, const wchar_t *name, void *arg)
+{
+ ACE_OS_TRACE ("ACE_OS::cond_init");
+# if defined (ACE_HAS_THREADS)
+ cv->waiters_ = 0;
+ cv->was_broadcast_ = 0;
+
+ int result = 0;
+ if (ACE_OS::sema_init (&cv->sema_, 0, type, name, arg) == -1)
+ result = -1;
+ else if (ACE_OS::thread_mutex_init (&cv->waiters_lock_) == -1)
+ result = -1;
+# if defined (VXWORKS) || defined (ACE_PSOS)
+ else if (ACE_OS::sema_init (&cv->waiters_done_, 0, type) == -1)
+# else
+ else if (ACE_OS::event_init (&cv->waiters_done_) == -1)
+# endif /* VXWORKS */
+ result = -1;
+ return result;
+# else
+ ACE_UNUSED_ARG (cv);
+ ACE_UNUSED_ARG (type);
+ ACE_UNUSED_ARG (name);
+ ACE_UNUSED_ARG (arg);
+ ACE_NOTSUP_RETURN (-1);
+# endif /* ACE_HAS_THREADS */
+}
+#endif /* ACE_HAS_WCHAR */
+
+int
+ACE_OS::cond_signal (ACE_cond_t *cv)
+{
+ ACE_OS_TRACE ("ACE_OS::cond_signal");
+# if defined (ACE_HAS_THREADS)
+ // If there aren't any waiters, then this is a no-op. Note that
+ // this function *must* be called with the <external_mutex> held
+ // since other wise there is a race condition that can lead to the
+ // lost wakeup bug... This is needed to ensure that the <waiters_>
+ // value is not in an inconsistent internal state while being
+ // updated by another thread.
+ ACE_OS::thread_mutex_lock (&cv->waiters_lock_);
+ int have_waiters = cv->waiters_ > 0;
+ ACE_OS::thread_mutex_unlock (&cv->waiters_lock_);
+
+ if (have_waiters != 0)
+ return ACE_OS::sema_post (&cv->sema_);
+ else
+ return 0; // No-op
+# else
+ ACE_UNUSED_ARG (cv);
+ ACE_NOTSUP_RETURN (-1);
+# endif /* ACE_HAS_THREADS */
+}
+
+int
+ACE_OS::cond_broadcast (ACE_cond_t *cv)
+{
+ ACE_OS_TRACE ("ACE_OS::cond_broadcast");
+# if defined (ACE_HAS_THREADS)
+ // The <external_mutex> must be locked before this call is made.
+
+ // This is needed to ensure that <waiters_> and <was_broadcast_> are
+ // consistent relative to each other.
+ ACE_OS::thread_mutex_lock (&cv->waiters_lock_);
+ int have_waiters = 0;
+
+ if (cv->waiters_ > 0)
+ {
+ // We are broadcasting, even if there is just one waiter...
+ // Record the fact that we are broadcasting. This helps the
+ // cond_wait() method know how to optimize itself. Be sure to
+ // set this with the <waiters_lock_> held.
+ cv->was_broadcast_ = 1;
+ have_waiters = 1;
+ }
+ ACE_OS::thread_mutex_unlock (&cv->waiters_lock_);
+ int result = 0;
+ if (have_waiters)
+ {
+ // Wake up all the waiters.
+ if (ACE_OS::sema_post (&cv->sema_, cv->waiters_) == -1)
+ result = -1;
+ // Wait for all the awakened threads to acquire their part of
+ // the counting semaphore.
+# if defined (VXWORKS) || defined (ACE_PSOS)
+ else if (ACE_OS::sema_wait (&cv->waiters_done_) == -1)
+# else
+ else if (ACE_OS::event_wait (&cv->waiters_done_) == -1)
+# endif /* VXWORKS */
+ result = -1;
+ // This is okay, even without the <waiters_lock_> held because
+ // no other waiter threads can wake up to access it.
+ cv->was_broadcast_ = 0;
+ }
+ return result;
+# else
+ ACE_UNUSED_ARG (cv);
+ ACE_NOTSUP_RETURN (-1);
+# endif /* ACE_HAS_THREADS */
+}
+
+int
+ACE_OS::cond_wait (ACE_cond_t *cv,
+ ACE_mutex_t *external_mutex)
+{
+ ACE_OS_TRACE ("ACE_OS::cond_wait");
+# if defined (ACE_HAS_PACE) && !defined (ACE_WIN32)
+ return (::pace_pthread_cond_wait(cv, external_mutex);
+# elif defined (ACE_HAS_THREADS)
+ // Prevent race conditions on the <waiters_> count.
+ ACE_OS::thread_mutex_lock (&cv->waiters_lock_);
+ cv->waiters_++;
+ ACE_OS::thread_mutex_unlock (&cv->waiters_lock_);
+
+ int result = 0;
+
+# if defined (ACE_HAS_SIGNAL_OBJECT_AND_WAIT)
+ if (external_mutex->type_ == USYNC_PROCESS)
+ // This call will automatically release the mutex and wait on the semaphore.
+# if defined (ACE_HAS_PACE) && !defined (ACE_WIN32)
+ ACE_WIN32CALL (ACE_ADAPT_RETVAL (::SignalObjectAndWait (external_mutex->proc_mutex_,
+ cv->sema_.sema_, INFINITE, FALSE),
+ result),
+ int, -1, result);
+# else
+ ACE_WIN32CALL (ACE_ADAPT_RETVAL (::SignalObjectAndWait (external_mutex->proc_mutex_,
+ cv->sema_, INFINITE, FALSE),
+ result),
+ int, -1, result);
+# endif /* ACE_HAS_PACE && !ACE_WIN32 */
+ else
+# endif /* ACE_HAS_SIGNAL_OBJECT_AND_WAIT */
+ {
+ // 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::mutex_unlock (external_mutex) != 0)
+ return -1;
+
+ // Wait to be awakened by a ACE_OS::cond_signal() or
+ // ACE_OS::cond_broadcast().
+ result = ACE_OS::sema_wait (&cv->sema_);
+ }
+
+ // Reacquire lock to avoid race conditions on the <waiters_> count.
+ ACE_OS::thread_mutex_lock (&cv->waiters_lock_);
+
+ // We're ready to return, so there's one less waiter.
+ cv->waiters_--;
+
+ int last_waiter = cv->was_broadcast_ && cv->waiters_ == 0;
+
+ // Release the lock so that other collaborating threads can make
+ // progress.
+ ACE_OS::thread_mutex_unlock (&cv->waiters_lock_);
+
+ if (result == -1)
+ // Bad things happened, so let's just return below.
+ /* NOOP */;
+# if defined (ACE_HAS_SIGNAL_OBJECT_AND_WAIT)
+ else if (external_mutex->type_ == USYNC_PROCESS)
+ {
+ if (last_waiter)
+
+ // This call atomically signals the <waiters_done_> event and
+ // waits until it can acquire the mutex. This is important to
+ // prevent unfairness.
+ ACE_WIN32CALL (ACE_ADAPT_RETVAL (::SignalObjectAndWait (cv->waiters_done_,
+ external_mutex->proc_mutex_,
+ INFINITE, FALSE),
+ result),
+ int, -1, result);
+ else
+ // We must always regain the <external_mutex>, even when
+ // errors occur because that's the guarantee that we give to
+ // our callers.
+ ACE_OS::mutex_lock (external_mutex);
+
+ return result;
+ /* NOTREACHED */
+ }
+# endif /* ACE_HAS_SIGNAL_OBJECT_AND_WAIT */
+ // If we're the last waiter thread during this particular broadcast
+ // then let all the other threads proceed.
+ else if (last_waiter)
+# if defined (VXWORKS) || defined (ACE_PSOS)
+ ACE_OS::sema_post (&cv->waiters_done_);
+# else
+ ACE_OS::event_signal (&cv->waiters_done_);
+# endif /* VXWORKS */
+
+ // We must always regain the <external_mutex>, even when errors
+ // occur because that's the guarantee that we give to our callers.
+ ACE_OS::mutex_lock (external_mutex);
+
+ return result;
+# else
+ ACE_UNUSED_ARG (cv);
+ ACE_UNUSED_ARG (external_mutex);
+ ACE_NOTSUP_RETURN (-1);
+# endif /* ACE_HAS_THREADS */
+}
+
+int
+ACE_OS::cond_timedwait (ACE_cond_t *cv,
+ ACE_mutex_t *external_mutex,
+ ACE_Time_Value *timeout)
+{
+ ACE_OS_TRACE ("ACE_OS::cond_timedwait");
+# if defined (ACE_HAS_PACE) && !defined (ACE_WIN32)
+ return (::pace_pthread_cond_timedwait(cv, external_mutex, timeout);
+# elif defined (ACE_HAS_THREADS)
+ // Handle the easy case first.
+ if (timeout == 0)
+ return ACE_OS::cond_wait (cv, external_mutex);
+# if defined (ACE_HAS_WTHREADS) || defined (VXWORKS) || defined (ACE_PSOS)
+
+ // Prevent race conditions on the <waiters_> count.
+ ACE_OS::thread_mutex_lock (&cv->waiters_lock_);
+ cv->waiters_++;
+ ACE_OS::thread_mutex_unlock (&cv->waiters_lock_);
+
+ int result = 0;
+ ACE_Errno_Guard error (errno, 0);
+ int msec_timeout;
+
+ if (timeout->sec () == 0 && timeout->usec () == 0)
+ msec_timeout = 0; // Do a "poll."
+ else
+ {
+ // 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 ());
+
+ // Watchout for situations where a context switch has caused the
+ // current time to be > the timeout.
+ if (relative_time < ACE_Time_Value::zero)
+ msec_timeout = 0;
+ else
+ msec_timeout = relative_time.msec ();
+ }
+
+# if defined (ACE_HAS_SIGNAL_OBJECT_AND_WAIT)
+ if (external_mutex->type_ == USYNC_PROCESS)
+ // This call will automatically release the mutex and wait on the
+ // semaphore.
+# if defined (ACE_HAS_PACE) && !defined (ACE_WIN32)
+ result = ::SignalObjectAndWait (external_mutex->proc_mutex_,
+ cv->sema_.sema_,
+ msec_timeout,
+ FALSE);
+# else
+ result = ::SignalObjectAndWait (external_mutex->proc_mutex_,
+ cv->sema_,
+ msec_timeout,
+ FALSE);
+# endif /* ACE_HAS_PACE && !ACE_WIN32 */
+ else
+# endif /* ACE_HAS_SIGNAL_OBJECT_AND_WAIT */
+ {
+ // 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::mutex_unlock (external_mutex) != 0)
+ return -1;
+
+ // Wait to be awakened by a ACE_OS::signal() or
+ // ACE_OS::broadcast().
+# if defined (ACE_WIN32)
+# if !defined (ACE_USES_WINCE_SEMA_SIMULATION)
+ result = ::WaitForSingleObject (cv->sema_, msec_timeout);
+# else /* ACE_USES_WINCE_SEMA_SIMULATION */
+ // Can't use Win32 API on our simulated semaphores.
+ result = ACE_OS::sema_wait (&cv->sema_,
+ ACE_Time_Value (0, msec_timeout * 1000));
+# endif /* ACE_USES_WINCE_SEMA_SIMULATION */
+# elif defined (ACE_PSOS)
+ // Inline the call to ACE_OS::sema_wait () because it takes an
+ // ACE_Time_Value argument. Avoid the cost of that conversion . . .
+ u_long ticks = (KC_TICKS2SEC * msec_timeout) / ACE_ONE_SECOND_IN_MSECS;
+ //Tick set to 0 tells pSOS to wait forever is SM_WAIT is set.
+ if(ticks == 0)
+ result = ::sm_p (cv->sema_.sema_, SM_NOWAIT, ticks); //no timeout
+ else
+ result = ::sm_p (cv->sema_.sema_, SM_WAIT, ticks);
+# elif defined (VXWORKS)
+ // Inline the call to ACE_OS::sema_wait () because it takes an
+ // ACE_Time_Value argument. Avoid the cost of that conversion . . .
+ int ticks_per_sec = ::sysClkRateGet ();
+ int ticks = msec_timeout * ticks_per_sec / ACE_ONE_SECOND_IN_MSECS;
+ result = ::semTake (cv->sema_.sema_, ticks);
+# endif /* ACE_WIN32 || VXWORKS */
+ }
+
+ // Reacquire lock to avoid race conditions.
+ ACE_OS::thread_mutex_lock (&cv->waiters_lock_);
+ cv->waiters_--;
+
+ int last_waiter = cv->was_broadcast_ && cv->waiters_ == 0;
+
+ ACE_OS::thread_mutex_unlock (&cv->waiters_lock_);
+
+# if defined (ACE_WIN32)
+ if (result != WAIT_OBJECT_0)
+ {
+ switch (result)
+ {
+ case WAIT_TIMEOUT:
+ error = ETIME;
+ break;
+ default:
+ error = ::GetLastError ();
+ break;
+ }
+ result = -1;
+ }
+# elif defined (ACE_PSOS)
+ if (result != 0)
+ {
+ switch (result)
+ {
+ case ERR_TIMEOUT: // Timeout occured with SM_WAIT
+ case ERR_NOMSG: // Didn't acquire semaphore w/ SM_NOWAIT (ticks=0)
+ error = ETIME;
+ break;
+ default:
+ error = errno;
+ break;
+ }
+ result = -1;
+ }
+# elif defined (VXWORKS)
+ if (result == ERROR)
+ {
+ switch (errno)
+ {
+ case S_objLib_OBJ_TIMEOUT:
+ error = ETIME;
+ break;
+ case S_objLib_OBJ_UNAVAILABLE:
+ if (msec_timeout == 0)
+ error = ETIME;
+ break;
+ default:
+ error = errno;
+ break;
+ }
+ result = -1;
+ }
+# endif /* ACE_WIN32 || VXWORKS */
+# if defined (ACE_HAS_SIGNAL_OBJECT_AND_WAIT)
+ if (external_mutex->type_ == USYNC_PROCESS)
+ {
+ if (last_waiter)
+ // This call atomically signals the <waiters_done_> event and
+ // waits until it can acquire the mutex. This is important to
+ // prevent unfairness.
+ ACE_WIN32CALL (ACE_ADAPT_RETVAL (::SignalObjectAndWait (cv->waiters_done_,
+ external_mutex->proc_mutex_,
+ INFINITE, FALSE),
+ result),
+ int, -1, result);
+ else
+ // We must always regain the <external_Mutex>, even when
+ // errors occur because that's the guarantee that we give to
+ // our callers.
+ ACE_OS::mutex_lock (external_mutex);
+
+ return result;
+ /* NOTREACHED */
+ }
+# endif /* ACE_HAS_SIGNAL_OBJECT_AND_WAIT */
+ // Note that this *must* be an "if" statement rather than an "else
+ // if" statement since the caller may have timed out and hence the
+ // result would have been -1 above.
+ if (last_waiter)
+ // Release the signaler/broadcaster if we're the last waiter.
+# if defined (ACE_WIN32)
+ ACE_OS::event_signal (&cv->waiters_done_);
+# else
+ ACE_OS::sema_post (&cv->waiters_done_);
+# endif /* ACE_WIN32 */
+
+ // We must always regain the <external_mutex>, even when errors
+ // occur because that's the guarantee that we give to our callers.
+ ACE_OS::mutex_lock (external_mutex);
+
+ return result;
+# endif /* ACE_HAS_WTHREADS || ACE_HAS_VXWORKS || ACE_PSOS */
+# else
+ ACE_UNUSED_ARG (cv);
+ ACE_UNUSED_ARG (external_mutex);
+ ACE_UNUSED_ARG (timeout);
+ ACE_NOTSUP_RETURN (-1);
+# endif /* ACE_HAS_THREADS */
+}
+
+# if defined (ACE_HAS_WTHREADS)
+int
+ACE_OS::cond_timedwait (ACE_cond_t *cv,
+ ACE_thread_mutex_t *external_mutex,
+ ACE_Time_Value *timeout)
+{
+ ACE_OS_TRACE ("ACE_OS::cond_timedwait");
+# if defined (ACE_HAS_THREADS)
+ // Handle the easy case first.
+ if (timeout == 0)
+ return ACE_OS::cond_wait (cv, external_mutex);
+
+ // Prevent race conditions on the <waiters_> count.
+ ACE_OS::thread_mutex_lock (&cv->waiters_lock_);
+ cv->waiters_++;
+ ACE_OS::thread_mutex_unlock (&cv->waiters_lock_);
+
+ int result = 0;
+ int error = 0;
+ int msec_timeout;
+
+ if (timeout->sec () == 0 && timeout->usec () == 0)
+ msec_timeout = 0; // Do a "poll."
+ else
+ {
+ // 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 ());
+
+ // Watchout for situations where a context switch has caused the
+ // current time to be > the timeout.
+ if (relative_time < ACE_Time_Value::zero)
+ msec_timeout = 0;
+ else
+ msec_timeout = relative_time.msec ();
+ }
+
+ // 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;
+
+ // Wait to be awakened by a ACE_OS::signal() or ACE_OS::broadcast().
+# if defined (ACE_USES_WINCE_SEMA_SIMULATION)
+ // Can't use Win32 API on simulated semaphores.
+ result = ACE_OS::sema_wait (&cv->sema_,
+ ACE_Time_Value (0, msec_timeout * 1000));
+
+ if (result == -1 && errno == ETIME)
+ result = WAIT_TIMEOUT;
+# else
+ result = ::WaitForSingleObject (cv->sema_, msec_timeout);
+# endif /* ACE_USES_WINCE_SEMA_SIMULATION */
+
+ // Reacquire lock to avoid race conditions.
+ ACE_OS::thread_mutex_lock (&cv->waiters_lock_);
+
+ cv->waiters_--;
+
+ int last_waiter = cv->was_broadcast_ && cv->waiters_ == 0;
+
+ ACE_OS::thread_mutex_unlock (&cv->waiters_lock_);
+
+ if (result != WAIT_OBJECT_0)
+ {
+ switch (result)
+ {
+ case WAIT_TIMEOUT:
+ error = ETIME;
+ break;
+ default:
+ error = ::GetLastError ();
+ break;
+ }
+ result = -1;
+ }
+
+ if (last_waiter)
+ // Release the signaler/broadcaster if we're the last waiter.
+ ACE_OS::event_signal (&cv->waiters_done_);
+
+ // 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;
+# else
+ ACE_NOTSUP_RETURN (-1);
+# endif /* ACE_HAS_THREADS */
+}
+
+int
+ACE_OS::cond_wait (ACE_cond_t *cv,
+ ACE_thread_mutex_t *external_mutex)
+{
+ ACE_OS_TRACE ("ACE_OS::cond_wait");
+# if defined (ACE_HAS_THREADS)
+ ACE_OS::thread_mutex_lock (&cv->waiters_lock_);
+ cv->waiters_++;
+ ACE_OS::thread_mutex_unlock (&cv->waiters_lock_);
+
+ 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;
+
+ // Wait to be awakened by a ACE_OS::cond_signal() or
+ // ACE_OS::cond_broadcast().
+# if !defined (ACE_USES_WINCE_SEMA_SIMULATION)
+ result = ::WaitForSingleObject (cv->sema_, INFINITE);
+# else
+ // Can't use Win32 API on simulated semaphores.
+ result = ACE_OS::sema_wait (&cv->sema_);
+
+ if (result != WAIT_OBJECT_0 && errno == ETIME)
+ result = WAIT_TIMEOUT;
+
+# endif /* ACE_USES_WINCE_SEMA_SIMULATION */
+
+ // Reacquire lock to avoid race conditions.
+ ACE_OS::thread_mutex_lock (&cv->waiters_lock_);
+
+ cv->waiters_--;
+
+ int last_waiter = cv->was_broadcast_ && cv->waiters_ == 0;
+
+ ACE_OS::thread_mutex_unlock (&cv->waiters_lock_);
+
+ if (result != WAIT_OBJECT_0)
+ {
+ switch (result)
+ {
+ case WAIT_TIMEOUT:
+ error = ETIME;
+ break;
+ default:
+ error = ::GetLastError ();
+ break;
+ }
+ }
+ else if (last_waiter)
+ // Release the signaler/broadcaster if we're the last waiter.
+ ACE_OS::event_signal (&cv->waiters_done_);
+
+ // 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);
+
+ // Reset errno in case mutex_lock() also fails...
+ errno = error;
+ return result;
+# else
+ ACE_NOTSUP_RETURN (-1);
+# endif /* ACE_HAS_THREADS */
+}
+# endif /* ACE_HAS_WTHREADS */
+#endif /* ACE_LACKS_COND_T */
+
+void
+ACE_OS::exit (int status)
+{
+ ACE_OS_TRACE ("ACE_OS::exit");
+
+#if defined (ACE_HAS_NONSTATIC_OBJECT_MANAGER) && !defined (ACE_HAS_WINCE) && !defined (ACE_DOESNT_INSTANTIATE_NONSTATIC_OBJECT_MANAGER)
+ // Shut down the ACE_Object_Manager, if it had registered its exit_hook.
+ // With ACE_HAS_NONSTATIC_OBJECT_MANAGER, the ACE_Object_Manager is
+ // instantiated on the main's stack. ::exit () doesn't destroy it.
+ if (exit_hook_)
+ (*exit_hook_) ();
+#endif /* ACE_HAS_NONSTATIC_OBJECT_MANAGER && !ACE_HAS_WINCE && !ACE_DOESNT_INSTANTIATE_NONSTATIC_OBJECT_MANAGER */
+
+#if !defined (ACE_HAS_WINCE)
+# if defined (ACE_WIN32)
+ ::ExitProcess ((UINT) status);
+# elif defined (ACE_PSOSIM)
+ ::u_exit (status);
+# else
+ ::exit (status);
+# endif /* ACE_WIN32 */
+#else
+ // @@ This is not exactly the same as ExitProcess. But this is the
+ // closest one I can get.
+ ::TerminateProcess (::GetCurrentProcess (), status);
+#endif /* ACE_HAS_WINCE */
+}
+
+# if defined (ACE_PSOS)
+
+// bit masks and shifts for prying info out of the pSOS time encoding
+const u_long ACE_PSOS_Time_t::year_mask = 0x0000FFFFul;
+const u_long ACE_PSOS_Time_t::month_mask = 0x000000FFul;
+const u_long ACE_PSOS_Time_t::day_mask = 0x000000FFul;
+const u_long ACE_PSOS_Time_t::hour_mask = 0x0000FFFFul;
+const u_long ACE_PSOS_Time_t::minute_mask = 0x000000FFul;
+const u_long ACE_PSOS_Time_t::second_mask = 0x000000FFul;
+const int ACE_PSOS_Time_t::year_shift = 16;
+const int ACE_PSOS_Time_t::month_shift = 8;
+const int ACE_PSOS_Time_t::hour_shift = 16;
+const int ACE_PSOS_Time_t::minute_shift = 8;
+const int ACE_PSOS_Time_t::year_origin = 1900;
+const int ACE_PSOS_Time_t::month_origin = 1;
+
+// maximum number of clock ticks supported
+const u_long ACE_PSOS_Time_t::max_ticks = ~0UL;
+
+ACE_PSOS_Time_t::ACE_PSOS_Time_t (void)
+ : date_ (0),
+ time_ (0),
+ ticks_ (0)
+{
+}
+
+// default ctor: date, time, and ticks all zeroed
+
+ACE_PSOS_Time_t::ACE_PSOS_Time_t (const timespec_t& t)
+{
+ struct tm* tm_struct = ACE_OS::gmtime (&(t.tv_sec));
+
+ // Encode date values from tm struct into pSOS date bit array.
+ date_ = (ACE_PSOS_Time_t::year_mask &
+ ACE_static_cast (u_long,
+ tm_struct->tm_year + ACE_PSOS_Time_t::year_origin)) <<
+ ACE_PSOS_Time_t::year_shift;
+ date_ |= (ACE_PSOS_Time_t::month_mask &
+ ACE_static_cast (u_long,
+ tm_struct->tm_mon + ACE_PSOS_Time_t::month_origin)) <<
+ ACE_PSOS_Time_t::month_shift;
+ date_ |= ACE_PSOS_Time_t::day_mask &
+ ACE_static_cast (u_long, tm_struct->tm_mday);
+ // Encode time values from tm struct into pSOS time bit array.
+ time_ = (ACE_PSOS_Time_t::hour_mask &
+ ACE_static_cast (u_long, tm_struct->tm_hour)) <<
+ ACE_PSOS_Time_t::hour_shift;
+ time_ |= (ACE_PSOS_Time_t::minute_mask &
+ ACE_static_cast (u_long, tm_struct->tm_min)) <<
+ ACE_PSOS_Time_t::minute_shift;
+ time_ |= ACE_PSOS_Time_t::second_mask &
+ ACE_static_cast (u_int, tm_struct->tm_sec);
+
+ // encode nanoseconds as system clock ticks
+ ticks_ = ACE_static_cast (u_long,
+ ((ACE_static_cast (double, t.tv_nsec) *
+ ACE_static_cast (double, KC_TICKS2SEC)) /
+ ACE_static_cast (double, 1000000000)));
+
+}
+
+// ctor from a timespec_t
+
+ACE_PSOS_Time_t::operator timespec_t (void)
+{
+ struct tm tm_struct;
+
+ // Decode date and time bit arrays and fill in fields of tm_struct.
+
+ tm_struct.tm_year =
+ ACE_static_cast (int, (ACE_PSOS_Time_t::year_mask &
+ (date_ >> ACE_PSOS_Time_t::year_shift))) -
+ ACE_PSOS_Time_t::year_origin;
+ tm_struct.tm_mon =
+ ACE_static_cast (int, (ACE_PSOS_Time_t::month_mask &
+ (date_ >> ACE_PSOS_Time_t::month_shift))) -
+ ACE_PSOS_Time_t::month_origin;
+ tm_struct.tm_mday =
+ ACE_static_cast (int, (ACE_PSOS_Time_t::day_mask & date_));
+ tm_struct.tm_hour =
+ ACE_static_cast (int, (ACE_PSOS_Time_t::hour_mask &
+ (time_ >> ACE_PSOS_Time_t::hour_shift)));
+ tm_struct.tm_min =
+ ACE_static_cast (int, (ACE_PSOS_Time_t::minute_mask &
+ (time_ >> ACE_PSOS_Time_t::minute_shift)));
+ tm_struct.tm_sec =
+ ACE_static_cast (int, (ACE_PSOS_Time_t::second_mask & time_));
+
+ // Indicate values we don't know as negative numbers.
+ tm_struct.tm_wday = -1;
+ tm_struct.tm_yday = -1;
+ tm_struct.tm_isdst = -1;
+
+ timespec_t t;
+
+ // Convert calendar time to time struct.
+ t.tv_sec = ACE_OS::mktime (&tm_struct);
+
+ // Encode nanoseconds as system clock ticks.
+ t.tv_nsec = ACE_static_cast (long,
+ ((ACE_static_cast (double, ticks_) *
+ ACE_static_cast (double, 1000000000)) /
+ ACE_static_cast (double, KC_TICKS2SEC)));
+ return t;
+}
+
+// type cast operator (to a timespec_t)
+
+u_long
+ACE_PSOS_Time_t::get_system_time (ACE_PSOS_Time_t& t)
+{
+ u_long ret_val = 0;
+
+# if defined (ACE_PSOSIM) // system time is broken in simulator.
+ timeval tv;
+ int result = 0;
+ ACE_OSCALL (::gettimeofday (&tv, 0), int, -1, result);
+ if (result == -1)
+ return 1;
+
+ ACE_Time_Value atv (tv);
+ timespec ts = atv;
+ ACE_PSOS_Time_t pt (ts);
+ t.date_ = pt.date_;
+ t.time_ = pt.time_;
+ t.ticks_ = pt.ticks_;
+# else
+ ret_val = tm_get (&(t.date_), &(t.time_), &(t.ticks_));
+# endif /* ACE_PSOSIM */
+ return ret_val;
+}
+
+// Static member function to get current system time.
+
+u_long
+ACE_PSOS_Time_t::set_system_time (const ACE_PSOS_Time_t& t)
+{
+ return tm_set (t.date_, t.time_, t.ticks_);
+}
+
+// Static member function to set current system time.
+
+# if defined (ACE_PSOSIM)
+
+u_long
+ACE_PSOS_Time_t::init_simulator_time (void)
+{
+ // This is a hack using a direct UNIX system call, because the
+ // appropriate ACE_OS method ultimately uses the pSOS tm_get
+ // function, which would fail because the simulator's system time is
+ // uninitialized (chicken and egg).
+ timeval t;
+ int result = 0;
+ ACE_OSCALL (::gettimeofday (&t, 0),
+ int,
+ -1,
+ result);
+
+ if (result == -1)
+ return 1;
+ else
+ {
+ ACE_Time_Value tv (t);
+ timespec ts = tv;
+ ACE_PSOS_Time_t pt (ts);
+ u_long ret_val =
+ ACE_PSOS_Time_t::set_system_time (pt);
+ return ret_val;
+
+ }
+}
+
+// Static member function to initialize system time, using UNIX calls.
+
+# endif /* ACE_PSOSIM */
+# endif /* ACE_PSOS && ! ACE_PSOS_DIAB_MIPS */
+
+# if defined (__DGUX) && defined (ACE_HAS_THREADS) && defined (_POSIX4A_DRAFT10_SOURCE)
+extern "C" int __d6_sigwait (sigset_t *set);
+
+extern "C" int __d10_sigwait (const sigset_t *set, int *sig)
+{
+ sigset_t unconst_set = *set;
+ int caught_sig = __d6_sigwait (&unconst_set);
+
+ if (caught == -1)
+ return -1;
+
+ *sig = caught_sig;
+ return 0;
+}
+# endif /* __DGUX && PTHREADS && _POSIX4A_DRAFT10_SOURCE */
+
+# define ACE_OS_PREALLOCATE_OBJECT(TYPE, ID)\
+ {\
+ TYPE *obj_p = 0;\
+ ACE_NEW_RETURN (obj_p, TYPE, -1);\
+ preallocated_object[ID] = (void *) obj_p;\
+ }
+# define ACE_OS_DELETE_PREALLOCATED_OBJECT(TYPE, ID)\
+ delete (TYPE *) preallocated_object[ID];\
+ preallocated_object[ID] = 0;
+
+ACE_Object_Manager_Base::ACE_Object_Manager_Base (void)
+ : object_manager_state_ (OBJ_MAN_UNINITIALIZED)
+ , dynamically_allocated_ (0)
+ , next_ (0)
+{
+}
+
+ACE_Object_Manager_Base::~ACE_Object_Manager_Base (void)
+{
+#if defined (ACE_HAS_NONSTATIC_OBJECT_MANAGER)
+ // Clear the flag so that fini () doesn't delete again.
+ dynamically_allocated_ = 0;
+#endif /* ACE_HAS_NONSTATIC_OBJECT_MANAGER */
+}
+
+int
+ACE_Object_Manager_Base::starting_up_i ()
+{
+ return object_manager_state_ < OBJ_MAN_INITIALIZED;
+}
+
+int
+ACE_Object_Manager_Base::shutting_down_i ()
+{
+ return object_manager_state_ > OBJ_MAN_INITIALIZED;
+}
+
+extern "C"
+void
+ACE_OS_Object_Manager_Internal_Exit_Hook (void)
+{
+ if (ACE_OS_Object_Manager::instance_)
+ ACE_OS_Object_Manager::instance ()->fini ();
+}
+
+ACE_OS_Object_Manager *ACE_OS_Object_Manager::instance_ = 0;
+
+void *ACE_OS_Object_Manager::preallocated_object[
+ ACE_OS_Object_Manager::ACE_OS_PREALLOCATED_OBJECTS] = { 0 };
+
+ACE_OS_Object_Manager::ACE_OS_Object_Manager (void)
+ // default_mask_ isn't initialized, because it's defined by <init>.
+ : thread_hook_ (0)
+ , exit_info_ ()
+#if defined (ACE_HAS_WIN32_STRUCTURAL_EXCEPTIONS)
+ , seh_except_selector_ (ACE_SEH_Default_Exception_Selector)
+ , seh_except_handler_ (ACE_SEH_Default_Exception_Handler)
+#endif /* ACE_HAS_WIN32_STRUCTURAL_EXCEPTIONS */
+{
+ // If instance_ was not 0, then another ACE_OS_Object_Manager has
+ // already been instantiated (it is likely to be one initialized by
+ // way of library/DLL loading). Let this one go through
+ // construction in case there really is a good reason for it (like,
+ // ACE is a static/archive library, and this one is the non-static
+ // instance (with ACE_HAS_NONSTATIC_OBJECT_MANAGER, or the user has
+ // a good reason for creating a separate one) but the original one
+ // will be the one retrieved from calls to
+ // ACE_Object_Manager::instance().
+
+ // Be sure that no further instances are created via instance ().
+ if (instance_ == 0)
+ instance_ = this;
+
+ init ();
+}
+
+ACE_OS_Object_Manager::~ACE_OS_Object_Manager (void)
+{
+ dynamically_allocated_ = 0; // Don't delete this again in fini()
+ fini ();
+}
+
+sigset_t *
+ACE_OS_Object_Manager::default_mask (void)
+{
+ return ACE_OS_Object_Manager::instance ()->default_mask_;
+}
+
+ACE_Thread_Hook *
+ACE_OS_Object_Manager::thread_hook (void)
+{
+ return ACE_OS_Object_Manager::instance ()->thread_hook_;
+}
+
+#if defined (ACE_HAS_WIN32_STRUCTURAL_EXCEPTIONS)
+ACE_SEH_EXCEPT_HANDLER
+ACE_OS_Object_Manager::seh_except_selector (void)
+{
+ return ACE_OS_Object_Manager::instance ()->seh_except_selector_;
+}
+
+ACE_SEH_EXCEPT_HANDLER
+ACE_OS_Object_Manager::seh_except_selector (ACE_SEH_EXCEPT_HANDLER n)
+{
+ ACE_OS_Object_Manager *instance =
+ ACE_OS_Object_Manager::instance ();
+
+ ACE_SEH_EXCEPT_HANDLER retv = instance->seh_except_selector_;
+ instance->seh_except_selector_ = n;
+ return retv;
+}
+
+ACE_SEH_EXCEPT_HANDLER
+ACE_OS_Object_Manager::seh_except_handler (void)
+{
+ return ACE_OS_Object_Manager::instance ()->seh_except_handler_;
+}
+
+ACE_SEH_EXCEPT_HANDLER
+ACE_OS_Object_Manager::seh_except_handler (ACE_SEH_EXCEPT_HANDLER n)
+{
+ ACE_OS_Object_Manager *instance =
+ ACE_OS_Object_Manager::instance ();
+
+ ACE_SEH_EXCEPT_HANDLER retv = instance->seh_except_handler_;
+ instance->seh_except_handler_ = n;
+ return retv;
+}
+#endif /* ACE_HAS_WIN32_STRUCTURAL_EXCEPTIONS */
+
+ACE_Thread_Hook *
+ACE_OS_Object_Manager::thread_hook (ACE_Thread_Hook *new_thread_hook)
+{
+ ACE_OS_Object_Manager *os_om = ACE_OS_Object_Manager::instance ();
+ ACE_Thread_Hook *old_hook = os_om->thread_hook_;
+ os_om->thread_hook_ = new_thread_hook;
+ return old_hook;
+}
+
+ACE_OS_Object_Manager *
+ACE_OS_Object_Manager::instance (void)
+{
+ // This function should be called during construction of static
+ // instances, or before any other threads have been created in the
+ // process. So, it's not thread safe.
+
+ if (instance_ == 0)
+ {
+ ACE_OS_Object_Manager *instance_pointer;
+
+ ACE_NEW_RETURN (instance_pointer,
+ ACE_OS_Object_Manager,
+ 0);
+ // I (coryan) removed it, using asserts in the OS layer
+ // brings down the Log msg stuff
+ // ACE_ASSERT (instance_pointer == instance_);
+
+ instance_pointer->dynamically_allocated_ = 1;
+
+ }
+
+ return instance_;
+}
+
+int
+ACE_OS_Object_Manager::init (void)
+{
+ if (starting_up_i ())
+ {
+ // First, indicate that this ACE_OS_Object_Manager instance is being
+ // initialized.
+ object_manager_state_ = OBJ_MAN_INITIALIZING;
+
+ if (this == instance_)
+ {
+# if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0)
+# if defined (ACE_HAS_WINCE_BROKEN_ERRNO)
+ ACE_CE_Errno::init ();
+# endif /* ACE_HAS_WINCE_BROKEN_ERRNO */
+ ACE_OS_PREALLOCATE_OBJECT (ACE_thread_mutex_t, ACE_OS_MONITOR_LOCK)
+ if (ACE_OS::thread_mutex_init
+ // This line must not be broken to avoid tickling a bug with SunC++'s preprocessor.
+ (ACE_reinterpret_cast (ACE_thread_mutex_t *, ACE_OS_Object_Manager::preallocated_object[ACE_OS_MONITOR_LOCK])) != 0)
+ ACE_OS_Object_Manager::print_error_message (
+ __LINE__, ACE_LIB_TEXT ("ACE_OS_MONITOR_LOCK"));
+ ACE_OS_PREALLOCATE_OBJECT (ACE_recursive_thread_mutex_t,
+ ACE_TSS_CLEANUP_LOCK)
+ if (ACE_OS::recursive_mutex_init
+ // This line must not be broken to avoid tickling a bug with SunC++'s preprocessor.
+ (ACE_reinterpret_cast (ACE_recursive_thread_mutex_t *, ACE_OS_Object_Manager::preallocated_object[ACE_TSS_CLEANUP_LOCK])) != 0)
+ ACE_OS_Object_Manager::print_error_message (
+ __LINE__, ACE_LIB_TEXT ("ACE_TSS_CLEANUP_LOCK"));
+ ACE_OS_PREALLOCATE_OBJECT (ACE_thread_mutex_t,
+ ACE_LOG_MSG_INSTANCE_LOCK)
+ if (ACE_OS::thread_mutex_init
+ // This line must not be broken to avoid tickling a bug with SunC++'s preprocessor.
+ (ACE_reinterpret_cast (ACE_thread_mutex_t *, ACE_OS_Object_Manager::preallocated_object[ACE_LOG_MSG_INSTANCE_LOCK])) != 0)
+ ACE_OS_Object_Manager::print_error_message (
+ __LINE__, ACE_LIB_TEXT ("ACE_LOG_MSG_INSTANCE_LOCK"));
+# if defined (ACE_HAS_TSS_EMULATION)
+ ACE_OS_PREALLOCATE_OBJECT (ACE_recursive_thread_mutex_t,
+ ACE_TSS_KEY_LOCK)
+ if (ACE_OS::recursive_mutex_init
+ // This line must not be broken to avoid tickling a bug with SunC++'s preprocessor.
+ (ACE_reinterpret_cast (ACE_recursive_thread_mutex_t *, ACE_OS_Object_Manager::preallocated_object[ACE_TSS_KEY_LOCK])) != 0)
+ ACE_OS_Object_Manager::print_error_message (
+ __LINE__, ACE_LIB_TEXT ("ACE_TSS_KEY_LOCK"));
+# if defined (ACE_HAS_THREAD_SPECIFIC_STORAGE)
+ ACE_OS_PREALLOCATE_OBJECT (ACE_recursive_thread_mutex_t,
+ ACE_TSS_BASE_LOCK)
+ if (ACE_OS::recursive_mutex_init
+ // This line must not be broken to avoid tickling a bug with SunC++'s preprocessor.
+ (ACE_reinterpret_cast (ACE_recursive_thread_mutex_t *, ACE_OS_Object_Manager::preallocated_object[ACE_TSS_BASE_LOCK])) != 0)
+ ACE_OS_Object_Manager::print_error_message (
+ __LINE__, ACE_LIB_TEXT ("ACE_TSS_BASE_LOCK"));
+# endif /* ACE_HAS_THREAD_SPECIFIC_STORAGE */
+# endif /* ACE_HAS_TSS_EMULATION */
+# endif /* ACE_MT_SAFE */
+
+ // Open Winsock (no-op on other platforms).
+ ACE_OS::socket_init (ACE_WSOCK_VERSION);
+
+ // Register the exit hook, for use by ACE_OS::exit ().
+ ACE_OS::set_exit_hook (&ACE_OS_Object_Manager_Internal_Exit_Hook);
+ }
+
+ ACE_NEW_RETURN (default_mask_, sigset_t, -1);
+ ACE_OS::sigfillset (default_mask_);
+
+ // Finally, indicate that the ACE_OS_Object_Manager instance has
+ // been initialized.
+ object_manager_state_ = OBJ_MAN_INITIALIZED;
+
+# if defined (ACE_WIN32)
+ ACE_OS::win32_versioninfo_.dwOSVersionInfoSize =
+ sizeof (OSVERSIONINFO);
+ ::GetVersionEx (&ACE_OS::win32_versioninfo_);
+# endif /* ACE_WIN32 */
+ return 0;
+ } else {
+ // Had already initialized.
+ return 1;
+ }
+}
+
+// Clean up an ACE_OS_Object_Manager. There can be instances of this object
+// other than The Instance. This can happen if a user creates one for some
+// reason. All objects clean up their per-object information and managed
+// objects, but only The Instance cleans up the static preallocated objects.
+int
+ACE_OS_Object_Manager::fini (void)
+{
+ if (instance_ == 0 || shutting_down_i ())
+ // Too late. Or, maybe too early. Either fini () has already
+ // been called, or init () was never called.
+ return object_manager_state_ == OBJ_MAN_SHUT_DOWN ? 1 : -1;
+
+ // No mutex here. Only the main thread should destroy the singleton
+ // ACE_OS_Object_Manager instance.
+
+ // Indicate that the ACE_OS_Object_Manager instance is being shut
+ // down. This object manager should be the last one to be shut
+ // down.
+ object_manager_state_ = OBJ_MAN_SHUTTING_DOWN;
+
+ // If another Object_Manager has registered for termination, do it.
+ if (next_)
+ {
+ next_->fini ();
+ next_ = 0; // Protect against recursive calls.
+ }
+
+ // Call all registered cleanup hooks, in reverse order of
+ // registration.
+ exit_info_.call_hooks ();
+
+ // Only clean up preallocated objects when the singleton Instance is being
+ // destroyed.
+ if (this == instance_)
+ {
+ // Close down Winsock (no-op on other platforms).
+ ACE_OS::socket_fini ();
+
+#if ! defined (ACE_HAS_STATIC_PREALLOCATION)
+ // Cleanup the dynamically preallocated objects.
+# if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0)
+# if !defined(ACE_HAS_BROKEN_PREALLOCATED_OBJECTS_AFTER_FORK)
+ if (ACE_OS::thread_mutex_destroy
+ // This line must not be broken to avoid tickling a bug with SunC++'s preprocessor.
+ (ACE_reinterpret_cast (ACE_thread_mutex_t *, ACE_OS_Object_Manager::preallocated_object[ACE_OS_MONITOR_LOCK])) != 0)
+ ACE_OS_Object_Manager::print_error_message (
+ __LINE__, ACE_LIB_TEXT ("ACE_OS_MONITOR_LOCK"));
+# endif /* ! ACE_HAS_BROKEN_PREALLOCATED_OBJECTS_AFTER_FORK */
+ ACE_OS_DELETE_PREALLOCATED_OBJECT (ACE_thread_mutex_t,
+ ACE_OS_MONITOR_LOCK)
+# if !defined(ACE_HAS_BROKEN_PREALLOCATED_OBJECTS_AFTER_FORK)
+ if (ACE_OS::recursive_mutex_destroy
+ // This line must not be broken to avoid tickling a bug with SunC++'s preprocessor.
+ (ACE_reinterpret_cast (ACE_recursive_thread_mutex_t *, ACE_OS_Object_Manager::preallocated_object[ACE_TSS_CLEANUP_LOCK])) != 0)
+ ACE_OS_Object_Manager::print_error_message (
+ __LINE__, ACE_LIB_TEXT ("ACE_TSS_CLEANUP_LOCK"));
+# endif /* ! ACE_HAS_BROKEN_PREALLOCATED_OBJECTS_AFTER_FORK */
+ ACE_OS_DELETE_PREALLOCATED_OBJECT (ACE_recursive_thread_mutex_t,
+ ACE_TSS_CLEANUP_LOCK)
+# if !defined(ACE_HAS_BROKEN_PREALLOCATED_OBJECTS_AFTER_FORK)
+ if (ACE_OS::thread_mutex_destroy
+ // This line must not be broken to avoid tickling a bug with SunC++'s preprocessor.
+ (ACE_reinterpret_cast (ACE_thread_mutex_t *, ACE_OS_Object_Manager::preallocated_object [ACE_LOG_MSG_INSTANCE_LOCK])) != 0)
+ ACE_OS_Object_Manager::print_error_message (
+ __LINE__, ACE_LIB_TEXT ("ACE_LOG_MSG_INSTANCE_LOCK "));
+# endif /* ! ACE_HAS_BROKEN_PREALLOCATED_OBJECTS_AFTER_FORK */
+ ACE_OS_DELETE_PREALLOCATED_OBJECT (ACE_thread_mutex_t,
+ ACE_LOG_MSG_INSTANCE_LOCK)
+# if defined (ACE_HAS_TSS_EMULATION)
+# if !defined(ACE_HAS_BROKEN_PREALLOCATED_OBJECTS_AFTER_FORK)
+ if (ACE_OS::recursive_mutex_destroy
+ // This line must not be broken to avoid tickling a bug with SunC++'s preprocessor.
+ (ACE_reinterpret_cast (ACE_recursive_thread_mutex_t *, ACE_OS_Object_Manager::preallocated_object[ACE_TSS_KEY_LOCK])) != 0)
+ ACE_OS_Object_Manager::print_error_message (
+ __LINE__, ACE_LIB_TEXT ("ACE_TSS_KEY_LOCK"));
+# endif /* ! ACE_HAS_BROKEN_PREALLOCATED_OBJECTS_AFTER_FORK */
+ ACE_OS_DELETE_PREALLOCATED_OBJECT (ACE_recursive_thread_mutex_t,
+ ACE_TSS_KEY_LOCK)
+# if defined (ACE_HAS_THREAD_SPECIFIC_STORAGE)
+# if !defined(ACE_HAS_BROKEN_PREALLOCATED_OBJECTS_AFTER_FORK)
+ if (ACE_OS::recursive_mutex_destroy
+ // This line must not be broken to avoid tickling a bug with SunC++'s preprocessor.
+ (ACE_reinterpret_cast (ACE_recursive_thread_mutex_t *, ACE_OS_Object_Manager::preallocated_object[ACE_TSS_BASE_LOCK])) != 0)
+ ACE_OS_Object_Manager::print_error_message (
+ __LINE__, ACE_LIB_TEXT ("ACE_TSS_BASE_LOCK"));
+# endif /* ! ACE_HAS_BROKEN_PREALLOCATED_OBJECTS_AFTER_FORK */
+ ACE_OS_DELETE_PREALLOCATED_OBJECT (ACE_recursive_thread_mutex_t,
+ ACE_TSS_BASE_LOCK)
+# endif /* ACE_HAS_THREAD_SPECIFIC_STORAGE */
+# endif /* ACE_HAS_TSS_EMULATION */
+# if defined (ACE_HAS_WINCE_BROKEN_ERRNO)
+ ACE_CE_Errno::fini ();
+# endif /* ACE_HAS_WINCE_BROKEN_ERRNO */
+# endif /* ACE_MT_SAFE */
+#endif /* ! ACE_HAS_STATIC_PREALLOCATION */
+ }
+
+ delete default_mask_;
+ default_mask_ = 0;
+
+ // Indicate that this ACE_OS_Object_Manager instance has been shut down.
+ object_manager_state_ = OBJ_MAN_SHUT_DOWN;
+
+ if (dynamically_allocated_)
+ {
+ delete this;
+ }
+
+ if (this == instance_)
+ instance_ = 0;
+
+ return 0;
+}
+
+int ace_exit_hook_marker = 0;
+
+int
+ACE_OS_Object_Manager::at_exit (ACE_EXIT_HOOK func)
+{
+ return exit_info_.at_exit_i (&ace_exit_hook_marker,
+ ACE_reinterpret_cast (ACE_CLEANUP_FUNC, func),
+ 0);
+}
+
+void
+ACE_OS_Object_Manager::print_error_message (u_int line_number,
+ const ACE_TCHAR *message)
+{
+ // To avoid duplication of these const strings in OS.o.
+#if !defined (ACE_HAS_WINCE)
+ fprintf (stderr, "ace/OS.cpp, line %u: %s ",
+ line_number,
+ message);
+ perror ("failed");
+#else
+ // @@ Need to use the following information.
+ ACE_UNUSED_ARG (line_number);
+ ACE_UNUSED_ARG (message);
+
+ ACE_TCHAR *lpMsgBuf = 0;
+ ::FormatMessage (FORMAT_MESSAGE_ALLOCATE_BUFFER |
+ FORMAT_MESSAGE_FROM_SYSTEM,
+ NULL,
+ ::GetLastError (),
+ MAKELANGID (LANG_NEUTRAL,
+ SUBLANG_DEFAULT),
+ // Default language
+ (ACE_TCHAR *) &lpMsgBuf,
+ 0,
+ NULL);
+ ::MessageBox (NULL,
+ lpMsgBuf,
+ ACE_LIB_TEXT ("ACE_OS error"),
+ MB_OK);
+#endif
+}
+
+int
+ACE_OS_Object_Manager::starting_up (void)
+{
+ return ACE_OS_Object_Manager::instance_
+ ? instance_->starting_up_i ()
+ : 1;
+}
+
+int
+ACE_OS_Object_Manager::shutting_down (void)
+{
+ return ACE_OS_Object_Manager::instance_
+ ? instance_->shutting_down_i ()
+ : 1;
+}
+
+#if !defined (ACE_HAS_NONSTATIC_OBJECT_MANAGER)
+class ACE_OS_Object_Manager_Manager
+ // = TITLE
+ // Ensure that the <ACE_OS_Object_Manager> gets initialized at
+ // program startup, and destroyed at program termination.
+ //
+ // = DESCRIPTION
+ // Without ACE_HAS_NONSTATIC_OBJECT_MANAGER, a static instance of this
+ // class is created. Therefore, it gets created before main ()
+ // is called. And it gets destroyed after main () returns.
+{
+public:
+ ACE_OS_Object_Manager_Manager (void);
+ ~ACE_OS_Object_Manager_Manager (void);
+
+private:
+ ACE_thread_t saved_main_thread_id_;
+ // Save the main thread ID, so that destruction can be suppressed.
+};
+
+ACE_OS_Object_Manager_Manager::ACE_OS_Object_Manager_Manager (void)
+ : saved_main_thread_id_ (ACE_OS::thr_self ())
+{
+ // Ensure that the Object_Manager gets initialized before any
+ // application threads have been spawned. Because this will be called
+ // during construction of static objects, that should always be the
+ // case.
+ (void) ACE_OS_Object_Manager::instance ();
+}
+
+ACE_OS_Object_Manager_Manager::~ACE_OS_Object_Manager_Manager (void)
+{
+ if (ACE_OS::thr_equal (ACE_OS::thr_self (),
+ saved_main_thread_id_))
+ {
+ delete ACE_OS_Object_Manager::instance_;
+ ACE_OS_Object_Manager::instance_ = 0;
+ }
+ // else if this destructor is not called by the main thread, then do
+ // not delete the ACE_OS_Object_Manager. That causes problems, on
+ // WIN32 at least.
+}
+
+static ACE_OS_Object_Manager_Manager ACE_OS_Object_Manager_Manager_instance;
+#endif /* ! ACE_HAS_NONSTATIC_OBJECT_MANAGER */
+
+# if defined (ACE_HAS_WINCE)
+ACE_CE_Bridge *ACE_CE_Bridge::default_text_bridge_ = 0;
+
+ACE_CE_Bridge::ACE_CE_Bridge (void)
+ : text_output_ (0),
+ notification_ (0),
+ idc_ (0)
+{
+}
+
+ACE_CE_Bridge::ACE_CE_Bridge (HWND w, int n, int i)
+ : text_output_ (w),
+ notification_ (n),
+ idc_ (i)
+{
+}
+
+void
+ACE_CE_Bridge::set_window (HWND w, int n, int i)
+{
+ this->text_output_ = w;
+ this->notification_ = n;
+ this->idc_ = i;
+}
+
+ACE_CE_Bridge::~ACE_CE_Bridge (void)
+{
+ // This method needs to be defined because there seems to be a bug
+ // in CE's compiler.
+}
+
+void
+ACE_CE_Bridge::set_self_default (void)
+{
+ ACE_CE_Bridge::default_text_bridge_ = this;
+}
+
+int
+ACE_CE_Bridge::notification (void)
+{
+ return this->notification_;
+}
+
+int
+ACE_CE_Bridge::idc (void)
+{
+ return this->idc_;
+}
+
+HWND
+ACE_CE_Bridge::window (void)
+{
+ return this->text_output_;
+}
+
+ACE_CE_Bridge *
+ACE_CE_Bridge::get_default_winbridge (void)
+{
+ return ACE_CE_Bridge::default_text_bridge_;
+}
+
+int
+ACE_CE_Bridge::write_msg (const ACE_TCHAR *str)
+{
+ ACE_TCHAR *s = ACE_OS::strdup (str);
+ return PostMessage (this->text_output_,
+ WM_COMMAND,
+ MAKEWORD (this->idc_,
+ this->notification_),
+ (long)((void *) s));
+}
+
+#if 0
+int
+ACE_CE_Bridge::write_msg (CString *s)
+{
+ // Don't ask!
+ return PostMessage (this->text_output_,
+ WM_COMMAND,
+ MAKEWORD (this->idc_,
+ this->notification_),
+ (long)((void *) s));
+}
+#endif /* 0 */
+
+// **** Warning ****
+// You should not use the following function under CE at all. This
+// function is used to make Svc_Conf_l.cpp compile under WinCE. It
+// might not do what it is expected to do under regular environments.
+// **** Warning ****
+
+# if defined (UNDER_CE) && (UNDER_CE < 211)
+void
+exit (int status)
+{
+# if defined (ACE_HAS_NONSTATIC_OBJECT_MANAGER) && !defined (ACE_HAS_WINCE) && !defined (ACE_DOESNT_INSTANTIATE_NONSTATIC_OBJECT_MANAGER)
+ // Shut down the ACE_Object_Manager, if it had registered its exit_hook.
+ // With ACE_HAS_NONSTATIC_OBJECT_MANAGER, the ACE_Object_Manager is
+ // instantiated on the main's stack. ::exit () doesn't destroy it.
+ if (exit_hook_)
+ (*exit_hook_) ();
+# endif /* ACE_HAS_NONSTATIC_OBJECT_MANAGER && !ACE_HAS_WINCE && !ACE_DOESNT_INSTANTIATE_NONSTATIC_OBJECT_MANAGER */
+
+ ACE_OS::exit (status);
+}
+# endif /* UNDER_CE && UNDER_CE < 211 */
+# endif /* ACE_HAS_WINCE */
+
+// You may be asking yourself, why are we doing this? Well, in winbase.h,
+// MS didn't follow their normal Api_FunctionA and Api_FunctionW style,
+// so we have to #undef their define to get access to the unicode version.
+// And because we don't want to #undef this for the users code, we keep
+// this method in the .cpp file.
+#if defined (ACE_WIN32) && defined (UNICODE) && !defined (ACE_USES_TCHAR)
+#undef GetEnvironmentStrings
+#endif /* ACE_WIN32 && UNICODE !ACE_USES_TCHAR */
+
+ACE_TCHAR *
+ACE_OS::getenvstrings (void)
+{
+#if defined (ACE_LACKS_ENV)
+ ACE_NOTSUP_RETURN (0);
+#elif defined (ACE_WIN32)
+# if defined (ACE_USES_WCHAR)
+ return ::GetEnvironmentStringsW ();
+# else /* ACE_USES_WCHAR */
+ return ::GetEnvironmentStrings ();
+# endif /* ACE_USES_WCHAR */
+#else /* ACE_WIN32 */
+ ACE_NOTSUP_RETURN (0);
+#endif /* ACE_WIN32 */
+}
+
+#if defined (ACE_HAS_STRPTIME)
+char *
+ACE_OS::strptime (char *buf, const char *format, struct tm *tm)
+{
+#if !defined (ACE_HAS_WINCE)
+#if defined (ACE_LACKS_NATIVE_STRPTIME)
+ int bi = 0;
+ int fi = 0;
+ int percent = 0;
+
+ if (!buf || !format)
+ return 0;
+
+ while (format[fi] != '\0')
+ {
+ if (percent)
+ {
+ percent = 0;
+ switch (format[fi])
+ {
+ case '%': // an escaped %
+ if (buf[bi] == '%')
+ {
+ fi++; bi++;
+ }
+ else
+ return buf + bi;
+ break;
+
+ /* not supported yet: weekday via locale long/short names
+ case 'a': / * weekday via locale * /
+ / * FALL THROUGH * /
+ case 'A': / * long/short names * /
+ break;
+ */
+
+ /* not supported yet:
+ case 'b': / * month via locale * /
+ / * FALL THROUGH * /
+ case 'B': / * long/short names * /
+ / * FALL THROUGH * /
+ case 'h':
+ break;
+ */
+
+ /* not supported yet:
+ case 'c': / * %x %X * /
+ break;
+ */
+
+ /* not supported yet:
+ case 'C': / * date & time - * /
+ / * locale long format * /
+ break;
+ */
+
+ case 'd': /* day of month (1-31) */
+ /* FALL THROUGH */
+ case 'e':
+ if (!ACE_OS::strptime_getnum (buf + bi, &tm->tm_mday, &bi, &fi, 1, 31))
+ return buf + bi;
+
+ break;
+
+ case 'D': /* %m/%d/%y */
+ if (!ACE_OS::strptime_getnum (buf + bi, &tm->tm_mon, &bi, &fi, 1, 12))
+ return buf + bi;
+
+ fi--;
+ tm->tm_mon--;
+
+ if (buf[bi] != '/')
+ return buf + bi;
+
+ bi++;
+
+ if (!ACE_OS::strptime_getnum (buf + bi, &tm->tm_mday, &bi, &fi, 1, 31))
+ return buf + bi;
+
+ fi--;
+ if (buf[bi] != '/')
+ return buf + bi;
+ bi++;
+ if (!ACE_OS::strptime_getnum (buf + bi, &tm->tm_year, &bi, &fi, 0, 99))
+ return buf + bi;
+ if (tm->tm_year < 69)
+ tm->tm_year += 100;
+ break;
+
+ case 'H': /* hour (0-23) */
+ /* FALL THROUGH */
+ case 'k':
+ if (!ACE_OS::strptime_getnum (buf + bi, &tm->tm_hour, &bi, &fi, 0, 23))
+ return buf + bi;
+ break;
+
+ /* not supported yet:
+ case 'I': / * hour (0-12) * /
+ / * FALL THROUGH * /
+ case 'l':
+ break;
+ */
+
+ case 'j': /* day of year (0-366) */
+ if (!ACE_OS::strptime_getnum (buf + bi, &tm->tm_yday, &bi, &fi, 1, 366))
+ return buf + bi;
+
+ tm->tm_yday--;
+ break;
+
+ case 'm': /* an escaped % */
+ if (!ACE_OS::strptime_getnum (buf + bi, &tm->tm_mon, &bi, &fi, 1, 12))
+ return buf + bi;
+
+ tm->tm_mon--;
+ break;
+
+ case 'M': /* minute (0-59) */
+ if (!ACE_OS::strptime_getnum (buf + bi, &tm->tm_min, &bi, &fi, 0, 59))
+ return buf + bi;
+
+ break;
+
+ /* not supported yet:
+ case 'p': / * am or pm for locale * /
+ break;
+ */
+
+ /* not supported yet:
+ case 'r': / * %I:%M:%S %p * /
+ break;
+ */
+
+ case 'R': /* %H:%M */
+ if (!ACE_OS::strptime_getnum (buf + bi, &tm->tm_hour, &bi, &fi, 0, 23))
+ return buf + bi;
+
+ fi--;
+ if (buf[bi] != ':')
+ return buf + bi;
+ bi++;
+ if (!ACE_OS::strptime_getnum (buf + bi, &tm->tm_min, &bi, &fi, 0, 59))
+ return buf + bi;
+
+ break;
+
+ case 'S': /* seconds (0-61) */
+ if (!ACE_OS::strptime_getnum (buf + bi, &tm->tm_sec, &bi, &fi, 0, 61))
+ return buf + bi;
+ break;
+
+ case 'T': /* %H:%M:%S */
+ if (!ACE_OS::strptime_getnum (buf + bi, &tm->tm_hour, &bi, &fi, 0, 23))
+ return buf + bi;
+
+ fi--;
+ if (buf[bi] != ':')
+ return buf + bi;
+ bi++;
+ if (!ACE_OS::strptime_getnum (buf + bi, &tm->tm_min, &bi, &fi, 0, 59))
+ return buf + bi;
+
+ fi--;
+ if (buf[bi] != ':')
+ return buf + bi;
+ bi++;
+ if (!ACE_OS::strptime_getnum (buf + bi, &tm->tm_sec, &bi, &fi, 0, 61))
+ return buf + bi;
+
+ break;
+
+ case 'w': /* day of week (0=Sun-6) */
+ if (!ACE_OS::strptime_getnum (buf + bi, &tm->tm_wday, &bi, &fi, 0, 6))
+ return buf + bi;
+
+ break;
+
+ /* not supported yet: date, based on locale
+ case 'x': / * date, based on locale * /
+ break;
+ */
+
+ /* not supported yet:
+ case 'X': / * time, based on locale * /
+ break;
+ */
+
+ case 'y': /* the year - 1900 (0-99) */
+ if (!ACE_OS::strptime_getnum (buf + bi, &tm->tm_year, &bi, &fi, 0, 99))
+ return buf + bi;
+
+ if (tm->tm_year < 69)
+ tm->tm_year += 100;
+ break;
+
+ case 'Y': /* the full year (1999) */
+ if (!ACE_OS::strptime_getnum (buf + bi, &tm->tm_year, &bi, &fi, 0, 0))
+ return buf + bi;
+
+ tm->tm_year -= 1900;
+ break;
+
+ default: /* unrecognised */
+ return buf + bi;
+ } /* switch (format[fi]) */
+
+ }
+ else
+ { /* if (percent) */
+ if (format[fi] == '%')
+ {
+ percent = 1;
+ fi++;
+ }
+ else
+ {
+ if (format[fi] == buf[bi])
+ {
+ fi++;
+ bi++;
+ }
+ else
+ return buf + bi;
+ }
+ } /* if (percent) */
+ } /* while (format[fi] */
+
+ return buf + bi;
+#else /* ! ACE_LACKS_NATIVE_STRPTIME */
+ return ::strptime (buf,
+ format,
+ tm);
+#endif /* ! ACE_LACKS_NATIVE_STRPTIME */
+#else /* ! ACE_HAS_WINCE */
+ ACE_UNUSED_ARG (buf);
+ ACE_UNUSED_ARG (format);
+ ACE_UNUSED_ARG (tm);
+
+ ACE_NOTSUP_RETURN (0);
+#endif /* ! ACE_HAS_WINCE */
+}
+
+# if defined (ACE_LACKS_NATIVE_STRPTIME)
+int
+ACE_OS::strptime_getnum (char *buf,
+ int *num,
+ int *bi,
+ int *fi,
+ int min,
+ int max)
+{
+ int i = 0, tmp = 0;
+
+ while (isdigit (buf[i]))
+ {
+ tmp = (tmp * 10) + (buf[i] - '0');
+ if (max && (tmp > max))
+ return 0;
+ i++;
+ }
+
+ if (tmp < min)
+ return 0;
+ else if (i)
+ {
+ *num = tmp;
+ (*fi)++;
+ *bi += i;
+ return 1;
+ }
+ else
+ return 0;
+}
+# endif /* ACE_LACKS_NATIVE_STRPTIME */
+#endif /* ACE_HAS_STRPTIME */
+
+ACE_HANDLE
+ACE_OS::accept (ACE_HANDLE handle,
+ struct sockaddr *addr,
+ int *addrlen,
+ const ACE_Accept_QoS_Params &qos_params)
+{
+#if defined (ACE_HAS_WINSOCK2) && (ACE_HAS_WINSOCK2 != 0)
+ ACE_SOCKCALL_RETURN (::WSAAccept ((ACE_SOCKET) handle,
+ addr,
+ (ACE_SOCKET_LEN *) addrlen,
+ (LPCONDITIONPROC) qos_params.qos_condition_callback (),
+ qos_params.callback_data ()),
+ ACE_HANDLE,
+ ACE_INVALID_HANDLE);
+#else
+ ACE_UNUSED_ARG (qos_params);
+ return ACE_OS::accept (handle,
+ addr,
+ addrlen);
+#endif /* ACE_HAS_WINSOCK2 */
+}
+
+ACE_HANDLE
+ACE_OS::join_leaf (ACE_HANDLE socket,
+ const sockaddr *name,
+ int namelen,
+ const ACE_QoS_Params &qos_params)
+{
+#if defined (ACE_HAS_WINSOCK2) && (ACE_HAS_WINSOCK2 != 0)
+
+ QOS qos;
+ // Construct the WinSock2 QOS structure.
+
+ qos.SendingFlowspec = *(qos_params.socket_qos ()->sending_flowspec ());
+ qos.ReceivingFlowspec = *(qos_params.socket_qos ()->receiving_flowspec ());
+ qos.ProviderSpecific = (WSABUF) qos_params.socket_qos ()->provider_specific ();
+
+ ACE_SOCKCALL_RETURN (::WSAJoinLeaf ((ACE_SOCKET) socket,
+ name,
+ namelen,
+ (WSABUF *) qos_params.caller_data (),
+ (WSABUF *) qos_params.callee_data (),
+ &qos,
+ (QOS *) qos_params.group_socket_qos (),
+ qos_params.flags ()),
+ ACE_HANDLE,
+ ACE_INVALID_HANDLE);
+
+#else
+ ACE_UNUSED_ARG (socket);
+ ACE_UNUSED_ARG (name);
+ ACE_UNUSED_ARG (namelen);
+ ACE_UNUSED_ARG (qos_params);
+ ACE_NOTSUP_RETURN (ACE_INVALID_HANDLE);
+#endif /* ACE_HAS_WINSOCK2 */
+}
+
+int
+ACE_OS::ioctl (ACE_HANDLE socket,
+ u_long io_control_code,
+ void *in_buffer_p,
+ u_long in_buffer,
+ void *out_buffer_p,
+ u_long out_buffer,
+ u_long *bytes_returned,
+ ACE_OVERLAPPED *overlapped,
+ ACE_OVERLAPPED_COMPLETION_FUNC func)
+{
+#if defined (ACE_HAS_WINSOCK2) && (ACE_HAS_WINSOCK2 != 0)
+ ACE_SOCKCALL_RETURN (::WSAIoctl ((ACE_SOCKET) socket,
+ io_control_code,
+ in_buffer_p,
+ in_buffer,
+ out_buffer_p,
+ out_buffer,
+ bytes_returned,
+ (WSAOVERLAPPED *) overlapped,
+ func),
+ int,
+ SOCKET_ERROR);
+#else
+ ACE_UNUSED_ARG (socket);
+ ACE_UNUSED_ARG (io_control_code);
+ ACE_UNUSED_ARG (in_buffer_p);
+ ACE_UNUSED_ARG (in_buffer);
+ ACE_UNUSED_ARG (out_buffer_p);
+ ACE_UNUSED_ARG (out_buffer);
+ ACE_UNUSED_ARG (bytes_returned);
+ ACE_UNUSED_ARG (overlapped);
+ ACE_UNUSED_ARG (func);
+ ACE_NOTSUP_RETURN (-1);
+#endif /* ACE_HAS_WINSOCK2 */
+}
+
+
+
+int
+ACE_OS::ioctl (ACE_HANDLE socket,
+ u_long io_control_code,
+ ACE_QoS &ace_qos,
+ u_long *bytes_returned,
+ void *buffer_p,
+ u_long buffer,
+ ACE_OVERLAPPED *overlapped,
+ ACE_OVERLAPPED_COMPLETION_FUNC func)
+{
+#if defined (ACE_HAS_WINSOCK2) && (ACE_HAS_WINSOCK2 != 0)
+
+ QOS qos;
+ u_long qos_len = sizeof (QOS);
+
+ if (io_control_code == SIO_SET_QOS)
+ {
+ qos.SendingFlowspec = *(ace_qos.sending_flowspec ());
+ qos.ReceivingFlowspec = *(ace_qos.receiving_flowspec ());
+ qos.ProviderSpecific = (WSABUF) ace_qos.provider_specific ();
+
+ qos_len += ace_qos.provider_specific ().iov_len;
+
+ ACE_SOCKCALL_RETURN (::WSAIoctl ((ACE_SOCKET) socket,
+ io_control_code,
+ &qos,
+ qos_len,
+ buffer_p,
+ buffer,
+ bytes_returned,
+ (WSAOVERLAPPED *) overlapped,
+ func),
+ int,
+ SOCKET_ERROR);
+ }
+ else
+ {
+ u_long dwBufferLen = 0;
+
+ // Query for the buffer size.
+ int result = ::WSAIoctl ((ACE_SOCKET) socket,
+ io_control_code,
+ NULL,
+ 0,
+ &dwBufferLen,
+ sizeof (dwBufferLen),
+ bytes_returned,
+ NULL,
+ NULL);
+
+
+ if (result == SOCKET_ERROR)
+ {
+ u_long dwErr = ::WSAGetLastError ();
+
+ if (dwErr == WSAEWOULDBLOCK)
+ {
+ errno = dwErr;
+ return -1;
+ }
+ else
+ if (dwErr != WSAENOBUFS)
+ {
+ errno = dwErr;
+ return -1;
+ }
+ }
+
+ char *qos_buf;
+ ACE_NEW_RETURN (qos_buf,
+ char [dwBufferLen],
+ -1);
+
+ QOS *qos = ACE_reinterpret_cast (QOS*,
+ qos_buf);
+
+ result = ::WSAIoctl ((ACE_SOCKET) socket,
+ io_control_code,
+ NULL,
+ 0,
+ qos,
+ dwBufferLen,
+ bytes_returned,
+ NULL,
+ NULL);
+
+ if (result == SOCKET_ERROR)
+ return result;
+
+ ACE_Flow_Spec sending_flowspec (qos->SendingFlowspec.TokenRate,
+ qos->SendingFlowspec.TokenBucketSize,
+ qos->SendingFlowspec.PeakBandwidth,
+ qos->SendingFlowspec.Latency,
+ qos->SendingFlowspec.DelayVariation,
+#if defined(ACE_HAS_WINSOCK2_GQOS)
+ qos->SendingFlowspec.ServiceType,
+ qos->SendingFlowspec.MaxSduSize,
+ qos->SendingFlowspec.MinimumPolicedSize,
+#else /* ACE_HAS_WINSOCK2_GQOS */
+ 0,
+ 0,
+ 0,
+#endif /* ACE_HAS_WINSOCK2_GQOS */
+ 0,
+ 0);
+
+ ACE_Flow_Spec receiving_flowspec (qos->ReceivingFlowspec.TokenRate,
+ qos->ReceivingFlowspec.TokenBucketSize,
+ qos->ReceivingFlowspec.PeakBandwidth,
+ qos->ReceivingFlowspec.Latency,
+ qos->ReceivingFlowspec.DelayVariation,
+#if defined(ACE_HAS_WINSOCK2_GQOS)
+ qos->ReceivingFlowspec.ServiceType,
+ qos->ReceivingFlowspec.MaxSduSize,
+ qos->ReceivingFlowspec.MinimumPolicedSize,
+#else /* ACE_HAS_WINSOCK2_GQOS */
+ 0,
+ 0,
+ 0,
+#endif /* ACE_HAS_WINSOCK2_GQOS */
+ 0,
+ 0);
+
+ ace_qos.sending_flowspec (&sending_flowspec);
+ ace_qos.receiving_flowspec (&receiving_flowspec);
+ ace_qos.provider_specific (*((struct iovec *) (&qos->ProviderSpecific)));
+
+
+ return result;
+ }
+
+#else
+ ACE_UNUSED_ARG (socket);
+ ACE_UNUSED_ARG (io_control_code);
+ ACE_UNUSED_ARG (ace_qos);
+ ACE_UNUSED_ARG (bytes_returned);
+ ACE_UNUSED_ARG (buffer_p);
+ ACE_UNUSED_ARG (buffer);
+ ACE_UNUSED_ARG (overlapped);
+ ACE_UNUSED_ARG (func);
+ ACE_NOTSUP_RETURN (-1);
+#endif /* ACE_HAS_WINSOCK2 */
+}
+
+int
+ACE_OS::connect (ACE_HANDLE handle,
+ const sockaddr *addr,
+ int addrlen,
+ const ACE_QoS_Params &qos_params)
+{
+ ACE_OS_TRACE ("ACE_OS::connect");
+#if defined (ACE_HAS_WINSOCK2) && (ACE_HAS_WINSOCK2 != 0)
+ ACE_SOCKCALL_RETURN (::WSAConnect ((ACE_SOCKET) handle,
+ (const sockaddr *) addr,
+ (ACE_SOCKET_LEN) addrlen,
+ (WSABUF *) qos_params.caller_data (),
+ (WSABUF *) qos_params.callee_data (),
+ (QOS *) qos_params.socket_qos (),
+ (QOS *) qos_params.group_socket_qos ()),
+ int, -1);
+#else
+ ACE_UNUSED_ARG (qos_params);
+ return ACE_OS::connect (handle,
+ (sockaddr *) addr,
+ addrlen);
+#endif /* ACE_HAS_WINSOCK2 */
+}
diff --git a/ace/OS/OS.h b/ace/OS/OS.h
new file mode 100644
index 00000000000..46b2214f4a2
--- /dev/null
+++ b/ace/OS/OS.h
@@ -0,0 +1,7529 @@
+// -*- C++ -*-
+
+//=============================================================================
+/**
+ * @file OS.h
+ *
+ * $Id$
+ *
+ * @author Douglas C. Schmidt <schmidt@cs.wustl.edu>
+ * @author Jesper S. M|ller<stophph@diku.dk>
+ * @author and a cast of thousands...
+ */
+//=============================================================================
+
+#ifndef ACE_OS_H
+#define ACE_OS_H
+
+#include "ace/pre.h"
+
+#include "ace/config-all.h"
+
+#if defined (ACE_HAS_VIRTUAL_TIME)
+#include /**/ <sys/times.h>
+#endif /*ACE_HAS_VIRTUAL_TIME*/
+
+#if !defined (ACE_LACKS_PRAGMA_ONCE)
+# pragma once
+#endif /* ACE_LACKS_PRAGMA_ONCE */
+
+// Include the split up ACE_OS classes
+#include "OS_Dirent.h"
+#include "OS_String.h"
+#include "OS_Memory.h"
+#include "OS_TLI.h"
+#include "OS_Errno.h"
+
+class ACE_Timeout_Manager;
+
+#if !defined (_SC_AIO_MAX)
+#define _SC_AIO_MAX 1
+#endif /* _SC_AIO_MAX */
+
+// Do not change these values wantonly since GPERF depends on them..
+#define ACE_ASCII_SIZE 128
+#define ACE_EBCDIC_SIZE 256
+
+#if 'a' < 'A'
+#define ACE_HAS_EBCDIC
+#define ACE_STANDARD_CHARACTER_SET_SIZE 256
+#else
+#define ACE_HAS_ASCII
+#define ACE_STANDARD_CHARACTER_SET_SIZE 128
+#endif /* 'a' < 'A' */
+
+# if defined (ACE_PSOS_TM)
+typedef long long longlong_t;
+typedef long id_t;
+# endif /* ACE_PSOS_TM */
+
+// Deal with MSVC++ insanity for CORBA...
+# if defined (ACE_HAS_BROKEN_NAMESPACES)
+# define ACE_CORBA_1(NAME) CORBA_##NAME
+# define ACE_CORBA_2(TYPE, NAME) CORBA_##TYPE##_##NAME
+# define ACE_CORBA_3(TYPE, NAME) CORBA_##TYPE::NAME
+# define ACE_NESTED_CLASS(TYPE, NAME) NAME
+# else /* ! ACE_HAS_BROKEN_NAMESPACES */
+# define ACE_CORBA_1(NAME) CORBA::NAME
+# define ACE_CORBA_2(TYPE, NAME) CORBA::TYPE::NAME
+# define ACE_CORBA_3(TYPE, NAME) CORBA::TYPE::NAME
+# define ACE_NESTED_CLASS(TYPE, NAME) TYPE::NAME
+# endif /* ! ACE_HAS_BROKEN_NAMESPACES */
+
+// Here are all ACE-specific default constants, needed throughout ACE
+// and its applications. The values can be over written by user
+// specific values in config.h files.
+#include "ace/Default_Constants.h"
+
+
+# if defined (ACE_HAS_4_4BSD_SENDMSG_RECVMSG)
+ // Control message size to pass a file descriptor.
+# define ACE_BSD_CONTROL_MSG_LEN sizeof (struct cmsghdr) + sizeof (ACE_HANDLE)
+# if defined (ACE_LACKS_CMSG_DATA_MACRO)
+# if defined (ACE_LACKS_CMSG_DATA_MEMBER)
+# define CMSG_DATA(cmsg) ((unsigned char *) ((struct cmsghdr *) (cmsg) + 1))
+# else
+# define CMSG_DATA(cmsg) ((cmsg)->cmsg_data)
+# endif /* ACE_LACKS_CMSG_DATA_MEMBER */
+# endif /* ACE_LACKS_CMSG_DATA_MACRO */
+# endif /* ACE_HAS_4_4BSD_SENDMSG_RECVMSG */
+
+
+// Default size of the ACE Reactor.
+# if defined (FD_SETSIZE)
+int const ACE_FD_SETSIZE = FD_SETSIZE;
+# else
+# define ACE_FD_SETSIZE FD_SETSIZE
+# endif /* ACE_FD_SETSIZE */
+
+# if !defined (ACE_DEFAULT_SELECT_REACTOR_SIZE)
+# define ACE_DEFAULT_SELECT_REACTOR_SIZE ACE_FD_SETSIZE
+# endif /* ACE_DEFAULT_SELECT_REACTOR_SIZE */
+
+
+// Here are all ACE-specific global declarations needed throughout
+// ACE.
+#include "Global_Macros.h"
+
+#if !defined (ACE_WIN32)
+#define ACE_MAX_USERID L_cuserid
+#endif /*!ACE_WIN32*/
+
+// include the ACE min()/max() functions.
+# include "ace/Min_Max.h"
+
+
+// These hooks enable ACE to have all dynamic memory management
+// automatically handled on a per-object basis.
+
+# if defined (ACE_LACKS_KEY_T)
+# if defined (ACE_WIN32)
+ // Win32 doesn't use numeric values to name its semaphores, it uses
+ // strings!
+typedef char *key_t;
+# else
+typedef int key_t;
+# endif /* ACE_WIN32 */
+# endif /* ACE_LACKS_KEY_T */
+
+///////////////////////////////////////////
+// //
+// NOTE: Please do not add any #includes //
+// before this point. On VxWorks, //
+// vxWorks.h must be #included //
+// first! //
+// //
+///////////////////////////////////////////
+
+#if defined (ACE_HAS_PACE)
+# include /**/ "pace/dirent.h"
+# include /**/ "pace/fcntl.h"
+# include /**/ "pace/sys/mman.h"
+# include /**/ "pace/pthread.h"
+# include /**/ "pace/pwd.h"
+# include /**/ "pace/stdio.h"
+# include /**/ "pace/stdlib.h"
+# include /**/ "pace/sched.h"
+# include /**/ "pace/semaphore.h"
+# include /**/ "pace/signal.h"
+# include /**/ "pace/sys/stat.h"
+# include /**/ "pace/stdio.h"
+# include /**/ "pace/time.h"
+# include /**/ "pace/unistd.h"
+# include /**/ "pace/sys/utsname.h"
+# include /**/ "pace/sys/wait.h"
+#endif /* ACE_HAS_PACE */
+
+# if defined (ACE_PSOS)
+
+# if defined (ACE_LACKS_ASSERT_MACRO)
+# define assert(expr)
+# endif
+
+# if defined (ACE_PSOSIM)
+
+# include /**/ "ace/sys_conf.h" /* system configuration file */
+# include /**/ <psos.h> /* pSOS+ system calls */
+# include /**/ <pna.h> /* pNA+ TCP/IP Network Manager calls */
+
+ /* In the *simulator* environment, use unsigned int for size_t */
+# define size_t unsigned int
+
+
+ /* include <rpc.h> pRPC+ Remote Procedure Call Library calls */
+ /* are not supported by pSOSim */
+ /* */
+ /* include <phile.h> pHILE+ file system calls are not supported */
+ /* by pSOSim *so*, for the time being, we make */
+ /* use of UNIX file system headers and then */
+ /* when we have time, we wrap UNIX file system */
+ /* calls w/ pHILE+ wrappers, and modify ACE to */
+ /* use the wrappers under pSOSim */
+
+ /* put includes for necessary UNIX file system calls here */
+# include /**/ <sys/stat.h>
+# include /**/ <sys/ioctl.h>
+# include /**/ <sys/sockio.h>
+# include /**/ <netinet/tcp.h>
+
+# define TCP_
+# if ! defined (BUFSIZ)
+# define BUFSIZ 1024
+# endif /* ! defined (BUFSIZ) */
+
+
+# else
+
+# if defined (ACE_PSOS_CANT_USE_SYS_TYPES)
+ // these are missing from the pSOS types.h file, and the compiler
+ // supplied types.h file collides with the pSOS version.
+# if !defined (ACE_SHOULD_NOT_DEFINE_SYS_TYPES)
+ typedef unsigned char u_char;
+ typedef unsigned short u_short;
+# endif /* ACE_SHOULD_NOT_DEFINE_SYS_TYPES */
+ typedef unsigned int u_int;
+# if !defined (ACE_SHOULD_NOT_DEFINE_SYS_TYPES)
+ typedef unsigned long u_long;
+# endif /* ACE_SHOULD_NOT_DEFINE_SYS_TYPES */
+
+ // These are defined in types.h included by (among others) pna.h
+# if 0
+ typedef unsigned char uchar_t;
+ typedef unsigned short ushort_t;
+ typedef unsigned int uint_t;
+ typedef unsigned long ulong_t;
+# endif /* 0 */
+ typedef char * caddr_t;
+
+# if defined (ACE_PSOS_DIAB_PPC)
+ // pid_t is defined in sys/types.h
+# if 0
+ typedef unsigned long pid_t;
+# endif /* 0 */
+# define ACE_INVALID_PID ((pid_t) ~0)
+# else /* !defined (ACE_PSOS_DIAB_PPC) */
+ typedef long pid_t;
+# define ACE_INVALID_PID ((pid_t) -1)
+# endif /* defined (ACE_PSOS_DIAB_PPC) */
+
+// typedef unsigned char wchar_t;
+# endif /* ACE_PSOS_CANT_USE_SYS_TYPES */
+
+# include /**/ "ace/sys_conf.h" /* system configuration file */
+# include /**/ <configs.h> /* includes all pSOS headers */
+// #include /**/ <psos.h> /* pSOS system calls */
+# include /**/ <pna.h> /* pNA+ TCP/IP Network Manager calls */
+# include /**/ <phile.h> /* pHILE+ file system calls */
+// #include /**/ <prepccfg.h> /* pREPC+ file system calls */
+# if defined (ACE_PSOS_DIAB_MIPS)
+# if defined (ACE_PSOS_USES_DIAB_SYS_CALLS)
+# include /**/ <unistd.h> /* Diab Data supplied file system calls */
+# else
+# include /**/ <prepc.h>
+# endif /* ACE_PSOS_USES_DIAB_SYS_CALLS */
+# include /**/ <sys/wait.h> /* Diab Data supplied header file */
+# endif /* ACE_PSOS_DIAB_MIPS */
+
+// This collides with phile.h
+// #include /**/ <sys/stat.h> /* Diab Data supplied header file */
+
+// Some versions have missing preprocessor definitions
+# if !defined (AF_UNIX)
+# define AF_UNIX 0x1
+# endif /* AF_UNIX */
+# define PF_UNIX AF_UNIX
+# define PF_INET AF_INET
+# if !defined (AF_MAX)
+# define AF_MAX AF_INET
+# endif /* AF_MAX */
+# if !defined (IFF_LOOPBACK)
+# define IFF_LOOPBACK IFF_EXTLOOPBACK
+# endif /* IFF_LOOPBACK */
+
+ typedef long fd_mask;
+# define IPPORT_RESERVED 1024
+# define IPPORT_USERRESERVED 5000
+
+# if !defined (howmany)
+# define howmany(x, y) (((x)+((y)-1))/(y))
+# endif /* howmany */
+
+ extern "C"
+ {
+ typedef void (* ACE_SignalHandler) (void);
+ typedef void (* ACE_SignalHandlerV) (void);
+ }
+
+# if !defined(SIG_DFL)
+# define SIG_DFL (ACE_SignalHandler) 0
+# endif /* philabs */
+
+# endif /* defined (ACE_PSOSIM) */
+
+// Some versions of pSOS do not define error numbers, but newer
+// versions do. So, include errno.h and then see which ones are not
+// yet defined.
+# include /**/ <errno.h>
+
+# if !defined (EPERM)
+# define EPERM 1 /* Not super-user */
+# endif /* EPERM */
+# if !defined (ENOENT)
+# define ENOENT 2 /* No such file or directory */
+# endif /* ENOENT */
+# if !defined (ESRCH)
+# define ESRCH 3 /* No such process */
+# endif /* ESRCH */
+# if ! defined (EINTR)
+# define EINTR 4 /* interrupted system call */
+# endif /* EINTR */
+# if !defined (EBADF)
+# define EBADF 9 /* Bad file number */
+# endif /* EBADF */
+# if !defined (EAGAIN)
+# define EAGAIN 11 /* Resource temporarily unavailable */
+# endif /* EAGAIN */
+# if !defined (EWOULDBLOCK)
+# define EWOULDBLOCK EAGAIN /* Blocking resource request would block */
+# endif /* EWOULDBLOCK */
+# if !defined (ENOMEM)
+# define ENOMEM 12 /* Not enough core */
+# endif /* ENOMEM */
+# if !defined (EACCESS)
+# define EACCES 13 /* Permission denied */
+# endif /* EACCESS */
+# if !defined (EFAULT)
+# define EFAULT 14 /* Bad access */
+# endif /* EFAULT */
+# if !defined (EEXIST)
+# define EEXIST 17 /* File exists */
+# endif /* EEXIST */
+# if !defined (ENOSPC)
+# define ENOSPC 28 /* No space left on device */
+# endif /* ENOSPC */
+# if !defined (EPIPE)
+# define EPIPE 32 /* Broken pipe */
+# endif /* EPIPE */
+# if !defined (ETIME)
+# define ETIME 62 /* timer expired */
+# endif /* ETIME */
+# if !defined (ENAMETOOLONG)
+# define ENAMETOOLONG 78 /* path name is too long */
+# endif /* ENAMETOOLONG */
+# if !defined (ENOSYS)
+# define ENOSYS 89 /* Unsupported file system operation */
+# endif /* ENOSYS */
+# if !defined (EADDRINUSE)
+# define EADDRINUSE 125 /* Address already in use */
+# endif /* EADDRINUSE */
+# if !defined (ENETUNREACH)
+# define ENETUNREACH 128 /* Network is unreachable */
+# endif /* ENETUNREACH */
+# if !defined (EISCONN)
+# define EISCONN 133 /* Socket is already connected */
+# endif /* EISCONN */
+# if !defined (ESHUTDOWN)
+# define ESHUTDOWN 143 /* Can't send after socket shutdown */
+# endif /* ESHUTDOWN */
+# if !defined (ECONNREFUSED)
+# define ECONNREFUSED 146 /* Connection refused */
+# endif /* ECONNREFUSED */
+# if !defined (EINPROGRESS)
+# define EINPROGRESS 150 /* operation now in progress */
+# endif /* EINPROGRESS */
+# if !defined (ERRMAX)
+# define ERRMAX 151 /* Last error number */
+# endif /* ERRMAX */
+
+# if ! defined (NSIG)
+# define NSIG 32
+# endif /* NSIG */
+
+# if ! defined (TCP_NODELAY)
+# define TCP_NODELAY 1
+# endif /* TCP_NODELAY */
+
+// For general purpose portability
+
+# define ACE_BITS_PER_ULONG (8 * sizeof (u_long))
+
+typedef u_long ACE_idtype_t;
+typedef u_long ACE_id_t;
+# define ACE_SELF (0)
+typedef u_long ACE_pri_t;
+
+// pHILE+ calls the DIR struct XDIR instead
+# if !defined (ACE_PSOS_DIAB_PPC)
+typedef XDIR ACE_DIR;
+# endif /* !defined (ACE_PSOS_DIAB_PPC) */
+
+// Use pSOS semaphores, wrapped . . .
+typedef struct
+{
+ u_long sema_;
+ // Semaphore handle. This is allocated by pSOS.
+
+ char name_[4];
+ // Name of the semaphore: really a 32 bit number to pSOS
+} ACE_sema_t;
+
+// Used for dynamic linking.
+# if !defined (ACE_DEFAULT_SVC_CONF)
+# define ACE_DEFAULT_SVC_CONF "./svc.conf"
+# endif /* ACE_DEFAULT_SVC_CONF */
+
+# if !defined (ACE_DEFAULT_SEM_KEY)
+# define ACE_DEFAULT_SEM_KEY 1234
+# endif /* ACE_DEFAULT_SEM_KEY */
+
+# define ACE_STDIN 0
+# define ACE_STDOUT 1
+# define ACE_STDERR 2
+
+# define ACE_DIRECTORY_SEPARATOR_STR_A "/"
+# define ACE_DIRECTORY_SEPARATOR_CHAR_A '/'
+# define ACE_PLATFORM_A "pSOS"
+# define ACE_PLATFORM_EXE_SUFFIX_A ""
+
+# define ACE_DLL_SUFFIX ACE_LIB_TEXT (".so")
+# define ACE_DLL_PREFIX ACE_LIB_TEXT ("lib")
+# define ACE_LD_SEARCH_PATH ACE_LIB_TEXT ("LD_LIBRARY_PATH")
+# define ACE_LD_SEARCH_PATH_SEPARATOR_STR ACE_LIB_TEXT (":")
+# define ACE_LOGGER_KEY ACE_LIB_TEXT ("/tmp/server_daemon")
+
+# define ACE_MAX_DEFAULT_PORT 65535
+
+# if ! defined(MAXPATHLEN)
+# define MAXPATHLEN 1024
+# endif /* MAXPATHLEN */
+
+# if ! defined(MAXNAMLEN)
+# define MAXNAMLEN 255
+# endif /* MAXNAMLEN */
+
+# if defined (ACE_LACKS_MMAP)
+# define PROT_READ 0
+# define PROT_WRITE 0
+# define PROT_EXEC 0
+# define PROT_NONE 0
+# define PROT_RDWR 0
+# define MAP_PRIVATE 0
+# define MAP_SHARED 0
+# define MAP_FIXED 0
+# endif /* ACE_LACKS_MMAP */
+
+
+typedef int ACE_exitcode;
+
+typedef ACE_HANDLE ACE_SHLIB_HANDLE;
+# define ACE_SHLIB_INVALID_HANDLE ACE_INVALID_HANDLE
+# define ACE_DEFAULT_SHLIB_MODE 0
+
+# define ACE_INVALID_SEM_KEY -1
+
+struct hostent {
+ char *h_name; /* official name of host */
+ char **h_aliases; /* alias list */
+ int h_addrtype; /* host address type */
+ int h_length; /* address length */
+ char **h_addr_list; /* (first, only) address from name server */
+# define h_addr h_addr_list[0] /* the first address */
+};
+
+struct servent {
+ char *s_name; /* official service name */
+ char **s_aliases; /* alias list */
+ int s_port; /* port # */
+ char *s_proto; /* protocol to use */
+};
+
+# define ACE_SEH_TRY if (1)
+# define ACE_SEH_EXCEPT(X) while (0)
+# define ACE_SEH_FINALLY if (1)
+
+# if !defined (LPSECURITY_ATTRIBUTES)
+# define LPSECURITY_ATTRIBUTES int
+# endif /* !defined LPSECURITY_ATTRIBUTES */
+# if !defined (GENERIC_READ)
+# define GENERIC_READ 0
+# endif /* !defined GENERIC_READ */
+# if !defined (FILE_SHARE_READ)
+# define FILE_SHARE_READ 0
+# endif /* !defined FILE_SHARE_READ */
+# if !defined (OPEN_EXISTING)
+# define OPEN_EXISTING 0
+# endif /* !defined OPEN_EXISTING */
+# if !defined (FILE_ATTRIBUTE_NORMAL)
+# define FILE_ATTRIBUTE_NORMAL 0
+# endif /* !defined FILE_ATTRIBUTE_NORMAL */
+# if !defined (MAXIMUM_WAIT_OBJECTS)
+# define MAXIMUM_WAIT_OBJECTS 0
+# endif /* !defined MAXIMUM_WAIT_OBJECTS */
+# if !defined (FILE_FLAG_OVERLAPPED)
+# define FILE_FLAG_OVERLAPPED 0
+# endif /* !defined FILE_FLAG_OVERLAPPED */
+# if !defined (FILE_FLAG_SEQUENTIAL_SCAN)
+# define FILE_FLAG_SEQUENTIAL_SCAN 0
+# endif /* !defined FILE_FLAG_SEQUENTIAL_SCAN */
+
+struct ACE_OVERLAPPED
+{
+ u_long Internal;
+ u_long InternalHigh;
+ u_long Offset;
+ u_long OffsetHigh;
+ ACE_HANDLE hEvent;
+};
+
+# if !defined (USER_INCLUDE_SYS_TIME_TM)
+# if defined (ACE_PSOS_DIAB_PPC)
+typedef struct timespec timespec_t;
+# else /* ! defined (ACE_PSOS_DIAB_PPC) */
+typedef struct timespec
+{
+ time_t tv_sec; // Seconds
+ long tv_nsec; // Nanoseconds
+} timespec_t;
+# endif /* defined (ACE_PSOS_DIAB_PPC) */
+# endif /* !defined (USER_INCLUDE_SYS_TIME_TM) */
+
+#if defined (ACE_PSOS_HAS_TIME)
+
+// Use pSOS time, wrapped . . .
+class ACE_OS_Export ACE_PSOS_Time_t
+{
+public:
+ /// default ctor: date, time, and ticks all zeroed.
+ ACE_PSOS_Time_t (void);
+
+ /// ctor from a timespec_t
+ ACE_PSOS_Time_t (const timespec_t& t);
+
+ /// type cast operator (to a timespec_t)
+ operator timespec_t ();
+
+ /// static member function to get current system time
+ static u_long get_system_time (ACE_PSOS_Time_t& t);
+
+ /// static member function to set current system time
+ static u_long set_system_time (const ACE_PSOS_Time_t& t);
+
+# if defined (ACE_PSOSIM)
+ /// static member function to initialize system time, using UNIX calls
+ static u_long init_simulator_time (void);
+# endif /* ACE_PSOSIM */
+
+ /// max number of ticks supported in a single system call
+ static const u_long max_ticks;
+private:
+ // = Constants for prying info out of the pSOS time encoding.
+ static const u_long year_mask;
+ static const u_long month_mask;
+ static const u_long day_mask;
+ static const u_long hour_mask;
+ static const u_long minute_mask;
+ static const u_long second_mask;
+ static const int year_shift;
+ static const int month_shift;
+ static const int hour_shift;
+ static const int minute_shift;
+ static const int year_origin;
+ static const int month_origin;
+
+ // error codes
+ static const u_long err_notime; // system time not set
+ static const u_long err_illdate; // date out of range
+ static const u_long err_illtime; // time out of range
+ static const u_long err_illticks; // ticks out of range
+
+ /// date : year in bits 31-16, month in bits 15-8, day in bits 7-0
+ u_long date_;
+
+ /// time : hour in bits 31-16, minutes in bits 15-8, seconds in bits 7-0
+ u_long time_;
+
+ /// ticks: number of system clock ticks (KC_TICKS2SEC-1 max)
+ u_long ticks_;
+} ;
+#endif /* ACE_PSOS_HAS_TIME */
+
+# endif /* defined (ACE_PSOS) */
+
+# if defined (ACE_HAS_CHARPTR_SPRINTF)
+# define ACE_SPRINTF_ADAPTER(X) ::strlen (X)
+# else
+# define ACE_SPRINTF_ADAPTER(X) X
+# endif /* ACE_HAS_CHARPTR_SPRINTF */
+
+// Default address for shared memory mapped files and SYSV shared memory
+// (defaults to 64 M).
+# if !defined (ACE_DEFAULT_BASE_ADDR)
+# define ACE_DEFAULT_BASE_ADDR ((char *) (64 * 1024 * 1024))
+# endif /* ACE_DEFAULT_BASE_ADDR */
+
+
+// This fudge factor can be overriden for timers that need it, such as on
+// Solaris, by defining the ACE_TIMER_SKEW symbol in the appropriate config
+// header.
+#if !defined (ACE_TIMER_SKEW)
+# define ACE_TIMER_SKEW 0
+#endif /* ACE_TIMER_SKEW */
+
+// This needs to go here *first* to avoid problems with AIX.
+# if defined (ACE_HAS_PTHREADS)
+extern "C" {
+# define ACE_DONT_INCLUDE_ACE_SIGNAL_H
+# include /**/ <signal.h>
+# undef ACE_DONT_INCLUDE_ACE_SIGNAL_H
+# include /**/ <pthread.h>
+# if defined (DIGITAL_UNIX)
+# define pthread_self __pthread_self
+extern "C" pthread_t pthread_self (void);
+# endif /* DIGITAL_UNIX */
+}
+# if defined (HPUX_10)
+// HP-UX 10 needs to see cma_sigwait, and since _CMA_NOWRAPPERS_ is defined,
+// this header does not get included from pthreads.h.
+# include /**/ <dce/cma_sigwait.h>
+# endif /* HPUX_10 */
+# endif /* ACE_HAS_PTHREADS */
+
+// There are a lot of threads-related macro definitions in the config files.
+// They came in at different times and from different places and platform
+// requirements as threads evolved. They are probably not all needed - some
+// overlap or are otherwise confused. This is an attempt to start
+// straightening them out.
+# if defined (ACE_HAS_PTHREADS_STD) /* POSIX.1c threads (pthreads) */
+ // ... and 2-parameter asctime_r and ctime_r
+# if !defined (ACE_HAS_2_PARAM_ASCTIME_R_AND_CTIME_R) && \
+ !defined (ACE_HAS_STHREADS)
+# define ACE_HAS_2_PARAM_ASCTIME_R_AND_CTIME_R
+# endif
+# endif /* ACE_HAS_PTHREADS_STD */
+
+
+
+// By default we perform no tracing on the OS layer, otherwise the
+// coupling between the OS layer and Log_Msg is too tight. But the
+// application can override the default if they wish to.
+# if !defined(ACE_OS_TRACE)
+# define ACE_OS_TRACE(X)
+# endif /* ACE_OS_TRACE */
+
+# if !defined (ACE_HAS_WINCE) && !defined (ACE_PSOS_DIAB_MIPS)
+# include /**/ <time.h>
+# if defined (__Lynx__)
+# include /**/ <st.h>
+# include /**/ <sem.h>
+# endif /* __Lynx__ */
+# endif /* ACE_HAS_WINCE ACE_PSOS_DIAB_MIPS */
+
+# if defined (ACE_LACKS_SYSTIME_H)
+// Some platforms may need to include this, but I suspect that most
+// will get it from <time.h>
+# if defined (VXWORKS)
+# include /**/ <sys/times.h>
+# else
+# include /**/ <sys/time.h>
+# endif /* VXWORKS */
+# endif /* ACE_LACKS_SYSTIME_H */
+
+# if defined (ACE_USES_STD_NAMESPACE_FOR_STDC_LIB) && \
+ (ACE_USES_STD_NAMESPACE_FOR_STDC_LIB != 0)
+using std::time_t;
+using std::tm;
+# if defined (ACE_WIN32)
+using std::_timezone;
+# else
+using std::timezone;
+# endif
+using std::difftime;
+# endif /* ACE_USES_STD_NAMESPACE_FOR_STDC_LIB */
+
+# if !defined (ACE_HAS_POSIX_TIME) && !defined (ACE_PSOS)
+// Definition per POSIX.
+typedef struct timespec
+{
+ time_t tv_sec; // Seconds
+ long tv_nsec; // Nanoseconds
+} timespec_t;
+# elif defined (ACE_HAS_BROKEN_POSIX_TIME)
+// OSF/1 defines struct timespec in <sys/timers.h> - Tom Marrs
+# include /**/ <sys/timers.h>
+# endif /* !ACE_HAS_POSIX_TIME */
+
+# if defined(ACE_LACKS_TIMESPEC_T)
+typedef struct timespec timespec_t;
+# endif /* ACE_LACKS_TIMESPEC_T */
+
+# if !defined (ACE_HAS_CLOCK_GETTIME) && !(defined (_CLOCKID_T_) || defined (_CLOCKID_T))
+typedef int clockid_t;
+# if !defined (CLOCK_REALTIME)
+# define CLOCK_REALTIME 0
+# endif /* CLOCK_REALTIME */
+# endif /* ! ACE_HAS_CLOCK_GETTIME && ! _CLOCKID_T_ */
+
+// -------------------------------------------------------------------
+// These forward declarations are only used to circumvent a bug in
+// MSVC 6.0 compiler. They shouldn't cause any problem for other
+// compilers and they can be removed once MS release a SP that contains
+// the fix.
+class ACE_Time_Value;
+ACE_OS_Export ACE_Time_Value operator + (const ACE_Time_Value &tv1,
+ const ACE_Time_Value &tv2);
+
+ACE_OS_Export ACE_Time_Value operator - (const ACE_Time_Value &tv1,
+ const ACE_Time_Value &tv2);
+
+// This forward declaration is needed by the set() and FILETIME() functions
+#if defined (ACE_LACKS_LONGLONG_T)
+ class ACE_Export ACE_U_LongLong;
+#endif //ghs
+// -------------------------------------------------------------------
+
+/**
+ * @class ACE_Time_Value
+ *
+ * @brief Operations on "timeval" structures, which express time in <secs> and <usecs>.
+ *
+ * This class centralizes all the time related processing in
+ * ACE. These timers are typically used in conjunction with OS
+ * mechanisms like <select>, <poll>, or <cond_timedwait>.
+ * <ACE_Time_Value> makes the use of these mechanisms portable
+ * across OS platforms,
+ */
+class ACE_OS_Export ACE_Time_Value
+{
+public:
+ // = Useful constants.
+
+ /// Constant "0".
+ static const ACE_Time_Value zero;
+
+ /**
+ * Constant for maximum time representable. Note that this time is
+ * not intended for use with <select> or other calls that may have
+ * *their own* implementation-specific maximum time representations.
+ * Its primary use is in time computations such as those used by the
+ * dynamic subpriority strategies in the <ACE_Dynamic_Message_Queue>
+ * class.
+ */
+ static const ACE_Time_Value max_time;
+
+ // = Initialization methods.
+
+ /// Default Constructor.
+ ACE_Time_Value (void);
+
+ /// Constructor.
+ ACE_Time_Value (long sec, long usec = 0);
+
+ // = Methods for converting to/from various time formats.
+ /// Construct the <ACE_Time_Value> from a <timeval>.
+ ACE_Time_Value (const struct timeval &t);
+
+ /// Initializes the <ACE_Time_Value> object from a <timespec_t>.
+ ACE_Time_Value (const timespec_t &t);
+
+ /// Copy constructor.
+ ACE_Time_Value (const ACE_Time_Value &tv);
+
+# if defined (ACE_WIN32)
+ /// Initializes the ACE_Time_Value object from a Win32 FILETIME
+ ACE_Time_Value (const FILETIME &ft);
+# endif /* ACE_WIN32 */
+
+ /// Construct a <Time_Value> from two <long>s.
+ void set (long sec, long usec);
+
+ /// Construct a <Time_Value> from a <double>, which is assumed to be
+ /// in second format, with any remainder treated as microseconds.
+ void set (double d);
+
+ /// Construct a <Time_Value> from a <timeval>.
+ void set (const timeval &t);
+
+ /// Initializes the <Time_Value> object from a <timespec_t>.
+ void set (const timespec_t &t);
+
+# if defined (ACE_WIN32)
+ /// Initializes the <Time_Value> object from a <timespec_t>.
+ void set (const FILETIME &ft);
+# endif /* ACE_WIN32 */
+
+ /// Converts from <Time_Value> format into milli-seconds format.
+ long msec (void) const;
+
+ /// Converts from milli-seconds format into <Time_Value> format.
+ void msec (long);
+
+ /// Returns the value of the object as a <timespec_t>.
+ operator timespec_t () const;
+
+ /// Returns the value of the object as a <timeval>.
+ operator timeval () const;
+
+ /// Returns a pointer to the object as a <timeval>.
+ operator const timeval *() const;
+
+# if defined (ACE_WIN32)
+ /// Returns the value of the object as a Win32 FILETIME.
+ operator FILETIME () const;
+# endif /* ACE_WIN32 */
+
+ // = The following are accessor/mutator methods.
+
+ /// Get seconds.
+ long sec (void) const;
+
+ /// Set seconds.
+ void sec (long sec);
+
+ /// Get microseconds.
+ long usec (void) const;
+
+ /// Set microseconds.
+ void usec (long usec);
+
+ // = The following arithmetic methods operate on <Time_Value>s.
+
+ /// Add <tv> to this.
+ ACE_Time_Value &operator += (const ACE_Time_Value &tv);
+
+ /// Subtract <tv> to this.
+ ACE_Time_Value &operator -= (const ACE_Time_Value &tv);
+
+ /// Multiply the time value by the <d> factor, which must be >= 0.
+ ACE_Time_Value &operator *= (double d);
+
+ /// Increment microseconds (the only reason this is here is
+ /// to allow the use of ACE_Atomic_Op with ACE_Time_Value).
+ ACE_Time_Value operator++ (int); // Postfix advance
+ ACE_Time_Value &operator++ (void); // Prefix advance
+
+ /// Decrement microseconds (the only reason this is here is
+ /// to allow the use of ACE_Atomic_Op with ACE_Time_Value).
+ ACE_Time_Value operator-- (int); // Postfix dec
+ ACE_Time_Value &operator-- (void); // Prefix dec
+
+ /// Adds two ACE_Time_Value objects together, returns the sum.
+ friend ACE_OS_Export ACE_Time_Value operator + (const ACE_Time_Value &tv1,
+ const ACE_Time_Value &tv2);
+
+ /// Subtracts two ACE_Time_Value objects, returns the difference.
+ friend ACE_OS_Export ACE_Time_Value operator - (const ACE_Time_Value &tv1,
+ const ACE_Time_Value &tv2);
+
+ /// True if tv1 < tv2.
+ friend ACE_OS_Export int operator < (const ACE_Time_Value &tv1,
+ const ACE_Time_Value &tv2);
+
+ /// True if tv1 > tv2.
+ friend ACE_OS_Export int operator > (const ACE_Time_Value &tv1,
+ const ACE_Time_Value &tv2);
+
+ /// True if tv1 <= tv2.
+ friend ACE_OS_Export int operator <= (const ACE_Time_Value &tv1,
+ const ACE_Time_Value &tv2);
+
+ /// True if tv1 >= tv2.
+ friend ACE_OS_Export int operator >= (const ACE_Time_Value &tv1,
+ const ACE_Time_Value &tv2);
+
+ /// True if tv1 == tv2.
+ friend ACE_OS_Export int operator == (const ACE_Time_Value &tv1,
+ const ACE_Time_Value &tv2);
+
+ /// True if tv1 != tv2.
+ friend ACE_OS_Export int operator != (const ACE_Time_Value &tv1,
+ const ACE_Time_Value &tv2);
+
+ /// Dump the state of an object.
+ void dump (void) const;
+
+# if defined (ACE_WIN32)
+ /// Const time difference between FILETIME and POSIX time.
+# if defined (ACE_LACKS_LONGLONG_T)
+ static const ACE_U_LongLong FILETIME_to_timval_skew;
+# else
+ static const DWORDLONG FILETIME_to_timval_skew;
+# endif // ACE_LACKS_LONGLONG_T
+# endif /* ACE_WIN32 */
+
+private:
+ /// Put the timevalue into a canonical form.
+ void normalize (void);
+
+ /// Store the values as a <timeval>.
+ timeval tv_;
+};
+
+/**
+ * @class ACE_Countdown_Time
+ *
+ * @brief Keeps track of the amount of elapsed time.
+ *
+ * This class has a side-effect on the <max_wait_time> -- every
+ * time the <stop> method is called the <max_wait_time> is
+ * updated.
+ */
+class ACE_OS_Export ACE_Countdown_Time
+{
+public:
+ // = Initialization and termination methods.
+ /// Cache the <max_wait_time> and call <start>.
+ ACE_Countdown_Time (ACE_Time_Value *max_wait_time);
+
+ /// Call <stop>.
+ ~ACE_Countdown_Time (void);
+
+ /// Cache the current time and enter a start state.
+ int start (void);
+
+ /// Subtract the elapsed time from max_wait_time_ and enter a stopped
+ /// state.
+ int stop (void);
+
+ /// Calls stop and then start. max_wait_time_ is modified by the
+ /// call to stop.
+ int update (void);
+
+private:
+ /// Maximum time we were willing to wait.
+ ACE_Time_Value *max_wait_time_;
+
+ /// Beginning of the start time.
+ ACE_Time_Value start_time_;
+
+ /// Keeps track of whether we've already been stopped.
+ int stopped_;
+};
+
+# if defined (ACE_HAS_USING_KEYWORD)
+# define ACE_USING using
+# else
+# define ACE_USING
+# endif /* ACE_HAS_USING_KEYWORD */
+
+# if defined (ACE_HAS_TYPENAME_KEYWORD)
+# define ACE_TYPENAME typename
+# else
+# define ACE_TYPENAME
+# endif /* ACE_HAS_TYPENAME_KEYWORD */
+
+# if defined (ACE_HAS_STD_TEMPLATE_SPECIALIZATION)
+# define ACE_TEMPLATE_SPECIALIZATION template<>
+# else
+# define ACE_TEMPLATE_SPECIALIZATION
+# endif /* ACE_HAS_STD_TEMPLATE_SPECIALIZATION */
+
+# if defined (ACE_HAS_STD_TEMPLATE_METHOD_SPECIALIZATION)
+# define ACE_TEMPLATE_METHOD_SPECIALIZATION template<>
+# else
+# define ACE_TEMPLATE_METHOD_SPECIALIZATION
+# endif /* ACE_HAS_STD_TEMPLATE_SPECIALIZATION */
+
+// The following is necessary since many C++ compilers don't support
+// typedef'd types inside of classes used as formal template
+// arguments... ;-(. Luckily, using the C++ preprocessor I can hide
+// most of this nastiness!
+
+# if defined (ACE_HAS_TEMPLATE_TYPEDEFS)
+
+// Handle ACE_Message_Queue.
+# define ACE_SYNCH_DECL class _ACE_SYNCH
+# define ACE_SYNCH_USE _ACE_SYNCH
+# define ACE_SYNCH_MUTEX_T ACE_TYPENAME _ACE_SYNCH::MUTEX
+# define ACE_SYNCH_CONDITION_T ACE_TYPENAME _ACE_SYNCH::CONDITION
+# define ACE_SYNCH_SEMAPHORE_T ACE_TYPENAME _ACE_SYNCH::SEMAPHORE
+
+// Handle ACE_Malloc*
+# define ACE_MEM_POOL_1 class _ACE_MEM_POOL
+# define ACE_MEM_POOL_2 _ACE_MEM_POOL
+# define ACE_MEM_POOL _ACE_MEM_POOL
+# define ACE_MEM_POOL_OPTIONS ACE_TYPENAME _ACE_MEM_POOL::OPTIONS
+
+// Handle ACE_Svc_Handler
+# define ACE_PEER_STREAM_1 class _ACE_PEER_STREAM
+# define ACE_PEER_STREAM_2 _ACE_PEER_STREAM
+# define ACE_PEER_STREAM _ACE_PEER_STREAM
+# define ACE_PEER_STREAM_ADDR ACE_TYPENAME _ACE_PEER_STREAM::PEER_ADDR
+
+// Handle ACE_Acceptor
+# define ACE_PEER_ACCEPTOR_1 class _ACE_PEER_ACCEPTOR
+# define ACE_PEER_ACCEPTOR_2 _ACE_PEER_ACCEPTOR
+# define ACE_PEER_ACCEPTOR _ACE_PEER_ACCEPTOR
+# define ACE_PEER_ACCEPTOR_ADDR ACE_TYPENAME _ACE_PEER_ACCEPTOR::PEER_ADDR
+
+// Handle ACE_Connector
+# define ACE_PEER_CONNECTOR_1 class _ACE_PEER_CONNECTOR
+# define ACE_PEER_CONNECTOR_2 _ACE_PEER_CONNECTOR
+# define ACE_PEER_CONNECTOR _ACE_PEER_CONNECTOR
+# define ACE_PEER_CONNECTOR_ADDR ACE_TYPENAME _ACE_PEER_CONNECTOR::PEER_ADDR
+# if !defined(ACE_HAS_TYPENAME_KEYWORD)
+# define ACE_PEER_CONNECTOR_ADDR_ANY ACE_PEER_CONNECTOR_ADDR::sap_any
+# else
+ //
+ // If the compiler supports 'typename' we cannot use
+ //
+ // PEER_CONNECTOR::PEER_ADDR::sap_any
+ //
+ // because PEER_CONNECTOR::PEER_ADDR is not considered a type. But:
+ //
+ // typename PEER_CONNECTOR::PEER_ADDR::sap_any
+ //
+ // will not work either, because now we are declaring sap_any a
+ // type, further:
+ //
+ // (typename PEER_CONNECTOR::PEER_ADDR)::sap_any
+ //
+ // is considered a casting expression. All I can think of is using a
+ // typedef, I tried PEER_ADDR but that was a source of trouble on
+ // some platforms. I will try:
+ //
+# define ACE_PEER_CONNECTOR_ADDR_ANY ACE_PEER_ADDR_TYPEDEF::sap_any
+# endif /* ACE_HAS_TYPENAME_KEYWORD */
+
+// Handle ACE_SOCK_*
+# define ACE_SOCK_ACCEPTOR ACE_SOCK_Acceptor
+# define ACE_SOCK_CONNECTOR ACE_SOCK_Connector
+# define ACE_SOCK_STREAM ACE_SOCK_Stream
+
+// Handle ACE_MEM_*
+# define ACE_MEM_ACCEPTOR ACE_MEM_Acceptor
+# define ACE_MEM_CONNECTOR ACE_MEM_Connector
+# define ACE_MEM_STREAM ACE_MEM_Stream
+
+// Handle ACE_LSOCK_*
+# define ACE_LSOCK_ACCEPTOR ACE_LSOCK_Acceptor
+# define ACE_LSOCK_CONNECTOR ACE_LSOCK_Connector
+# define ACE_LSOCK_STREAM ACE_LSOCK_Stream
+
+// Handle ACE_TLI_*
+# define ACE_TLI_ACCEPTOR ACE_TLI_Acceptor
+# define ACE_TLI_CONNECTOR ACE_TLI_Connector
+# define ACE_TLI_STREAM ACE_TLI_Stream
+
+// Handle ACE_SPIPE_*
+# define ACE_SPIPE_ACCEPTOR ACE_SPIPE_Acceptor
+# define ACE_SPIPE_CONNECTOR ACE_SPIPE_Connector
+# define ACE_SPIPE_STREAM ACE_SPIPE_Stream
+
+// Handle ACE_UPIPE_*
+# define ACE_UPIPE_ACCEPTOR ACE_UPIPE_Acceptor
+# define ACE_UPIPE_CONNECTOR ACE_UPIPE_Connector
+# define ACE_UPIPE_STREAM ACE_UPIPE_Stream
+
+// Handle ACE_FILE_*
+# define ACE_FILE_CONNECTOR ACE_FILE_Connector
+# define ACE_FILE_STREAM ACE_FILE_IO
+
+// Handle ACE_*_Memory_Pool.
+# define ACE_MMAP_MEMORY_POOL ACE_MMAP_Memory_Pool
+# define ACE_LITE_MMAP_MEMORY_POOL ACE_Lite_MMAP_Memory_Pool
+# define ACE_SBRK_MEMORY_POOL ACE_Sbrk_Memory_Pool
+# define ACE_SHARED_MEMORY_POOL ACE_Shared_Memory_Pool
+# define ACE_LOCAL_MEMORY_POOL ACE_Local_Memory_Pool
+# define ACE_PAGEFILE_MEMORY_POOL ACE_Pagefile_Memory_Pool
+
+# else /* TEMPLATES are broken in some form or another (i.e., most C++ compilers) */
+
+// Handle ACE_Message_Queue.
+# if defined (ACE_HAS_OPTIMIZED_MESSAGE_QUEUE)
+# define ACE_SYNCH_DECL class _ACE_SYNCH_MUTEX_T, class _ACE_SYNCH_CONDITION_T, class _ACE_SYNCH_SEMAPHORE_T
+# define ACE_SYNCH_USE _ACE_SYNCH_MUTEX_T, _ACE_SYNCH_CONDITION_T, _ACE_SYNCH_SEMAPHORE_T
+# else
+# define ACE_SYNCH_DECL class _ACE_SYNCH_MUTEX_T, class _ACE_SYNCH_CONDITION_T
+# define ACE_SYNCH_USE _ACE_SYNCH_MUTEX_T, _ACE_SYNCH_CONDITION_T
+# endif /* ACE_HAS_OPTIMIZED_MESSAGE_QUEUE */
+# define ACE_SYNCH_MUTEX_T _ACE_SYNCH_MUTEX_T
+# define ACE_SYNCH_CONDITION_T _ACE_SYNCH_CONDITION_T
+# define ACE_SYNCH_SEMAPHORE_T _ACE_SYNCH_SEMAPHORE_T
+
+// Handle ACE_Malloc*
+# define ACE_MEM_POOL_1 class _ACE_MEM_POOL, class _ACE_MEM_POOL_OPTIONS
+# define ACE_MEM_POOL_2 _ACE_MEM_POOL, _ACE_MEM_POOL_OPTIONS
+# define ACE_MEM_POOL _ACE_MEM_POOL
+# define ACE_MEM_POOL_OPTIONS _ACE_MEM_POOL_OPTIONS
+
+// Handle ACE_Svc_Handler
+# define ACE_PEER_STREAM_1 class _ACE_PEER_STREAM, class _ACE_PEER_ADDR
+# define ACE_PEER_STREAM_2 _ACE_PEER_STREAM, _ACE_PEER_ADDR
+# define ACE_PEER_STREAM _ACE_PEER_STREAM
+# define ACE_PEER_STREAM_ADDR _ACE_PEER_ADDR
+
+// Handle ACE_Acceptor
+# define ACE_PEER_ACCEPTOR_1 class _ACE_PEER_ACCEPTOR, class _ACE_PEER_ADDR
+# define ACE_PEER_ACCEPTOR_2 _ACE_PEER_ACCEPTOR, _ACE_PEER_ADDR
+# define ACE_PEER_ACCEPTOR _ACE_PEER_ACCEPTOR
+# define ACE_PEER_ACCEPTOR_ADDR _ACE_PEER_ADDR
+
+// Handle ACE_Connector
+# define ACE_PEER_CONNECTOR_1 class _ACE_PEER_CONNECTOR, class _ACE_PEER_ADDR
+# define ACE_PEER_CONNECTOR_2 _ACE_PEER_CONNECTOR, _ACE_PEER_ADDR
+# define ACE_PEER_CONNECTOR _ACE_PEER_CONNECTOR
+# define ACE_PEER_CONNECTOR_ADDR _ACE_PEER_ADDR
+# define ACE_PEER_CONNECTOR_ADDR_ANY ACE_PEER_CONNECTOR_ADDR::sap_any
+
+// Handle ACE_SOCK_*
+# define ACE_SOCK_ACCEPTOR ACE_SOCK_Acceptor, ACE_INET_Addr
+# define ACE_SOCK_CONNECTOR ACE_SOCK_Connector, ACE_INET_Addr
+# define ACE_SOCK_STREAM ACE_SOCK_Stream, ACE_INET_Addr
+
+// Handle ACE_MEM_*
+# define ACE_MEM_ACCEPTOR ACE_MEM_Acceptor, ACE_MEM_Addr
+# define ACE_MEM_CONNECTOR ACE_MEM_Connector, ACE_INET_Addr
+# define ACE_MEM_STREAM ACE_MEM_Stream, ACE_INET_Addr
+
+// Handle ACE_LSOCK_*
+# define ACE_LSOCK_ACCEPTOR ACE_LSOCK_Acceptor, ACE_UNIX_Addr
+# define ACE_LSOCK_CONNECTOR ACE_LSOCK_Connector, ACE_UNIX_Addr
+# define ACE_LSOCK_STREAM ACE_LSOCK_Stream, ACE_UNIX_Addr
+
+// Handle ACE_TLI_*
+# define ACE_TLI_ACCEPTOR ACE_TLI_Acceptor, ACE_INET_Addr
+# define ACE_TLI_CONNECTOR ACE_TLI_Connector, ACE_INET_Addr
+# define ACE_TLI_STREAM ACE_TLI_Stream, ACE_INET_Addr
+
+// Handle ACE_SPIPE_*
+# define ACE_SPIPE_ACCEPTOR ACE_SPIPE_Acceptor, ACE_SPIPE_Addr
+# define ACE_SPIPE_CONNECTOR ACE_SPIPE_Connector, ACE_SPIPE_Addr
+# define ACE_SPIPE_STREAM ACE_SPIPE_Stream, ACE_SPIPE_Addr
+
+// Handle ACE_UPIPE_*
+# define ACE_UPIPE_ACCEPTOR ACE_UPIPE_Acceptor, ACE_SPIPE_Addr
+# define ACE_UPIPE_CONNECTOR ACE_UPIPE_Connector, ACE_SPIPE_Addr
+# define ACE_UPIPE_STREAM ACE_UPIPE_Stream, ACE_SPIPE_Addr
+
+// Handle ACE_FILE_*
+# define ACE_FILE_CONNECTOR ACE_FILE_Connector, ACE_FILE_Addr
+# define ACE_FILE_STREAM ACE_FILE_IO, ACE_FILE_Addr
+
+// Handle ACE_*_Memory_Pool.
+# define ACE_MMAP_MEMORY_POOL ACE_MMAP_Memory_Pool, ACE_MMAP_Memory_Pool_Options
+# define ACE_LITE_MMAP_MEMORY_POOL ACE_Lite_MMAP_Memory_Pool, ACE_MMAP_Memory_Pool_Options
+# define ACE_SBRK_MEMORY_POOL ACE_Sbrk_Memory_Pool, ACE_Sbrk_Memory_Pool_Options
+# define ACE_SHARED_MEMORY_POOL ACE_Shared_Memory_Pool, ACE_Shared_Memory_Pool_Options
+# define ACE_LOCAL_MEMORY_POOL ACE_Local_Memory_Pool, ACE_Local_Memory_Pool_Options
+# define ACE_PAGEFILE_MEMORY_POOL ACE_Pagefile_Memory_Pool, ACE_Pagefile_Memory_Pool_Options
+# endif /* ACE_HAS_TEMPLATE_TYPEDEFS */
+
+// These two are only for backward compatibility. You should avoid
+// using them if not necessary.
+# define ACE_SYNCH_1 ACE_SYNCH_DECL
+# define ACE_SYNCH_2 ACE_SYNCH_USE
+
+// For Win32 compatibility...
+# if !defined (ACE_WSOCK_VERSION)
+# define ACE_WSOCK_VERSION 0, 0
+# endif /* ACE_WSOCK_VERSION */
+
+# if defined (ACE_HAS_BROKEN_CTIME)
+# undef ctime
+# endif /* ACE_HAS_BROKEN_CTIME */
+
+/// Service Objects, i.e., objects dynamically loaded via the service
+/// configurator, must provide a destructor function with the
+/// following prototype to perform object cleanup.
+extern "C" {
+typedef void (*ACE_Service_Object_Exterminator)(void *);
+}
+
+/** @name Service Configurator macros
+ *
+ * The following macros are used to define helper objects used in
+ * ACE's Service Configurator. This is an implementation of the
+ * Service Configurator pattern:
+ *
+ * http://www.cs.wustl.edu/~schmidt/PDF/SvcConf.pdf
+ *
+ * The intent of this pattern is to allow developers to dynamically
+ * load and configure services into a system. With a little help from
+ * this macros statically linked services can also be dynamically
+ * configured.
+ *
+ * More details about this component are available in the documentation
+ * of the ACE_Service_Configurator class and also
+ * ACE_Dynamic_Service.
+ *
+ * Notice that in all the macros the SERVICE_CLASS parameter must be
+ * the name of a class derived from ACE_Service_Object.
+ */
+//@{
+/// Declare a the data structure required to register a statically
+/// linked service into the service configurator.
+/**
+ * The macro should be used in the header file where the service is
+ * declared, its only argument is usually the name of the class that
+ * implements the service.
+ *
+ * @param SERVICE_CLASS The name of the class implementing the
+ * service.
+ */
+# define ACE_STATIC_SVC_DECLARE(SERVICE_CLASS) \
+extern ACE_Static_Svc_Descriptor ace_svc_desc_##SERVICE_CLASS ;
+
+/// As ACE_STATIC_SVC_DECLARE, but using an export macro for NT
+/// compilers.
+/**
+ * NT compilers require the use of explicit directives to export and
+ * import symbols from a DLL. If you need to define a service in a
+ * dynamic library you should use this version instead.
+ * Normally ACE uses a macro to inject the correct export/import
+ * directives on NT. Naturally it also the macro expands to a blank
+ * on platforms that do not require such directives.
+ * The first argument (EXPORT_NAME) is the prefix for this export
+ * macro, the full name is formed by appending _Export.
+ * ACE provides tools to generate header files that define the macro
+ * correctly on all platforms, please see
+ * $ACE_ROOT/bin/generate_export_file.pl
+ *
+ * @param EXPORT_NAME The export macro name prefix.
+ * @param SERVICE_CLASS The name of the class implementing the service.
+ */
+#define ACE_STATIC_SVC_DECLARE_EXPORT(EXPORT_NAME,SERVICE_CLASS) \
+extern EXPORT_NAME##_Export ACE_Static_Svc_Descriptor ace_svc_desc_##SERVICE_CLASS;
+
+/// Define the data structure used to register a statically linked
+/// service into the Service Configurator.
+/**
+ * The service configurator requires several arguments to build and
+ * control an statically linked service, including its name, the
+ * factory function used to construct the service, and some flags.
+ * All those parameters are configured in a single structure, an
+ * instance of this structure is statically initialized using the
+ * following macro.
+ *
+ * @param SERVICE_CLASS The name of the class that implements the
+ * service, must derive from ACE_Service_Configurator.
+ * @param NAME The name for this service, this name is used by the
+ * service configurator to match configuration options provided in
+ * the svc.conf file.
+ * @param TYPE The type of object. Objects can be streams or service
+ * objects. Please read the ACE_Service_Configurator and ASX
+ * documentation for more details.
+ * @param FN The name of the factory function, usually the
+ * ACE_SVC_NAME macro can be used to generate the name. The
+ * factory function is often defined using ACE_FACTORY_DECLARE and
+ * ACE_FACTORY_DEFINE.
+ * @param FLAGS Flags to control the ownership and lifecycle of the
+ * object. Please read the ACE_Service_Configurator documentation
+ * for more details.
+ * @param ACTIVE If not zero then a thread will be dedicate to the
+ * service. Please read the ACE_Service_Configurator documentation
+ * for more details.
+ */
+#define ACE_STATIC_SVC_DEFINE(SERVICE_CLASS, NAME, TYPE, FN, FLAGS, ACTIVE) \
+ACE_Static_Svc_Descriptor ace_svc_desc_##SERVICE_CLASS = { NAME, TYPE, FN, FLAGS, ACTIVE };
+
+/// Automatically register a service with the service configurator
+/**
+ * In some applications the services must be automatically registered
+ * with the service configurator, before main() starts.
+ * The ACE_STATIC_SVC_REQUIRE macro defines a class whose constructor
+ * register the service, it also defines a static instance of that
+ * class to ensure that the service is registered before main.
+ *
+ * On platforms that lack adequate support for static C++ objects the
+ * macro ACE_STATIC_SVC_REGISTER can be used to explicitly register
+ * the service.
+ *
+ * @todo One class per-Service_Object seems wasteful. It should be
+ * possible to define a single class and re-use it for all the
+ * service objects, just by passing the Service_Descriptor as an
+ * argument to the constructor.
+ */
+#if defined(ACE_LACKS_STATIC_CONSTRUCTORS)
+# define ACE_STATIC_SVC_REQUIRE(SERVICE_CLASS)\
+class ACE_Static_Svc_##SERVICE_CLASS {\
+public:\
+ ACE_Static_Svc_##SERVICE_CLASS() { \
+ ACE_Service_Config::static_svcs ()->insert (\
+ &ace_svc_desc_##SERVICE_CLASS); \
+ } \
+};
+#define ACE_STATIC_SVC_REGISTER(SERVICE_CLASS)\
+ACE_Static_Svc_##SERVICE_CLASS ace_static_svc_##SERVICE_CLASS
+
+#else /* !ACE_LACKS_STATIC_CONSTRUCTORS */
+
+# define ACE_STATIC_SVC_REQUIRE(SERVICE_CLASS)\
+class ACE_Static_Svc_##SERVICE_CLASS {\
+public:\
+ ACE_Static_Svc_##SERVICE_CLASS() { \
+ ACE_Service_Config::static_svcs ()->insert (\
+ &ace_svc_desc_##SERVICE_CLASS); \
+ } \
+};\
+static ACE_Static_Svc_##SERVICE_CLASS ace_static_svc_##SERVICE_CLASS;
+#define ACE_STATIC_SVC_REGISTER(SERVICE_CLASS) do {} while (0)
+
+#endif /* !ACE_LACKS_STATIC_CONSTRUCTORS */
+
+/// Declare the factory method used to create dynamically loadable
+/// services.
+/**
+ * Once the service implementation is dynamically loaded the Service
+ * Configurator uses a factory method to create the object.
+ * This macro declares such a factory function with the proper
+ * interface and export macros.
+ * Normally used in the header file that declares the service
+ * implementation.
+ *
+ * @param CLS must match the prefix of the export macro used for this
+ * service.
+ * @param SERVICE_CLASS must match the name of the class that
+ * implements the service.
+ *
+ */
+#define ACE_FACTORY_DECLARE(CLS,SERVICE_CLASS) \
+extern "C" CLS##_Export ACE_Service_Object *\
+_make_##SERVICE_CLASS (ACE_Service_Object_Exterminator *);
+
+/// Define the factory method (and destructor) for a dynamically
+/// loadable service.
+/**
+ * Use with arguments matching ACE_FACTORY_DECLARE.
+ * Normally used in the .cpp file that defines the service
+ * implementation.
+ *
+ * This macro defines both the factory method and the function used to
+ * cleanup the service object.
+ */
+# define ACE_FACTORY_DEFINE(CLS,SERVICE_CLASS) \
+extern "C" void _gobble_##SERVICE_CLASS (void *p) { \
+ ACE_Service_Object *_p = ACE_reinterpret_cast (ACE_Service_Object *, p); \
+ ACE_ASSERT (_p != 0); \
+ delete _p; } \
+extern "C" ACE_Service_Object *\
+_make_##SERVICE_CLASS (ACE_Service_Object_Exterminator *gobbler) \
+{ \
+ ACE_TRACE (#SERVICE_CLASS); \
+ if (gobbler != 0) \
+ *gobbler = (ACE_Service_Object_Exterminator) _gobble_##SERVICE_CLASS; \
+ return new SERVICE_CLASS; \
+}
+
+/// The canonical name for a service factory method
+#define ACE_SVC_NAME(SERVICE_CLASS) _make_##SERVICE_CLASS
+
+/// The canonical way to invoke (i.e. construct) a service factory
+/// method.
+#define ACE_SVC_INVOKE(SERVICE_CLASS) _make_##SERVICE_CLASS (0)
+
+//@}
+
+/** @name Helper macros for services defined in the netsvcs library.
+ *
+ * The ACE services defined in netsvcs use this helper macros for
+ * simplicity.
+ *
+ */
+//@{
+# define ACE_SVC_FACTORY_DECLARE(X) ACE_FACTORY_DECLARE (ACE_Svc, X)
+# define ACE_SVC_FACTORY_DEFINE(X) ACE_FACTORY_DEFINE (ACE_Svc, X)
+//@}
+
+# if defined (ACE_HAS_THREADS) && (defined (ACE_HAS_THREAD_SPECIFIC_STORAGE) || defined (ACE_HAS_TSS_EMULATION))
+# define ACE_TSS_TYPE(T) ACE_TSS< T >
+# if defined (ACE_HAS_BROKEN_CONVERSIONS)
+# define ACE_TSS_GET(I, T) (*(I))
+# else
+# define ACE_TSS_GET(I, T) ((I)->operator T * ())
+# endif /* ACE_HAS_BROKEN_CONVERSIONS */
+# else
+# define ACE_TSS_TYPE(T) T
+# define ACE_TSS_GET(I, T) (I)
+# endif /* ACE_HAS_THREADS && (ACE_HAS_THREAD_SPECIFIC_STORAGE || ACE_HAS_TSS_EMULATIOND) */
+
+# if defined (ACE_LACKS_MODE_MASKS)
+// MODE MASKS
+
+// the following macros are for POSIX conformance.
+
+# if !defined (ACE_HAS_USER_MODE_MASKS)
+# define S_IRWXU 00700 /* read, write, execute: owner. */
+# define S_IRUSR 00400 /* read permission: owner. */
+# define S_IWUSR 00200 /* write permission: owner. */
+# define S_IXUSR 00100 /* execute permission: owner. */
+# endif /* ACE_HAS_USER_MODE_MASKS */
+# define S_IRWXG 00070 /* read, write, execute: group. */
+# define S_IRGRP 00040 /* read permission: group. */
+# define S_IWGRP 00020 /* write permission: group. */
+# define S_IXGRP 00010 /* execute permission: group. */
+# define S_IRWXO 00007 /* read, write, execute: other. */
+# define S_IROTH 00004 /* read permission: other. */
+# define S_IWOTH 00002 /* write permission: other. */
+# define S_IXOTH 00001 /* execute permission: other. */
+
+# endif /* ACE_LACKS_MODE_MASKS */
+
+# if defined (ACE_LACKS_SEMBUF_T)
+struct sembuf
+{
+ unsigned short sem_num; // semaphore #
+ short sem_op; // semaphore operation
+ short sem_flg; // operation flags
+};
+# endif /* ACE_LACKS_SEMBUF_T */
+
+# if defined (ACE_LACKS_MSGBUF_T)
+struct msgbuf {};
+# endif /* ACE_LACKS_MSGBUF_T */
+
+# if defined (ACE_LACKS_STRRECVFD)
+struct strrecvfd {};
+# endif /* ACE_LACKS_STRRECVFD */
+
+# if defined (ACE_HAS_PROC_FS)
+# include /**/ <sys/procfs.h>
+# endif /* ACE_HAS_PROC_FS */
+
+# if defined(__rtems__)
+struct iovec {
+ char *iov_base; // Base address.
+ size_t iov_len; // Length.
+};
+# endif
+
+# if defined (ACE_HAS_BROKEN_WRITEV)
+typedef struct iovec ACE_WRITEV_TYPE;
+# else
+typedef const struct iovec ACE_WRITEV_TYPE;
+# endif /* ACE_HAS_BROKEN_WRITEV */
+
+# if defined (ACE_HAS_BROKEN_READV)
+typedef const struct iovec ACE_READV_TYPE;
+# else
+typedef struct iovec ACE_READV_TYPE;
+# endif /* ACE_HAS_BROKEN_READV */
+
+# if defined (ACE_HAS_BROKEN_SETRLIMIT)
+typedef struct rlimit ACE_SETRLIMIT_TYPE;
+# else
+typedef const struct rlimit ACE_SETRLIMIT_TYPE;
+# endif /* ACE_HAS_BROKEN_SETRLIMIT */
+
+# if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0)
+# define ACE_MT(X) X
+# if !defined (_REENTRANT)
+# define _REENTRANT
+# endif /* _REENTRANT */
+# else
+# define ACE_MT(X)
+# endif /* ACE_MT_SAFE */
+
+# if !defined (ACE_DEFAULT_THREAD_PRIORITY)
+# define ACE_DEFAULT_THREAD_PRIORITY (-0x7fffffffL - 1L)
+# endif /* ACE_DEFAULT_THREAD_PRIORITY */
+
+// Convenient macro for testing for deadlock, as well as for detecting
+// when mutexes fail.
+#define ACE_GUARD_ACTION(MUTEX, OBJ, LOCK, ACTION, REACTION) \
+ ACE_Guard< MUTEX > OBJ (LOCK); \
+ if (OBJ.locked () != 0) { ACTION; } \
+ else { REACTION; }
+#define ACE_GUARD_REACTION(MUTEX, OBJ, LOCK, REACTION) \
+ ACE_GUARD_ACTION(MUTEX, OBJ, LOCK, ;, REACTION)
+#define ACE_GUARD(MUTEX, OBJ, LOCK) \
+ ACE_GUARD_REACTION(MUTEX, OBJ, LOCK, return)
+#define ACE_GUARD_RETURN(MUTEX, OBJ, LOCK, RETURN) \
+ ACE_GUARD_REACTION(MUTEX, OBJ, LOCK, return RETURN)
+# define ACE_WRITE_GUARD(MUTEX,OBJ,LOCK) \
+ ACE_Write_Guard< MUTEX > OBJ (LOCK); \
+ if (OBJ.locked () == 0) return;
+# define ACE_WRITE_GUARD_RETURN(MUTEX,OBJ,LOCK,RETURN) \
+ ACE_Write_Guard< MUTEX > OBJ (LOCK); \
+ if (OBJ.locked () == 0) return RETURN;
+# define ACE_READ_GUARD(MUTEX,OBJ,LOCK) \
+ ACE_Read_Guard< MUTEX > OBJ (LOCK); \
+ if (OBJ.locked () == 0) return;
+# define ACE_READ_GUARD_RETURN(MUTEX,OBJ,LOCK,RETURN) \
+ ACE_Read_Guard< MUTEX > OBJ (LOCK); \
+ if (OBJ.locked () == 0) return RETURN;
+
+# if defined (ACE_HAS_PACE) && !defined (ACE_WIN32)
+# include /**/ "pace/semaphore.h"
+# if !defined (SEM_FAILED)
+# define SEM_FAILED ((pace_sem_t *) -1)
+# endif /* !SEM_FAILED */
+
+typedef struct
+{
+ pace_sem_t *sema_;
+ // Pointer to semaphore handle. This is allocated by ACE if we are
+ // working with an unnamed POSIX semaphore or by the OS if we are
+ // working with a named POSIX semaphore.
+
+ char *name_;
+ // Name of the semaphore (if this is non-NULL then this is a named
+ // POSIX semaphore, else its an unnamed POSIX semaphore).
+} ACE_sema_t;
+
+# elif defined (ACE_HAS_POSIX_SEM)
+# include /**/ <semaphore.h>
+# if !defined (SEM_FAILED) && !defined (ACE_LACKS_NAMED_POSIX_SEM)
+# define SEM_FAILED ((sem_t *) -1)
+# endif /* !SEM_FAILED */
+
+typedef struct
+{
+ sem_t *sema_;
+ // Pointer to semaphore handle. This is allocated by ACE if we are
+ // working with an unnamed POSIX semaphore or by the OS if we are
+ // working with a named POSIX semaphore.
+
+ char *name_;
+ // Name of the semaphore (if this is non-NULL then this is a named
+ // POSIX semaphore, else its an unnamed POSIX semaphore).
+
+#if defined (ACE_LACKS_NAMED_POSIX_SEM)
+ int new_sema_;
+ // this->sema_ doesn't always get created dynamically if a platform
+ // doesn't support named posix semaphores. We use this flag to
+ // remember if we need to delete <sema_> or not.
+#endif /* ACE_LACKS_NAMED_POSIX_SEM */
+} ACE_sema_t;
+# endif /* ACE_HAS_PACE && !ACE_WIN32 */
+
+struct cancel_state
+{
+ int cancelstate;
+ // e.g., PTHREAD_CANCEL_ENABLE, PTHREAD_CANCEL_DISABLE,
+ // PTHREAD_CANCELED.
+
+ int canceltype;
+ // e.g., PTHREAD_CANCEL_DEFERRED and PTHREAD_CANCEL_ASYNCHRONOUS.
+};
+
+# if defined (ACE_HAS_WINCE)
+# include /**/ <types.h>
+
+typedef DWORD nlink_t;
+
+// CE's add-on for c-style fstat/stat functionalities. This struct is
+// by no mean complete compared to what you usually find in UNIX
+// platforms. Only members that have direct conversion using Win32's
+// BY_HANDLE_FILE_INFORMATION are defined so that users can discover
+// non-supported members at compile time. Time values are of type
+// ACE_Time_Value for easy comparison.
+
+struct stat
+{
+ // mode_t st_mode; // UNIX styled file attribute
+ // nlink_t st_nlink; // number of hard links
+ ACE_Time_Value st_atime; // time of last access
+ ACE_Time_Value st_mtime; // time of last data modification
+ off_t st_size; // file size, in bytes
+ // u_long st_blksize; // optimal blocksize for I/O
+ // u_long st_flags; // user defined flags for file
+};
+
+# else /* ! ACE_HAS_WINCE */
+# if defined (ACE_LACKS_SYS_TYPES_H)
+# if ! defined (ACE_PSOS)
+ typedef unsigned char u_char;
+ typedef unsigned short u_short;
+ typedef unsigned int u_int;
+ typedef unsigned long u_long;
+
+ typedef unsigned char uchar_t;
+ typedef unsigned short ushort_t;
+ typedef unsigned int uint_t;
+ typedef unsigned long ulong_t;
+# endif /* ! defined (ACE_PSOS) */
+# else
+# include /**/ <sys/types.h>
+# endif /* ACE_LACKS_SYS_TYPES_H */
+
+# if ! defined (ACE_PSOS)
+# include /**/ <sys/stat.h>
+# endif
+# endif /* ACE_HAS_WINCE */
+
+
+#if defined (ACE_HAS_NO_THROW_SPEC)
+# define ACE_THROW_SPEC(X)
+#else
+# if defined (ACE_HAS_EXCEPTIONS)
+# define ACE_THROW_SPEC(X) throw X
+# if defined (ACE_WIN32) && defined(_MSC_VER) && !defined (ghs)
+// @@ MSVC "supports" the keyword but doesn't implement it (Huh?).
+// Therefore, we simply supress the warning for now.
+# pragma warning( disable : 4290 )
+# endif /* ACE_WIN32 */
+# else /* ! ACE_HAS_EXCEPTIONS */
+# define ACE_THROW_SPEC(X)
+# endif /* ! ACE_HAS_EXCEPTIONS */
+#endif /*ACE_HAS_NO_THROW_SPEC*/
+
+#if !defined (ACE_LACKS_UNISTD_H)
+# include /**/ <unistd.h>
+#endif /* ACE_LACKS_UNISTD_H */
+
+#if defined (ACE_HAS_PRIOCNTL)
+ // Need to #include thread.h before #defining THR_BOUND, etc.,
+ // when building without threads on SunOS 5.x.
+# if defined (sun)
+# include /**/ <thread.h>
+# endif /* sun */
+
+ // Need to #include these before #defining USYNC_PROCESS on SunOS 5.x.
+# include /**/ <sys/rtpriocntl.h>
+# include /**/ <sys/tspriocntl.h>
+#endif /* ACE_HAS_PRIOCNTL */
+
+# if defined (ACE_HAS_THREADS)
+
+# if defined (ACE_HAS_STHREADS)
+# include /**/ <synch.h>
+# include /**/ <thread.h>
+# define ACE_SCOPE_PROCESS P_PID
+# define ACE_SCOPE_LWP P_LWPID
+# define ACE_SCOPE_THREAD (ACE_SCOPE_LWP + 1)
+# else
+# define ACE_SCOPE_PROCESS 0
+# define ACE_SCOPE_LWP 1
+# define ACE_SCOPE_THREAD 2
+# endif /* ACE_HAS_STHREADS */
+
+# if !defined (ACE_HAS_PTHREADS)
+# define ACE_SCHED_OTHER 0
+# define ACE_SCHED_FIFO 1
+# define ACE_SCHED_RR 2
+# endif /* ! ACE_HAS_PTHREADS */
+
+# if defined (ACE_HAS_PTHREADS)
+# define ACE_SCHED_OTHER SCHED_OTHER
+# define ACE_SCHED_FIFO SCHED_FIFO
+# define ACE_SCHED_RR SCHED_RR
+
+// Definitions for mapping POSIX pthreads draft 6 into 1003.1c names
+
+# if defined (ACE_HAS_PTHREADS_DRAFT6)
+# define PTHREAD_SCOPE_PROCESS PTHREAD_SCOPE_LOCAL
+# define PTHREAD_SCOPE_SYSTEM PTHREAD_SCOPE_GLOBAL
+# define PTHREAD_CREATE_UNDETACHED 0
+# define PTHREAD_CREATE_DETACHED 1
+# define PTHREAD_CREATE_JOINABLE 0
+# define PTHREAD_EXPLICIT_SCHED 0
+# define PTHREAD_MIN_PRIORITY 0
+# define PTHREAD_MAX_PRIORITY 126
+# endif /* ACE_HAS_PTHREADS_DRAFT6 */
+
+// Definitions for THREAD- and PROCESS-LEVEL priorities...some
+// implementations define these while others don't. In order to
+// further complicate matters, we don't redefine the default (*_DEF)
+// values if they've already been defined, which allows individual
+// programs to have their own ACE-wide "default".
+
+// PROCESS-level values
+# if defined (_POSIX_PRIORITY_SCHEDULING) && \
+ !defined(_UNICOS) && !defined(UNIXWARE_7_1)
+# define ACE_PROC_PRI_FIFO_MIN (sched_get_priority_min(SCHED_FIFO))
+# define ACE_PROC_PRI_RR_MIN (sched_get_priority_min(SCHED_RR))
+# if defined (HPUX)
+ // HP-UX's other is the SCHED_HPUX class, which uses historical
+ // values that have reverse semantics from POSIX (low value is
+ // more important priority). To use these in pthreads calls,
+ // the values need to be converted. The other scheduling classes
+ // don't need this special treatment.
+# define ACE_PROC_PRI_OTHER_MIN \
+ (sched_get_priority_min(SCHED_OTHER))
+# else
+# define ACE_PROC_PRI_OTHER_MIN (sched_get_priority_min(SCHED_OTHER))
+# endif /* HPUX */
+# else /* UNICOS is missing a sched_get_priority_min() implementation,
+ SCO too */
+# define ACE_PROC_PRI_FIFO_MIN 0
+# define ACE_PROC_PRI_RR_MIN 0
+# define ACE_PROC_PRI_OTHER_MIN 0
+# endif
+
+# if defined (_POSIX_PRIORITY_SCHEDULING) && !defined(UNIXWARE_7_1)
+# define ACE_PROC_PRI_FIFO_MAX (sched_get_priority_max(SCHED_FIFO))
+# define ACE_PROC_PRI_RR_MAX (sched_get_priority_max(SCHED_RR))
+# if defined (HPUX)
+# define ACE_PROC_PRI_OTHER_MAX \
+ (sched_get_priority_max(SCHED_OTHER))
+# else
+# define ACE_PROC_PRI_OTHER_MAX (sched_get_priority_max(SCHED_OTHER))
+# endif /* HPUX */
+# else /* SCO missing sched_get_priority_max() implementation */
+# define ACE_PROC_PRI_FIFO_MAX 59
+# define ACE_PROC_PRI_RR_MAX 59
+# define ACE_PROC_PRI_OTHER_MAX 59
+# endif
+
+# if !defined(ACE_PROC_PRI_FIFO_DEF)
+# define ACE_PROC_PRI_FIFO_DEF (ACE_PROC_PRI_FIFO_MIN + (ACE_PROC_PRI_FIFO_MAX - ACE_PROC_PRI_FIFO_MIN)/2)
+# endif
+# if !defined(ACE_PROC_PRI_RR_DEF)
+# define ACE_PROC_PRI_RR_DEF (ACE_PROC_PRI_RR_MIN + (ACE_PROC_PRI_RR_MAX - ACE_PROC_PRI_RR_MIN)/2)
+# endif
+# if !defined(ACE_PROC_PRI_OTHER_DEF)
+# define ACE_PROC_PRI_OTHER_DEF (ACE_PROC_PRI_OTHER_MIN + (ACE_PROC_PRI_OTHER_MAX - ACE_PROC_PRI_OTHER_MIN)/2)
+# endif
+
+// THREAD-level values
+# if defined(PRI_FIFO_MIN) && defined(PRI_FIFO_MAX) && defined(PRI_RR_MIN) && defined(PRI_RR_MAX) && defined(PRI_OTHER_MIN) && defined(PRI_OTHER_MAX)
+# if !defined (ACE_THR_PRI_FIFO_MIN)
+# define ACE_THR_PRI_FIFO_MIN (long) PRI_FIFO_MIN
+# endif /* !ACE_THR_PRI_FIFO_MIN */
+# if !defined (ACE_THR_PRI_FIFO_MAX)
+# define ACE_THR_PRI_FIFO_MAX (long) PRI_FIFO_MAX
+# endif /* !ACE_THR_PRI_FIFO_MAX */
+# if !defined (ACE_THR_PRI_RR_MIN)
+# define ACE_THR_PRI_RR_MIN (long) PRI_RR_MIN
+# endif /* !ACE_THR_PRI_RR_MIN */
+# if !defined (ACE_THR_PRI_RR_MAX)
+# define ACE_THR_PRI_RR_MAX (long) PRI_RR_MAX
+# endif /* !ACE_THR_PRI_RR_MAX */
+# if !defined (ACE_THR_PRI_OTHER_MIN)
+# define ACE_THR_PRI_OTHER_MIN (long) PRI_OTHER_MIN
+# endif /* !ACE_THR_PRI_OTHER_MIN */
+# if !defined (ACE_THR_PRI_OTHER_MAX)
+# define ACE_THR_PRI_OTHER_MAX (long) PRI_OTHER_MAX
+# endif /* !ACE_THR_PRI_OTHER_MAX */
+# elif defined (AIX)
+ // AIX's priority range is 1 (low) to 127 (high). There aren't
+ // any preprocessor macros I can find. PRIORITY_MIN is for
+ // process priorities, as far as I can see, and does not apply
+ // to thread priority. The 1 to 127 range is from the
+ // pthread_attr_setschedparam man page (Steve Huston, 18-May-2001).
+# if !defined (ACE_THR_PRI_FIFO_MIN)
+# define ACE_THR_PRI_FIFO_MIN (long) 1
+# endif /* !ACE_THR_PRI_FIFO_MIN */
+# if !defined (ACE_THR_PRI_FIFO_MAX)
+# define ACE_THR_PRI_FIFO_MAX (long) 127
+# endif /* !ACE_THR_PRI_FIFO_MAX */
+# if !defined (ACE_THR_PRI_RR_MIN)
+# define ACE_THR_PRI_RR_MIN (long) 1
+# endif /* !ACE_THR_PRI_RR_MIN */
+# if !defined (ACE_THR_PRI_RR_MAX)
+# define ACE_THR_PRI_RR_MAX (long) 127
+# endif /* !ACE_THR_PRI_RR_MAX */
+# if !defined (ACE_THR_PRI_OTHER_MIN)
+# define ACE_THR_PRI_OTHER_MIN (long) 1
+# endif /* !ACE_THR_PRI_OTHER_MIN */
+# if !defined (ACE_THR_PRI_OTHER_MAX)
+# define ACE_THR_PRI_OTHER_MAX (long) 127
+# endif /* !ACE_THR_PRI_OTHER_MAX */
+# elif defined (sun)
+# if !defined (ACE_THR_PRI_FIFO_MIN)
+# define ACE_THR_PRI_FIFO_MIN (long) 0
+# endif /* !ACE_THR_PRI_FIFO_MIN */
+# if !defined (ACE_THR_PRI_FIFO_MAX)
+# define ACE_THR_PRI_FIFO_MAX (long) 59
+# endif /* !ACE_THR_PRI_FIFO_MAX */
+# if !defined (ACE_THR_PRI_RR_MIN)
+# define ACE_THR_PRI_RR_MIN (long) 0
+# endif /* !ACE_THR_PRI_RR_MIN */
+# if !defined (ACE_THR_PRI_RR_MAX)
+# define ACE_THR_PRI_RR_MAX (long) 59
+# endif /* !ACE_THR_PRI_RR_MAX */
+# if !defined (ACE_THR_PRI_OTHER_MIN)
+# define ACE_THR_PRI_OTHER_MIN (long) 0
+# endif /* !ACE_THR_PRI_OTHER_MIN */
+# if !defined (ACE_THR_PRI_OTHER_MAX)
+# define ACE_THR_PRI_OTHER_MAX (long) 127
+# endif /* !ACE_THR_PRI_OTHER_MAX */
+# else
+# if !defined (ACE_THR_PRI_FIFO_MIN)
+# define ACE_THR_PRI_FIFO_MIN (long) ACE_PROC_PRI_FIFO_MIN
+# endif /* !ACE_THR_PRI_FIFO_MIN */
+# if !defined (ACE_THR_PRI_FIFO_MAX)
+# define ACE_THR_PRI_FIFO_MAX (long) ACE_PROC_PRI_FIFO_MAX
+# endif /* !ACE_THR_PRI_FIFO_MAX */
+# if !defined (ACE_THR_PRI_RR_MIN)
+# define ACE_THR_PRI_RR_MIN (long) ACE_PROC_PRI_RR_MIN
+# endif /* !ACE_THR_PRI_RR_MIN */
+# if !defined (ACE_THR_PRI_RR_MAX)
+# define ACE_THR_PRI_RR_MAX (long) ACE_PROC_PRI_RR_MAX
+# endif /* !ACE_THR_PRI_RR_MAX */
+# if !defined (ACE_THR_PRI_OTHER_MIN)
+# define ACE_THR_PRI_OTHER_MIN (long) ACE_PROC_PRI_OTHER_MIN
+# endif /* !ACE_THR_PRI_OTHER_MIN */
+# if !defined (ACE_THR_PRI_OTHER_MAX)
+# define ACE_THR_PRI_OTHER_MAX (long) ACE_PROC_PRI_OTHER_MAX
+# endif /* !ACE_THR_PRI_OTHER_MAX */
+# endif
+# if !defined(ACE_THR_PRI_FIFO_DEF)
+# define ACE_THR_PRI_FIFO_DEF ((ACE_THR_PRI_FIFO_MIN + ACE_THR_PRI_FIFO_MAX)/2)
+# endif
+# if !defined(ACE_THR_PRI_RR_DEF)
+# define ACE_THR_PRI_RR_DEF ((ACE_THR_PRI_RR_MIN + ACE_THR_PRI_RR_MAX)/2)
+# endif
+# if !defined(ACE_THR_PRI_OTHER_DEF)
+# define ACE_THR_PRI_OTHER_DEF ((ACE_THR_PRI_OTHER_MIN + ACE_THR_PRI_OTHER_MAX)/2)
+# endif
+
+// Typedefs to help compatibility with Windows NT and Pthreads.
+typedef pthread_t ACE_hthread_t;
+typedef pthread_t ACE_thread_t;
+
+# if defined (ACE_HAS_TSS_EMULATION)
+ typedef pthread_key_t ACE_OS_thread_key_t;
+ typedef u_long ACE_thread_key_t;
+# else /* ! ACE_HAS_TSS_EMULATION */
+ typedef pthread_key_t ACE_thread_key_t;
+# endif /* ! ACE_HAS_TSS_EMULATION */
+
+# if !defined (ACE_LACKS_COND_T)
+typedef pthread_mutex_t ACE_mutex_t;
+typedef pthread_cond_t ACE_cond_t;
+typedef pthread_condattr_t ACE_condattr_t;
+typedef pthread_mutexattr_t ACE_mutexattr_t;
+# endif /* ! ACE_LACKS_COND_T */
+typedef pthread_mutex_t ACE_thread_mutex_t;
+
+# if !defined (PTHREAD_CANCEL_DISABLE)
+# define PTHREAD_CANCEL_DISABLE 0
+# endif /* PTHREAD_CANCEL_DISABLE */
+
+# if !defined (PTHREAD_CANCEL_ENABLE)
+# define PTHREAD_CANCEL_ENABLE 0
+# endif /* PTHREAD_CANCEL_ENABLE */
+
+# if !defined (PTHREAD_CANCEL_DEFERRED)
+# define PTHREAD_CANCEL_DEFERRED 0
+# endif /* PTHREAD_CANCEL_DEFERRED */
+
+# if !defined (PTHREAD_CANCEL_ASYNCHRONOUS)
+# define PTHREAD_CANCEL_ASYNCHRONOUS 0
+# endif /* PTHREAD_CANCEL_ASYNCHRONOUS */
+
+# define THR_CANCEL_DISABLE PTHREAD_CANCEL_DISABLE
+# define THR_CANCEL_ENABLE PTHREAD_CANCEL_ENABLE
+# define THR_CANCEL_DEFERRED PTHREAD_CANCEL_DEFERRED
+# define THR_CANCEL_ASYNCHRONOUS PTHREAD_CANCEL_ASYNCHRONOUS
+
+# if !defined (PTHREAD_CREATE_JOINABLE)
+# if defined (PTHREAD_CREATE_UNDETACHED)
+# define PTHREAD_CREATE_JOINABLE PTHREAD_CREATE_UNDETACHED
+# else
+# define PTHREAD_CREATE_JOINABLE 0
+# endif /* PTHREAD_CREATE_UNDETACHED */
+# endif /* PTHREAD_CREATE_JOINABLE */
+
+# if !defined (PTHREAD_CREATE_DETACHED)
+# define PTHREAD_CREATE_DETACHED 1
+# endif /* PTHREAD_CREATE_DETACHED */
+
+# if !defined (PTHREAD_PROCESS_PRIVATE) && !defined (ACE_HAS_PTHREAD_PROCESS_ENUM)
+# if defined (PTHREAD_MUTEXTYPE_FAST)
+# define PTHREAD_PROCESS_PRIVATE PTHREAD_MUTEXTYPE_FAST
+# else
+# define PTHREAD_PROCESS_PRIVATE 0
+# endif /* PTHREAD_MUTEXTYPE_FAST */
+# endif /* PTHREAD_PROCESS_PRIVATE */
+
+# if !defined (PTHREAD_PROCESS_SHARED) && !defined (ACE_HAS_PTHREAD_PROCESS_ENUM)
+# if defined (PTHREAD_MUTEXTYPE_FAST)
+# define PTHREAD_PROCESS_SHARED PTHREAD_MUTEXTYPE_FAST
+# else
+# define PTHREAD_PROCESS_SHARED 1
+# endif /* PTHREAD_MUTEXTYPE_FAST */
+# endif /* PTHREAD_PROCESS_SHARED */
+
+# if defined (ACE_HAS_PTHREADS_DRAFT4)
+# if defined (PTHREAD_PROCESS_PRIVATE)
+# if !defined (USYNC_THREAD)
+# define USYNC_THREAD PTHREAD_PROCESS_PRIVATE
+# endif /* ! USYNC_THREAD */
+# else
+# if !defined (USYNC_THREAD)
+# define USYNC_THREAD MUTEX_NONRECURSIVE_NP
+# endif /* ! USYNC_THREAD */
+# endif /* PTHREAD_PROCESS_PRIVATE */
+
+# if defined (PTHREAD_PROCESS_SHARED)
+# if !defined (USYNC_PROCESS)
+# define USYNC_PROCESS PTHREAD_PROCESS_SHARED
+# endif /* ! USYNC_PROCESS */
+# else
+# if !defined (USYNC_PROCESS)
+# define USYNC_PROCESS MUTEX_NONRECURSIVE_NP
+# endif /* ! USYNC_PROCESS */
+# endif /* PTHREAD_PROCESS_SHARED */
+# elif !defined (ACE_HAS_STHREADS)
+# if !defined (USYNC_THREAD)
+# define USYNC_THREAD PTHREAD_PROCESS_PRIVATE
+# endif /* ! USYNC_THREAD */
+# if !defined (USYNC_PROCESS)
+# define USYNC_PROCESS PTHREAD_PROCESS_SHARED
+# endif /* ! USYNC_PROCESS */
+# endif /* ACE_HAS_PTHREADS_DRAFT4 */
+
+/* MM-Graz: prevent warnings */
+#undef THR_BOUND
+#undef THR_NEW_LWP
+#undef THR_DETACHED
+#undef THR_SUSPENDED
+#undef THR_DAEMON
+
+# define THR_BOUND 0x00000001
+# if defined (CHORUS)
+# define THR_NEW_LWP 0x00000000
+# else
+# define THR_NEW_LWP 0x00000002
+# endif /* CHORUS */
+# define THR_DETACHED 0x00000040
+# define THR_SUSPENDED 0x00000080
+# define THR_DAEMON 0x00000100
+# define THR_JOINABLE 0x00010000
+# define THR_SCHED_FIFO 0x00020000
+# define THR_SCHED_RR 0x00040000
+# define THR_SCHED_DEFAULT 0x00080000
+
+# if defined (ACE_HAS_IRIX62_THREADS)
+# define THR_SCOPE_SYSTEM 0x00100000
+# else
+# define THR_SCOPE_SYSTEM THR_BOUND
+#endif /*ACE_HAS_IRIX62_THREADS*/
+
+# define THR_SCOPE_PROCESS 0x00200000
+# define THR_INHERIT_SCHED 0x00400000
+# define THR_EXPLICIT_SCHED 0x00800000
+# define THR_SCHED_IO 0x01000000
+
+# if !defined (ACE_HAS_STHREADS)
+# if !defined (ACE_HAS_POSIX_SEM)
+/**
+ * @class ACE_sema_t
+ *
+ * @brief This is used to implement semaphores for platforms that support
+ * POSIX pthreads, but do *not* support POSIX semaphores, i.e.,
+ * it's a different type than the POSIX <sem_t>.
+ */
+class ACE_OS_Export ACE_sema_t
+{
+friend class ACE_OS;
+protected:
+ /// Serialize access to internal state.
+ ACE_mutex_t lock_;
+
+ /// Block until there are no waiters.
+ ACE_cond_t count_nonzero_;
+
+ /// Count of the semaphore.
+ u_long count_;
+
+ /// Number of threads that have called <ACE_OS::sema_wait>.
+ u_long waiters_;
+};
+# endif /* !ACE_HAS_POSIX_SEM */
+
+# if defined (ACE_LACKS_PTHREAD_YIELD) && defined (ACE_HAS_THR_YIELD)
+ // If we are on Solaris we can just reuse the existing
+ // implementations of these synchronization types.
+# if !defined (ACE_LACKS_RWLOCK_T)
+# include /**/ <synch.h>
+typedef rwlock_t ACE_rwlock_t;
+# endif /* !ACE_LACKS_RWLOCK_T */
+# include /**/ <thread.h>
+# endif /* (ACE_LACKS_PTHREAD_YIELD) && defined (ACE_HAS_THR_YIELD) */
+
+# else
+# if !defined (ACE_HAS_POSIX_SEM)
+typedef sema_t ACE_sema_t;
+# endif /* !ACE_HAS_POSIX_SEM */
+# endif /* !ACE_HAS_STHREADS */
+# elif defined (ACE_HAS_STHREADS)
+// Solaris threads, without PTHREADS.
+// Typedefs to help compatibility with Windows NT and Pthreads.
+typedef thread_t ACE_thread_t;
+typedef thread_key_t ACE_thread_key_t;
+typedef mutex_t ACE_mutex_t;
+# if !defined (ACE_LACKS_RWLOCK_T)
+typedef rwlock_t ACE_rwlock_t;
+# endif /* !ACE_LACKS_RWLOCK_T */
+# if !defined (ACE_HAS_POSIX_SEM)
+typedef sema_t ACE_sema_t;
+# endif /* !ACE_HAS_POSIX_SEM */
+
+typedef cond_t ACE_cond_t;
+struct ACE_OS_Export ACE_condattr_t
+{
+ int type;
+};
+struct ACE_OS_Export ACE_mutexattr_t
+{
+ int type;
+};
+typedef ACE_thread_t ACE_hthread_t;
+typedef ACE_mutex_t ACE_thread_mutex_t;
+
+# define THR_CANCEL_DISABLE 0
+# define THR_CANCEL_ENABLE 0
+# define THR_CANCEL_DEFERRED 0
+# define THR_CANCEL_ASYNCHRONOUS 0
+# define THR_JOINABLE 0
+# define THR_SCHED_FIFO 0
+# define THR_SCHED_RR 0
+# define THR_SCHED_DEFAULT 0
+
+# elif defined (ACE_PSOS)
+
+// Some versions of pSOS provide native mutex support. For others,
+// implement ACE_thread_mutex_t and ACE_mutex_t using pSOS semaphores.
+// Either way, the types are all u_longs.
+typedef u_long ACE_mutex_t;
+typedef u_long ACE_thread_mutex_t;
+typedef u_long ACE_thread_t;
+typedef u_long ACE_hthread_t;
+
+#if defined (ACE_PSOS_HAS_COND_T)
+typedef u_long ACE_cond_t;
+typedef u_long ACE_condattr_t;
+struct ACE_OS_Export ACE_mutexattr_t
+{
+ int type;
+};
+#endif /* ACE_PSOS_HAS_COND_T */
+
+
+// TCB registers 0-7 are for application use
+# define PSOS_TASK_REG_TSS 0
+# define PSOS_TASK_REG_MAX 7
+
+# define PSOS_TASK_MIN_PRIORITY 1
+# define PSOS_TASK_MAX_PRIORITY 239
+
+// Key type: the ACE TSS emulation requires the key type be unsigned,
+// for efficiency. Current POSIX and Solaris TSS implementations also
+// use unsigned int, so the ACE TSS emulation is compatible with them.
+// Native pSOS TSD, where available, uses unsigned long as the key type.
+# if defined (ACE_PSOS_HAS_TSS)
+typedef u_long ACE_thread_key_t;
+# else
+typedef u_int ACE_thread_key_t;
+# endif /* ACE_PSOS_HAS_TSS */
+
+# define THR_CANCEL_DISABLE 0 /* thread can never be cancelled */
+# define THR_CANCEL_ENABLE 0 /* thread can be cancelled */
+# define THR_CANCEL_DEFERRED 0 /* cancellation deferred to cancellation point */
+# define THR_CANCEL_ASYNCHRONOUS 0 /* cancellation occurs immediately */
+
+# define THR_BOUND 0
+# define THR_NEW_LWP 0
+# define THR_DETACHED 0
+# define THR_SUSPENDED 0
+# define THR_DAEMON 0
+# define THR_JOINABLE 0
+
+# define THR_SCHED_FIFO 0
+# define THR_SCHED_RR 0
+# define THR_SCHED_DEFAULT 0
+# define USYNC_THREAD T_LOCAL
+# define USYNC_PROCESS T_GLOBAL
+
+/* from psos.h */
+/* #define T_NOPREEMPT 0x00000001 Not preemptible bit */
+/* #define T_PREEMPT 0x00000000 Preemptible */
+/* #define T_TSLICE 0x00000002 Time-slicing enabled bit */
+/* #define T_NOTSLICE 0x00000000 No Time-slicing */
+/* #define T_NOASR 0x00000004 ASRs disabled bit */
+/* #define T_ASR 0x00000000 ASRs enabled */
+
+/* #define SM_GLOBAL 0x00000001 1 = Global */
+/* #define SM_LOCAL 0x00000000 0 = Local */
+/* #define SM_PRIOR 0x00000002 Queue by priority */
+/* #define SM_FIFO 0x00000000 Queue by FIFO order */
+
+/* #define T_NOFPU 0x00000000 Not using FPU */
+/* #define T_FPU 0x00000002 Using FPU bit */
+
+# elif defined (VXWORKS)
+// For mutex implementation using mutual-exclusion semaphores (which
+// can be taken recursively).
+# include /**/ <semLib.h>
+
+# include /**/ <envLib.h>
+# include /**/ <hostLib.h>
+# include /**/ <ioLib.h>
+# include /**/ <remLib.h>
+# include /**/ <selectLib.h>
+# include /**/ <sigLib.h>
+# include /**/ <sockLib.h>
+# include /**/ <sysLib.h>
+# include /**/ <taskLib.h>
+# include /**/ <taskHookLib.h>
+
+extern "C"
+struct sockaddr_un {
+ short sun_family; // AF_UNIX.
+ char sun_path[108]; // path name.
+};
+
+# define MAXPATHLEN 1024
+# define MAXNAMLEN 255
+# define NSIG (_NSIGS + 1)
+
+// task options: the other options are either obsolete, internal, or for
+// Fortran or Ada support
+# define VX_UNBREAKABLE 0x0002 /* breakpoints ignored */
+# define VX_FP_TASK 0x0008 /* floating point coprocessor */
+# define VX_PRIVATE_ENV 0x0080 /* private environment support */
+# define VX_NO_STACK_FILL 0x0100 /* do not stack fill for
+ checkstack () */
+
+# define THR_CANCEL_DISABLE 0
+# define THR_CANCEL_ENABLE 0
+# define THR_CANCEL_DEFERRED 0
+# define THR_CANCEL_ASYNCHRONOUS 0
+# define THR_BOUND 0
+# define THR_NEW_LWP 0
+# define THR_DETACHED 0
+# define THR_SUSPENDED 0
+# define THR_DAEMON 0
+# define THR_JOINABLE 0
+# define THR_SCHED_FIFO 0
+# define THR_SCHED_RR 0
+# define THR_SCHED_DEFAULT 0
+# define THR_INHERIT_SCHED 0
+# define THR_EXPLICIT_SCHED 0
+# define THR_SCHED_IO 0
+# define THR_SCOPE_SYSTEM 0
+# define THR_SCOPE_PROCESS 0
+# define USYNC_THREAD 0
+# define USYNC_PROCESS 1 /* It's all global on VxWorks
+ (without MMU option). */
+# if defined (ACE_HAS_PACE)
+# define ACE_PROC_PRI_FIFO_MIN (sched_get_priority_min(SCHED_FIFO))
+# define ACE_PROC_PRI_FIFO_MAX (sched_get_priority_max(SCHED_FIFO))
+# define ACE_PROC_PRI_RR_MIN (sched_get_priority_min(SCHED_RR))
+# define ACE_PROC_PRI_RR_MAX (sched_get_priority_max(SCHED_RR))
+# define ACE_PROC_PRI_OTHER_MIN (sched_get_priority_min(SCHED_OTHER))
+# define ACE_PROC_PRI_OTHER_MAX (sched_get_priority_max(SCHED_OTHER))
+# if !defined (ACE_THR_PRI_FIFO_MIN)
+# define ACE_THR_PRI_FIFO_MIN (long) ACE_PROC_PRI_FIFO_MIN
+# endif /* !ACE_THR_PRI_FIFO_MIN */
+# if !defined (ACE_THR_PRI_FIFO_MAX)
+# define ACE_THR_PRI_FIFO_MAX (long) ACE_PROC_PRI_FIFO_MAX
+# endif /* !ACE_THR_PRI_FIFO_MAX */
+# if !defined (ACE_THR_PRI_RR_MIN)
+# define ACE_THR_PRI_RR_MIN (long) ACE_PROC_PRI_RR_MIN
+# endif /* !ACE_THR_PRI_RR_MIN */
+# if !defined (ACE_THR_PRI_RR_MAX)
+# define ACE_THR_PRI_RR_MAX (long) ACE_PROC_PRI_RR_MAX
+# endif /* !ACE_THR_PRI_RR_MAX */
+# if !defined (ACE_THR_PRI_OTHER_MIN)
+# define ACE_THR_PRI_OTHER_MIN (long) ACE_PROC_PRI_OTHER_MIN
+# endif /* !ACE_THR_PRI_OTHER_MIN */
+# if !defined (ACE_THR_PRI_OTHER_MAX)
+# define ACE_THR_PRI_OTHER_MAX (long) ACE_PROC_PRI_OTHER_MAX
+# endif /* !ACE_THR_PRI_OTHER_MAX */
+# endif /* ACE_HAS_PACE */
+
+# if !defined (ACE_DEFAULT_SYNCH_TYPE)
+ // Types include these options: SEM_Q_PRIORITY, SEM_Q_FIFO,
+ // SEM_DELETE_SAFE, and SEM_INVERSION_SAFE. SEM_Q_FIFO is
+ // used as the default because that is VxWorks' default.
+# define ACE_DEFAULT_SYNCH_TYPE SEM_Q_FIFO
+# endif /* ! ACE_DEFAULT_SYNCH_TYPE */
+
+# if defined (ACE_HAS_PACE)
+typedef pace_pthread_mutex_t ACE_mutex_t;
+typedef pace_pthread_mutexattr_t ACE_mutexattr_t;
+typedef pace_pthread_cond_t ACE_cond_t;
+typedef pace_pthread_condattr_t ACE_condattr_t;
+# else
+typedef SEM_ID ACE_mutex_t;
+# endif /* ACE_HAS_PACE */
+// Implement ACE_thread_mutex_t with ACE_mutex_t because there's just
+// one process . . .
+typedef ACE_mutex_t ACE_thread_mutex_t;
+# if !defined (ACE_HAS_POSIX_SEM)
+// Use VxWorks semaphores, wrapped ...
+typedef struct
+{
+# if defined (ACE_HAS_PACE)
+ pace_pthread_mutex_t sema_;
+# else
+ SEM_ID sema_;
+# endif /* ACE_HAS_PACE */
+ // Semaphore handle. This is allocated by VxWorks.
+
+ char *name_;
+ // Name of the semaphore: always NULL with VxWorks.
+} ACE_sema_t;
+# endif /* !ACE_HAS_POSIX_SEM */
+# if defined (ACE_HAS_PACE)
+typedef pace_pthread_t ACE_thread_t;
+typedef pace_pthread_t ACE_hthread_t;
+# else
+typedef char * ACE_thread_t;
+typedef int ACE_hthread_t;
+# endif /* ACE_HAS_PACE */
+// Key type: the ACE TSS emulation requires the key type be unsigned,
+// for efficiency. (Current POSIX and Solaris TSS implementations also
+// use u_int, so the ACE TSS emulation is compatible with them.)
+typedef u_int ACE_thread_key_t;
+
+ // Marker for ACE_Thread_Manager to indicate that it allocated
+ // an ACE_thread_t. It is placed at the beginning of the ID.
+# define ACE_THR_ID_ALLOCATED '\022'
+
+# elif defined (ACE_HAS_WTHREADS)
+
+typedef CRITICAL_SECTION ACE_thread_mutex_t;
+
+# if defined (ACE_HAS_PACE)
+typedef pace_pthread_mutex_t ACE_mutex_t;
+# else
+typedef struct
+{
+ int type_; // Either USYNC_THREAD or USYNC_PROCESS
+ union
+ {
+ HANDLE proc_mutex_;
+ CRITICAL_SECTION thr_mutex_;
+ };
+} ACE_mutex_t;
+# endif /* ACE_HAS_PACE */
+
+// Wrapper for NT Events.
+typedef HANDLE ACE_event_t;
+
+# if !defined (ACE_HAS_PACE) || defined (ACE_WIN32)
+// This can probably get _wider_ as more types are defined in PACE.
+// ie: see above ACE_mutex_t
+
+//@@ ACE_USES_WINCE_SEMA_SIMULATION is used to debug
+// semaphore simulation on WinNT. It should be
+// changed to ACE_USES_HAS_WINCE at some later point.
+# if !defined (ACE_USES_WINCE_SEMA_SIMULATION)
+typedef HANDLE ACE_sema_t;
+# else
+/**
+ * @class ACE_sema_t
+ *
+ * @brief Semaphore simulation for Windows CE.
+ */
+class ACE_OS_Export ACE_sema_t
+{
+public:
+ /// Serializes access to <count_>.
+ ACE_thread_mutex_t lock_;
+
+ /// This event is signaled whenever the count becomes non-zero.
+ ACE_event_t count_nonzero_;
+
+ /// Current count of the semaphore.
+ u_int count_;
+};
+
+# endif /* ACE_USES_WINCE_SEMA_SIMULATION */
+# endif /* !ACE_HAS_PACE || defined (ACE_WIN32) */
+
+// 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 0x02000000 /* ignore in most places */
+# define THR_BOUND 0 /* ignore in most places */
+# define THR_NEW_LWP 0 /* ignore in most places */
+# define THR_DAEMON 0 /* ignore in most places */
+# define THR_JOINABLE 0 /* ignore in most places */
+# define THR_SUSPENDED CREATE_SUSPENDED
+# define THR_USE_AFX 0x01000000
+# define THR_SCHED_FIFO 0
+# define THR_SCHED_RR 0
+# define THR_SCHED_DEFAULT 0
+# define THR_SCOPE_PROCESS 0
+# define THR_SCOPE_SYSTEM 0
+# endif /* ACE_HAS_PTHREADS / STHREADS / PSOS / VXWORKS / WTHREADS */
+
+// If we're using PACE then we don't want this class (since PACE
+// takes care of it) unless we're on Windows. Win32 mutexes, semaphores,
+// and condition variables are not yet supported in PACE.
+# if defined (ACE_LACKS_COND_T) && (!defined (ACE_HAS_PACE) || defined (ACE_WIN32))
+/**
+ * @class ACE_cond_t
+ *
+ * @brief This structure is used to implement condition variables on
+ * platforms that lack it natively, such as VxWorks, pSoS, and
+ * Win32.
+ *
+ * At the current time, this stuff only works for threads
+ * within the same process.
+ */
+class ACE_OS_Export ACE_cond_t
+{
+public:
+ friend class ACE_OS;
+
+ /// Returns the number of waiters.
+ long waiters (void) const;
+
+protected:
+ /// Number of waiting threads.
+ long waiters_;
+
+ /// Serialize access to the waiters count.
+ ACE_thread_mutex_t waiters_lock_;
+
+ /// Queue up threads waiting for the condition to become signaled.
+ ACE_sema_t sema_;
+
+# if defined (VXWORKS) || defined (ACE_PSOS)
+ /**
+ * A semaphore used by the broadcast/signal thread to wait for all
+ * the waiting thread(s) to wake up and be released from the
+ * semaphore.
+ */
+ ACE_sema_t waiters_done_;
+# elif defined (ACE_WIN32)
+ /**
+ * 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.
+ */
+ HANDLE waiters_done_;
+# else
+# error "Please implement this feature or check your config.h file!"
+# endif /* VXWORKS || ACE_PSOS */
+
+ /// Keeps track of whether we were broadcasting or just signaling.
+ size_t was_broadcast_;
+};
+
+struct ACE_OS_Export ACE_condattr_t
+{
+ int type;
+};
+
+# if defined (ACE_HAS_PACE)
+typedef pace_pthread_mutexattr_t ACE_mutexattr_t;
+# else
+struct ACE_OS_Export ACE_mutexattr_t
+{
+ int type;
+};
+# endif /* ACE_HAS_PACE */
+# endif /* ACE_LACKS_COND_T */
+
+# if defined (ACE_LACKS_RWLOCK_T) && !defined (ACE_HAS_PTHREADS_UNIX98_EXT)
+
+/**
+ * @class ACE_rwlock_t
+ *
+ * @brief This is used to implement readers/writer locks on NT,
+ * VxWorks, and POSIX pthreads.
+ *
+ * At the current time, this stuff only works for threads
+ * within the same process.
+ */
+struct ACE_OS_Export ACE_rwlock_t
+{
+protected:
+ friend class ACE_OS;
+
+ 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.
+
+ int important_writer_;
+ // indicate that a reader is trying to upgrade
+
+ ACE_cond_t waiting_important_writer_;
+ // condition for the upgrading reader
+};
+# elif defined (ACE_HAS_PTHREADS_UNIX98_EXT)
+typedef pthread_rwlock_t ACE_rwlock_t;
+# elif defined (ACE_HAS_STHREADS)
+# include /**/ <synch.h>
+typedef rwlock_t ACE_rwlock_t;
+# endif /* ACE_LACKS_RWLOCK_T */
+
+// Define some default thread priorities on all threaded platforms, if
+// not defined above or in the individual platform config file.
+// ACE_THR_PRI_FIFO_DEF should be used by applications for default
+// real-time thread priority. ACE_THR_PRI_OTHER_DEF should be used
+// for non-real-time priority.
+# if !defined(ACE_THR_PRI_FIFO_DEF)
+# if defined (ACE_WTHREADS)
+ // It would be more in spirit to use THREAD_PRIORITY_NORMAL. But,
+ // using THREAD_PRIORITY_ABOVE_NORMAL should give preference to the
+ // threads in this process, even if the process is not in the
+ // REALTIME_PRIORITY_CLASS.
+# define ACE_THR_PRI_FIFO_DEF THREAD_PRIORITY_ABOVE_NORMAL
+# else /* ! ACE_WTHREADS */
+# define ACE_THR_PRI_FIFO_DEF 0
+# endif /* ! ACE_WTHREADS */
+# endif /* ! ACE_THR_PRI_FIFO_DEF */
+
+# if !defined(ACE_THR_PRI_OTHER_DEF)
+# if defined (ACE_WTHREADS)
+ // It would be more in spirit to use THREAD_PRIORITY_NORMAL. But,
+ // using THREAD_PRIORITY_ABOVE_NORMAL should give preference to the
+ // threads in this process, even if the process is not in the
+ // REALTIME_PRIORITY_CLASS.
+# define ACE_THR_PRI_OTHER_DEF THREAD_PRIORITY_NORMAL
+# else /* ! ACE_WTHREADS */
+# define ACE_THR_PRI_OTHER_DEF 0
+# endif /* ! ACE_WTHREADS */
+# endif /* ! ACE_THR_PRI_OTHER_DEF */
+
+#if defined (ACE_HAS_RECURSIVE_MUTEXES)
+typedef ACE_thread_mutex_t ACE_recursive_thread_mutex_t;
+#else
+/**
+ * @class ACE_recursive_thread_mutex_t
+ *
+ * @brief Implement a thin C++ wrapper that allows nested acquisition
+ * and release of a mutex that occurs in the same thread.
+ *
+ * This implementation is based on an algorithm sketched by Dave
+ * Butenhof <butenhof@zko.dec.com>. Naturally, I take the
+ * credit for any mistakes ;-)
+ */
+class ACE_recursive_thread_mutex_t
+{
+public:
+ /// Guards the state of the nesting level and thread id.
+ ACE_thread_mutex_t nesting_mutex_;
+
+ /// This condition variable suspends other waiting threads until the
+ /// mutex is available.
+ ACE_cond_t lock_available_;
+
+ /// Current nesting level of the recursion.
+ int nesting_level_;
+
+ /// Current owner of the lock.
+ ACE_thread_t owner_id_;
+};
+#endif /* ACE_WIN32 */
+
+# else /* !ACE_HAS_THREADS, i.e., the OS/platform doesn't support threading. */
+
+// Give these things some reasonable value...
+# define ACE_SCOPE_PROCESS 0
+# define ACE_SCOPE_LWP 1
+# define ACE_SCOPE_THREAD 2
+# define ACE_SCHED_OTHER 0
+# define ACE_SCHED_FIFO 1
+# define ACE_SCHED_RR 2
+# if !defined (THR_CANCEL_DISABLE)
+# define THR_CANCEL_DISABLE 0
+# endif /* ! THR_CANCEL_DISABLE */
+# if !defined (THR_CANCEL_ENABLE)
+# define THR_CANCEL_ENABLE 0
+# endif /* ! THR_CANCEL_ENABLE */
+# if !defined (THR_CANCEL_DEFERRED)
+# define THR_CANCEL_DEFERRED 0
+# endif /* ! THR_CANCEL_DEFERRED */
+# if !defined (THR_CANCEL_ASYNCHRONOUS)
+# define THR_CANCEL_ASYNCHRONOUS 0
+# endif /* ! THR_CANCEL_ASYNCHRONOUS */
+# if !defined (THR_JOINABLE)
+# define THR_JOINABLE 0 /* ignore in most places */
+# endif /* ! THR_JOINABLE */
+# if !defined (THR_DETACHED)
+# define THR_DETACHED 0 /* ignore in most places */
+# endif /* ! THR_DETACHED */
+# if !defined (THR_DAEMON)
+# define THR_DAEMON 0 /* ignore in most places */
+# endif /* ! THR_DAEMON */
+# if !defined (THR_BOUND)
+# define THR_BOUND 0 /* ignore in most places */
+# endif /* ! THR_BOUND */
+# if !defined (THR_NEW_LWP)
+# define THR_NEW_LWP 0 /* ignore in most places */
+# endif /* ! THR_NEW_LWP */
+# if !defined (THR_SUSPENDED)
+# define THR_SUSPENDED 0 /* ignore in most places */
+# endif /* ! THR_SUSPENDED */
+# if !defined (THR_SCHED_FIFO)
+# define THR_SCHED_FIFO 0
+# endif /* ! THR_SCHED_FIFO */
+# if !defined (THR_SCHED_RR)
+# define THR_SCHED_RR 0
+# endif /* ! THR_SCHED_RR */
+# if !defined (THR_SCHED_DEFAULT)
+# define THR_SCHED_DEFAULT 0
+# endif /* ! THR_SCHED_DEFAULT */
+# if !defined (USYNC_THREAD)
+# define USYNC_THREAD 0
+# endif /* ! USYNC_THREAD */
+# if !defined (USYNC_PROCESS)
+# define USYNC_PROCESS 0
+# endif /* ! USYNC_PROCESS */
+# if !defined (THR_SCOPE_PROCESS)
+# define THR_SCOPE_PROCESS 0
+# endif /* ! THR_SCOPE_PROCESS */
+# if !defined (THR_SCOPE_SYSTEM)
+# define THR_SCOPE_SYSTEM 0
+# endif /* ! THR_SCOPE_SYSTEM */
+
+// These are dummies needed for class OS.h
+typedef int ACE_cond_t;
+struct ACE_OS_Export ACE_condattr_t
+{
+ int type;
+};
+struct ACE_OS_Export ACE_mutexattr_t
+{
+ int type;
+};
+typedef int ACE_mutex_t;
+typedef int ACE_thread_mutex_t;
+typedef int ACE_recursive_thread_mutex_t;
+# if !defined (ACE_HAS_POSIX_SEM) && !defined (ACE_PSOS)
+typedef int ACE_sema_t;
+# endif /* !ACE_HAS_POSIX_SEM && !ACE_PSOS */
+typedef int ACE_rwlock_t;
+typedef int ACE_thread_t;
+typedef int ACE_hthread_t;
+typedef u_int ACE_thread_key_t;
+
+// Ensure that ACE_THR_PRI_FIFO_DEF and ACE_THR_PRI_OTHER_DEF are
+// defined on non-threaded platforms, to support application source
+// code compatibility. ACE_THR_PRI_FIFO_DEF should be used by
+// applications for default real-time thread priority.
+// ACE_THR_PRI_OTHER_DEF should be used for non-real-time priority.
+# if !defined(ACE_THR_PRI_FIFO_DEF)
+# define ACE_THR_PRI_FIFO_DEF 0
+# endif /* ! ACE_THR_PRI_FIFO_DEF */
+# if !defined(ACE_THR_PRI_OTHER_DEF)
+# define ACE_THR_PRI_OTHER_DEF 0
+# endif /* ! ACE_THR_PRI_OTHER_DEF */
+
+# endif /* ACE_HAS_THREADS */
+
+# if defined (ACE_PSOS)
+
+// Wrapper for NT events on pSOS.
+class ACE_OS_Export ACE_event_t
+{
+ friend class ACE_OS;
+
+protected:
+
+ /// Protect critical section.
+ ACE_mutex_t lock_;
+
+ /// Keeps track of waiters.
+ ACE_cond_t condition_;
+
+ /// Specifies if this is an auto- or manual-reset event.
+ int manual_reset_;
+
+ /// "True" if signaled.
+ int is_signaled_;
+
+ /// Number of waiting threads.
+ u_long waiting_threads_;
+};
+
+# endif /* ACE_PSOS */
+
+// Standard C Library includes
+// NOTE: stdarg.h must be #included before stdio.h on LynxOS.
+# include /**/ <stdarg.h>
+# if !defined (ACE_HAS_WINCE)
+# include /**/ <assert.h>
+# include /**/ <stdio.h>
+// this is a nasty hack to get around problems with the
+// pSOS definition of BUFSIZ as the config table entry
+// (which is valued using the LC_BUFSIZ value anyway)
+# if defined (ACE_PSOS)
+# if defined (BUFSIZ)
+# undef BUFSIZ
+# endif /* defined (BUFSIZ) */
+# define BUFSIZ LC_BUFSIZ
+# endif /* defined (ACE_PSOS) */
+
+#if defined (ACE_PSOS_DIAB_MIPS)
+#undef size_t
+typedef unsigned int size_t;
+#endif
+
+# if !defined (ACE_LACKS_NEW_H)
+# include /**/ <new.h>
+# endif /* ! ACE_LACKS_NEW_H */
+
+# if !defined (ACE_PSOS_DIAB_MIPS) && !defined (VXWORKS)
+# define ACE_DONT_INCLUDE_ACE_SIGNAL_H
+# include /**/ <signal.h>
+# undef ACE_DONT_INCLUDE_ACE_SIGNAL_H
+# endif /* ! ACE_PSOS_DIAB_MIPS && ! VXWORKS */
+
+# if ! defined (ACE_PSOS_DIAB_MIPS)
+# include /**/ <fcntl.h>
+# endif /* ! ACE_PSOS_DIAB_MIPS */
+# endif /* ACE_HAS_WINCE */
+
+# include /**/ <limits.h>
+# include /**/ <ctype.h>
+# if ! defined (ACE_PSOS_DIAB_MIPS)
+# include /**/ <string.h>
+# include /**/ <stdlib.h>
+# endif /* ! ACE_PSOS_DIAB_MIPS */
+# include /**/ <float.h>
+
+// This is defined by XOPEN to be a minimum of 16. POSIX.1g
+// also defines this value. platform-specific config.h can
+// override this if need be.
+# if !defined (IOV_MAX)
+# define IOV_MAX 16
+# endif /* IOV_MAX */
+
+# if !defined (ACE_IOV_MAX)
+#define ACE_IOV_MAX IOV_MAX
+# endif /* ACE_IOV_MAX */
+
+# if defined (ACE_PSOS_SNARFS_HEADER_INFO)
+ // Header information snarfed from compiler provided header files
+ // that are not included because there is already an identically
+ // named file provided with pSOS, which does not have this info
+ // from compiler supplied stdio.h
+ extern FILE *fdopen(int, const char *);
+ extern int getopt(int, char *const *, const char *);
+ extern char *tempnam(const char *, const char *);
+ extern "C" int fileno(FILE *);
+
+// #define fileno(stream) ((stream)->_file)
+
+ // from compiler supplied string.h
+ extern char *strdup (const char *);
+
+ // from compiler supplied stat.h
+ extern mode_t umask (mode_t);
+ extern int mkfifo (const char *, mode_t);
+ extern int mkdir (const char *, mode_t);
+
+ // from compiler supplied stdlib.h
+ extern int putenv (char *);
+
+ int isatty (int h);
+
+# endif /* ACE_PSOS_SNARFS_HEADER_INFO */
+
+# if defined (ACE_NEEDS_SCHED_H)
+# include /**/ <sched.h>
+# endif /* ACE_NEEDS_SCHED_H */
+
+#if !defined (ACE_OSTREAM_TYPE)
+# if defined (ACE_LACKS_IOSTREAM_TOTALLY)
+# define ACE_OSTREAM_TYPE FILE
+# else /* ! ACE_LACKS_IOSTREAM_TOTALLY */
+# define ACE_OSTREAM_TYPE ostream
+# endif /* ! ACE_LACKS_IOSTREAM_TOTALLY */
+#endif /* ! ACE_OSTREAM_TYPE */
+
+#if !defined (ACE_DEFAULT_LOG_STREAM)
+# if defined (ACE_LACKS_IOSTREAM_TOTALLY)
+# define ACE_DEFAULT_LOG_STREAM 0
+# else /* ! ACE_LACKS_IOSTREAM_TOTALLY */
+# define ACE_DEFAULT_LOG_STREAM (&cerr)
+# endif /* ! ACE_LACKS_IOSTREAM_TOTALLY */
+#endif /* ! ACE_DEFAULT_LOG_STREAM */
+
+// If the user wants minimum IOStream inclusion, we will just include
+// the forward declarations
+# if defined (ACE_HAS_MINIMUM_IOSTREAMH_INCLUSION)
+// Forward declaration for streams
+# include "ace/iosfwd.h"
+# else /* ACE_HAS_MINIMUM_IOSTREAMH_INCLUSION */
+// Else they will get all the stream header files
+# include "ace/streams.h"
+# endif /* ACE_HAS_MINIMUM_IOSTREAMH_INCLUSION */
+
+# if !defined (ACE_HAS_WINCE)
+# if ! defined (ACE_PSOS_DIAB_MIPS)
+# include /**/ <fcntl.h>
+# endif /* ! ACE_PSOS_DIAB_MIPS */
+# endif /* ACE_HAS_WINCE */
+
+// This must come after signal.h is #included.
+# if defined (SCO)
+# define SIGIO SIGPOLL
+# include /**/ <sys/regset.h>
+# endif /* SCO */
+
+# if defined ACE_HAS_BYTESEX_H
+# include /**/ <bytesex.h>
+# endif /* ACE_HAS_BYTESEX_H */
+# include "Basic_Types.h"
+
+/* This should work for linux, solaris 5.6 and above, IRIX, OSF */
+# if defined (ACE_HAS_LLSEEK) || defined (ACE_HAS_LSEEK64)
+# if ACE_SIZEOF_LONG == 8
+ typedef off_t ACE_LOFF_T;
+# elif defined (__sgi) || defined (AIX) || defined (HPUX) \
+ || defined (__QNX__)
+ typedef off64_t ACE_LOFF_T;
+# elif defined (__sun)
+ typedef offset_t ACE_LOFF_T;
+# elif defined (WIN32) //Add by Nick Lin -- for win32 llseek
+ typedef __int64 ACE_LOFF_T; //Add by Nick Lin -- for win32 llseek
+# else
+ typedef loff_t ACE_LOFF_T;
+# endif
+# endif /* ACE_HAS_LLSEEK || ACE_HAS_LSEEK64 */
+
+// Define some helpful constants.
+// Not type-safe, and signed. For backward compatibility.
+#define ACE_ONE_SECOND_IN_MSECS 1000L
+#define ACE_ONE_SECOND_IN_USECS 1000000L
+#define ACE_ONE_SECOND_IN_NSECS 1000000000L
+
+// Type-safe, and unsigned.
+static const ACE_UINT32 ACE_U_ONE_SECOND_IN_MSECS = 1000U;
+static const ACE_UINT32 ACE_U_ONE_SECOND_IN_USECS = 1000000U;
+static const ACE_UINT32 ACE_U_ONE_SECOND_IN_NSECS = 1000000000U;
+
+# if defined (ACE_HAS_SIG_MACROS)
+# undef sigemptyset
+# undef sigfillset
+# undef sigaddset
+# undef sigdelset
+# undef sigismember
+# endif /* ACE_HAS_SIG_MACROS */
+
+// This must come after signal.h is #included. It's to counteract
+// the sigemptyset and sigfillset #defines, which only happen
+// when __OPTIMIZE__ is #defined (really!) on Linux.
+# if defined (linux) && defined (__OPTIMIZE__)
+# undef sigemptyset
+# undef sigfillset
+# endif /* linux && __OPTIMIZE__ */
+
+// Prototypes should come after ace/Basic_Types.h since some types may
+// be used in the prototypes.
+
+#if defined (ACE_LACKS_GETPGID_PROTOTYPE) && \
+ !defined (_XOPEN_SOURCE) && !defined (_XOPEN_SOURCE_EXTENDED)
+extern "C" pid_t getpgid (pid_t pid);
+#endif /* ACE_LACKS_GETPGID_PROTOTYPE &&
+ !_XOPEN_SOURCE && !_XOPEN_SOURCE_EXTENDED */
+
+#if defined (ACE_LACKS_STRPTIME_PROTOTYPE) && !defined (_XOPEN_SOURCE)
+extern "C" char *strptime (const char *s, const char *fmt, struct tm *tp);
+#endif /* ACE_LACKS_STRPTIME_PROTOTYPE */
+
+#if defined (ACE_LACKS_STRTOK_R_PROTOTYPE) && !defined (_POSIX_SOURCE)
+extern "C" char *strtok_r (char *s, const char *delim, char **save_ptr);
+#endif /* ACE_LACKS_STRTOK_R_PROTOTYPE */
+
+#if !defined (_LARGEFILE64_SOURCE)
+# if defined (ACE_LACKS_LSEEK64_PROTOTYPE) && \
+ defined (ACE_LACKS_LLSEEK_PROTOTYPE)
+# error Define either ACE_LACKS_LSEEK64_PROTOTYPE or ACE_LACKS_LLSEEK_PROTOTYPE, not both!
+# elif defined (ACE_LACKS_LSEEK64_PROTOTYPE)
+extern "C" ACE_LOFF_T lseek64 (int fd, ACE_LOFF_T offset, int whence);
+# elif defined (ACE_LACKS_LLSEEK_PROTOTYPE)
+extern "C" ACE_LOFF_T llseek (int fd, ACE_LOFF_T offset, int whence);
+# endif
+#endif /* _LARGEFILE64_SOURCE */
+
+#if defined (ACE_LACKS_PREAD_PROTOTYPE) && (_XOPEN_SOURCE - 0) < 500
+// _XOPEN_SOURCE == 500 Single Unix conformance
+// It seems that _XOPEN_SOURCE == 500 means that the prototypes are
+// already defined in the system headers.
+extern "C" ssize_t pread (int fd,
+ void *buf,
+ size_t nbytes,
+ off_t offset);
+
+extern "C" ssize_t pwrite (int fd,
+ const void *buf,
+ size_t n,
+ off_t offset);
+#endif /* ACE_LACKS_PREAD_PROTOTYPE && (_XOPEN_SOURCE - 0) < 500 */
+
+# if defined (ACE_LACKS_UALARM_PROTOTYPE)
+extern "C" u_int ualarm (u_int usecs, u_int interval);
+# endif /* ACE_LACKS_UALARM_PROTOTYPE */
+
+# if defined (ACE_HAS_BROKEN_SENDMSG)
+typedef struct msghdr ACE_SENDMSG_TYPE;
+# else
+typedef const struct msghdr ACE_SENDMSG_TYPE;
+# endif /* ACE_HAS_BROKEN_SENDMSG */
+
+# if defined (ACE_HAS_BROKEN_RANDR)
+// The SunOS 5.4.X version of rand_r is inconsistent with the header
+// files...
+typedef u_int ACE_RANDR_TYPE;
+extern "C" int rand_r (ACE_RANDR_TYPE seed);
+# else
+# if defined (HPUX_10)
+// HP-UX 10.x's stdlib.h (long *) doesn't match that man page (u_int *)
+typedef long ACE_RANDR_TYPE;
+# else
+typedef u_int ACE_RANDR_TYPE;
+# endif /* HPUX_10 */
+# endif /* ACE_HAS_BROKEN_RANDR */
+
+# if defined (ACE_HAS_UTIME)
+# include /**/ <utime.h>
+# endif /* ACE_HAS_UTIME */
+
+# if !defined (ACE_HAS_MSG) && !defined (SCO)
+struct msghdr {};
+# endif /* ACE_HAS_MSG */
+
+# if defined (ACE_HAS_MSG) && defined (ACE_LACKS_MSG_ACCRIGHTS)
+# if !defined (msg_accrights)
+# undef msg_control
+# define msg_accrights msg_control
+# endif /* ! msg_accrights */
+
+# if !defined (msg_accrightslen)
+# undef msg_controllen
+# define msg_accrightslen msg_controllen
+# endif /* ! msg_accrightslen */
+# endif /* ACE_HAS_MSG && ACE_LACKS_MSG_ACCRIGHTS */
+
+# if !defined (ACE_HAS_SIG_ATOMIC_T)
+typedef int sig_atomic_t;
+# endif /* !ACE_HAS_SIG_ATOMIC_T */
+
+# if !defined (ACE_HAS_SSIZE_T)
+typedef int ssize_t;
+# endif /* ACE_HAS_SSIZE_T */
+
+# if defined (ACE_HAS_PACE)
+# if defined (ACE_HAS_LYNXOS_SIGNALS)
+typedef void (*ACE_SignalHandler)(...);
+typedef void (*ACE_SignalHandlerV)(...);
+# else
+typedef pace_sig_pf ACE_SignalHandler;
+typedef pace_sig_pf ACE_SignalHandlerV;
+# endif /* ACE_HAS_LYNXOS_SIGNALS */
+# elif defined (ACE_HAS_CONSISTENT_SIGNAL_PROTOTYPES)
+// Prototypes for both signal() and struct sigaction are consistent..
+# if defined (ACE_HAS_SIG_C_FUNC)
+extern "C" {
+# endif /* ACE_HAS_SIG_C_FUNC */
+# if !defined (ACE_PSOS)
+typedef void (*ACE_SignalHandler)(int);
+typedef void (*ACE_SignalHandlerV)(int);
+# endif /* !defined (ACE_PSOS) */
+# if defined (ACE_HAS_SIG_C_FUNC)
+}
+# endif /* ACE_HAS_SIG_C_FUNC */
+# elif defined (ACE_HAS_LYNXOS_SIGNALS)
+typedef void (*ACE_SignalHandler)(...);
+typedef void (*ACE_SignalHandlerV)(...);
+# elif defined (ACE_HAS_TANDEM_SIGNALS)
+typedef void (*ACE_SignalHandler)(...);
+typedef void (*ACE_SignalHandlerV)(...);
+# elif defined (ACE_HAS_IRIX_53_SIGNALS)
+typedef void (*ACE_SignalHandler)(...);
+typedef void (*ACE_SignalHandlerV)(...);
+# elif defined (ACE_HAS_SPARCWORKS_401_SIGNALS)
+typedef void (*ACE_SignalHandler)(int, ...);
+typedef void (*ACE_SignalHandlerV)(int,...);
+# elif defined (ACE_HAS_SUNOS4_SIGNAL_T)
+typedef void (*ACE_SignalHandler)(...);
+typedef void (*ACE_SignalHandlerV)(...);
+# elif defined (ACE_HAS_SVR4_SIGNAL_T)
+// SVR4 Signals are inconsistent (e.g., see struct sigaction)..
+typedef void (*ACE_SignalHandler)(int);
+# if !defined (m88k) /* with SVR4_SIGNAL_T */
+typedef void (*ACE_SignalHandlerV)(void);
+# else
+typedef void (*ACE_SignalHandlerV)(int);
+# endif /* m88k */ /* with SVR4_SIGNAL_T */
+# elif defined (ACE_WIN32)
+typedef void (__cdecl *ACE_SignalHandler)(int);
+typedef void (__cdecl *ACE_SignalHandlerV)(int);
+# elif defined (ACE_HAS_UNIXWARE_SVR4_SIGNAL_T)
+typedef void (*ACE_SignalHandler)(int);
+typedef void (*ACE_SignalHandlerV)(...);
+# else /* This is necessary for some older broken version of cfront */
+# if defined (SIG_PF)
+# define ACE_SignalHandler SIG_PF
+# else
+typedef void (*ACE_SignalHandler)(int);
+# endif /* SIG_PF */
+typedef void (*ACE_SignalHandlerV)(...);
+# endif /* ACE_HAS_PACE */
+
+# if defined (BUFSIZ)
+# define ACE_STREAMBUF_SIZE BUFSIZ
+# else
+# define ACE_STREAMBUF_SIZE 1024
+# endif /* BUFSIZ */
+
+# if defined (ACE_WIN32)
+// Turn off warnings for /W4
+// To resume any of these warning: #pragma warning(default: 4xxx)
+// which should be placed after these defines
+
+# if !defined (ALL_WARNINGS) && defined(_MSC_VER) && !defined(ghs) && !defined(__MINGW32__)
+// #pragma warning(disable: 4101) // unreferenced local variable
+# pragma warning(disable: 4127) /* constant expression for TRACE/ASSERT */
+# pragma warning(disable: 4134) /* message map member fxn casts */
+# pragma warning(disable: 4511) /* private copy constructors are good to have */
+# pragma warning(disable: 4512) /* private operator= are good to have */
+# pragma warning(disable: 4514) /* unreferenced inlines are common */
+# pragma warning(disable: 4710) /* private constructors are disallowed */
+# pragma warning(disable: 4705) /* statement has no effect in optimized code */
+// #pragma warning(disable: 4701) // local variable *may* be used without init
+// #pragma warning(disable: 4702) // unreachable code caused by optimizations
+# pragma warning(disable: 4791) /* loss of debugging info in retail version */
+// #pragma warning(disable: 4204) // non-constant aggregate initializer
+# pragma warning(disable: 4275) /* deriving exported class from non-exported */
+# pragma warning(disable: 4251) /* using non-exported as public in exported */
+# pragma warning(disable: 4786) /* identifier was truncated to '255' characters in the browser information */
+# pragma warning(disable: 4097) /* typedef-name used as synonym for class-name */
+# endif /* !ALL_WARNINGS && _MSV_VER && !ghs && !__MINGW32__ */
+
+// STRICT type checking in WINDOWS.H enhances type safety for Windows
+// programs by using distinct types to represent all the different
+// HANDLES in Windows. So for example, STRICT prevents you from
+// mistakenly passing an HPEN to a routine expecting an HBITMAP.
+// Note that we only use this if we
+# if defined (ACE_HAS_STRICT) && (ACE_HAS_STRICT != 0)
+# if !defined (STRICT) /* may already be defined */
+# define STRICT
+# endif /* !STRICT */
+# endif /* ACE_HAS_STRICT */
+
+# if !defined (ACE_HAS_WINCE)
+# include /**/ <sys/timeb.h>
+# endif /* ACE_HAS_WINCE */
+
+// Need to work around odd glitches with NT.
+# if !defined (ACE_MAX_DEFAULT_PORT)
+# define ACE_MAX_DEFAULT_PORT 65535
+# endif /* ACE_MAX_DEFAULT_PORT */
+
+// We're on WinNT or Win95
+# define ACE_PLATFORM_A "Win32"
+# define ACE_PLATFORM_EXE_SUFFIX_A ".exe"
+
+// Used for dynamic linking
+# if !defined (ACE_DEFAULT_SVC_CONF)
+# define ACE_DEFAULT_SVC_CONF ACE_LIB_TEXT (".\\svc.conf")
+# endif /* ACE_DEFAULT_SVC_CONF */
+
+// The following are #defines and #includes that are specific to
+// WIN32.
+# define ACE_STDIN GetStdHandle (STD_INPUT_HANDLE)
+# define ACE_STDOUT GetStdHandle (STD_OUTPUT_HANDLE)
+# define ACE_STDERR GetStdHandle (STD_ERROR_HANDLE)
+
+// Default semaphore key and mutex name
+# if !defined (ACE_DEFAULT_SEM_KEY)
+# define ACE_DEFAULT_SEM_KEY "ACE_SEM_KEY"
+# endif /* ACE_DEFAULT_SEM_KEY */
+
+# define ACE_INVALID_SEM_KEY 0
+
+# if defined (ACE_HAS_WINCE)
+// @@ WinCE probably doesn't have structural exception support
+// But I need to double check to find this out
+# define ACE_SEH_TRY if (1)
+# define ACE_SEH_EXCEPT(X) while (0)
+# define ACE_SEH_FINALLY if (1)
+# else
+# if !defined (ACE_HAS_WIN32_STRUCTURAL_EXCEPTIONS)
+# define ACE_SEH_TRY if (1)
+# define ACE_SEH_EXCEPT(X) while (0)
+# define ACE_SEH_FINALLY if (1)
+# elif defined(__BORLANDC__)
+# if (__BORLANDC__ >= 0x0530) /* Borland C++ Builder 3.0 */
+# define ACE_SEH_TRY try
+# define ACE_SEH_EXCEPT(X) __except(X)
+# define ACE_SEH_FINALLY __finally
+# else
+# define ACE_SEH_TRY if (1)
+# define ACE_SEH_EXCEPT(X) while (0)
+# define ACE_SEH_FINALLY if (1)
+# endif
+# elif defined (__IBMCPP__) && (__IBMCPP__ >= 400)
+# define ACE_SEH_TRY if (1)
+# define ACE_SEH_EXCEPT(X) while (0)
+# define ACE_SEH_FINALLY if (1)
+# else
+# define ACE_SEH_TRY __try
+# define ACE_SEH_EXCEPT(X) __except(X)
+# define ACE_SEH_FINALLY __finally
+# endif /* __BORLANDC__ */
+# endif /* ACE_HAS_WINCE */
+
+// The "null" device on Win32.
+# define ACE_DEV_NULL "nul"
+
+// Define the pathname separator characters for Win32 (ugh).
+# define ACE_DIRECTORY_SEPARATOR_STR_A "\\"
+# define ACE_DIRECTORY_SEPARATOR_CHAR_A '\\'
+# define ACE_LD_SEARCH_PATH ACE_LIB_TEXT ("PATH")
+# define ACE_LD_SEARCH_PATH_SEPARATOR_STR ACE_LIB_TEXT (";")
+# define ACE_DLL_SUFFIX ACE_LIB_TEXT (".dll")
+# if defined (__MINGW32__)
+# define ACE_DLL_PREFIX ACE_LIB_TEXT ("lib")
+# else /* __MINGW32__ */
+# define ACE_DLL_PREFIX ACE_LIB_TEXT ("")
+# endif /* __MINGW32__ */
+
+// This will help until we figure out everything:
+# define NFDBITS 32 /* only used in unused functions... */
+// These two may be used for internal flags soon:
+# define MAP_PRIVATE 1
+# define MAP_SHARED 2
+# define MAP_FIXED 4
+
+# define RUSAGE_SELF 1
+
+struct shmaddr { };
+struct msqid_ds {};
+
+// Fake the UNIX rusage structure. Perhaps we can add more to this
+// later on?
+struct rusage
+{
+ FILETIME ru_utime;
+ FILETIME ru_stime;
+};
+
+// MMAP flags
+# define PROT_READ PAGE_READONLY
+# define PROT_WRITE PAGE_READWRITE
+# define PROT_RDWR PAGE_READWRITE
+/* If we can find suitable use for these flags, here they are:
+PAGE_WRITECOPY
+PAGE_EXECUTE
+PAGE_EXECUTE_READ
+PAGE_EXECUTE_READWRITE
+PAGE_EXECUTE_WRITECOPY
+PAGE_GUARD
+PAGE_NOACCESS
+PAGE_NOCACHE */
+
+# if defined (ACE_HAS_WINSOCK2) && (ACE_HAS_WINSOCK2 != 0)
+# include /**/ <ws2tcpip.h>
+# endif /* ACE_HAS_WINSOCK2 */
+
+// error code mapping
+# define ETIME ERROR_SEM_TIMEOUT
+# define EWOULDBLOCK WSAEWOULDBLOCK
+# define EINPROGRESS WSAEINPROGRESS
+# define EALREADY WSAEALREADY
+# define ENOTSOCK WSAENOTSOCK
+# define EDESTADDRREQ WSAEDESTADDRREQ
+# define EMSGSIZE WSAEMSGSIZE
+# define EPROTOTYPE WSAEPROTOTYPE
+# define ENOPROTOOPT WSAENOPROTOOPT
+# define EPROTONOSUPPORT WSAEPROTONOSUPPORT
+# define ESOCKTNOSUPPORT WSAESOCKTNOSUPPORT
+# define EOPNOTSUPP WSAEOPNOTSUPP
+# define EPFNOSUPPORT WSAEPFNOSUPPORT
+# define EAFNOSUPPORT WSAEAFNOSUPPORT
+# define EADDRINUSE WSAEADDRINUSE
+# define EADDRNOTAVAIL WSAEADDRNOTAVAIL
+# define ENETDOWN WSAENETDOWN
+# define ENETUNREACH WSAENETUNREACH
+# define ENETRESET WSAENETRESET
+# define ECONNABORTED WSAECONNABORTED
+# define ECONNRESET WSAECONNRESET
+# define ENOBUFS WSAENOBUFS
+# define EISCONN WSAEISCONN
+# define ENOTCONN WSAENOTCONN
+# define ESHUTDOWN WSAESHUTDOWN
+# define ETOOMANYREFS WSAETOOMANYREFS
+# define ETIMEDOUT WSAETIMEDOUT
+# define ECONNREFUSED WSAECONNREFUSED
+# define ELOOP WSAELOOP
+# define EHOSTDOWN WSAEHOSTDOWN
+# define EHOSTUNREACH WSAEHOSTUNREACH
+# define EPROCLIM WSAEPROCLIM
+# define EUSERS WSAEUSERS
+# define EDQUOT WSAEDQUOT
+# define ESTALE WSAESTALE
+# define EREMOTE WSAEREMOTE
+// Grrr! These two are already defined by the horrible 'standard'
+// library.
+// #define ENAMETOOLONG WSAENAMETOOLONG
+// #define ENOTEMPTY WSAENOTEMPTY
+
+# if !defined (ACE_HAS_WINCE)
+# include /**/ <time.h>
+# include /**/ <direct.h>
+# include /**/ <process.h>
+# include /**/ <io.h>
+# endif /* ACE_HAS_WINCE */
+
+# if defined (__BORLANDC__)
+# include /**/ <fcntl.h>
+# define _chdir chdir
+# define _ftime ftime
+# undef _access
+# define _access access
+# if (__BORLANDC__ <= 0x540)
+# define _getcwd getcwd
+# define _stat stat
+# endif
+# define _isatty isatty
+# define _umask umask
+# define _fstat fstat
+# define _stricmp stricmp
+# define _strnicmp strnicmp
+
+# define _timeb timeb
+
+# define _O_CREAT O_CREAT
+# define _O_EXCL O_EXCL
+# define _O_TRUNC O_TRUNC
+ // 0x0800 is used for O_APPEND. 0x08 looks free.
+# define _O_TEMPORARY 0x08 /* see fcntl.h */
+# define _O_RDWR O_RDWR
+# define _O_WRONLY O_WRONLY
+# define _O_RDONLY O_RDONLY
+# define _O_APPEND O_APPEND
+# define _O_BINARY O_BINARY
+# define _O_TEXT O_TEXT
+# endif /* __BORLANDC__ */
+
+typedef OVERLAPPED ACE_OVERLAPPED;
+
+typedef DWORD ACE_thread_t;
+# if !defined(__MINGW32__)
+typedef long pid_t;
+# endif /* __MINGW32__ */
+typedef HANDLE ACE_hthread_t;
+
+#define ACE_INVALID_PID ((pid_t) -1)
+# if defined (ACE_HAS_TSS_EMULATION)
+ typedef DWORD ACE_OS_thread_key_t;
+ typedef u_int ACE_thread_key_t;
+# else /* ! ACE_HAS_TSS_EMULATION */
+ typedef DWORD ACE_thread_key_t;
+# endif /* ! ACE_HAS_TSS_EMULATION */
+
+# if !defined (ACE_LACKS_LONGLONG_T)
+// 64-bit quad-word definitions.
+typedef unsigned __int64 ACE_QWORD;
+typedef unsigned __int64 ACE_hrtime_t;
+inline ACE_QWORD ACE_MAKE_QWORD (DWORD lo, DWORD hi) { return ACE_QWORD (lo) | (ACE_QWORD (hi) << 32); }
+inline DWORD ACE_LOW_DWORD (ACE_QWORD q) { return (DWORD) q; }
+inline DWORD ACE_HIGH_DWORD (ACE_QWORD q) { return (DWORD) (q >> 32); }
+# else
+// Can't find ANY place that ACE_QWORD is used, but hrtime_t is.
+typedef ACE_UINT64 ACE_hrtime_t;
+# endif // ACE_LACKS_LONGLONG_T
+
+// Win32 dummies to help compilation.
+
+# if !defined (__BORLANDC__)
+# if defined (ACE_HAS_PACE)
+typedef pace_nlink_t nlink_t;
+typedef pace_mode_t mode_t;
+typedef pace_uid_t uid_t;
+typedef pace_gid_t gid_t;
+# else /* !ACE_HAS_PACE */
+typedef DWORD nlink_t;
+# if !defined(__MINGW32__)
+typedef u_short mode_t;
+# endif /* !__MINGW32__ */
+typedef long uid_t;
+typedef long gid_t;
+# endif /* ACE_HAS_PACE */
+# endif /* __BORLANDC__ */
+typedef char *caddr_t;
+
+typedef DWORD ACE_exitcode;
+# define ACE_SYSCALL_FAILED 0xFFFFFFFF
+
+// Needed to map calls to NT transparently.
+# define MS_ASYNC 0
+# define MS_INVALIDATE 0
+
+// Reliance on CRT - I don't really like this.
+
+# define O_NDELAY 1
+# if !defined (MAXPATHLEN)
+# define MAXPATHLEN _MAX_PATH
+# endif /* !MAXPATHLEN */
+# define MAXNAMLEN _MAX_FNAME
+# define EADDRINUSE WSAEADDRINUSE
+
+// The ordering of the fields in this struct is important. It has to
+// match those in WSABUF.
+struct iovec
+{
+ size_t iov_len; // byte count to read/write
+ char *iov_base; // data to be read/written
+
+ // WSABUF is a Winsock2-only type.
+#if defined (ACE_HAS_WINSOCK2) && (ACE_HAS_WINSOCK2 != 0)
+ operator WSABUF &(void) { return *((WSABUF *) this); }
+#endif /* defined (ACE_HAS_WINSOCK2) && (ACE_HAS_WINSOCK2 != 0) */
+};
+
+struct msghdr
+{
+ sockaddr * msg_name;
+ // optional address
+
+ int msg_namelen;
+ // size of address
+
+ iovec *msg_iov;
+ /* scatter/gather array */
+
+ int msg_iovlen;
+ // # elements in msg_iov
+
+ caddr_t msg_accrights;
+ // access rights sent/received
+
+ int msg_accrightslen;
+};
+
+typedef int ACE_idtype_t;
+typedef DWORD ACE_id_t;
+# define ACE_SELF (0)
+typedef int ACE_pri_t;
+
+// Dynamic loading-related types - used for dlopen and family.
+typedef HINSTANCE ACE_SHLIB_HANDLE;
+# define ACE_SHLIB_INVALID_HANDLE 0
+# define ACE_DEFAULT_SHLIB_MODE 0
+
+# elif defined (ACE_PSOS)
+
+typedef ACE_UINT64 ACE_hrtime_t;
+
+# if defined (ACE_SIGINFO_IS_SIGINFO_T)
+ typedef struct siginfo siginfo_t;
+# endif /* ACE_LACKS_SIGINFO_H */
+
+# else /* !defined (ACE_WIN32) && !defined (ACE_PSOS) */
+
+# if defined (m88k)
+# define RUSAGE_SELF 1
+# endif /* m88k */
+
+// Default port is MAX_SHORT.
+# define ACE_MAX_DEFAULT_PORT 65535
+
+// Default semaphore key
+# if !defined (ACE_DEFAULT_SEM_KEY)
+# define ACE_DEFAULT_SEM_KEY 1234
+# endif /* ACE_DEFAULT_SEM_KEY */
+
+# define ACE_INVALID_SEM_KEY -1
+
+// Define the pathname separator characters for UNIX.
+# define ACE_DIRECTORY_SEPARATOR_STR_A "/"
+# define ACE_DIRECTORY_SEPARATOR_CHAR_A '/'
+
+// We're some kind of UNIX...
+# define ACE_PLATFORM_A "UNIX"
+# define ACE_PLATFORM_EXE_SUFFIX_A ""
+
+# if !defined (ACE_LD_SEARCH_PATH)
+# define ACE_LD_SEARCH_PATH "LD_LIBRARY_PATH"
+# endif /* ACE_LD_SEARCH_PATH */
+# if !defined (ACE_LD_SEARCH_PATH_SEPARATOR_STR)
+# define ACE_LD_SEARCH_PATH_SEPARATOR_STR ":"
+# endif /* ACE_LD_SEARCH_PATH_SEPARATOR_STR */
+
+# if !defined (ACE_DLL_SUFFIX)
+# define ACE_DLL_SUFFIX ".so"
+# endif /* ACE_DLL_SUFFIX */
+# if !defined (ACE_DLL_PREFIX)
+# define ACE_DLL_PREFIX "lib"
+# endif /* ACE_DLL_PREFIX */
+
+// Used for dynamic linking.
+# if !defined (ACE_DEFAULT_SVC_CONF)
+# define ACE_DEFAULT_SVC_CONF ACE_LIB_TEXT ("./svc.conf")
+# endif /* ACE_DEFAULT_SVC_CONF */
+
+// The following are #defines and #includes that are specific to UNIX.
+
+# define ACE_STDIN 0
+# define ACE_STDOUT 1
+# define ACE_STDERR 2
+
+// Be consistent with Winsock naming
+typedef int ACE_exitcode;
+# define ACE_INVALID_HANDLE -1
+# define ACE_SYSCALL_FAILED -1
+
+# define ACE_SEH_TRY if (1)
+# define ACE_SEH_EXCEPT(X) while (0)
+# define ACE_SEH_FINALLY if (1)
+
+# if !defined (ACE_INVALID_PID)
+# define ACE_INVALID_PID ((pid_t) -1)
+# endif /* ACE_INVALID_PID */
+
+// The "null" device on UNIX.
+# define ACE_DEV_NULL "/dev/null"
+
+// Wrapper for NT events on UNIX.
+class ACE_OS_Export ACE_event_t
+{
+ friend class ACE_OS;
+protected:
+ /// Protect critical section.
+ ACE_mutex_t lock_;
+
+ /// Keeps track of waiters.
+ ACE_cond_t condition_;
+
+ /// Specifies if this is an auto- or manual-reset event.
+ int manual_reset_;
+
+ /// "True" if signaled.
+ int is_signaled_;
+
+ /// Number of waiting threads.
+ u_long waiting_threads_;
+};
+
+struct ACE_OVERLAPPED
+{
+ u_long Internal;
+ u_long InternalHigh;
+ u_long Offset;
+ u_long OffsetHigh;
+ ACE_HANDLE hEvent;
+};
+
+
+// Add some typedefs and macros to enhance Win32 conformance...
+# if !defined (LPSECURITY_ATTRIBUTES)
+# define LPSECURITY_ATTRIBUTES int
+# endif /* !defined LPSECURITY_ATTRIBUTES */
+# if !defined (GENERIC_READ)
+# define GENERIC_READ 0
+# endif /* !defined GENERIC_READ */
+# if !defined (FILE_SHARE_READ)
+# define FILE_SHARE_READ 0
+# endif /* !defined FILE_SHARE_READ */
+# if !defined (OPEN_EXISTING)
+# define OPEN_EXISTING 0
+# endif /* !defined OPEN_EXISTING */
+# if !defined (FILE_ATTRIBUTE_NORMAL)
+# define FILE_ATTRIBUTE_NORMAL 0
+# endif /* !defined FILE_ATTRIBUTE_NORMAL */
+# if !defined (MAXIMUM_WAIT_OBJECTS)
+# define MAXIMUM_WAIT_OBJECTS 0
+# endif /* !defined MAXIMUM_WAIT_OBJECTS */
+# if !defined (FILE_FLAG_OVERLAPPED)
+# define FILE_FLAG_OVERLAPPED 0
+# endif /* !defined FILE_FLAG_OVERLAPPED */
+# if !defined (FILE_FLAG_SEQUENTIAL_SCAN)
+# define FILE_FLAG_SEQUENTIAL_SCAN 0
+# endif /* FILE_FLAG_SEQUENTIAL_SCAN */
+
+# if defined (ACE_HAS_BROKEN_IF_HEADER)
+struct ifafilt;
+# endif /* ACE_HAS_BROKEN_IF_HEADER */
+
+# if defined (ACE_HAS_AIX_BROKEN_SOCKET_HEADER)
+# undef __cplusplus
+# include /**/ <sys/socket.h>
+# define __cplusplus
+# else
+# include /**/ <sys/socket.h>
+# endif /* ACE_HAS_AIX_BROKEN_SOCKET_HEADER */
+
+extern "C"
+{
+# if defined (VXWORKS)
+ struct hostent {
+ char *h_name; /* official name of host */
+ char **h_aliases; /* aliases: not used on VxWorks */
+ int h_addrtype; /* host address type */
+ int h_length; /* address length */
+ char **h_addr_list; /* (first, only) address from name server */
+# define h_addr h_addr_list[0] /* the first address */
+ };
+# elif defined (ACE_HAS_CYGWIN32_SOCKET_H)
+# include /**/ <cygwin32/socket.h>
+# else
+# if defined (ACE_HAS_STL_QUEUE_CONFLICT)
+# define queue _Queue_
+# endif /* ACE_HAS_STL_QUEUE_CONFLICT */
+# include /**/ <netdb.h>
+# if defined (ACE_HAS_STL_QUEUE_CONFLICT)
+# undef queue
+# endif /* ACE_HAS_STL_QUEUE_CONFLICT */
+# endif /* VXWORKS */
+
+
+// This part if to avoid STL name conflict with the map structure
+// in net/if.h.
+# if defined (ACE_HAS_STL_MAP_CONFLICT)
+# define map _Resource_Allocation_Map_
+# endif /* ACE_HAS_STL_MAP_CONFLICT */
+# include /**/ <net/if.h>
+# if defined (ACE_HAS_STL_MAP_CONFLICT)
+# undef map
+# endif /* ACE_HAS_STL_MAP_CONFLICT */
+
+# if defined (ACE_HAS_STL_QUEUE_CONFLICT)
+# define queue _Queue_
+# endif /* ACE_HAS_STL_QUEUE_CONFLICT */
+# include /**/ <netinet/in.h>
+# if defined (ACE_HAS_STL_QUEUE_CONFLICT)
+# undef queue
+# endif /* ACE_HAS_STL_QUEUE_CONFLICT */
+
+# if defined (VXWORKS)
+ // Work around a lack of ANSI prototypes for these functions on VxWorks.
+ unsigned long inet_addr (const char *);
+ char *inet_ntoa (const struct in_addr);
+ struct in_addr inet_makeaddr (const int, const int);
+ unsigned long inet_network (const char *);
+# else /* ! VXWORKS */
+# include /**/ <arpa/inet.h>
+# endif /* ! VXWORKS */
+}
+# if !defined (ACE_LACKS_TCP_H)
+# if defined(ACE_HAS_CONFLICTING_XTI_MACROS)
+# if defined(TCP_NODELAY)
+# undef TCP_NODELAY
+# endif
+# if defined(TCP_MAXSEG)
+# undef TCP_MAXSEG
+# endif
+# endif
+# include /**/ <netinet/tcp.h>
+# endif /* ACE_LACKS_TCP_H */
+
+# if defined (__Lynx__)
+# ifndef howmany
+# define howmany(x, y) (((x)+((y)-1))/(y))
+# endif /* howmany */
+# endif /* __Lynx__ */
+
+# if defined (CHORUS)
+# include /**/ <chorus.h>
+# if !defined(CHORUS_4)
+# include /**/ <cx/select.h>
+# else
+# include /**/ <stdio.h>
+# endif
+# include /**/ <sys/uio.h>
+# include /**/ <time.h>
+# include /**/ <stdfileio.h>
+# include /**/ <am/afexec.h>
+# include /**/ <sys/types.h>
+# include /**/ <sys/signal.h>
+# include /**/ <sys/wait.h>
+# include /**/ <pwd.h>
+# include /**/ <timer/chBench.h>
+extern_C int getgid __((void));
+extern_C int getuid __((void));
+extern_C char* getcwd __((char* buf, size_t size));
+extern_C int pipe __((int* fildes));
+extern_C int gethostname __((char*, size_t));
+
+// This must come after limits.h is included
+# define MAXPATHLEN _POSIX_PATH_MAX
+
+# if !defined(CHORUS_4)
+typedef cx_fd_mask fd_mask;
+typedef void (*__sighandler_t)(int); // keep Signal compilation happy
+# endif
+# ifndef howmany
+# define howmany(x, y) (((x)+((y)-1))/(y))
+# endif /* howmany */
+# elif defined (CYGWIN32)
+# include /**/ <sys/uio.h>
+# include /**/ <sys/file.h>
+# include /**/ <sys/time.h>
+# include /**/ <sys/resource.h>
+# include /**/ <sys/wait.h>
+# include /**/ <pwd.h>
+# elif defined (__QNX__)
+# include /**/ <sys/uio.h>
+# include /**/ <sys/ipc.h>
+# include /**/ <sys/sem.h>
+# include /**/ <sys/time.h>
+# include /**/ <sys/wait.h>
+# include /**/ <sys/resource.h>
+# include /**/ <pwd.h>
+ // sets O_NDELAY
+# include /**/ <unix.h>
+# include /**/ <sys/param.h> /* for NBBY */
+ typedef long fd_mask;
+# if !defined (NFDBITS)
+# define NFDBITS (sizeof(fd_mask) * NBBY) /* bits per mask */
+# endif /* ! NFDBITS */
+# if !defined (howmany)
+# define howmany(x, y) (((x)+((y)-1))/(y))
+# endif /* ! howmany */
+# elif defined(__rtems__)
+# include /**/ <sys/file.h>
+# include /**/ <sys/resource.h>
+# include /**/ <sys/fcntl.h>
+# include /**/ <sys/time.h>
+# include /**/ <sys/utsname.h>
+# include /**/ <sys/wait.h>
+# include /**/ <pwd.h>
+
+extern "C"
+{
+ int select (int n, fd_set *readfds, fd_set *writefds,
+ fd_set *exceptfds, const struct timeval *timeout);
+};
+# elif ! defined (VXWORKS)
+# include /**/ <sys/uio.h>
+# include /**/ <sys/ipc.h>
+# if !defined(ACE_LACKS_SYSV_SHMEM)
+// No reason to #include this if the platform lacks support for SHMEM
+# include /**/ <sys/shm.h>
+# endif /* ACE_LACKS_SYSV_SHMEM */
+# if ! defined (__MACOSX__)
+# include /**/ <sys/sem.h>
+# endif /* ! defined (__MACOSX__) */
+# include /**/ <sys/file.h>
+# include /**/ <sys/time.h>
+# include /**/ <sys/resource.h>
+# include /**/ <sys/wait.h>
+# include /**/ <pwd.h>
+# endif /* ! VXWORKS */
+# include /**/ <sys/ioctl.h>
+
+// IRIX5 defines bzero() in this odd file...
+# if defined (ACE_HAS_BSTRING)
+# include /**/ <bstring.h>
+# endif /* ACE_HAS_BSTRING */
+
+// AIX defines bzero() in this odd file...
+# if defined (ACE_HAS_STRINGS)
+# include /**/ <strings.h>
+# endif /* ACE_HAS_STRINGS */
+
+# if defined (ACE_HAS_TERM_IOCTLS)
+# if defined (__QNX__)
+# include /**/ <termios.h>
+# else /* ! __QNX__ */
+# include /**/ <sys/termios.h>
+# endif /* ! __QNX__ */
+# if defined (HPUX)
+# include /**/ <sys/modem.h>
+# endif /* HPUX */
+# endif /* ACE_HAS_TERM_IOCTLS */
+
+#if !defined (VMIN)
+#define ACE_VMIN 4
+#else
+#define ACE_VMIN VMIN
+#endif /* VMIN */
+
+#if !defined (VTIME)
+#define ACE_VTIME 5
+#else
+#define ACE_VTIME VTIME
+#endif /* VTIME */
+
+# if defined (ACE_HAS_AIO_CALLS)
+# include /**/ <aio.h>
+# endif /* ACE_HAS_AIO_CALLS */
+
+# if !defined (ACE_LACKS_PARAM_H)
+# include /**/ <sys/param.h>
+# endif /* ACE_LACKS_PARAM_H */
+
+# if !defined (ACE_LACKS_UNIX_DOMAIN_SOCKETS) && !defined (VXWORKS)
+# include /**/ <sys/un.h>
+# endif /* ACE_LACKS_UNIX_DOMAIN_SOCKETS */
+
+# if defined (ACE_HAS_SIGINFO_T)
+# if !defined (ACE_LACKS_SIGINFO_H)
+# if defined (__QNX__)
+# include /**/ <sys/siginfo.h>
+# elif defined(__rtems__)
+# include /**/ <signal.h>
+# else /* ! __QNX__ */
+# include /**/ <siginfo.h>
+# endif /* ! __QNX__ */
+# endif /* ACE_LACKS_SIGINFO_H */
+# if !defined (ACE_LACKS_UCONTEXT_H)
+# include /**/ <ucontext.h>
+# endif /* ACE_LACKS_UCONTEXT_H */
+# endif /* ACE_HAS_SIGINFO_T */
+
+# if defined (ACE_HAS_POLL)
+# include /**/ <poll.h>
+# endif /* ACE_HAS_POLL */
+
+# if defined (ACE_HAS_STREAMS)
+# if defined (AIX)
+# if !defined (_XOPEN_EXTENDED_SOURCE)
+# define _XOPEN_EXTENDED_SOURCE
+# endif /* !_XOPEN_EXTENDED_SOURCE */
+# include /**/ <stropts.h>
+# undef _XOPEN_EXTENDED_SOURCE
+# else
+# include /**/ <stropts.h>
+# endif /* AIX */
+# endif /* ACE_HAS_STREAMS */
+
+# if defined (DIGITAL_UNIX)
+ // sigwait is yet another macro on Digital UNIX 4.0, just causing
+ // trouble when introducing member functions with the same name.
+ // Thanks to Thilo Kielmann" <kielmann@informatik.uni-siegen.de> for
+ // this fix.
+# if defined (__DECCXX_VER)
+# undef sigwait
+ // cxx on Digital Unix 4.0 needs this declaration. With it,
+ // <::_Psigwait> works with cxx -pthread. g++ does _not_ need
+ // it.
+ extern "C" int _Psigwait __((const sigset_t *set, int *sig));
+# elif defined (__KCC)
+# undef sigwait
+ inline int sigwait (const sigset_t* set, int* sig)
+ { return _Psigwait (set, sig); }
+# endif /* __DECCXX_VER */
+# elif !defined (ACE_HAS_SIGWAIT)
+# if defined(__rtems__)
+ extern "C" int sigwait (const sigset_t *set, int *sig);
+# else
+ extern "C" int sigwait (sigset_t *set);
+# endif /* __rtems__ */
+# endif /* ! DIGITAL_UNIX && ! ACE_HAS_SIGWAIT */
+
+# if defined (ACE_HAS_SELECT_H)
+# include /**/ <sys/select.h>
+# endif /* ACE_HAS_SELECT_H */
+
+# if defined (ACE_HAS_ALLOCA_H)
+# include /**/ <alloca.h>
+# endif /* ACE_HAS_ALLOCA_H */
+
+/* Set the proper handle type for dynamically-loaded libraries. */
+/* Also define a default 'mode' for loading a library - the names and values */
+/* differ between OSes, so if you write code that uses the mode, be careful */
+/* of the platform differences. */
+# if defined (ACE_HAS_SVR4_DYNAMIC_LINKING)
+# if defined (ACE_HAS_DLFCN_H_BROKEN_EXTERN_C)
+extern "C" {
+# endif /* ACE_HAS_DLFCN_H_BROKEN_EXTERN_C */
+# include /**/ <dlfcn.h>
+# if defined (ACE_HAS_DLFCN_H_BROKEN_EXTERN_C)
+}
+# endif /* ACE_HAS_DLFCN_H_BROKEN_EXTERN_C */
+ typedef void *ACE_SHLIB_HANDLE;
+# define ACE_SHLIB_INVALID_HANDLE 0
+# if defined (__KCC) && defined(RTLD_GROUP) && defined(RTLD_NODELETE)
+# define ACE_DEFAULT_SHLIB_MODE RTLD_LAZY | RTLD_GROUP | RTLD_NODELETE
+# else
+# define ACE_DEFAULT_SHLIB_MODE RTLD_LAZY
+# endif /* KCC */
+# elif defined (__hpux)
+# if defined(__GNUC__) || __cplusplus >= 199707L
+# include /**/ <dl.h>
+# else
+# include /**/ <cxxdl.h>
+# endif /* (g++ || HP aC++) vs. HP C++ */
+ typedef shl_t ACE_SHLIB_HANDLE;
+# define ACE_SHLIB_INVALID_HANDLE 0
+# define ACE_DEFAULT_SHLIB_MODE BIND_DEFERRED
+# else
+ typedef void *ACE_SHLIB_HANDLE;
+# define ACE_SHLIB_INVALID_HANDLE 0
+# define ACE_DEFAULT_SHLIB_MODE RTLD_LAZY
+
+# endif /* ACE_HAS_SVR4_DYNAMIC_LINKING */
+
+#if !defined (RTLD_LAZY)
+#define RTLD_LAZY 1
+#endif /* !RTLD_LAZY */
+
+#if !defined (RTLD_NOW)
+#define RTLD_NOW 2
+#endif /* !RTLD_NOW */
+
+#if !defined (RTLD_GLOBAL)
+#define RTLD_GLOBAL 3
+#endif /* !RTLD_GLOBAL */
+
+# if defined (ACE_HAS_SOCKIO_H)
+# include /**/ <sys/sockio.h>
+# endif /* ACE_HAS_SOCKIO_ */
+
+// There must be a better way to do this...
+# if !defined (RLIMIT_NOFILE)
+# if defined (linux) || defined (AIX) || defined (SCO)
+# if defined (RLIMIT_OFILE)
+# define RLIMIT_NOFILE RLIMIT_OFILE
+# else
+# define RLIMIT_NOFILE 200
+# endif /* RLIMIT_OFILE */
+# endif /* defined (linux) || defined (AIX) || defined (SCO) */
+# endif /* RLIMIT_NOFILE */
+
+# if defined (ACE_LACKS_MMAP)
+# define PROT_READ 0
+# define PROT_WRITE 0
+# define PROT_EXEC 0
+# define PROT_NONE 0
+# define PROT_RDWR 0
+# define MAP_PRIVATE 0
+# define MAP_SHARED 0
+# define MAP_FIXED 0
+# endif /* ACE_LACKS_MMAP */
+
+// Fixes a problem with HP/UX.
+# if defined (ACE_HAS_BROKEN_MMAP_H)
+extern "C"
+{
+# include /**/ <sys/mman.h>
+}
+# elif !defined (ACE_LACKS_MMAP)
+# include /**/ <sys/mman.h>
+# endif /* ACE_HAS_BROKEN_MMAP_H */
+
+// OSF1 has problems with sys/msg.h and C++...
+# if defined (ACE_HAS_BROKEN_MSG_H)
+# define _KERNEL
+# endif /* ACE_HAS_BROKEN_MSG_H */
+# if !defined (ACE_LACKS_SYSV_MSG_H)
+# include /**/ <sys/msg.h>
+# endif /* ACE_LACKS_SYSV_MSG_H */
+# if defined (ACE_HAS_BROKEN_MSG_H)
+# undef _KERNEL
+# endif /* ACE_HAS_BROKEN_MSG_H */
+
+# if defined (ACE_LACKS_SYSV_MSQ_PROTOS)
+extern "C"
+{
+ int msgget (key_t, int);
+ int msgrcv (int, void *, size_t, long, int);
+ int msgsnd (int, const void *, size_t, int);
+ int msgctl (int, int, struct msqid_ds *);
+}
+# endif /* ACE_LACKS_SYSV_MSQ_PROTOS */
+
+# if defined (ACE_HAS_PRIOCNTL)
+# include /**/ <sys/priocntl.h>
+# endif /* ACE_HAS_PRIOCNTL */
+
+# if defined (ACE_HAS_IDTYPE_T)
+ typedef idtype_t ACE_idtype_t;
+# else
+ typedef int ACE_idtype_t;
+# endif /* ACE_HAS_IDTYPE_T */
+
+# if defined (ACE_HAS_STHREADS) || defined (DIGITAL_UNIX)
+# if defined (ACE_LACKS_PRI_T)
+ typedef int pri_t;
+# endif /* ACE_LACKS_PRI_T */
+ typedef id_t ACE_id_t;
+# define ACE_SELF P_MYID
+ typedef pri_t ACE_pri_t;
+# else /* ! ACE_HAS_STHREADS && ! DIGITAL_UNIX */
+ typedef long ACE_id_t;
+# define ACE_SELF (-1)
+ typedef short ACE_pri_t;
+# endif /* ! ACE_HAS_STHREADS && ! DIGITAL_UNIX */
+
+# if defined (ACE_HAS_HI_RES_TIMER) && !defined (ACE_LACKS_LONGLONG_T)
+ /* hrtime_t is defined on systems (Suns) with ACE_HAS_HI_RES_TIMER */
+ typedef hrtime_t ACE_hrtime_t;
+# else /* ! ACE_HAS_HI_RES_TIMER || ACE_LACKS_LONGLONG_T */
+ typedef ACE_UINT64 ACE_hrtime_t;
+# endif /* ! ACE_HAS_HI_RES_TIMER || ACE_LACKS_LONGLONG_T */
+
+# endif /* !defined (ACE_WIN32) && !defined (ACE_PSOS) */
+
+// Define the Wide character and normal versions of some of the string macros
+# if defined (ACE_HAS_WCHAR)
+# define ACE_DIRECTORY_SEPARATOR_STR_W ACE_TEXT_WIDE(ACE_DIRECTORY_SEPARATOR_STR_A)
+# define ACE_DIRECTORY_SEPARATOR_CHAR_W ACE_TEXT_WIDE(ACE_DIRECTORY_SEPARATOR_CHAR_A)
+# define ACE_PLATFORM_W ACE_TEXT_WIDE(ACE_PLATFORM_A)
+# define ACE_PLATFORM_EXE_SUFFIX_W ACE_TEXT_WIDE(ACE_PLATFORM_EXE_SUFFIX_A)
+# endif /* ACE_HAS_WCHAR */
+
+# define ACE_DIRECTORY_SEPARATOR_STR ACE_LIB_TEXT (ACE_DIRECTORY_SEPARATOR_STR_A)
+# define ACE_DIRECTORY_SEPARATOR_CHAR ACE_LIB_TEXT (ACE_DIRECTORY_SEPARATOR_CHAR_A)
+# define ACE_PLATFORM ACE_LIB_TEXT (ACE_PLATFORM_A)
+# define ACE_PLATFORM_EXE_SUFFIX ACE_LIB_TEXT (ACE_PLATFORM_EXE_SUFFIX_A)
+
+// Theses defines are used by the ACE Name Server.
+# if !defined (ACE_DEFAULT_LOCALNAME_A)
+# define ACE_DEFAULT_LOCALNAME_A "localnames"
+# endif /* ACE_DEFAULT_LOCALNAME_A */
+# if !defined (ACE_DEFAULT_GLOBALNAME_A)
+# define ACE_DEFAULT_GLOBALNAME_A "globalnames"
+# endif /* ACE_DEFAULT_GLOBALNAME_A */
+
+// ACE_DEFAULT_NAMESPACE_DIR is for legacy mode apps. A better
+// way of doing this is something like ACE_Lib_Find::get_temp_dir, since
+// this directory may not exist
+# if defined (ACE_LEGACY_MODE)
+# if defined (ACE_WIN32)
+# define ACE_DEFAULT_NAMESPACE_DIR_A "C:\\temp"
+# else /* ACE_WIN32 */
+# define ACE_DEFAULT_NAMESPACE_DIR_A "/tmp"
+# endif /* ACE_WIN32 */
+# if defined (ACE_HAS_WCHAR)
+# define ACE_DEFAULT_NAMESPACE_DIR_W ACE_TEXT_WIDE(ACE_DEFAULT_NAMESPACE_DIR_A)
+# endif /* ACE_HAS_WCHAR */
+# define ACE_DEFAULT_NAMESPACE_DIR ACE_LIB_TEXT(ACE_DEFAULT_NAMESPACE_DIR_A)
+# endif /* ACE_LEGACY_MODE */
+
+# if defined (ACE_HAS_WCHAR)
+# define ACE_DEFAULT_LOCALNAME_W ACE_TEXT_WIDE(ACE_DEFAULT_LOCALNAME_A)
+# define ACE_DEFAULT_GLOBALNAME_W ACE_TEXT_WIDE(ACE_DEFAULT_GLOBALNAME_A)
+# endif /* ACE_HAS_WCHAR */
+
+# define ACE_DEFAULT_LOCALNAME ACE_LIB_TEXT (ACE_DEFAULT_LOCALNAME_A)
+# define ACE_DEFAULT_GLOBALNAME ACE_LIB_TEXT (ACE_DEFAULT_GLOBALNAME_A)
+
+// defined Win32 specific macros for UNIX platforms
+# if !defined (O_BINARY)
+# define O_BINARY 0
+# endif /* O_BINARY */
+# if !defined (_O_BINARY)
+# define _O_BINARY O_BINARY
+# endif /* _O_BINARY */
+# if !defined (O_TEXT)
+# define O_TEXT 0
+# endif /* O_TEXT */
+# if !defined (_O_TEXT)
+# define _O_TEXT O_TEXT
+# endif /* _O_TEXT */
+# if !defined (O_RAW)
+# define O_RAW 0
+# endif /* O_RAW */
+# if !defined (_O_RAW)
+# define _O_RAW O_RAW
+# endif /* _O_RAW */
+
+# if !defined (ACE_DEFAULT_SYNCH_TYPE)
+# define ACE_DEFAULT_SYNCH_TYPE USYNC_THREAD
+# endif /* ! ACE_DEFAULT_SYNCH_TYPE */
+
+# if !defined (ACE_MAP_PRIVATE)
+# define ACE_MAP_PRIVATE MAP_PRIVATE
+# endif /* ! ACE_MAP_PRIVATE */
+
+# if !defined (ACE_MAP_SHARED)
+# define ACE_MAP_SHARED MAP_SHARED
+# endif /* ! ACE_MAP_SHARED */
+
+# if !defined (ACE_MAP_FIXED)
+# define ACE_MAP_FIXED MAP_FIXED
+# endif /* ! ACE_MAP_FIXED */
+
+#if defined (ACE_LACKS_UTSNAME_T)
+# if !defined (SYS_NMLN)
+# define SYS_NMLN 257
+# endif /* SYS_NMLN */
+# if !defined (_SYS_NMLN)
+# define _SYS_NMLN SYS_NMLN
+# endif /* _SYS_NMLN */
+struct ACE_utsname
+{
+ ACE_TCHAR sysname[_SYS_NMLN];
+ ACE_TCHAR nodename[_SYS_NMLN];
+ ACE_TCHAR release[_SYS_NMLN];
+ ACE_TCHAR version[_SYS_NMLN];
+ ACE_TCHAR machine[_SYS_NMLN];
+};
+# else
+# include /**/ <sys/utsname.h>
+typedef struct utsname ACE_utsname;
+# endif /* ACE_LACKS_UTSNAME_T */
+
+// Increase the range of "address families". Please note that this
+// must appear _after_ the include of sys/socket.h, for the AF_FILE
+// definition on Linux/glibc2.
+#if !defined (AF_ANY)
+# define AF_ANY (-1)
+#endif /* AF_ANY */
+
+# define AF_SPIPE (AF_MAX + 1)
+# if !defined (AF_FILE)
+# define AF_FILE (AF_MAX + 2)
+# endif /* ! AF_FILE */
+# define AF_DEV (AF_MAX + 3)
+# define AF_UPIPE (AF_SPIPE)
+
+# if defined (ACE_SELECT_USES_INT)
+typedef int ACE_FD_SET_TYPE;
+# else
+typedef fd_set ACE_FD_SET_TYPE;
+# endif /* ACE_SELECT_USES_INT */
+
+# if !defined (MAXNAMELEN)
+# if defined (FILENAME_MAX)
+# define MAXNAMELEN FILENAME_MAX
+# else
+# define MAXNAMELEN 256
+# endif /* FILENAME_MAX */
+# endif /* MAXNAMELEN */
+
+# if !defined(MAXHOSTNAMELEN)
+# define MAXHOSTNAMELEN 256
+# endif /* MAXHOSTNAMELEN */
+
+// Define INET loopback address constant if it hasn't been defined
+// Dotted Decimal 127.0.0.1 == Hexidecimal 0x7f000001
+# if !defined (INADDR_LOOPBACK)
+# define INADDR_LOOPBACK ((ACE_UINT32) 0x7f000001)
+# endif /* INADDR_LOOPBACK */
+
+// The INADDR_NONE address is generally 255.255.255.255.
+# if !defined (INADDR_NONE)
+# define INADDR_NONE ((ACE_UINT32) 0xffffffff)
+# endif /* INADDR_NONE */
+
+// Define INET string length constants if they haven't been defined
+//
+// for IPv4 dotted-decimal
+# if !defined (INET_ADDRSTRLEN)
+# define INET_ADDRSTRLEN 16
+# endif /* INET_ADDRSTRLEN */
+//
+// for IPv6 hex string
+# if !defined (INET6_ADDRSTRLEN)
+# define INET6_ADDRSTRLEN 46
+# endif /* INET6_ADDRSTRLEN */
+
+#if defined (ACE_HAS_IPV6)
+
+# if defined (ACE_USES_IPV4_IPV6_MIGRATION)
+# define ACE_ADDRESS_FAMILY_INET AF_UNSPEC
+# define ACE_PROTOCOL_FAMILY_INET PF_UNSPEC
+# else
+# define ACE_ADDRESS_FAMILY_INET AF_INET6
+# define ACE_PROTOCOL_FAMILY_INET PF_INET6
+# endif /* ACE_USES_IPV4_IPV6_MIGRATION */
+
+#else
+# define ACE_ADDRESS_FAMILY_INET AF_INET
+# define ACE_PROTOCOL_FAMILY_INET PF_INET
+#endif
+
+# if defined (ACE_LACKS_SIGSET)
+# if defined (ACE_HAS_PACE) && !defined (ACE_WIN32)
+typedef pace_sigset_t sigset_t;
+# elif !defined(__MINGW32__)
+typedef u_int sigset_t;
+# endif /* !ACE_HAS_PACE && !__MINGW32__*/
+# endif /* ACE_LACKS_SIGSET */
+
+# if defined (ACE_LACKS_SIGACTION)
+struct sigaction
+{
+ int sa_flags;
+ ACE_SignalHandlerV sa_handler;
+ sigset_t sa_mask;
+};
+# endif /* ACE_LACKS_SIGACTION */
+
+# if !defined (SIGHUP)
+# define SIGHUP 0
+# endif /* SIGHUP */
+
+# if !defined (SIGINT)
+# define SIGINT 0
+# endif /* SIGINT */
+
+# if !defined (SIGSEGV)
+# define SIGSEGV 0
+# endif /* SIGSEGV */
+
+# if !defined (SIGIO)
+# define SIGIO 0
+# endif /* SIGSEGV */
+
+# if !defined (SIGUSR1)
+# define SIGUSR1 0
+# endif /* SIGUSR1 */
+
+# if !defined (SIGUSR2)
+# define SIGUSR2 0
+# endif /* SIGUSR2 */
+
+# if !defined (SIGCHLD)
+# define SIGCHLD 0
+# endif /* SIGCHLD */
+
+# if !defined (SIGCLD)
+# define SIGCLD SIGCHLD
+# endif /* SIGCLD */
+
+# if !defined (SIGQUIT)
+# define SIGQUIT 0
+# endif /* SIGQUIT */
+
+# if !defined (SIGPIPE)
+# define SIGPIPE 0
+# endif /* SIGPIPE */
+
+# if !defined (SIGALRM)
+# define SIGALRM 0
+# endif /* SIGALRM */
+
+# if !defined (SIG_DFL)
+# if defined (ACE_PSOS_DIAB_MIPS) || defined (ACE_PSOS_DIAB_PPC)
+# define SIG_DFL ((void *) 0)
+# else
+# define SIG_DFL ((__sighandler_t) 0)
+# endif
+# endif /* SIG_DFL */
+
+# if !defined (SIG_IGN)
+# if defined (ACE_PSOS_DIAB_MIPS) || defined (ACE_PSOS_DIAB_PPC)
+# define SIG_IGN ((void *) 1) /* ignore signal */
+# else
+# define SIG_IGN ((__sighandler_t) 1) /* ignore signal */
+# endif
+# endif /* SIG_IGN */
+
+# if !defined (SIG_ERR)
+# if defined (ACE_PSOS_DIAB_MIPS) || defined (ACE_PSOS_DIAB_PPC)
+# define SIG_ERR ((void *) -1) /* error return from signal */
+# else
+# define SIG_ERR ((__sighandler_t) -1) /* error return from signal */
+# endif
+# endif /* SIG_ERR */
+
+# if !defined (O_NONBLOCK)
+# define O_NONBLOCK 1
+# endif /* O_NONBLOCK */
+
+# if !defined (SIG_BLOCK)
+# define SIG_BLOCK 1
+# endif /* SIG_BLOCK */
+
+# if !defined (SIG_UNBLOCK)
+# define SIG_UNBLOCK 2
+# endif /* SIG_UNBLOCK */
+
+# if !defined (SIG_SETMASK)
+# define SIG_SETMASK 3
+# endif /* SIG_SETMASK */
+
+# if !defined (IPC_CREAT)
+# define IPC_CREAT 0
+# endif /* IPC_CREAT */
+
+# if !defined (IPC_NOWAIT)
+# define IPC_NOWAIT 0
+# endif /* IPC_NOWAIT */
+
+# if !defined (IPC_RMID)
+# define IPC_RMID 0
+# endif /* IPC_RMID */
+
+# if !defined (IPC_EXCL)
+# define IPC_EXCL 0
+# endif /* IPC_EXCL */
+
+# if !defined (IP_DROP_MEMBERSHIP)
+# define IP_DROP_MEMBERSHIP 0
+# endif /* IP_DROP_MEMBERSHIP */
+
+# if !defined (IP_ADD_MEMBERSHIP)
+# define IP_ADD_MEMBERSHIP 0
+# define ACE_LACKS_IP_ADD_MEMBERSHIP
+# endif /* IP_ADD_MEMBERSHIP */
+
+# if !defined (IP_DEFAULT_MULTICAST_TTL)
+# define IP_DEFAULT_MULTICAST_TTL 0
+# endif /* IP_DEFAULT_MULTICAST_TTL */
+
+# if !defined (IP_DEFAULT_MULTICAST_LOOP)
+# define IP_DEFAULT_MULTICAST_LOOP 0
+# endif /* IP_DEFAULT_MULTICAST_LOOP */
+
+# if !defined (IP_MULTICAST_IF)
+# define IP_MULTICAST_IF 0
+#endif /* IP_MULTICAST_IF */
+
+# if !defined (IP_MULTICAST_TTL)
+# define IP_MULTICAST_TTL 1
+#endif /* IP_MULTICAST_TTL */
+
+# if !defined (IP_MAX_MEMBERSHIPS)
+# define IP_MAX_MEMBERSHIPS 0
+# endif /* IP_MAX_MEMBERSHIP */
+
+# if !defined (SIOCGIFBRDADDR)
+# define SIOCGIFBRDADDR 0
+# endif /* SIOCGIFBRDADDR */
+
+# if !defined (SIOCGIFADDR)
+# define SIOCGIFADDR 0
+# endif /* SIOCGIFADDR */
+
+# if !defined (IPC_PRIVATE)
+# define IPC_PRIVATE ACE_INVALID_SEM_KEY
+# endif /* IPC_PRIVATE */
+
+# if !defined (IPC_STAT)
+# define IPC_STAT 0
+# endif /* IPC_STAT */
+
+# if !defined (GETVAL)
+# define GETVAL 0
+# endif /* GETVAL */
+
+# if !defined (F_GETFL)
+# define F_GETFL 0
+# endif /* F_GETFL */
+
+# if !defined (SETVAL)
+# define SETVAL 0
+# endif /* SETVAL */
+
+# if !defined (GETALL)
+# define GETALL 0
+# endif /* GETALL */
+
+# if !defined (SETALL)
+# define SETALL 0
+# endif /* SETALL */
+
+# if !defined (SEM_UNDO)
+# define SEM_UNDO 0
+# endif /* SEM_UNDO */
+
+# if defined (__Lynx__)
+ // LynxOS Neutrino sets NSIG to the highest-numbered signal.
+# define ACE_NSIG (NSIG + 1)
+# elif defined (__rtems__)
+# define ACE_NSIG (SIGRTMAX)
+# else
+ // All other platforms set NSIG to one greater than the
+ // highest-numbered signal.
+# define ACE_NSIG NSIG
+# endif /* __Lynx__ */
+
+# if !defined (R_OK)
+# define R_OK 04 /* Test for Read permission. */
+# endif /* R_OK */
+
+# if !defined (W_OK)
+# define W_OK 02 /* Test for Write permission. */
+# endif /* W_OK */
+
+# if !defined (X_OK)
+# define X_OK 01 /* Test for eXecute permission. */
+# endif /* X_OK */
+
+# if !defined (F_OK)
+# define F_OK 0 /* Test for existence of File. */
+# endif /* F_OK */
+
+# if !defined (ESUCCESS)
+# define ESUCCESS 0
+# endif /* !ESUCCESS */
+
+# if !defined (EIDRM)
+# define EIDRM 0
+# endif /* !EIDRM */
+
+# if !defined (ENFILE)
+# define ENFILE EMFILE /* No more socket descriptors are available. */
+# endif /* !ENOSYS */
+
+# if !defined (ECOMM)
+ // Not the same, but ECONNABORTED is provided on NT.
+# define ECOMM ECONNABORTED
+# endif /* ECOMM */
+
+# if !defined (WNOHANG)
+# define WNOHANG 0100
+# endif /* !WNOHANG */
+
+# if !defined (EDEADLK)
+# define EDEADLK 1000 /* Some large number.... */
+# endif /* !EDEADLK */
+
+# if !defined (MS_SYNC)
+# define MS_SYNC 0x0
+# endif /* !MS_SYNC */
+
+# if !defined (PIPE_BUF)
+# define PIPE_BUF 5120
+# endif /* PIPE_BUF */
+
+# if !defined (PROT_RDWR)
+# define PROT_RDWR (PROT_READ|PROT_WRITE)
+# endif /* PROT_RDWR */
+
+# if defined (ACE_HAS_POSIX_NONBLOCK)
+# define ACE_NONBLOCK O_NONBLOCK
+# else
+# define ACE_NONBLOCK O_NDELAY
+# endif /* ACE_HAS_POSIX_NONBLOCK */
+
+// These are used by the <ACE_IPC_SAP::enable> and
+// <ACE_IPC_SAP::disable> methods. They must be unique and cannot
+// conflict with the value of <ACE_NONBLOCK>. We make the numbers
+// negative here so they won't conflict with other values like SIGIO,
+// etc.
+# define ACE_SIGIO -1
+# define ACE_SIGURG -2
+# define ACE_CLOEXEC -3
+
+# define LOCALNAME 0
+# define REMOTENAME 1
+
+# if !defined (ETIMEDOUT) && defined (ETIME)
+# define ETIMEDOUT ETIME
+# endif /* ETIMEDOUT */
+
+# if !defined (ETIME) && defined (ETIMEDOUT)
+# define ETIME ETIMEDOUT
+# endif /* ETIMED */
+
+# if !defined (EBUSY)
+# define EBUSY ETIME
+# endif /* EBUSY */
+
+# if !defined (_SC_TIMER_MAX)
+# define _SC_TIMER_MAX 44
+# endif /* _SC_TIMER_MAX */
+
+// Default number of <ACE_Event_Handler>s supported by
+// <ACE_Timer_Heap>.
+# if !defined (ACE_DEFAULT_TIMERS)
+# define ACE_DEFAULT_TIMERS _SC_TIMER_MAX
+# endif /* ACE_DEFAULT_TIMERS */
+
+# if defined (ACE_HAS_STRUCT_NETDB_DATA)
+typedef char ACE_HOSTENT_DATA[sizeof(struct hostent_data)];
+typedef char ACE_SERVENT_DATA[sizeof(struct servent_data)];
+typedef char ACE_PROTOENT_DATA[sizeof(struct protoent_data)];
+# else
+# if !defined ACE_HOSTENT_DATA_SIZE
+# define ACE_HOSTENT_DATA_SIZE (4*1024)
+# endif /*ACE_HOSTENT_DATA_SIZE */
+# if !defined ACE_SERVENT_DATA_SIZE
+# define ACE_SERVENT_DATA_SIZE (4*1024)
+# endif /*ACE_SERVENT_DATA_SIZE */
+# if !defined ACE_PROTOENT_DATA_SIZE
+# define ACE_PROTOENT_DATA_SIZE (2*1024)
+# endif /*ACE_PROTOENT_DATA_SIZE */
+typedef char ACE_HOSTENT_DATA[ACE_HOSTENT_DATA_SIZE];
+typedef char ACE_SERVENT_DATA[ACE_SERVENT_DATA_SIZE];
+typedef char ACE_PROTOENT_DATA[ACE_PROTOENT_DATA_SIZE];
+# endif /* ACE_HAS_STRUCT_NETDB_DATA */
+
+# if !defined (ACE_HAS_SEMUN) || (defined (__GLIBC__) && defined (_SEM_SEMUN_UNDEFINED))
+union semun
+{
+ int val; // value for SETVAL
+ struct semid_ds *buf; // buffer for IPC_STAT & IPC_SET
+ u_short *array; // array for GETALL & SETALL
+};
+# endif /* !ACE_HAS_SEMUN || (defined (__GLIBC__) && defined (_SEM_SEMUN_UNDEFINED)) */
+
+// Max size of an ACE Log Record data buffer. This can be reset in
+// the config.h file if you'd like to increase or decrease the size.
+# if !defined (ACE_MAXLOGMSGLEN)
+# define ACE_MAXLOGMSGLEN 4 * 1024
+# endif /* ACE_MAXLOGMSGLEN */
+
+// Max size of an ACE Token.
+# define ACE_MAXTOKENNAMELEN 40
+
+// Max size of an ACE Token client ID.
+# define ACE_MAXCLIENTIDLEN MAXHOSTNAMELEN + 20
+
+// Create some useful typedefs.
+
+typedef const char **SYS_SIGLIST;
+
+// This is for C++ static methods.
+# if defined (VXWORKS)
+typedef int ACE_THR_FUNC_INTERNAL_RETURN_TYPE;
+typedef FUNCPTR ACE_THR_FUNC_INTERNAL; // where typedef int (*FUNCPTR) (...)
+# elif defined (ACE_PSOS)
+typedef void (*ACE_THR_FUNC_INTERNAL)(void *);
+# else
+typedef ACE_THR_FUNC ACE_THR_FUNC_INTERNAL;
+# endif /* VXWORKS */
+
+extern "C" {
+typedef void (*ACE_THR_C_DEST)(void *);
+}
+typedef void (*ACE_THR_DEST)(void *);
+
+# if !defined (MAP_FAILED) || defined (ACE_HAS_BROKEN_MAP_FAILED)
+# undef MAP_FAILED
+# define MAP_FAILED ((void *) -1)
+# elif defined (ACE_HAS_LONG_MAP_FAILED)
+# undef MAP_FAILED
+# define MAP_FAILED ((void *) -1L)
+# endif /* !MAP_FAILED || ACE_HAS_BROKEN_MAP_FAILED */
+
+# if defined (ACE_HAS_CHARPTR_DL)
+typedef ACE_TCHAR * ACE_DL_TYPE;
+# else
+typedef const ACE_TCHAR * ACE_DL_TYPE;
+# endif /* ACE_HAS_CHARPTR_DL */
+
+# if !defined (ACE_HAS_SIGINFO_T)
+# if defined (ACE_HAS_PACE)
+typedef pace_siginfo_t siginfo_t;
+# else
+struct ACE_OS_Export siginfo_t
+{
+ siginfo_t (ACE_HANDLE handle);
+ siginfo_t (ACE_HANDLE *handles); // JCEJ 12/23/96
+
+ ACE_HANDLE si_handle_;
+ // Win32 HANDLE that has become signaled.
+
+ ACE_HANDLE *si_handles_;
+ // Array of Win32 HANDLEs all of which have become signaled.
+};
+# endif /* ACE_HAS_PACE */
+# endif /* ACE_HAS_SIGINFO_T */
+
+// Typedef for the null handler func.
+extern "C"
+{
+ typedef void (*ACE_SIGNAL_C_FUNC)(int,siginfo_t*,void*);
+}
+
+# if !defined (ACE_HAS_UCONTEXT_T)
+typedef int ucontext_t;
+# endif /* ACE_HAS_UCONTEXT_T */
+
+# if !defined (SA_SIGINFO)
+# define SA_SIGINFO 0
+# endif /* SA_SIGINFO */
+
+# if !defined (SA_RESTART)
+# define SA_RESTART 0
+# endif /* SA_RESTART */
+
+# if defined (ACE_HAS_TIMOD_H)
+# if defined (ACE_HAS_STL_QUEUE_CONFLICT)
+# define queue _Queue_
+# endif /* ACE_HAS_STL_QUEUE_CONFLICT */
+# include /**/ <sys/timod.h>
+# if defined (ACE_HAS_STL_QUEUE_CONFLICT)
+# undef queue
+# endif /* ACE_HAS_STL_QUEUE_CONFLICT */
+# elif defined (ACE_HAS_OSF_TIMOD_H)
+# include /**/ <tli/timod.h>
+# endif /* ACE_HAS_TIMOD_H */
+
+/**
+ * @class ACE_Thread_ID
+ *
+ * @brief Defines a platform-independent thread ID.
+ */
+class ACE_OS_Export ACE_Thread_ID
+{
+public:
+ // = Initialization method.
+ ACE_Thread_ID (ACE_thread_t, ACE_hthread_t);
+ ACE_Thread_ID (const ACE_Thread_ID &id);
+
+ // = Set/Get the Thread ID.
+ ACE_thread_t id (void);
+ void id (ACE_thread_t);
+
+ // = Set/Get the Thread handle.
+ ACE_hthread_t handle (void);
+ void handle (ACE_hthread_t);
+
+ // != Comparison operator.
+ int operator== (const ACE_Thread_ID &) const;
+ int operator!= (const ACE_Thread_ID &) const;
+
+private:
+ /// Identify the thread.
+ ACE_thread_t thread_id_;
+
+ /// Handle to the thread (typically used to "wait" on Win32).
+ ACE_hthread_t thread_handle_;
+};
+
+// Type of the extended signal handler.
+typedef void (*ACE_Sig_Handler_Ex) (int, siginfo_t *siginfo, ucontext_t *ucontext);
+
+// = The ACE_Sched_Priority type should be used for platform-
+// independent thread and process priorities, by convention.
+// int should be used for OS-specific priorities.
+typedef int ACE_Sched_Priority;
+
+// forward declaration
+class ACE_Sched_Params;
+
+# if defined (ACE_LACKS_FILELOCKS)
+# if ! defined (VXWORKS) && ! defined (ACE_PSOS) && ! defined (__rtems__)
+// VxWorks defines struct flock in sys/fcntlcom.h. But it doesn't
+// appear to support flock (). RTEMS defines struct flock but
+// currently does not support locking.
+struct flock
+{
+ short l_type;
+ short l_whence;
+ off_t l_start;
+ off_t l_len; /* len == 0 means until end of file */
+ long l_sysid;
+ pid_t l_pid;
+ long l_pad[4]; /* reserve area */
+};
+# endif /* ! VXWORKS */
+# endif /* ACE_LACKS_FILELOCKS */
+
+# if !defined (ACE_HAS_IP_MULTICAST) && defined (ACE_LACKS_IP_ADD_MEMBERSHIP)
+ // Even if ACE_HAS_IP_MULTICAST is not defined, if IP_ADD_MEMBERSHIP
+ // is defined, assume that the ip_mreq struct is also defined
+ // (presumably in netinet/in.h).
+ struct ip_mreq
+ {
+ struct in_addr imr_multiaddr;
+ // IP multicast address of group
+ struct in_addr imr_interface;
+ // local IP address of interface
+ };
+# endif /* ! ACE_HAS_IP_MULTICAST && ACE_LACKS_IP_ADD_MEMBERSHIP */
+
+# if !defined (ACE_HAS_STRBUF_T)
+struct strbuf
+{
+ int maxlen; // no. of bytes in buffer.
+ int len; // no. of bytes returned.
+ void *buf; // pointer to data.
+};
+# endif /* ACE_HAS_STRBUF_T */
+
+/**
+ * @class ACE_Str_Buf
+ *
+ * @brief Simple wrapper for STREAM pipes strbuf.
+ */
+class ACE_OS_Export ACE_Str_Buf : public strbuf
+{
+public:
+ // = Initialization method
+ /// Constructor.
+ ACE_Str_Buf (void *b = 0, int l = 0, int max = 0);
+
+ /// Constructor.
+ ACE_Str_Buf (strbuf &);
+};
+
+# if defined (ACE_HAS_BROKEN_BITSHIFT)
+ // This might not be necessary any more: it was added prior to the
+ // (fd_mask) cast being added to the version below. Maybe that cast
+ // will fix the problem on tandems. Fri Dec 12 1997 David L. Levine
+# define ACE_MSB_MASK (~(ACE_UINT32 (1) << ACE_UINT32 (NFDBITS - 1)))
+# else
+ // This needs to go here to avoid overflow problems on some compilers.
+# if defined (ACE_WIN32)
+ // Does ACE_WIN32 have an fd_mask?
+# define ACE_MSB_MASK (~(1 << (NFDBITS - 1)))
+# else /* ! ACE_WIN32 */
+# define ACE_MSB_MASK (~((fd_mask) 1 << (NFDBITS - 1)))
+# endif /* ! ACE_WIN32 */
+# endif /* ACE_HAS_BROKEN_BITSHIFT */
+
+// Signature for registering a cleanup function that is used by the
+// <ACE_Object_Manager> and the <ACE_Thread_Manager>.
+# if defined (ACE_HAS_SIG_C_FUNC)
+extern "C" {
+# endif /* ACE_HAS_SIG_C_FUNC */
+typedef void (*ACE_CLEANUP_FUNC)(void *object, void *param) /* throw () */;
+# if defined (ACE_HAS_SIG_C_FUNC)
+}
+# endif /* ACE_HAS_SIG_C_FUNC */
+
+# if defined (ACE_WIN32)
+// Default WIN32 structured exception handler.
+int ACE_SEH_Default_Exception_Selector (void *);
+int ACE_SEH_Default_Exception_Handler (void *);
+# endif /* ACE_WIN32 */
+
+/**
+ * @class ACE_Cleanup
+ *
+ * @brief Base class for objects that are cleaned by ACE_Object_Manager.
+ */
+class ACE_OS_Export ACE_Cleanup
+{
+public:
+ /// No-op constructor.
+ ACE_Cleanup (void);
+
+ /// Destructor.
+ virtual ~ACE_Cleanup (void);
+
+ /// Cleanup method that, by default, simply deletes itself.
+ virtual void cleanup (void *param = 0);
+};
+
+// Adapter for cleanup, used by ACE_Object_Manager.
+extern "C" ACE_OS_Export
+void ace_cleanup_destroyer (ACE_Cleanup *, void *param = 0);
+
+/**
+ * @class ACE_Cleanup_Info
+ *
+ * @brief Hold cleanup information for thread/process
+ */
+class ACE_OS_Export ACE_Cleanup_Info
+{
+public:
+ /// Default constructor.
+ ACE_Cleanup_Info (void);
+
+ /// Equality operator.
+ int operator== (const ACE_Cleanup_Info &o) const;
+
+ /// Inequality operator.
+ int operator!= (const ACE_Cleanup_Info &o) const;
+
+ /// Point to object that gets passed into the <cleanup_hook_>.
+ void *object_;
+
+ /// Cleanup hook that gets called back.
+ ACE_CLEANUP_FUNC cleanup_hook_;
+
+ /// Parameter passed to the <cleanup_hook_>.
+ void *param_;
+};
+
+class ACE_Cleanup_Info_Node;
+
+/**
+ * @class ACE_OS_Exit_Info
+ *
+ * @brief Hold Object Manager cleanup (exit) information.
+ *
+ * For internal use by the ACE library, only.
+ */
+class ACE_OS_Export ACE_OS_Exit_Info
+{
+public:
+ /// Default constructor.
+ ACE_OS_Exit_Info (void);
+
+ /// Destructor.
+ ~ACE_OS_Exit_Info (void);
+
+ /// Use to register a cleanup hook.
+ int at_exit_i (void *object, ACE_CLEANUP_FUNC cleanup_hook, void *param);
+
+ /// Look for a registered cleanup hook object. Returns 1 if already
+ /// registered, 0 if not.
+ int find (void *object);
+
+ /// Call all registered cleanup hooks, in reverse order of
+ /// registration.
+ void call_hooks ();
+
+private:
+ /**
+ * Keeps track of all registered objects. The last node is only
+ * used to terminate the list (it doesn't contain a valid
+ * ACE_Cleanup_Info).
+ */
+ ACE_Cleanup_Info_Node *registered_objects_;
+};
+
+class ACE_Base_Thread_Adapter;
+class ACE_Thread_Hook;
+
+# if defined (ACE_HAS_PHARLAP_RT)
+#define ACE_IPPROTO_TCP SOL_SOCKET
+# else
+#define ACE_IPPROTO_TCP IPPROTO_TCP
+# endif /* ACE_HAS_PHARLAP_RT */
+
+# if defined (ACE_LACKS_FLOATING_POINT)
+typedef ACE_UINT32 ACE_timer_t;
+# else
+typedef double ACE_timer_t;
+# endif /* ACE_LACKS_FLOATING_POINT */
+
+# if defined (ACE_HAS_PRUSAGE_T)
+ typedef prusage_t ACE_Rusage;
+# elif defined (ACE_HAS_GETRUSAGE)
+ typedef rusage ACE_Rusage;
+# else
+ typedef int ACE_Rusage;
+# endif /* ACE_HAS_PRUSAGE_T */
+
+# if !defined (ACE_WIN32) && !defined (ACE_LACKS_UNIX_SYSLOG)
+# include /**/ <syslog.h>
+# endif /* !defined (ACE_WIN32) && !defined (ACE_LACKS_UNIX_SYSLOG) */
+
+#if defined (ACE_HAS_SYS_FILIO_H)
+# include /**/ <sys/filio.h>
+#endif /* ACE_HAS_SYS_FILIO_H */
+
+# if defined (ACE_HAS_PACE)
+ // = typedef for the _stat data structure
+ typedef pace_stat_s ACE_stat;
+# else
+# if defined (ACE_WIN32) && !defined (ACE_HAS_WINCE) && !defined (__BORLANDC__)
+ typedef struct _stat ACE_stat;
+# else
+ typedef struct stat ACE_stat;
+# endif /* ACE_WIN32 */
+# endif /* ACE_HAS_PACE */
+
+// We need this for MVS...
+extern "C" {
+ typedef int (*ACE_COMPARE_FUNC)(const void *, const void *);
+}
+
+
+
+/// Helper for the ACE_OS::timezone() function
+/**
+ * We put all the timezone stuff that used to be in ACE_OS::timezone()
+ * here because on some platforms "timezone" is a macro. Because of this,
+ * the name ACE_OS::timezone will cause errors. So in order to use the
+ * macro as it is defined but also keep the name ACE_OS::timezone, we
+ * use timezone first here in this inline function, and then undefine
+ * timezone.
+ */
+inline long ace_timezone()
+{
+#if !defined (ACE_HAS_WINCE) && !defined (VXWORKS) && !defined (ACE_PSOS) \
+ && !defined (CHORUS)
+# if defined (ACE_WIN32)
+ return _timezone; // For Win32.
+# elif defined (__Lynx__) || defined (__FreeBSD__) || defined (ACE_HAS_SUNOS4_GETTIMEOFDAY)
+ long result = 0;
+ struct timeval time;
+ struct timezone zone;
+ ACE_UNUSED_ARG (result);
+ ACE_OSCALL (::gettimeofday (&time, &zone), int, -1, result);
+ return zone.tz_minuteswest * 60;
+# else /* __Lynx__ || __FreeBSD__ ... */
+ return timezone;
+# endif /* __Lynx__ || __FreeBSD__ ... */
+#else
+ ACE_NOTSUP_RETURN (0);
+#endif /* !ACE_HAS_WINCE && !VXWORKS && !ACE_PSOS */
+}
+
+
+#if !defined (ACE_LACKS_DIFFTIME)
+/// Helper for the ACE_OS::difftime() function
+/**
+ * We moved the difftime code that used to be in ACE_OS::difftime()
+ * here because on some platforms "difftime" is a macro. Because of this,
+ * the name ACE_OS::difftime will cause errors. So in order to use the
+ * macro as it is defined but also keep the name ACE_OS::difftime, we
+ * use difftime first here in this inline function, and then undefine
+ * it.
+ */
+inline double ace_difftime(time_t t1, time_t t0)
+{
+# if defined (ACE_HAS_PACE)
+ return ::pace_difftime (t1, t0);
+# elif defined (ACE_PSOS) && ! defined (ACE_PSOS_HAS_TIME)
+ // simulate difftime ; just subtracting ; ACE_PSOS case
+ return ((double)t1) - ((double)t0);
+# else
+ return difftime (t1, t0);
+# endif /* ACE_HAS_PACE */
+}
+#endif /* !ACE_LACKS_DIFFTIME */
+
+
+/// Helper for the ACE_OS::cuserid() function
+/**
+ * On some platforms cuserid is a macro. Defining ACE_OS::cuserid()
+ * becomes really hard, as there is no way to save the macro
+ * definition using the pre-processor.
+ * This inline function achieves the same effect, without namespace
+ * pollution or performance penalties.
+ *
+ * @todo We maybe should move a lot of the code in ACE_OS::cuserid here so
+ * it is treated the same as the above ace_difftime and ace_timezone.
+ * But since there is a good deal more code in ACE_OS::cuserid, we
+ * probably need to move some of it off into some sort of emulation
+ * function.
+ */
+#if !defined (ACE_LACKS_CUSERID) && !defined(ACE_HAS_ALT_CUSERID) \
+ && !defined(ACE_WIN32) && !defined (VXWORKS)
+inline char *ace_cuserid(char *user)
+{
+ return cuserid(user);
+}
+#endif /* !ACE_LACKS_CUSERID && !ACE_HAS_ALT_CUSERID && ... */
+
+#if defined (SD_RECEIVE)
+#define ACE_SHUTDOWN_READ SD_RECEIVE
+#elif defined (SHUT_RD)
+#define ACE_SHUTDOWN_READ SHUT_RD
+#else
+#define ACE_SHUTDOWN_READ 0
+#endif /* SD_RECEIVE */
+
+#if defined (SD_SEND)
+#define ACE_SHUTDOWN_WRITE SD_SEND
+#elif defined (SHUT_WR)
+#define ACE_SHUTDOWN_WRITE SHUT_WR
+#else
+#define ACE_SHUTDOWN_WRITE 1
+#endif /* SD_RECEIVE */
+
+#if defined (SD_BOTH)
+#define ACE_SHUTDOWN_BOTH SD_BOTH
+#elif defined (SHUT_RDWR)
+#define ACE_SHUTDOWN_BOTH SHUT_RDWR
+#else
+#define ACE_SHUTDOWN_BOTH 2
+#endif /* SD_RECEIVE */
+
+// forward declarations of QoS data structures
+class ACE_QoS;
+class ACE_QoS_Params;
+class ACE_Accept_QoS_Params;
+
+#if defined (ACE_HAS_WINSOCK2) && (ACE_HAS_WINSOCK2 != 0)
+typedef WSAPROTOCOL_INFO ACE_Protocol_Info;
+
+// Callback function that's used by the QoS-enabled <ACE_OS::ioctl>
+// method.
+typedef LPWSAOVERLAPPED_COMPLETION_ROUTINE ACE_OVERLAPPED_COMPLETION_FUNC;
+typedef GROUP ACE_SOCK_GROUP;
+#else /* (ACE_HAS_WINSOCK2) && (ACE_HAS_WINSOCK2 != 0) */
+struct ACE_Protocol_Info
+{
+ u_long dwServiceFlags1;
+ int iAddressFamily;
+ int iProtocol;
+ char szProtocol[255+1];
+};
+
+// Callback function that's used by the QoS-enabled <ACE_OS::ioctl>
+// method.
+typedef void (*ACE_OVERLAPPED_COMPLETION_FUNC) (u_long error,
+ u_long bytes_transferred,
+ ACE_OVERLAPPED *overlapped,
+ u_long flags);
+typedef u_long ACE_SOCK_GROUP;
+
+#endif /* (ACE_HAS_WINSOCK2) && (ACE_HAS_WINSOCK2 != 0) */
+
+
+/**
+ * @class ACE_OS
+ *
+ * @brief This class defines an OS independent programming API that
+ * shields developers from nonportable aspects of writing
+ * efficient system programs on Win32, POSIX and other versions
+ * of UNIX, and various real-time operating systems.
+ *
+ * This class encapsulates the differences between various OS
+ * platforms. When porting ACE to a new platform, this class is
+ * the place to focus on. Once this file is ported to a new
+ * platform, pretty much everything else comes for "free." See
+ * <www.cs.wustl.edu/~schmidt/ACE_wrappers/etc/ACE-porting.html>
+ * for instructions on porting ACE. Please see the README file
+ * in this directory for complete information on the meaning of
+ * the various macros.
+ */
+class ACE_OS_Export ACE_OS
+ : public ACE_OS_Dirent,
+ public ACE_OS_String,
+ public ACE_OS_Memory,
+ public ACE_OS_TLI
+{
+
+ ACE_CLASS_IS_NAMESPACE (ACE_OS);
+public:
+ friend class ACE_Timeout_Manager;
+
+# if defined (CHORUS) && !defined (CHORUS_4)
+ // We must format this code as follows to avoid confusing OSE.
+ enum ACE_HRTimer_Op
+ {
+ ACE_HRTIMER_START = K_BSTART,
+ ACE_HRTIMER_INCR = K_BPOINT,
+ ACE_HRTIMER_STOP = K_BSTOP,
+ ACE_HRTIMER_GETTIME = 0xFFFF
+ };
+# else /* ! CHORUS */
+ enum ACE_HRTimer_Op
+ {
+ ACE_HRTIMER_START = 0x0, // Only use these if you can stand
+ ACE_HRTIMER_INCR = 0x1, // for interrupts to be disabled during
+ ACE_HRTIMER_STOP = 0x2, // the timed interval!!!!
+ ACE_HRTIMER_GETTIME = 0xFFFF
+ };
+# endif /* ! CHORUS */
+
+ /**
+ * @class ace_flock_t
+ *
+ * @brief OS file locking structure.
+ */
+ class ace_flock_t
+ {
+ public:
+ /// Dump state of the object.
+ void dump (void) const;
+
+# if defined (ACE_WIN32)
+ ACE_OVERLAPPED overlapped_;
+# else
+ struct flock lock_;
+# endif /* ACE_WIN32 */
+
+ /// Name of this filelock.
+ const ACE_TCHAR *lockname_;
+
+ /// Handle to the underlying file.
+ ACE_HANDLE handle_;
+
+# if defined (CHORUS)
+ /// This is the mutex that's stored in shared memory. It can only
+ /// be destroyed by the actor that initialized it.
+ ACE_mutex_t *process_lock_;
+# endif /* CHORUS */
+ };
+
+# if defined (ACE_WIN32)
+ // = Default Win32 Security Attributes definition.
+ static LPSECURITY_ATTRIBUTES default_win32_security_attributes (LPSECURITY_ATTRIBUTES);
+
+ // = Win32 OS version determination function.
+ /// Return the win32 OSVERSIONINFO structure.
+ static const OSVERSIONINFO &get_win32_versioninfo (void);
+
+ // = A pair of functions for modifying ACE's Win32 resource usage.
+ /// Return the handle of the module containing ACE's resources. By
+ /// default, for a DLL build of ACE this is a handle to the ACE DLL
+ /// itself, and for a static build it is a handle to the executable.
+ static HINSTANCE get_win32_resource_module (void);
+
+ /// Allow an application to modify which module contains ACE's
+ /// resources. This is mainly useful for a static build of ACE where
+ /// the required resources reside somewhere other than the executable.
+ static void set_win32_resource_module (HINSTANCE);
+
+# endif /* ACE_WIN32 */
+
+ // = A set of wrappers for miscellaneous operations.
+ static int atoi (const char *s);
+
+# if defined (ACE_HAS_WCHAR)
+ static int atoi (const wchar_t *s);
+# endif /* ACE_HAS_WCHAR */
+
+ /// This method computes the largest integral value not greater than x.
+ static double floor (double x);
+
+ /// This method computes the smallest integral value not less than x.
+ static double ceil (double x);
+
+ static char *getenv (const char *symbol);
+# if defined (ACE_HAS_WCHAR) && defined (ACE_WIN32)
+ static wchar_t *getenv (const wchar_t *symbol);
+# endif /* ACE_HAS_WCHAR && ACE_WIN32 */
+ static int putenv (const ACE_TCHAR *string);
+ static ACE_TCHAR *strenvdup (const ACE_TCHAR *str);
+ static ACE_TCHAR *getenvstrings (void);
+
+ static int getopt (int argc,
+ char *const *argv,
+ const char *optstring);
+ static int argv_to_string (ACE_TCHAR **argv,
+ ACE_TCHAR *&buf,
+ int substitute_env_args = 1);
+ static int string_to_argv (ACE_TCHAR *buf,
+ size_t &argc,
+ ACE_TCHAR **&argv,
+ int substitute_env_args = 1);
+ static long sysconf (int);
+
+ //@{ @name A set of wrappers for condition variables.
+ static int condattr_init (ACE_condattr_t &attributes,
+ int type = ACE_DEFAULT_SYNCH_TYPE);
+ static int condattr_destroy (ACE_condattr_t &attributes);
+ static int cond_broadcast (ACE_cond_t *cv);
+ static int cond_destroy (ACE_cond_t *cv);
+ static int cond_init (ACE_cond_t *cv,
+ short type = ACE_DEFAULT_SYNCH_TYPE,
+ const char *name = 0,
+ void *arg = 0);
+ static int cond_init (ACE_cond_t *cv,
+ ACE_condattr_t &attributes,
+ const char *name = 0,
+ void *arg = 0);
+# if defined (ACE_HAS_WCHAR)
+ static int cond_init (ACE_cond_t *cv,
+ short type,
+ const wchar_t *name,
+ void *arg = 0);
+ static int cond_init (ACE_cond_t *cv,
+ ACE_condattr_t &attributes,
+ const wchar_t *name,
+ void *arg = 0);
+# endif /* ACE_HAS_WCHAR */
+ 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) && 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 && ACE_HAS_WTHREADS */
+ //@}
+
+
+ //@{ @name Wrappers to obtain the current user id
+# if !defined (ACE_LACKS_CUSERID)
+#if defined(cuserid)
+# undef cuserid
+#endif /* cuserid */
+ static char *cuserid (char *user,
+ size_t maxlen = ACE_MAX_USERID);
+
+# if defined (ACE_HAS_WCHAR)
+ static wchar_t *cuserid (wchar_t *user,
+ size_t maxlen = ACE_MAX_USERID);
+# endif /* ACE_HAS_WCHAR */
+# endif /* ACE_LACKS_CUSERID */
+ //@}
+
+ //@{ @name Wrappers to obtain configuration info
+ static int uname (ACE_utsname *name);
+ static long sysinfo (int cmd,
+ char *buf,
+ long count);
+ static int hostname (char *name,
+ size_t maxnamelen);
+
+#if defined (ACE_HAS_WCHAR)
+ static int hostname (wchar_t *name,
+ size_t maxnamelen);
+#endif /* ACE_HAS_WCHAR */
+ //@}
+
+ //@{ @name A set of wrappers for explicit dynamic linking.
+ static int dlclose (ACE_SHLIB_HANDLE handle);
+
+ static ACE_TCHAR *dlerror (void);
+ static ACE_SHLIB_HANDLE dlopen (const ACE_TCHAR *filename,
+ int mode = ACE_DEFAULT_SHLIB_MODE);
+ static void *dlsym (ACE_SHLIB_HANDLE handle,
+ const ACE_TCHAR *symbol);
+ //@}
+
+ //{@ @name A set of wrappers for stdio file operations.
+ static int last_error (void);
+ static void last_error (int);
+ static int set_errno_to_last_error (void);
+ static int set_errno_to_wsa_last_error (void);
+ static int fclose (FILE *fp);
+ static int fcntl (ACE_HANDLE handle,
+ int cmd,
+ long arg = 0);
+ static int fdetach (const char *file);
+
+ static int fsync (ACE_HANDLE handle);
+
+ static FILE *fopen (const ACE_TCHAR *filename, const ACE_TCHAR *mode);
+ static FILE *freopen (const ACE_TCHAR *filename, const ACE_TCHAR *mode, FILE* stream);
+# if defined (fdopen)
+# undef fdopen
+# endif /* fdopen */
+ static FILE *fdopen (ACE_HANDLE handle, const ACE_TCHAR *mode);
+ static ACE_TCHAR *fgets (ACE_TCHAR *buf, int size, FILE *fp);
+ static int stat (const ACE_TCHAR *file, ACE_stat *);
+ static int truncate (const ACE_TCHAR *filename, off_t length);
+
+ static int fprintf (FILE *fp, const char *format, ...);
+ static int sprintf (char *buf, const char *format, ...);
+ static int vsprintf (char *buffer, const char *format, va_list argptr);
+ static int printf (const char *format, ...);
+# if defined (ACE_HAS_WCHAR)
+ static int sprintf (wchar_t *buf, const wchar_t *format, ...);
+ static int fprintf (FILE *fp, const wchar_t *format, ...);
+ static int vsprintf (wchar_t *buffer, const wchar_t *format, va_list argptr);
+# endif /* ACE_HAS_WCHAR */
+
+ static void perror (const ACE_TCHAR *s);
+
+ // The old gets () which directly maps to the evil, unprotected
+ // gets () has been deprecated. If you really need gets (),
+ // consider the following one.
+
+ // A better gets ().
+ // If n == 0, input is swallowed, but NULL is returned.
+ // Otherwise, reads up to n-1 bytes (not including the newline),
+ // then swallows rest up to newline
+ // then swallows newline
+ static char *gets (char *str, int n = 0);
+ static int puts (const ACE_TCHAR *s);
+ static int fputs (const ACE_TCHAR *s,
+ FILE *stream);
+
+ static int fflush (FILE *fp);
+ static size_t fread (void *ptr,
+ size_t size,
+ size_t nelems,
+ FILE *fp);
+ static int fseek (FILE *fp,
+ long offset,
+ int ptrname);
+ static int fstat (ACE_HANDLE,
+ ACE_stat *);
+ static int lstat (const char *,
+ ACE_stat *);
+ static int ftruncate (ACE_HANDLE,
+ off_t);
+ static size_t fwrite (const void *ptr,
+ size_t size,
+ size_t nitems,
+ FILE *fp);
+ static void rewind (FILE *fp);
+ //@}
+
+ //@{ @name Wrappers for searching and sorting.
+ static void *bsearch (const void *key,
+ const void *base,
+ size_t nel,
+ size_t size,
+ ACE_COMPARE_FUNC);
+ static void qsort (void *base,
+ size_t nel,
+ size_t width,
+ ACE_COMPARE_FUNC);
+ //@}
+
+ //@{ @name A set of wrappers for file locks.
+ static int flock_init (ACE_OS::ace_flock_t *lock,
+ int flags = 0,
+ const ACE_TCHAR *name = 0,
+ mode_t perms = 0);
+ static int flock_destroy (ACE_OS::ace_flock_t *lock,
+ int unlink_file = 1);
+# if defined (ACE_WIN32)
+ static void adjust_flock_params (ACE_OS::ace_flock_t *lock,
+ short whence,
+ off_t &start,
+ off_t &len);
+# endif /* ACE_WIN32 */
+ static int flock_rdlock (ACE_OS::ace_flock_t *lock,
+ short whence = 0,
+ off_t start = 0,
+ off_t len = 0);
+ static int flock_tryrdlock (ACE_OS::ace_flock_t *lock,
+ short whence = 0,
+ off_t start = 0,
+ off_t len = 0);
+ static int flock_trywrlock (ACE_OS::ace_flock_t *lock,
+ short whence = 0,
+ off_t start = 0,
+ off_t len = 0);
+ static int flock_unlock (ACE_OS::ace_flock_t *lock,
+ short whence = 0,
+ off_t start = 0,
+ off_t len = 0);
+ static int flock_wrlock (ACE_OS::ace_flock_t *lock,
+ short whence = 0,
+ off_t start = 0,
+ off_t len = 0);
+ //@}
+
+ //@{ @name A set of wrappers for low-level process operations.
+ static int atexit (ACE_EXIT_HOOK func);
+ static int execl (const char *path,
+ const char *arg0, ...);
+ static int execle (const char *path,
+ const char *arg0, ...);
+ static int execlp (const char *file,
+ const char *arg0, ...);
+ static int execv (const char *path,
+ char *const argv[]);
+ static int execvp (const char *file,
+ char *const argv[]);
+ static int execve (const char *path,
+ char *const argv[],
+ char *const envp[]);
+ static void _exit (int status = 0);
+ static void exit (int status = 0);
+ static void abort (void);
+ static pid_t fork (void);
+
+ //@{
+ /// Forks and exec's a process in a manner that works on Solaris and
+ /// NT. argv[0] must be the full path name to the executable.
+ static pid_t fork (const ACE_TCHAR *program_name);
+ static pid_t fork_exec (ACE_TCHAR *argv[]);
+ //@}
+
+ static int getpagesize (void);
+ static int allocation_granularity (void);
+
+ static gid_t getgid (void);
+ static int setgid (gid_t);
+ static pid_t getpid (void);
+ static pid_t getpgid (pid_t pid);
+ static pid_t getppid (void);
+ static uid_t getuid (void);
+ static int setuid (uid_t);
+ static pid_t setsid (void);
+ static int setpgid (pid_t pid, pid_t pgid);
+ static int setreuid (uid_t ruid, uid_t euid);
+ static int setregid (gid_t rgid, gid_t egid);
+ static int system (const ACE_TCHAR *s);
+ //@}
+
+ /**
+ * Calls <::waitpid> on UNIX/POSIX platforms and <::await> on
+ * Chorus. Does not work on Vxworks, or pSoS.
+ * On Win32, <pid> is ignored if the <handle> is not equal to 0.
+ * Passing the process <handle> is prefer on Win32 because using
+ * <pid> to wait on the project doesn't always work correctly
+ * if the waited process has already terminated.
+ */
+ static pid_t waitpid (pid_t pid,
+ ACE_exitcode *status = 0,
+ int wait_options = 0,
+ ACE_HANDLE handle = 0);
+
+ /**
+ * Calls <::WaitForSingleObject> on Win32 and <ACE::waitpid>
+ * otherwise. Returns the passed in <pid_t> on success and -1 on
+ * failure.
+ * On Win32, <pid> is ignored if the <handle> is not equal to 0.
+ * Passing the process <handle> is prefer on Win32 because using
+ * <pid> to wait on the project doesn't always work correctly
+ * if the waited process has already terminated.
+ */
+ static pid_t wait (pid_t pid,
+ ACE_exitcode *status,
+ int wait_options = 0,
+ ACE_HANDLE handle = 0);
+
+ /// Calls OS <::wait> function, so it's only portable to UNIX/POSIX
+ /// platforms.
+ static pid_t wait (int * = 0);
+
+ //@{ @name A set of wrappers for timers and resource stats.
+ static u_int alarm (u_int secs);
+ static u_int ualarm (u_int usecs,
+ u_int interval = 0);
+ static u_int ualarm (const ACE_Time_Value &tv,
+ const ACE_Time_Value &tv_interval = ACE_Time_Value::zero);
+ static ACE_hrtime_t gethrtime (const ACE_HRTimer_Op = ACE_HRTIMER_GETTIME);
+# if defined (ACE_HAS_POWERPC_TIMER) && (defined (ghs) || defined (__GNUG__))
+ static void readPPCTimeBase (u_long &most,
+ u_long &least);
+# endif /* ACE_HAS_POWERPC_TIMER && (ghs or __GNUG__) */
+ static int clock_gettime (clockid_t,
+ struct timespec *);
+ static ACE_Time_Value gettimeofday (void);
+ static int getrusage (int who,
+ struct rusage *rusage);
+ static int getrlimit (int resource,
+ struct rlimit *rl);
+ static int setrlimit (int resource,
+ ACE_SETRLIMIT_TYPE *rl);
+ static int sleep (u_int seconds);
+ static int sleep (const ACE_Time_Value &tv);
+ static int nanosleep (const struct timespec *requested,
+ struct timespec *remaining = 0);
+
+# if defined (ACE_HAS_BROKEN_R_ROUTINES)
+# undef ctime_r
+# undef asctime_r
+# undef rand_r
+# undef getpwnam_r
+# endif /* ACE_HAS_BROKEN_R_ROUTINES */
+ //@}
+
+ //@{ @name A set of wrappers for operations on time.
+# if !defined (ACE_HAS_WINCE)
+ static time_t mktime (struct tm *timeptr);
+# endif /* !ACE_HAS_WINCE */
+
+ // wrapper for time zone information.
+ static void tzset (void);
+
+# if defined (timezone)
+# undef timezone
+# endif /* timezone */
+ static long timezone (void);
+
+# if defined (difftime)
+# undef difftime
+# endif /* difftime */
+ static double difftime (time_t t1,
+ time_t t0);
+ static time_t time (time_t *tloc = 0);
+ static struct tm *localtime (const time_t *clock);
+ static struct tm *localtime_r (const time_t *clock,
+ struct tm *res);
+ static struct tm *gmtime (const time_t *clock);
+ static struct tm *gmtime_r (const time_t *clock,
+ struct tm *res);
+ static char *asctime (const struct tm *tm);
+ static char *asctime_r (const struct tm *tm,
+ char *buf, int buflen);
+ static ACE_TCHAR *ctime (const time_t *t);
+ static ACE_TCHAR *ctime_r (const time_t *clock, ACE_TCHAR *buf, int buflen);
+ static size_t strftime (char *s,
+ size_t maxsize,
+ const char *format,
+ const struct tm *timeptr);
+ //@}
+
+ //@{ @name A set of wrappers for System V message queues.
+ static int msgctl (int msqid,
+ int cmd,
+ struct msqid_ds *);
+ static int msgget (key_t key,
+ int msgflg);
+ static int msgrcv (int int_id,
+ void *buf,
+ size_t len,
+ long type,
+ int flags);
+ static int msgsnd (int int_id,
+ const void *buf,
+ size_t len,
+ int flags);
+ //@}
+
+ //@{ @name A set of wrappers for memory mapped files.
+ static int madvise (caddr_t addr,
+ size_t len,
+ int advice);
+ static void *mmap (void *addr,
+ size_t len,
+ int prot,
+ int flags,
+ ACE_HANDLE handle,
+ off_t off = 0,
+ ACE_HANDLE *file_mapping = 0,
+ LPSECURITY_ATTRIBUTES sa = 0,
+ const ACE_TCHAR *file_mapping_name = 0);
+ static int mprotect (void *addr,
+ size_t len,
+ int prot);
+ static int msync (void *addr,
+ size_t len,
+ int sync);
+ static int munmap (void *addr,
+ size_t len);
+ //@}
+
+ //@{ @name A set of wrappers for recursive mutex locks.
+ static int recursive_mutex_init (ACE_recursive_thread_mutex_t *m,
+ const ACE_TCHAR *name = 0,
+ ACE_mutexattr_t *arg = 0,
+ LPSECURITY_ATTRIBUTES sa = 0);
+ static int recursive_mutex_destroy (ACE_recursive_thread_mutex_t *m);
+ static int recursive_mutex_lock (ACE_recursive_thread_mutex_t *m);
+ static int recursive_mutex_trylock (ACE_recursive_thread_mutex_t *m);
+ static int recursive_mutex_unlock (ACE_recursive_thread_mutex_t *m);
+ //@}
+
+ //@{ @name A set of wrappers for mutex locks.
+ static int mutex_init (ACE_mutex_t *m,
+ int type = ACE_DEFAULT_SYNCH_TYPE,
+ const char *name = 0,
+ ACE_mutexattr_t *arg = 0,
+ LPSECURITY_ATTRIBUTES sa = 0);
+#if defined (ACE_HAS_WCHAR)
+ static int mutex_init (ACE_mutex_t *m,
+ int type,
+ const wchar_t *name,
+ ACE_mutexattr_t *arg = 0,
+ LPSECURITY_ATTRIBUTES sa = 0);
+#endif /* ACE_HAS_WCHAR */
+ static int mutex_destroy (ACE_mutex_t *m);
+
+ /// Win32 note: Abandoned mutexes are not treated differently. 0 is
+ /// returned since the calling thread does get the ownership.
+ static int mutex_lock (ACE_mutex_t *m);
+
+ /// This method is only implemented for Win32. For abandoned
+ /// mutexes, <abandoned> is set to 1 and 0 is returned.
+ static int mutex_lock (ACE_mutex_t *m,
+ int &abandoned);
+
+ /**
+ * This method attempts to acquire a lock, but gives up if the lock
+ * has not been acquired by the given time. If the lock is not
+ * acquired within the given amount of time, then this method
+ * returns -1 with an <ETIME> errno on platforms that actually
+ * support timed mutexes. The timeout should be an absolute time.
+ * Note that the mutex should not be a recursive one, i.e., it
+ * should only be a standard mutex or an error checking mutex.
+ */
+ static int mutex_lock (ACE_mutex_t *m,
+ const ACE_Time_Value &timeout);
+
+ /**
+ * If <timeout> == 0, calls <ACE_OS::mutex_lock(m)>. Otherwise,
+ * this method attempts to acquire a lock, but gives up if the lock
+ * has not been acquired by the given time, in which case it returns
+ * -1 with an <ETIME> errno on platforms that actually support timed
+ * mutexes. The timeout should be an absolute time. Note that the
+ * mutex should not be a recursive one, i.e., it should only be a
+ * standard mutex or an error checking mutex.
+ */
+ static int mutex_lock (ACE_mutex_t *m,
+ const ACE_Time_Value *timeout);
+
+ /// Win32 note: Abandoned mutexes are not treated differently. 0 is
+ /// returned since the calling thread does get the ownership.
+ static int mutex_trylock (ACE_mutex_t *m);
+
+ /// This method is only implemented for Win32. For abandoned
+ /// mutexes, <abandoned> is set to 1 and 0 is returned.
+ static int mutex_trylock (ACE_mutex_t *m,
+ int &abandoned);
+
+ static int mutex_unlock (ACE_mutex_t *m);
+ //@}
+
+ //@{ @name A set of wrappers for mutex locks that only work within a single process.
+ static int thread_mutex_init (ACE_thread_mutex_t *m,
+ int type = ACE_DEFAULT_SYNCH_TYPE,
+ const char *name = 0,
+ ACE_mutexattr_t *arg = 0);
+#if defined (ACE_HAS_WCHAR)
+ static int thread_mutex_init (ACE_thread_mutex_t *m,
+ int type,
+ const wchar_t *name,
+ ACE_mutexattr_t *arg = 0);
+#endif /* ACE_HAS_WCHAR */
+ static int thread_mutex_destroy (ACE_thread_mutex_t *m);
+ static int thread_mutex_lock (ACE_thread_mutex_t *m);
+ static int thread_mutex_lock (ACE_thread_mutex_t *m,
+ const ACE_Time_Value &timeout);
+ static int thread_mutex_lock (ACE_thread_mutex_t *m,
+ const ACE_Time_Value *timeout);
+ static int thread_mutex_trylock (ACE_thread_mutex_t *m);
+ static int thread_mutex_unlock (ACE_thread_mutex_t *m);
+ //@}
+
+ //@{ @name A set of wrappers for low-level file operations.
+ static int access (const char *path, int amode);
+#if defined (ACE_HAS_WCHAR)
+ static int access (const wchar_t *path, int amode);
+#endif /* ACE_HAS_WCHAR */
+
+ static int close (ACE_HANDLE handle);
+ static ACE_HANDLE creat (const ACE_TCHAR *filename,
+ mode_t mode);
+ static ACE_HANDLE dup (ACE_HANDLE handle);
+ static int dup2 (ACE_HANDLE oldfd,
+ ACE_HANDLE newfd);
+ static int fattach (int handle,
+ const char *path);
+ static long filesize (ACE_HANDLE handle);
+ static long filesize (const ACE_TCHAR *handle);
+ static int getmsg (ACE_HANDLE handle,
+ struct strbuf *ctl,
+ struct strbuf
+ *data, int *flags);
+ static int getpmsg (ACE_HANDLE handle,
+ struct strbuf *ctl,
+ struct strbuf
+ *data,
+ int *band,
+ int *flags);
+
+ /// UNIX-style <ioctl>.
+ static int ioctl (ACE_HANDLE handle,
+ int cmd,
+ void * = 0);
+
+ /// QoS-enabled <ioctl>.
+ static int ioctl (ACE_HANDLE socket,
+ u_long io_control_code,
+ void *in_buffer_p,
+ u_long in_buffer,
+ void *out_buffer_p,
+ u_long out_buffer,
+ u_long *bytes_returned,
+ ACE_OVERLAPPED *overlapped,
+ ACE_OVERLAPPED_COMPLETION_FUNC func);
+
+ /// QoS-enabled <ioctl> when the I/O control code is either
+ /// SIO_SET_QOS or SIO_GET_QOS.
+ static int ioctl (ACE_HANDLE socket,
+ u_long io_control_code,
+ ACE_QoS &ace_qos,
+ u_long *bytes_returned,
+ void *buffer_p = 0,
+ u_long buffer = 0,
+ ACE_OVERLAPPED *overlapped = 0,
+ ACE_OVERLAPPED_COMPLETION_FUNC func = 0);
+
+ static int isastream (ACE_HANDLE handle);
+ static int isatty (int handle);
+#if defined (ACE_WIN32)
+ static int isatty (ACE_HANDLE handle);
+#endif /* ACE_WIN32 */
+ static off_t lseek (ACE_HANDLE handle,
+ off_t offset,
+ int whence);
+#if defined (ACE_HAS_LLSEEK) || defined (ACE_HAS_LSEEK64)
+ static ACE_LOFF_T llseek (ACE_HANDLE handle, ACE_LOFF_T offset, int whence);
+#endif /* ACE_HAS_LLSEEK */
+
+ // It used to be that the <perms> argument default was 0 on all
+ // platforms. Further, the ACE_OS::open implementations ignored <perms>
+ // for Win32 and always supplied read|write|delete. To preserve
+ // backward compatibility and allow users to pass in values
+ // that are used as desired, the defaults are now what the default
+ // action used to be on Win32. The implementation now obeys what is passed.
+#if defined (ACE_WIN32)
+# if defined (ACE_HAS_WINNT4) && (ACE_HAS_WINNT4 == 1)
+# define ACE_DEFAULT_OPEN_PERMS (FILE_SHARE_READ | FILE_SHARE_WRITE | \
+ FILE_SHARE_DELETE)
+# else
+# define ACE_DEFAULT_OPEN_PERMS (FILE_SHARE_READ | FILE_SHARE_WRITE)
+# endif /* ACE_HAS_WINCE */
+#else
+# define ACE_DEFAULT_OPEN_PERMS 0
+#endif /* ACE_WIN32 */
+
+ /// The O_APPEND flag is only partly supported on Win32. If you specify
+ /// O_APPEND, then the file pointer will be positioned at the end of
+ /// the file initially during open, but it is not re-positioned at
+ /// the end prior to each write, as specified by POSIX. This
+ /// is generally good enough for typical situations, but it is ``not
+ /// quite right'' in its semantics.
+ static ACE_HANDLE open (const char *filename,
+ int mode,
+ int perms = ACE_DEFAULT_OPEN_PERMS,
+ LPSECURITY_ATTRIBUTES sa = 0);
+#if defined (ACE_HAS_WCHAR)
+ static ACE_HANDLE open (const wchar_t *filename,
+ int mode,
+ int perms = ACE_DEFAULT_OPEN_PERMS,
+ LPSECURITY_ATTRIBUTES sa = 0);
+#endif /* ACE_HAS_WCHAR */
+ static int putmsg (ACE_HANDLE handle,
+ const struct strbuf *ctl,
+ const struct strbuf *data,
+ int flags);
+ static int putpmsg (ACE_HANDLE handle,
+ const struct strbuf *ctl,
+ const struct strbuf *data,
+ int band,
+ int flags);
+ static ssize_t read (ACE_HANDLE handle,
+ void *buf,
+ size_t len);
+ static ssize_t read (ACE_HANDLE handle,
+ void *buf,
+ size_t len,
+ ACE_OVERLAPPED *);
+ /**
+ * Receive <len> bytes into <buf> from <handle> (uses the
+ * <ACE_OS::read> call, which uses the <read> system call on UNIX
+ * and the <ReadFile> call on Win32). If errors occur, -1 is
+ * returned. If EOF occurs, 0 is returned. Whatever data has been
+ * transmitted will be returned to the caller through
+ * <bytes_transferred>.
+ */
+ static ssize_t read_n (ACE_HANDLE handle,
+ void *buf,
+ size_t len,
+ size_t *bytes_transferred = 0);
+
+ static int readlink (const char *path,
+ char *buf,
+ size_t bufsiz);
+ static ssize_t pread (ACE_HANDLE handle,
+ void *buf,
+ size_t nbyte,
+ off_t offset);
+ static int recvmsg (ACE_HANDLE handle,
+ struct msghdr *msg,
+ int flags);
+ static int sendmsg (ACE_HANDLE handle,
+ const struct msghdr *msg,
+ int flags);
+ static ssize_t write (ACE_HANDLE handle,
+ const void *buf,
+ size_t nbyte);
+ static ssize_t write (ACE_HANDLE handle,
+ const void *buf,
+ size_t nbyte,
+ ACE_OVERLAPPED *);
+
+ /**
+ * Send <len> bytes from <buf> to <handle> (uses the <ACE_OS::write>
+ * calls, which is uses the <write> system call on UNIX and the
+ * <WriteFile> call on Win32). If errors occur, -1 is returned. If
+ * EOF occurs, 0 is returned. Whatever data has been transmitted
+ * will be returned to the caller through <bytes_transferred>.
+ */
+ static ssize_t write_n (ACE_HANDLE handle,
+ const void *buf,
+ size_t len,
+ size_t *bytes_transferred = 0);
+
+ static ssize_t pwrite (ACE_HANDLE handle,
+ const void *buf,
+ size_t nbyte,
+ off_t offset);
+ static ssize_t readv (ACE_HANDLE handle,
+ iovec *iov,
+ int iovlen);
+ static ssize_t writev (ACE_HANDLE handle,
+ const iovec *iov,
+ int iovcnt);
+ static ssize_t recvv (ACE_HANDLE handle,
+ iovec *iov,
+ int iovlen);
+ static ssize_t sendv (ACE_HANDLE handle,
+ const iovec *iov,
+ int iovcnt);
+ //@}
+
+ //@{ @name A set of wrappers for event demultiplexing and IPC.
+ static int select (int width,
+ fd_set *rfds,
+ fd_set *wfds = 0,
+ fd_set *efds = 0,
+ const ACE_Time_Value *tv = 0);
+ static int select (int width,
+ fd_set *rfds,
+ fd_set *wfds,
+ fd_set *efds,
+ const ACE_Time_Value &tv);
+ static int poll (struct pollfd *pollfds,
+ u_long len,
+ const ACE_Time_Value *tv = 0);
+ static int poll (struct pollfd *pollfds,
+ u_long len,
+ const ACE_Time_Value &tv);
+ static int pipe (ACE_HANDLE handles[]);
+
+ static ACE_HANDLE shm_open (const ACE_TCHAR *filename,
+ int mode,
+ int perms = 0,
+ LPSECURITY_ATTRIBUTES sa = 0);
+ static int shm_unlink (const ACE_TCHAR *path);
+ //@}
+
+ //@{ @name A set of wrappers for directory operations.
+ static mode_t umask (mode_t cmask);
+
+#if !defined (ACE_LACKS_CHDIR)
+ static int chdir (const char *path);
+
+#if defined (ACE_HAS_WCHAR)
+ static int chdir (const wchar_t *path);
+#endif /* ACE_HAS_WCHAR */
+#endif /* ACE_LACKS_CHDIR */
+
+ static int mkdir (const ACE_TCHAR *path,
+ mode_t mode = ACE_DEFAULT_DIR_PERMS);
+ static int mkfifo (const ACE_TCHAR *file,
+ mode_t mode = ACE_DEFAULT_FILE_PERMS);
+ static ACE_TCHAR *mktemp (ACE_TCHAR *t);
+ static ACE_HANDLE mkstemp (ACE_TCHAR *t);
+ static ACE_TCHAR *getcwd (ACE_TCHAR *, size_t);
+ static int rename (const ACE_TCHAR *old_name,
+ const ACE_TCHAR *new_name,
+ int flags = -1);
+ static int unlink (const ACE_TCHAR *path);
+ static ACE_TCHAR *tempnam (const ACE_TCHAR *dir = 0,
+ const ACE_TCHAR *pfx = 0);
+ //@}
+
+ //@{ @name A set of wrappers for random number operations.
+ static int rand (void);
+ static int rand_r (ACE_RANDR_TYPE &seed);
+ static void srand (u_int seed);
+ //@}
+
+ //@{ @name A set of wrappers for readers/writer locks.
+ static int rwlock_init (ACE_rwlock_t *rw,
+ int type = ACE_DEFAULT_SYNCH_TYPE,
+ const ACE_TCHAR *name = 0,
+ void *arg = 0);
+ static int rwlock_destroy (ACE_rwlock_t *rw);
+ static int rw_rdlock (ACE_rwlock_t *rw);
+ static int rw_wrlock (ACE_rwlock_t *rw);
+ static int rw_tryrdlock (ACE_rwlock_t *rw);
+ static int rw_trywrlock (ACE_rwlock_t *rw);
+ static int rw_trywrlock_upgrade (ACE_rwlock_t *rw);
+ static int rw_unlock (ACE_rwlock_t *rw);
+ //@}
+
+ //@{ @name A set of wrappers for auto-reset and manual events.
+ static int event_init (ACE_event_t *event,
+ int manual_reset = 0,
+ int initial_state = 0,
+ int type = ACE_DEFAULT_SYNCH_TYPE,
+ const char *name = 0,
+ void *arg = 0,
+ LPSECURITY_ATTRIBUTES sa = 0);
+# if defined (ACE_HAS_WCHAR)
+ static int event_init (ACE_event_t *event,
+ int manual_reset,
+ int initial_state,
+ int type,
+ const wchar_t *name,
+ void *arg = 0,
+ LPSECURITY_ATTRIBUTES sa = 0);
+# endif /* ACE_HAS_WCHAR */
+ static int event_destroy (ACE_event_t *event);
+ static int event_wait (ACE_event_t *event);
+ static int event_timedwait (ACE_event_t *event,
+ ACE_Time_Value *timeout,
+ int use_absolute_time = 1);
+ static int event_signal (ACE_event_t *event);
+ static int event_pulse (ACE_event_t *event);
+ static int event_reset (ACE_event_t *event);
+ //@}
+
+ //@{ @name A set of wrappers for semaphores.
+ static int sema_destroy (ACE_sema_t *s);
+ static int sema_init (ACE_sema_t *s,
+ u_int count,
+ int type = ACE_DEFAULT_SYNCH_TYPE,
+ const char *name = 0,
+ void *arg = 0,
+ int max = 0x7fffffff,
+ LPSECURITY_ATTRIBUTES sa = 0);
+# if defined (ACE_HAS_WCHAR)
+ static int sema_init (ACE_sema_t *s,
+ u_int count,
+ int type,
+ const wchar_t *name,
+ void *arg = 0,
+ int max = 0x7fffffff,
+ LPSECURITY_ATTRIBUTES sa = 0);
+# endif /* ACE_HAS_WCHAR */
+ static int sema_post (ACE_sema_t *s);
+ static int sema_post (ACE_sema_t *s,
+ size_t release_count);
+ static int sema_trywait (ACE_sema_t *s);
+ static int sema_wait (ACE_sema_t *s);
+ static int sema_wait (ACE_sema_t *s,
+ ACE_Time_Value &tv);
+ static int sema_wait (ACE_sema_t *s,
+ ACE_Time_Value *tv);
+ //@}
+
+ //@{ @name A set of wrappers for System V semaphores.
+ static int semctl (int int_id,
+ int semnum,
+ int cmd,
+ semun);
+ static int semget (key_t key,
+ int nsems,
+ int flags);
+ static int semop (int int_id,
+ struct sembuf *sops,
+ size_t nsops);
+ //@}
+
+ //@{ @name Thread scheduler interface.
+ /// Set scheduling parameters. An id of ACE_SELF indicates, e.g.,
+ /// set the parameters on the calling thread.
+ static int sched_params (const ACE_Sched_Params &, ACE_id_t id = ACE_SELF);
+ //@}
+
+ //@{ @name A set of wrappers for System V shared memory.
+ static void *shmat (int int_id,
+ void *shmaddr,
+ int shmflg);
+ static int shmctl (int int_id,
+ int cmd,
+ struct shmid_ds *buf);
+ static int shmdt (void *shmaddr);
+ static int shmget (key_t key,
+ int size,
+ int flags);
+ ///@}
+
+ //@{ @name A set of wrappers for Signals.
+ static int kill (pid_t pid,
+ int signum);
+ static int sigaction (int signum,
+ const struct sigaction *nsa,
+ struct sigaction *osa);
+ static int sigaddset (sigset_t *s,
+ int signum);
+ static int sigdelset (sigset_t *s,
+ int signum);
+ static int sigemptyset (sigset_t *s);
+ static int sigfillset (sigset_t *s);
+ static int sigismember (sigset_t *s,
+ int signum);
+ static ACE_SignalHandler signal (int signum,
+ ACE_SignalHandler);
+ static int sigsuspend (const sigset_t *set);
+ static int sigprocmask (int how,
+ const sigset_t *nsp,
+ sigset_t *osp);
+
+ static int pthread_sigmask (int how,
+ const sigset_t *nsp,
+ sigset_t *osp);
+ //@}
+
+ //@{ @name A set of wrappers for sockets.
+ /// BSD-style <accept> (no QoS).
+ static ACE_HANDLE accept (ACE_HANDLE handle,
+ struct sockaddr *addr,
+ int *addrlen);
+
+ /**
+ * QoS-enabled <accept>, which passes <qos_params> to <accept>. If
+ * the OS platform doesn't support QoS-enabled <accept> then the
+ * <qos_params> are ignored and the BSD-style <accept> is called.
+ */
+ static ACE_HANDLE accept (ACE_HANDLE handle,
+ struct sockaddr *addr,
+ int *addrlen,
+ const ACE_Accept_QoS_Params &qos_params);
+ /// BSD-style <connect> (no QoS).
+ static int connect (ACE_HANDLE handle,
+ struct sockaddr *addr,
+ int addrlen);
+ /**
+ * QoS-enabled <connect>, which passes <qos_params> to <connect>.
+ * If the OS platform doesn't support QoS-enabled <connect> then the
+ * <qos_params> are ignored and the BSD-style <connect> is called.
+ */
+ static int connect (ACE_HANDLE handle,
+ const sockaddr *addr,
+ int addrlen,
+ const ACE_QoS_Params &qos_params);
+
+ static int bind (ACE_HANDLE s,
+ struct sockaddr *name,
+ int namelen);
+
+ static int closesocket (ACE_HANDLE s);
+ static struct hostent *gethostbyaddr (const char *addr,
+ int length,
+ int type);
+ static struct hostent *gethostbyname (const char *name);
+ static struct hostent *getipnodebyname (const char *name, int family,
+ int flags = 0);
+ static struct hostent *getipnodebyaddr (const void *src, size_t len,
+ int family);
+ static struct hostent *gethostbyaddr_r (const char *addr,
+ int length,
+ int type,
+ struct hostent *result,
+ ACE_HOSTENT_DATA buffer,
+ int *h_errnop);
+ static struct hostent *gethostbyname_r (const char *name,
+ struct hostent *result,
+ ACE_HOSTENT_DATA buffer,
+ int *h_errnop);
+ static int getpeername (ACE_HANDLE handle,
+ struct sockaddr *addr,
+ int *addrlen);
+ static struct protoent *getprotobyname (const char *name);
+ static struct protoent *getprotobyname_r (const char *name,
+ struct protoent *result,
+ ACE_PROTOENT_DATA buffer);
+ static struct protoent *getprotobynumber (int proto);
+ static struct protoent *getprotobynumber_r (int proto,
+ struct protoent *result,
+ ACE_PROTOENT_DATA buffer);
+ static struct servent *getservbyname (const char *svc,
+ const char *proto);
+ static struct servent *getservbyname_r (const char *svc,
+ const char *proto,
+ struct servent *result,
+ ACE_SERVENT_DATA buf);
+ static int getsockname (ACE_HANDLE handle,
+ struct sockaddr *addr,
+ int *addrlen);
+ static int getsockopt (ACE_HANDLE handle,
+ int level,
+ int optname,
+ char *optval,
+ int *optlen);
+ static unsigned long inet_addr (const char *name);
+ static char *inet_ntoa (const struct in_addr addr);
+ static int inet_aton (const char *strptr,
+ struct in_addr *addr);
+ static const char *inet_ntop (int family,
+ const void *addrptr,
+ char *strptr,
+ size_t len);
+ static int inet_pton (int family,
+ const char *strptr,
+ void *addrptr);
+ /// Retrieve information about available transport protocols
+ /// installed on the local machine.
+ static int enum_protocols (int *protocols,
+ ACE_Protocol_Info *protocol_buffer,
+ u_long *buffer_length);
+ /// Joins a leaf node into a QoS-enabled multi-point session.
+ static ACE_HANDLE join_leaf (ACE_HANDLE socket,
+ const sockaddr *name,
+ int namelen,
+ const ACE_QoS_Params &qos_params);
+ static int listen (ACE_HANDLE handle,
+ int backlog);
+ static int recv (ACE_HANDLE handle,
+ char *buf,
+ int len,
+ int flags = 0);
+ static int recvfrom (ACE_HANDLE handle,
+ char *buf,
+ int len,
+ int flags,
+ struct sockaddr *addr,
+ int *addrlen);
+ static int recvfrom (ACE_HANDLE handle,
+ iovec *buffers,
+ int buffer_count,
+ size_t &number_of_bytes_recvd,
+ int &flags,
+ struct sockaddr *addr,
+ int *addrlen,
+ ACE_OVERLAPPED *overlapped,
+ ACE_OVERLAPPED_COMPLETION_FUNC func);
+ static int send (ACE_HANDLE handle,
+ const char *buf,
+ int len,
+ int flags = 0);
+ static int sendto (ACE_HANDLE handle,
+ const char *buf,
+ int len,
+ int flags,
+ const struct sockaddr *addr,
+ int addrlen);
+ static int sendto (ACE_HANDLE handle,
+ const iovec *buffers,
+ int buffer_count,
+ size_t &number_of_bytes_sent,
+ int flags,
+ const struct sockaddr *addr,
+ int addrlen,
+ ACE_OVERLAPPED *overlapped,
+ ACE_OVERLAPPED_COMPLETION_FUNC func);
+
+ /// Manipulate the options associated with a socket.
+ static int setsockopt (ACE_HANDLE handle,
+ int level,
+ int optname,
+ const char *optval,
+ int optlen);
+ static int shutdown (ACE_HANDLE handle,
+ int how);
+
+ /// Create a BSD-style socket (no QoS).
+ static ACE_HANDLE socket (int protocol_family,
+ int type,
+ int proto);
+
+ /// Create a QoS-enabled socket. If the OS platform doesn't support
+ /// QoS-enabled <socket> then the BSD-style <socket> is called.
+ static ACE_HANDLE socket (int protocol_family,
+ int type,
+ int proto,
+ ACE_Protocol_Info *protocolinfo,
+ ACE_SOCK_GROUP g,
+ u_long flags);
+
+ static int socketpair (int domain,
+ int type,
+ int protocol,
+ ACE_HANDLE sv[2]);
+
+ /// Initialize WinSock before first use (e.g., when a DLL is first
+ /// loaded or the first use of a socket() call.
+ static int socket_init (int version_high = 1,
+ int version_low = 1);
+
+ /// Finalize WinSock after last use (e.g., when a DLL is unloaded).
+ static int socket_fini (void);
+ //@}
+
+ //@{ @name A set of wrappers for password routines.
+ static void setpwent (void);
+ static void endpwent (void);
+ static struct passwd *getpwent (void);
+ static struct passwd *getpwnam (const char *user);
+ static struct passwd *getpwnam_r (const char *name,
+ struct passwd *pwent,
+ char *buffer,
+ int buflen);
+ //@}
+
+ //@{ @name A set of wrappers for regular expressions.
+ static char *compile (const char *instring,
+ char *expbuf,
+ char *endbuf);
+ static int step (const char *str,
+ char *expbuf);
+ //@}
+
+ //@{ @name Wide-character strings
+ // @@ UNICODE: (brunsch) Can this be handled better?
+ // The following WChar typedef and functions are used by TAO. TAO
+ // does not use wchar_t because the size of wchar_t is
+ // platform-dependent. These are to be used for all
+ // manipulate\ions of CORBA::WString.
+ typedef ACE_UINT16 WChar;
+ static u_int wslen (const WChar *);
+ static WChar *wscpy (WChar *,
+ const WChar *);
+ static int wscmp (const WChar *,
+ const WChar *);
+ static int wsncmp (const WChar *,
+ const WChar *,
+ size_t len);
+ //@}
+
+# if 0
+ //@{ @name A set of wrappers for threads (these are portable since they use the ACE_Thread_ID).
+ static int thr_continue (const ACE_Thread_ID &thread);
+ static int thr_create (ACE_THR_FUNC,
+ void *args,
+ long flags,
+ ACE_Thread_ID *,
+ long priority = ACE_DEFAULT_THREAD_PRIORITY,
+ void *stack = 0,
+ size_t stacksize = 0);
+ static int thr_getprio (ACE_Thread_ID thr_id,
+ int &prio,
+ int *policy = 0);
+ static int thr_join (ACE_Thread_ID waiter_id,
+ void **status);
+ static int thr_kill (ACE_Thread_ID thr_id,
+ int signum);
+ static ACE_Thread_ID thr_self (void);
+ static int thr_setprio (ACE_Thread_ID thr_id,
+ int prio);
+ static int thr_setprio (const ACE_Sched_Priority prio);
+ static int thr_suspend (ACE_Thread_ID target_thread);
+ static int thr_cancel (ACE_Thread_ID t_id);
+ //@}
+# endif /* 0 */
+
+ //@{ @name A set of wrappers for threads
+
+ // These are non-portable since they use ACE_thread_t and
+ // ACE_hthread_t and will go away in a future release.
+ static int thr_continue (ACE_hthread_t target_thread);
+
+ /*
+ * Creates a new thread having <flags> attributes and running <func>
+ * with <args> (if <thread_adapter> is non-0 then <func> and <args>
+ * are ignored and are obtained from <thread_adapter>). <thr_id>
+ * and <t_handle> are set to the thread's ID and handle (?),
+ * respectively. The thread runs at <priority> priority (see
+ * below).
+ *
+ * The <flags> are a bitwise-OR of the following:
+ * = BEGIN<INDENT>
+ * THR_CANCEL_DISABLE, THR_CANCEL_ENABLE, THR_CANCEL_DEFERRED,
+ * THR_CANCEL_ASYNCHRONOUS, THR_BOUND, THR_NEW_LWP, THR_DETACHED,
+ * THR_SUSPENDED, THR_DAEMON, THR_JOINABLE, THR_SCHED_FIFO,
+ * THR_SCHED_RR, THR_SCHED_DEFAULT, THR_EXPLICIT_SCHED,
+ * THR_SCOPE_SYSTEM, THR_SCOPE_PROCESS
+ * = END<INDENT>
+ *
+ * By default, or if <priority> is set to
+ * ACE_DEFAULT_THREAD_PRIORITY, an "appropriate" priority value for
+ * the given scheduling policy (specified in <flags}>, e.g.,
+ * <THR_SCHED_DEFAULT>) is used. This value is calculated
+ * dynamically, and is the median value between the minimum and
+ * maximum priority values for the given policy. If an explicit
+ * value is given, it is used. Note that actual priority values are
+ * EXTREMEMLY implementation-dependent, and are probably best
+ * avoided.
+ *
+ * Note that <thread_adapter> is always deleted by <thr_create>,
+ * therefore it must be allocated with global operator new.
+ */
+ static int thr_create (ACE_THR_FUNC func,
+ void *args,
+ long flags,
+ ACE_thread_t *thr_id,
+ ACE_hthread_t *t_handle = 0,
+ long priority = ACE_DEFAULT_THREAD_PRIORITY,
+ void *stack = 0,
+ size_t stacksize = 0,
+ ACE_Base_Thread_Adapter *thread_adapter = 0);
+
+ static int thr_getprio (ACE_hthread_t thr_id,
+ int &prio);
+ static int thr_join (ACE_hthread_t waiter_id,
+ void **status);
+ static int thr_join (ACE_thread_t waiter_id,
+ ACE_thread_t *thr_id,
+ void **status);
+ static int thr_kill (ACE_thread_t thr_id,
+ int signum);
+ static ACE_thread_t thr_self (void);
+ static void thr_self (ACE_hthread_t &);
+ static int thr_setprio (ACE_hthread_t thr_id,
+ int prio);
+ static int thr_setprio (const ACE_Sched_Priority prio);
+ static int thr_suspend (ACE_hthread_t target_thread);
+ static int thr_cancel (ACE_thread_t t_id);
+
+ static int thr_cmp (ACE_hthread_t t1,
+ ACE_hthread_t t2);
+ static int thr_equal (ACE_thread_t t1,
+ ACE_thread_t t2);
+ static void thr_exit (void *status = 0);
+ static int thr_getconcurrency (void);
+ static int lwp_getparams (ACE_Sched_Params &);
+# if defined (ACE_HAS_TSS_EMULATION) && defined (ACE_HAS_THREAD_SPECIFIC_STORAGE)
+ static int thr_getspecific (ACE_OS_thread_key_t key,
+ void **data);
+# endif /* ACE_HAS_TSS_EMULATION && ACE_HAS_THREAD_SPECIFIC_STORAGE */
+ 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)
+# if defined (ACE_HAS_TSS_EMULATION) && defined (ACE_HAS_THREAD_SPECIFIC_STORAGE)
+ static int thr_keycreate (ACE_OS_thread_key_t *key,
+ ACE_THR_C_DEST,
+ void *inst = 0);
+# endif /* ACE_HAS_TSS_EMULATION && ACE_HAS_THREAD_SPECIFIC_STORAGE */
+ static int thr_keycreate (ACE_thread_key_t *key,
+ ACE_THR_C_DEST,
+ void *inst = 0);
+# else
+# if defined (ACE_HAS_TSS_EMULATION) && defined (ACE_HAS_THREAD_SPECIFIC_STORAGE)
+ static int thr_keycreate (ACE_OS_thread_key_t *key,
+ ACE_THR_DEST,
+ void *inst = 0);
+# endif /* ACE_HAS_TSS_EMULATION && ACE_HAS_THREAD_SPECIFIC_STORAGE */
+ 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);
+ static int lwp_setparams (const ACE_Sched_Params &);
+# if defined (ACE_HAS_TSS_EMULATION) && defined (ACE_HAS_THREAD_SPECIFIC_STORAGE)
+ static int thr_setspecific (ACE_OS_thread_key_t key,
+ void *data);
+# endif /* ACE_HAS_TSS_EMULATION && ACE_HAS_THREAD_SPECIFIC_STORAGE */
+ static int thr_setspecific (ACE_thread_key_t key,
+ void *data);
+ static int thr_sigsetmask (int how,
+ const sigset_t *nsm,
+ sigset_t *osm);
+ static int thr_setcancelstate (int new_state,
+ int *old_state);
+ static int thr_setcanceltype (int new_type,
+ int *old_type);
+ static int sigwait (sigset_t *set,
+ int *sig = 0);
+ static int sigtimedwait (const sigset_t *set,
+ siginfo_t *info,
+ const ACE_Time_Value *timeout);
+ static void thr_testcancel (void);
+ static void thr_yield (void);
+
+ /**
+ * This method uses process id and object pointer to come up with a
+ * machine wide unique name. The process ID will provide uniqueness
+ * between processes on the same machine. The "this" pointer of the
+ * <object> will provide uniqueness between other "live" objects in
+ * the same process. The uniqueness of this name is therefore only
+ * valid for the life of <object>.
+ */
+ static void unique_name (const void *object,
+ ACE_TCHAR *name,
+ size_t length);
+
+ /// This is necessary to deal with POSIX pthreads and their use of
+ /// structures for thread ids.
+ static ACE_thread_t NULL_thread;
+
+ /// This is necessary to deal with POSIX pthreads and their use of
+ /// structures for thread handles.
+ static ACE_hthread_t NULL_hthread;
+
+ /// This is necessary to deal with POSIX pthreads and their use of
+ /// structures for TSS keys.
+ static ACE_thread_key_t NULL_key;
+
+# if defined (CHORUS)
+ /// This is used to map an actor's id into a KnCap for killing and
+ /// waiting actors.
+ static KnCap actorcaps_[ACE_CHORUS_MAX_ACTORS];
+# endif /* CHORUS */
+ //@}
+
+# if defined (ACE_WIN32)
+ /// Keeps track of whether we've already initialized WinSock...
+ static int socket_initialized_;
+# endif /* ACE_WIN32 */
+
+ /// Handle asynchronous thread cancellation cleanup.
+ static void mutex_lock_cleanup (void *mutex);
+
+ /**
+ * Call TSS destructors for the current thread. If the current
+ * thread is the main thread, then the argument must be 1.
+ * For private use of ACE_Object_Manager and ACE_Thread_Adapter only.
+ */
+ static void cleanup_tss (const u_int main_thread);
+
+# if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0) && defined (ACE_LACKS_NETDB_REENTRANT_FUNCTIONS)
+ static int netdb_acquire (void);
+ static int netdb_release (void);
+# endif /* defined (ACE_MT_SAFE) && ACE_LACKS_NETDB_REENTRANT_FUNCTIONS */
+
+ /// Find the schedling class ID that corresponds to the class name.
+ static int scheduling_class (const char *class_name, ACE_id_t &);
+
+ /// Friendly interface to <priocntl>(2).
+ static int set_scheduling_params (const ACE_Sched_Params &,
+ ACE_id_t id = ACE_SELF);
+
+ /// Low-level interface to <priocntl>(2).
+ /**
+ * Can't call the following priocntl, because that's a macro on
+ * Solaris.
+ */
+ static int priority_control (ACE_idtype_t, ACE_id_t, int, void *);
+
+#if defined (ACE_HAS_STRPTIME)
+ static char *strptime (char *buf,
+ const char *format,
+ struct tm *tm);
+
+# if defined (ACE_LACKS_NATIVE_STRPTIME)
+ static int strptime_getnum (char *buf, int *num, int *bi,
+ int *fi, int min, int max);
+# endif /* ACE_LACKS_NATIVE_STRPTIME */
+#endif /* ACE_HAS_STRPTIME */
+
+private:
+
+#if defined (ACE_LACKS_WRITEV)
+ static int writev_emulation (ACE_HANDLE handle,
+ ACE_WRITEV_TYPE *iov,
+ int iovcnt);
+#endif /* ACE_LACKS_WRITEV */
+
+#if defined (ACE_LACKS_READV)
+ static ssize_t readv_emulation (ACE_HANDLE handle,
+ ACE_READV_TYPE *iov,
+ int iovcnt);
+#endif /* ACE_LACKS_READV */
+
+ /// Function that is called by <ACE_OS::exit>, if non-null.
+ static ACE_EXIT_HOOK exit_hook_;
+
+ /// For use by ACE_Object_Manager only, to register its exit hook..
+ static ACE_EXIT_HOOK set_exit_hook (ACE_EXIT_HOOK hook);
+
+ /// Allow the ACE_OS_Object_Manager to call set_exit_hook.
+ friend class ACE_OS_Object_Manager;
+
+# if defined (ACE_WIN32)
+# if defined (ACE_HAS_WINCE)
+ /// Supporting data for ctime and ctime_r functions on WinCE.
+ static const wchar_t *day_of_week_name[7];
+ static const wchar_t *month_name[12];
+# endif /* ACE_HAS_WINCE */
+
+ /// Translate fopen's mode char to open's mode. This helper function
+ /// is here to avoid maintaining several pieces of identical code.
+ static void fopen_mode_to_open_mode_converter (ACE_TCHAR x, int &hmode);
+
+ static OSVERSIONINFO win32_versioninfo_;
+
+ static HINSTANCE win32_resource_module_;
+
+# endif /* ACE_WIN32 */
+
+#if defined (ACE_HAS_VIRTUAL_TIME)
+ static clock_t times (struct tms *buf);
+#endif /* ACE_HAS_VIRTUAL_TIME */
+
+ //changed for ACE_HAS_VIRTUAL_TIME changes.
+
+ static int cond_timedwait_i (ACE_cond_t *cv,
+ ACE_mutex_t *m,
+ ACE_Time_Value *);
+
+ static u_int alarm_i (u_int secs);
+
+ static u_int ualarm_i (u_int usecs, u_int interval = 0);
+
+ static u_int ualarm_i (const ACE_Time_Value &tv,
+ const ACE_Time_Value &tv_interval = ACE_Time_Value::zero);
+
+ static int sleep_i (u_int seconds);
+
+ static int sleep_i (const ACE_Time_Value &tv);
+
+ static int nanosleep_i (const struct timespec *requested,
+ struct timespec *remaining = 0);
+
+ static int select_i (int width,
+ fd_set *rfds,
+ fd_set *wfds,
+ fd_set *efds,
+ const ACE_Time_Value *tv = 0);
+
+ static int select_i (int width,
+ fd_set *rfds,
+ fd_set *wfds,
+ fd_set *efds,
+ const ACE_Time_Value &tv);
+
+ static int poll_i (struct pollfd *pollfds,
+ u_long len,
+ const ACE_Time_Value *tv = 0);
+
+ static int poll_i (struct pollfd *pollfds,
+ u_long len,
+ const ACE_Time_Value &tv);
+
+ static int sema_wait_i (ACE_sema_t *s);
+
+ static int sema_wait_i (ACE_sema_t *s,
+ ACE_Time_Value &tv);
+
+ static int sigtimedwait_i (const sigset_t *set,
+ siginfo_t *info,
+ const ACE_Time_Value *timeout);
+
+ static ACE_Time_Value gettimeofday_i (void);
+};
+
+/**
+ * @class ACE_Object_Manager_Base
+ *
+ * @brief Base class for ACE_Object_Manager(s).
+ *
+ * Encapsulates the most useful ACE_Object_Manager data structures.
+ */
+class ACE_OS_Export ACE_Object_Manager_Base
+{
+# if (defined (ACE_PSOS) && defined (__DIAB)) || \
+ (defined (__DECCXX_VER) && __DECCXX_VER < 60000000)
+ // The Diab compiler got confused and complained about access rights
+ // if this section was protected (changing this to public makes it happy).
+ // Similarly, DEC CXX 5.6 needs the methods to be public.
+public:
+# else /* ! (ACE_PSOS && __DIAB) || ! __DECCXX_VER < 60000000 */
+protected:
+# endif /* ! (ACE_PSOS && __DIAB) || ! __DECCXX_VER < 60000000 */
+ /// Default constructor.
+ ACE_Object_Manager_Base (void);
+
+ /// Destructor.
+ virtual ~ACE_Object_Manager_Base (void);
+
+public:
+ /**
+ * Explicitly initialize. Returns 0 on success, -1 on failure due
+ * to dynamic allocation failure (in which case errno is set to
+ * ENOMEM), or 1 if it had already been called.
+ */
+ virtual int init (void) = 0;
+
+ /**
+ * Explicitly destroy. Returns 0 on success, -1 on failure because
+ * the number of fini () calls hasn't reached the number of init ()
+ * calls, or 1 if it had already been called.
+ */
+ virtual int fini (void) = 0;
+
+ enum Object_Manager_State
+ {
+ OBJ_MAN_UNINITIALIZED = 0,
+ OBJ_MAN_INITIALIZING,
+ OBJ_MAN_INITIALIZED,
+ OBJ_MAN_SHUTTING_DOWN,
+ OBJ_MAN_SHUT_DOWN
+ };
+
+protected:
+ /**
+ * Returns 1 before ACE_Object_Manager_Base has been constructed.
+ * This flag can be used to determine if the program is constructing
+ * static objects. If no static object spawns any threads, the
+ * program will be single-threaded when this flag returns 1. (Note
+ * that the program still might construct some static objects when
+ * this flag returns 0, if ACE_HAS_NONSTATIC_OBJECT_MANAGER is not
+ * defined.)
+ */
+ int starting_up_i (void);
+
+ /**
+ * Returns 1 after ACE_Object_Manager_Base has been destroyed. This
+ * flag can be used to determine if the program is in the midst of
+ * destroying static objects. (Note that the program might destroy
+ * some static objects before this flag can return 1, if
+ * ACE_HAS_NONSTATIC_OBJECT_MANAGER is not defined.)
+ */
+ int shutting_down_i (void);
+
+ /// State of the Object_Manager;
+ Object_Manager_State object_manager_state_;
+
+ /**
+ * Flag indicating whether the ACE_Object_Manager was dynamically
+ * allocated by ACE. (If is was dynamically allocated by the
+ * application, then the application is responsible for destroying
+ * it.)
+ */
+ u_int dynamically_allocated_;
+
+ /// Link to next Object_Manager, for chaining.
+ ACE_Object_Manager_Base *next_;
+private:
+ // Disallow copying by not implementing the following . . .
+ ACE_Object_Manager_Base (const ACE_Object_Manager_Base &);
+ ACE_Object_Manager_Base &operator= (const ACE_Object_Manager_Base &);
+};
+
+extern "C"
+void
+ACE_OS_Object_Manager_Internal_Exit_Hook (void);
+
+
+// @@ This forward declaration should go away.
+class ACE_Log_Msg;
+
+class ACE_OS_Export ACE_OS_Object_Manager : public ACE_Object_Manager_Base
+{
+public:
+ /// Explicitly initialize.
+ virtual int init (void);
+
+ /// Explicitly destroy.
+ virtual int fini (void);
+
+ /**
+ * Returns 1 before the <ACE_OS_Object_Manager> has been
+ * constructed. See <ACE_Object_Manager::starting_up> for more
+ * information.
+ */
+ static int starting_up (void);
+
+ /// Returns 1 after the <ACE_OS_Object_Manager> has been destroyed.
+ /// See <ACE_Object_Manager::shutting_down> for more information.
+ static int shutting_down (void);
+
+ /// Unique identifiers for preallocated objects.
+ enum Preallocated_Object
+ {
+# if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0)
+ ACE_OS_MONITOR_LOCK,
+ ACE_TSS_CLEANUP_LOCK,
+ ACE_LOG_MSG_INSTANCE_LOCK,
+# if defined (ACE_HAS_TSS_EMULATION)
+ ACE_TSS_KEY_LOCK,
+# if defined (ACE_HAS_THREAD_SPECIFIC_STORAGE)
+ ACE_TSS_BASE_LOCK,
+# endif /* ACE_HAS_THREAD_SPECIFIC_STORAGE */
+# endif /* ACE_HAS_TSS_EMULATION */
+# else
+ // Without ACE_MT_SAFE, There are no preallocated objects. Make
+ // sure that the preallocated_array size is at least one by
+ // declaring this dummy . . .
+ ACE_OS_EMPTY_PREALLOCATED_OBJECT,
+# endif /* ACE_MT_SAFE */
+
+ /// This enum value must be last!
+ ACE_OS_PREALLOCATED_OBJECTS
+ };
+
+ /// Accesses a default signal set used, for example, in
+ /// <ACE_Sig_Guard> methods.
+ static sigset_t *default_mask (void);
+
+ /// Returns the current thread hook for the process.
+ static ACE_Thread_Hook *thread_hook (void);
+
+ /// Returns the existing thread hook and assign a <new_thread_hook>.
+ static ACE_Thread_Hook *thread_hook (ACE_Thread_Hook *new_thread_hook);
+
+#if defined (ACE_HAS_WIN32_STRUCTURAL_EXCEPTIONS)
+ /// Get/Set TSS exception action.
+ static ACE_SEH_EXCEPT_HANDLER seh_except_selector (void);
+ static ACE_SEH_EXCEPT_HANDLER seh_except_selector (ACE_SEH_EXCEPT_HANDLER);
+
+ static ACE_SEH_EXCEPT_HANDLER seh_except_handler (void);
+ static ACE_SEH_EXCEPT_HANDLER seh_except_handler (ACE_SEH_EXCEPT_HANDLER);
+#endif /* ACE_HAS_WIN32_STRUCTURAL_EXCEPTIONS */
+
+public:
+ // = Applications shouldn't use these so they're hidden here.
+
+ // They're public so that the <ACE_Object_Manager> can be
+ // constructed/destructed in <main> with
+ // <ACE_HAS_NONSTATIC_OBJECT_MANAGER>.
+ /// Constructor.
+ ACE_OS_Object_Manager (void);
+
+ /// Destructor.
+ ~ACE_OS_Object_Manager (void);
+
+private:
+ /// Accessor to singleton instance.
+ static ACE_OS_Object_Manager *instance (void);
+
+ /// Singleton instance pointer.
+ static ACE_OS_Object_Manager *instance_;
+
+ /// Table of preallocated objects.
+ static void *preallocated_object[ACE_OS_PREALLOCATED_OBJECTS];
+
+ /// Default signal set used, for example, in ACE_Sig_Guard.
+ sigset_t *default_mask_;
+
+ /// Thread hook that's used by this process.
+ ACE_Thread_Hook *thread_hook_;
+
+ /// For at_exit support.
+ ACE_OS_Exit_Info exit_info_;
+
+#if defined (ACE_HAS_WIN32_STRUCTURAL_EXCEPTIONS)
+ /// These handlers determine how a thread handles win32 structured
+ /// exception.
+ ACE_SEH_EXCEPT_HANDLER seh_except_selector_;
+ ACE_SEH_EXCEPT_HANDLER seh_except_handler_;
+#endif /* ACE_HAS_WIN32_STRUCTURAL_EXCEPTIONS */
+
+ /// For <ACE_OS::atexit> support.
+ int at_exit (ACE_EXIT_HOOK func);
+
+ /// For use by init () and fini (), to consolidate error reporting.
+ static void print_error_message (u_int line_number, const ACE_TCHAR *message);
+
+ /// This class is for internal use by ACE_OS, etc., only.
+ friend class ACE_OS;
+ friend class ACE_Object_Manager;
+ friend class ACE_OS_Object_Manager_Manager;
+ friend class ACE_TSS_Cleanup;
+ friend class ACE_TSS_Emulation;
+ friend class ACE_Log_Msg;
+ friend void ACE_OS_Object_Manager_Internal_Exit_Hook ();
+};
+
+# if defined (ACE_LACKS_TIMEDWAIT_PROTOTYPES)
+extern "C" ssize_t recv_timedwait (ACE_HANDLE handle,
+ char *buf,
+ int len,
+ int flags,
+ struct timespec *timeout);
+extern "C" ssize_t read_timedwait (ACE_HANDLE handle,
+ char *buf,
+ size_t n,
+ struct timespec *timeout);
+extern "C" ssize_t recvmsg_timedwait (ACE_HANDLE handle,
+ struct msghdr *msg,
+ int flags,
+ struct timespec *timeout);
+extern "C" ssize_t recvfrom_timedwait (ACE_HANDLE handle,
+ char *buf,
+ int len,
+ int flags,
+ struct sockaddr *addr,
+ int
+ *addrlen,
+ struct timespec *timeout);
+extern "C" ssize_t readv_timedwait (ACE_HANDLE handle,
+ iovec *iov,
+ int iovcnt,
+ struct timespec* timeout);
+extern "C" ssize_t send_timedwait (ACE_HANDLE handle,
+ const char *buf,
+ int len,
+ int flags,
+ struct timespec *timeout);
+extern "C" ssize_t write_timedwait (ACE_HANDLE handle,
+ const void *buf,
+ size_t n,
+ struct timespec *timeout);
+extern "C" ssize_t sendmsg_timedwait (ACE_HANDLE handle,
+ ACE_SENDMSG_TYPE *msg,
+ int flags,
+ struct timespec *timeout);
+extern "C" ssize_t sendto_timedwait (ACE_HANDLE handle,
+ const char *buf,
+ int len,
+ int flags,
+ const struct sockaddr *addr,
+ int addrlen,
+ struct timespec *timeout);
+extern "C" ssize_t writev_timedwait (ACE_HANDLE handle,
+ ACE_WRITEV_TYPE *iov,
+ int iovcnt,
+ struct timespec *timeout);
+# endif /* ACE_LACKS_TIMEDWAIT_PROTOTYPES */
+
+# if defined (ACE_HAS_TSS_EMULATION)
+ // Allow config.h to set the default number of thread keys.
+# if !defined (ACE_DEFAULT_THREAD_KEYS)
+# define ACE_DEFAULT_THREAD_KEYS 64
+# endif /* ! ACE_DEFAULT_THREAD_KEYS */
+
+// forward declaration
+class ACE_TSS_Keys;
+
+/**
+ * @class ACE_TSS_Emulation
+ *
+ * @brief Thread-specific storage emulation.
+ *
+ * This provides a thread-specific storage implementation.
+ * It is intended for use on platforms that don't have a
+ * native TSS, or have a TSS with limitations such as the
+ * number of keys or lack of support for removing keys.
+ */
+class ACE_OS_Export ACE_TSS_Emulation
+{
+public:
+ typedef void (*ACE_TSS_DESTRUCTOR)(void *value) /* throw () */;
+
+ /// Maximum number of TSS keys allowed over the life of the program.
+ enum { ACE_TSS_THREAD_KEYS_MAX = ACE_DEFAULT_THREAD_KEYS };
+
+ /// Returns the total number of keys allocated so far.
+ static u_int total_keys ();
+
+ /// Sets the argument to the next available key. Returns 0 on success,
+ /// -1 if no keys are available.
+ static int next_key (ACE_thread_key_t &key);
+
+ /// Release a key that was used. This way the key can be given out in a
+ /// new request. Returns 0 on success, 1 if the key was not reserved.
+ static int release_key (ACE_thread_key_t key);
+
+ /// Returns the exit hook associated with the key. Does _not_ check
+ /// for a valid key.
+ static ACE_TSS_DESTRUCTOR tss_destructor (const ACE_thread_key_t key);
+
+ /// Associates the TSS destructor with the key. Does _not_ check
+ /// for a valid key.
+ static void tss_destructor (const ACE_thread_key_t key,
+ ACE_TSS_DESTRUCTOR destructor);
+
+ /// Accesses the object referenced by key in the current thread's TSS array.
+ /// Does _not_ check for a valid key.
+ static void *&ts_object (const ACE_thread_key_t key);
+
+ /**
+ * Setup an array to be used for local TSS. Returns the array
+ * address on success. Returns 0 if local TSS had already been
+ * setup for this thread. There is no corresponding tss_close ()
+ * because it is not needed.
+ * NOTE: tss_open () is called by ACE for threads that it spawns.
+ * If your application spawns threads without using ACE, and it uses
+ * ACE's TSS emulation, each of those threads should call tss_open
+ * (). See the ace_thread_adapter () implementaiton for an example.
+ */
+ static void *tss_open (void *ts_storage[ACE_TSS_THREAD_KEYS_MAX]);
+
+ /// Shutdown TSS emulation. For use only by ACE_OS::cleanup_tss ().
+ static void tss_close ();
+
+private:
+ // Global TSS structures.
+ /// Contains the possible value of the next key to be allocated. Which key
+ /// is actually allocated is based on the tss_keys_used
+ static u_int total_keys_;
+
+ /// Array of thread exit hooks (TSS destructors) that are called for each
+ /// key (that has one) when the thread exits.
+ static ACE_TSS_DESTRUCTOR tss_destructor_ [ACE_TSS_THREAD_KEYS_MAX];
+
+ /// TSS_Keys instance to administrate whether a specific key is in used
+ /// or not
+ static ACE_TSS_Keys tss_keys_used_;
+
+# if defined (ACE_HAS_THREAD_SPECIFIC_STORAGE)
+ /// Location of current thread's TSS array.
+ static void **tss_base (void* ts_storage[] = 0, u_int *ts_created = 0);
+# else /* ! ACE_HAS_THREAD_SPECIFIC_STORAGE */
+ /// Location of current thread's TSS array.
+ static void **&tss_base ();
+# endif /* ! ACE_HAS_THREAD_SPECIFIC_STORAGE */
+
+# if defined (ACE_HAS_THREAD_SPECIFIC_STORAGE)
+ // Rely on native thread specific storage for the implementation,
+ // but just use one key.
+ static ACE_OS_thread_key_t native_tss_key_;
+
+ // Used to indicate if native tss key has been allocated
+ static int key_created_;
+# endif /* ACE_HAS_THREAD_SPECIFIC_STORAGE */
+};
+
+# else /* ! ACE_HAS_TSS_EMULATION */
+# if defined (TLS_MINIMUM_AVAILABLE)
+ // WIN32 platforms define TLS_MINIMUM_AVAILABLE natively.
+# define ACE_DEFAULT_THREAD_KEYS TLS_MINIMUM_AVAILABLE
+# endif /* TSL_MINIMUM_AVAILABLE */
+
+# endif /* ACE_HAS_TSS_EMULATION */
+
+// moved ACE_TSS_Ref, ACE_TSS_Info, and ACE_TSS_Keys class
+// declarations from OS.cpp so they are visible to the single
+// file of template instantiations.
+# if defined (ACE_WIN32) || defined (ACE_HAS_TSS_EMULATION) || (defined (ACE_PSOS) && defined (ACE_PSOS_HAS_TSS))
+/**
+ * @class ACE_TSS_Ref
+ *
+ * @brief "Reference count" for thread-specific storage keys.
+ *
+ * Since the <ACE_Unbounded_Stack> doesn't allow duplicates, the
+ * "reference count" is the identify of the thread_id.
+ */
+class ACE_TSS_Ref
+{
+public:
+ /// Constructor
+ ACE_TSS_Ref (ACE_thread_t id);
+
+ /// Default constructor
+ ACE_TSS_Ref (void);
+
+ /// Check for equality.
+ int operator== (const ACE_TSS_Ref &) const;
+
+ /// Check for inequality.
+ int operator!= (const ACE_TSS_Ref &) const;
+
+// private:
+
+ /// ID of thread using a specific key.
+ ACE_thread_t tid_;
+};
+
+/**
+ * @class ACE_TSS_Info
+ *
+ * @brief Thread Specific Key management.
+ *
+ * This class maps a key to a "destructor."
+ */
+class ACE_TSS_Info
+{
+public:
+ /// Constructor
+ ACE_TSS_Info (ACE_thread_key_t key,
+ void (*dest)(void *) = 0,
+ void *tss_inst = 0);
+
+ /// Default constructor
+ ACE_TSS_Info (void);
+
+ /// Returns 1 if the key is in use, 0 if not.
+ int key_in_use (void) const { return thread_count_ != -1; }
+
+ /// Mark the key as being in use if the flag is non-zero, or
+ /// not in use if the flag is 0.
+ void key_in_use (int flag) { thread_count_ = flag == 0 ? -1 : 1; }
+
+ /// Check for equality.
+ int operator== (const ACE_TSS_Info &) const;
+
+ /// Check for inequality.
+ int operator!= (const ACE_TSS_Info &) const;
+
+ /// Dump the state.
+ void dump (void);
+
+private:
+ /// Key to the thread-specific storage item.
+ ACE_thread_key_t key_;
+
+ /// "Destructor" that gets called when the item is finally released.
+ void (*destructor_)(void *);
+
+ /// Pointer to ACE_TSS<xxx> instance that has/will allocate the key.
+ void *tss_obj_;
+
+ /// Count of threads that are using this key. Contains -1 when the
+ /// key is not in use.
+ int thread_count_;
+
+ friend class ACE_TSS_Cleanup;
+};
+
+/**
+ * @class ACE_TSS_Keys
+ *
+ * @brief Collection of in-use flags for a thread's TSS keys.
+ * For internal use only by ACE_TSS_Cleanup; it is public because
+ * some compilers can't use nested classes for template instantiation
+ * parameters.
+ *
+ * Wrapper around array of whether each key is in use. A simple
+ * typedef doesn't work with Sun C++ 4.2.
+ */
+class ACE_TSS_Keys
+{
+public:
+ /// Default constructor, to initialize all bits to zero (unused).
+ ACE_TSS_Keys (void);
+
+ /// Mark the specified key as being in use, if it was not already so marked.
+ /// Returns 1 if the had already been marked, 0 if not.
+ int test_and_set (const ACE_thread_key_t key);
+
+ /// Mark the specified key as not being in use, if it was not already so
+ /// cleared. Returns 1 if the key had already been cleared, 0 if not.
+ int test_and_clear (const ACE_thread_key_t key);
+
+ /// Return whether the specific key is marked as in use.
+ /// Returns 1 if the key is been marked, 0 if not.
+ int is_set (const ACE_thread_key_t key) const;
+
+private:
+ /// For a given key, find the word and bit number that represent it.
+ static void find (const u_int key, u_int &word, u_int &bit);
+
+ enum
+ {
+# if ACE_SIZEOF_LONG == 8
+ ACE_BITS_PER_WORD = 64,
+# elif ACE_SIZEOF_LONG == 4
+ ACE_BITS_PER_WORD = 32,
+# else
+# error ACE_TSS_Keys only supports 32 or 64 bit longs.
+# endif /* ACE_SIZEOF_LONG == 8 */
+ ACE_WORDS = (ACE_DEFAULT_THREAD_KEYS - 1) / ACE_BITS_PER_WORD + 1
+ };
+
+ /// Bit flag collection. A bit value of 1 indicates that the key is in
+ /// use by this thread.
+ u_long key_bit_words_[ACE_WORDS];
+};
+
+# endif /* defined (ACE_WIN32) || defined (ACE_HAS_TSS_EMULATION) */
+
+// Support non-scalar thread keys, such as with some POSIX
+// implementations, e.g., MVS.
+# if defined (ACE_HAS_NONSCALAR_THREAD_KEY_T)
+# define ACE_KEY_INDEX(OBJ,KEY) \
+ u_int OBJ; \
+ ACE_OS::memcpy (&OBJ, &KEY, sizeof (u_int))
+# else
+# define ACE_KEY_INDEX(OBJ,KEY) u_int OBJ = KEY
+# endif /* ACE_HAS_NONSCALAR_THREAD_KEY_T */
+
+// Some useful abstrations for expressions involving
+// ACE_Allocator.malloc (). The difference between ACE_NEW_MALLOC*
+// with ACE_ALLOCATOR* is that they call constructors also.
+
+# define ACE_ALLOCATOR_RETURN(POINTER,ALLOCATOR,RET_VAL) \
+ do { POINTER = ALLOCATOR; \
+ if (POINTER == 0) { errno = ENOMEM; return RET_VAL; } \
+ } while (0)
+# define ACE_ALLOCATOR(POINTER,ALLOCATOR) \
+ do { POINTER = ALLOCATOR; \
+ if (POINTER == 0) { errno = ENOMEM; return; } \
+ } while (0)
+
+# define ACE_NEW_MALLOC_RETURN(POINTER,ALLOCATOR,CONSTRUCTOR,RET_VAL) \
+ do { POINTER = ALLOCATOR; \
+ if (POINTER == 0) { errno = ENOMEM; return RET_VAL;} \
+ else { new (POINTER) CONSTRUCTOR; } \
+ } while (0)
+# define ACE_NEW_MALLOC(POINTER,ALLOCATOR,CONSTRUCTOR) \
+ do { POINTER = ALLOCATOR; \
+ if (POINTER == 0) { errno = ENOMEM; return;} \
+ else { new (POINTER) CONSTRUCTOR; } \
+ } while (0)
+
+# define ACE_NOOP(x)
+
+# define ACE_DES_NOFREE(POINTER,CLASS) \
+ do { \
+ if (POINTER) \
+ { \
+ (POINTER)->~CLASS (); \
+ } \
+ } \
+ while (0)
+
+# define ACE_DES_ARRAY_NOFREE(POINTER,SIZE,CLASS) \
+ do { \
+ if (POINTER) \
+ { \
+ for (size_t i = 0; \
+ i < SIZE; \
+ ++i) \
+ { \
+ (&(POINTER)[i])->~CLASS (); \
+ } \
+ } \
+ } \
+ while (0)
+
+# define ACE_DES_FREE(POINTER,DEALLOCATOR,CLASS) \
+ do { \
+ if (POINTER) \
+ { \
+ (POINTER)->~CLASS (); \
+ DEALLOCATOR (POINTER); \
+ } \
+ } \
+ while (0)
+
+# define ACE_DES_ARRAY_FREE(POINTER,SIZE,DEALLOCATOR,CLASS) \
+ do { \
+ if (POINTER) \
+ { \
+ for (size_t i = 0; \
+ i < SIZE; \
+ ++i) \
+ { \
+ (&(POINTER)[i])->~CLASS (); \
+ } \
+ DEALLOCATOR (POINTER); \
+ } \
+ } \
+ while (0)
+
+# if defined (ACE_HAS_WORKING_EXPLICIT_TEMPLATE_DESTRUCTOR)
+# define ACE_DES_NOFREE_TEMPLATE(POINTER,T_CLASS,T_PARAMETER) \
+ do { \
+ if (POINTER) \
+ { \
+ (POINTER)->~T_CLASS (); \
+ } \
+ } \
+ while (0)
+# define ACE_DES_ARRAY_NOFREE_TEMPLATE(POINTER,SIZE,T_CLASS,T_PARAMETER) \
+ do { \
+ if (POINTER) \
+ { \
+ for (size_t i = 0; \
+ i < SIZE; \
+ ++i) \
+ { \
+ (&(POINTER)[i])->~T_CLASS (); \
+ } \
+ } \
+ } \
+ while (0)
+#if defined(__IBMCPP__) && (__IBMCPP__ >= 400)
+# define ACE_DES_FREE_TEMPLATE(POINTER,DEALLOCATOR,T_CLASS,T_PARAMETER) \
+ do { \
+ if (POINTER) \
+ { \
+ (POINTER)->~T_CLASS T_PARAMETER (); \
+ DEALLOCATOR (POINTER); \
+ } \
+ } \
+ while (0)
+#else
+# define ACE_DES_FREE_TEMPLATE(POINTER,DEALLOCATOR,T_CLASS,T_PARAMETER) \
+ do { \
+ if (POINTER) \
+ { \
+ (POINTER)->~T_CLASS (); \
+ DEALLOCATOR (POINTER); \
+ } \
+ } \
+ while (0)
+#endif /* defined(__IBMCPP__) && (__IBMCPP__ >= 400) */
+# define ACE_DES_ARRAY_FREE_TEMPLATE(POINTER,SIZE,DEALLOCATOR,T_CLASS,T_PARAMETER) \
+ do { \
+ if (POINTER) \
+ { \
+ for (size_t i = 0; \
+ i < SIZE; \
+ ++i) \
+ { \
+ (&(POINTER)[i])->~T_CLASS (); \
+ } \
+ DEALLOCATOR (POINTER); \
+ } \
+ } \
+ while (0)
+#if defined(__IBMCPP__) && (__IBMCPP__ >= 400)
+# define ACE_DES_FREE_TEMPLATE2(POINTER,DEALLOCATOR,T_CLASS,T_PARAM1,T_PARAM2) \
+ do { \
+ if (POINTER) \
+ { \
+ (POINTER)->~T_CLASS <T_PARAM1, T_PARAM2> (); \
+ DEALLOCATOR (POINTER); \
+ } \
+ } \
+ while (0)
+#else
+# define ACE_DES_FREE_TEMPLATE2(POINTER,DEALLOCATOR,T_CLASS,T_PARAM1,T_PARAM2) \
+ do { \
+ if (POINTER) \
+ { \
+ (POINTER)->~T_CLASS (); \
+ DEALLOCATOR (POINTER); \
+ } \
+ } \
+ while (0)
+#endif /* defined(__IBMCPP__) && (__IBMCPP__ >= 400) */
+# define ACE_DES_FREE_TEMPLATE3(POINTER,DEALLOCATOR,T_CLASS,T_PARAM1,T_PARAM2,T_PARAM3) \
+ do { \
+ if (POINTER) \
+ { \
+ (POINTER)->~T_CLASS (); \
+ DEALLOCATOR (POINTER); \
+ } \
+ } \
+ while (0)
+# define ACE_DES_FREE_TEMPLATE4(POINTER,DEALLOCATOR,T_CLASS,T_PARAM1,T_PARAM2,T_PARAM3, T_PARAM4) \
+ do { \
+ if (POINTER) \
+ { \
+ (POINTER)->~T_CLASS (); \
+ DEALLOCATOR (POINTER); \
+ } \
+ } \
+ while (0)
+# define ACE_DES_ARRAY_FREE_TEMPLATE2(POINTER,SIZE,DEALLOCATOR,T_CLASS,T_PARAM1,T_PARAM2) \
+ do { \
+ if (POINTER) \
+ { \
+ for (size_t i = 0; \
+ i < SIZE; \
+ ++i) \
+ { \
+ (&(POINTER)[i])->~T_CLASS (); \
+ } \
+ DEALLOCATOR (POINTER); \
+ } \
+ } \
+ while (0)
+# else /* ! ACE_HAS_WORKING_EXPLICIT_TEMPLATE_DESTRUCTOR */
+# define ACE_DES_NOFREE_TEMPLATE(POINTER,T_CLASS,T_PARAMETER) \
+ do { \
+ if (POINTER) \
+ { \
+ (POINTER)->T_CLASS T_PARAMETER::~T_CLASS (); \
+ } \
+ } \
+ while (0)
+# define ACE_DES_ARRAY_NOFREE_TEMPLATE(POINTER,SIZE,T_CLASS,T_PARAMETER) \
+ do { \
+ if (POINTER) \
+ { \
+ for (size_t i = 0; \
+ i < SIZE; \
+ ++i) \
+ { \
+ (POINTER)[i].T_CLASS T_PARAMETER::~T_CLASS (); \
+ } \
+ } \
+ } \
+ while (0)
+# if defined (__Lynx__) && __LYNXOS_SDK_VERSION == 199701L
+ // LynxOS 3.0.0's g++ has trouble with the real versions of these.
+# define ACE_DES_FREE_TEMPLATE(POINTER,DEALLOCATOR,T_CLASS,T_PARAMETER)
+# define ACE_DES_ARRAY_FREE_TEMPLATE(POINTER,DEALLOCATOR,T_CLASS,T_PARAMETER)
+# define ACE_DES_FREE_TEMPLATE2(POINTER,DEALLOCATOR,T_CLASS,T_PARAM1,T_PARAM2)
+# define ACE_DES_FREE_TEMPLATE3(POINTER,DEALLOCATOR,T_CLASS,T_PARAM1,T_PARAM2)
+# define ACE_DES_FREE_TEMPLATE4(POINTER,DEALLOCATOR,T_CLASS,T_PARAM1,T_PARAM2)
+# define ACE_DES_ARRAY_FREE_TEMPLATE2(POINTER,DEALLOCATOR,T_CLASS,T_PARAM1,T_PARAM2)
+# else
+# define ACE_DES_FREE_TEMPLATE(POINTER,DEALLOCATOR,T_CLASS,T_PARAMETER) \
+ do { \
+ if (POINTER) \
+ { \
+ POINTER->T_CLASS T_PARAMETER::~T_CLASS (); \
+ DEALLOCATOR (POINTER); \
+ } \
+ } \
+ while (0)
+# define ACE_DES_ARRAY_FREE_TEMPLATE(POINTER,SIZE,DEALLOCATOR,T_CLASS,T_PARAMETER) \
+ do { \
+ if (POINTER) \
+ { \
+ for (size_t i = 0; \
+ i < SIZE; \
+ ++i) \
+ { \
+ POINTER[i].T_CLASS T_PARAMETER::~T_CLASS (); \
+ } \
+ DEALLOCATOR (POINTER); \
+ } \
+ } \
+ while (0)
+# define ACE_DES_FREE_TEMPLATE2(POINTER,DEALLOCATOR,T_CLASS,T_PARAM1,T_PARAM2) \
+ do { \
+ if (POINTER) \
+ { \
+ POINTER->T_CLASS <T_PARAM1, T_PARAM2>::~T_CLASS (); \
+ DEALLOCATOR (POINTER); \
+ } \
+ } \
+ while (0)
+# define ACE_DES_FREE_TEMPLATE3(POINTER,DEALLOCATOR,T_CLASS,T_PARAM1,T_PARAM2,T_PARAM3) \
+ do { \
+ if (POINTER) \
+ { \
+ POINTER->T_CLASS <T_PARAM1, T_PARAM2, T_PARAM3>::~T_CLASS (); \
+ DEALLOCATOR (POINTER); \
+ } \
+ } \
+ while (0)
+# define ACE_DES_FREE_TEMPLATE4(POINTER,DEALLOCATOR,T_CLASS,T_PARAM1,T_PARAM2,T_PARAM3,T_PARAM4) \
+ do { \
+ if (POINTER) \
+ { \
+ POINTER->T_CLASS <T_PARAM1, T_PARAM2, T_PARAM3, T_PARAM4>::~T_CLASS (); \
+ DEALLOCATOR (POINTER); \
+ } \
+ } \
+ while (0)
+# define ACE_DES_ARRAY_FREE_TEMPLATE2(POINTER,SIZE,DEALLOCATOR,T_CLASS,T_PARAM1,T_PARAM2) \
+ do { \
+ if (POINTER) \
+ { \
+ for (size_t i = 0; \
+ i < SIZE; \
+ ++i) \
+ { \
+ POINTER[i].T_CLASS <T_PARAM1, T_PARAM2>::~T_CLASS (); \
+ } \
+ DEALLOCATOR (POINTER); \
+ } \
+ } \
+ while (0)
+# endif /* defined (__Lynx__) && __LYNXOS_SDK_VERSION == 199701L */
+# endif /* defined ! ACE_HAS_WORKING_EXPLICIT_TEMPLATE_DESTRUCTOR */
+
+#if defined (ACE_HAS_PACE)
+# define ACE_PTHREAD_CLEANUP_PUSH(A) pace_pthread_cleanup_push (ACE_OS::mutex_lock_cleanup, (void *) A);
+# define ACE_PTHREAD_CLEANUP_POP(A) pace_pthread_cleanup_pop(A)
+# elif defined (ACE_HAS_THR_C_FUNC)
+// This is necessary to work around nasty problems with MVS C++.
+extern "C" ACE_OS_Export void ace_mutex_lock_cleanup_adapter (void *args);
+# define ACE_PTHREAD_CLEANUP_PUSH(A) pthread_cleanup_push (ace_mutex_lock_cleanup_adapter, (void *) A);
+# define ACE_PTHREAD_CLEANUP_POP(A) pthread_cleanup_pop(A)
+# elif defined (ACE_HAS_PTHREADS) && !defined (ACE_LACKS_PTHREAD_CLEANUP)
+// Though we are defining a extern "C" function to match the prototype of
+// pthread_cleanup_push, it is undone by the Solaris header file
+// /usr/include/pthread.h. So this macro generates a warning under Solaris
+// with SunCC. This is a bug in the Solaris header file.
+extern "C" ACE_OS_Export void ace_mutex_lock_cleanup_adapter (void *args);
+# define ACE_PTHREAD_CLEANUP_PUSH(A) pthread_cleanup_push (ace_mutex_lock_cleanup_adapter, (void *) A);
+# define ACE_PTHREAD_CLEANUP_POP(A) pthread_cleanup_pop(A)
+# else
+# define ACE_PTHREAD_CLEANUP_PUSH(A)
+# define ACE_PTHREAD_CLEANUP_POP(A)
+# endif /* ACE_HAS_PACE */
+
+# if !defined (ACE_DEFAULT_MUTEX_A)
+# define ACE_DEFAULT_MUTEX_A "ACE_MUTEX"
+# endif /* ACE_DEFAULT_MUTEX_A */
+
+# if defined (ACE_HAS_WCHAR)
+# define ACE_DEFAULT_MUTEX_W ACE_TEXT_WIDE(ACE_DEFAULT_MUTEX_A)
+# endif /* ACE_HAS_WCHAR */
+
+# define ACE_DEFAULT_MUTEX ACE_LIB_TEXT (ACE_DEFAULT_MUTEX_A)
+
+# if !defined (ACE_MAIN)
+# define ACE_MAIN main
+# endif /* ! ACE_MAIN */
+
+# if defined (ACE_DOESNT_INSTANTIATE_NONSTATIC_OBJECT_MANAGER)
+# if !defined (ACE_HAS_NONSTATIC_OBJECT_MANAGER)
+# define ACE_HAS_NONSTATIC_OBJECT_MANAGER
+# endif /* ACE_HAS_NONSTATIC_OBJECT_MANAGER */
+# endif /* ACE_DOESNT_INSTANTIATE_NONSTATIC_OBJECT_MANAGER */
+
+# if defined (ACE_HAS_NONSTATIC_OBJECT_MANAGER) && !defined (ACE_DOESNT_INSTANTIATE_NONSTATIC_OBJECT_MANAGER)
+
+# if !defined (ACE_HAS_MINIMAL_ACE_OS)
+# include "ace/Object_Manager.h"
+# endif /* ! ACE_HAS_MINIMAL_ACE_OS */
+
+// Rename "main ()" on platforms that don't allow it to be called "main ()".
+
+// Also, create ACE_Object_Manager static instance(s) in "main ()".
+// ACE_MAIN_OBJECT_MANAGER defines the ACE_Object_Manager(s) that will
+// be instantiated on the stack of main (). Note that it is only used
+// when compiling main (): its value does not affect the contents of
+// ace/OS.o.
+# if !defined (ACE_MAIN_OBJECT_MANAGER)
+# define ACE_MAIN_OBJECT_MANAGER \
+ ACE_OS_Object_Manager ace_os_object_manager; \
+ ACE_Object_Manager ace_object_manager;
+# endif /* ! ACE_MAIN_OBJECT_MANAGER */
+
+# if defined (ACE_PSOSIM)
+// PSOSIM root lacks the standard argc, argv command line parameters,
+// create dummy argc and argv in the "real" main and pass to "user" main.
+// NOTE: ACE_MAIN must be defined to give the return type as well as the
+// name of the entry point.
+# define main \
+ace_main_i (int, char *[]); /* forward declaration */ \
+ACE_MAIN () /* user's entry point, e.g., "main" w/out argc, argv */ \
+{ \
+ int argc = 1; /* dummy arg count */ \
+ char *argv[] = {"psosim"}; /* dummy arg list */ \
+ ACE_MAIN_OBJECT_MANAGER \
+ int ret_val = -1; /* assume the worst */ \
+ if (ACE_PSOS_Time_t::init_simulator_time ()) /* init simulator time */ \
+ { \
+ ACE_ERROR((LM_ERROR, "init_simulator_time failed\n")); /* report */ \
+ } \
+ else \
+ { \
+ ret_val = ace_main_i (argc, argv); /* call user main, save result */ \
+ } \
+ ACE_OS::exit (ret_val); /* pass code to simulator exit */ \
+} \
+int \
+ace_main_i
+# elif defined (ACE_PSOS) && defined (ACE_PSOS_LACKS_ARGC_ARGV)
+// PSOS root lacks the standard argc, argv command line parameters,
+// create dummy argc and argv in the "real" main and pass to "user" main.
+// Ignore return value from user main as well. NOTE: ACE_MAIN must be
+// defined to give the return type as well as the name of the entry point
+# define main \
+ace_main_i (int, char *[]); /* forward declaration */ \
+ACE_MAIN () /* user's entry point, e.g., "main" w/out argc, argv */ \
+{ \
+ int argc = 1; /* dummy arg count */ \
+ char *argv[] = {"root"}; /* dummy arg list */ \
+ ACE_MAIN_OBJECT_MANAGER \
+ ace_main_i (argc, argv); /* call user main, ignore result */ \
+} \
+int \
+ace_main_i
+# else
+# define main \
+ace_main_i (int, ACE_TCHAR *[]); /* forward declaration */ \
+int \
+ACE_MAIN (int argc, ACE_TCHAR *argv[]) /* user's entry point, e.g., main */ \
+{ \
+ ACE_MAIN_OBJECT_MANAGER \
+ return ace_main_i (argc, argv); /* what the user calls "main" */ \
+} \
+int \
+ace_main_i
+# if defined (ACE_WIN32) && defined (UNICODE)
+# define wmain \
+ace_main_i (int, ACE_TCHAR *[]); /* forward declaration */ \
+int \
+wmain (int argc, ACE_TCHAR *argv[]) /* user's entry point, e.g., main */ \
+{ \
+ ACE_MAIN_OBJECT_MANAGER \
+ return ace_main_i (argc, argv); /* what the user calls "main" */ \
+} \
+int \
+ace_main_i
+# endif /* ACE_WIN32 && UNICODE */
+# endif /* ACE_PSOSIM */
+# endif /* ACE_HAS_NONSTATIC_OBJECT_MANAGER && !ACE_HAS_WINCE && !ACE_DOESNT_INSTANTIATE_NONSTATIC_OBJECT_MANAGER */
+
+#if defined (ACE_HAS_WINCE)
+
+/**
+ * @class ACE_CE_Bridge
+ *
+ * @brief This class bridges between ACE's default text output windows
+ * and the original ACE program.
+ *
+ * As there is no such thing as text-based programs on Windows
+ * CE. We need to create a windows to read the command prompt
+ * and bridge the output windows with the original ACE program
+ * entry point. You'll need to link your program with
+ * "ace-windows.lib" for this to work. You can refer to
+ * $ACE_ROOT/WindowsCE/Main for how I use a dialog box to run
+ * the original ACE programs. This is certainly not the only
+ * way to use ACE in Windows programs.
+ */
+class ACE_OS_Export ACE_CE_Bridge
+
+{
+public:
+ /// Default ctor.
+ ACE_CE_Bridge (void);
+
+ /// Construct and set the default windows.
+ ACE_CE_Bridge (HWND, int notification, int idc);
+
+ /// Default dtor.
+ ~ACE_CE_Bridge (void);
+
+ /// Specify which window to use.
+ void set_window (HWND, int notification, int idc);
+
+ /// Set the default window.
+ void set_self_default (void);
+
+ /// Access functions.
+ int notification (void);
+ int idc (void);
+ HWND window (void);
+
+ /// Get the reference of default ACE_CE_BRIDGE.
+ static ACE_CE_Bridge *get_default_winbridge (void);
+
+ /// Write a string to windows.
+ int write_msg (const ACE_TCHAR *str);
+
+#if 0
+ /// Write a CString to windows. Notice that the CString object will
+ /// be freed by windows.
+ int write_msg (CString *cs);
+#endif /* 0 */
+private:
+ // @@ We should use a allocator here.
+
+ /// A pointer to the window that knows how to
+ /// handle ACE related messages.
+ HWND text_output_;
+
+ /// Notification of the window that receives WM_COMMAND when
+ /// outputing strings.
+ int notification_;
+
+ /// IDC code of the window that receives WM_COMMAND when
+ /// outputing strings.
+ int idc_;
+
+ ACE_TCHAR *cmdline_;
+
+ /// A pointer to the default ACE_CE_BRIDGE obj.
+ static ACE_CE_Bridge *default_text_bridge_;
+};
+
+# endif /* ACE_HAS_WINCE */
+
+# if defined (ACE_WIN32) && ! defined (ACE_HAS_WINCE) \
+ && ! defined (ACE_HAS_PHARLAP)
+typedef TRANSMIT_FILE_BUFFERS ACE_TRANSMIT_FILE_BUFFERS;
+typedef LPTRANSMIT_FILE_BUFFERS ACE_LPTRANSMIT_FILE_BUFFERS;
+typedef PTRANSMIT_FILE_BUFFERS ACE_PTRANSMIT_FILE_BUFFERS;
+
+# define ACE_INFINITE INFINITE
+# define ACE_STATUS_TIMEOUT STATUS_TIMEOUT
+# define ACE_WAIT_FAILED WAIT_FAILED
+# define ACE_WAIT_TIMEOUT WAIT_TIMEOUT
+# else /* ACE_WIN32 */
+struct ACE_TRANSMIT_FILE_BUFFERS
+{
+ void *Head;
+ size_t HeadLength;
+ void *Tail;
+ size_t TailLength;
+};
+typedef ACE_TRANSMIT_FILE_BUFFERS* ACE_PTRANSMIT_FILE_BUFFERS;
+typedef ACE_TRANSMIT_FILE_BUFFERS* ACE_LPTRANSMIT_FILE_BUFFERS;
+
+# if !defined (ACE_INFINITE)
+# define ACE_INFINITE LONG_MAX
+# endif /* ACE_INFINITE */
+# define ACE_STATUS_TIMEOUT LONG_MAX
+# define ACE_WAIT_FAILED LONG_MAX
+# define ACE_WAIT_TIMEOUT LONG_MAX
+# endif /* ACE_WIN32 */
+
+# if 0
+# if !defined (ACE_HAS_MINIMAL_ACE_OS)
+# include "ace/Trace.h"
+# endif /* ! ACE_HAS_MINIMAL_ACE_OS */
+#endif
+
+# if defined (ACE_HAS_INLINED_OSCALLS)
+# if defined (ACE_INLINE)
+# undef ACE_INLINE
+# endif /* ACE_INLINE */
+# define ACE_INLINE inline
+# include "OS.i"
+# endif /* ACE_HAS_INLINED_OSCALLS */
+
+// Byte swapping macros to deal with differences between little endian
+// and big endian machines. Note that "long" here refers to 32 bit
+// quantities.
+# define ACE_SWAP_LONG(L) ((ACE_SWAP_WORD ((L) & 0xFFFF) << 16) \
+ | ACE_SWAP_WORD(((L) >> 16) & 0xFFFF))
+# define ACE_SWAP_WORD(L) ((((L) & 0x00FF) << 8) | (((L) & 0xFF00) >> 8))
+
+# if defined (ACE_LITTLE_ENDIAN)
+# define ACE_HTONL(X) ACE_SWAP_LONG (X)
+# define ACE_NTOHL(X) ACE_SWAP_LONG (X)
+# define ACE_IDL_NCTOHL(X) (X)
+# define ACE_IDL_NSTOHL(X) (X)
+# else
+# define ACE_HTONL(X) X
+# define ACE_NTOHL(X) X
+# define ACE_IDL_NCTOHL(X) (X << 24)
+# define ACE_IDL_NSTOHL(X) ((X) << 16)
+# endif /* ACE_LITTLE_ENDIAN */
+
+# if defined (ACE_LITTLE_ENDIAN)
+# define ACE_HTONS(x) ACE_SWAP_WORD(x)
+# define ACE_NTOHS(x) ACE_SWAP_WORD(x)
+# else
+# define ACE_HTONS(x) x
+# define ACE_NTOHS(x) x
+# endif /* ACE_LITTLE_ENDIAN */
+
+# if defined (ACE_HAS_AIO_CALLS)
+ // = Giving unique ACE scoped names for some important
+ // RTSignal-Related constants. Becuase sometimes, different
+ // platforms use different names for these constants.
+
+ // Number of realtime signals provided in the system.
+ // _POSIX_RTSIG_MAX is the upper limit on the number of real time
+ // signals supported in a posix-4 compliant system.
+# if defined (_POSIX_RTSIG_MAX)
+# define ACE_RTSIG_MAX _POSIX_RTSIG_MAX
+# else /* not _POSIX_RTSIG_MAX */
+ // POSIX-4 compilant system has to provide atleast 8 RT signals.
+ // @@ Make sure the platform does *not* define this constant with
+ // some other name. If yes, use that instead of 8.
+# define ACE_RTSIG_MAX 8
+# endif /* _POSIX_RTSIG_MAX */
+# endif /* ACE_HAS_AIO_CALLS */
+
+ // Wrapping around wait status <wstat> macros for platforms that
+ // lack them.
+
+ // Evaluates to a non-zero value if status was returned for a child
+ // process that terminated normally. 0 means status wasn't
+ // returned.
+#if !defined (WIFEXITED)
+# define WIFEXITED(stat) 1
+#endif /* WIFEXITED */
+
+ // If the value of WIFEXITED(stat) is non-zero, this macro evaluates
+ // to the exit code that the child process exit(3C), or the value
+ // that the child process returned from main. Peaceful exit code is
+ // 0.
+#if !defined (WEXITSTATUS)
+# define WEXITSTATUS(stat) stat
+#endif /* WEXITSTATUS */
+
+ // Evaluates to a non-zero value if status was returned for a child
+ // process that terminated due to the receipt of a signal. 0 means
+ // status wasnt returned.
+#if !defined (WIFSIGNALED)
+# define WIFSIGNALED(stat) 0
+#endif /* WIFSIGNALED */
+
+ // If the value of WIFSIGNALED(stat) is non-zero, this macro
+ // evaluates to the number of the signal that caused the
+ // termination of the child process.
+#if !defined (WTERMSIG)
+# define WTERMSIG(stat) 0
+#endif /* WTERMSIG */
+
+#if !defined (WIFSTOPPED)
+# define WIFSTOPPED(stat) 0
+#endif /* WIFSTOPPED */
+
+#if !defined (WSTOPSIG)
+# define WSTOPSIG(stat) 0
+#endif /* WSTOPSIG */
+
+#if !defined (WIFCONTINUED)
+# define WIFCONTINUED(stat) 0
+#endif /* WIFCONTINUED */
+
+#if !defined (WCOREDUMP)
+# define WCOREDUMP(stat) 0
+#endif /* WCOREDUMP */
+
+// Stuff used by the ACE CDR classes.
+#if defined ACE_LITTLE_ENDIAN
+# define ACE_CDR_BYTE_ORDER 1
+// little endian encapsulation byte order has value = 1
+#else /* ! ACE_LITTLE_ENDIAN */
+# define ACE_CDR_BYTE_ORDER 0
+// big endian encapsulation byte order has value = 0
+#endif /* ! ACE_LITTLE_ENDIAN */
+
+/**
+ * @name Default values to control CDR classes memory allocation
+ * strategies
+ */
+//@{
+
+/// Control the initial size of all CDR buffers, application
+/// developers may want to optimize this value to fit their request
+/// size
+#if !defined (ACE_DEFAULT_CDR_BUFSIZE)
+# define ACE_DEFAULT_CDR_BUFSIZE 512
+#endif /* ACE_DEFAULT_CDR_BUFSIZE */
+
+/// Stop exponential growth of CDR buffers to avoid overallocation
+#if !defined (ACE_DEFAULT_CDR_EXP_GROWTH_MAX)
+# define ACE_DEFAULT_CDR_EXP_GROWTH_MAX 65536
+#endif /* ACE_DEFAULT_CDR_EXP_GROWTH_MAX */
+
+/// Control CDR buffer growth after maximum exponential growth is
+/// reached
+#if !defined (ACE_DEFAULT_CDR_LINEAR_GROWTH_CHUNK)
+# define ACE_DEFAULT_CDR_LINEAR_GROWTH_CHUNK 65536
+#endif /* ACE_DEFAULT_CDR_LINEAR_GROWTH_CHUNK */
+//@}
+
+/// Control the zero-copy optimizations for octet sequences
+/**
+ * Large octet sequences can be sent without any copies by chaining
+ * them in the list of message blocks that represent a single CDR
+ * stream. However, if the octet sequence is too small the zero copy
+ * optimizations actually hurt performance. Octet sequences smaller
+ * than this value will be copied.
+ */
+#if !defined (ACE_DEFAULT_CDR_MEMCPY_TRADEOFF)
+#define ACE_DEFAULT_CDR_MEMCPY_TRADEOFF 256
+#endif /* ACE_DEFAULT_CDR_MEMCPY_TRADEOFF */
+
+/**
+ * In some environments it is useful to swap the bytes on write, for
+ * instance: a fast server can be feeding a lot of slow clients that
+ * happen to have the wrong byte order.
+ * Because this is a rarely used feature we disable it by default to
+ * minimize footprint.
+ * This macro enables the functionality, but we still need a way to
+ * activate it on a per-connection basis.
+ */
+// #define ACE_ENABLE_SWAP_ON_WRITE
+
+/**
+ * In some environements we never need to swap bytes when reading, for
+ * instance embebbed systems (such as avionics) or homogenous
+ * networks.
+ * Setting this macro disables the capabilities to demarshall streams
+ * in the wrong byte order.
+ */
+// #define ACE_DISABLE_SWAP_ON_READ
+
+
+//@{
+/**
+ * @name Efficiently compute aligned pointers to powers of 2 boundaries.
+ */
+
+/**
+ * Efficiently align "value" up to "alignment", knowing that all such
+ * boundaries are binary powers and that we're using two's complement
+ * arithmetic.
+ *
+ * Since the alignment is a power of two its binary representation is:
+ *
+ * alignment = 0...010...0
+ *
+ * hence
+ *
+ * alignment - 1 = 0...001...1 = T1
+ *
+ * so the complement is:
+ *
+ * ~(alignment - 1) = 1...110...0 = T2
+ *
+ * Notice that there is a multiple of <alignment> in the range
+ * [<value>,<value> + T1], also notice that if
+ *
+ * X = ( <value> + T1 ) & T2
+ *
+ * then
+ *
+ * <value> <= X <= <value> + T1
+ *
+ * because the & operator only changes the last bits, and since X is a
+ * multiple of <alignment> (its last bits are zero) we have found the
+ * multiple we wanted.
+ */
+/// Return the next integer aligned to a required boundary
+/**
+ * @param ptr the base pointer
+ * @param alignment the required alignment
+ */
+#define ACE_align_binary(ptr, alignment) \
+ ((ptr + ((ptr_arith_t)((alignment)-1))) & (~((ptr_arith_t)((alignment)-1))))
+
+/// Return the next address aligned to a required boundary
+#define ACE_ptr_align_binary(ptr, alignment) \
+ ((char *) ACE_align_binary (((ptr_arith_t) (ptr)), (alignment)))
+//@}
+
+// Defining POSIX4 real-time signal range.
+#if defined ACE_HAS_AIO_CALLS
+#define ACE_SIGRTMIN SIGRTMIN
+#define ACE_SIGRTMAX SIGRTMAX
+#else /* !ACE_HAS_AIO_CALLS */
+#define ACE_SIGRTMIN 0
+#define ACE_SIGRTMAX 0
+#endif /* ACE_HAS_AIO_CALLS */
+
+# if defined (ACE_LACKS_SYS_NERR)
+extern ACE_OS_Export int sys_nerr;
+# endif /* ACE_LACKS_SYS_NERR */
+
+#if defined (ACE_LEGACY_MODE)
+# include "ace/Log_Msg.h"
+# include "ace/Thread_Hook.h"
+# include "ace/Thread_Adapter.h"
+# include "ace/Thread_Exit.h"
+# include "ace/Thread_Control.h"
+#endif /* ACE_LEGACY_MODE */
+
+#include "ace/post.h"
+#endif /* ACE_OS_H */
diff --git a/ace/OS/OS.i b/ace/OS/OS.i
new file mode 100644
index 00000000000..1b4fa6c33b6
--- /dev/null
+++ b/ace/OS/OS.i
@@ -0,0 +1,11666 @@
+// -*- C++ -*-
+// $Id$
+
+#if defined (__CYGWIN32__)
+# include /**/ <getopt.h>
+#endif
+
+#if !defined (ACE_HAS_INLINED_OSCALLS)
+# undef ACE_INLINE
+# define ACE_INLINE
+#endif /* ACE_HAS_INLINED_OSCALLS */
+
+#if defined (ACE_LACKS_RLIMIT_PROTOTYPE)
+int getrlimit (int resource, struct rlimit *rlp);
+int setrlimit (int resource, const struct rlimit *rlp);
+#endif /* ACE_LACKS_RLIMIT_PROTOTYPE */
+
+#if !defined (ACE_HAS_STRERROR)
+# if defined (ACE_HAS_SYS_ERRLIST)
+extern char *sys_errlist[];
+# define strerror(err) sys_errlist[err]
+# else
+# define strerror(err) "strerror is unsupported"
+# endif /* ACE_HAS_SYS_ERRLIST */
+#endif /* !ACE_HAS_STERROR */
+
+#if defined (ACE_HAS_SYS_SIGLIST)
+# if !defined (_sys_siglist)
+# define _sys_siglist sys_siglist
+# endif /* !defined (sys_siglist) */
+//extern char **_sys_siglist;
+#endif /* ACE_HAS_SYS_SIGLIST */
+
+#if defined (ACE_HAS_SOCKLEN_T)
+typedef socklen_t ACE_SOCKET_LEN;
+#elif defined (ACE_HAS_SIZET_SOCKET_LEN)
+typedef size_t ACE_SOCKET_LEN;
+#else
+typedef int ACE_SOCKET_LEN;
+#endif /* ACE_HAS_SIZET_SOCKET_LEN */
+
+#if defined (ACE_LACKS_CONST_STRBUF_PTR)
+typedef struct strbuf *ACE_STRBUF_TYPE;
+#else
+typedef const struct strbuf *ACE_STRBUF_TYPE;
+#endif /* ACE_LACKS_CONST_STRBUF_PTR */
+
+#if defined (ACE_HAS_VOIDPTR_SOCKOPT)
+typedef void *ACE_SOCKOPT_TYPE1;
+#elif defined (ACE_HAS_CHARPTR_SOCKOPT)
+typedef char *ACE_SOCKOPT_TYPE1;
+#else
+typedef const char *ACE_SOCKOPT_TYPE1;
+#endif /* ACE_HAS_VOIDPTR_SOCKOPT */
+
+#if !defined (_BSD_SOURCE) && \
+ !defined (_XOPEN_SOURCE) && !defined (_XOPEN_SOURCE_EXTENDED)
+# if defined (ACE_LACKS_SETREUID_PROTOTYPE)
+extern "C" {
+extern int setreuid (uid_t ruid, uid_t euid);
+}
+# endif /* ACE_LACKS_SETREUID_PROTOTYPE */
+
+# if defined (ACE_LACKS_SETREGID_PROTOTYPE)
+extern "C" {
+extern int setregid (gid_t rgid, gid_t egid);
+}
+# endif /* ACE_LACKS_SETREGID_PROTOTYPE */
+#endif /* !_BSD_SOURCE && !_XOPEN_SOURCE && !_XOPEN_SOURCE_EXTENDED */
+
+#if defined (ACE_NEEDS_FTRUNCATE)
+extern "C" ACE_Export int ftruncate (ACE_HANDLE handle, long len);
+#endif /* ACE_NEEDS_FTRUNCATE */
+
+#if defined (ACE_HAS_VOIDPTR_MMAP)
+// Needed for some odd OS's (e.g., SGI).
+typedef void *ACE_MMAP_TYPE;
+#else
+typedef char *ACE_MMAP_TYPE;
+#endif /* ACE_HAS_VOIDPTR_MMAP */
+
+#if defined (ACE_HAS_XLI)
+# include /**/ <xliuser.h>
+#endif /* ACE_HAS_XLI */
+
+#if defined (_M_UNIX)
+extern "C" int _dlclose (void *);
+extern "C" char *_dlerror (void);
+extern "C" void *_dlopen (const char *, int);
+extern "C" void * _dlsym (void *, const char *);
+#endif /* _M_UNIX */
+
+#if !defined (ACE_HAS_CPLUSPLUS_HEADERS)
+# include /**/ <libc.h>
+# include /**/ <osfcn.h>
+#endif /* ACE_HAS_CPLUSPLUS_HEADERS */
+
+#if defined (ACE_HAS_SYSENT_H)
+# include /**/ <sysent.h>
+#endif /* ACE_HAS_SYSENT_H_*/
+
+#if defined (ACE_USES_STD_NAMESPACE_FOR_STDC_LIB) && \
+ (ACE_USES_STD_NAMESPACE_FOR_STDC_LIB != 0)
+using std::bsearch;
+using std::qsort;
+# if defined (ACE_WIN32)
+using std::_tzset;
+# else
+using std::tzset;
+# endif
+using std::ctime;
+using std::localtime;
+using std::gmtime;
+using std::asctime;
+using std::strftime;
+#endif /* ACE_USES_STD_NAMESPACE_FOR_STDC_LIB */
+
+#if defined (ACE_HAS_SVR4_GETTIMEOFDAY)
+# if !defined (m88k) && !defined (SCO)
+extern "C" int gettimeofday (struct timeval *tp, void * = 0);
+# else
+extern "C" int gettimeofday (struct timeval *tp);
+# endif /* !m88k && !SCO */
+#elif defined (ACE_HAS_OSF1_GETTIMEOFDAY)
+extern "C" int gettimeofday (struct timeval *tp, struct timezone * = 0);
+#elif defined (ACE_HAS_SUNOS4_GETTIMEOFDAY)
+# define ACE_HAS_SVR4_GETTIMEOFDAY
+#endif /* ACE_HAS_SVR4_GETTIMEOFDAY */
+
+#if defined (ACE_LACKS_CONST_TIMESPEC_PTR)
+typedef struct timespec * ACE_TIMESPEC_PTR;
+#else
+typedef const struct timespec * ACE_TIMESPEC_PTR;
+#endif /* HPUX */
+
+#if !defined (ACE_LACKS_MALLOC_H)
+# include /**/ <malloc.h>
+#endif /* ACE_LACKS_MALLOC_H */
+
+// Returns the value of the object as a timeval.
+
+ACE_INLINE
+ACE_Time_Value::operator timeval () const
+{
+ ACE_OS_TRACE ("ACE_Time_Value::operator timeval");
+ return this->tv_;
+}
+
+// Returns a pointer to the object as a timeval.
+
+ACE_INLINE
+ACE_Time_Value::operator const timeval * () const
+{
+ ACE_OS_TRACE ("ACE_Time_Value::operator const timeval *");
+ return (const timeval *) &this->tv_;
+}
+
+ACE_INLINE void
+ACE_Time_Value::set (long sec, long usec)
+{
+ // ACE_OS_TRACE ("ACE_Time_Value::set");
+ this->tv_.tv_sec = sec;
+ this->tv_.tv_usec = usec;
+}
+
+ACE_INLINE void
+ACE_Time_Value::set (double d)
+{
+ // ACE_OS_TRACE ("ACE_Time_Value::set");
+ long l = (long) d;
+ this->tv_.tv_sec = l;
+ this->tv_.tv_usec = (long) ((d - (double) l) * ACE_ONE_SECOND_IN_USECS);
+ this->normalize ();
+}
+
+// Initializes a timespec_t. Note that this approach loses precision
+// since it converts the nano-seconds into micro-seconds. But then
+// again, do any real systems have nano-second timer precision?!
+
+ACE_INLINE void
+ACE_Time_Value::set (const timespec_t &tv)
+{
+ // ACE_OS_TRACE ("ACE_Time_Value::set");
+#if ! defined(ACE_HAS_BROKEN_TIMESPEC_MEMBERS)
+ this->tv_.tv_sec = tv.tv_sec;
+ // Convert nanoseconds into microseconds.
+ this->tv_.tv_usec = tv.tv_nsec / 1000;
+#else
+ this->tv_.tv_sec = tv.ts_sec;
+ // Convert nanoseconds into microseconds.
+ this->tv_.tv_usec = tv.ts_nsec / 1000;
+#endif /* ACE_HAS_BROKEN_TIMESPEC_MEMBERS */
+
+ this->normalize ();
+}
+
+ACE_INLINE void
+ACE_Time_Value::set (const timeval &tv)
+{
+ // ACE_OS_TRACE ("ACE_Time_Value::set");
+ this->tv_.tv_sec = tv.tv_sec;
+ this->tv_.tv_usec = tv.tv_usec;
+
+ this->normalize ();
+}
+
+ACE_INLINE
+ACE_Time_Value::ACE_Time_Value (const timeval &tv)
+ // : tv_ ()
+{
+ // ACE_OS_TRACE ("ACE_Time_Value::ACE_Time_Value");
+ this->set (tv);
+}
+
+ACE_INLINE
+ACE_Time_Value::ACE_Time_Value (void)
+ // : tv_ ()
+{
+ // ACE_OS_TRACE ("ACE_Time_Value::ACE_Time_Value");
+ this->set (0, 0);
+
+ // Don't need to normalize time value of (0, 0).
+}
+
+ACE_INLINE
+ACE_Time_Value::ACE_Time_Value (long sec, long usec)
+{
+ // ACE_OS_TRACE ("ACE_Time_Value::ACE_Time_Value");
+ this->set (sec, usec);
+ this->normalize ();
+}
+
+// Returns number of seconds.
+
+ACE_INLINE long
+ACE_Time_Value::sec (void) const
+{
+ ACE_OS_TRACE ("ACE_Time_Value::sec");
+ return this->tv_.tv_sec;
+}
+
+// Sets the number of seconds.
+
+ACE_INLINE void
+ACE_Time_Value::sec (long sec)
+{
+ ACE_OS_TRACE ("ACE_Time_Value::sec");
+ this->tv_.tv_sec = sec;
+}
+
+// Converts from Time_Value format into milli-seconds format.
+
+ACE_INLINE long
+ACE_Time_Value::msec (void) const
+{
+ ACE_OS_TRACE ("ACE_Time_Value::msec");
+ return this->tv_.tv_sec * 1000 + this->tv_.tv_usec / 1000;
+}
+
+// Converts from milli-seconds format into Time_Value format.
+
+ACE_INLINE void
+ACE_Time_Value::msec (long milliseconds)
+{
+ ACE_OS_TRACE ("ACE_Time_Value::msec");
+ // Convert millisecond units to seconds;
+ this->tv_.tv_sec = milliseconds / 1000;
+ // Convert remainder to microseconds;
+ this->tv_.tv_usec = (milliseconds - (this->tv_.tv_sec * 1000)) * 1000;
+}
+
+// Returns number of micro-seconds.
+
+ACE_INLINE long
+ACE_Time_Value::usec (void) const
+{
+ ACE_OS_TRACE ("ACE_Time_Value::usec");
+ return this->tv_.tv_usec;
+}
+
+// Sets the number of micro-seconds.
+
+ACE_INLINE void
+ACE_Time_Value::usec (long usec)
+{
+ ACE_OS_TRACE ("ACE_Time_Value::usec");
+ this->tv_.tv_usec = usec;
+}
+
+// Initializes the ACE_Time_Value object from another ACE_Time_Value
+
+ACE_INLINE
+ACE_Time_Value::ACE_Time_Value (const ACE_Time_Value &tv)
+ : tv_ (tv.tv_)
+{
+ // ACE_OS_TRACE ("ACE_Time_Value::ACE_Time_Value");
+}
+
+ACE_INLINE ACE_Time_Value &
+ACE_Time_Value::operator *= (double d)
+{
+ double time = this->sec () * ACE_ONE_SECOND_IN_USECS + this->usec ();
+ time *= d;
+ this->sec ((long)(time / ACE_ONE_SECOND_IN_USECS));
+ this->usec (((long)time) % ACE_ONE_SECOND_IN_USECS);
+
+ return *this;
+}
+
+ACE_INLINE ACE_Time_Value
+operator * (double d, const ACE_Time_Value &tv)
+{
+ return ACE_Time_Value (tv) *= d;
+}
+
+ACE_INLINE ACE_Time_Value
+operator * (const ACE_Time_Value &tv, double d)
+{
+ return ACE_Time_Value (tv) *= d;
+}
+
+// True if tv1 > tv2.
+
+ACE_INLINE int
+operator > (const ACE_Time_Value &tv1,
+ const ACE_Time_Value &tv2)
+{
+ ACE_OS_TRACE ("operator >");
+ if (tv1.sec () > tv2.sec ())
+ return 1;
+ else if (tv1.sec () == tv2.sec ()
+ && tv1.usec () > tv2.usec ())
+ return 1;
+ else
+ return 0;
+}
+
+// True if tv1 >= tv2.
+
+ACE_INLINE int
+operator >= (const ACE_Time_Value &tv1,
+ const ACE_Time_Value &tv2)
+{
+ ACE_OS_TRACE ("operator >=");
+ if (tv1.sec () > tv2.sec ())
+ return 1;
+ else if (tv1.sec () == tv2.sec ()
+ && tv1.usec () >= tv2.usec ())
+ return 1;
+ else
+ return 0;
+}
+
+// Returns the value of the object as a timespec_t.
+
+ACE_INLINE
+ACE_Time_Value::operator timespec_t () const
+{
+ ACE_OS_TRACE ("ACE_Time_Value::operator timespec_t");
+ timespec_t tv;
+#if ! defined(ACE_HAS_BROKEN_TIMESPEC_MEMBERS)
+ tv.tv_sec = this->sec ();
+ // Convert microseconds into nanoseconds.
+ tv.tv_nsec = this->tv_.tv_usec * 1000;
+#else
+ tv.ts_sec = this->sec ();
+ // Convert microseconds into nanoseconds.
+ tv.ts_nsec = this->tv_.tv_usec * 1000;
+#endif /* ACE_HAS_BROKEN_TIMESPEC_MEMBERS */
+ return tv;
+}
+
+// Initializes the ACE_Time_Value object from a timespec_t.
+
+ACE_INLINE
+ACE_Time_Value::ACE_Time_Value (const timespec_t &tv)
+ // : tv_ ()
+{
+ // ACE_OS_TRACE ("ACE_Time_Value::ACE_Time_Value");
+ this->set (tv);
+}
+
+// True if tv1 < tv2.
+
+ACE_INLINE int
+operator < (const ACE_Time_Value &tv1,
+ const ACE_Time_Value &tv2)
+{
+ ACE_OS_TRACE ("operator <");
+ return tv2 > tv1;
+}
+
+// True if tv1 >= tv2.
+
+ACE_INLINE int
+operator <= (const ACE_Time_Value &tv1,
+ const ACE_Time_Value &tv2)
+{
+ ACE_OS_TRACE ("operator <=");
+ return tv2 >= tv1;
+}
+
+// True if tv1 == tv2.
+
+ACE_INLINE int
+operator == (const ACE_Time_Value &tv1,
+ const ACE_Time_Value &tv2)
+{
+ // ACE_OS_TRACE ("operator ==");
+ return tv1.sec () == tv2.sec ()
+ && tv1.usec () == tv2.usec ();
+}
+
+// True if tv1 != tv2.
+
+ACE_INLINE int
+operator != (const ACE_Time_Value &tv1,
+ const ACE_Time_Value &tv2)
+{
+ // ACE_OS_TRACE ("operator !=");
+ return !(tv1 == tv2);
+}
+
+// Add TV to this.
+
+ACE_INLINE ACE_Time_Value &
+ACE_Time_Value::operator+= (const ACE_Time_Value &tv)
+{
+ ACE_OS_TRACE ("ACE_Time_Value::operator+=");
+ this->sec (this->sec () + tv.sec ());
+ this->usec (this->usec () + tv.usec ());
+ this->normalize ();
+ return *this;
+}
+
+// Subtract TV to this.
+
+ACE_INLINE ACE_Time_Value &
+ACE_Time_Value::operator-= (const ACE_Time_Value &tv)
+{
+ ACE_OS_TRACE ("ACE_Time_Value::operator-=");
+ this->sec (this->sec () - tv.sec ());
+ this->usec (this->usec () - tv.usec ());
+ this->normalize ();
+ return *this;
+}
+
+// Adds two ACE_Time_Value objects together, returns the sum.
+
+ACE_INLINE ACE_Time_Value
+operator + (const ACE_Time_Value &tv1,
+ const ACE_Time_Value &tv2)
+{
+ ACE_OS_TRACE ("operator +");
+ ACE_Time_Value sum (tv1.sec () + tv2.sec (),
+ tv1.usec () + tv2.usec ());
+
+ sum.normalize ();
+ return sum;
+}
+
+// Subtracts two ACE_Time_Value objects, returns the difference.
+
+ACE_INLINE ACE_Time_Value
+operator - (const ACE_Time_Value &tv1,
+ const ACE_Time_Value &tv2)
+{
+ ACE_OS_TRACE ("operator -");
+ ACE_Time_Value delta (tv1.sec () - tv2.sec (),
+ tv1.usec () - tv2.usec ());
+ delta.normalize ();
+ return delta;
+}
+
+ACE_INLINE int
+ACE_OS::fcntl (ACE_HANDLE handle, int cmd, long arg)
+{
+ ACE_OS_TRACE ("ACE_OS::fcntl");
+#if defined (ACE_HAS_PACE)
+ ACE_OSCALL_RETURN (::pace_fcntl (handle, cmd, arg), int, -1);
+# elif defined (ACE_LACKS_FCNTL)
+ ACE_UNUSED_ARG (handle);
+ ACE_UNUSED_ARG (cmd);
+ ACE_UNUSED_ARG (arg);
+ ACE_NOTSUP_RETURN (-1);
+# else
+ ACE_OSCALL_RETURN (::fcntl (handle, cmd, arg), int, -1);
+# endif /* ACE_HAS_PACE */
+}
+
+#if !defined (ACE_LACKS_CHDIR)
+ACE_INLINE int
+ACE_OS::chdir (const char *path)
+{
+ ACE_OS_TRACE ("ACE_OS::chdir");
+#if defined (ACE_HAS_PACE)
+ ACE_OSCALL_RETURN (::pace_chdir (path), int, -1);
+#elif defined (VXWORKS)
+ ACE_OSCALL_RETURN (::chdir (ACE_const_cast (char *, path)), int, -1);
+
+#elif defined (ACE_PSOS_LACKS_PHILE)
+ ACE_UNUSED_ARG (path);
+ ACE_NOTSUP_RETURN (-1);
+
+#elif defined (ACE_PSOS)
+ ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::change_dir ((char *) path), ace_result_),
+ int, -1);
+
+// This #elif seems weird... is Visual Age on NT not setting ACE_WIN32?
+#elif !defined (ACE_WIN32) && !defined (AIX) && defined (__IBMCPP__) && (__IBMCPP__ >= 400)
+ ACE_OSCALL_RETURN (::_chdir (path), int, -1);
+
+#elif defined (ACE_HAS_WINCE)
+ ACE_UNUSED_ARG (path);
+ ACE_NOTSUP_RETURN (-1);
+
+#else
+ ACE_OSCALL_RETURN (::chdir (path), int, -1);
+
+#endif /* ACE_HAS_PACE */
+}
+
+#if defined (ACE_HAS_WCHAR)
+ACE_INLINE int
+ACE_OS::chdir (const wchar_t *path)
+{
+#if defined (ACE_WIN32)
+ ACE_OSCALL_RETURN (::_wchdir (path), int, -1);
+#else /* ACE_WIN32 */
+ return ACE_OS::chdir (ACE_Wide_To_Ascii (path).char_rep ());
+#endif /* ACE_WIN32 */
+}
+#endif /* ACE_HAS_WCHAR */
+#endif /* ACE_LACKS_CHDIR */
+
+#if !defined (ACE_LACKS_MKTEMP)
+ACE_INLINE ACE_TCHAR *
+ACE_OS::mktemp (ACE_TCHAR *s)
+{
+# if defined (ACE_WIN32) && defined (ACE_USES_WCHAR)
+ return ::_wmktemp (s);
+# elif defined (ACE_WIN32)
+ return ::_mktemp (s);
+# else /* ACE_WIN32 */
+ return ::mktemp (s);
+# endif /* ACE_WIN32 */
+}
+#endif /* !ACE_LACKS_MKTEMP */
+
+#if !defined (ACE_LACKS_MKSTEMP)
+ACE_INLINE ACE_HANDLE
+ACE_OS::mkstemp (ACE_TCHAR *s)
+{
+ return ::mkstemp (s);
+}
+#endif /* !ACE_LACKS_MKSTEMP */
+
+ACE_INLINE int
+ACE_OS::mkfifo (const ACE_TCHAR *file, mode_t mode)
+{
+ ACE_OS_TRACE ("ACE_OS::mkfifo");
+#if defined (ACE_HAS_PACE)
+ ACE_OSCALL_RETURN (::pace_mkfifo (file, mode), int, -1);
+#elif defined (ACE_LACKS_MKFIFO)
+ ACE_UNUSED_ARG (file);
+ ACE_UNUSED_ARG (mode);
+ ACE_NOTSUP_RETURN (-1);
+#else
+ ACE_OSCALL_RETURN (::mkfifo (file, mode), int, -1);
+# endif /* ACE_HAS_PACE */
+}
+
+#if !defined (ACE_WIN32)
+
+// Matthew Stevens 7-10-95 Fix GNU GCC 2.7 for memchr() problem.
+# if defined (ACE_HAS_GNU_CSTRING_H)
+// Define this file to keep /usr/include/memory.h from being included.
+# include /**/ <cstring>
+# else
+# if defined (ACE_LACKS_MEMORY_H)
+# if !defined (ACE_PSOS_DIAB_MIPS)
+# include /**/ <string.h>
+# endif /* ACE_PSOS_DIAB_MIPS */
+# else
+# include /**/ <memory.h>
+# endif /* VXWORKS */
+# endif /* ACE_HAS_GNU_CSTRING_H */
+
+// These prototypes are chronically lacking from many versions of
+// UNIX.
+extern "C" int isastream (int);
+# if !defined (ACE_HAS_GETRUSAGE_PROTO)
+extern "C" int getrusage (int who, struct rusage *rusage);
+# endif /* ! ACE_HAS_GETRUSAGE_PROTO */
+
+# if defined (ACE_LACKS_SYSCALL)
+extern "C" int syscall (int, ACE_HANDLE, struct rusage *);
+# endif /* ACE_LACKS_SYSCALL */
+
+# if defined (ACE_LACKS_MKTEMP)
+extern "C" char *mktemp (char *);
+# endif /* ACE_LACKS_MKTEMP */
+
+// The following are #defines and #includes that must be visible for
+// ACE to compile it's OS wrapper class implementation correctly. We
+// put them inside of here to reduce compiler overhead if we're not
+// inlining...
+
+# if defined (ACE_HAS_REGEX)
+# include /**/ <regexpr.h>
+# endif /* ACE_HAS_REGEX */
+
+# if defined (ACE_HAS_SYSINFO)
+# include /**/ <sys/systeminfo.h>
+# endif /* ACE_HAS_SYS_INFO */
+
+# if defined (ACE_HAS_SYSCALL_H)
+# include /**/ <sys/syscall.h>
+# endif /* ACE_HAS_SYSCALL_H */
+
+# if defined (UNIXWARE) /* See strcasecmp, below */
+# include /**/ <ctype.h>
+# endif /* UNIXWARE */
+
+// Adapt the weird threading and synchronization routines (which
+// return errno rather than -1) so that they return -1 and set errno.
+// This is more consistent with the rest of ACE_OS and enables use to
+// use the ACE_OSCALL* macros.
+# if defined (VXWORKS)
+# define ACE_ADAPT_RETVAL(OP,RESULT) ((RESULT = (OP)) != OK ? (errno = RESULT, -1) : 0)
+# else
+# define ACE_ADAPT_RETVAL(OP,RESULT) ((RESULT = (OP)) != 0 ? (errno = RESULT, -1) : 0)
+# endif /* VXWORKS */
+
+ACE_INLINE int
+ACE_OS::fstat (ACE_HANDLE handle, ACE_stat *stp)
+{
+ ACE_OS_TRACE ("ACE_OS::fstat");
+#if defined (ACE_HAS_PACE)
+ ACE_OSCALL_RETURN (::pace_fstat (handle, stp), int, -1);
+#elif defined (ACE_PSOS_LACKS_PHILE)
+ ACE_UNUSED_ARG (handle);
+ ACE_UNUSED_ARG (stp);
+ ACE_NOTSUP_RETURN (-1);
+#elif defined (ACE_PSOS)
+ ACE_OSCALL_RETURN (::fstat_f (handle, stp), int, -1);
+#else
+# if defined (ACE_HAS_X86_STAT_MACROS)
+ // Solaris for intel uses an macro for fstat(), this is a wrapper
+ // for _fxstat() use of the macro.
+ // causes compile and runtime problems.
+ ACE_OSCALL_RETURN (::_fxstat (_STAT_VER, handle, stp), int, -1);
+# elif defined (ACE_WIN32)
+ ACE_OSCALL_RETURN (::_fstat (handle, stp), int, -1);
+# else
+ ACE_OSCALL_RETURN (::fstat (handle, stp), int, -1);
+# endif /* !ACE_HAS_X86_STAT_MACROS */
+#endif /* defined (ACE_HAS_PACE) */
+}
+
+ACE_INLINE int
+ACE_OS::lstat (const char *file, ACE_stat *stp)
+{
+ ACE_OS_TRACE ("ACE_OS::lstat");
+# if defined (ACE_LACKS_LSTAT) || \
+ defined (ACE_HAS_WINCE) || defined (ACE_WIN32)
+ ACE_UNUSED_ARG (file);
+ ACE_UNUSED_ARG (stp);
+ ACE_NOTSUP_RETURN (-1);
+#else
+# if defined (ACE_HAS_X86_STAT_MACROS)
+ // Solaris for intel uses an macro for lstat(), this macro is a
+ // wrapper for _lxstat().
+ ACE_OSCALL_RETURN (::_lxstat (_STAT_VER, file, stp), int, -1);
+# elif defined (ACE_WIN32)
+ ACE_OSCALL_RETURN (::_lstat (file, stp), int, -1);
+# else /* !ACE_HAS_X86_STAT_MACROS */
+ ACE_OSCALL_RETURN (::lstat (file, stp), int, -1);
+#endif /* !ACE_HAS_X86_STAT_MACROS */
+# endif /* VXWORKS */
+}
+
+ACE_INLINE int
+ACE_OS::fsync (ACE_HANDLE handle)
+{
+ ACE_OS_TRACE ("ACE_OS::fsync");
+#if defined (ACE_HAS_PACE)
+ ACE_OSCALL_RETURN (::pace_fsync (handle), int, -1);
+# elif defined (ACE_LACKS_FSYNC)
+ ACE_UNUSED_ARG (handle);
+ ACE_NOTSUP_RETURN (-1);
+# else
+ ACE_OSCALL_RETURN (::fsync (handle), int, -1);
+# endif /* ACE_HAS_PACE */
+}
+
+ACE_INLINE int
+ACE_OS::getopt (int argc, char *const *argv, const char *optstring)
+{
+ ACE_OS_TRACE ("ACE_OS::getopt");
+#if defined (VXWORKS) || defined (ACE_PSOS)
+ ACE_UNUSED_ARG (argc);
+ ACE_UNUSED_ARG (argv);
+ ACE_UNUSED_ARG (optstring);
+ ACE_NOTSUP_RETURN (-1);
+# elif defined (ACE_LACKS_GETOPT_PROTO)
+ ACE_OSCALL_RETURN (::getopt (argc, (char**) argv, optstring), int, -1);
+# elif defined (ACE_LACKS_POSIX_PROTOTYPES)
+ ACE_OSCALL_RETURN (::getopt (argc, (const char* const *) argv, optstring), int, -1);
+# else
+ ACE_OSCALL_RETURN (::getopt (argc, argv, optstring), int, -1);
+# endif /* VXWORKS */
+}
+
+ACE_INLINE int
+ACE_OS::pipe (ACE_HANDLE fds[])
+{
+ ACE_OS_TRACE ("ACE_OS::pipe");
+#if defined (ACE_HAS_PACE)
+ ACE_OSCALL_RETURN (::pace_pipe (fds), int, -1);
+#elif defined (VXWORKS) || defined (ACE_PSOS)
+ ACE_UNUSED_ARG (fds);
+ ACE_NOTSUP_RETURN (-1);
+# else
+ ACE_OSCALL_RETURN (::pipe (fds), int, -1);
+# endif /* ACE_HAS_PACE */
+}
+
+# if defined (DIGITAL_UNIX)
+extern "C" {
+ extern char *_Pctime_r (const time_t *, char *);
+ extern struct tm *_Plocaltime_r (const time_t *, struct tm *);
+ extern struct tm *_Pgmtime_r (const time_t *, struct tm *);
+ extern char *_Pasctime_r (const struct tm *, char *);
+ extern int _Prand_r (unsigned int *seedptr);
+ extern int _Pgetpwnam_r (const char *, struct passwd *,
+ char *, size_t, struct passwd **);
+}
+# endif /* DIGITAL_UNIX */
+
+// VAC++ doesn't correctly grok the ::getpwnam_r - the function is redefined
+// in pwd.h, and that redefinition is used here
+# if defined (_AIX) && defined (__IBMCPP__) && (__IBMCPP__ >= 400)
+extern "C" {
+ extern int _posix_getpwnam_r(const char *, struct passwd *, char *,
+ int, struct passwd **);
+ }
+#endif /* AIX and VAC++ 4 */
+
+ACE_INLINE int
+ACE_OS::rand_r (ACE_RANDR_TYPE &seed)
+{
+ ACE_OS_TRACE ("ACE_OS::rand_r");
+#if defined (ACE_HAS_PACE)
+ ACE_OSCALL_RETURN (::pace_rand_r (&seed), int, -1);
+# elif defined (ACE_HAS_REENTRANT_FUNCTIONS) && \
+ !defined (ACE_LACKS_RAND_REENTRANT_FUNCTIONS)
+# if defined (DIGITAL_UNIX)
+ ACE_OSCALL_RETURN (::_Prand_r (&seed), int, -1);
+# elif defined (HPUX_10)
+ // rand() is thread-safe on HP-UX 10. rand_r's signature is not consistent
+ // with latest POSIX and will change in a future HP-UX release so that it
+ // is consistent. At that point, this #elif section can be changed or
+ // removed, and just call rand_r.
+ ACE_UNUSED_ARG (seed);
+ ACE_OSCALL_RETURN (::rand(), int, -1);
+# elif defined (ACE_HAS_BROKEN_RANDR)
+ ACE_OSCALL_RETURN (::rand_r (seed), int, -1);
+# else
+ ACE_OSCALL_RETURN (::rand_r (&seed), int, -1);
+# endif /* DIGITAL_UNIX */
+# else
+ ACE_UNUSED_ARG (seed);
+ ACE_OSCALL_RETURN (::rand (), int, -1);
+# endif /* ACE_HAS_PACE */
+}
+
+ACE_INLINE pid_t
+ACE_OS::setsid (void)
+{
+ ACE_OS_TRACE ("ACE_OS::setsid");
+#if defined (ACE_HAS_PACE)
+ ACE_OSCALL_RETURN (::pace_setsid (), int , -1);
+#elif defined (VXWORKS) || defined (CHORUS) || defined (ACE_PSOS)
+ ACE_NOTSUP_RETURN (-1);
+# else
+ ACE_OSCALL_RETURN (::setsid (), int, -1);
+# endif /* ACE_HAS_PACE */
+}
+
+ACE_INLINE mode_t
+ACE_OS::umask (mode_t cmask)
+{
+ ACE_OS_TRACE ("ACE_OS::umask");
+#if defined (ACE_HAS_PACE)
+ return ::pace_umask (cmask);
+#elif defined (VXWORKS) || defined (ACE_PSOS)
+ ACE_UNUSED_ARG (cmask);
+ ACE_NOTSUP_RETURN (-1);
+# else
+ return ::umask (cmask); // This call shouldn't fail...
+# endif /* ACE_HAS_PACE */
+}
+
+#else /* ACE_WIN32 */
+
+// Adapt the Win32 System Calls (which return BOOLEAN values of TRUE
+// and FALSE) into int values expected by the ACE_OSCALL macros.
+# define ACE_ADAPT_RETVAL(OP,RESULT) ((RESULT = (OP)) == FALSE ? -1 : 0)
+
+// Perform a mapping of Win32 error numbers into POSIX errnos.
+# define ACE_FAIL_RETURN(RESULT) do { \
+ switch (ACE_OS::set_errno_to_last_error ()) { \
+ case ERROR_NOT_ENOUGH_MEMORY: errno = ENOMEM; break; \
+ case ERROR_FILE_EXISTS: errno = EEXIST; break; \
+ case ERROR_SHARING_VIOLATION: errno = EACCES; break; \
+ case ERROR_PATH_NOT_FOUND: errno = ENOENT; break; \
+ } \
+ return RESULT; } while (0)
+
+ACE_INLINE LPSECURITY_ATTRIBUTES
+ACE_OS::default_win32_security_attributes (LPSECURITY_ATTRIBUTES sa)
+{
+#if defined (ACE_DEFINES_DEFAULT_WIN32_SECURITY_ATTRIBUTES)
+ if (sa == 0)
+ {
+ // @@ This is a good place to use pthread_once.
+ static SECURITY_ATTRIBUTES default_sa;
+ static SECURITY_DESCRIPTOR sd;
+ InitializeSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION);
+ SetSecurityDescriptorDacl(&sd, TRUE, NULL, FALSE);
+ default_sa.nLength = sizeof(SECURITY_ATTRIBUTES);
+ default_sa.lpSecurityDescriptor = &sd;
+ default_sa.bInheritHandle = TRUE;
+ sa = &default_sa;
+ }
+ return sa;
+#else /* !ACE_DEFINES_DEFAULT_WIN32_SECURITY_ATTRIBUTES */
+ return sa;
+#endif /* ACE_DEFINES_DEFAULT_WIN32_SECURITY_ATTRIBUTES */
+}
+
+ACE_INLINE int
+ACE_OS::getopt (int argc, char *const *argv, const char *optstring)
+{
+ ACE_UNUSED_ARG (argc);
+ ACE_UNUSED_ARG (argv);
+ ACE_UNUSED_ARG (optstring);
+
+ ACE_OS_TRACE ("ACE_OS::getopt");
+ ACE_NOTSUP_RETURN (-1);
+}
+
+ACE_INLINE int
+ACE_OS::pipe (ACE_HANDLE fds[])
+{
+#if defined (ACE_HAS_PACE)
+ ACE_OSCALL_RETURN (::pace_pipe (fds), int, -1);
+# elif !defined (ACE_HAS_WINCE) && !defined (__IBMCPP__)
+ ACE_OS_TRACE ("ACE_OS::pipe");
+ ACE_WIN32CALL_RETURN (ACE_ADAPT_RETVAL
+ (::CreatePipe (&fds[0], &fds[1], 0, 0),
+ ace_result_), int, -1);
+# else
+ ACE_NOTSUP_RETURN (-1);
+# endif /* ACE_HAS_PACE */
+}
+
+ACE_INLINE int
+ACE_OS::rand_r (ACE_RANDR_TYPE& seed)
+{
+ ACE_UNUSED_ARG (seed);
+
+ ACE_OS_TRACE ("ACE_OS::rand_r");
+ ACE_NOTSUP_RETURN (-1);
+}
+
+ACE_INLINE pid_t
+ACE_OS::setsid (void)
+{
+ ACE_OS_TRACE ("ACE_OS::setsid");
+ ACE_NOTSUP_RETURN (-1);
+}
+
+ACE_INLINE mode_t
+ACE_OS::umask (mode_t cmask)
+{
+#if defined (ACE_HAS_PACE)
+ ACE_OSCALL_RETURN (::pace_umask (cmask), mode_t, -1);
+# elif !defined (ACE_HAS_WINCE)
+ ACE_OS_TRACE ("ACE_OS::umask");
+ ACE_OSCALL_RETURN (::_umask (cmask), mode_t, -1);
+# else
+ ACE_NOTSUP_RETURN (-1);
+# endif /* ACE_HAS_PACE */
+}
+
+ACE_INLINE int
+ACE_OS::fstat (ACE_HANDLE handle, ACE_stat *stp)
+{
+ ACE_OS_TRACE ("ACE_OS::fstat");
+#if defined (ACE_HAS_PACE)
+ ACE_OSCALL_RETURN (::pace_fstat (handle, stp), int, -1);
+# elif 1
+ BY_HANDLE_FILE_INFORMATION fdata;
+
+ if (::GetFileInformationByHandle (handle, &fdata) == FALSE)
+ {
+ ACE_OS::set_errno_to_last_error ();
+ return -1;
+ }
+ else if (fdata.nFileSizeHigh != 0)
+ {
+ errno = EINVAL;
+ return -1;
+ }
+ else
+ {
+ stp->st_size = fdata.nFileSizeLow;
+ stp->st_atime = ACE_Time_Value (fdata.ftLastAccessTime).sec ();
+ stp->st_mtime = ACE_Time_Value (fdata.ftLastWriteTime).sec ();
+#if !defined (ACE_HAS_WINCE)
+ stp->st_ctime = ACE_Time_Value (fdata.ftCreationTime).sec ();
+ stp->st_nlink = ACE_static_cast (short, fdata.nNumberOfLinks);
+ stp->st_dev = stp->st_rdev = 0; // No equivalent conversion.
+ stp->st_mode = S_IXOTH | S_IROTH |
+ (fdata.dwFileAttributes & FILE_ATTRIBUTE_READONLY ? 0 : S_IWOTH);
+#endif /* !ACE_HAS_WINCE */
+ }
+ return 0;
+# else /* 1 */
+ // This implementation close the handle.
+ int retval = -1;
+ int fd = ::_open_osfhandle ((long) handle, 0);
+ if (fd != -1)
+ retval = ::_fstat (fd, stp);
+
+ ::_close (fd);
+ // Remember to close the file handle.
+ return retval;
+# endif /* ACE_HAS_PACE */
+}
+
+#endif /* WIN32 */
+
+ACE_INLINE int
+ACE_OS::clock_gettime (clockid_t clockid, struct timespec *ts)
+{
+ ACE_OS_TRACE ("ACE_OS::clock_gettime");
+#if defined (ACE_HAS_PACE)
+ ACE_OSCALL_RETURN (::pace_clock_gettime (clockid, ts), int, -1);
+#elif defined (ACE_HAS_CLOCK_GETTIME)
+ ACE_OSCALL_RETURN (::clock_gettime (clockid, ts), int, -1);
+# elif defined (ACE_PSOS) && ! defined (ACE_PSOS_DIAB_MIPS)
+ ACE_UNUSED_ARG (clockid);
+ ACE_PSOS_Time_t pt;
+ int result = ACE_PSOS_Time_t::get_system_time (pt);
+ *ts = ACE_static_cast (struct timespec, pt);
+ return result;
+#else
+ ACE_UNUSED_ARG (clockid);
+ ACE_UNUSED_ARG (ts);
+ ACE_NOTSUP_RETURN (-1);
+#endif /* ACE_HAS_PACE */
+}
+
+ACE_INLINE ACE_Time_Value
+ACE_OS::gettimeofday (void)
+{
+ // ACE_OS_TRACE ("ACE_OS::gettimeofday");
+
+#if !defined (ACE_HAS_WINCE)&& !defined (ACE_WIN32)
+ timeval tv;
+ int result = 0;
+#endif // !defined (ACE_HAS_WINCE)&& !defined (ACE_WIN32)
+
+#if (0)
+ struct timespec ts;
+
+ ACE_OSCALL (ACE_OS::clock_gettime (CLOCK_REALTIME, &ts), int, -1, result);
+ tv.tv_sec = ts.tv_sec;
+ tv.tv_usec = ts.tv_nsec / 1000L; // timespec has nsec, but timeval has usec
+
+#elif defined (ACE_HAS_WINCE)
+ SYSTEMTIME tsys;
+ FILETIME tfile;
+ ::GetSystemTime (&tsys);
+ ::SystemTimeToFileTime (&tsys, &tfile);
+ return ACE_Time_Value (tfile);
+#elif defined (ACE_WIN32)
+ FILETIME tfile;
+ ::GetSystemTimeAsFileTime (&tfile);
+ return ACE_Time_Value (tfile);
+#if 0
+ // From Todd Montgomery...
+ struct _timeb tb;
+ ::_ftime (&tb);
+ tv.tv_sec = tb.time;
+ tv.tv_usec = 1000 * tb.millitm;
+#endif /* 0 */
+#elif defined (ACE_HAS_AIX_HI_RES_TIMER)
+ timebasestruct_t tb;
+
+ ::read_real_time (&tb, TIMEBASE_SZ);
+ ::time_base_to_time (&tb, TIMEBASE_SZ);
+
+ tv.tv_sec = tb.tb_high;
+ tv.tv_usec = tb.tb_low / 1000L;
+#else
+# if defined (ACE_HAS_TIMEZONE_GETTIMEOFDAY) || \
+ (defined (ACE_HAS_SVR4_GETTIMEOFDAY) && !defined (m88k) && !defined (SCO))
+ ACE_OSCALL (::gettimeofday (&tv, 0), int, -1, result);
+# elif defined (VXWORKS) || defined (CHORUS) || defined (ACE_PSOS)
+ // Assumes that struct timespec is same size as struct timeval,
+ // which assumes that time_t is a long: it currently (VxWorks
+ // 5.2/5.3) is.
+ struct timespec ts;
+
+ ACE_OSCALL (ACE_OS::clock_gettime (CLOCK_REALTIME, &ts), int, -1, result);
+ tv.tv_sec = ts.tv_sec;
+ tv.tv_usec = ts.tv_nsec / 1000L; // timespec has nsec, but timeval has usec
+# else
+ ACE_OSCALL (::gettimeofday (&tv), int, -1, result);
+# endif /* ACE_HAS_SVR4_GETTIMEOFDAY */
+#endif /* 0 */
+#if !defined (ACE_HAS_WINCE)&& !defined (ACE_WIN32)
+ if (result == -1)
+ return -1;
+ else
+ return ACE_Time_Value (tv);
+#endif // !defined (ACE_HAS_WINCE)&& !defined (ACE_WIN32)
+}
+
+ACE_INLINE int
+ACE_OS::stat (const ACE_TCHAR *file, ACE_stat *stp)
+{
+ ACE_OS_TRACE ("ACE_OS::stat");
+#if defined (ACE_HAS_PACE)
+ ACE_OSCALL_RETURN (::pace_stat (file, stp), int, -1);
+#elif defined (VXWORKS)
+ ACE_OSCALL_RETURN (::stat ((char *) file, stp), int, -1);
+#elif defined (ACE_PSOS_LACKS_PHILE)
+ ACE_UNUSED_ARG (file);
+ ACE_UNUSED_ARG (stp);
+ ACE_NOTSUP_RETURN (-1);
+#elif defined (ACE_PSOS)
+ ACE_OSCALL_RETURN (::stat_f ((char *) file, stp), int, -1);
+#elif defined (ACE_HAS_WINCE)
+ ACE_TEXT_WIN32_FIND_DATA fdata;
+
+ HANDLE fhandle;
+
+ fhandle = ::FindFirstFile (file, &fdata);
+ if (fhandle == INVALID_HANDLE_VALUE)
+ {
+ ACE_OS::set_errno_to_last_error ();
+ return -1;
+ }
+ else if (fdata.nFileSizeHigh != 0)
+ {
+ errno = EINVAL;
+ return -1;
+ }
+ else
+ {
+ stp->st_size = fdata.nFileSizeLow;
+ stp->st_atime = ACE_Time_Value (fdata.ftLastAccessTime);
+ stp->st_mtime = ACE_Time_Value (fdata.ftLastWriteTime);
+ }
+ return 0;
+#elif defined (ACE_HAS_X86_STAT_MACROS)
+ // Solaris for intel uses an macro for stat(), this macro is a
+ // wrapper for _xstat().
+ ACE_OSCALL_RETURN (::_xstat (_STAT_VER, file, stp), int, -1);
+#elif defined (__BORLANDC__) && (__BORLANDC__ <= 0x540) && defined (ACE_USES_WCHAR)
+ ACE_OSCALL_RETURN (::_wstat (file, stp), int, -1);
+#elif defined (ACE_WIN32)
+# if defined (ACE_USES_WCHAR)
+ ACE_OSCALL_RETURN (::_wstat (file, (struct _stat *) stp), int, -1);
+# else
+ ACE_OSCALL_RETURN (::_stat (file, (struct _stat *) stp), int, -1);
+# endif /* ACE_USES_WCHAR */
+#else /* VXWORKS */
+ ACE_OSCALL_RETURN (::stat (file, stp), int, -1);
+#endif /* ACE_HAS_PACE */
+}
+
+ACE_INLINE time_t
+ACE_OS::time (time_t *tloc)
+{
+#if defined (ACE_HAS_PACE)
+ ACE_OSCALL_RETURN (::pace_time (tloc), time_t, (time_t) -1);
+#elif !defined (ACE_HAS_WINCE)
+ ACE_OS_TRACE ("ACE_OS::time");
+# if defined (ACE_PSOS) && ! defined (ACE_PSOS_HAS_TIME)
+ unsigned long d_date, d_time, d_tick;
+ tm_get(&d_date, &d_time, &d_tick); // get current time
+ if (tloc)
+ *tloc = d_time; // set time as time_t
+ return d_time;
+# else
+ ACE_OSCALL_RETURN (::time (tloc), time_t, (time_t) -1);
+# endif /* ACE_PSOS && ! ACE_PSOS_HAS_TIME */
+#else
+ time_t retv = ACE_OS::gettimeofday ().sec ();
+ if (tloc)
+ *tloc = retv;
+ return retv;
+#endif /* ACE_HAS_PACE */
+}
+
+ACE_INLINE void
+ACE_OS::srand (u_int seed)
+{
+ ACE_OS_TRACE ("ACE_OS::srand");
+#if defined (ACE_HAS_PACE)
+ ::pace_srand (seed);
+#else
+ ::srand (seed);
+#endif /* ACE_HAS_PACE */
+}
+
+ACE_INLINE int
+ACE_OS::rand (void)
+{
+ ACE_OS_TRACE ("ACE_OS::rand");
+#if defined (ACE_HAS_PACE)
+ ACE_OSCALL_RETURN (::pace_rand (), int, -1);
+#else
+ ACE_OSCALL_RETURN (::rand (), int, -1);
+#endif /* ACE_HAS_PACE */
+}
+
+ACE_INLINE int
+ACE_OS::unlink (const ACE_TCHAR *path)
+{
+ ACE_OS_TRACE ("ACE_OS::unlink");
+#if defined (ACE_HAS_PACE)
+ ACE_OSCALL_RETURN (::pace_unlink (path), int, -1);
+# elif defined (VXWORKS)
+ ACE_OSCALL_RETURN (::unlink (ACE_const_cast (char *, path)), int, -1);
+# elif defined (ACE_PSOS) && ! defined (ACE_PSOS_LACKS_PHILE)
+ ACE_OSCALL_RETURN (::remove_f ((char *) path), int , -1);
+# elif defined (ACE_PSOS) && defined (ACE_PSOS_HAS_C_LIBRARY)
+ ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::remove ((char *) path),
+ ace_result_),
+ int, -1);
+# elif defined (ACE_HAS_WINCE)
+ // @@ The problem is, DeleteFile is not actually equals to unlink. ;(
+ ACE_WIN32CALL_RETURN (ACE_ADAPT_RETVAL (::DeleteFile (path), ace_result_),
+ int, -1);
+# elif defined (ACE_LACKS_UNLINK)
+ ACE_UNUSED_ARG (path);
+ ACE_NOTSUP_RETURN (-1);
+# elif defined (ACE_WIN32) && defined (ACE_USES_WCHAR)
+ ACE_OSCALL_RETURN (::_wunlink (path), int, -1);
+# else
+ ACE_OSCALL_RETURN (::unlink (path), int, -1);
+# endif /* ACE_HAS_PACE */
+}
+
+ACE_INLINE int
+ACE_OS::rename (const ACE_TCHAR *old_name,
+ const ACE_TCHAR *new_name,
+ int flags)
+{
+#if defined (ACE_HAS_PACE)
+ ACE_UNUSED_ARG (flags);
+ ACE_OSCALL_RETURN (::pace_rename (old_name, new_name), int, -1);
+# elif (ACE_LACKS_RENAME)
+ ACE_UNUSED_ARG (old_name);
+ ACE_UNUSED_ARG (new_name);
+ ACE_UNUSED_ARG (flags);
+ ACE_NOTSUP_RETURN (-1);
+# elif defined (ACE_HAS_WINCE)
+ ACE_UNUSED_ARG (flags);
+ if (MoveFile (old_name, new_name) != 0)
+ ACE_FAIL_RETURN (-1);
+ return 0;
+# elif defined (ACE_WIN32) && defined (ACE_HAS_WINNT4) && (ACE_HAS_WINNT4 == 1)
+ // NT4 (and up) provides a way to rename/move a file with similar semantics
+ // to what's usually done on UNIX - if there's an existing file with
+ // <new_name> it is removed before the file is renamed/moved. The
+ // MOVEFILE_COPY_ALLOWED is specified to allow such a rename across drives.
+ if (flags == -1)
+ flags = MOVEFILE_COPY_ALLOWED | MOVEFILE_REPLACE_EXISTING;
+ if (ACE_TEXT_MoveFileEx(old_name, new_name, flags) == 0)
+ ACE_FAIL_RETURN (-1);
+ return 0;
+# elif defined (ACE_WIN32) && defined (ACE_USES_WCHAR)
+ ACE_UNUSED_ARG (flags);
+ ACE_OSCALL_RETURN (::_wrename (old_name, new_name), int, -1);
+# else /* ACE_LACKS_RENAME */
+ ACE_UNUSED_ARG (flags);
+ ACE_OSCALL_RETURN (::rename (old_name, new_name), int, -1);
+# endif /* ACE_HAS_PACE */
+}
+
+ACE_INLINE ACE_TCHAR *
+ACE_OS::tempnam (const ACE_TCHAR *dir, const ACE_TCHAR *pfx)
+{
+ ACE_OS_TRACE ("ACE_OS::tempnam");
+#if defined (VXWORKS) || defined (ACE_HAS_WINCE) || defined (ACE_LACKS_TEMPNAM)
+ ACE_UNUSED_ARG (dir);
+ ACE_UNUSED_ARG (pfx);
+ ACE_NOTSUP_RETURN (0);
+#elif defined (ACE_PSOS)
+ // pSOS only considers the directory prefix
+ ACE_UNUSED_ARG (pfx);
+ ACE_OSCALL_RETURN (::tmpnam ((char *) dir), char *, 0);
+#elif (defined (__BORLANDC__) && !defined(ACE_USES_WCHAR)) || (defined (ACE_WIN32) && defined (__IBMCPP__))
+ ACE_OSCALL_RETURN (::_tempnam ((char *) dir, (char *) pfx), char *, 0);
+#elif defined (__BORLANDC__) && defined (ACE_USES_WCHAR)
+ ACE_OSCALL_RETURN (::_wtempnam ((wchar_t*) dir, (wchar_t*) pfx), wchar_t *, 0);
+#elif defined (ACE_WIN32) && defined (ACE_USES_WCHAR)
+ ACE_OSCALL_RETURN (::_wtempnam (dir, pfx), wchar_t *, 0);
+#else /* VXWORKS */
+ ACE_OSCALL_RETURN (::tempnam (dir, pfx), char *, 0);
+#endif /* VXWORKS */
+}
+
+ACE_INLINE ACE_HANDLE
+ACE_OS::shm_open (const ACE_TCHAR *filename,
+ int mode,
+ int perms,
+ LPSECURITY_ATTRIBUTES sa)
+{
+ ACE_OS_TRACE ("ACE_OS::shm_open");
+#if defined (ACE_HAS_PACE) && !defined (ACE_WIN32)
+ ACE_UNUSED_ARG (sa);
+ ACE_OSCALL_RETURN (::pace_shm_open (filename, mode, perms), ACE_HANDLE, -1);
+# elif defined (ACE_HAS_SHM_OPEN)
+ ACE_UNUSED_ARG (sa);
+ ACE_OSCALL_RETURN (::shm_open (filename, mode, perms), ACE_HANDLE, -1);
+# else /* ! ACE_HAS_SHM_OPEN */
+ // Just use ::open.
+ return ACE_OS::open (filename, mode, perms, sa);
+# endif /* ACE_HAS_PACE */
+}
+
+ACE_INLINE int
+ACE_OS::shm_unlink (const ACE_TCHAR *path)
+{
+ ACE_OS_TRACE ("ACE_OS::shm_unlink");
+#if defined (ACE_HAS_PACE) && !defined (ACE_WIN32)
+ ACE_OSCALL_RETURN (::pace_shm_unlink (path), int, -1);
+# elif defined (ACE_HAS_SHM_OPEN)
+ ACE_OSCALL_RETURN (::shm_unlink (path), int, -1);
+# else /* ! ACE_HAS_SHM_OPEN */
+ // Just use ::unlink.
+ return ACE_OS::unlink (path);
+# endif /* ACE_HAS_PACE */
+}
+
+#if !defined (ACE_LACKS_CUSERID)
+ACE_INLINE char *
+ACE_OS::cuserid (char *user, size_t maxlen)
+{
+ ACE_OS_TRACE ("ACE_OS::cuserid");
+#if defined (VXWORKS)
+ ACE_UNUSED_ARG (maxlen);
+ if (user == 0)
+ {
+ // Require that the user field be non-null, i.e., don't
+ // allocate or use static storage.
+ ACE_NOTSUP_RETURN (0);
+ }
+ else
+ {
+ ::remCurIdGet (user, 0);
+ return user;
+ }
+#elif defined (CHORUS) || defined (ACE_PSOS) || defined (__QNXNTO__)
+ ACE_UNUSED_ARG (user);
+ ACE_UNUSED_ARG (maxlen);
+ ACE_NOTSUP_RETURN (0);
+#elif defined (ACE_WIN32)
+ BOOL result = GetUserNameA (user, (u_long *) &maxlen);
+ if (result == FALSE)
+ ACE_FAIL_RETURN (0);
+ else
+ return user;
+#elif defined (ACE_HAS_ALT_CUSERID)
+# if defined (ACE_LACKS_PWD_FUNCTIONS)
+# error Cannot use alternate cuserid() without POSIX password functions!
+# endif /* ACE_LACKS_PWD_FUNCTIONS */
+
+ // POSIX.1 dropped the cuserid() function.
+ // GNU GLIBC and other platforms correctly deprecate the cuserid()
+ // function.
+
+ if (maxlen == 0)
+ {
+ // It doesn't make sense to have a zero length user ID.
+ errno = EINVAL;
+ return 0;
+ }
+
+ struct passwd *pw = 0;
+
+ // Make sure the file pointer is at the beginning of the password file
+ ::setpwent ();
+ // Should use ACE_OS::setpwent() but I didn't want to move this
+ // method after it.
+
+ // Use the effective user ID to determine the user name.
+ pw = ::getpwuid (::geteuid ());
+
+ // Make sure the password file is closed.
+ ::endpwent ();
+
+ size_t max_length = 0;
+ char *userid = 0;
+
+ if (user == 0)
+ {
+ // Not reentrant/thread-safe, but nothing else can be done if a
+ // zero pointer was passed in as the destination.
+
+#if defined (_POSIX_SOURCE)
+ const size_t ACE_L_cuserid = L_cuserid;
+#else
+ const size_t ACE_L_cuserid = 9; // 8 character user ID + NULL
+#endif /* _POSIX_SOURCE */
+
+ static ACE_TCHAR tmp[ACE_L_cuserid] = { 0 };
+ max_length = ACE_L_cuserid - 1; // Do not include NULL in length
+
+ userid = tmp;
+ }
+ else
+ {
+ max_length = maxlen;
+ userid = user;
+ }
+
+ // Extract the user name from the passwd structure.
+ if (ACE_OS_String::strlen (pw->pw_name) <= max_length)
+ {
+ return ACE_OS_String::strcpy (userid, pw->pw_name);
+ }
+ else
+ {
+ errno = ENOSPC; // Buffer is not large enough.
+ return 0;
+ }
+#else
+ // Hackish because of missing buffer size!
+ ACE_UNUSED_ARG (maxlen);
+ ACE_OSCALL_RETURN (::ace_cuserid(user), char*, 0);
+#endif /* VXWORKS */
+}
+
+#if defined (ACE_HAS_WCHAR)
+ACE_INLINE wchar_t *
+ACE_OS::cuserid (wchar_t *user, size_t maxlen)
+{
+# if defined (ACE_WIN32)
+ BOOL result = GetUserNameW (user, (u_long *) &maxlen);
+ if (result == FALSE)
+ ACE_FAIL_RETURN (0);
+ else
+ return user;
+# else /* ACE_WIN32 */
+ char *char_user;
+ wchar_t *result = 0;
+
+ ACE_NEW_RETURN (char_user, char[maxlen + 1], 0);
+
+ if (ACE_OS::cuserid (char_user, maxlen))
+ {
+ ACE_OS::strcpy (user, ACE_Ascii_To_Wide (char_user).wchar_rep ());
+ result = user;
+ }
+
+ delete [] char_user;
+
+ return result;
+# endif /* ACE_WIN32 */
+}
+#endif /* ACE_HAS_WCHAR */
+#endif /* ACE_LACKS_CUSERID */
+
+ACE_INLINE int
+ACE_OS::atexit (ACE_EXIT_HOOK func)
+{
+ return ACE_OS_Object_Manager::instance ()->at_exit (func);
+}
+
+// Doesn't need a macro since it *never* returns!
+
+ACE_INLINE void
+ACE_OS::_exit (int status)
+{
+ ACE_OS_TRACE ("ACE_OS::_exit");
+#if defined (ACE_HAS_PACE)
+ ::pace_exit (status);
+#elif defined (VXWORKS)
+ ::exit (status);
+#elif defined (ACE_PSOSIM)
+ ::u_exit (status);
+#elif defined (ACE_PSOS)
+# if defined (ACE_PSOS_LACKS_PREPC) /* pSoS TM does not support exit. */
+ ACE_UNUSED_ARG (status);
+ return;
+# else
+ ::exit (status);
+# endif /* defined (ACE_PSOS_LACKS_PREPC) */
+#elif !defined (ACE_HAS_WINCE)
+ ::_exit (status);
+#else
+ ::TerminateProcess (::GetCurrentProcess (),
+ status);
+#endif /* ACE_HAS_PACE */
+}
+
+ACE_INLINE void
+ACE_OS::abort (void)
+{
+#if defined (ACE_HAS_PACE)
+ ::pace_abort ();
+#elif !defined (ACE_HAS_WINCE)
+ ::abort ();
+#else
+ // @@ CE doesn't support abort?
+ exit (1);
+#endif /* ACE_HAS_PACE */
+}
+
+#if !defined (ACE_HAS_WINCE)
+ACE_INLINE int
+ACE_OS::vsprintf (char *buffer, const char *format, va_list argptr)
+{
+# if defined (ACE_HAS_PACE)
+ return ACE_SPRINTF_ADAPTER (::pace_vsprintf (buffer, format, argptr));
+# else
+ return ACE_SPRINTF_ADAPTER (::vsprintf (buffer, format, argptr));
+# endif /* ACE_HAS_PACE */
+}
+#endif /* ACE_HAS_WINCE */
+
+#if defined (ACE_HAS_WCHAR)
+ACE_INLINE int
+ACE_OS::vsprintf (wchar_t *buffer, const wchar_t *format, va_list argptr)
+{
+# if defined (ACE_HAS_VSWPRINTF)
+ return ::vswprintf (buffer, format, argptr);
+
+# else
+ ACE_UNUSED_ARG (buffer);
+ ACE_UNUSED_ARG (format);
+ ACE_UNUSED_ARG (argptr);
+ ACE_NOTSUP_RETURN (-1);
+
+# endif /* ACE_HAS_VSWPRINTF */
+}
+#endif /* ACE_HAS_WCHAR */
+
+
+ACE_INLINE long
+ACE_OS::sysconf (int name)
+{
+ ACE_OS_TRACE ("ACE_OS::sysconf");
+#if defined (ACE_HAS_PACE)
+ ACE_OSCALL_RETURN (::pace_sysconf (name), long, -1);
+#elif defined (ACE_WIN32) || defined (VXWORKS) || defined (ACE_PSOS)
+ ACE_UNUSED_ARG (name);
+ ACE_NOTSUP_RETURN (-1);
+#else
+ ACE_OSCALL_RETURN (::sysconf (name), long, -1);
+#endif /* ACE_HAS_PACE*/
+}
+
+ACE_INLINE int
+ACE_OS::mutex_init (ACE_mutex_t *m,
+ int type,
+ const char *name,
+ ACE_mutexattr_t *attributes,
+ LPSECURITY_ATTRIBUTES sa)
+{
+ // ACE_OS_TRACE ("ACE_OS::mutex_init");
+#if defined (ACE_HAS_PACE) && !defined (ACE_WIN32)
+ pace_pthread_mutexattr_t l_attributes;
+ if (attributes == 0)
+ attributes = &l_attributes;
+ int result = 0;
+
+ // Only do these initializations if the <attributes> parameter
+ // wasn't originally set.
+ if (attributes == &l_attributes)
+ {
+ if (::pace_pthread_mutexattr_init (attributes) == 0)
+ result = 0;
+ else
+ result = -1; // ACE_ADAPT_RETVAL used it for intermediate status
+ }
+
+ if (result == 0)
+ {
+ if (
+# if defined (_POSIX_THREAD_PROCESS_SHARED)
+ ::pace_pthread_mutexattr_setpshared (attributes, type) == 0 &&
+# endif /* _POSIX_THREAD_PROCESS_SHARED */
+ ::pace_pthread_mutex_init (m, attributes) == 0)
+ result = 0;
+ else
+ result = -1; // ACE_ADAPT_RETVAL used it for intermediate status
+
+ // Only do the deletions if the <attributes> parameter wasn't
+ // originally set and we successfully created the attributes.
+ if (attributes == &l_attributes)
+ ::pace_pthread_mutexattr_destroy (&l_attributes);
+ }
+
+ ACE_UNUSED_ARG (sa);
+ ACE_UNUSED_ARG (name);
+ ACE_UNUSED_ARG (type);
+
+ return result;
+
+#elif defined (ACE_HAS_THREADS)
+# if defined (ACE_HAS_PTHREADS)
+ ACE_UNUSED_ARG (name);
+ ACE_UNUSED_ARG (attributes);
+ ACE_UNUSED_ARG (sa);
+
+ pthread_mutexattr_t l_attributes;
+ if (attributes == 0)
+ attributes = &l_attributes;
+ int result = 0;
+ int attr_init = 0; // have we initialized the local attributes.
+
+ // Only do these initializations if the <attributes> parameter
+ // wasn't originally set.
+ if (attributes == &l_attributes)
+ {
+# if defined (ACE_HAS_PTHREADS_DRAFT4)
+ if (::pthread_mutexattr_create (attributes) == 0)
+# elif defined (ACE_HAS_PTHREADS_DRAFT7) || defined (ACE_HAS_PTHREADS_STD)
+ if (ACE_ADAPT_RETVAL (::pthread_mutexattr_init (attributes), result) == 0)
+# else /* draft 6 */
+ if (::pthread_mutexattr_init (attributes) == 0)
+# endif /* ACE_HAS_PTHREADS_DRAFT4 */
+ {
+ result = 0;
+ attr_init = 1; // we have initialized these attributes
+ }
+ else
+ result = -1; // ACE_ADAPT_RETVAL used it for intermediate status
+ }
+
+ if (result == 0)
+ {
+# if defined (ACE_HAS_PTHREADS_DRAFT4)
+ if (
+# if defined (ACE_HAS_PTHREAD_MUTEXATTR_SETKIND_NP)
+ ::pthread_mutexattr_setkind_np (attributes, type) == 0 &&
+# endif /* ACE_HAS_PTHREAD_MUTEXATTR_SETKIND_NP */
+ ::pthread_mutex_init (m, *attributes) == 0)
+# elif defined (ACE_HAS_PTHREADS_DRAFT7) || defined (ACE_HAS_PTHREADS_STD)
+ if (
+# if defined (_POSIX_THREAD_PROCESS_SHARED) && !defined (ACE_LACKS_MUTEXATTR_PSHARED)
+ ACE_ADAPT_RETVAL (::pthread_mutexattr_setpshared (attributes, type),
+ result) == 0 &&
+# endif /* _POSIX_THREAD_PROCESS_SHARED && ! ACE_LACKS_MUTEXATTR_PSHARED */
+ ACE_ADAPT_RETVAL (::pthread_mutex_init (m, attributes), result) == 0)
+# else
+ if (
+# if !defined (ACE_LACKS_MUTEXATTR_PSHARED)
+ ::pthread_mutexattr_setpshared (attributes, type) == 0 &&
+# endif /* ACE_LACKS_MUTEXATTR_PSHARED */
+# if defined (ACE_HAS_PTHREAD_MUTEXATTR_SETKIND_NP)
+ ::pthread_mutexattr_setkind_np (attributes, type) == 0 &&
+# endif /* ACE_HAS_PTHREAD_MUTEXATTR_SETKIND_NP */
+ ::pthread_mutex_init (m, attributes) == 0)
+# endif /* ACE_HAS_PTHREADS_DRAFT4 */
+ result = 0;
+ else
+ result = -1; // ACE_ADAPT_RETVAL used it for intermediate status
+ }
+
+# if (!defined (ACE_HAS_PTHREAD_MUTEXATTR_SETKIND_NP) && !defined (_POSIX_THREAD_PROCESS_SHARED) || defined (ACE_LACKS_MUTEXATTR_PSHARED)) \
+ || ((defined (ACE_HAS_PTHREADS_DRAFT7) || defined (ACE_HAS_PTHREADS_STD)) && !defined (_POSIX_THREAD_PROCESS_SHARED))
+ ACE_UNUSED_ARG (type);
+# endif /* ! ACE_HAS_PTHREAD_MUTEXATTR_SETKIND_NP */
+
+ // Only do the deletions if the <attributes> parameter wasn't
+ // originally set.
+ if (attributes == &l_attributes && attr_init)
+# if defined (ACE_HAS_PTHREADS_DRAFT4)
+ ::pthread_mutexattr_delete (&l_attributes);
+# else
+ ::pthread_mutexattr_destroy (&l_attributes);
+# endif /* ACE_HAS_PTHREADS_DRAFT4 */
+
+ return result;
+# elif defined (ACE_HAS_STHREADS)
+ ACE_UNUSED_ARG (name);
+ ACE_UNUSED_ARG (sa);
+ ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::mutex_init (m, type, attributes),
+ ace_result_),
+ int, -1);
+# elif defined (ACE_HAS_WTHREADS)
+ m->type_ = type;
+
+ switch (type)
+ {
+ case USYNC_PROCESS:
+# if defined (ACE_HAS_WINCE)
+ // @@todo (brunsch) This idea should be moved into ACE_OS_Win32.
+ m->proc_mutex_ = ::CreateMutexW (ACE_OS::default_win32_security_attributes (sa),
+ FALSE,
+ ACE_Ascii_To_Wide (name).wchar_rep ());
+# else /* ACE_HAS_WINCE */
+ m->proc_mutex_ = ::CreateMutexA (ACE_OS::default_win32_security_attributes (sa),
+ FALSE,
+ name);
+# endif /* ACE_HAS_WINCE */
+ if (m->proc_mutex_ == 0)
+ ACE_FAIL_RETURN (-1);
+ else
+ {
+ // Make sure to set errno to ERROR_ALREADY_EXISTS if necessary.
+ ACE_OS::set_errno_to_last_error ();
+ return 0;
+ }
+ case USYNC_THREAD:
+ return ACE_OS::thread_mutex_init (&m->thr_mutex_,
+ type,
+ name,
+ attributes);
+ default:
+ errno = EINVAL;
+ return -1;
+ }
+ /* NOTREACHED */
+
+# elif defined (ACE_PSOS)
+ ACE_UNUSED_ARG (type);
+ ACE_UNUSED_ARG (attributes);
+ ACE_UNUSED_ARG (sa);
+# if defined (ACE_PSOS_HAS_MUTEX)
+
+ u_long flags = MU_LOCAL;
+ u_long ceiling = 0;
+
+# if defined (ACE_HAS_RECURSIVE_MUTEXES)
+ flags |= MU_RECURSIVE;
+# else /* ! ACE_HAS_RECURSIVE_MUTEXES */
+ flags |= MU_NONRECURSIVE;
+# endif /* ACE_HAS_RECURSIVE_MUTEXES */
+
+# if defined (ACE_PSOS_HAS_PRIO_MUTEX)
+
+ flags |= MU_PRIOR;
+
+# if defined (ACE_PSOS_HAS_PRIO_INHERIT_MUTEX)
+ flags |= MU_PRIO_INHERIT;
+# elif defined (ACE_PSOS_HAS_PRIO_PROTECT_MUTEX)
+ ceiling = PSOS_TASK_MAX_PRIORITY;
+ flags |= MU_PRIO_PROTECT;
+# else
+ flags |= MU_PRIO_NONE;
+# endif /* ACE_PSOS_HAS_PRIO_INHERIT_MUTEX */
+
+# else /* ! ACE_PSOS_HAS_PRIO_MUTEX */
+
+ flags |= MU_FIFO | MU_PRIO_NONE;
+
+# endif
+
+ // Fake a pSOS name - it can be any 4-byte value, not necessarily needing
+ // to be ASCII. So use the mutex pointer passed in. That should identify
+ // each one uniquely.
+ union { ACE_mutex_t *p; char n[4]; } m_name;
+ m_name.p = m;
+
+ ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::mu_create (m_name.n,
+ flags,
+ ceiling,
+ m),
+ ace_result_),
+ int, -1);
+
+# else /* ! ACE_PSOS_HAS_MUTEX */
+ ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::sm_create ((char *) name,
+ 1,
+ SM_LOCAL | SM_PRIOR,
+ m),
+ ace_result_),
+ int, -1);
+# endif /* ACE_PSOS_HAS_MUTEX */
+# elif defined (VXWORKS)
+ ACE_UNUSED_ARG (name);
+ ACE_UNUSED_ARG (attributes);
+ ACE_UNUSED_ARG (sa);
+
+ return (*m = ::semMCreate (type)) == 0 ? -1 : 0;
+# endif /* ACE_HAS_PTHREADS */
+#else
+ ACE_UNUSED_ARG (m);
+ ACE_UNUSED_ARG (type);
+ ACE_UNUSED_ARG (name);
+ ACE_UNUSED_ARG (attributes);
+ ACE_UNUSED_ARG (sa);
+ ACE_NOTSUP_RETURN (-1);
+#endif /* ACE_HAS_PACE */
+}
+
+#if defined (ACE_HAS_WCHAR)
+ACE_INLINE int
+ACE_OS::mutex_init (ACE_mutex_t *m,
+ int type,
+ const wchar_t *name,
+ ACE_mutexattr_t *attributes,
+ LPSECURITY_ATTRIBUTES sa)
+{
+#if defined (ACE_HAS_THREADS) && defined (ACE_HAS_WTHREADS)
+ m->type_ = type;
+
+ switch (type)
+ {
+ case USYNC_PROCESS:
+ m->proc_mutex_ = ::CreateMutexW (ACE_OS::default_win32_security_attributes (sa),
+ FALSE,
+ name);
+ if (m->proc_mutex_ == 0)
+ ACE_FAIL_RETURN (-1);
+ else
+ return 0;
+ case USYNC_THREAD:
+ return ACE_OS::thread_mutex_init (&m->thr_mutex_,
+ type,
+ name,
+ attributes);
+ }
+
+ errno = EINVAL;
+ return -1;
+#else /* ACE_HAS_THREADS && ACE_HAS_WTHREADS */
+ return ACE_OS::mutex_init (m,
+ type, ACE_Wide_To_Ascii (name).char_rep (),
+ attributes,
+ sa);
+#endif /* ACE_HAS_THREADS && ACE_HAS_WTHREADS */
+}
+#endif /* ACE_HAS_WCHAR */
+
+ACE_INLINE int
+ACE_OS::mutex_destroy (ACE_mutex_t *m)
+{
+ ACE_OS_TRACE ("ACE_OS::mutex_destroy");
+#if defined (ACE_HAS_PACE) && !defined (ACE_WIN32)
+ int dummy_retval = 0;
+ ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::pace_pthread_mutex_destroy (m),
+ dummy_retval), int, -1);
+#elif defined (ACE_HAS_THREADS)
+# if defined (ACE_HAS_PTHREADS)
+# if (defined (ACE_HAS_PTHREADS_DRAFT4) || defined (ACE_HAS_PTHREADS_DRAFT6))
+ ACE_OSCALL_RETURN (::pthread_mutex_destroy (m), int, -1);
+# else
+ ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::pthread_mutex_destroy (m),
+ ace_result_), int, -1);
+# endif /* ACE_HAS_PTHREADS_DRAFT4 || ACE_HAS_PTHREADS_DRAFT6*/
+# elif defined (ACE_HAS_STHREADS)
+ ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::mutex_destroy (m), ace_result_), int, -1);
+# elif defined (ACE_HAS_WTHREADS)
+ switch (m->type_)
+ {
+ case USYNC_PROCESS:
+ ACE_WIN32CALL_RETURN (ACE_ADAPT_RETVAL (::CloseHandle (m->proc_mutex_),
+ ace_result_),
+ int, -1);
+ case USYNC_THREAD:
+ return ACE_OS::thread_mutex_destroy (&m->thr_mutex_);
+ default:
+ errno = EINVAL;
+ return -1;
+ }
+ /* NOTREACHED */
+# elif defined (ACE_PSOS)
+# if defined (ACE_PSOS_HAS_MUTEX)
+ ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::mu_delete (*m), ace_result_),
+ int, -1);
+# else /* ! ACE_PSOS_HAS_MUTEX */
+ ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::sm_delete (*m), ace_result_),
+ int, -1);
+# endif /* ACE_PSOS_HAS_MUTEX */
+# elif defined (VXWORKS)
+ return ::semDelete (*m) == OK ? 0 : -1;
+# endif /* Threads variety case */
+#else
+ ACE_UNUSED_ARG (m);
+ ACE_NOTSUP_RETURN (-1);
+#endif /* ACE_HAS_PACE */
+}
+
+ACE_INLINE int
+ACE_OS::mutex_lock (ACE_mutex_t *m)
+{
+ // ACE_OS_TRACE ("ACE_OS::mutex_lock");
+#if defined (ACE_HAS_PACE) && !defined (ACE_WIN32)
+ int dummy_retval = 0;
+ ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::pace_pthread_mutex_lock (m),
+ dummy_retval), int, -1);
+#elif defined (ACE_HAS_THREADS)
+# if defined (ACE_HAS_PTHREADS)
+ // Note, don't use "::" here since the following call is often a macro.
+# if (defined (ACE_HAS_PTHREADS_DRAFT4) || defined (ACE_HAS_PTHREADS_DRAFT6))
+ ACE_OSCALL_RETURN (pthread_mutex_lock (m), int, -1);
+# else
+ ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (pthread_mutex_lock (m), ace_result_),
+ int, -1);
+# endif /* ACE_HAS_PTHREADS_DRAFT4 || ACE_HAS_PTHREADS_DRAFT6 */
+# elif defined (ACE_HAS_STHREADS)
+ ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::mutex_lock (m), ace_result_), int, -1);
+# elif defined (ACE_HAS_WTHREADS)
+ switch (m->type_)
+ {
+ case USYNC_PROCESS:
+ switch (::WaitForSingleObject (m->proc_mutex_, INFINITE))
+ {
+ //
+ // Timeout can't occur, so don't bother checking...
+ //
+ case WAIT_OBJECT_0:
+ case WAIT_ABANDONED:
+ // We will ignore abandonments in this method
+ // Note that we still hold the lock
+ return 0;
+ default:
+ // This is a hack, we need to find an appropriate mapping...
+ ACE_OS::set_errno_to_last_error ();
+ return -1;
+ }
+ case USYNC_THREAD:
+ return ACE_OS::thread_mutex_lock (&m->thr_mutex_);
+ default:
+ errno = EINVAL;
+ return -1;
+ }
+ /* NOTREACHED */
+# elif defined (ACE_PSOS)
+# if defined (ACE_PSOS_HAS_MUTEX)
+ ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::mu_lock (*m, MU_WAIT, 0),
+ ace_result_),
+ int, -1);
+# else /* ACE_PSOS_HAS_MUTEX */
+ ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::sm_p (*m, SM_WAIT, 0),
+ ace_result_),
+ int, -1);
+# endif /* ACE_PSOS_HAS_MUTEX */
+# elif defined (VXWORKS)
+ return ::semTake (*m, WAIT_FOREVER) == OK ? 0 : -1;
+# endif /* Threads variety case */
+#else
+ ACE_UNUSED_ARG (m);
+ ACE_NOTSUP_RETURN (-1);
+#endif /* ACE_HAS_PACE */
+}
+
+ACE_INLINE int
+ACE_OS::mutex_lock (ACE_mutex_t *m,
+ int &abandoned)
+{
+ ACE_OS_TRACE ("ACE_OS::mutex_lock");
+#if defined (ACE_HAS_THREADS) && defined (ACE_HAS_WTHREADS)
+ abandoned = 0;
+ switch (m->type_)
+ {
+ case USYNC_PROCESS:
+ switch (::WaitForSingleObject (m->proc_mutex_, INFINITE))
+ {
+ //
+ // Timeout can't occur, so don't bother checking...
+ //
+ case WAIT_OBJECT_0:
+ return 0;
+ case WAIT_ABANDONED:
+ abandoned = 1;
+ return 0; // something goofed, but we hold the lock ...
+ default:
+ // This is a hack, we need to find an appropriate mapping...
+ ACE_OS::set_errno_to_last_error ();
+ return -1;
+ }
+ case USYNC_THREAD:
+ return ACE_OS::thread_mutex_lock (&m->thr_mutex_);
+ default:
+ errno = EINVAL;
+ return -1;
+ }
+ /* NOTREACHED */
+#else
+ ACE_UNUSED_ARG (m);
+ ACE_UNUSED_ARG (abandoned);
+ ACE_NOTSUP_RETURN (-1);
+#endif /* ACE_HAS_THREADS and ACE_HAS_WTHREADS */
+}
+
+ACE_INLINE int
+ACE_OS::mutex_trylock (ACE_mutex_t *m)
+{
+ ACE_OS_TRACE ("ACE_OS::mutex_trylock");
+#if defined (ACE_HAS_PACE) && !defined (ACE_WIN32)
+ int dummy_retval = 0;
+ ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::pace_pthread_mutex_trylock (m),
+ dummy_retval), int, -1);
+#elif defined (ACE_HAS_THREADS)
+# if defined (ACE_HAS_PTHREADS)
+ // Note, don't use "::" here since the following call is often a macro.
+# if (defined (ACE_HAS_PTHREADS_DRAFT4) || defined (ACE_HAS_PTHREADS_DRAFT6))
+ int status = pthread_mutex_trylock (m);
+ if (status == 1)
+ status = 0;
+ else if (status == 0) {
+ status = -1;
+ errno = EBUSY;
+ }
+ return status;
+# else
+ ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (pthread_mutex_trylock (m), ace_result_),
+ int, -1);
+# endif /* ACE_HAS_PTHREADS_DRAFT4 || ACE_HAS_PTHREADS_DRAFT6 */
+# elif defined (ACE_HAS_STHREADS)
+ ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::mutex_trylock (m), ace_result_), int, -1);
+# elif defined (ACE_HAS_WTHREADS)
+ switch (m->type_)
+ {
+ case USYNC_PROCESS:
+ {
+ // Try for 0 milliseconds - i.e. nonblocking.
+ switch (::WaitForSingleObject (m->proc_mutex_, 0))
+ {
+ case WAIT_OBJECT_0:
+ return 0;
+ case WAIT_ABANDONED:
+ // We will ignore abandonments in this method. Note that
+ // we still hold the lock.
+ return 0;
+ case WAIT_TIMEOUT:
+ errno = EBUSY;
+ return -1;
+ default:
+ ACE_OS::set_errno_to_last_error ();
+ return -1;
+ }
+ }
+ case USYNC_THREAD:
+ return ACE_OS::thread_mutex_trylock (&m->thr_mutex_);
+ default:
+ errno = EINVAL;
+ return -1;
+ }
+ /* NOTREACHED */
+# elif defined (ACE_PSOS)
+# if defined (ACE_PSOS_HAS_MUTEX)
+ ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::mu_lock (*m, MU_NOWAIT, 0),
+ ace_result_),
+ int, -1);
+# else /* ! ACE_PSOS_HAS_MUTEX */
+ switch (::sm_p (*m, SM_NOWAIT, 0))
+ {
+ case 0:
+ return 0;
+ case ERR_NOSEM:
+ errno = EBUSY;
+ // intentional fall through
+ default:
+ return -1;
+ }
+# endif /* ACE_PSOS_HAS_MUTEX */
+
+# elif defined (VXWORKS)
+ if (::semTake (*m, NO_WAIT) == ERROR)
+ if (errno == S_objLib_OBJ_UNAVAILABLE)
+ {
+ // couldn't get the semaphore
+ errno = EBUSY;
+ return -1;
+ }
+ else
+ // error
+ return -1;
+ else
+ // got the semaphore
+ return 0;
+# endif /* Threads variety case */
+#else
+ ACE_UNUSED_ARG (m);
+ ACE_NOTSUP_RETURN (-1);
+#endif /* ACE_HAS_PACE */
+}
+
+ACE_INLINE int
+ACE_OS::mutex_trylock (ACE_mutex_t *m, int &abandoned)
+{
+#if defined (ACE_HAS_THREADS) && defined (ACE_HAS_WTHREADS)
+ abandoned = 0;
+ switch (m->type_)
+ {
+ case USYNC_PROCESS:
+ {
+ // Try for 0 milliseconds - i.e. nonblocking.
+ switch (::WaitForSingleObject (m->proc_mutex_, 0))
+ {
+ case WAIT_OBJECT_0:
+ return 0;
+ case WAIT_ABANDONED:
+ abandoned = 1;
+ return 0; // something goofed, but we hold the lock ...
+ case WAIT_TIMEOUT:
+ errno = EBUSY;
+ return -1;
+ default:
+ ACE_OS::set_errno_to_last_error ();
+ return -1;
+ }
+ }
+ case USYNC_THREAD:
+ return ACE_OS::thread_mutex_trylock (&m->thr_mutex_);
+ default:
+ errno = EINVAL;
+ return -1;
+ }
+ /* NOTREACHED */
+#else
+ ACE_UNUSED_ARG (m);
+ ACE_UNUSED_ARG (abandoned);
+ ACE_NOTSUP_RETURN (-1);
+#endif /* ACE_HAS_THREADS and ACE_HAS_WTHREADS */
+}
+
+ACE_INLINE int
+ACE_OS::mutex_lock (ACE_mutex_t *m,
+ const ACE_Time_Value &timeout)
+{
+#if defined (ACE_HAS_THREADS) && defined (ACE_HAS_MUTEX_TIMEOUTS)
+
+# if defined (ACE_HAS_PTHREADS)
+ int result;
+
+ // "timeout" should be an absolute time.
+
+ timespec_t ts = timeout; // Calls ACE_Time_Value::operator timespec_t().
+
+ // Note that the mutex should not be a recursive one, i.e., it
+ // should only be a standard mutex or an error checking mutex.
+
+ ACE_OSCALL (ACE_ADAPT_RETVAL (::pthread_mutex_timedlock (m, &ts), result), int, -1, result);
+
+ // We need to adjust this to make the errno values consistent.
+ if (result == -1 && errno == ETIMEDOUT)
+ errno = ETIME;
+ return result;
+
+# elif defined (ACE_HAS_WTHREADS)
+ // Note that we must convert between absolute time (which is passed
+ // as a parameter) and relative time (which is what the system call
+ // expects).
+ ACE_Time_Value relative_time (timeout - ACE_OS::gettimeofday ());
+
+ switch (m->type_)
+ {
+ case USYNC_PROCESS:
+ switch (::WaitForSingleObject (m->proc_mutex_,
+ relative_time.msec ()))
+ {
+ case WAIT_OBJECT_0:
+ case WAIT_ABANDONED:
+ // We will ignore abandonments in this method
+ // Note that we still hold the lock
+ return 0;
+ case WAIT_TIMEOUT:
+ errno = ETIME;
+ return -1;
+ default:
+ // This is a hack, we need to find an appropriate mapping...
+ ACE_OS::set_errno_to_last_error ();
+ return -1;
+ }
+ case USYNC_THREAD:
+ ACE_NOTSUP_RETURN (-1);
+ default:
+ errno = EINVAL;
+ return -1;
+ }
+ /* NOTREACHED */
+
+# elif defined (ACE_PSOS)
+
+ // Note that we must convert between absolute time (which is
+ // passed as a parameter) and relative time (which is what
+ // the system call expects).
+ ACE_Time_Value relative_time (timeout - ACE_OS::gettimeofday ());
+
+ u_long ticks = relative_time.sec() * KC_TICKS2SEC +
+ relative_time.usec () * KC_TICKS2SEC /
+ ACE_ONE_SECOND_IN_USECS;
+ if (ticks == 0)
+ ACE_OSCALL_RETURN (::sm_p (*m, SM_NOWAIT, 0), int, -1); // no timeout
+ else
+ ACE_OSCALL_RETURN (::sm_p (*m, SM_WAIT, ticks), int, -1);
+
+# elif defined (VXWORKS)
+
+ // Note that we must convert between absolute time (which is passed
+ // as a parameter) and relative time (which is what the system call
+ // expects).
+ ACE_Time_Value relative_time (timeout - ACE_OS::gettimeofday ());
+
+ int ticks_per_sec = ::sysClkRateGet ();
+
+ int ticks = relative_time.sec() * ticks_per_sec +
+ relative_time.usec () * ticks_per_sec / ACE_ONE_SECOND_IN_USECS;
+ if (::semTake (*m, ticks) == ERROR)
+ {
+ if (errno == S_objLib_OBJ_TIMEOUT)
+ // Convert the VxWorks errno to one that's common for to ACE
+ // platforms.
+ errno = ETIME;
+ else if (errno == S_objLib_OBJ_UNAVAILABLE)
+ errno = EBUSY;
+ return -1;
+ }
+ else
+ return 0;
+# endif /* ACE_HAS_PTHREADS */
+
+#else
+ ACE_UNUSED_ARG (m);
+ ACE_UNUSED_ARG (timeout);
+ ACE_NOTSUP_RETURN (-1);
+#endif /* ACE_HAS_THREADS && ACE_HAS_MUTEX_TIMEOUTS */
+}
+
+ACE_INLINE int
+ACE_OS::mutex_lock (ACE_mutex_t *m,
+ const ACE_Time_Value *timeout)
+{
+ return timeout == 0 ? ACE_OS::mutex_lock (m) : ACE_OS::mutex_lock (m, *timeout);
+}
+
+ACE_INLINE int
+ACE_OS::mutex_unlock (ACE_mutex_t *m)
+{
+ ACE_OS_TRACE ("ACE_OS::mutex_unlock");
+#if defined (ACE_HAS_PACE) && !defined (ACE_WIN32)
+ int dummy_retval = 0;
+ ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::pace_pthread_mutex_unlock (m),
+ dummy_retval), int, -1);
+#elif defined (ACE_HAS_THREADS)
+# if defined (ACE_HAS_PTHREADS)
+ // Note, don't use "::" here since the following call is often a macro.
+# if (defined (ACE_HAS_PTHREADS_DRAFT4) || defined (ACE_HAS_PTHREADS_DRAFT6))
+ ACE_OSCALL_RETURN (pthread_mutex_unlock (m), int, -1);
+# else
+ ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (pthread_mutex_unlock (m), ace_result_),
+ int, -1);
+# endif /* ACE_HAS_PTHREADS_DRAFT4 || ACE_HAS_PTHREADS_DRAFT6 */
+# elif defined (ACE_HAS_STHREADS)
+ ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::mutex_unlock (m), ace_result_), int, -1);
+# elif defined (ACE_HAS_WTHREADS)
+ switch (m->type_)
+ {
+ case USYNC_PROCESS:
+ ACE_WIN32CALL_RETURN (ACE_ADAPT_RETVAL (::ReleaseMutex (m->proc_mutex_),
+ ace_result_),
+ int, -1);
+ case USYNC_THREAD:
+ return ACE_OS::thread_mutex_unlock (&m->thr_mutex_);
+ default:
+ errno = EINVAL;
+ return -1;
+ }
+ /* NOTREACHED */
+# elif defined (ACE_PSOS)
+# if defined (ACE_PSOS_HAS_MUTEX)
+ ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::mu_unlock (*m), ace_result_),
+ int, -1);
+# else /* ! ACE_PSOS_HAS_MUTEX */
+ ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::sm_v (*m), ace_result_),
+ int, -1);
+# endif /* ACE_PSOS_HAS_MUTEX */
+# elif defined (VXWORKS)
+ return ::semGive (*m) == OK ? 0 : -1;
+# endif /* Threads variety case */
+#else
+ ACE_UNUSED_ARG (m);
+ ACE_NOTSUP_RETURN (-1);
+#endif /* ACE_HAS_PACE */
+}
+
+ACE_INLINE int
+ACE_OS::thread_mutex_init (ACE_thread_mutex_t *m,
+ int type,
+ const char *name,
+ ACE_mutexattr_t *arg)
+{
+ // ACE_OS_TRACE ("ACE_OS::thread_mutex_init");
+#if defined (ACE_HAS_THREADS)
+# if defined (ACE_HAS_WTHREADS)
+ ACE_UNUSED_ARG (type);
+ ACE_UNUSED_ARG (name);
+ ACE_UNUSED_ARG (arg);
+ ::InitializeCriticalSection (m);
+ return 0;
+
+# elif defined (ACE_HAS_STHREADS) || defined (ACE_HAS_PTHREADS) || defined (ACE_HAS_PACE)
+ ACE_UNUSED_ARG (type);
+ // Force the use of USYNC_THREAD!
+ return ACE_OS::mutex_init (m, USYNC_THREAD, name, arg);
+
+# elif defined (VXWORKS) || defined (ACE_PSOS)
+ return mutex_init (m, type, name, arg);
+
+# endif /* ACE_HAS_STHREADS || ACE_HAS_PTHREADS */
+
+#else
+ ACE_UNUSED_ARG (m);
+ ACE_UNUSED_ARG (type);
+ ACE_UNUSED_ARG (name);
+ ACE_UNUSED_ARG (arg);
+ ACE_NOTSUP_RETURN (-1);
+
+#endif /* ACE_HAS_THREADS */
+}
+
+#if defined (ACE_HAS_WCHAR)
+ACE_INLINE int
+ACE_OS::thread_mutex_init (ACE_thread_mutex_t *m,
+ int type,
+ const wchar_t *name,
+ ACE_mutexattr_t *arg)
+{
+ // ACE_OS_TRACE ("ACE_OS::thread_mutex_init");
+#if defined (ACE_HAS_THREADS)
+# if defined (ACE_HAS_WTHREADS)
+ ACE_UNUSED_ARG (type);
+ ACE_UNUSED_ARG (name);
+ ACE_UNUSED_ARG (arg);
+ ::InitializeCriticalSection (m);
+ return 0;
+
+# elif defined (ACE_HAS_STHREADS) || defined (ACE_HAS_PTHREADS) || defined (ACE_HAS_PACE)
+ ACE_UNUSED_ARG (type);
+ // Force the use of USYNC_THREAD!
+ return ACE_OS::mutex_init (m, USYNC_THREAD, name, arg);
+
+# elif defined (VXWORKS) || defined (ACE_PSOS)
+ return mutex_init (m, type, name, arg);
+
+# endif /* ACE_HAS_STHREADS || ACE_HAS_PTHREADS */
+
+#else
+ ACE_UNUSED_ARG (m);
+ ACE_UNUSED_ARG (type);
+ ACE_UNUSED_ARG (name);
+ ACE_UNUSED_ARG (arg);
+ ACE_NOTSUP_RETURN (-1);
+
+#endif /* ACE_HAS_THREADS */
+}
+#endif /* ACE_HAS_WCHAR */
+
+ACE_INLINE int
+ACE_OS::thread_mutex_destroy (ACE_thread_mutex_t *m)
+{
+ ACE_OS_TRACE ("ACE_OS::thread_mutex_destroy");
+#if defined (ACE_HAS_THREADS)
+# if defined (ACE_HAS_WTHREADS)
+ ::DeleteCriticalSection (m);
+ return 0;
+
+# elif defined (ACE_HAS_STHREADS) || defined (ACE_HAS_PTHREADS) || defined (ACE_HAS_PACE)
+ return ACE_OS::mutex_destroy (m);
+
+# elif defined (VXWORKS) || defined (ACE_PSOS)
+ return mutex_destroy (m);
+
+# endif /* ACE_HAS_STHREADS || ACE_HAS_PTHREADS */
+
+#else
+ ACE_UNUSED_ARG (m);
+ ACE_NOTSUP_RETURN (-1);
+
+#endif /* ACE_HAS_THREADS */
+}
+
+ACE_INLINE int
+ACE_OS::thread_mutex_lock (ACE_thread_mutex_t *m)
+{
+ // ACE_OS_TRACE ("ACE_OS::thread_mutex_lock");
+#if defined (ACE_HAS_THREADS)
+# if defined (ACE_HAS_WTHREADS)
+ ::EnterCriticalSection (m);
+ return 0;
+# elif defined (ACE_HAS_STHREADS) || defined (ACE_HAS_PTHREADS) || defined (ACE_HAS_PACE)
+ return ACE_OS::mutex_lock (m);
+#elif defined (VXWORKS) || defined (ACE_PSOS)
+ return mutex_lock (m);
+#endif /* ACE_HAS_STHREADS || ACE_HAS_PTHREADS || ACE_HAS_PACE */
+#else
+ ACE_UNUSED_ARG (m);
+ ACE_NOTSUP_RETURN (-1);
+#endif /* ACE_HAS_THREADS */
+}
+
+ACE_INLINE int
+ACE_OS::thread_mutex_lock (ACE_thread_mutex_t *m,
+ const ACE_Time_Value &timeout)
+{
+ // ACE_OS_TRACE ("ACE_OS::thread_mutex_lock");
+
+ // For all platforms, except MS Windows, this method is equivalent
+ // to calling ACE_OS::mutex_lock() since ACE_thread_mutex_t and
+ // ACE_mutex_t are the same type. However, those typedefs evaluate
+ // to different types on MS Windows. The "thread mutex"
+ // implementation in ACE for MS Windows cannot readily support
+ // timeouts due to a lack of timeout features for this type of MS
+ // Windows synchronization mechanism.
+
+#if defined (ACE_HAS_THREADS) && !defined (ACE_HAS_WTHREADS)
+# if defined (ACE_HAS_STHREADS) || defined (ACE_HAS_PTHREADS) || defined (ACE_HAS_PACE)
+ return ACE_OS::mutex_lock (m, timeout);
+#elif defined (VXWORKS) || defined (ACE_PSOS)
+ return mutex_lock (m, timeout);
+#endif /* ACE_HAS_STHREADS || ACE_HAS_PTHREADS || ACE_HAS_PACE */
+#else
+ ACE_UNUSED_ARG (m);
+ ACE_UNUSED_ARG (timeout);
+ ACE_NOTSUP_RETURN (-1);
+#endif /* ACE_HAS_THREADS */
+}
+
+ACE_INLINE int
+ACE_OS::thread_mutex_lock (ACE_thread_mutex_t *m,
+ const ACE_Time_Value *timeout)
+{
+ return timeout == 0
+ ? ACE_OS::thread_mutex_lock (m)
+ : ACE_OS::thread_mutex_lock (m, *timeout);
+}
+
+ACE_INLINE int
+ACE_OS::thread_mutex_trylock (ACE_thread_mutex_t *m)
+{
+ ACE_OS_TRACE ("ACE_OS::thread_mutex_trylock");
+
+#if defined (ACE_HAS_THREADS)
+# if defined (ACE_HAS_WTHREADS)
+# if defined (ACE_HAS_WIN32_TRYLOCK)
+ BOOL result = ::TryEnterCriticalSection (m);
+ if (result == TRUE)
+ return 0;
+ else
+ {
+ errno = EBUSY;
+ return -1;
+ }
+# else
+ ACE_UNUSED_ARG (m);
+ ACE_NOTSUP_RETURN (-1);
+# endif /* ACE_HAS_WIN32_TRYLOCK */
+# elif defined (ACE_HAS_STHREADS) || defined (ACE_HAS_PTHREADS) || defined (ACE_HAS_PACE)
+ return ACE_OS::mutex_trylock (m);
+# elif defined (VXWORKS) || defined (ACE_PSOS)
+ return ACE_OS::mutex_trylock (m);
+#endif /* Threads variety case */
+
+#else
+ ACE_UNUSED_ARG (m);
+ ACE_NOTSUP_RETURN (-1);
+#endif /* ACE_HAS_THREADS */
+}
+
+ACE_INLINE int
+ACE_OS::thread_mutex_unlock (ACE_thread_mutex_t *m)
+{
+ ACE_OS_TRACE ("ACE_OS::thread_mutex_unlock");
+#if defined (ACE_HAS_THREADS)
+# if defined (ACE_HAS_WTHREADS)
+ ::LeaveCriticalSection (m);
+ return 0;
+# elif defined (ACE_HAS_STHREADS) || defined (ACE_HAS_PTHREADS) || defined (ACE_HAS_PACE)
+ return ACE_OS::mutex_unlock (m);
+# elif defined (VXWORKS) || defined (ACE_PSOS)
+ return ACE_OS::mutex_unlock (m);
+# endif /* Threads variety case */
+#else
+ ACE_UNUSED_ARG (m);
+ ACE_NOTSUP_RETURN (-1);
+#endif /* ACE_HAS_THREADS */
+}
+
+// If we're using PACE then we want this method unless we're on Windows.
+// Win32 mutexes, semaphores, and condition variables are not yet
+// supported in PACE.
+#if !defined (ACE_LACKS_COND_T) || (defined (ACE_HAS_PACE) && !defined (ACE_WIN32))
+// NOTE: The ACE_OS::cond_* functions for Unix platforms are defined
+// here because the ACE_OS::sema_* functions below need them.
+// However, ACE_WIN32 and VXWORKS define the ACE_OS::cond_* functions
+// using the ACE_OS::sema_* functions. So, they are defined in OS.cpp.
+
+ACE_INLINE int
+ACE_OS::cond_destroy (ACE_cond_t *cv)
+{
+ ACE_OS_TRACE ("ACE_OS::cond_destroy");
+#if defined (ACE_HAS_PACE) && !defined (ACE_WIN32)
+ ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::pace_pthread_cond_destroy (cv),
+ ace_result_), int, -1);
+# elif defined (ACE_HAS_THREADS)
+# if defined (ACE_HAS_PTHREADS)
+# if defined (ACE_HAS_PTHREADS_DRAFT4) || defined (ACE_HAS_PTHREADS_DRAFT6)
+ ACE_OSCALL_RETURN (::pthread_cond_destroy (cv), int, -1);
+# else
+ ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::pthread_cond_destroy (cv), ace_result_), int, -1);
+# endif /* ACE_HAS_PTHREADS_DRAFT4 || ACE_HAS_PTHREADS_DRAFT6 */
+# elif defined (ACE_HAS_STHREADS)
+ ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::cond_destroy (cv), ace_result_), int, -1);
+# elif defined (ACE_PSOS) && defined (ACE_PSOS_HAS_COND_T)
+ ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::cv_delete (*cv), ace_result_),
+ int, -1);
+# endif /* ACE_HAS_STHREADS */
+# else
+ ACE_UNUSED_ARG (cv);
+ ACE_NOTSUP_RETURN (-1);
+# endif /* ACE_HAS_PACE */
+}
+
+ACE_INLINE int
+ACE_OS::condattr_init (ACE_condattr_t &attributes,
+ int type)
+{
+ ACE_UNUSED_ARG (type);
+#if defined (ACE_HAS_PACE) && !defined (ACE_WIN32)
+ int result = -1;
+
+ if (::pace_pthread_condattr_init (&attributes) == 0
+# if defined (_POSIX_THREAD_PROCESS_SHARED)
+ && ::pace_pthread_condattr_setpshared(&attributes, type) == 0
+# endif /* _POSIX_THREAD_PROCESS_SHARED */
+ )
+ result = 0;
+ else
+ result = -1; // ACE_ADAPT_RETVAL used it for intermediate status
+
+ return result;
+
+# elif defined (ACE_HAS_THREADS) && ! defined (__MACOSX__)
+# if defined (ACE_HAS_PTHREADS)
+ int result = -1;
+
+ if (
+# if defined (ACE_HAS_PTHREADS_DRAFT4)
+ ::pthread_condattr_create (&attributes) == 0
+# elif defined (ACE_HAS_PTHREADS_STD) || defined (ACE_HAS_PTHREADS_DRAFT7)
+ ACE_ADAPT_RETVAL(::pthread_condattr_init (&attributes), result) == 0
+# if defined (_POSIX_THREAD_PROCESS_SHARED) && !defined (ACE_LACKS_MUTEXATTR_PSHARED)
+ && ACE_ADAPT_RETVAL(::pthread_condattr_setpshared(&attributes, type),
+ result) == 0
+# endif /* _POSIX_THREAD_PROCESS_SHARED && ! ACE_LACKS_MUTEXATTR_PSHARED */
+# else /* this is draft 6 */
+ ::pthread_condattr_init (&attributes) == 0
+# if !defined (ACE_LACKS_CONDATTR_PSHARED)
+ && ::pthread_condattr_setpshared (&attributes, type) == 0
+# endif /* ACE_LACKS_CONDATTR_PSHARED */
+# if defined (ACE_HAS_PTHREAD_CONDATTR_SETKIND_NP)
+ && ::pthread_condattr_setkind_np (&attributes, type) == 0
+# endif /* ACE_HAS_PTHREAD_CONDATTR_SETKIND_NP */
+# endif /* ACE_HAS_PTHREADS_DRAFT4 */
+ )
+ result = 0;
+ else
+ result = -1; // ACE_ADAPT_RETVAL used it for intermediate status
+
+ return result;
+# elif defined (ACE_HAS_STHREADS)
+ attributes.type = type;
+
+ return 0;
+
+# elif defined (ACE_PSOS) && defined (ACE_PSOS_HAS_COND_T)
+# if defined (ACE_PSOS_HAS_PRIO_MUTEX)
+ attributes = CV_LOCAL | CV_PRIOR;
+# else /* ACE_PSOS_HAS_PRIO_MUTEX */
+ attributes = CV_LOCAL | CV_FIFO;
+# endif /* ACE_PSOS_HAS_PRIO_MUTEX */
+ return 0;
+
+# else
+ ACE_UNUSED_ARG (attributes);
+ ACE_UNUSED_ARG (type);
+ ACE_NOTSUP_RETURN (-1);
+
+# endif /* ACE_HAS_PTHREADS vs. ACE_HAS_STHREADS vs. pSOS */
+
+# elif defined (__MACOSX__)
+ ACE_UNUSED_ARG (attributes);
+ ACE_UNUSED_ARG (type);
+ return 0;
+
+#else
+ ACE_UNUSED_ARG (attributes);
+ ACE_UNUSED_ARG (type);
+ ACE_NOTSUP_RETURN (-1);
+# endif /* */
+}
+
+ACE_INLINE int
+ACE_OS::condattr_destroy (ACE_condattr_t &attributes)
+{
+#if defined (ACE_HAS_PACE) && !defined (ACE_WIN32)
+ return ::pace_pthread_condattr_destroy (&attributes);
+# elif defined (ACE_HAS_THREADS) && ! defined (__MACOSX__)
+# if defined (ACE_HAS_PTHREADS)
+
+# if defined (ACE_HAS_PTHREADS_DRAFT4)
+ ::pthread_condattr_delete (&attributes);
+# else
+ ::pthread_condattr_destroy (&attributes);
+# endif /* ACE_HAS_PTHREADS_DRAFT4 */
+
+# elif defined (ACE_HAS_STHREADS)
+ attributes.type = 0;
+
+# elif defined (ACE_PSOS) && defined (ACE_PSOS_HAS_COND_T)
+ attributes = 0;
+
+# endif /* ACE_HAS_PTHREADS vs. ACE_HAS_STHREADS vs. ACE_PSOS */
+ return 0;
+# else
+ ACE_UNUSED_ARG (attributes);
+ return 0;
+# endif /* ACE_HAS_PACE */
+}
+
+ACE_INLINE int
+ACE_OS::cond_init (ACE_cond_t *cv,
+ ACE_condattr_t &attributes,
+ const char *name,
+ void *arg)
+{
+ // ACE_OS_TRACE ("ACE_OS::cond_init");
+ ACE_UNUSED_ARG (name);
+ ACE_UNUSED_ARG (arg);
+#if defined (ACE_HAS_PACE) && !defined (ACE_WIN32)
+ ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::pace_pthread_cond_init (cv, &attributes),
+ ace_result_), int, -1);
+# elif defined (ACE_HAS_THREADS)
+# if defined (ACE_HAS_PTHREADS)
+ int result = -1;
+
+ if (
+# if defined (ACE_HAS_PTHREADS_DRAFT4)
+ ::pthread_cond_init (cv, attributes) == 0
+# elif defined (ACE_HAS_PTHREADS_STD) || defined (ACE_HAS_PTHREADS_DRAFT7)
+ ACE_ADAPT_RETVAL(::pthread_cond_init (cv, &attributes), result) == 0
+# else /* this is draft 6 */
+ ::pthread_cond_init (cv, &attributes) == 0
+# endif /* ACE_HAS_PTHREADS_DRAFT4 */
+ )
+ result = 0;
+ else
+ result = -1; // ACE_ADAPT_RETVAL used it for intermediate status
+
+ return result;
+# elif defined (ACE_HAS_STHREADS)
+ ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::cond_init (cv,
+ attributes.type,
+ arg),
+ ace_result_),
+ int, -1);
+# elif defined (ACE_PSOS) && defined (ACE_PSOS_HAS_COND_T)
+ ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::cv_create (ACE_const_cast (char *, name),
+ attributes,
+ cv),
+ ace_result_),
+ int, -1);
+# endif /* ACE_HAS_PTHREADS vs. ACE_HAS_STHREADS vs. ACE_PSOS */
+# else
+ ACE_UNUSED_ARG (cv);
+ ACE_UNUSED_ARG (attributes);
+ ACE_UNUSED_ARG (name);
+ ACE_UNUSED_ARG (arg);
+ ACE_NOTSUP_RETURN (-1);
+# endif /* ACE_HAS_PACE */
+}
+
+#if defined (ACE_HAS_WCHAR)
+ACE_INLINE int
+ACE_OS::cond_init (ACE_cond_t *cv,
+ ACE_condattr_t &attributes,
+ const wchar_t *name,
+ void *arg)
+{
+ return ACE_OS::cond_init (cv, attributes, ACE_Wide_To_Ascii (name).char_rep (), arg);
+}
+#endif /* ACE_HAS_WCHAR */
+
+ACE_INLINE int
+ACE_OS::cond_init (ACE_cond_t *cv, short type, const char *name, void *arg)
+{
+ ACE_condattr_t attributes;
+ if (ACE_OS::condattr_init (attributes, type) == 0
+ && ACE_OS::cond_init (cv, attributes, name, arg) == 0)
+ {
+ (void) ACE_OS::condattr_destroy (attributes);
+ return 0;
+ }
+ return -1;
+}
+
+#if defined (ACE_HAS_WCHAR)
+ACE_INLINE int
+ACE_OS::cond_init (ACE_cond_t *cv, short type, const wchar_t *name, void *arg)
+{
+ return ACE_OS::cond_init (cv, type, ACE_Wide_To_Ascii (name).char_rep (), arg);
+}
+#endif /* ACE_HAS_WCHAR */
+
+ACE_INLINE int
+ACE_OS::cond_signal (ACE_cond_t *cv)
+{
+ ACE_OS_TRACE ("ACE_OS::cond_signal");
+#if defined (ACE_HAS_PACE) && !defined (ACE_WIN32)
+ ACE_OSCALL_RETURN (::pace_pthread_cond_signal (cv), int, -1);
+# elif defined (ACE_HAS_THREADS)
+# if defined (ACE_HAS_PTHREADS)
+# if defined (ACE_HAS_PTHREADS_DRAFT4) || defined (ACE_HAS_PTHREADS_DRAFT6)
+ ACE_OSCALL_RETURN (::pthread_cond_signal (cv), int, -1);
+# else
+ ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::pthread_cond_signal (cv),ace_result_),
+ int, -1);
+# endif /* ACE_HAS_PTHREADS_DRAFT4 || ACE_HAS_PTHREADS_DRAFT6 */
+# elif defined (ACE_HAS_STHREADS)
+ ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::cond_signal (cv), ace_result_), int, -1);
+# elif defined (ACE_PSOS) && defined (ACE_PSOS_HAS_COND_T)
+ ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::cv_signal (*cv), ace_result_),
+ int, -1);
+# endif /* ACE_HAS_STHREADS */
+# else
+ ACE_UNUSED_ARG (cv);
+ ACE_NOTSUP_RETURN (-1);
+# endif /* ACE_HAS_PACE */
+}
+
+ACE_INLINE int
+ACE_OS::cond_broadcast (ACE_cond_t *cv)
+{
+ ACE_OS_TRACE ("ACE_OS::cond_broadcast");
+#if defined (ACE_HAS_PACE) && !defined (ACE_WIN32)
+ ACE_OSCALL_RETURN (::pace_pthread_cond_broadcast (cv), int, -1);
+# elif defined (ACE_HAS_THREADS)
+# if defined (ACE_HAS_PTHREADS)
+# if defined (ACE_HAS_PTHREADS_DRAFT4) || defined (ACE_HAS_PTHREADS_DRAFT6)
+ ACE_OSCALL_RETURN (::pthread_cond_broadcast (cv), int, -1);
+# else
+ ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::pthread_cond_broadcast (cv),
+ ace_result_),
+ int, -1);
+# endif /* ACE_HAS_PTHREADS_DRAFT4 || ACE_HAS_PTHREADS_DRAFT6 */
+# elif defined (ACE_HAS_STHREADS)
+ ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::cond_broadcast (cv),
+ ace_result_),
+ int, -1);
+# elif defined (ACE_PSOS) && defined (ACE_PSOS_HAS_COND_T)
+ ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::cv_broadcast (*cv), ace_result_),
+ int, -1);
+# endif /* ACE_HAS_STHREADS */
+# else
+ ACE_UNUSED_ARG (cv);
+ ACE_NOTSUP_RETURN (-1);
+# endif /* ACE_HAS_PACE */
+}
+
+ACE_INLINE int
+ACE_OS::cond_wait (ACE_cond_t *cv,
+ ACE_mutex_t *external_mutex)
+{
+ ACE_OS_TRACE ("ACE_OS::cond_wait");
+#if defined (ACE_HAS_PACE) && !defined (ACE_WIN32)
+ ACE_OSCALL_RETURN (::pace_pthread_cond_wait (cv, external_mutex), int, -1);
+# elif defined (ACE_HAS_THREADS)
+# if defined (ACE_HAS_PTHREADS)
+# if defined (ACE_HAS_PTHREADS_DRAFT4) || defined (ACE_HAS_PTHREADS_DRAFT6)
+ ACE_OSCALL_RETURN (::pthread_cond_wait (cv, external_mutex), int, -1);
+# else
+ ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::pthread_cond_wait (cv, external_mutex), ace_result_),
+ int, -1);
+# endif /* ACE_HAS_PTHREADS_DRAFT4 || ACE_HAS_PTHREADS_DRAFT6 */
+# elif defined (ACE_HAS_STHREADS)
+ ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::cond_wait (cv, external_mutex), ace_result_),
+ int, -1);
+# elif defined (ACE_PSOS) && defined (ACE_PSOS_HAS_COND_T)
+ ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::cv_wait (*cv, *external_mutex, 0),
+ ace_result_),
+ int, -1);
+# endif /* ACE_HAS_PTHREADS */
+# else
+ ACE_UNUSED_ARG (cv);
+ ACE_UNUSED_ARG (external_mutex);
+ ACE_NOTSUP_RETURN (-1);
+# endif /* ACE_HAS_PACE */
+}
+
+ACE_INLINE int
+ACE_OS::cond_timedwait (ACE_cond_t *cv,
+ ACE_mutex_t *external_mutex,
+ ACE_Time_Value *timeout)
+{
+ ACE_OS_TRACE ("ACE_OS::cond_timedwait");
+ //#if defined (ACE_HAS_PACE)
+#if 0
+ int result;
+ timespec_t ts;
+
+ if (timeout != 0)
+ ts = *timeout; // Calls ACE_Time_Value::operator timespec_t().
+ ACE_OSCALL (ACE_ADAPT_RETVAL (timeout == 0
+ ? (::pace_pthread_cond_wait (cv, external_mutex))
+ : (::pace_pthread_cond_timedwait (cv, external_mutex, (ACE_TIMESPEC_PTR) &ts),
+ int, -1, result)));
+
+ // We need to adjust this to make the POSIX and Solaris return
+ // values consistent. EAGAIN is from Pthreads DRAFT4 (HP-UX 10.20 and
+ // down); EINTR is from LynxOS.
+ if (result == -1 &&
+ (errno == ETIMEDOUT || errno == EAGAIN || errno == EINTR))
+ errno = ETIME;
+
+ if (timeout != 0)
+ timeout->set (ts); // Update the time value before returning.
+
+ return result;
+
+# elif defined (ACE_HAS_THREADS)
+ int result;
+ timespec_t ts;
+
+ if (timeout != 0)
+ ts = *timeout; // Calls ACE_Time_Value::operator timespec_t().
+
+# if defined (ACE_HAS_PTHREADS)
+
+# if defined (ACE_HAS_PTHREADS_DRAFT4) || defined (ACE_HAS_PTHREADS_DRAFT6)
+ if (timeout == 0)
+ ACE_OSCALL (::pthread_cond_wait (cv, external_mutex),
+ int, -1, result);
+ else
+ {
+
+# if defined (__Lynx__)
+ // Note that we must convert between absolute time (which is
+ // passed as a parameter) and relative time (which is what the
+ // LynxOS pthread_cond_timedwait expects). This differs from 1003.4a
+ // draft 4.
+
+ timespec_t relative_time = *timeout - ACE_OS::gettimeofday ();
+
+ ACE_OSCALL (::pthread_cond_timedwait (cv, external_mutex,
+ &relative_time),
+ int, -1, result);
+# else
+ ACE_OSCALL (::pthread_cond_timedwait (cv, external_mutex,
+ (ACE_TIMESPEC_PTR) &ts),
+ int, -1, result);
+# endif /* __Lynx__ */
+ }
+
+# else
+ ACE_OSCALL (ACE_ADAPT_RETVAL (timeout == 0
+ ? ::pthread_cond_wait (cv, external_mutex)
+ : ::pthread_cond_timedwait (cv, external_mutex,
+ (ACE_TIMESPEC_PTR) &ts),
+ result),
+ int, -1, result);
+# endif /* ACE_HAS_PTHREADS_DRAFT4 || ACE_HAS_PTHREADS_DRAFT6*/
+ // We need to adjust this to make the POSIX and Solaris return
+ // values consistent. EAGAIN is from Pthreads DRAFT4 (HP-UX 10.20 and
+ // down); EINTR is from LynxOS.
+ if (result == -1 &&
+ (errno == ETIMEDOUT || errno == EAGAIN || errno == EINTR))
+ errno = ETIME;
+
+# elif defined (ACE_HAS_STHREADS)
+ ACE_OSCALL (ACE_ADAPT_RETVAL (timeout == 0
+ ? ::cond_wait (cv, external_mutex)
+ : ::cond_timedwait (cv,
+ external_mutex,
+ (timestruc_t*)&ts),
+ result),
+ int, -1, result);
+# elif defined (ACE_PSOS) && defined (ACE_PSOS_HAS_COND_T)
+ // pSOS condition value timeout is expressed in ticks. If the
+ // cv_wait times out, the mutex is unlocked upon return.
+ if (timeout == 0)
+ {
+ ACE_OSCALL (ACE_ADAPT_RETVAL (::cv_wait (*cv, *external_mutex, 0),
+ result),
+ int, -1, result);
+ }
+ else
+ {
+ // Need to convert the passed absolute time to relative time
+ // expressed in ticks.
+ ACE_Time_Value relative_time (*timeout - ACE_OS::gettimeofday ());
+ int ticks = (relative_time.sec () * KC_TICKS2SEC) +
+ (relative_time.usec () * KC_TICKS2SEC /
+ ACE_ONE_SECOND_IN_USECS);
+ if (ticks <= 0)
+ ticks = 1; // Don't wait forever
+ ACE_OSCALL (ACE_ADAPT_RETVAL (::cv_wait (*cv, *external_mutex, ticks),
+ result),
+ int, -1, result);
+ if (result == -1 && errno == 1)
+ {
+ // cv timed out and returned pSOS timeout error 0x01, which
+ // ACE_ADAPT_RETVAL stored in errno.
+ ::mu_lock (*external_mutex, MU_WAIT, 0);
+ errno = ETIME;
+ }
+ }
+
+ return result;
+
+# endif /* ACE_HAS_STHREADS */
+ if (timeout != 0)
+ timeout->set (ts); // Update the time value before returning.
+
+ return result;
+# else
+ ACE_UNUSED_ARG (cv);
+ ACE_UNUSED_ARG (external_mutex);
+ ACE_UNUSED_ARG (timeout);
+ ACE_NOTSUP_RETURN (-1);
+# endif /* ACE_HAS_PACE */
+}
+#endif /* !ACE_LACKS_COND_T */
+
+ACE_INLINE int
+ACE_OS::thr_equal (ACE_thread_t t1, ACE_thread_t t2)
+{
+#if defined (ACE_HAS_PACE) && !defined (ACE_WIN32)
+ return ::pace_pthread_equal (t1, t2);
+#elif defined (ACE_HAS_PTHREADS)
+# if defined (pthread_equal)
+ // If it's a macro we can't say "::pthread_equal"...
+ return pthread_equal (t1, t2);
+# else
+ return ::pthread_equal (t1, t2);
+# endif /* pthread_equal */
+#elif defined (VXWORKS)
+ return ! ACE_OS::strcmp (t1, t2);
+#else /* For both STHREADS and WTHREADS... */
+ // Hum, Do we need to treat WTHREAD differently?
+ // levine 13 oct 98 % I don't think so, ACE_thread_t is a DWORD.
+ return t1 == t2;
+#endif /* ACE_HAS_PACE */
+}
+
+ACE_INLINE void
+ACE_OS::thr_self (ACE_hthread_t &self)
+{
+ ACE_OS_TRACE ("ACE_OS::thr_self");
+#if defined (ACE_HAS_PACE) && !defined (ACE_WIN32)
+ self = ::pace_pthread_self ();
+#elif defined (ACE_HAS_THREADS)
+# if defined (ACE_HAS_PTHREADS)
+ // Note, don't use "::" here since the following call is often a macro.
+ self = pthread_self ();
+# elif defined (ACE_HAS_THREAD_SELF)
+ self = ::thread_self ();
+# elif defined (ACE_HAS_STHREADS)
+ self = ::thr_self ();
+# elif defined (ACE_HAS_WTHREADS)
+ self = ::GetCurrentThread ();
+# elif defined (ACE_PSOS)
+ t_ident ((char *) 0, 0, &self);
+# elif defined (VXWORKS)
+ self = ::taskIdSelf ();
+# endif /* ACE_HAS_STHREADS */
+#else
+ self = 1; // Might as well make it the main thread ;-)
+#endif /* ACE_HAS_PACE */
+}
+
+ACE_INLINE ACE_thread_t
+ACE_OS::thr_self (void)
+{
+ // ACE_OS_TRACE ("ACE_OS::thr_self");
+#if defined (ACE_HAS_PACE) && !defined (ACE_WIN32)
+ return ::pace_pthread_self ();
+#elif defined (ACE_HAS_THREADS)
+# if defined (ACE_HAS_PTHREADS)
+ // Note, don't use "::" here since the following call is often a macro.
+ ACE_OSCALL_RETURN (pthread_self (), int, -1);
+# elif defined (ACE_HAS_STHREADS)
+ ACE_OSCALL_RETURN (::thr_self (), int, -1);
+# elif defined (ACE_HAS_WTHREADS)
+ return ::GetCurrentThreadId ();
+# elif defined (ACE_PSOS)
+ // there does not appear to be a way to get
+ // a task's name other than at creation
+ return 0;
+# elif defined (VXWORKS)
+ return ::taskName (::taskIdSelf ());
+# endif /* ACE_HAS_STHREADS */
+#else
+ return 1; // Might as well make it the first thread ;-)
+#endif /* ACE_HAS_PACE */
+}
+
+ACE_INLINE int
+ACE_OS::recursive_mutex_init (ACE_recursive_thread_mutex_t *m,
+ const ACE_TCHAR *name,
+ ACE_mutexattr_t *arg,
+ LPSECURITY_ATTRIBUTES sa)
+{
+ ACE_UNUSED_ARG (sa);
+#if defined (ACE_HAS_THREADS)
+#if defined (ACE_HAS_RECURSIVE_MUTEXES)
+ return ACE_OS::thread_mutex_init (m, 0, name, arg);
+#else
+ if (ACE_OS::thread_mutex_init (&m->nesting_mutex_, 0, name, arg) == -1)
+ return -1;
+ else if (ACE_OS::cond_init (&m->lock_available_,
+ (short) USYNC_THREAD,
+ name,
+ 0) == -1)
+ return -1;
+ else
+ {
+ m->nesting_level_ = 0;
+ m->owner_id_ = ACE_OS::NULL_thread;
+ return 0;
+ }
+#endif /* ACE_HAS_RECURSIVE_MUTEXES */
+#else
+ ACE_UNUSED_ARG (m);
+ ACE_UNUSED_ARG (name);
+ ACE_UNUSED_ARG (arg);
+ ACE_NOTSUP_RETURN (-1);
+#endif /* ACE_HAS_THREADS */
+}
+
+ACE_INLINE int
+ACE_OS::recursive_mutex_destroy (ACE_recursive_thread_mutex_t *m)
+{
+#if defined (ACE_HAS_THREADS)
+#if defined (ACE_HAS_RECURSIVE_MUTEXES)
+ return ACE_OS::thread_mutex_destroy (m);
+#else
+ if (ACE_OS::thread_mutex_destroy (&m->nesting_mutex_) == -1)
+ return -1;
+ else if (ACE_OS::cond_destroy (&m->lock_available_) == -1)
+ return -1;
+ else
+ return 0;
+#endif /* ACE_HAS_RECURSIVE_MUTEXES */
+#else
+ ACE_UNUSED_ARG (m);
+ ACE_NOTSUP_RETURN (-1);
+#endif /* ACE_HAS_THREADS */
+}
+
+ACE_INLINE int
+ACE_OS::recursive_mutex_lock (ACE_recursive_thread_mutex_t *m)
+{
+#if defined (ACE_HAS_THREADS)
+#if defined (ACE_HAS_RECURSIVE_MUTEXES)
+ return ACE_OS::thread_mutex_lock (m);
+#else
+ ACE_thread_t t_id = ACE_OS::thr_self ();
+ int result = 0;
+
+ // Acquire the guard.
+ if (ACE_OS::thread_mutex_lock (&m->nesting_mutex_) == -1)
+ result = -1;
+ else
+ {
+ // If there's no contention, just grab the lock immediately
+ // (since this is the common case we'll optimize for it).
+ if (m->nesting_level_ == 0)
+ m->owner_id_ = t_id;
+ // If we already own the lock, then increment the nesting level
+ // and return.
+ else if (ACE_OS::thr_equal (t_id, m->owner_id_) == 0)
+ {
+ // Wait until the nesting level has dropped to zero, at
+ // which point we can acquire the lock.
+ while (m->nesting_level_ > 0)
+ ACE_OS::cond_wait (&m->lock_available_,
+ &m->nesting_mutex_);
+
+ // At this point the nesting_mutex_ is held...
+ m->owner_id_ = t_id;
+ }
+
+ // At this point, we can safely increment the nesting_level_ no
+ // matter how we got here!
+ m->nesting_level_++;
+ }
+
+ {
+ // Save/restore errno.
+ ACE_Errno_Guard error (errno);
+ ACE_OS::thread_mutex_unlock (&m->nesting_mutex_);
+ }
+ return result;
+#endif /* ACE_HAS_RECURSIVE_MUTEXES */
+#else
+ ACE_UNUSED_ARG (m);
+ ACE_NOTSUP_RETURN (-1);
+#endif /* ACE_HAS_THREADS */
+}
+
+ACE_INLINE int
+ACE_OS::recursive_mutex_trylock (ACE_recursive_thread_mutex_t *m)
+{
+#if defined (ACE_HAS_THREADS)
+#if defined (ACE_HAS_RECURSIVE_MUTEXES)
+ return ACE_OS::thread_mutex_trylock (m);
+#else
+ ACE_thread_t t_id = ACE_OS::thr_self ();
+ int result = 0;
+
+ // Acquire the guard.
+ if (ACE_OS::thread_mutex_lock (&m->nesting_mutex_) == -1)
+ result = -1;
+ else
+ {
+ // If there's no contention, just grab the lock immediately.
+ if (m->nesting_level_ == 0)
+ {
+ m->owner_id_ = t_id;
+ m->nesting_level_ = 1;
+ }
+ // If we already own the lock, then increment the nesting level
+ // and proceed.
+ else if (ACE_OS::thr_equal (t_id, m->owner_id_))
+ m->nesting_level_++;
+ else
+ {
+ errno = EBUSY;
+ result = -1;
+ }
+ }
+
+ {
+ // Save/restore errno.
+ ACE_Errno_Guard error (errno);
+ ACE_OS::thread_mutex_unlock (&m->nesting_mutex_);
+ }
+ return result;
+#endif /* ACE_HAS_RECURSIVE_MUTEXES */
+#else
+ ACE_UNUSED_ARG (m);
+ ACE_NOTSUP_RETURN (-1);
+#endif /* ACE_HAS_THREADS */
+}
+
+ACE_INLINE int
+ACE_OS::recursive_mutex_unlock (ACE_recursive_thread_mutex_t *m)
+{
+#if defined (ACE_HAS_THREADS)
+#if defined (ACE_HAS_RECURSIVE_MUTEXES)
+ return ACE_OS::thread_mutex_unlock (m);
+#else
+ ACE_OS_TRACE ("ACE_OS::recursive_mutex_unlock");
+#if !defined (ACE_NDEBUG)
+ ACE_thread_t t_id = ACE_OS::thr_self ();
+#endif /* ACE_NDEBUG */
+ int result = 0;
+
+ if (ACE_OS::thread_mutex_lock (&m->nesting_mutex_) == -1)
+ result = -1;
+ else
+ {
+#if !defined (ACE_NDEBUG)
+ if (m->nesting_level_ == 0
+ || ACE_OS::thr_equal (t_id, m->owner_id_) == 0)
+ {
+ errno = EINVAL;
+ result = -1;
+ }
+ else
+#endif /* ACE_NDEBUG */
+ {
+ m->nesting_level_--;
+ if (m->nesting_level_ == 0)
+ {
+ // This may not be strictly necessary, but it does put
+ // the mutex into a known state...
+ m->owner_id_ = ACE_OS::NULL_thread;
+
+ // Inform a waiter that the lock is free.
+ if (ACE_OS::cond_signal (&m->lock_available_) == -1)
+ result = -1;
+ }
+ }
+ }
+
+ {
+ // Save/restore errno.
+ ACE_Errno_Guard error (errno);
+ ACE_OS::thread_mutex_unlock (&m->nesting_mutex_);
+ }
+ return result;
+#endif /* ACE_HAS_RECURSIVE_MUTEXES */
+#else
+ ACE_UNUSED_ARG (m);
+ ACE_NOTSUP_RETURN (-1);
+#endif /* ACE_HAS_THREADS */
+}
+
+ACE_INLINE int
+ACE_OS::sema_destroy (ACE_sema_t *s)
+{
+ ACE_OS_TRACE ("ACE_OS::sema_destroy");
+#if defined (ACE_HAS_PACE) && !defined (ACE_WIN32)
+ int result;
+ if (s->name_)
+ {
+ result = ::pace_sem_unlink (s->name_);
+ pace_free ((void *) s->name_);
+ return pace_sem_close (s->sema_);
+ }
+ else
+ {
+ result = ::pace_sem_destroy (s->sema_);
+ delete s->sema_;
+ s->sema_ = 0;
+ return result;
+ }
+# elif defined (ACE_HAS_POSIX_SEM)
+ int result;
+# if defined (ACE_LACKS_NAMED_POSIX_SEM)
+ if (s->name_)
+ {
+ // Only destroy the semaphore if we're the ones who
+ // initialized it.
+ ACE_OSCALL (::sem_destroy (s->sema_),int, -1, result);
+ ACE_OS::shm_unlink (s->name_);
+ delete s->name_;
+ return result;
+ }
+# else
+ if (s->name_)
+ {
+ ACE_OSCALL (::sem_unlink (s->name_), int, -1, result);
+ ACE_OS::free ((void *) s->name_);
+ ACE_OSCALL_RETURN (::sem_close (s->sema_), int, -1);
+ }
+# endif /* ACE_LACKS_NAMED_POSIX_SEM */
+ else
+ {
+ ACE_OSCALL (::sem_destroy (s->sema_), int, -1, result);
+# if defined (ACE_LACKS_NAMED_POSIX_SEM)
+ if (s->new_sema_ != 0)
+# endif /* ACE_LACKS_NAMED_POSIX_SEM */
+ delete s->sema_;
+ s->sema_ = 0;
+ return result;
+ }
+# elif defined (ACE_HAS_THREADS)
+# if defined (ACE_HAS_STHREADS)
+ ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::sema_destroy (s), ace_result_), int, -1);
+# elif defined (ACE_HAS_PTHREADS)
+ int r1 = ACE_OS::mutex_destroy (&s->lock_);
+ int r2 = ACE_OS::cond_destroy (&s->count_nonzero_);
+ return r1 != 0 || r2 != 0 ? -1 : 0;
+# elif defined (ACE_HAS_WTHREADS)
+# if !defined (ACE_USES_WINCE_SEMA_SIMULATION)
+ ACE_WIN32CALL_RETURN (ACE_ADAPT_RETVAL (::CloseHandle (*s), ace_result_), int, -1);
+# else /* ACE_USES_WINCE_SEMA_SIMULATION */
+ // Free up underlying objects of the simulated semaphore.
+ int r1 = ACE_OS::thread_mutex_destroy (&s->lock_);
+ int r2 = ACE_OS::event_destroy (&s->count_nonzero_);
+ return r1 != 0 || r2 != 0 ? -1 : 0;
+# endif /* ACE_USES_WINCE_SEMA_SIMULATION */
+# elif defined (ACE_PSOS)
+ int result;
+ ACE_OSCALL (ACE_ADAPT_RETVAL (::sm_delete (s->sema_), result), int, -1, result);
+ s->sema_ = 0;
+ return result;
+# elif defined (VXWORKS)
+ int result;
+ ACE_OSCALL (::semDelete (s->sema_), int, -1, result);
+ s->sema_ = 0;
+ return result;
+# endif /* ACE_HAS_STHREADS */
+# else
+ ACE_UNUSED_ARG (s);
+ ACE_NOTSUP_RETURN (-1);
+# endif /* ACE_HAS_PACE */
+}
+
+// NOTE: The following four function definitions must appear before
+// ACE_OS::sema_init ().
+
+ACE_INLINE int
+ACE_OS::close (ACE_HANDLE handle)
+{
+ ACE_OS_TRACE ("ACE_OS::close");
+#if defined (ACE_HAS_PACE)
+ ACE_OSCALL_RETURN (::pace_close (handle), int, -1);
+#elif defined (ACE_WIN32)
+ ACE_WIN32CALL_RETURN (ACE_ADAPT_RETVAL (::CloseHandle (handle), ace_result_), int, -1);
+#elif defined (ACE_PSOS) && ! defined (ACE_PSOS_LACKS_PHILE)
+ u_long result = ::close_f (handle);
+ if (result != 0)
+ {
+ errno = result;
+ return ACE_static_cast (int, -1);
+ }
+ return ACE_static_cast (int, 0);
+#else
+ ACE_OSCALL_RETURN (::close (handle), int, -1);
+#endif /* ACE_HAS_PACE */
+}
+
+// This function returns the number of bytes in the file referenced by
+// FD.
+
+ACE_INLINE long
+ACE_OS::filesize (ACE_HANDLE handle)
+{
+ ACE_OS_TRACE ("ACE_OS::filesize");
+#if defined (ACE_WIN32)
+ ACE_WIN32CALL_RETURN (::GetFileSize (handle, NULL), long, -1);
+#else /* !ACE_WIN32 */
+ struct stat sb;
+ return ACE_OS::fstat (handle, &sb) == -1 ? -1 : (long) sb.st_size;
+#endif /* ACE_WIN32 */
+}
+
+ACE_INLINE int
+ACE_OS::ftruncate (ACE_HANDLE handle, off_t offset)
+{
+ ACE_OS_TRACE ("ACE_OS::ftruncate");
+#if defined (ACE_HAS_PACE)
+ ACE_OSCALL_RETURN (::pace_ftruncate (handle, offset), int, -1);
+#elif defined (ACE_WIN32)
+ if (::SetFilePointer (handle, offset, NULL, FILE_BEGIN) != (unsigned) -1)
+ ACE_WIN32CALL_RETURN (ACE_ADAPT_RETVAL (::SetEndOfFile (handle), ace_result_), int, -1);
+ else
+ ACE_FAIL_RETURN (-1);
+ /* NOTREACHED */
+#elif defined (ACE_PSOS_LACKS_PHILE)
+ ACE_UNUSED_ARG (handle);
+ ACE_UNUSED_ARG (offset);
+ ACE_NOTSUP_RETURN (-1);
+#elif defined (ACE_PSOS)
+ ACE_OSCALL_RETURN (::ftruncate_f (handle, offset), int, -1);
+#else
+ ACE_OSCALL_RETURN (::ftruncate (handle, offset), int, -1);
+#endif /* ACE_HAS_PACE */
+}
+
+ACE_INLINE void *
+ACE_OS::mmap (void *addr,
+ size_t len,
+ int prot,
+ int flags,
+ ACE_HANDLE file_handle,
+ off_t off,
+ ACE_HANDLE *file_mapping,
+ LPSECURITY_ATTRIBUTES sa,
+ const ACE_TCHAR *file_mapping_name)
+{
+ ACE_OS_TRACE ("ACE_OS::mmap");
+#if !defined (ACE_WIN32) || defined (ACE_HAS_PHARLAP)
+ ACE_UNUSED_ARG (file_mapping_name);
+#endif /* !defined (ACE_WIN32) || defined (ACE_HAS_PHARLAP) */
+
+#if defined (ACE_HAS_PACE) && !defined (__Lynx__) && !defined (ACE_WIN32)
+ ACE_UNUSED_ARG (file_mapping);
+ ACE_UNUSED_ARG (sa);
+ ACE_OSCALL_RETURN ((void *) ::pace_mmap (addr,
+ len,
+ prot,
+ flags,
+ file_handle,
+ off),
+ void *, MAP_FAILED);
+
+#elif defined (ACE_WIN32) && !defined (ACE_HAS_PHARLAP)
+ int nt_flags = 0;
+ ACE_HANDLE local_handle = ACE_INVALID_HANDLE;
+
+ // Ensure that file_mapping is non-zero.
+ if (file_mapping == 0)
+ file_mapping = &local_handle;
+
+ if (ACE_BIT_ENABLED (flags, MAP_PRIVATE))
+ {
+ prot = PAGE_WRITECOPY;
+ nt_flags = FILE_MAP_COPY;
+ }
+ else if (ACE_BIT_ENABLED (flags, MAP_SHARED))
+ {
+ if (ACE_BIT_ENABLED (prot, PAGE_READONLY))
+ nt_flags = FILE_MAP_READ;
+ if (ACE_BIT_ENABLED (prot, PAGE_READWRITE))
+ nt_flags = FILE_MAP_WRITE;
+ }
+
+ // Only create a new handle if we didn't have a valid one passed in.
+ if (*file_mapping == ACE_INVALID_HANDLE)
+ {
+#if !defined(ACE_HAS_WINCE) && (!defined (ACE_HAS_WINNT4) || (ACE_HAS_WINNT4 == 0))
+ int try_create = 1;
+ if ((file_mapping_name != 0) && (*file_mapping_name != 0))
+ {
+ // On Win9x, we first try to OpenFileMapping to
+ // file_mapping_name. Only if there is no mapping object
+ // with that name we try CreateFileMapping.
+
+ *file_mapping = ACE_TEXT_OpenFileMapping (nt_flags,
+ 0,
+ file_mapping_name);
+ if (*file_mapping != 0
+ || ::GetLastError () != ERROR_INVALID_NAME)
+ try_create = 0;
+ }
+
+ if (try_create)
+#endif /* !ACE_HAS_WINCE && (ACE_HAS_WINNT4 || ACE_HAS_WINNT4 == 0) */
+ {
+ const LPSECURITY_ATTRIBUTES attr =
+ ACE_OS::default_win32_security_attributes (sa);
+
+ *file_mapping = ACE_TEXT_CreateFileMapping (file_handle,
+ attr,
+ prot,
+ 0,
+ 0,
+ file_mapping_name);
+ }
+ }
+
+ if (*file_mapping == 0)
+ ACE_FAIL_RETURN (MAP_FAILED);
+
+# if defined (ACE_OS_EXTRA_MMAP_FLAGS)
+ nt_flags |= ACE_OS_EXTRA_MMAP_FLAGS;
+# endif /* ACE_OS_EXTRA_MMAP_FLAGS */
+
+# if !defined (ACE_HAS_WINCE)
+ void *addr_mapping = ::MapViewOfFileEx (*file_mapping,
+ nt_flags,
+ 0,
+ off,
+ len,
+ addr);
+# else
+ ACE_UNUSED_ARG (addr); // WinCE doesn't allow specifying <addr>.
+ void *addr_mapping = ::MapViewOfFile (*file_mapping,
+ nt_flags,
+ 0,
+ off,
+ len);
+# endif /* ! ACE_HAS_WINCE */
+
+ // Only close this down if we used the temporary.
+ if (file_mapping == &local_handle)
+ ::CloseHandle (*file_mapping);
+
+ if (addr_mapping == 0)
+ ACE_FAIL_RETURN (MAP_FAILED);
+
+ else if (ACE_BIT_ENABLED (flags, MAP_FIXED)
+ && addr_mapping != addr)
+ {
+ errno = EINVAL;
+ return MAP_FAILED;
+ }
+ else
+ return addr_mapping;
+#elif defined (__Lynx__)
+ // The LynxOS 2.5.0 mmap doesn't allow operations on plain
+ // file descriptors. So, create a shm object and use that.
+ ACE_UNUSED_ARG (sa);
+
+ char name [128];
+ sprintf (name, "%d", file_handle);
+
+ // Assumes that this was called by ACE_Mem_Map, so &file_mapping != 0.
+ // Otherwise, we don't support the incomplete LynxOS mmap implementation.
+ // We do support it by creating a hidden shared memory object, and using
+ // that for the mapping.
+ int shm_handle;
+ if (! file_mapping)
+ file_mapping = &shm_handle;
+ if ((*file_mapping = ::shm_open (name,
+ O_RDWR | O_CREAT | O_TRUNC,
+ ACE_DEFAULT_FILE_PERMS)) == -1)
+ return MAP_FAILED;
+ else
+ {
+ // The size of the shared memory object must be explicitly set on LynxOS.
+ const off_t filesize = ACE_OS::filesize (file_handle);
+ if (::ftruncate (*file_mapping, filesize) == -1)
+ return MAP_FAILED;
+ else
+ {
+# if defined (ACE_OS_EXTRA_MMAP_FLAGS)
+ flags |= ACE_OS_EXTRA_MMAP_FLAGS;
+# endif /* ACE_OS_EXTRA_MMAP_FLAGS */
+ char *map = (char *) ::mmap ((ACE_MMAP_TYPE) addr,
+ len,
+ prot,
+ flags,
+ *file_mapping,
+ off);
+ if (map == MAP_FAILED)
+ return MAP_FAILED;
+ else
+ // Finally, copy the file contents to the shared memory object.
+ return ::read (file_handle, map, (int) filesize) == filesize
+ ? map
+ : MAP_FAILED;
+ }
+ }
+#elif !defined (ACE_LACKS_MMAP)
+ ACE_UNUSED_ARG (sa);
+
+# if defined (ACE_OS_EXTRA_MMAP_FLAGS)
+ flags |= ACE_OS_EXTRA_MMAP_FLAGS;
+# endif /* ACE_OS_EXTRA_MMAP_FLAGS */
+ ACE_UNUSED_ARG (file_mapping);
+ ACE_OSCALL_RETURN ((void *) ::mmap ((ACE_MMAP_TYPE) addr,
+ len,
+ prot,
+ flags,
+ file_handle,
+ off),
+ void *, MAP_FAILED);
+#else
+ ACE_UNUSED_ARG (addr);
+ ACE_UNUSED_ARG (len);
+ ACE_UNUSED_ARG (prot);
+ ACE_UNUSED_ARG (flags);
+ ACE_UNUSED_ARG (file_handle);
+ ACE_UNUSED_ARG (off);
+ ACE_UNUSED_ARG (file_mapping);
+ ACE_UNUSED_ARG (sa);
+ ACE_NOTSUP_RETURN (MAP_FAILED);
+#endif /*ACE_HAS_PACE */
+}
+
+// NOTE: The previous four function definitions must appear before
+// ACE_OS::sema_init ().
+
+ACE_INLINE int
+ACE_OS::sema_init (ACE_sema_t *s,
+ u_int count,
+ int type,
+ const char *name,
+ void *arg,
+ int max,
+ LPSECURITY_ATTRIBUTES sa)
+{
+ ACE_OS_TRACE ("ACE_OS::sema_init");
+#if defined (ACE_HAS_PACE) && !defined (ACE_WIN32)
+ ACE_UNUSED_ARG (arg);
+ ACE_UNUSED_ARG (max);
+ ACE_UNUSED_ARG (sa);
+ s->name_ = 0;
+ if (name)
+ {
+ ACE_ALLOCATOR_RETURN (s->name_,
+ ACE_OS::strdup (name),
+ -1);
+ s->sema_ = ::pace_sem_open (s->name_,
+ O_CREAT,
+ ACE_DEFAULT_FILE_PERMS,
+ count);
+ if (s->sema_ == (pace_sem_t *) SEM_FAILED)
+ return -1;
+ else
+ return 0;
+ }
+ else
+ {
+ ACE_NEW_RETURN (s->sema_, pace_sem_t, -1);
+ ACE_OSCALL_RETURN (::pace_sem_init (s->sema_,
+ type != USYNC_THREAD,
+ count), int, -1);
+ }
+# elif defined (ACE_HAS_POSIX_SEM)
+ ACE_UNUSED_ARG (arg);
+ ACE_UNUSED_ARG (max);
+ ACE_UNUSED_ARG (sa);
+
+ s->name_ = 0;
+
+# if defined (ACE_LACKS_NAMED_POSIX_SEM)
+ s->new_sema_ = 0;
+ if (type == USYNC_PROCESS)
+ {
+ // Let's see if it already exists.
+ ACE_HANDLE fd = ACE_OS::shm_open (name,
+ O_RDWR | O_CREAT | O_EXCL,
+ ACE_DEFAULT_FILE_PERMS);
+ if (fd == ACE_INVALID_HANDLE)
+ {
+ if (errno == EEXIST)
+ fd = ACE_OS::shm_open (name,
+ O_RDWR | O_CREAT,
+ ACE_DEFAULT_FILE_PERMS);
+ else
+ return -1;
+ }
+ else
+ {
+ // We own this shared memory object! Let's set its
+ // size.
+ if (ACE_OS::ftruncate (fd,
+ sizeof (ACE_sema_t)) == -1)
+ return -1;
+ s->name_ = ACE_OS::strdup (name);
+ if (s->name_ == 0)
+ return -1;
+ }
+ if (fd == -1)
+ return -1;
+
+ s->sema_ = (sem_t *)
+ ACE_OS::mmap (0,
+ sizeof (ACE_sema_t),
+ PROT_RDWR,
+ MAP_SHARED,
+ fd,
+ 0);
+ ACE_OS::close (fd);
+ if (s->sema_ == (sem_t *) MAP_FAILED)
+ return -1;
+ if (s->name_
+ // @@ According UNIX Network Programming V2 by Stevens,
+ // sem_init() is currently not required to return zero on
+ // success, but it *does* return -1 upon failure. For
+ // this reason, check for failure by comparing to -1,
+ // instead of checking for success by comparing to zero.
+ // -Ossama
+ // Only initialize it if we're the one who created it.
+ && ::sem_init (s->sema_, type == USYNC_PROCESS, count) == -1)
+ return -1;
+ return 0;
+ }
+#else
+ if (name)
+ {
+#if defined (sun) || defined (HPUX)
+ // Solaris and HP-UX require the name to start with a slash. Solaris
+ // further requires that there be no other slashes than the first.
+ const char *last_slash = ACE_OS::strrchr (name, '/');
+ char name2[MAXPATHLEN];
+ if (0 == last_slash)
+ {
+ ACE_OS::strcpy (name2, "/");
+ ACE_OS::strcat (name2, name);
+ name = name2;
+ }
+# if defined (sun)
+ else
+ name = last_slash; // Chop off chars preceding last slash
+# endif /* sun */
+#endif /* sun || HPUX */
+
+ ACE_ALLOCATOR_RETURN (s->name_,
+ ACE_OS::strdup (name),
+ -1);
+ s->sema_ = ::sem_open (s->name_,
+ O_CREAT,
+ ACE_DEFAULT_FILE_PERMS,
+ count);
+ if (s->sema_ == (sem_t *) SEM_FAILED)
+ return -1;
+ else
+ return 0;
+ }
+# endif /* ACE_LACKS_NAMED_POSIX_SEM */
+ else
+ {
+ ACE_NEW_RETURN (s->sema_,
+ sem_t,
+ -1);
+# if defined (ACE_LACKS_NAMED_POSIX_SEM)
+ s->new_sema_ = 1;
+# endif /* ACE_LACKS_NAMED_POSIX_SEM */
+ ACE_OSCALL_RETURN (::sem_init (s->sema_,
+ type != USYNC_THREAD,
+ count), int, -1);
+ }
+# elif defined (ACE_HAS_THREADS)
+# if defined (ACE_HAS_STHREADS)
+ ACE_UNUSED_ARG (name);
+ ACE_UNUSED_ARG (max);
+ ACE_UNUSED_ARG (sa);
+ ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::sema_init (s, count, type, arg), ace_result_),
+ int, -1);
+# elif defined (ACE_HAS_PTHREADS)
+ ACE_UNUSED_ARG (max);
+ ACE_UNUSED_ARG (sa);
+ int result = -1;
+
+ if (ACE_OS::mutex_init (&s->lock_, type, name,
+ (ACE_mutexattr_t *) arg) == 0
+ && ACE_OS::cond_init (&s->count_nonzero_, type, name, arg) == 0
+ && ACE_OS::mutex_lock (&s->lock_) == 0)
+ {
+ s->count_ = count;
+ s->waiters_ = 0;
+
+ if (ACE_OS::mutex_unlock (&s->lock_) == 0)
+ result = 0;
+ }
+
+ if (result == -1)
+ {
+ ACE_OS::mutex_destroy (&s->lock_);
+ ACE_OS::cond_destroy (&s->count_nonzero_);
+ }
+ return result;
+# elif defined (ACE_HAS_WTHREADS)
+# if ! defined (ACE_USES_WINCE_SEMA_SIMULATION)
+ ACE_UNUSED_ARG (type);
+ ACE_UNUSED_ARG (arg);
+ // Create the semaphore with its value initialized to <count> and
+ // its maximum value initialized to <max>.
+ *s =
+ ::CreateSemaphoreA (ACE_OS::default_win32_security_attributes (sa),
+ count,
+ max,
+ name);
+
+ if (*s == 0)
+ ACE_FAIL_RETURN (-1);
+ /* NOTREACHED */
+ else
+ return 0;
+# else /* ACE_USES_WINCE_SEMA_SIMULATION */
+ int result = -1;
+
+ // Initialize internal object for semaphore simulation.
+ // Grab the lock as soon as possible when we initializing
+ // the semaphore count. Notice that we initialize the
+ // event object as "manually reset" so we can amortize the
+ // cost for singling/reseting the event.
+ // @@ I changed the mutex type to thread_mutex. Notice that this
+ // is basically a CriticalSection object and doesn't not has
+ // any security attribute whatsoever. However, since this
+ // semaphore implementation only works within a process, there
+ // shouldn't any security issue at all.
+ if (ACE_OS::thread_mutex_init (&s->lock_, type, name, (ACE_mutexattr_t *)arg) == 0
+ && ACE_OS::event_init (&s->count_nonzero_, 1,
+ count > 0, type, name, arg, sa) == 0
+ && ACE_OS::thread_mutex_lock (&s->lock_) == 0)
+ {
+ s->count_ = count;
+
+ if (ACE_OS::thread_mutex_unlock (&s->lock_) == 0)
+ result = 0;
+ }
+
+ // Destroy the internal objects if we didn't initialize
+ // either of them successfully. Don't bother to check
+ // for errors.
+ if (result == -1)
+ {
+ ACE_OS::thread_mutex_destroy (&s->lock_);
+ ACE_OS::event_destroy (&s->count_nonzero_);
+ }
+ return result;
+# endif /* ACE_USES_WINCE_SEMA_SIMULATION */
+# elif defined (ACE_PSOS)
+ u_long result;
+ ACE_OS::memcpy (s->name_, name, sizeof (s->name_));
+ // default semaphore creation flags to priority based, global across nodes
+ u_long flags = 0;
+ flags |= (type & SM_LOCAL) ? SM_LOCAL : SM_GLOBAL;
+ flags |= (type & SM_FIFO) ? SM_FIFO : SM_PRIOR;
+ result = ::sm_create (s->name_, count, flags, &(s->sema_));
+ return (result == 0) ? 0 : -1;
+# elif defined (VXWORKS)
+ ACE_UNUSED_ARG (name);
+ ACE_UNUSED_ARG (arg);
+ ACE_UNUSED_ARG (max);
+ ACE_UNUSED_ARG (sa);
+ s->name_ = 0;
+ s->sema_ = ::semCCreate (type, count);
+ return s->sema_ ? 0 : -1;
+# endif /* ACE_HAS_STHREADS */
+# else
+ ACE_UNUSED_ARG (s);
+ ACE_UNUSED_ARG (count);
+ ACE_UNUSED_ARG (type);
+ ACE_UNUSED_ARG (name);
+ ACE_UNUSED_ARG (arg);
+ ACE_UNUSED_ARG (max);
+ ACE_UNUSED_ARG (sa);
+ ACE_NOTSUP_RETURN (-1);
+# endif /* ACE_HAS_PACE */
+}
+
+#if defined (ACE_HAS_WCHAR)
+ACE_INLINE int
+ACE_OS::sema_init (ACE_sema_t *s,
+ u_int count,
+ int type,
+ const wchar_t *name,
+ void *arg,
+ int max,
+ LPSECURITY_ATTRIBUTES sa)
+{
+# if defined (ACE_HAS_WTHREADS)
+# if ! defined (ACE_USES_WINCE_SEMA_SIMULATION)
+ ACE_UNUSED_ARG (type);
+ ACE_UNUSED_ARG (arg);
+ // Create the semaphore with its value initialized to <count> and
+ // its maximum value initialized to <max>.
+ *s =
+ ::CreateSemaphoreW (ACE_OS::default_win32_security_attributes (sa),
+ count,
+ max,
+ name);
+
+ if (*s == 0)
+ ACE_FAIL_RETURN (-1);
+ /* NOTREACHED */
+ else
+ return 0;
+# else /* ACE_USES_WINCE_SEMA_SIMULATION */
+ int result = -1;
+
+ // Initialize internal object for semaphore simulation.
+ // Grab the lock as soon as possible when we initializing
+ // the semaphore count. Notice that we initialize the
+ // event object as "manually reset" so we can amortize the
+ // cost for singling/reseting the event.
+ // @@ I changed the mutex type to thread_mutex. Notice that this
+ // is basically a CriticalSection object and doesn't not has
+ // any security attribute whatsoever. However, since this
+ // semaphore implementation only works within a process, there
+ // shouldn't any security issue at all.
+ if (ACE_OS::thread_mutex_init (&s->lock_, type, name, (ACE_mutexattr_t *)arg) == 0
+ && ACE_OS::event_init (&s->count_nonzero_, 1,
+ count > 0, type, name, arg, sa) == 0
+ && ACE_OS::thread_mutex_lock (&s->lock_) == 0)
+ {
+ s->count_ = count;
+
+ if (ACE_OS::thread_mutex_unlock (&s->lock_) == 0)
+ result = 0;
+ }
+
+ // Destroy the internal objects if we didn't initialize
+ // either of them successfully. Don't bother to check
+ // for errors.
+ if (result == -1)
+ {
+ ACE_OS::thread_mutex_destroy (&s->lock_);
+ ACE_OS::event_destroy (&s->count_nonzero_);
+ }
+ return result;
+# endif /* ACE_USES_WINCE_SEMA_SIMULATION */
+# else /* ACE_HAS_WTHREADS */
+ // Just call the normal char version.
+ return ACE_OS::sema_init (s, count, type, ACE_Wide_To_Ascii (name).char_rep (), arg, max, sa);
+# endif /* ACE_HAS_PACE && ACE_HAS_WTHREADS */
+}
+#endif /* ACE_HAS_WCHAR */
+
+ACE_INLINE int
+ACE_OS::sema_post (ACE_sema_t *s)
+{
+ ACE_OS_TRACE ("ACE_OS::sema_post");
+#if defined (ACE_HAS_PACE) && !defined (ACE_WIN32)
+ ACE_OSCALL_RETURN (::pace_sem_post (s->sema_), int, -1);
+# elif defined (ACE_HAS_POSIX_SEM)
+ ACE_OSCALL_RETURN (::sem_post (s->sema_), int, -1);
+# elif defined (ACE_HAS_THREADS)
+# if defined (ACE_HAS_STHREADS)
+ ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::sema_post (s), ace_result_), int, -1);
+# elif defined (ACE_HAS_PTHREADS)
+ int result = -1;
+
+ if (ACE_OS::mutex_lock (&s->lock_) == 0)
+ {
+ // Always allow a waiter to continue if there is one.
+ if (s->waiters_ > 0)
+ result = ACE_OS::cond_signal (&s->count_nonzero_);
+ else
+ result = 0;
+
+ s->count_++;
+ ACE_OS::mutex_unlock (&s->lock_);
+ }
+ return result;
+# elif defined (ACE_HAS_WTHREADS)
+# if !defined (ACE_USES_WINCE_SEMA_SIMULATION)
+ ACE_WIN32CALL_RETURN (ACE_ADAPT_RETVAL (::ReleaseSemaphore (*s, 1, 0),
+ ace_result_),
+ int, -1);
+# else /* ACE_USES_WINCE_SEMA_SIMULATION */
+ int result = -1;
+
+ // Since we are simulating semaphores, we need to update semaphore
+ // count manually. Grab the lock to prevent race condition first.
+ if (ACE_OS::thread_mutex_lock (&s->lock_) == 0)
+ {
+ // Check the original state of event object. Single the event
+ // object in transition from semaphore not available to
+ // semaphore available.
+ if (s->count_++ <= 0)
+ result = ACE_OS::event_signal (&s->count_nonzero_);
+ else
+ result = 0;
+
+ ACE_OS::thread_mutex_unlock (&s->lock_);
+ }
+ return result;
+# endif /* ACE_USES_WINCE_SEMA_SIMULATION */
+# elif defined (ACE_PSOS)
+ int result;
+ ACE_OSCALL (ACE_ADAPT_RETVAL (::sm_v (s->sema_), result), int, -1, result);
+ return result;
+# elif defined (VXWORKS)
+ ACE_OSCALL_RETURN (::semGive (s->sema_), int, -1);
+# endif /* ACE_HAS_STHREADS */
+# else
+ ACE_UNUSED_ARG (s);
+ ACE_NOTSUP_RETURN (-1);
+# endif /* ACE_HAS_PACE */
+}
+
+ACE_INLINE int
+ACE_OS::sema_post (ACE_sema_t *s, size_t release_count)
+{
+#if defined (ACE_WIN32) && !defined (ACE_USES_WINCE_SEMA_SIMULATION)
+ // Win32 supports this natively.
+# if defined (ACE_HAS_PACE) && !defined (ACE_WIN32)
+ ACE_WIN32CALL_RETURN (ACE_ADAPT_RETVAL (::ReleaseSemaphore (*(s->sema_),
+ release_count, 0), ace_result_),
+ int, -1);
+# else
+ ACE_WIN32CALL_RETURN (ACE_ADAPT_RETVAL (::ReleaseSemaphore (*s, release_count, 0),
+ ace_result_), int, -1);
+# endif /* ACE_HAS_PACE */
+#else
+ // On POSIX platforms we need to emulate this ourselves.
+ // @@ We can optimize on this implementation. However,
+ // the semaphore promitive on Win32 doesn't allow one
+ // to increase a semaphore to more than the count it was
+ // first initialized. Posix and solaris don't seem to have
+ // this restriction. Should we impose the restriction in
+ // our semaphore simulation?
+ for (size_t i = 0; i < release_count; i++)
+ if (ACE_OS::sema_post (s) == -1)
+ return -1;
+
+ return 0;
+#endif /* ACE_WIN32 */
+}
+
+ACE_INLINE int
+ACE_OS::sema_trywait (ACE_sema_t *s)
+{
+ ACE_OS_TRACE ("ACE_OS::sema_trywait");
+#if defined (ACE_HAS_PACE) && !defined (ACE_WIN32)
+ ACE_OSCALL_RETURN (::pace_sem_trywait (s->sema_), int, -1);
+# elif defined (ACE_HAS_POSIX_SEM)
+ // POSIX semaphores set errno to EAGAIN if trywait fails
+ ACE_OSCALL_RETURN (::sem_trywait (s->sema_), int, -1);
+# elif defined (ACE_HAS_THREADS)
+# if defined (ACE_HAS_STHREADS)
+ // STHREADS semaphores set errno to EBUSY if trywait fails.
+ ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::sema_trywait (s),
+ ace_result_),
+ int, -1);
+# elif defined (ACE_HAS_PTHREADS)
+
+ int result = -1;
+
+ if (ACE_OS::mutex_lock (&s->lock_) == 0)
+ {
+ if (s->count_ > 0)
+ {
+ --s->count_;
+ result = 0;
+ }
+ else
+ errno = EBUSY;
+
+ ACE_OS::mutex_unlock (&s->lock_);
+ }
+ return result;
+# elif defined (ACE_HAS_WTHREADS)
+# if !defined (ACE_USES_WINCE_SEMA_SIMULATION)
+ int result = ::WaitForSingleObject (*s, 0);
+
+ if (result == WAIT_OBJECT_0)
+ return 0;
+ else
+ {
+ if (result == WAIT_TIMEOUT)
+ errno = EBUSY;
+ else
+ ACE_OS::set_errno_to_last_error ();
+ // This is a hack, we need to find an appropriate mapping...
+ return -1;
+ }
+# else /* ACE_USES_WINCE_SEMA_SIMULATION */
+ // Check the status of semaphore first. Return immediately
+ // if the semaphore is not available and avoid grabing the
+ // lock.
+ int result = ::WaitForSingleObject (s->count_nonzero_, 0);
+
+ if (result == WAIT_OBJECT_0) // Proceed when it is available.
+ {
+ ACE_OS::thread_mutex_lock (&s->lock_);
+
+ // Need to double check if the semaphore is still available.
+ // The double checking scheme will slightly affect the
+ // efficiency if most of the time semaphores are not blocked.
+ result = ::WaitForSingleObject (s->count_nonzero_, 0);
+ if (result == WAIT_OBJECT_0)
+ {
+ // Adjust the semaphore count. Only update the event
+ // object status when the state changed.
+ s->count_--;
+ if (s->count_ <= 0)
+ ACE_OS::event_reset (&s->count_nonzero_);
+ result = 0;
+ }
+
+ ACE_OS::thread_mutex_unlock (&s->lock_);
+ }
+
+ // Translate error message to errno used by ACE.
+ if (result == WAIT_TIMEOUT)
+ errno = EBUSY;
+ else
+ ACE_OS::set_errno_to_last_error ();
+ // This is taken from the hack above. ;)
+ return -1;
+# endif /* ACE_USES_WINCE_SEMA_SIMULATION */
+# elif defined (ACE_PSOS)
+ switch (::sm_p (s->sema_, SM_NOWAIT, 0))
+ {
+ case 0:
+ return 0;
+ case ERR_NOSEM:
+ errno = EBUSY;
+ // intentional fall through
+ default:
+ return -1;
+ }
+# elif defined (VXWORKS)
+ if (::semTake (s->sema_, NO_WAIT) == ERROR)
+ if (errno == S_objLib_OBJ_UNAVAILABLE)
+ {
+ // couldn't get the semaphore
+ errno = EBUSY;
+ return -1;
+ }
+ else
+ // error
+ return -1;
+ else
+ // got the semaphore
+ return 0;
+# endif /* ACE_HAS_STHREADS */
+# else
+ ACE_UNUSED_ARG (s);
+ ACE_NOTSUP_RETURN (-1);
+# endif /* ACE_HAS_PACE */
+}
+
+ACE_INLINE int
+ACE_OS::sema_wait (ACE_sema_t *s)
+{
+ ACE_OS_TRACE ("ACE_OS::sema_wait");
+#if defined (ACE_HAS_PACE) && !defined (ACE_WIN32)
+ ACE_OSCALL_RETURN (::pace_sem_wait (s->sema_), int, -1);
+# elif defined (ACE_HAS_POSIX_SEM)
+ ACE_OSCALL_RETURN (::sem_wait (s->sema_), int, -1);
+# elif defined (ACE_HAS_THREADS)
+# if defined (ACE_HAS_STHREADS)
+ ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::sema_wait (s), ace_result_), int, -1);
+# elif defined (ACE_HAS_PTHREADS)
+ int result = 0;
+
+ ACE_PTHREAD_CLEANUP_PUSH (&s->lock_);
+
+ if (ACE_OS::mutex_lock (&s->lock_) != 0)
+ result = -1;
+ else
+ {
+ // Keep track of the number of waiters so that we can signal
+ // them properly in <ACE_OS::sema_post>.
+ s->waiters_++;
+
+ // Wait until the semaphore count is > 0.
+ while (s->count_ == 0)
+ if (ACE_OS::cond_wait (&s->count_nonzero_,
+ &s->lock_) == -1)
+ {
+ result = -2; // -2 means that we need to release the mutex.
+ break;
+ }
+
+ --s->waiters_;
+ }
+
+ if (result == 0)
+ --s->count_;
+
+ if (result != -1)
+ ACE_OS::mutex_unlock (&s->lock_);
+ ACE_PTHREAD_CLEANUP_POP (0);
+ return result < 0 ? -1 : result;
+
+# elif defined (ACE_HAS_WTHREADS)
+# if !defined (ACE_USES_WINCE_SEMA_SIMULATION)
+ switch (::WaitForSingleObject (*s, INFINITE))
+ {
+ case WAIT_OBJECT_0:
+ return 0;
+ default:
+ // This is a hack, we need to find an appropriate mapping...
+ ACE_OS::set_errno_to_last_error ();
+ return -1;
+ }
+ /* NOTREACHED */
+# else /* ACE_USES_WINCE_SEMA_SIMULATION */
+ // Timed wait.
+ int result = -1;
+ for (;;)
+ // Check if the semaphore is avialable or not and wait forever.
+ // Don't bother to grab the lock if it is not available (to avoid
+ // deadlock.)
+ switch (::WaitForSingleObject (s->count_nonzero_, INFINITE))
+ {
+ case WAIT_OBJECT_0:
+ ACE_OS::thread_mutex_lock (&s->lock_);
+
+ // Need to double check if the semaphore is still available.
+ // This time, we shouldn't wait at all.
+ if (::WaitForSingleObject (s->count_nonzero_, 0) == WAIT_OBJECT_0)
+ {
+ // Decrease the internal counter. Only update the event
+ // object's status when the state changed.
+ s->count_--;
+ if (s->count_ <= 0)
+ ACE_OS::event_reset (&s->count_nonzero_);
+ result = 0;
+ }
+
+ ACE_OS::thread_mutex_unlock (&s->lock_);
+ // if we didn't get a hold on the semaphore, the result won't
+ // be 0 and thus, we'll start from the beginning again.
+ if (result == 0)
+ return 0;
+ break;
+
+ default:
+ // Since we wait indefinitely, anything other than
+ // WAIT_OBJECT_O indicates an error.
+ ACE_OS::set_errno_to_last_error ();
+ // This is taken from the hack above. ;)
+ return -1;
+ }
+ /* NOTREACHED */
+# endif /* ACE_USES_WINCE_SEMA_SIMULATION */
+# elif defined (ACE_PSOS)
+ int result;
+ ACE_OSCALL (ACE_ADAPT_RETVAL (::sm_p (s->sema_, SM_WAIT, 0), result),
+ int, -1, result);
+ return result;
+# elif defined (VXWORKS)
+ ACE_OSCALL_RETURN (::semTake (s->sema_, WAIT_FOREVER), int, -1);
+# endif /* ACE_HAS_STHREADS */
+# else
+ ACE_UNUSED_ARG (s);
+ ACE_NOTSUP_RETURN (-1);
+# endif /* ACE_HAS_PACE */
+}
+
+ACE_INLINE int
+ACE_OS::sema_wait (ACE_sema_t *s, ACE_Time_Value &tv)
+{
+ ACE_OS_TRACE ("ACE_OS::sema_wait");
+# if defined (ACE_HAS_POSIX_SEM)
+ ACE_UNUSED_ARG (s);
+ ACE_UNUSED_ARG (tv);
+ ACE_NOTSUP_RETURN (-1);
+# elif defined (ACE_HAS_THREADS)
+# if defined (ACE_HAS_STHREADS)
+ ACE_UNUSED_ARG (s);
+ ACE_UNUSED_ARG (tv);
+ ACE_NOTSUP_RETURN (-1);
+# elif defined (ACE_HAS_PTHREADS)
+ int result = 0;
+ ACE_Errno_Guard error (errno);
+
+ ACE_PTHREAD_CLEANUP_PUSH (&s->lock_);
+
+ if (ACE_OS::mutex_lock (&s->lock_) != 0)
+ result = -1;
+ else
+ {
+ // Keep track of the number of waiters so that we can signal
+ // them properly in <ACE_OS::sema_post>.
+ s->waiters_++;
+
+ // Wait until the semaphore count is > 0 or until we time out.
+ while (s->count_ == 0)
+ if (ACE_OS::cond_timedwait (&s->count_nonzero_,
+ &s->lock_,
+ &tv) == -1)
+ {
+ error = errno;
+ result = -2; // -2 means that we need to release the mutex.
+ break;
+ }
+
+ --s->waiters_;
+ }
+
+ if (result == 0)
+ {
+# if defined (ACE_LACKS_COND_TIMEDWAIT_RESET)
+ tv = ACE_OS::gettimeofday ();
+# endif /* ACE_LACKS_COND_TIMEDWAIT_RESET */
+ --s->count_;
+ }
+
+ if (result != -1)
+ ACE_OS::mutex_unlock (&s->lock_);
+ ACE_PTHREAD_CLEANUP_POP (0);
+ return result < 0 ? -1 : result;
+# elif defined (ACE_HAS_WTHREADS)
+# if !defined (ACE_USES_WINCE_SEMA_SIMULATION)
+ int msec_timeout;
+
+ if (tv.sec () == 0 && tv.usec () == 0)
+ msec_timeout = 0; // Do a "poll."
+ else
+ {
+ // 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 (tv - ACE_OS::gettimeofday ());
+
+ // Watchout for situations where a context switch has caused the
+ // current time to be > the timeout.
+ if (relative_time < ACE_Time_Value::zero)
+ msec_timeout = 0;
+ else
+ msec_timeout = relative_time.msec ();
+ }
+
+ switch (::WaitForSingleObject (*s, msec_timeout))
+ {
+ case WAIT_OBJECT_0:
+ tv = ACE_OS::gettimeofday (); // Update time to when acquired
+ return 0;
+ case WAIT_TIMEOUT:
+ errno = ETIME;
+ return -1;
+ default:
+ // This is a hack, we need to find an appropriate mapping...
+ ACE_OS::set_errno_to_last_error ();
+ return -1;
+ }
+ /* NOTREACHED */
+# else /* ACE_USES_WINCE_SEMA_SIMULATION */
+ // Note that in this mode, the acquire is done in two steps, and
+ // we may get signaled but cannot grab the semaphore before
+ // timeout. In that case, we'll need to restart the process with
+ // updated timeout value.
+
+ // <tv> is an absolute time
+ ACE_Time_Value relative_time = tv - ACE_OS::gettimeofday ();
+ int result = -1;
+
+ // While we are not timeout yet.
+ while (relative_time > ACE_Time_Value::zero)
+ {
+ // Wait for our turn to get the object.
+ switch (::WaitForSingleObject (s->count_nonzero_, relative_time.msec ()))
+ {
+ case WAIT_OBJECT_0:
+ ACE_OS::thread_mutex_lock (&s->lock_);
+
+ // Need to double check if the semaphore is still available.
+ // We can only do a "try lock" styled wait here to avoid
+ // blocking threads that want to signal the semaphore.
+ if (::WaitForSingleObject (s->count_nonzero_, 0) == WAIT_OBJECT_0)
+ {
+ // As before, only reset the object when the semaphore
+ // is no longer available.
+ s->count_--;
+ if (s->count_ <= 0)
+ ACE_OS::event_reset (&s->count_nonzero_);
+ result = 0;
+ }
+
+ ACE_OS::thread_mutex_unlock (&s->lock_);
+
+ // Only return when we successfully get the semaphore.
+ if (result == 0)
+ {
+ tv = ACE_OS::gettimeofday (); // Update to time acquired
+ return 0;
+ }
+ break;
+
+ // We have timed out.
+ case WAIT_TIMEOUT:
+ errno = ETIME;
+ return -1;
+
+ // What?
+ default:
+ ACE_OS::set_errno_to_last_error ();
+ // This is taken from the hack above. ;)
+ return -1;
+ };
+
+ // Haven't been able to get the semaphore yet, update the
+ // timeout value to reflect the remaining time we want to wait.
+ relative_time = tv - ACE_OS::gettimeofday ();
+ }
+
+ // We have timed out.
+ errno = ETIME;
+ return -1;
+# endif /* ACE_USES_WINCE_SEMA_SIMULATION */
+# elif defined (ACE_PSOS)
+ // Note that we must convert between absolute time (which is
+ // passed as a parameter) and relative time (which is what
+ // the system call expects).
+ ACE_Time_Value relative_time (tv - ACE_OS::gettimeofday ());
+
+ u_long ticks = relative_time.sec() * KC_TICKS2SEC +
+ relative_time.usec () * KC_TICKS2SEC /
+ ACE_ONE_SECOND_IN_USECS;
+ if(ticks == 0)
+ ACE_OSCALL_RETURN (::sm_p (s->sema_, SM_NOWAIT, 0), int, -1); //no timeout
+ else
+ ACE_OSCALL_RETURN (::sm_p (s->sema_, SM_WAIT, ticks), int, -1);
+# elif defined (VXWORKS)
+ // Note that we must convert between absolute time (which is
+ // passed as a parameter) and relative time (which is what
+ // the system call expects).
+ ACE_Time_Value relative_time (tv - ACE_OS::gettimeofday ());
+
+ int ticks_per_sec = ::sysClkRateGet ();
+
+ int ticks = relative_time.sec() * ticks_per_sec +
+ relative_time.usec () * ticks_per_sec / ACE_ONE_SECOND_IN_USECS;
+ if (::semTake (s->sema_, ticks) == ERROR)
+ {
+ if (errno == S_objLib_OBJ_TIMEOUT)
+ // Convert the VxWorks errno to one that's common for to ACE
+ // platforms.
+ errno = ETIME;
+ else if (errno == S_objLib_OBJ_UNAVAILABLE)
+ errno = EBUSY;
+ return -1;
+ }
+ else
+ {
+ tv = ACE_OS::gettimeofday (); // Update to time acquired
+ return 0;
+ }
+# endif /* ACE_HAS_STHREADS */
+# else
+ ACE_UNUSED_ARG (s);
+ ACE_UNUSED_ARG (tv);
+ ACE_NOTSUP_RETURN (-1);
+# endif /* ACE_HAS_POSIX_SEM */
+}
+
+ACE_INLINE int
+ACE_OS::sema_wait (ACE_sema_t *s, ACE_Time_Value *tv)
+{
+ return tv == 0 ? ACE_OS::sema_wait (s) : ACE_OS::sema_wait (s, *tv);
+}
+
+ACE_INLINE int
+ACE_OS::rw_tryrdlock (ACE_rwlock_t *rw)
+{
+ ACE_OS_TRACE ("ACE_OS::rw_tryrdlock");
+#if defined (ACE_HAS_THREADS)
+# if !defined (ACE_LACKS_RWLOCK_T) || defined (ACE_HAS_PTHREADS_UNIX98_EXT)
+# if defined (ACE_HAS_PTHREADS_UNIX98_EXT)
+ ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (pthread_rwlock_tryrdlock (rw),
+ ace_result_),
+ int, -1);
+# else /* Solaris */
+ ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::rw_tryrdlock (rw), ace_result_), int, -1);
+# endif /* ACE_HAS_PTHREADS_UNIX98_EXT */
+# else /* NT, POSIX, and VxWorks don't support this natively. */
+ int result = -1;
+
+ if (ACE_OS::mutex_lock (&rw->lock_) != -1)
+ {
+ ACE_Errno_Guard error (errno);
+
+ if (rw->ref_count_ == -1 || rw->num_waiting_writers_ > 0)
+ {
+ error = EBUSY;
+ result = -1;
+ }
+ else
+ {
+ rw->ref_count_++;
+ result = 0;
+ }
+
+ ACE_OS::mutex_unlock (&rw->lock_);
+ }
+ return result;
+# endif /* ! ACE_LACKS_RWLOCK_T */
+#else
+ ACE_UNUSED_ARG (rw);
+ ACE_NOTSUP_RETURN (-1);
+#endif /* ACE_HAS_THREADS */
+}
+
+ACE_INLINE int
+ACE_OS::rw_trywrlock (ACE_rwlock_t *rw)
+{
+ ACE_OS_TRACE ("ACE_OS::rw_trywrlock");
+#if defined (ACE_HAS_THREADS)
+# if !defined (ACE_LACKS_RWLOCK_T) || defined (ACE_HAS_PTHREADS_UNIX98_EXT)
+# if defined (ACE_HAS_PTHREADS_UNIX98_EXT)
+ ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (pthread_rwlock_trywrlock (rw),
+ ace_result_),
+ int, -1);
+# else /* Solaris */
+ ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::rw_trywrlock (rw), ace_result_), int, -1);
+# endif /* ACE_HAS_PTHREADS_UNIX98_EXT */
+# else /* NT, POSIX, and VxWorks don't support this natively. */
+ int result = -1;
+
+ if (ACE_OS::mutex_lock (&rw->lock_) != -1)
+ {
+ ACE_Errno_Guard error (errno);
+
+ if (rw->ref_count_ != 0)
+ {
+ error = EBUSY;
+ result = -1;
+ }
+ else
+ {
+ rw->ref_count_ = -1;
+ result = 0;
+ }
+
+ ACE_OS::mutex_unlock (&rw->lock_);
+ }
+ return result;
+# endif /* ! ACE_LACKS_RWLOCK_T */
+#else
+ ACE_UNUSED_ARG (rw);
+ ACE_NOTSUP_RETURN (-1);
+#endif /* ACE_HAS_THREADS */
+}
+
+ACE_INLINE int
+ACE_OS::rw_rdlock (ACE_rwlock_t *rw)
+{
+ ACE_OS_TRACE ("ACE_OS::rw_rdlock");
+#if defined (ACE_HAS_THREADS)
+# if !defined (ACE_LACKS_RWLOCK_T) || defined (ACE_HAS_PTHREADS_UNIX98_EXT)
+# if defined (ACE_HAS_PTHREADS_UNIX98_EXT)
+ ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (pthread_rwlock_rdlock (rw),
+ ace_result_),
+ int, -1);
+# else /* Solaris */
+ ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::rw_rdlock (rw), ace_result_), int, -1);
+# endif /* ACE_HAS_PTHREADS_UNIX98_EXT */
+# else /* NT, POSIX, and VxWorks don't support this natively. */
+# if defined (ACE_HAS_PTHREADS)
+ ACE_PTHREAD_CLEANUP_PUSH (&rw->lock_);
+# endif /* ACE_HAS_PTHREADS */
+ int result = 0;
+ if (ACE_OS::mutex_lock (&rw->lock_) == -1)
+ result = -1; // -1 means didn't get the mutex.
+ else
+ {
+ // Give preference to writers who are waiting.
+ while (rw->ref_count_ < 0 || rw->num_waiting_writers_ > 0)
+ {
+ rw->num_waiting_readers_++;
+ if (ACE_OS::cond_wait (&rw->waiting_readers_, &rw->lock_) == -1)
+ {
+ result = -2; // -2 means that we need to release the mutex.
+ break;
+ }
+ rw->num_waiting_readers_--;
+ }
+ }
+ if (result == 0)
+ rw->ref_count_++;
+ if (result != -1)
+ ACE_OS::mutex_unlock (&rw->lock_);
+# if defined (ACE_HAS_PTHREADS)
+ ACE_PTHREAD_CLEANUP_POP (0);
+# endif /* defined (ACE_HAS_PTHREADS) */
+ return 0;
+# endif /* ! ACE_LACKS_RWLOCK_T */
+#else
+ ACE_UNUSED_ARG (rw);
+ ACE_NOTSUP_RETURN (-1);
+#endif /* ACE_HAS_THREADS */
+}
+
+ACE_INLINE int
+ACE_OS::rw_wrlock (ACE_rwlock_t *rw)
+{
+ ACE_OS_TRACE ("ACE_OS::rw_wrlock");
+#if defined (ACE_HAS_THREADS)
+# if !defined (ACE_LACKS_RWLOCK_T) || defined (ACE_HAS_PTHREADS_UNIX98_EXT)
+# if defined (ACE_HAS_PTHREADS_UNIX98_EXT)
+ ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (pthread_rwlock_wrlock (rw),
+ ace_result_),
+ int, -1);
+# else /* Solaris */
+ ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::rw_wrlock (rw), ace_result_), int, -1);
+# endif /* ACE_HAS_PTHREADS_UNIX98_EXT */
+# else /* NT, POSIX, and VxWorks don't support this natively. */
+# if defined (ACE_HAS_PTHREADS)
+ ACE_PTHREAD_CLEANUP_PUSH (&rw->lock_);
+# endif /* defined (ACE_HAS_PTHREADS) */
+ int result = 0;
+
+ if (ACE_OS::mutex_lock (&rw->lock_) == -1)
+ result = -1; // -1 means didn't get the mutex.
+ else
+ {
+ while (rw->ref_count_ != 0)
+ {
+ rw->num_waiting_writers_++;
+
+ if (ACE_OS::cond_wait (&rw->waiting_writers_, &rw->lock_) == -1)
+ {
+ result = -2; // -2 means we need to release the mutex.
+ break;
+ }
+
+ rw->num_waiting_writers_--;
+ }
+ }
+ if (result == 0)
+ rw->ref_count_ = -1;
+ if (result != -1)
+ ACE_OS::mutex_unlock (&rw->lock_);
+# if defined (ACE_HAS_PTHREADS)
+ ACE_PTHREAD_CLEANUP_POP (0);
+# endif /* defined (ACE_HAS_PTHREADS) */
+ return 0;
+# endif /* ! ACE_LACKS_RWLOCK_T */
+#else
+ ACE_UNUSED_ARG (rw);
+ ACE_NOTSUP_RETURN (-1);
+#endif /* ACE_HAS_THREADS */
+}
+
+ACE_INLINE int
+ACE_OS::rw_unlock (ACE_rwlock_t *rw)
+{
+ ACE_OS_TRACE ("ACE_OS::rw_unlock");
+#if defined (ACE_HAS_THREADS)
+# if !defined (ACE_LACKS_RWLOCK_T) || defined (ACE_HAS_PTHREADS_UNIX98_EXT)
+# if defined (ACE_HAS_PTHREADS_UNIX98_EXT)
+ ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (pthread_rwlock_unlock (rw),
+ ace_result_),
+ int, -1);
+# else /* Solaris */
+ ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::rw_unlock (rw), ace_result_), int, -1);
+# endif /* ACE_HAS_PTHREADS_UNIX98_EXT */
+# else /* NT, POSIX, and VxWorks don't support this natively. */
+ if (ACE_OS::mutex_lock (&rw->lock_) == -1)
+ return -1;
+
+ if (rw->ref_count_ > 0) // Releasing a reader.
+ rw->ref_count_--;
+ else if (rw->ref_count_ == -1) // Releasing a writer.
+ rw->ref_count_ = 0;
+ else
+ return -1; // @@ ACE_ASSERT (!"count should not be 0!\n");
+
+
+ int result = 0;
+ ACE_Errno_Guard error (errno);
+
+ if (rw->important_writer_ && rw->ref_count_ == 1)
+ // only the reader requesting to upgrade its lock is left over.
+ {
+ result = ACE_OS::cond_signal (&rw->waiting_important_writer_);
+ error = errno;
+ }
+ else if (rw->num_waiting_writers_ > 0 && rw->ref_count_ == 0)
+ // give preference to writers over readers...
+ {
+ result = ACE_OS::cond_signal (&rw->waiting_writers_);
+ error = errno;
+ }
+ else if (rw->num_waiting_readers_ > 0 && rw->num_waiting_writers_ == 0)
+ {
+ result = ACE_OS::cond_broadcast (&rw->waiting_readers_);
+ error = errno;
+ }
+
+ ACE_OS::mutex_unlock (&rw->lock_);
+ return result;
+# endif /* ! ace_lacks_rwlock_t */
+#else
+ ACE_UNUSED_ARG (rw);
+ ACE_NOTSUP_RETURN (-1);
+#endif /* ace_has_threads */
+}
+
+// Note that the caller of this method *must* already possess this
+// lock as a read lock.
+// return {-1 and no errno set means: error,
+// -1 and errno==EBUSY set means: could not upgrade,
+// 0 means: upgraded successfully}
+
+ACE_INLINE int
+ACE_OS::rw_trywrlock_upgrade (ACE_rwlock_t *rw)
+{
+ ACE_OS_TRACE ("ACE_OS::rw_trywrlock_upgrade");
+#if defined (ACE_HAS_THREADS)
+# if !defined (ACE_LACKS_RWLOCK_T)
+ // Some native rwlocks, such as those on Solaris and HP-UX 11, don't
+ // support the upgrade feature . . .
+ ACE_UNUSED_ARG (rw);
+ ACE_NOTSUP_RETURN (-1);
+# else /* NT, POSIX, and VxWorks don't support this natively. */
+ // The ACE rwlock emulation does support upgrade . . .
+ int result = 0;
+
+# if defined (ACE_HAS_PTHREADS)
+ ACE_PTHREAD_CLEANUP_PUSH (&rw->lock_);
+# endif /* defined (ACE_HAS_PTHREADS) */
+
+ if (ACE_OS::mutex_lock (&rw->lock_) == -1)
+ return -1;
+ // -1 means didn't get the mutex, error
+ else if (rw->important_writer_)
+ // an other reader upgrades already
+ {
+ result = -1;
+ errno = EBUSY;
+ }
+ else
+ {
+ while (rw->ref_count_ > 1) // wait until only I am left
+ {
+ rw->num_waiting_writers_++; // prohibit any more readers
+ rw->important_writer_ = 1;
+
+ if (ACE_OS::cond_wait (&rw->waiting_important_writer_, &rw->lock_) == -1)
+ {
+ result = -1;
+ // we know that we have the lock again, we have this guarantee,
+ // but something went wrong
+ }
+ rw->important_writer_ = 0;
+ rw->num_waiting_writers_--;
+ }
+ if (result == 0)
+ {
+ // nothing bad happend
+ rw->ref_count_ = -1;
+ // now I am a writer
+ // everything is O.K.
+ }
+ }
+
+ ACE_OS::mutex_unlock (&rw->lock_);
+
+# if defined (ACE_HAS_PTHREADS)
+ ACE_PTHREAD_CLEANUP_POP (0);
+# endif /* defined (ACE_HAS_PTHREADS) */
+
+ return result;
+
+# endif /* ! ACE_LACKS_RWLOCK_T */
+#else
+ ACE_UNUSED_ARG (rw);
+ ACE_NOTSUP_RETURN (-1);
+#endif /* ACE_HAS_THREADS */
+}
+
+#if defined (ACE_HAS_THREADS) && (!defined (ACE_LACKS_RWLOCK_T) || \
+ defined (ACE_HAS_PTHREADS_UNIX98_EXT))
+ACE_INLINE int
+ACE_OS::rwlock_init (ACE_rwlock_t *rw,
+ int type,
+ const ACE_TCHAR *name,
+ void *arg)
+{
+ // ACE_OS_TRACE ("ACE_OS::rwlock_init");
+# if defined (ACE_HAS_PTHREADS_UNIX98_EXT)
+ ACE_UNUSED_ARG (name);
+ ACE_UNUSED_ARG (arg);
+
+ int status;
+ pthread_rwlockattr_t attr;
+ pthread_rwlockattr_init (&attr);
+ pthread_rwlockattr_setpshared (&attr, (type == USYNC_THREAD ?
+ PTHREAD_PROCESS_PRIVATE :
+ PTHREAD_PROCESS_SHARED));
+ status = ACE_ADAPT_RETVAL (pthread_rwlock_init (rw, &attr), status);
+ pthread_rwlockattr_destroy (&attr);
+
+ return status;
+
+# else
+ type = type;
+ name = name;
+ ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::rwlock_init (rw, type, arg), ace_result_), int, -1);
+# endif /* ACE_HAS_PTHREADS_UNIX98_EXT */
+}
+#endif /* ACE_HAS THREADS && !defined (ACE_LACKS_RWLOCK_T) */
+
+ACE_INLINE int
+ACE_OS::rwlock_destroy (ACE_rwlock_t *rw)
+{
+ ACE_OS_TRACE ("ACE_OS::rwlock_destroy");
+#if defined (ACE_HAS_THREADS)
+# if !defined (ACE_LACKS_RWLOCK_T) || defined (ACE_HAS_PTHREADS_UNIX98_EXT)
+# if defined (ACE_HAS_PTHREADS_UNIX98_EXT)
+ ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (pthread_rwlock_destroy (rw),
+ ace_result_),
+ int, -1);
+# else /* Solaris */
+ ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::rwlock_destroy (rw), ace_result_), int, -1);
+# endif /* ACE_HAS_PTHREADS_UNIX98_EXT */
+# else /* NT, POSIX, and VxWorks don't support this natively. */
+ ACE_OS::mutex_destroy (&rw->lock_);
+ ACE_OS::cond_destroy (&rw->waiting_readers_);
+ ACE_OS::cond_destroy (&rw->waiting_important_writer_);
+ return ACE_OS::cond_destroy (&rw->waiting_writers_);
+# endif /* ACE_HAS_STHREADS && !defined (ACE_LACKS_RWLOCK_T) */
+#else
+ ACE_UNUSED_ARG (rw);
+ ACE_NOTSUP_RETURN (-1);
+#endif /* ACE_HAS_THREADS */
+}
+
+ACE_INLINE int
+ACE_OS::event_init (ACE_event_t *event,
+ int manual_reset,
+ int initial_state,
+ int type,
+ const char *name,
+ void *arg,
+ LPSECURITY_ATTRIBUTES sa)
+{
+#if defined (ACE_WIN32)
+ ACE_UNUSED_ARG (type);
+ ACE_UNUSED_ARG (arg);
+# if defined (ACE_HAS_WINCE)
+ // @@todo (brunsch) This idea should be moved into ACE_OS_Win32.
+ *event = ::CreateEventW (ACE_OS::default_win32_security_attributes(sa),
+ manual_reset,
+ initial_state,
+ ACE_Ascii_To_Wide (name).wchar_rep ());
+# else /* ACE_HAS_WINCE */
+ *event = ::CreateEventA (ACE_OS::default_win32_security_attributes(sa),
+ manual_reset,
+ initial_state,
+ name);
+# endif /* ACE_HAS_WINCE */
+ if (*event == NULL)
+ ACE_FAIL_RETURN (-1);
+ else
+ return 0;
+#elif defined (ACE_HAS_THREADS)
+ ACE_UNUSED_ARG (sa);
+ event->manual_reset_ = manual_reset;
+ event->is_signaled_ = initial_state;
+ event->waiting_threads_ = 0;
+
+ int result = ACE_OS::cond_init (&event->condition_,
+ ACE_static_cast (short, type),
+ name,
+ arg);
+ if (result == 0)
+ result = ACE_OS::mutex_init (&event->lock_,
+ type,
+ name,
+ (ACE_mutexattr_t *) arg);
+ return result;
+#else
+ ACE_UNUSED_ARG (event);
+ ACE_UNUSED_ARG (manual_reset);
+ ACE_UNUSED_ARG (initial_state);
+ ACE_UNUSED_ARG (type);
+ ACE_UNUSED_ARG (name);
+ ACE_UNUSED_ARG (arg);
+ ACE_UNUSED_ARG (sa);
+ ACE_NOTSUP_RETURN (-1);
+#endif /* ACE_WIN32 */
+}
+
+#if defined (ACE_HAS_WCHAR)
+ACE_INLINE int
+ACE_OS::event_init (ACE_event_t *event,
+ int manual_reset,
+ int initial_state,
+ int type,
+ const wchar_t *name,
+ void *arg,
+ LPSECURITY_ATTRIBUTES sa)
+{
+#if defined (ACE_WIN32)
+ ACE_UNUSED_ARG (type);
+ ACE_UNUSED_ARG (arg);
+ *event = ::CreateEventW (ACE_OS::default_win32_security_attributes(sa),
+ manual_reset,
+ initial_state,
+ name);
+ if (*event == NULL)
+ ACE_FAIL_RETURN (-1);
+
+ return 0;
+#else /* ACE_WIN32 */
+ return ACE_OS::event_init (event,
+ manual_reset,
+ initial_state,
+ type,
+ ACE_Wide_To_Ascii (name).char_rep (),
+ arg,
+ sa);
+#endif /* ACE_WIN32 */
+}
+#endif /* ACE_HAS_WCHAR */
+
+ACE_INLINE int
+ACE_OS::event_destroy (ACE_event_t *event)
+{
+#if defined (ACE_WIN32)
+ ACE_WIN32CALL_RETURN (ACE_ADAPT_RETVAL (::CloseHandle (*event), ace_result_), int, -1);
+#elif defined (ACE_HAS_THREADS)
+ int r1 = ACE_OS::mutex_destroy (&event->lock_);
+ int r2 = ACE_OS::cond_destroy (&event->condition_);
+ return r1 != 0 || r2 != 0 ? -1 : 0;
+#else
+ ACE_UNUSED_ARG (event);
+ ACE_NOTSUP_RETURN (-1);
+#endif /* ACE_WIN32 */
+}
+
+ACE_INLINE int
+ACE_OS::event_wait (ACE_event_t *event)
+{
+#if defined (ACE_WIN32)
+ switch (::WaitForSingleObject (*event, INFINITE))
+ {
+ case WAIT_OBJECT_0:
+ return 0;
+ default:
+ ACE_OS::set_errno_to_last_error ();
+ return -1;
+ }
+#elif defined (ACE_HAS_THREADS)
+ int result = 0;
+ int error = 0;
+
+ // grab the lock first
+ if (ACE_OS::mutex_lock (&event->lock_) == 0)
+ {
+ if (event->is_signaled_ == 1)
+ // Event is currently signaled.
+ {
+ if (event->manual_reset_ == 0)
+ // AUTO: reset state
+ event->is_signaled_ = 0;
+ }
+ else
+ // event is currently not signaled
+ {
+ event->waiting_threads_++;
+
+ if (ACE_OS::cond_wait (&event->condition_,
+ &event->lock_) != 0)
+ {
+ result = -1;
+ error = errno;
+ // Something went wrong...
+ }
+
+ event->waiting_threads_--;
+ }
+
+ // Now we can let go of the lock.
+ ACE_OS::mutex_unlock (&event->lock_);
+
+ if (result == -1)
+ // Reset errno in case mutex_unlock() also fails...
+ errno = error;
+ }
+ else
+ result = -1;
+ return result;
+#else
+ ACE_UNUSED_ARG (event);
+ ACE_NOTSUP_RETURN (-1);
+#endif /* ACE_WIN32 */
+}
+
+ACE_INLINE int
+ACE_OS::event_timedwait (ACE_event_t *event,
+ ACE_Time_Value *timeout,
+ int use_absolute_time)
+{
+#if defined (ACE_WIN32)
+ DWORD result;
+
+ if (timeout == 0)
+ // Wait forever
+ result = ::WaitForSingleObject (*event, INFINITE);
+ else if (timeout->sec () == 0 && timeout->usec () == 0)
+ // Do a "poll".
+ result = ::WaitForSingleObject (*event, 0);
+ 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
+ // WaitForSingleObjects() expects).
+ // <timeout> parameter is given in absolute or relative value
+ // depending on parameter <use_absolute_time>.
+ int msec_timeout;
+ if (use_absolute_time)
+ {
+ // Time is given in absolute time, we should use
+ // gettimeofday() to calculate relative time
+ ACE_Time_Value relative_time (*timeout - ACE_OS::gettimeofday ());
+
+ // Watchout for situations where a context switch has caused
+ // the current time to be > the timeout. Thanks to Norbert
+ // Rapp <NRapp@nexus-informatics.de> for pointing this.
+ if (relative_time < ACE_Time_Value::zero)
+ msec_timeout = 0;
+ else
+ msec_timeout = relative_time.msec ();
+ }
+ else
+ // time is given in relative time, just convert it into
+ // milliseconds and use it
+ msec_timeout = timeout->msec ();
+ result = ::WaitForSingleObject (*event, msec_timeout);
+ }
+
+ switch (result)
+ {
+ case WAIT_OBJECT_0:
+ return 0;
+ case WAIT_TIMEOUT:
+ errno = ETIME;
+ return -1;
+ default:
+ // This is a hack, we need to find an appropriate mapping...
+ ACE_OS::set_errno_to_last_error ();
+ return -1;
+ }
+#elif defined (ACE_HAS_THREADS)
+ int result = 0;
+ int error = 0;
+
+ // grab the lock first
+ if (ACE_OS::mutex_lock (&event->lock_) == 0)
+ {
+ if (event->is_signaled_ == 1)
+ // event is currently signaled
+ {
+ if (event->manual_reset_ == 0)
+ // AUTO: reset state
+ event->is_signaled_ = 0;
+ }
+ else
+ // event is currently not signaled
+ {
+ event->waiting_threads_++;
+
+ // cond_timewait() expects absolute time, check
+ // <use_absolute_time> flag.
+ if (use_absolute_time == 0 && timeout != 0)
+ *timeout += ACE_OS::gettimeofday ();
+
+ if (ACE_OS::cond_timedwait (&event->condition_,
+ &event->lock_,
+ timeout) != 0)
+ {
+ result = -1;
+ error = errno;
+ }
+
+ event->waiting_threads_--;
+ }
+
+ // Now we can let go of the lock.
+ ACE_OS::mutex_unlock (&event->lock_);
+
+ if (result == -1)
+ // Reset errno in case mutex_unlock() also fails...
+ errno = error;
+ }
+ else
+ result = -1;
+ return result;
+#else
+ ACE_UNUSED_ARG (event);
+ ACE_UNUSED_ARG (timeout);
+ ACE_UNUSED_ARG (use_absolute_time);
+ ACE_NOTSUP_RETURN (-1);
+#endif /* ACE_WIN32 */
+}
+
+ACE_INLINE int
+ACE_OS::event_signal (ACE_event_t *event)
+{
+#if defined (ACE_WIN32)
+ ACE_WIN32CALL_RETURN (ACE_ADAPT_RETVAL (::SetEvent (*event), ace_result_), int, -1);
+#elif defined (ACE_HAS_THREADS)
+ int result = 0;
+ int error = 0;
+
+ // grab the lock first
+ if (ACE_OS::mutex_lock (&event->lock_) == 0)
+ {
+ // Manual-reset event.
+ if (event->manual_reset_ == 1)
+ {
+ // signal event
+ event->is_signaled_ = 1;
+ // wakeup all
+ if (ACE_OS::cond_broadcast (&event->condition_) != 0)
+ {
+ result = -1;
+ error = errno;
+ }
+ }
+ // Auto-reset event
+ else
+ {
+ if (event->waiting_threads_ == 0)
+ // No waiters: signal event.
+ event->is_signaled_ = 1;
+
+ // Waiters: wakeup one waiter.
+ else if (ACE_OS::cond_signal (&event->condition_) != 0)
+ {
+ result = -1;
+ error = errno;
+ }
+ }
+
+ // Now we can let go of the lock.
+ ACE_OS::mutex_unlock (&event->lock_);
+
+ if (result == -1)
+ // Reset errno in case mutex_unlock() also fails...
+ errno = error;
+ }
+ else
+ result = -1;
+ return result;
+#else
+ ACE_UNUSED_ARG (event);
+ ACE_NOTSUP_RETURN (-1);
+#endif /* ACE_WIN32 */
+}
+
+ACE_INLINE int
+ACE_OS::event_pulse (ACE_event_t *event)
+{
+#if defined (ACE_WIN32)
+ ACE_WIN32CALL_RETURN (ACE_ADAPT_RETVAL (::PulseEvent (*event), ace_result_), int, -1);
+#elif defined (ACE_HAS_THREADS)
+ int result = 0;
+ int error = 0;
+
+ // grab the lock first
+ if (ACE_OS::mutex_lock (&event->lock_) == 0)
+ {
+ // Manual-reset event.
+ if (event->manual_reset_ == 1)
+ {
+ // Wakeup all waiters.
+ if (ACE_OS::cond_broadcast (&event->condition_) != 0)
+ {
+ result = -1;
+ error = errno;
+ }
+ }
+ // Auto-reset event: wakeup one waiter.
+ else if (ACE_OS::cond_signal (&event->condition_) != 0)
+ {
+ result = -1;
+ error = errno;
+ }
+
+ // Reset event.
+ event->is_signaled_ = 0;
+
+ // Now we can let go of the lock.
+ ACE_OS::mutex_unlock (&event->lock_);
+
+ if (result == -1)
+ // Reset errno in case mutex_unlock() also fails...
+ errno = error;
+ }
+ else
+ result = -1;
+ return result;
+#else
+ ACE_UNUSED_ARG (event);
+ ACE_NOTSUP_RETURN (-1);
+#endif /* ACE_WIN32 */
+}
+
+ACE_INLINE int
+ACE_OS::event_reset (ACE_event_t *event)
+{
+#if defined (ACE_WIN32)
+ ACE_WIN32CALL_RETURN (ACE_ADAPT_RETVAL (::ResetEvent (*event), ace_result_), int, -1);
+#elif defined (ACE_HAS_THREADS)
+ int result = 0;
+
+ // Grab the lock first.
+ if (ACE_OS::mutex_lock (&event->lock_) == 0)
+ {
+ // Reset event.
+ event->is_signaled_ = 0;
+
+ // Now we can let go of the lock.
+ ACE_OS::mutex_unlock (&event->lock_);
+ }
+ else
+ result = -1;
+ return result;
+#else
+ ACE_UNUSED_ARG (event);
+ ACE_NOTSUP_RETURN (-1);
+#endif /* ACE_WIN32 */
+}
+
+#if defined (ACE_WIN32)
+# define ACE_SOCKCALL_RETURN(OP,TYPE,FAILVALUE) \
+ do { TYPE ace_result_ = (TYPE) OP; \
+ if (ace_result_ == FAILVALUE) { int ___ = ::WSAGetLastError (); errno = ___; return (TYPE) FAILVALUE; } else return ace_result_; \
+ } while (0)
+#else
+# define ACE_SOCKCALL_RETURN(OP,TYPE,FAILVALUE) ACE_OSCALL_RETURN(OP,TYPE,FAILVALUE)
+#endif /* ACE_WIN32 */
+
+#if defined (ACE_LACKS_NETDB_REENTRANT_FUNCTIONS)
+# if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0)
+# define ACE_NETDBCALL_RETURN(OP,TYPE,FAILVALUE,TARGET,SIZE) \
+ do \
+ { \
+ if (ACE_OS::netdb_acquire ()) \
+ return FAILVALUE; \
+ else \
+ { \
+ TYPE ace_result_; \
+ ACE_OSCALL (OP, TYPE, FAILVALUE, ace_result_); \
+ if (ace_result_ != FAILVALUE) \
+ ::memcpy (TARGET, \
+ ace_result_, \
+ SIZE < sizeof (TYPE) ? SIZE : sizeof (TYPE)); \
+ ACE_OS::netdb_release (); \
+ return ace_result_; \
+ } \
+ } while(0)
+# else /* ! (ACE_MT_SAFE && ACE_MT_SAFE != 0) */
+# define ACE_NETDBCALL_RETURN(OP,TYPE,FAILVALUE,TARGET,SIZE) \
+ do \
+ { \
+ TYPE ace_result_; \
+ ACE_OSCALL(OP,TYPE,FAILVALUE,ace_result_); \
+ if (ace_result_ != FAILVALUE) \
+ ::memcpy (TARGET, \
+ ace_result_, \
+ SIZE < sizeof (TYPE) ? SIZE : sizeof (TYPE)); \
+ return ace_result_; \
+ } while(0)
+# endif /* ACE_MT_SAFE && ACE_MT_SAFE != 0 */
+#endif /* ACE_LACKS_NETDB_REENTRANT_FUNCTIONS */
+
+ACE_INLINE ACE_HANDLE
+ACE_OS::accept (ACE_HANDLE handle,
+ struct sockaddr *addr,
+ int *addrlen)
+{
+ ACE_OS_TRACE ("ACE_OS::accept");
+#if defined (ACE_PSOS)
+# if !defined (ACE_PSOS_DIAB_PPC)
+ ACE_SOCKCALL_RETURN (::accept ((ACE_SOCKET) handle,
+ (struct sockaddr_in *) addr,
+ (ACE_SOCKET_LEN *) addrlen),
+ ACE_HANDLE,
+ ACE_INVALID_HANDLE);
+# else
+ACE_SOCKCALL_RETURN (::accept ((ACE_SOCKET) handle,
+ (struct sockaddr *) addr,
+ (ACE_SOCKET_LEN *) addrlen),
+ ACE_HANDLE,
+ ACE_INVALID_HANDLE);
+# endif /* defined ACE_PSOS_DIAB_PPC */
+#else
+ // On a non-blocking socket with no connections to accept, this
+ // system call will return EWOULDBLOCK or EAGAIN, depending on the
+ // platform. UNIX 98 allows either errno, and they may be the same
+ // numeric value. So to make life easier for upper ACE layers as
+ // well as application programmers, always change EAGAIN to
+ // EWOULDBLOCK. Rather than hack the ACE_OSCALL_RETURN macro, it's
+ // handled explicitly here. If the ACE_OSCALL macro ever changes,
+ // this function needs to be reviewed. On Win32, the regular macros
+ // can be used, as this is not an issue.
+
+# if defined (ACE_WIN32)
+ ACE_SOCKCALL_RETURN (::accept ((ACE_SOCKET) handle,
+ addr,
+ (ACE_SOCKET_LEN *) addrlen),
+ ACE_HANDLE,
+ ACE_INVALID_HANDLE);
+# else
+# if defined (ACE_HAS_BROKEN_ACCEPT_ADDR)
+ // Apparently some platforms like VxWorks can't correctly deal with
+ // a NULL addr.
+
+ sockaddr_in fake_addr;
+ int fake_addrlen;
+
+ if (addrlen == 0)
+ addrlen = &fake_addrlen;
+
+ if (addr == 0)
+ {
+ addr = (sockaddr *) &fake_addr;
+ *addrlen = sizeof fake_addr;
+ }
+# endif /* VXWORKS */
+ ACE_HANDLE ace_result = ::accept ((ACE_SOCKET) handle,
+ addr,
+ (ACE_SOCKET_LEN *) addrlen) ;
+ if (ace_result == ACE_INVALID_HANDLE && errno == EAGAIN)
+ errno = EWOULDBLOCK;
+ return ace_result;
+
+# endif /* defined (ACE_WIN32) */
+#endif /* defined (ACE_PSOS) */
+}
+
+ACE_INLINE int
+ACE_OS::enum_protocols (int *protocols,
+ ACE_Protocol_Info *protocol_buffer,
+ u_long *buffer_length)
+{
+#if defined (ACE_HAS_WINSOCK2) && (ACE_HAS_WINSOCK2 != 0)
+
+ ACE_SOCKCALL_RETURN (::WSAEnumProtocols (protocols,
+ protocol_buffer,
+ buffer_length),
+ int,
+ SOCKET_ERROR);
+
+#else
+ ACE_UNUSED_ARG (protocols);
+ ACE_UNUSED_ARG (protocol_buffer);
+ ACE_UNUSED_ARG (buffer_length);
+ ACE_NOTSUP_RETURN (-1);
+#endif /* ACE_HAS_WINSOCK2 */
+}
+
+
+ACE_INLINE int
+ACE_OS::bind (ACE_HANDLE handle, struct sockaddr *addr, int addrlen)
+{
+ ACE_OS_TRACE ("ACE_OS::bind");
+#if defined (ACE_PSOS) && !defined (ACE_PSOS_DIAB_PPC)
+ ACE_SOCKCALL_RETURN (::bind ((ACE_SOCKET) handle,
+ (struct sockaddr_in *) addr,
+ (ACE_SOCKET_LEN) addrlen),
+ int, -1);
+#else /* !defined (ACE_PSOS) || defined (ACE_PSOS_DIAB_PPC) */
+ ACE_SOCKCALL_RETURN (::bind ((ACE_SOCKET) handle,
+ addr,
+ (ACE_SOCKET_LEN) addrlen), int, -1);
+#endif /* defined (ACE_PSOS) && !defined (ACE_PSOS_DIAB_PPC) */
+}
+
+ACE_INLINE int
+ACE_OS::connect (ACE_HANDLE handle,
+ struct sockaddr *addr,
+ int addrlen)
+{
+ ACE_OS_TRACE ("ACE_OS::connect");
+#if defined (ACE_PSOS) && !defined (ACE_PSOS_DIAB_PPC)
+ ACE_SOCKCALL_RETURN (::connect ((ACE_SOCKET) handle,
+ (struct sockaddr_in *) addr,
+ (ACE_SOCKET_LEN) addrlen),
+ int, -1);
+#else /* !defined (ACE_PSOS) || defined (ACE_PSOS_DIAB_PPC) */
+ ACE_SOCKCALL_RETURN (::connect ((ACE_SOCKET) handle,
+ addr,
+ (ACE_SOCKET_LEN) addrlen), int, -1);
+#endif /* defined (ACE_PSOS) && !defined (ACE_PSOS_DIAB_PPC) */
+}
+
+#if !defined (VXWORKS)
+ACE_INLINE struct hostent *
+ACE_OS::gethostbyname (const char *name)
+{
+ ACE_OS_TRACE ("ACE_OS::gethostbyname");
+# if defined (ACE_PSOS)
+ ACE_UNUSED_ARG (name);
+ ACE_NOTSUP_RETURN (0);
+# elif defined (ACE_HAS_NONCONST_GETBY)
+ ACE_SOCKCALL_RETURN (::gethostbyname (ACE_const_cast (char *, name)),
+ struct hostent *,
+ 0);
+# else
+ ACE_SOCKCALL_RETURN (::gethostbyname (name),
+ struct hostent *,
+ 0);
+# endif /* ACE_HAS_NONCONST_GETBY */
+}
+
+
+ACE_INLINE struct hostent *
+ACE_OS::gethostbyaddr (const char *addr, int length, int type)
+{
+ ACE_OS_TRACE ("ACE_OS::gethostbyaddr");
+# if defined (ACE_PSOS)
+ ACE_UNUSED_ARG (addr);
+ ACE_UNUSED_ARG (length);
+ ACE_UNUSED_ARG (type);
+ ACE_NOTSUP_RETURN (0);
+# elif defined (ACE_HAS_NONCONST_GETBY)
+ ACE_SOCKCALL_RETURN (::gethostbyaddr (ACE_const_cast (char *, addr),
+ (ACE_SOCKET_LEN) length,
+ type),
+ struct hostent *,
+ 0);
+# else
+ ACE_SOCKCALL_RETURN (::gethostbyaddr (addr,
+ (ACE_SOCKET_LEN) length,
+ type),
+ struct hostent *,
+ 0);
+# endif /* ACE_HAS_NONCONST_GETBY */
+}
+
+
+ACE_INLINE struct hostent *
+ACE_OS::getipnodebyname (const char *name, int family, int flags)
+{
+ ACE_OS_TRACE ("ACE_OS::getipnodebyname");
+# if defined (ACE_PSOS)
+ ACE_UNUSED_ARG (name);
+ ACE_UNUSED_ARG (family);
+ ACE_UNUSED_ARG (flags);
+ ACE_NOTSUP_RETURN (0);
+# elif defined (ACE_HAS_IPV6)
+# if defined (__GLIBC__)
+ ACE_UNUSED_ARG (flags);
+# if defined (ACE_HAS_NONCONST_GETBY)
+ ACE_SOCKCALL_RETURN (::gethostbyname2 (ACE_const_cast (char *, name),
+ family),
+ struct hostent *, 0);
+# else
+ ACE_SOCKCALL_RETURN (::gethostbyname2 (name, family),
+ struct hostent *, 0);
+# endif /* ACE_HAS_NONCONST_GETBY */
+# else
+ struct hostent *hptr;
+ int errnum;
+ if ((hptr = ::getipnodebyname (name, family, flags, &errnum)) == 0)
+ {
+ errno = errnum;
+ }
+ return hptr;
+# endif /* __GLIBC__ */
+# else
+ // IPv4-only implementation
+ ACE_UNUSED_ARG (flags);
+ if (family == AF_INET)
+ return ACE_OS::gethostbyname (name);
+
+ ACE_NOTSUP_RETURN (0);
+# endif /* ACE_PSOS */
+}
+
+
+ACE_INLINE struct hostent *
+ACE_OS::getipnodebyaddr (const void *src, size_t len, int family)
+{
+#if defined (ACE_HAS_IPV6)
+# if defined (__GLIBC__)
+ ACE_UNUSED_ARG (src);
+ ACE_UNUSED_ARG (len);
+ ACE_UNUSED_ARG (family);
+ ACE_NOTSUP_RETURN (0);
+# else
+ struct hostent *hptr;
+ int errnum;
+ if ((hptr = ::getipnodebyaddr (src, len, family, &errnum)) == 0)
+ {
+ errno = errnum;
+ }
+ return hptr;
+# endif /* whatever_doesnt_have_getipnodebyname */
+#else
+ // IPv4-only implementation
+ if (family == AF_INET)
+ return ACE_OS::gethostbyaddr (ACE_static_cast (const char *, src),
+ len,
+ family);
+
+ ACE_NOTSUP_RETURN (0);
+# endif /* ACE_PSOS */
+}
+#endif /* ! VXWORKS */
+
+// It would be really cool to add another version of select that would
+// function like the one we're defending against below!
+ACE_INLINE int
+ACE_OS::select (int width,
+ fd_set *rfds, fd_set *wfds, fd_set *efds,
+ const ACE_Time_Value *timeout)
+{
+ ACE_OS_TRACE ("ACE_OS::select");
+#if defined (ACE_HAS_NONCONST_SELECT_TIMEVAL)
+ // We must defend against non-conformity!
+ timeval copy;
+ timeval *timep;
+
+ if (timeout != 0)
+ {
+ copy = *timeout;
+ timep = &copy;
+ }
+ else
+ timep = 0;
+#else
+ const timeval *timep = (timeout == 0 ? (const timeval *)0 : *timeout);
+#endif /* ACE_HAS_NONCONST_SELECT_TIMEVAL */
+ ACE_SOCKCALL_RETURN (::select (width,
+ (ACE_FD_SET_TYPE *) rfds,
+ (ACE_FD_SET_TYPE *) wfds,
+ (ACE_FD_SET_TYPE *) efds,
+ timep),
+ int, -1);
+}
+
+ACE_INLINE int
+ACE_OS::select (int width,
+ fd_set *rfds, fd_set *wfds, fd_set *efds,
+ const ACE_Time_Value &timeout)
+{
+ ACE_OS_TRACE ("ACE_OS::select");
+#if defined (ACE_HAS_NONCONST_SELECT_TIMEVAL)
+# define ___ACE_TIMEOUT &copy
+ timeval copy = timeout;
+#else
+# define ___ACE_TIMEOUT timep
+ const timeval *timep = timeout;
+#endif /* ACE_HAS_NONCONST_SELECT_TIMEVAL */
+ ACE_SOCKCALL_RETURN (::select (width,
+ (ACE_FD_SET_TYPE *) rfds,
+ (ACE_FD_SET_TYPE *) wfds,
+ (ACE_FD_SET_TYPE *) efds,
+ ___ACE_TIMEOUT),
+ int, -1);
+#undef ___ACE_TIMEOUT
+}
+
+ACE_INLINE int
+ACE_OS::recv (ACE_HANDLE handle, char *buf, int len, int flags)
+{
+ ACE_OS_TRACE ("ACE_OS::recv");
+
+ // On UNIX, a non-blocking socket with no data to receive, this
+ // system call will return EWOULDBLOCK or EAGAIN, depending on the
+ // platform. UNIX 98 allows either errno, and they may be the same
+ // numeric value. So to make life easier for upper ACE layers as
+ // well as application programmers, always change EAGAIN to
+ // EWOULDBLOCK. Rather than hack the ACE_OSCALL_RETURN macro, it's
+ // handled explicitly here. If the ACE_OSCALL macro ever changes,
+ // this function needs to be reviewed. On Win32, the regular macros
+ // can be used, as this is not an issue.
+#if defined (ACE_WIN32)
+ ACE_SOCKCALL_RETURN (::recv ((ACE_SOCKET) handle, buf, len, flags), int, -1);
+#else
+ int ace_result_;
+ ace_result_ = ::recv ((ACE_SOCKET) handle, buf, len, flags);
+ if (ace_result_ == -1 && errno == EAGAIN)
+ errno = EWOULDBLOCK;
+ return ace_result_;
+#endif /* defined (ACE_WIN32) */
+}
+
+ACE_INLINE int
+ACE_OS::recvfrom (ACE_HANDLE handle,
+ char *buf,
+ int len,
+ int flags,
+ struct sockaddr *addr,
+ int *addrlen)
+{
+ ACE_OS_TRACE ("ACE_OS::recvfrom");
+#if defined (ACE_PSOS)
+# if !defined ACE_PSOS_DIAB_PPC
+ ACE_SOCKCALL_RETURN (::recvfrom ((ACE_SOCKET) handle, buf, (ACE_SOCKET_LEN) len, flags,
+ (struct sockaddr_in *) addr, (ACE_SOCKET_LEN *) addrlen),
+ int, -1);
+# else
+ ACE_SOCKCALL_RETURN (::recvfrom ((ACE_SOCKET) handle, buf, (ACE_SOCKET_LEN) len, flags,
+ (struct sockaddr *) addr, (ACE_SOCKET_LEN *) addrlen),
+ int, -1);
+# endif /* defined ACE_PSOS_DIAB_PPC */
+#elif defined (ACE_WIN32)
+ int result = ::recvfrom ((ACE_SOCKET) handle,
+ buf,
+ (ACE_SOCKET_LEN) len,
+ flags,
+ addr,
+ (ACE_SOCKET_LEN *) addrlen);
+ if (result == SOCKET_ERROR)
+ {
+ ACE_OS::set_errno_to_wsa_last_error ();
+ if (errno == WSAEMSGSIZE &&
+ ACE_BIT_ENABLED (flags, MSG_PEEK))
+ return len;
+ else
+ return -1;
+ }
+ else
+ return result;
+#else /* non Win32 and non PSOS */
+ ACE_SOCKCALL_RETURN (::recvfrom ((ACE_SOCKET) handle, buf, (ACE_SOCKET_LEN) len, flags,
+ addr, (ACE_SOCKET_LEN *) addrlen),
+ int, -1);
+#endif /* defined (ACE_PSOS) */
+}
+
+ACE_INLINE int
+ACE_OS::send (ACE_HANDLE handle, const char *buf, int len, int flags)
+{
+ ACE_OS_TRACE ("ACE_OS::send");
+
+ // On UNIX, a non-blocking socket with no data to receive, this
+ // system call will return EWOULDBLOCK or EAGAIN, depending on the
+ // platform. UNIX 98 allows either errno, and they may be the same
+ // numeric value. So to make life easier for upper ACE layers as
+ // well as application programmers, always change EAGAIN to
+ // EWOULDBLOCK. Rather than hack the ACE_OSCALL_RETURN macro, it's
+ // handled explicitly here. If the ACE_OSCALL macro ever changes,
+ // this function needs to be reviewed. On Win32, the regular macros
+ // can be used, as this is not an issue.
+#if defined (ACE_WIN32)
+ ACE_SOCKCALL_RETURN (::send ((ACE_SOCKET) handle, buf, len, flags), int, -1);
+#else
+ int ace_result_;
+# if defined (VXWORKS) || defined (HPUX) || defined (ACE_PSOS)
+ ace_result_ = ::send ((ACE_SOCKET) handle, (char *) buf, len, flags);
+# else
+ ace_result_ = ::send ((ACE_SOCKET) handle, buf, len, flags);
+# endif /* VXWORKS */
+ if (ace_result_ == -1 && errno == EAGAIN)
+ errno = EWOULDBLOCK;
+ return ace_result_;
+#endif /* defined (ACE_WIN32) */
+}
+
+ACE_INLINE int
+ACE_OS::recvfrom (ACE_HANDLE handle,
+ iovec *buffers,
+ int buffer_count,
+ size_t &number_of_bytes_recvd,
+ int &flags,
+ struct sockaddr *addr,
+ int *addrlen,
+ ACE_OVERLAPPED *overlapped,
+ ACE_OVERLAPPED_COMPLETION_FUNC func)
+{
+ ACE_OS_TRACE ("ACE_OS::recvfrom");
+
+#if defined (ACE_HAS_WINSOCK2) && (ACE_HAS_WINSOCK2 != 0)
+ DWORD bytes_recvd;
+ DWORD the_flags = flags;
+ int result = ::WSARecvFrom ((SOCKET) handle,
+ (WSABUF*)buffers,
+ buffer_count,
+ &bytes_recvd,
+ &the_flags,
+ addr,
+ addrlen,
+ overlapped,
+ func);
+ flags = the_flags;
+ number_of_bytes_recvd = ACE_static_cast (size_t, bytes_recvd);
+ return result;
+#else
+ ACE_UNUSED_ARG (handle);
+ ACE_UNUSED_ARG (buffers);
+ ACE_UNUSED_ARG (buffer_count);
+ ACE_UNUSED_ARG (number_of_bytes_recvd);
+ ACE_UNUSED_ARG (flags);
+ ACE_UNUSED_ARG (addr);
+ ACE_UNUSED_ARG (addrlen);
+ ACE_UNUSED_ARG (overlapped);
+ ACE_UNUSED_ARG (func);
+ ACE_NOTSUP_RETURN (-1);
+#endif /* defined (ACE_HAS_WINSOCK2) && (ACE_HAS_WINSOCK2 != 0) */
+}
+
+ACE_INLINE int
+ACE_OS::sendto (ACE_HANDLE handle,
+ const char *buf,
+ int len,
+ int flags,
+ const struct sockaddr *addr,
+ int addrlen)
+{
+ ACE_OS_TRACE ("ACE_OS::sendto");
+#if defined (VXWORKS)
+ ACE_SOCKCALL_RETURN (::sendto ((ACE_SOCKET) handle, (char *) buf, len, flags,
+ ACE_const_cast (struct sockaddr *, addr), addrlen),
+ int, -1);
+#elif defined (ACE_PSOS)
+# if !defined (ACE_PSOS_DIAB_PPC)
+ ACE_SOCKCALL_RETURN (::sendto ((ACE_SOCKET) handle, (char *) buf, len, flags,
+ (struct sockaddr_in *) addr, addrlen),
+ int, -1);
+# else
+ ACE_SOCKCALL_RETURN (::sendto ((ACE_SOCKET) handle, (char *) buf, len, flags,
+ (struct sockaddr *) addr, addrlen),
+ int, -1);
+# endif /*defined ACE_PSOS_DIAB_PPC */
+#else
+ ACE_SOCKCALL_RETURN (::sendto ((ACE_SOCKET) handle, buf, len, flags,
+ ACE_const_cast (struct sockaddr *, addr), addrlen),
+ int, -1);
+#endif /* VXWORKS */
+}
+
+ACE_INLINE int
+ACE_OS::sendto (ACE_HANDLE handle,
+ const iovec *buffers,
+ int buffer_count,
+ size_t &number_of_bytes_sent,
+ int flags,
+ const struct sockaddr *addr,
+ int addrlen,
+ ACE_OVERLAPPED *overlapped,
+ ACE_OVERLAPPED_COMPLETION_FUNC func)
+{
+ ACE_OS_TRACE ("ACE_OS::sendto");
+#if defined (ACE_HAS_WINSOCK2) && (ACE_HAS_WINSOCK2 != 0)
+ DWORD bytes_sent;
+ int result = ::WSASendTo ((SOCKET) handle,
+ (WSABUF*)buffers,
+ buffer_count,
+ &bytes_sent,
+ flags,
+ addr,
+ addrlen,
+ overlapped,
+ func);
+ number_of_bytes_sent = ACE_static_cast (size_t, bytes_sent);
+ return result;
+#else
+ ACE_UNUSED_ARG (overlapped);
+ ACE_UNUSED_ARG (func);
+
+ number_of_bytes_sent = 0;
+
+ int result = 0;
+
+ for (int i = 0; i < buffer_count; i++)
+ {
+ result = ACE_OS::sendto (handle,
+ ACE_reinterpret_cast (char *ACE_CAST_CONST,
+ buffers[i].iov_base),
+ buffers[i].iov_len,
+ flags,
+ addr,
+ addrlen);
+ if (result == -1)
+ break;
+ number_of_bytes_sent += result;
+ }
+
+ return result;
+#endif /* defined (ACE_HAS_WINSOCK2) && (ACE_HAS_WINSOCK2 != 0) */
+}
+
+ACE_INLINE int
+ACE_OS::getpeername (ACE_HANDLE handle, struct sockaddr *addr,
+ int *addrlen)
+{
+ ACE_OS_TRACE ("ACE_OS::getpeername");
+#if defined (ACE_PSOS) && !defined ACE_PSOS_DIAB_PPC
+ ACE_SOCKCALL_RETURN (::getpeername ((ACE_SOCKET) handle,
+ (struct sockaddr_in *) addr,
+ (ACE_SOCKET_LEN *) addrlen),
+ int, -1);
+#else
+ ACE_SOCKCALL_RETURN (::getpeername ((ACE_SOCKET) handle,
+ addr,
+ (ACE_SOCKET_LEN *) addrlen),
+ int, -1);
+#endif /* defined (ACE_PSOS) */
+}
+
+ACE_INLINE struct protoent *
+ACE_OS::getprotobyname (const char *name)
+{
+#if defined (VXWORKS) || defined (ACE_HAS_WINCE) || (defined (ghs) && defined (__Chorus)) || defined (ACE_PSOS)
+ ACE_UNUSED_ARG (name);
+ ACE_NOTSUP_RETURN (0);
+#elif defined (ACE_HAS_NONCONST_GETBY)
+ ACE_SOCKCALL_RETURN (::getprotobyname (ACE_const_cast (char *, name)),
+ struct protoent *,
+ 0);
+#else
+ ACE_SOCKCALL_RETURN (::getprotobyname (name),
+ struct protoent *,
+ 0);
+#endif /* VXWORKS */
+}
+
+ACE_INLINE struct protoent *
+ACE_OS::getprotobyname_r (const char *name,
+ struct protoent *result,
+ ACE_PROTOENT_DATA buffer)
+{
+#if defined (VXWORKS) || defined (ACE_HAS_WINCE) || (defined (ghs) && defined (__Chorus)) || defined (ACE_PSOS)
+ ACE_UNUSED_ARG (name);
+ ACE_UNUSED_ARG (result);
+ ACE_UNUSED_ARG (buffer);
+ ACE_NOTSUP_RETURN (0);
+#elif defined (ACE_HAS_REENTRANT_FUNCTIONS) && !defined (UNIXWARE)
+# if defined (AIX) || defined (DIGITAL_UNIX) || defined (HPUX_10)
+ if (::getprotobyname_r (name, result, (struct protoent_data *) buffer) == 0)
+ return result;
+ else
+ return 0;
+# elif defined (__GLIBC__)
+ // GNU C library has a different signature
+ if (::getprotobyname_r (name,
+ result,
+ buffer,
+ sizeof (ACE_PROTOENT_DATA),
+ &result) == 0)
+ return result;
+ else
+ return 0;
+# else
+# if defined(ACE_LACKS_NETDB_REENTRANT_FUNCTIONS)
+ ACE_UNUSED_ARG (result);
+ ACE_NETDBCALL_RETURN (::getprotobyname (name),
+ struct protoent *, 0,
+ buffer, sizeof (ACE_PROTOENT_DATA));
+# else
+ ACE_SOCKCALL_RETURN (::getprotobyname_r (name,
+ result,
+ buffer,
+ sizeof (ACE_PROTOENT_DATA)),
+ struct protoent *, 0);
+# endif /* ACE_LACKS_NETDB_REENTRANT_FUNCTIONS */
+# endif /* defined (AIX) || defined (DIGITAL_UNIX) */
+#elif defined (ACE_HAS_NONCONST_GETBY)
+ ACE_UNUSED_ARG (result);
+ ACE_UNUSED_ARG (buffer);
+ ACE_SOCKCALL_RETURN (::getprotobyname (ACE_const_cast (char *, name)),
+ struct protoent *, 0);
+#else
+ ACE_UNUSED_ARG (buffer);
+ ACE_UNUSED_ARG (result);
+
+ ACE_SOCKCALL_RETURN (::getprotobyname (name),
+ struct protoent *,
+ 0);
+#endif /* defined (ACE_HAS_REENTRANT_FUNCTIONS) !defined (UNIXWARE) */
+}
+
+ACE_INLINE struct protoent *
+ACE_OS::getprotobynumber (int proto)
+{
+#if defined (VXWORKS) || defined (ACE_HAS_WINCE) || (defined (ghs) && defined (__Chorus)) || defined (ACE_PSOS)
+ ACE_UNUSED_ARG (proto);
+ ACE_NOTSUP_RETURN (0);
+#else
+ ACE_SOCKCALL_RETURN (::getprotobynumber (proto),
+ struct protoent *, 0);
+#endif /* VXWORKS */
+}
+
+ACE_INLINE struct protoent *
+ACE_OS::getprotobynumber_r (int proto,
+ struct protoent *result,
+ ACE_PROTOENT_DATA buffer)
+{
+#if defined (VXWORKS) || defined (ACE_HAS_WINCE) || (defined (ghs) && defined (__Chorus)) || defined (ACE_PSOS)
+ ACE_UNUSED_ARG (proto);
+ ACE_UNUSED_ARG (result);
+ ACE_UNUSED_ARG (buffer);
+ ACE_NOTSUP_RETURN (0);
+#elif defined (ACE_HAS_REENTRANT_FUNCTIONS) && !defined (UNIXWARE)
+# if defined (AIX) || defined (DIGITAL_UNIX) || defined (HPUX_10)
+ if (::getprotobynumber_r (proto, result, (struct protoent_data *) buffer) == 0)
+ return result;
+ else
+ return 0;
+# elif defined (__GLIBC__)
+ // GNU C library has a different signature
+ if (::getprotobynumber_r (proto,
+ result,
+ buffer,
+ sizeof (ACE_PROTOENT_DATA),
+ &result) == 0)
+ return result;
+ else
+ return 0;
+# else
+# if defined(ACE_LACKS_NETDB_REENTRANT_FUNCTIONS)
+ ACE_UNUSED_ARG (result);
+ ACE_NETDBCALL_RETURN (::getprotobynumber (proto),
+ struct protoent *, 0,
+ buffer, sizeof (ACE_PROTOENT_DATA));
+# else
+ ACE_SOCKCALL_RETURN (::getprotobynumber_r (proto, result, buffer, sizeof (ACE_PROTOENT_DATA)),
+ struct protoent *, 0);
+# endif /* ACE_LACKS_NETDB_REENTRANT_FUNCTIONS */
+# endif /* defined (AIX) || defined (DIGITAL_UNIX) */
+#else
+ ACE_UNUSED_ARG (buffer);
+ ACE_UNUSED_ARG (result);
+
+ ACE_SOCKCALL_RETURN (::getprotobynumber (proto),
+ struct protoent *, 0);
+#endif /* defined (ACE_HAS_REENTRANT_FUNCTIONS) && !defined (UNIXWARE) */
+}
+
+ACE_INLINE struct servent *
+ACE_OS::getservbyname (const char *svc, const char *proto)
+{
+ ACE_OS_TRACE ("ACE_OS::getservbyname");
+#if defined (ACE_LACKS_GETSERVBYNAME)
+ ACE_UNUSED_ARG (svc);
+ ACE_UNUSED_ARG (proto);
+ ACE_NOTSUP_RETURN (0);
+#elif defined (ACE_HAS_NONCONST_GETBY)
+ ACE_SOCKCALL_RETURN (::getservbyname (ACE_const_cast (char *, svc),
+ ACE_const_cast (char *, proto)),
+ struct servent *,
+ 0);
+#else
+ ACE_SOCKCALL_RETURN (::getservbyname (svc,
+ proto),
+ struct servent *,
+ 0);
+#endif /* ACE_HAS_NONCONST_GETBY */
+}
+
+ACE_INLINE int
+ACE_OS::getsockname (ACE_HANDLE handle,
+ struct sockaddr *addr,
+ int *addrlen)
+{
+ ACE_OS_TRACE ("ACE_OS::getsockname");
+#if defined (ACE_PSOS) && !defined (ACE_PSOS_DIAB_PPC)
+ ACE_SOCKCALL_RETURN (::getsockname ((ACE_SOCKET) handle,
+ (struct sockaddr_in *) addr,
+ (ACE_SOCKET_LEN *) addrlen),
+ int, -1);
+#else
+ ACE_SOCKCALL_RETURN (::getsockname ((ACE_SOCKET) handle,
+ addr,
+ (ACE_SOCKET_LEN *) addrlen),
+ int, -1);
+#endif /* defined (ACE_PSOS) */
+}
+
+ACE_INLINE int
+ACE_OS::getsockopt (ACE_HANDLE handle,
+ int level,
+ int optname,
+ char *optval,
+ int *optlen)
+{
+ ACE_OS_TRACE ("ACE_OS::getsockopt");
+ ACE_SOCKCALL_RETURN (::getsockopt ((ACE_SOCKET) handle,
+ level,
+ optname,
+ optval,
+ (ACE_SOCKET_LEN *) optlen),
+ int,
+ -1);
+}
+
+ACE_INLINE int
+ACE_OS::listen (ACE_HANDLE handle, int backlog)
+{
+ ACE_OS_TRACE ("ACE_OS::listen");
+ ACE_SOCKCALL_RETURN (::listen ((ACE_SOCKET) handle, backlog), int, -1);
+}
+
+ACE_INLINE int
+ACE_OS::setsockopt (ACE_HANDLE handle,
+ int level,
+ int optname,
+ const char *optval,
+ int optlen)
+{
+ ACE_OS_TRACE ("ACE_OS::setsockopt");
+ ACE_SOCKCALL_RETURN (::setsockopt ((ACE_SOCKET) handle,
+ level,
+ optname,
+ (ACE_SOCKOPT_TYPE1) optval,
+ optlen),
+ int,
+ -1);
+}
+
+ACE_INLINE int
+ACE_OS::shutdown (ACE_HANDLE handle, int how)
+{
+ ACE_OS_TRACE ("ACE_OS::shutdown");
+ ACE_SOCKCALL_RETURN (::shutdown ((ACE_SOCKET) handle, how), int, -1);
+}
+
+ACE_INLINE ACE_HANDLE
+ACE_OS::socket (int domain,
+ int type,
+ int proto)
+{
+ ACE_OS_TRACE ("ACE_OS::socket");
+ ACE_SOCKCALL_RETURN (::socket (domain,
+ type,
+ proto),
+ ACE_HANDLE,
+ ACE_INVALID_HANDLE);
+}
+
+ACE_INLINE ACE_HANDLE
+ACE_OS::socket (int domain,
+ int type,
+ int proto,
+ ACE_Protocol_Info *protocolinfo,
+ ACE_SOCK_GROUP g,
+ u_long flags)
+{
+ ACE_OS_TRACE ("ACE_OS::socket");
+
+#if defined (ACE_HAS_WINSOCK2) && (ACE_HAS_WINSOCK2 != 0)
+ ACE_SOCKCALL_RETURN (::WSASocket (domain,
+ type,
+ proto,
+ protocolinfo,
+ g,
+ flags),
+ ACE_HANDLE,
+ ACE_INVALID_HANDLE);
+#else
+ ACE_UNUSED_ARG (protocolinfo);
+ ACE_UNUSED_ARG (g);
+ ACE_UNUSED_ARG (flags);
+
+ return ACE_OS::socket (domain,
+ type,
+ proto);
+#endif /* ACE_HAS_WINSOCK2 */
+}
+
+ACE_INLINE int
+ACE_OS::atoi (const char *s)
+{
+#if defined (ACE_HAS_PACE)
+ ACE_OSCALL_RETURN (::pace_atoi (s), int, -1);
+#else /* ACE_HAS_PACE */
+ ACE_OSCALL_RETURN (::atoi (s), int, -1);
+#endif /* ACE_HAS_PACE */
+}
+
+#if defined (ACE_HAS_WCHAR)
+ACE_INLINE int
+ACE_OS::atoi (const wchar_t *s)
+{
+#if defined (ACE_WIN32)
+ ACE_OSCALL_RETURN (::_wtoi (s), int, -1);
+#else /* ACE_WIN32 */
+ return ACE_OS::atoi (ACE_Wide_To_Ascii(s).char_rep());
+#endif /* ACE_WIN32 */
+}
+#endif /* ACE_HAS_WCHAR */
+
+ACE_INLINE double
+ACE_OS::floor (double x)
+{
+ // This method computes the largest integral value not greater than x.
+ return double (ACE_static_cast (long, x));
+}
+
+ACE_INLINE double
+ACE_OS::ceil (double x)
+{
+ // This method computes the smallest integral value not less than x.
+ double floor = ACE_OS::floor (x);
+ if (floor == x)
+ return floor;
+ else
+ return floor + 1;
+}
+
+ACE_INLINE int
+ACE_OS::recvmsg (ACE_HANDLE handle, struct msghdr *msg, int flags)
+{
+ ACE_OS_TRACE ("ACE_OS::recvmsg");
+#if !defined (ACE_LACKS_RECVMSG)
+# if (defined (ACE_HAS_WINSOCK2) && (ACE_HAS_WINSOCK2 != 0))
+ DWORD bytes_received = 0;
+
+ int result = ::WSARecvFrom ((SOCKET) handle,
+ (WSABUF *) msg->msg_iov,
+ msg->msg_iovlen,
+ &bytes_received,
+ (DWORD *) &flags,
+ msg->msg_name,
+ &msg->msg_namelen,
+ 0,
+ 0);
+
+ if (result != 0)
+ {
+ ACE_OS::set_errno_to_last_error ();
+ return -1;
+ }
+ else
+ return (ssize_t) bytes_received;
+# else /* ACE_HAS_WINSOCK2 */
+ ACE_SOCKCALL_RETURN (::recvmsg (handle, msg, flags), int, -1);
+# endif /* ACE_HAS_WINSOCK2 */
+#else
+ ACE_UNUSED_ARG (flags);
+ ACE_UNUSED_ARG (msg);
+ ACE_UNUSED_ARG (handle);
+
+ ACE_NOTSUP_RETURN (-1);
+#endif /* ACE_LACKS_RECVMSG */
+}
+
+ACE_INLINE int
+ACE_OS::sendmsg (ACE_HANDLE handle,
+ const struct msghdr *msg,
+ int flags)
+{
+ ACE_OS_TRACE ("ACE_OS::sendmsg");
+#if !defined (ACE_LACKS_SENDMSG)
+# if (defined (ACE_HAS_WINSOCK2) && (ACE_HAS_WINSOCK2 != 0))
+ DWORD bytes_sent = 0;
+ int result = ::WSASendTo ((SOCKET) handle,
+ (WSABUF *) msg->msg_iov,
+ msg->msg_iovlen,
+ &bytes_sent,
+ flags,
+ msg->msg_name,
+ msg->msg_namelen,
+ 0,
+ 0);
+
+ if (result != 0)
+ {
+ ACE_OS::set_errno_to_last_error ();
+ return -1;
+ }
+ else
+ return (ssize_t) bytes_sent;
+# elif defined (ACE_LACKS_POSIX_PROTOTYPES) || defined (ACE_PSOS)
+ ACE_SOCKCALL_RETURN (::sendmsg (handle, (struct msghdr *) msg, flags), int, -1);
+# else
+ ACE_SOCKCALL_RETURN (::sendmsg (handle, (ACE_SENDMSG_TYPE *) msg, flags), int, -1);
+# endif /* ACE_LACKS_POSIX_PROTOTYPES */
+#else
+ ACE_UNUSED_ARG (flags);
+ ACE_UNUSED_ARG (msg);
+ ACE_UNUSED_ARG (handle);
+
+ ACE_NOTSUP_RETURN (-1);
+#endif /* ACE_LACKS_SENDMSG */
+}
+
+ACE_INLINE int
+ACE_OS::fclose (FILE *fp)
+{
+#if defined (ACE_HAS_PACE)
+ ACE_OSCALL_RETURN (::pace_fclose (fp), int, -1);
+#elif !defined (ACE_HAS_WINCE)
+ ACE_OS_TRACE ("ACE_OS::fclose");
+ ACE_OSCALL_RETURN (::fclose (fp), int, -1);
+#else
+ // On CE, FILE * == void * == HANDLE
+ ACE_WIN32CALL_RETURN (ACE_ADAPT_RETVAL(::CloseHandle (fp), ace_result_),
+ int, -1);
+#endif /* ACE_HAS_PACE */
+}
+
+ACE_INLINE ACE_TCHAR *
+ACE_OS::fgets (ACE_TCHAR *buf, int size, FILE *fp)
+{
+ ACE_OS_TRACE ("ACE_OS::fgets");
+#if defined (ACE_HAS_PACE)
+ ACE_OSCALL_RETURN (::pace_fgets (buf, size, fp), char*, 0);
+#elif defined (ACE_HAS_WINCE)
+ ACE_UNUSED_ARG (buf);
+ ACE_UNUSED_ARG (size);
+ ACE_UNUSED_ARG (fp);
+ ACE_NOTSUP_RETURN (0);
+#elif defined (ACE_WIN32) && defined (ACE_USES_WCHAR)
+ ACE_OSCALL_RETURN (::fgetws (buf, size, fp), wchar_t *, 0);
+#else /* ACE_WIN32 */
+ ACE_OSCALL_RETURN (::fgets (buf, size, fp), char *, 0);
+#endif /* ACE_HAS_PACE */
+}
+
+#if !defined (ACE_WIN32)
+// Win32 implementation of fopen(const ACE_TCHAR*, const ACE_TCHAR*)
+// is in OS.cpp.
+ACE_INLINE FILE *
+ACE_OS::fopen (const ACE_TCHAR *filename, const ACE_TCHAR *mode)
+{
+#if defined (ACE_HAS_PACE)
+ ACE_OSCALL_RETURN (::pace_fopen (filename, mode), FILE*, 0);
+#else
+ ACE_OS_TRACE ("ACE_OS::fopen");
+ ACE_OSCALL_RETURN (::fopen (filename, mode), FILE *, 0);
+#endif /* ACE_HAS_PACE */
+}
+#endif /* ACE_WIN32 */
+
+ACE_INLINE FILE *
+ACE_OS::freopen (const ACE_TCHAR *filename, const ACE_TCHAR *mode, FILE* stream)
+{
+ ACE_OS_TRACE ("ACE_OS::freopen");
+#if defined (ACE_HAS_PACE)
+ ACE_OSCALL_RETURN (::pace_freopen (filename, mode, stream), FILE*, 0);
+#elif defined (ACE_HAS_WINCE)
+ ACE_UNUSED_ARG (filename);
+ ACE_UNUSED_ARG (mode);
+ ACE_UNUSED_ARG (stream);
+ ACE_NOTSUP_RETURN (0);
+#elif defined (ACE_WIN32) && defined (ACE_USES_WCHAR)
+ ACE_OSCALL_RETURN (::_wfreopen (filename, mode, stream), FILE *, 0);
+#else
+ ACE_OSCALL_RETURN (::freopen (filename, mode, stream), FILE *, 0);
+#endif /* defined (ACE_HAS_PACE) */
+}
+
+ACE_INLINE int
+ACE_OS::fflush (FILE *fp)
+{
+#if defined (ACE_HAS_PACE)
+ ACE_OSCALL_RETURN (::pace_fflush (fp), int, -1);
+#elif !defined (ACE_HAS_WINCE)
+ ACE_OS_TRACE ("ACE_OS::fflush");
+ ACE_OSCALL_RETURN (::fflush (fp), int, -1);
+#else
+ ACE_WIN32CALL_RETURN (ACE_ADAPT_RETVAL(::FlushFileBuffers (fp),
+ ace_result_),
+ int, -1);
+#endif /* ACE_HAS_PACE */
+}
+
+ACE_INLINE size_t
+ACE_OS::fread (void *ptr, size_t size, size_t nelems, FILE *fp)
+{
+ ACE_OS_TRACE ("ACE_OS::fread");
+#if defined (ACE_HAS_PACE)
+ ACE_OSCALL_RETURN (::pace_fread (ptr, size, nelems, fp), int, 0);
+#elif defined (ACE_HAS_WINCE)
+ DWORD len = 0;
+ size_t tlen = size * nelems;
+
+ if (::ReadFile (fp, ptr, tlen, &len, NULL) == FALSE)
+ {
+ ACE_OS::set_errno_to_last_error ();
+ return -1;
+ }
+ else if (tlen != len)
+ {
+ // only return length of multiple of <size>
+ len = (len / size) * size ;
+ // then rewind file pointer.
+ ::SetFilePointer (fp, (len - tlen), 0, FILE_CURRENT);
+ }
+ return len;
+#elif defined (ACE_LACKS_POSIX_PROTOTYPES)
+ ACE_OSCALL_RETURN (::fread ((char *) ptr, size, nelems, fp), int, 0);
+#else
+ ACE_OSCALL_RETURN (::fread (ptr, size, nelems, fp), int, 0);
+#endif /* ACE_HAS_PACE */
+}
+
+ACE_INLINE size_t
+ACE_OS::fwrite (const void *ptr, size_t size, size_t nitems, FILE *fp)
+{
+ ACE_OS_TRACE ("ACE_OS::fwrite");
+#if defined (ACE_HAS_PACE)
+ ACE_OSCALL_RETURN (::pace_fwrite (ptr, size, nitems, fp), int, 0);
+#elif defined (ACE_HAS_WINCE)
+ DWORD len = 0;
+ size_t tlen = size * nitems;
+
+ if (::WriteFile (fp, ptr, tlen, &len, NULL) == FALSE)
+ {
+ ACE_OS::set_errno_to_last_error ();
+ return -1;
+ }
+ else if (tlen != len)
+ {
+ // only return length of multiple of <size>
+ len = (len / size) * size ;
+ // then rewind file pointer.
+ ::SetFilePointer (fp, (len - tlen), 0, FILE_CURRENT);
+ }
+ return len;
+#elif defined (ACE_LACKS_POSIX_PROTOTYPES)
+ ACE_OSCALL_RETURN (::fwrite ((const char *) ptr, size, nitems, fp), int, 0);
+#else
+ ACE_OSCALL_RETURN (::fwrite (ptr, size, nitems, fp), int, 0);
+#endif /* ACE_HAS_PACE */
+}
+
+ACE_INLINE int
+ACE_OS::truncate (const ACE_TCHAR *filename,
+ off_t offset)
+{
+ ACE_OS_TRACE ("ACE_OS::truncate");
+#if defined (ACE_HAS_PACE) && !defined (ACE_WIN32)
+ int fd = ::pace_open (filename, O_RDWR, ACE_DEFAULT_FILE_PERMS);
+ int result = 0;
+ if (fd == -1)
+ return -1;
+ ACE_OSCALL (::pace_ftruncate (fd, offset), int, -1, result);
+ pace_close (fd);
+ return result;
+#elif defined (ACE_WIN32)
+ ACE_HANDLE handle = ACE_OS::open (filename,
+ O_WRONLY,
+ ACE_DEFAULT_FILE_PERMS);
+ if (handle == ACE_INVALID_HANDLE)
+ ACE_FAIL_RETURN (-1);
+ else if (::SetFilePointer (handle,
+ offset,
+ NULL,
+ FILE_BEGIN) != (unsigned) -1)
+ {
+ BOOL result = ::SetEndOfFile (handle);
+ ::CloseHandle (handle);
+ ACE_WIN32CALL_RETURN (ACE_ADAPT_RETVAL (result, ace_result_), int, -1);
+ }
+ else
+ {
+ ::CloseHandle (handle);
+ ACE_FAIL_RETURN (-1);
+ }
+ /* NOTREACHED */
+#elif !defined (ACE_LACKS_TRUNCATE)
+ ACE_OSCALL_RETURN (::truncate (filename, offset), int, -1);
+#else
+ ACE_UNUSED_ARG (filename);
+ ACE_UNUSED_ARG (offset);
+ ACE_NOTSUP_RETURN (-1);
+#endif /* ACE_HAS_PACE */
+}
+
+// Accessors to PWD file.
+
+ACE_INLINE struct passwd *
+ACE_OS::getpwnam (const char *name)
+{
+#if defined (ACE_HAS_PACE)
+ return ::pace_getpwnam (name);
+#elif !defined (ACE_LACKS_PWD_FUNCTIONS)
+# if !defined (ACE_WIN32)
+ return ::getpwnam (name);
+# else
+ ACE_UNUSED_ARG (name);
+ ACE_NOTSUP_RETURN (0);
+# endif /* ACE_WIN32 */
+#else
+ ACE_UNUSED_ARG (name);
+ ACE_NOTSUP_RETURN (0);
+#endif /* ACE_HAS_PACE */
+}
+
+ACE_INLINE void
+ACE_OS::setpwent (void)
+{
+#if !defined (ACE_LACKS_PWD_FUNCTIONS)
+# if !defined (ACE_WIN32)
+ ::setpwent ();
+# else
+# endif /* ACE_WIN32 */
+#else
+#endif /* ! ACE_LACKS_PWD_FUNCTIONS */
+}
+
+ACE_INLINE void
+ACE_OS::endpwent (void)
+{
+#if !defined (ACE_LACKS_PWD_FUNCTIONS)
+# if !defined (ACE_WIN32)
+ ::endpwent ();
+# else
+# endif /* ACE_WIN32 */
+#else
+#endif /* ! ACE_LACKS_PWD_FUNCTIONS */
+}
+
+ACE_INLINE struct passwd *
+ACE_OS::getpwent (void)
+{
+#if !defined (ACE_LACKS_PWD_FUNCTIONS)
+# if !defined (ACE_WIN32)
+ return ::getpwent ();
+# else
+ ACE_NOTSUP_RETURN (0);
+# endif /* ACE_WIN32 */
+#else
+ ACE_NOTSUP_RETURN (0);
+#endif /* ! ACE_LACKS_PWD_FUNCTIONS */
+}
+
+ACE_INLINE struct passwd *
+ACE_OS::getpwnam_r (const char *name, struct passwd *pwent,
+ char *buffer, int buflen)
+{
+#if defined (ACE_HAS_PACE) || defined (ACE_HAS_POSIX_GETPWNAM_R)
+ struct passwd *result;
+ int status;
+
+# if defined (ACE_HAS_PACE)
+ status = ::pace_getpwnam_r (name, pwent, buffer, buflen, &result);
+# else
+ status = ::getpwnam_r (name, pwent, buffer, buflen, &result);
+# endif /* ACE_HAS_PACE */
+
+ if (status != 0)
+ {
+ errno = status;
+ result = 0;
+ }
+ return result;
+#elif !defined (ACE_LACKS_PWD_FUNCTIONS)
+# if defined (ACE_HAS_REENTRANT_FUNCTIONS)
+# if !defined (ACE_LACKS_PWD_REENTRANT_FUNCTIONS)
+# if defined (ACE_HAS_PTHREADS_STD) && \
+ !defined (ACE_HAS_STHREADS) || \
+ defined (HPUX_11) || \
+ defined (__USLC__) // Added by Roland Gigler for SCO UnixWare 7.
+ struct passwd *result;
+ int status;
+# if defined (DIGITAL_UNIX)
+ ::_Pgetpwnam_r (name, pwent, buffer, buflen, &result);
+# else
+ // VAC++ doesn't correctly grok the ::getpwnam_r - the function is redefined
+ // in pwd.h, and that redefinition is used here
+# if defined (__IBMCPP__) && (__IBMCPP__ >= 400) /* VAC++ 4 */
+ status = _posix_getpwnam_r (name, pwent, buffer, buflen, &result);
+# else
+ status = ::getpwnam_r (name, pwent, buffer, buflen, &result);
+# endif /* __IBMCPP__ && (__IBMCPP__ >= 400) */
+ if (status != 0)
+ {
+ errno = status;
+ result = 0;
+ }
+# endif /* (DIGITAL_UNIX) */
+ return result;
+# elif defined (AIX) || defined (HPUX_10)
+ if (::getpwnam_r (name, pwent, buffer, buflen) == -1)
+ return 0;
+ else
+ return pwent;
+# else
+ return ::getpwnam_r (name, pwent, buffer, buflen);
+# endif /* ACE_HAS_PTHREADS_STD */
+# else
+ ACE_UNUSED_ARG (name);
+ ACE_UNUSED_ARG (pwent);
+ ACE_UNUSED_ARG (buffer);
+ ACE_UNUSED_ARG (buflen);
+ ACE_NOTSUP_RETURN (0);
+# endif /* ! ACE_LACKS_PWD_REENTRANT_FUNCTIONS */
+# else
+ ACE_UNUSED_ARG (name);
+ ACE_UNUSED_ARG (pwent);
+ ACE_UNUSED_ARG (buffer);
+ ACE_UNUSED_ARG (buflen);
+ ACE_NOTSUP_RETURN (0);
+# endif /* ACE_HAS_REENTRANT_FUNCTIONS */
+#else
+ ACE_UNUSED_ARG (name);
+ ACE_UNUSED_ARG (pwent);
+ ACE_UNUSED_ARG (buffer);
+ ACE_UNUSED_ARG (buflen);
+ ACE_NOTSUP_RETURN (0);
+#endif /* ACE_HAS_PACE */
+}
+
+// DNS accessors.
+
+#if !defined (VXWORKS)
+ACE_INLINE struct hostent *
+ACE_OS::gethostbyaddr_r (const char *addr,
+ int length,
+ int type,
+ hostent *result,
+ ACE_HOSTENT_DATA buffer,
+ int *h_errnop)
+{
+ ACE_OS_TRACE ("ACE_OS::gethostbyaddr_r");
+# if defined (ACE_PSOS)
+ ACE_UNUSED_ARG (addr);
+ ACE_UNUSED_ARG (length);
+ ACE_UNUSED_ARG (type);
+ ACE_UNUSED_ARG (result);
+ ACE_UNUSED_ARG (buffer);
+ ACE_UNUSED_ARG (h_errnop);
+ ACE_NOTSUP_RETURN (0);
+# elif defined (ACE_HAS_REENTRANT_FUNCTIONS) && !defined (UNIXWARE)
+# if defined (AIX) || defined (DIGITAL_UNIX) || defined (HPUX_10)
+ ::memset (buffer, 0, sizeof (ACE_HOSTENT_DATA));
+
+ if (::gethostbyaddr_r ((char *) addr, length, type, result,
+ (struct hostent_data *) buffer)== 0)
+ return result;
+ else
+ {
+ *h_errnop = h_errno;
+ return (struct hostent *) 0;
+ }
+# elif defined (__GLIBC__)
+ // GNU C library has a different signature
+ ::memset (buffer, 0, sizeof (ACE_HOSTENT_DATA));
+
+ if (::gethostbyaddr_r ((char *) addr,
+ length,
+ type,
+ result,
+ buffer,
+ sizeof (ACE_HOSTENT_DATA),
+ &result,
+ h_errnop) == 0)
+ return result;
+ else
+ return (struct hostent *) 0;
+# else
+# if defined(ACE_LACKS_NETDB_REENTRANT_FUNCTIONS)
+ ACE_UNUSED_ARG (result);
+ ACE_UNUSED_ARG (h_errnop);
+ ACE_NETDBCALL_RETURN (::gethostbyaddr (addr, (ACE_SOCKET_LEN) length, type),
+ struct hostent *, 0,
+ buffer, sizeof (ACE_HOSTENT_DATA));
+# else
+ ACE_SOCKCALL_RETURN (::gethostbyaddr_r (addr, length, type, result,
+ buffer, sizeof (ACE_HOSTENT_DATA),
+ h_errnop),
+ struct hostent *, 0);
+# endif /* ACE_LACKS_NETDB_REENTRANT_FUNCTIONS */
+# endif /* defined (AIX) || defined (DIGITAL_UNIX) */
+# elif defined (ACE_HAS_NONCONST_GETBY)
+ ACE_UNUSED_ARG (result);
+ ACE_UNUSED_ARG (buffer);
+ ACE_UNUSED_ARG (h_errnop);
+ ACE_SOCKCALL_RETURN (::gethostbyaddr (ACE_const_cast (char *, addr),
+ (ACE_SOCKET_LEN) length,
+ type),
+ struct hostent *,
+ 0);
+# else
+ ACE_UNUSED_ARG (h_errnop);
+ ACE_UNUSED_ARG (buffer);
+ ACE_UNUSED_ARG (result);
+
+ ACE_SOCKCALL_RETURN (::gethostbyaddr (addr,
+ (ACE_SOCKET_LEN) length,
+ type),
+ struct hostent *,
+ 0);
+# endif /* defined (ACE_HAS_REENTRANT_FUNCTIONS) && !defined (UNIXWARE) */
+}
+
+ACE_INLINE struct hostent *
+ACE_OS::gethostbyname_r (const char *name,
+ hostent *result,
+ ACE_HOSTENT_DATA buffer,
+ int *h_errnop)
+{
+ ACE_OS_TRACE ("ACE_OS::gethostbyname_r");
+#if defined (ACE_PSOS)
+ ACE_UNUSED_ARG (name);
+ ACE_UNUSED_ARG (result);
+ ACE_UNUSED_ARG (buffer);
+ ACE_UNUSED_ARG (h_errnop);
+ ACE_NOTSUP_RETURN (0);
+# elif defined (ACE_HAS_REENTRANT_FUNCTIONS) && !defined (UNIXWARE)
+# if defined (DIGITAL_UNIX) || \
+ (defined (ACE_AIX_MINOR_VERS) && (ACE_AIX_MINOR_VERS > 2))
+ ACE_UNUSED_ARG (result);
+ ACE_UNUSED_ARG (buffer);
+ ACE_UNUSED_ARG (h_errnop);
+
+ // gethostbyname returns thread-specific storage on Digital Unix and
+ // AIX 4.3
+ ACE_SOCKCALL_RETURN (::gethostbyname (name), struct hostent *, 0);
+# elif defined (AIX) || defined (HPUX_10)
+ ::memset (buffer, 0, sizeof (ACE_HOSTENT_DATA));
+
+ if (::gethostbyname_r (name, result, (struct hostent_data *) buffer) == 0)
+ return result;
+ else
+ {
+ *h_errnop = h_errno;
+ return (struct hostent *) 0;
+ }
+# elif defined (__GLIBC__)
+ // GNU C library has a different signature
+ ::memset (buffer, 0, sizeof (ACE_HOSTENT_DATA));
+
+ if (::gethostbyname_r (name,
+ result,
+ buffer,
+ sizeof (ACE_HOSTENT_DATA),
+ &result,
+ h_errnop) == 0)
+ return result;
+ else
+ return (struct hostent *) 0;
+# else
+# if defined(ACE_LACKS_NETDB_REENTRANT_FUNCTIONS)
+ ACE_UNUSED_ARG (result);
+ ACE_UNUSED_ARG (h_errnop);
+ ACE_NETDBCALL_RETURN (::gethostbyname (name),
+ struct hostent *, 0,
+ buffer, sizeof (ACE_HOSTENT_DATA));
+# else
+ ACE_SOCKCALL_RETURN (::gethostbyname_r (name, result, buffer,
+ sizeof (ACE_HOSTENT_DATA),
+ h_errnop),
+ struct hostent *,
+ 0);
+# endif /* ACE_LACKS_NETDB_REENTRANT_FUNCTIONS */
+# endif /* defined (AIX) || defined (DIGITAL_UNIX) */
+# elif defined (ACE_HAS_NONCONST_GETBY)
+ ACE_UNUSED_ARG (result);
+ ACE_UNUSED_ARG (buffer);
+ ACE_UNUSED_ARG (h_errnop);
+ ACE_SOCKCALL_RETURN (::gethostbyname (ACE_const_cast (char *, name)),
+ struct hostent *,
+ 0);
+# else
+ ACE_UNUSED_ARG (result);
+ ACE_UNUSED_ARG (buffer);
+ ACE_UNUSED_ARG (h_errnop);
+
+ ACE_SOCKCALL_RETURN (::gethostbyname (name),
+ struct hostent *,
+ 0);
+# endif /* defined (ACE_HAS_REENTRANT_FUNCTIONS) && !defined (UNIXWARE) */
+}
+#endif /* ! VXWORKS */
+
+#if 0
+// @@ gets is evil anyway.
+// and it is *** DEPRECATED *** now. If you
+// really needs gets, use ACE_OS::gets (char*, int)
+// instead.
+ACE_INLINE char *
+ACE_OS::gets (char *str)
+{
+ ACE_OS_TRACE ("ACE_OS::gets");
+ ACE_OSCALL_RETURN (::gets (str), char *, 0);
+}
+#endif /* 0 */
+
+ACE_INLINE struct servent *
+ACE_OS::getservbyname_r (const char *svc,
+ const char *proto,
+ struct servent *result,
+ ACE_SERVENT_DATA buf)
+{
+ ACE_OS_TRACE ("ACE_OS::getservbyname_r");
+#if defined (ACE_LACKS_GETSERVBYNAME)
+ ACE_UNUSED_ARG (svc);
+ ACE_UNUSED_ARG (proto);
+ ACE_UNUSED_ARG (result);
+ ACE_UNUSED_ARG (buf);
+ ACE_NOTSUP_RETURN (0);
+#elif defined (ACE_HAS_REENTRANT_FUNCTIONS) && !defined (UNIXWARE)
+# if defined (AIX) || defined (DIGITAL_UNIX) || defined (HPUX_10)
+ ::memset (buf, 0, sizeof (ACE_SERVENT_DATA));
+
+ if (::getservbyname_r (svc, proto, result, (struct servent_data *) buf) == 0)
+ return result;
+ else
+ return (struct servent *) 0;
+# elif defined (__GLIBC__)
+ // GNU C library has a different signature
+ ::memset (buf, 0, sizeof (ACE_SERVENT_DATA));
+
+ if (::getservbyname_r (svc,
+ proto,
+ result,
+ buf,
+ sizeof (ACE_SERVENT_DATA),
+ &result) == 0)
+ return result;
+ else
+ return (struct servent *) 0;
+# else
+# if defined(ACE_LACKS_NETDB_REENTRANT_FUNCTIONS)
+ ACE_UNUSED_ARG (result);
+ ACE_NETDBCALL_RETURN (::getservbyname (svc, proto),
+ struct servent *, 0,
+ buf, sizeof (ACE_SERVENT_DATA));
+# else
+ ACE_SOCKCALL_RETURN (::getservbyname_r (svc, proto, result, buf,
+ sizeof (ACE_SERVENT_DATA)),
+ struct servent *, 0);
+# endif /* ACE_LACKS_NETDB_REENTRANT_FUNCTIONS */
+# endif /* defined (AIX) || defined (DIGITAL_UNIX) */
+#elif defined (ACE_HAS_NONCONST_GETBY)
+ ACE_UNUSED_ARG (buf);
+ ACE_UNUSED_ARG (result);
+ ACE_SOCKCALL_RETURN (::getservbyname (ACE_const_cast (char *, svc),
+ ACE_const_cast (char *, proto)),
+ struct servent *,
+ 0);
+#else
+ ACE_UNUSED_ARG (buf);
+ ACE_UNUSED_ARG (result);
+
+ ACE_SOCKCALL_RETURN (::getservbyname (svc,
+ proto),
+ struct servent *,
+ 0);
+#endif /* defined (ACE_HAS_REENTRANT_FUNCTIONS) && !defined (UNIXWARE) */
+}
+
+ACE_INLINE unsigned long
+ACE_OS::inet_addr (const char *name)
+{
+ ACE_OS_TRACE ("ACE_OS::inet_addr");
+#if defined (VXWORKS) || defined (ACE_PSOS)
+
+ u_long ret = 0;
+ u_int segment;
+ u_int valid = 1;
+
+ for (u_int i = 0; i < 4; ++i)
+ {
+ ret <<= 8;
+ if (*name != '\0')
+ {
+ segment = 0;
+
+ while (*name >= '0' && *name <= '9')
+ {
+ segment *= 10;
+ segment += *name++ - '0';
+ }
+ if (*name != '.' && *name != '\0')
+ {
+ valid = 0;
+ break;
+ }
+
+ ret |= segment;
+
+ if (*name == '.')
+ {
+ ++name;
+ }
+ }
+ }
+ return valid ? htonl (ret) : INADDR_NONE;
+#elif defined (ACE_HAS_NONCONST_GETBY)
+ return ::inet_addr ((char *) name);
+#else
+ return ::inet_addr (name);
+#endif /* ACE_HAS_NONCONST_GETBY */
+}
+
+// For pSOS, this function is in OS.cpp
+#if !defined (ACE_PSOS)
+ACE_INLINE char *
+ACE_OS::inet_ntoa (const struct in_addr addr)
+{
+ ACE_OS_TRACE ("ACE_OS::inet_ntoa");
+ ACE_OSCALL_RETURN (::inet_ntoa (addr),
+ char *,
+ 0);
+}
+#endif /* defined (ACE_PSOS) */
+
+ACE_INLINE int
+ACE_OS::inet_pton (int family, const char *strptr, void *addrptr)
+{
+ ACE_OS_TRACE ("ACE_OS::inet_pton");
+
+#if defined (ACE_HAS_IPV6)
+ ACE_OSCALL_RETURN (::inet_pton (family, strptr, addrptr), int, -1);
+#else
+ if (family == AF_INET)
+ {
+ struct in_addr in_val;
+
+ if (ACE_OS::inet_aton (strptr, &in_val))
+ {
+ ACE_OS::memcpy (addrptr, &in_val, sizeof (struct in_addr));
+ return 1; // Success
+ }
+
+ return 0; // Input is not a valid presentation format
+ }
+
+ ACE_NOTSUP_RETURN(-1);
+#endif /* ACE_HAS_IPV6 */
+}
+
+ACE_INLINE const char *
+ACE_OS::inet_ntop (int family, const void *addrptr, char *strptr, size_t len)
+{
+ ACE_OS_TRACE ("ACE_OS::inet_ntop");
+
+#if defined (ACE_HAS_IPV6)
+ ACE_OSCALL_RETURN (::inet_ntop (family, addrptr, strptr, len), const char *, 0);
+#else
+ const u_char *p =
+ ACE_reinterpret_cast (const u_char *, addrptr);
+
+ if (family == AF_INET)
+ {
+ char temp[INET_ADDRSTRLEN];
+
+ // Stevens uses snprintf() in his implementation but snprintf()
+ // doesn't appear to be very portable. For now, hope that using
+ // sprintf() will not cause any string/memory overrun problems.
+ ACE_OS::sprintf (temp,
+ "%d.%d.%d.%d",
+ p[0], p[1], p[2], p[3]);
+
+ if (ACE_OS::strlen (temp) >= len)
+ {
+ errno = ENOSPC;
+ return 0; // Failure
+ }
+
+ ACE_OS::strcpy (strptr, temp);
+ return strptr;
+ }
+
+ ACE_NOTSUP_RETURN(0);
+#endif /* ACE_HAS_IPV6 */
+}
+
+ACE_INLINE int
+ACE_OS::set_errno_to_last_error (void)
+{
+# if defined (ACE_WIN32)
+// Borland C++ Builder 4 has a bug in the RTL that resets the
+// <GetLastError> value to zero when errno is accessed. Thus, we have
+// to use this to set errno to GetLastError. It's bad, but only for
+// WIN32.
+# if defined(__BORLANDC__) && (__BORLANDC__ == 0x540) || defined (__IBMCPP__) && (__IBMCPP__ >= 400)
+ int last_error = ::GetLastError ();
+ return errno = last_error;
+# else /* defined(__BORLANDC__) && (__BORLANDC__ == 0x540) */
+ return errno = ::GetLastError ();
+# endif /* defined(__BORLANDC__) && (__BORLANDC__ == 0x540) */
+#else
+ return errno;
+# endif /* defined(ACE_WIN32) */
+}
+
+ACE_INLINE int
+ACE_OS::set_errno_to_wsa_last_error (void)
+{
+# if defined (ACE_WIN32)
+// Borland C++ Builder 4 has a bug in the RTL that resets the
+// <GetLastError> value to zero when errno is accessed. Thus, we have
+// to use this to set errno to GetLastError. It's bad, but only for
+// WIN32
+# if defined(__BORLANDC__) && (__BORLANDC__ == 0x540) || defined (__IBMCPP__) && (__IBMCPP__ >= 400)
+ int last_error = ::WSAGetLastError ();
+ return errno = last_error;
+# else /* defined(__BORLANDC__) && (__BORLANDC__ == 0x540) */
+ return errno = ::WSAGetLastError ();
+# endif /* defined(__BORLANDC__) && (__BORLANDC__ == 0x540) */
+#else
+ return errno;
+# endif /* defined(ACE_WIN32) */
+}
+
+ACE_INLINE int
+ACE_OS::last_error (void)
+{
+ // ACE_OS_TRACE ("ACE_OS::last_error");
+
+#if defined (ACE_WIN32)
+ int lerror = ::GetLastError ();
+ int lerrno = errno;
+ return lerrno == 0 ? lerror : lerrno;
+#else
+ return errno;
+#endif /* ACE_WIN32 */
+}
+
+ACE_INLINE void
+ACE_OS::last_error (int error)
+{
+ ACE_OS_TRACE ("ACE_OS::last_error");
+#if defined (ACE_WIN32)
+ ::SetLastError (error);
+#else
+ errno = error;
+#endif /* ACE_WIN32 */
+}
+
+ACE_INLINE void
+ACE_OS::perror (const ACE_TCHAR *s)
+{
+ ACE_OS_TRACE ("ACE_OS::perror");
+#if defined (ACE_HAS_PACE)
+ ::pace_perror (s);
+#elif defined (ACE_HAS_WINCE)
+ // @@ WINCE: How should this be handled
+ ACE_UNUSED_ARG (s);
+#elif defined (ACE_WIN32) && defined (ACE_USES_WCHAR)
+ ::_wperror (s);
+#else
+ ::perror (s);
+#endif /* ACE_HAS_PACE */
+}
+
+
+// @@ WINCE: Do we need to implement puts on WinCE???
+#if !defined (ACE_HAS_WINCE)
+ACE_INLINE int
+ACE_OS::puts (const ACE_TCHAR *s)
+{
+ ACE_OS_TRACE ("ACE_OS::puts");
+#if defined (ACE_HAS_PACE)
+ ACE_OSCALL_RETURN (::pace_puts (s), int, -1);
+#elif defined (ACE_WIN32) && defined (ACE_USES_WCHAR)
+ ACE_OSCALL_RETURN (::_putws (s), int, -1);
+#else /* ACE_WIN32 */
+ ACE_OSCALL_RETURN (::puts (s), int, -1);
+#endif /* ACE_HAS_PACE */
+}
+
+ACE_INLINE int
+ACE_OS::fputs (const ACE_TCHAR *s, FILE *stream)
+{
+ ACE_OS_TRACE ("ACE_OS::fputs");
+#if defined (ACE_HAS_PACE)
+ ACE_OSCALL_RETURN (::pace_fputs (s, stream), int, -1);
+#elif defined (ACE_WIN32) && defined (ACE_USES_WCHAR)
+ ACE_OSCALL_RETURN (::fputws (s, stream), int, -1);
+#else /* ACE_WIN32 */
+ ACE_OSCALL_RETURN (::fputs (s, stream), int, -1);
+#endif /* ACE_HAS_PACE */
+}
+#endif /* ! ACE_HAS_WINCE */
+
+ACE_INLINE ACE_SignalHandler
+ACE_OS::signal (int signum, ACE_SignalHandler func)
+{
+ if (signum == 0)
+ return 0;
+ else
+#if defined (ACE_HAS_PACE)
+# if defined (ACE_HAS_LYNXOS_SIGNALS)
+ return (void (*)(...))::pace_signal (signum, (void (*)(int)) func);
+# else
+ return ::pace_signal (signum, func);
+# endif /* ACE_HAS_LYNXOS_SIGNALS */
+#elif defined (ACE_PSOS) && !defined (ACE_PSOS_TM) && !defined (ACE_PSOS_DIAB_MIPS) && !defined (ACE_PSOS_DIAB_PPC)
+ return (ACE_SignalHandler) ::signal (signum, (void (*)(void)) func);
+#elif defined (ACE_PSOS_DIAB_MIPS) || defined (ACE_PSOS_DIAB_PPC)
+ return 0;
+#elif defined (ACE_PSOS_TM)
+ // @@ It would be good to rework this so the ACE_PSOS_TM specific
+ // branch is not needed, but prying it out of ACE_LACKS_UNIX_SIGNALS
+ // will take some extra work - deferred for now.
+ return (ACE_SignalHandler) ::signal (signum, (void (*)(int)) func);
+#elif defined (ACE_WIN32) && !defined (ACE_HAS_WINCE) || !defined (ACE_LACKS_UNIX_SIGNALS)
+# if !defined (ACE_HAS_TANDEM_SIGNALS) && !defined (ACE_HAS_LYNXOS_SIGNALS)
+ return ::signal (signum, func);
+# else
+ return (ACE_SignalHandler) ::signal (signum, (void (*)(int)) func);
+# endif /* !ACE_HAS_TANDEM_SIGNALS */
+#else
+ // @@ WINCE: Don't know how to implement signal on WinCE (yet.)
+ ACE_UNUSED_ARG (signum);
+ ACE_UNUSED_ARG (func);
+ ACE_NOTSUP_RETURN (0); // Should return SIG_ERR but it is not defined on WinCE.
+#endif /* ACE_HAS_PACE */
+}
+
+ACE_INLINE int
+ACE_OS::system (const ACE_TCHAR *s)
+{
+ // ACE_OS_TRACE ("ACE_OS::system");
+#if defined (CHORUS) || defined (ACE_HAS_WINCE) || defined(ACE_PSOS)
+ ACE_UNUSED_ARG (s);
+ ACE_NOTSUP_RETURN (-1);
+#elif defined (ACE_WIN32) && defined (ACE_USES_WCHAR)
+ ACE_OSCALL_RETURN (::_wsystem (s), int, -1);
+#else
+ ACE_OSCALL_RETURN (::system (s), int, -1);
+#endif /* !CHORUS */
+}
+
+ACE_INLINE int
+ACE_OS::thr_continue (ACE_hthread_t target_thread)
+{
+ ACE_OS_TRACE ("ACE_OS::thr_continue");
+#if defined (ACE_HAS_THREADS)
+# if defined (ACE_HAS_STHREADS)
+ ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::thr_continue (target_thread), ace_result_), int, -1);
+# elif defined (ACE_HAS_PTHREADS)
+# if defined (ACE_HAS_PTHREADS_UNIX98_EXT)
+ ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (pthread_continue (target_thread),
+ ace_result_),
+ int, -1);
+# else
+ ACE_UNUSED_ARG (target_thread);
+ ACE_NOTSUP_RETURN (-1);
+# endif /* ACE_HAS_PTHREADS_UNIX98_EXT */
+# elif defined (ACE_HAS_WTHREADS)
+ DWORD result = ::ResumeThread (target_thread);
+ if (result == ACE_SYSCALL_FAILED)
+ ACE_FAIL_RETURN (-1);
+ else
+ return 0;
+# elif defined (ACE_PSOS)
+ ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::t_resume (target_thread), ace_result_), int, -1);
+# elif defined (VXWORKS)
+# if defined (ACE_HAS_PACE)
+ // pthread_continue (like pthread_suspend) is not an official POSIX
+ // function. We get this for free with ACE. So use the thread ID from
+ // the pace_pthread_t structure.
+ ACE_OSCALL_RETURN (::taskResume (target_thread->tid), int, -1);
+# else
+ ACE_OSCALL_RETURN (::taskResume (target_thread), int, -1);
+# endif /* ACE_HAS_PACE */
+# endif /* ACE_HAS_STHREADS */
+#else
+ ACE_UNUSED_ARG (target_thread);
+ ACE_NOTSUP_RETURN (-1);
+#endif /* ACE_HAS_THREADS */
+}
+
+ACE_INLINE int
+ACE_OS::thr_cmp (ACE_hthread_t t1, ACE_hthread_t t2)
+{
+#if defined (ACE_HAS_PACE) && !defined (ACE_WIN32)
+ return ::pace_pthread_equal (t1, t2);
+#elif defined (ACE_HAS_PTHREADS)
+# if defined (pthread_equal)
+ // If it's a macro we can't say "::pthread_equal"...
+ return pthread_equal (t1, t2);
+# else
+ return ::pthread_equal (t1, t2);
+# endif /* pthread_equal */
+#else /* For STHREADS, WTHREADS, and VXWORKS ... */
+ // Hum, Do we need to treat WTHREAD differently?
+ // levine 13 oct 98 % Probably, ACE_hthread_t is a HANDLE.
+ return t1 == t2;
+#endif /* ACE_HAS_PACE */
+}
+
+ACE_INLINE int
+ACE_OS::thr_getconcurrency (void)
+{
+ ACE_OS_TRACE ("ACE_OS::thr_getconcurrency");
+#if defined (ACE_HAS_THREADS)
+# if defined (ACE_HAS_STHREADS)
+ return ::thr_getconcurrency ();
+# elif defined (ACE_HAS_PTHREADS) || defined (VXWORKS) || defined (ACE_PSOS)
+ ACE_NOTSUP_RETURN (-1);
+# elif defined (ACE_HAS_WTHREADS)
+ ACE_NOTSUP_RETURN (-1);
+# endif /* ACE_HAS_STHREADS */
+#else
+ ACE_NOTSUP_RETURN (-1);
+#endif /* ACE_HAS_THREADS */
+}
+
+ACE_INLINE int
+ACE_OS::thr_getprio (ACE_hthread_t thr_id, int &prio)
+{
+ ACE_OS_TRACE ("ACE_OS::thr_getprio");
+#if defined (ACE_HAS_PACE) && !defined (ACE_WIN32)
+ struct sched_param param;
+ int result;
+ int policy = 0;
+
+ result = ::pace_pthread_getschedparam (thr_id, &policy, &param);
+
+ prio = param.sched_priority;
+ return result;
+#elif defined (ACE_HAS_THREADS)
+# if (defined (ACE_HAS_PTHREADS) && !defined (ACE_LACKS_SETSCHED))
+
+# if defined (ACE_HAS_PTHREADS_DRAFT4)
+ int result;
+ result = ::pthread_getprio (thr_id);
+ if (result != -1)
+ {
+ prio = result;
+ return 0;
+ }
+ else
+ return -1;
+# elif defined (ACE_HAS_PTHREADS_DRAFT6)
+
+ pthread_attr_t attr;
+ if (pthread_getschedattr (thr_id, &attr) == 0)
+ {
+ prio = pthread_attr_getprio(&attr);
+ return 0;
+ }
+ return -1;
+# else
+
+ struct sched_param param;
+ int result;
+ int policy = 0;
+
+ ACE_OSCALL (ACE_ADAPT_RETVAL (::pthread_getschedparam (thr_id, &policy, &param),
+ result), int,
+ -1, result);
+ prio = param.sched_priority;
+ return result;
+# endif /* ACE_HAS_PTHREADS_DRAFT4 */
+# elif defined (ACE_HAS_STHREADS)
+ ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::thr_getprio (thr_id, &prio), ace_result_), int, -1);
+# elif defined (ACE_HAS_WTHREADS)
+ prio = ::GetThreadPriority (thr_id);
+ if (prio == THREAD_PRIORITY_ERROR_RETURN)
+ ACE_FAIL_RETURN (-1);
+ else
+ return 0;
+# elif defined (ACE_PSOS)
+ // passing a 0 in the second argument does not alter task priority, third arg gets existing one
+ ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::t_setpri (thr_id, 0, (u_long *) &prio), ace_result_), int, -1);
+# elif defined (VXWORKS)
+ ACE_OSCALL_RETURN (::taskPriorityGet (thr_id, &prio), int, -1);
+# else
+ ACE_UNUSED_ARG (thr_id);
+ ACE_UNUSED_ARG (prio);
+ ACE_NOTSUP_RETURN (-1);
+# endif /* ACE_HAS_STHREADS */
+#else
+ ACE_UNUSED_ARG (thr_id);
+ ACE_UNUSED_ARG (prio);
+ ACE_NOTSUP_RETURN (-1);
+#endif /* ACE_HAS_PACE */
+}
+
+#if defined (ACE_HAS_TSS_EMULATION)
+
+# if defined (ACE_HAS_THREAD_SPECIFIC_STORAGE)
+ACE_INLINE int
+ACE_OS::thr_getspecific (ACE_OS_thread_key_t key, void **data)
+{
+ ACE_OS_TRACE ("ACE_OS::thr_getspecific");
+// If we are using TSS emulation then we shuld use ACE's implementation
+// of it and not make any PACE calls.
+//# if defined (ACE_HAS_PACE) && !defined (ACE_WIN32)
+// *data = ::pace_pthread_getspecific (key);
+// return 0;
+//# elif defined (ACE_HAS_THREADS)
+# if defined (ACE_HAS_THREADS)
+# if defined (ACE_HAS_PTHREADS)
+# if defined (ACE_HAS_PTHREADS_DRAFT4) || defined (ACE_HAS_PTHREADS_DRAFT6)
+ return pthread_getspecific (key, data);
+# else /* this is ACE_HAS_PTHREADS_DRAFT7 or STD */
+# if (pthread_getspecific)
+ // This is a macro on some platforms, e.g., CHORUS!
+ *data = pthread_getspecific (key);
+# else
+ *data = pthread_getspecific (key);
+# endif /* pthread_getspecific */
+# endif /* ACE_HAS_PTHREADS_DRAFT4, 6 */
+ return 0;
+# elif defined (ACE_HAS_STHREADS)
+ ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::thr_getspecific (key, data), ace_result_), int, -1);
+# elif defined (ACE_PSOS) && defined (ACE_PSOS_HAS_TSS)
+ ACE_hthread_t tid;
+ ACE_OS::thr_self (tid);
+ return (::tsd_getval (key, tid, data) == 0) ? 0 : -1;
+# elif defined (ACE_HAS_WTHREADS)
+
+ // The following handling of errno is designed like this due to
+ // ACE_Log_Msg::instance calling ACE_OS::thr_getspecific.
+ // Basically, it is ok for a system call to reset the error to zero.
+ // (It really shouldn't, though). However, we have to remember to
+ // store errno *immediately* after an error is detected. Calling
+ // ACE_ERROR_RETURN((..., errno)) did not work because errno was
+ // cleared before being passed to the thread-specific instance of
+ // ACE_Log_Msg. The workaround for was to make it so
+ // thr_getspecific did not have the side effect of clearing errno.
+ // The correct fix is for ACE_ERROR_RETURN to store errno
+ //(actually ACE_OS::last_error) before getting the ACE_Log_Msg tss
+ // pointer, which is how it is implemented now. However, other uses
+ // of ACE_Log_Msg may not work correctly, so we're keeping this as
+ // it is for now.
+
+ ACE_Errno_Guard error (errno);
+ *data = ::TlsGetValue (key);
+# if !defined (ACE_HAS_WINCE)
+ if (*data == 0 && (error = ::GetLastError ()) != NO_ERROR)
+ return -1;
+ else
+# endif /* ACE_HAS_WINCE */
+ return 0;
+# endif /* ACE_HAS_STHREADS */
+# else
+ ACE_UNUSED_ARG (key);
+ ACE_UNUSED_ARG (data);
+ ACE_NOTSUP_RETURN (-1);
+//# endif /* ACE_HAS_PACE */
+# endif /* ACE_HAS_THREADS */
+}
+# endif /* ACE_HAS_THREAD_SPECIFIC_STORAGE */
+
+# if !defined (ACE_HAS_THREAD_SPECIFIC_STORAGE)
+ACE_INLINE
+void **&
+ACE_TSS_Emulation::tss_base ()
+{
+# if defined (VXWORKS)
+ return (void **&) taskIdCurrent->ACE_VXWORKS_SPARE;
+# elif defined (ACE_PSOS)
+ // not supported
+ long x=0; //JINLU
+ return (void **&) x;
+# else
+ // Uh oh.
+ ACE_NOTSUP_RETURN (0);
+# endif /* VXWORKS */
+}
+# endif /* ! ACE_HAS_THREAD_SPECIFIC_STORAGE */
+
+ACE_INLINE
+ACE_TSS_Emulation::ACE_TSS_DESTRUCTOR
+ACE_TSS_Emulation::tss_destructor (const ACE_thread_key_t key)
+{
+ ACE_KEY_INDEX (key_index, key);
+ return tss_destructor_ [key_index];
+}
+
+ACE_INLINE
+void
+ACE_TSS_Emulation::tss_destructor (const ACE_thread_key_t key,
+ ACE_TSS_DESTRUCTOR destructor)
+{
+ ACE_KEY_INDEX (key_index, key);
+ tss_destructor_ [key_index] = destructor;
+}
+
+ACE_INLINE
+void *&
+ACE_TSS_Emulation::ts_object (const ACE_thread_key_t key)
+{
+ ACE_KEY_INDEX (key_index, key);
+
+#if defined (ACE_PSOS)
+ u_long tss_base;
+ t_getreg (0, PSOS_TASK_REG_TSS, &tss_base);
+ return ((void **) tss_base)[key_index];
+#else
+# if defined (VXWORKS)
+ /* If someone wants tss_base make sure they get one. This
+ gets used if someone spawns a VxWorks task directly, not
+ through ACE. The allocated array will never be deleted! */
+ if (0 == taskIdCurrent->ACE_VXWORKS_SPARE)
+ {
+ taskIdCurrent->ACE_VXWORKS_SPARE =
+ ACE_reinterpret_cast (int, new void *[ACE_TSS_THREAD_KEYS_MAX]);
+
+ // Zero the entire TSS array. Do it manually instead of using
+ // memset, for optimum speed. Though, memset may be faster :-)
+ void **tss_base_p =
+ ACE_reinterpret_cast (void **, taskIdCurrent->ACE_VXWORKS_SPARE);
+ for (u_int i = 0; i < ACE_TSS_THREAD_KEYS_MAX; ++i, ++tss_base_p)
+ {
+ *tss_base_p = 0;
+ }
+ }
+# endif /* VXWORKS */
+
+ return tss_base ()[key_index];
+#endif /* defined (ACE_PSOS) */
+}
+
+#endif /* ACE_HAS_TSS_EMULATION */
+
+
+ACE_INLINE int
+ACE_OS::thr_getspecific (ACE_thread_key_t key, void **data)
+{
+ // ACE_OS_TRACE ("ACE_OS::thr_getspecific");
+ // If we are using TSS emulation then we shuld use ACE's implementation
+ // of it and not make any PACE calls.
+#if defined (ACE_HAS_PACE) && !defined (ACE_HAS_TSS_EMULATION) && !defined (ACE_WIN32)
+ *data = ::pace_pthread_getspecific (key);
+ return 0;
+#elif defined (ACE_HAS_THREADS)
+# if defined (ACE_HAS_TSS_EMULATION)
+ ACE_KEY_INDEX (key_index, key);
+ if (key_index >= ACE_TSS_Emulation::total_keys ())
+ {
+ errno = EINVAL;
+ data = 0;
+ return -1;
+ }
+ else
+ {
+ *data = ACE_TSS_Emulation::ts_object (key);
+ return 0;
+ }
+# elif defined (ACE_HAS_STHREADS)
+ ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::thr_getspecific (key, data), ace_result_), int, -1);
+# elif defined (ACE_HAS_PTHREADS)
+# if defined (ACE_HAS_PTHREADS_DRAFT4) || defined (ACE_HAS_PTHREADS_DRAFT6)
+ return ::pthread_getspecific (key, data);
+# else /* this is Draft 7 or STD */
+ *data = pthread_getspecific (key);
+ return 0;
+# endif /* ACE_HAS_PTHREADS_DRAFT4, 6 */
+# elif defined (ACE_HAS_WTHREADS)
+
+ // The following handling of errno is designed like this due to
+ // ACE_Log_Msg::instance calling ACE_OS::thr_getspecific.
+ // Basically, it is ok for a system call to reset the error to zero.
+ // (It really shouldn't, though). However, we have to remember to
+ // store errno *immediately* after an error is detected. Calling
+ // ACE_ERROR_RETURN((..., errno)) did not work because errno was
+ // cleared before being passed to the thread-specific instance of
+ // ACE_Log_Msg. The workaround for was to make it so
+ // thr_getspecific did not have the side effect of clearing errno.
+ // The correct fix is for ACE_ERROR_RETURN to store errno
+ //(actually ACE_OS::last_error) before getting the ACE_Log_Msg tss
+ // pointer, which is how it is implemented now. However, other uses
+ // of ACE_Log_Msg may not work correctly, so we're keeping this as
+ // it is for now.
+
+ ACE_Errno_Guard error (errno);
+ *data = ::TlsGetValue (key);
+# if !defined (ACE_HAS_WINCE)
+ if (*data == 0 && (error = ::GetLastError ()) != NO_ERROR)
+
+ return -1;
+ else
+# endif /* ACE_HAS_WINCE */
+ return 0;
+# elif defined (ACE_PSOS) && defined (ACE_PSOS_HAS_TSS)
+ ACE_hthread_t tid;
+ ACE_OS::thr_self (tid);
+ ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::tsd_getval (key, tid, data),
+ ace_result_),
+ int, -1);
+# else
+ ACE_UNUSED_ARG (key);
+ ACE_UNUSED_ARG (data);
+ ACE_NOTSUP_RETURN (-1);
+# endif /* ACE_HAS_STHREADS */
+#else
+ ACE_UNUSED_ARG (key);
+ ACE_UNUSED_ARG (data);
+ ACE_NOTSUP_RETURN (-1);
+#endif /* ACE_HAS_PACE && !ACE_HAS_TSS_EMULATION */
+}
+
+ACE_INLINE int
+ACE_OS::thr_join (ACE_hthread_t thr_handle,
+ void **status)
+{
+ ACE_OS_TRACE ("ACE_OS::thr_join");
+#if defined (ACE_HAS_PACE) && !defined (ACE_WIN32)
+ ACE_OSCALL_RETURN ( ACE_ADAPT_RETVAL (::pace_pthread_join
+ (thr_handle, status),
+ ace_result_), int, -1);
+#elif defined (ACE_HAS_THREADS)
+# if defined (ACE_HAS_STHREADS)
+ ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::thr_join (thr_handle, 0, status), ace_result_),
+ int, -1);
+# elif defined (ACE_HAS_PTHREADS)
+# if defined (ACE_HAS_PTHREADS_DRAFT4) || defined (ACE_HAS_PTHREADS_DRAFT6)
+ int ace_result;
+# if defined (ACE_LACKS_NULL_PTHREAD_STATUS)
+ void *temp;
+ ACE_OSCALL (::pthread_join (thr_handle,
+ status == 0 ? &temp : status),
+ int, -1, ace_result);
+# else
+ ACE_OSCALL (::pthread_join (thr_handle, status), int, -1, ace_result);
+# endif /* ACE_LACKS_NULL_PTHREAD_STATUS */
+ // Joinable threads need to be detached after joining on Pthreads
+ // draft 4 (at least) to reclaim thread storage.
+# if defined (ACE_HAS_PTHREADS_DRAFT4)
+# if defined (HPUX_10)
+ // HP-UX DCE threads' pthread_detach will smash thr_id if it's just given
+ // as an argument. Since the id is still needed, give pthread_detach
+ // a junker to scribble on.
+ ACE_thread_t junker;
+ cma_handle_assign(&thr_handle, &junker);
+ ::pthread_detach (&junker);
+# else
+ ::pthread_detach (&thr_handle);
+# endif /* HPUX_10 */
+# endif /* ACE_HAS_PTHREADS_DRAFT4 */
+
+ return ace_result;
+
+# else
+ ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::pthread_join (thr_handle, status), ace_result_),
+ int, -1);
+# endif /* ACE_HAS_PTHREADS_DRAFT4, 6 */
+# elif defined (ACE_HAS_WTHREADS)
+ void *local_status = 0;
+
+ // Make sure that status is non-NULL.
+ if (status == 0)
+ status = &local_status;
+
+ if (::WaitForSingleObject (thr_handle, INFINITE) == WAIT_OBJECT_0
+ && ::GetExitCodeThread (thr_handle, (LPDWORD) status) != FALSE)
+ {
+ ::CloseHandle (thr_handle);
+ return 0;
+ }
+ ACE_FAIL_RETURN (-1);
+ /* NOTREACHED */
+# elif defined (VXWORKS) || defined (ACE_PSOS)
+ ACE_UNUSED_ARG (thr_handle);
+ ACE_UNUSED_ARG (status);
+ ACE_NOTSUP_RETURN (-1);
+# else
+ ACE_UNUSED_ARG (thr_handle);
+ ACE_UNUSED_ARG (status);
+ ACE_NOTSUP_RETURN (-1);
+# endif /* ACE_HAS_STHREADS */
+#else
+ ACE_UNUSED_ARG (thr_handle);
+ ACE_UNUSED_ARG (status);
+ ACE_NOTSUP_RETURN (-1);
+#endif /* ACE_HAS_PACE */
+}
+
+ACE_INLINE int
+ACE_OS::thr_join (ACE_thread_t waiter_id,
+ ACE_thread_t *thr_id,
+ void **status)
+{
+ ACE_OS_TRACE ("ACE_OS::thr_join");
+#if defined (ACE_HAS_PACE) && !defined (ACE_WIN32)
+ ACE_UNUSED_ARG (thr_id);
+ ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::pace_pthread_join
+ (waiter_id, status),
+ ace_result_), int, -1);
+#elif defined (ACE_HAS_THREADS)
+# if defined (ACE_HAS_STHREADS)
+ ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::thr_join (waiter_id, thr_id, status), ace_result_),
+ int, -1);
+# elif defined (ACE_HAS_PTHREADS)
+ ACE_UNUSED_ARG (thr_id);
+# if defined (ACE_HAS_PTHREADS_DRAFT4) || defined (ACE_HAS_PTHREADS_DRAFT6)
+# if defined (ACE_LACKS_NULL_PTHREAD_STATUS)
+ void *temp;
+ ACE_OSCALL_RETURN (::pthread_join (waiter_id,
+ status == 0 ? &temp : status), int, -1);
+# else
+ ACE_OSCALL_RETURN (::pthread_join (waiter_id, status), int, -1);
+# endif
+# else
+ ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::pthread_join (waiter_id, status), ace_result_),
+ int, -1);
+# endif /* ACE_HAS_PTHREADS_DRAFT4, 6 */
+# elif defined (ACE_HAS_WTHREADS)
+ ACE_UNUSED_ARG (waiter_id);
+ ACE_UNUSED_ARG (thr_id);
+ ACE_UNUSED_ARG (status);
+
+ // This could be implemented if the DLL-Main function or the
+ // task exit base class some log the threads which have exited
+ ACE_NOTSUP_RETURN (-1);
+# elif defined (VXWORKS) || defined (ACE_PSOS)
+ ACE_UNUSED_ARG (waiter_id);
+ ACE_UNUSED_ARG (thr_id);
+ ACE_UNUSED_ARG (status);
+ ACE_NOTSUP_RETURN (-1);
+# endif /* ACE_HAS_STHREADS */
+#else
+ ACE_UNUSED_ARG (waiter_id);
+ ACE_UNUSED_ARG (thr_id);
+ ACE_UNUSED_ARG (status);
+ ACE_NOTSUP_RETURN (-1);
+#endif /* ACE_HAS_PACE */
+}
+
+ACE_INLINE int
+ACE_OS::thr_setcancelstate (int new_state, int *old_state)
+{
+ ACE_OS_TRACE ("ACE_OS::thr_setcancelstate");
+#if defined (ACE_HAS_PACE) && !defined (ACE_WIN32)
+ ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::pace_pthread_setcancelstate
+ (new_state, old_state),
+ ace_result_), int, -1);
+#elif defined (ACE_HAS_THREADS)
+# if defined (ACE_HAS_PTHREADS) && !defined (ACE_LACKS_PTHREAD_CANCEL)
+# if defined (ACE_HAS_PTHREADS_DRAFT4)
+ int old;
+ old = pthread_setcancel (new_state);
+ if (old == -1)
+ return -1;
+ *old_state = old;
+ return 0;
+# elif defined (ACE_HAS_PTHREADS_DRAFT6)
+ ACE_UNUSED_ARG(old_state);
+ ACE_OSCALL_RETURN (pthread_setintr (new_state), int, -1);
+# else /* this is draft 7 or std */
+ ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::pthread_setcancelstate (new_state,
+ old_state),
+ ace_result_),
+ int, -1);
+# endif /* ACE_HAS_PTHREADS_DRAFT4 */
+# elif defined (ACE_HAS_STHREADS)
+ ACE_UNUSED_ARG (new_state);
+ ACE_UNUSED_ARG (old_state);
+ ACE_NOTSUP_RETURN (-1);
+# elif defined (ACE_HAS_WTHREADS)
+ ACE_UNUSED_ARG (new_state);
+ ACE_UNUSED_ARG (old_state);
+ ACE_NOTSUP_RETURN (-1);
+# else /* Could be ACE_HAS_PTHREADS && ACE_LACKS_PTHREAD_CANCEL */
+ ACE_UNUSED_ARG (new_state);
+ ACE_UNUSED_ARG (old_state);
+ ACE_NOTSUP_RETURN (-1);
+# endif /* ACE_HAS_PTHREADS */
+#else
+ ACE_UNUSED_ARG (new_state);
+ ACE_UNUSED_ARG (old_state);
+ ACE_NOTSUP_RETURN (-1);
+#endif /* ACE_HAS_PACE */
+}
+
+ACE_INLINE int
+ACE_OS::thr_setcanceltype (int new_type, int *old_type)
+{
+ ACE_OS_TRACE ("ACE_OS::thr_setcanceltype");
+#if defined (ACE_HAS_PACE) && !defined (ACE_WIN32)
+ ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::pace_pthread_setcanceltype
+ (new_type, old_type),
+ ace_result_), int, -1);
+#elif defined (ACE_HAS_THREADS)
+# if defined (ACE_HAS_PTHREADS) && !defined (ACE_LACKS_PTHREAD_CANCEL)
+# if defined (ACE_HAS_PTHREADS_DRAFT4)
+ int old;
+ old = pthread_setasynccancel(new_type);
+ if (old == -1)
+ return -1;
+ *old_type = old;
+ return 0;
+# elif defined (ACE_HAS_PTHREADS_DRAFT6)
+ ACE_UNUSED_ARG(old_type);
+ ACE_OSCALL_RETURN (pthread_setintrtype (new_type), int, -1);
+# else /* this is draft 7 or std */
+ ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::pthread_setcanceltype (new_type,
+ old_type),
+ ace_result_),
+ int, -1);
+# endif /* ACE_HAS_PTHREADS_DRAFT4 */
+# else /* Could be ACE_HAS_PTHREADS && ACE_LACKS_PTHREAD_CANCEL */
+ ACE_UNUSED_ARG (new_type);
+ ACE_UNUSED_ARG (old_type);
+ ACE_NOTSUP_RETURN (-1);
+# endif /* ACE_HAS_PTHREADS */
+#else
+ ACE_UNUSED_ARG (new_type);
+ ACE_UNUSED_ARG (old_type);
+ ACE_NOTSUP_RETURN (-1);
+#endif /* ACE_HAS_PACE */
+}
+
+ACE_INLINE int
+ACE_OS::thr_cancel (ACE_thread_t thr_id)
+{
+ ACE_OS_TRACE ("ACE_OS::thr_cancel");
+#if defined (ACE_HAS_PACE) && !defined (ACE_WIN32)
+ ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::pace_pthread_cancel (thr_id),
+ ace_result_), int, -1);
+#elif defined (ACE_HAS_THREADS)
+# if defined (ACE_HAS_PTHREADS) && !defined (ACE_LACKS_PTHREAD_CANCEL)
+# if defined (ACE_HAS_PTHREADS_DRAFT4) || defined (ACE_HAS_PTHREADS_DRAFT6)
+ ACE_OSCALL_RETURN (::pthread_cancel (thr_id), int, -1);
+# else
+ ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::pthread_cancel (thr_id),
+ ace_result_),
+ int, -1);
+# endif /* ACE_HAS_PTHREADS_DRAFT4 || ACE_HAS_PTHREADS_DRAFT6 */
+# else /* Could be ACE_HAS_PTHREADS && ACE_LACKS_PTHREAD_CANCEL */
+ ACE_UNUSED_ARG (thr_id);
+ ACE_NOTSUP_RETURN (-1);
+# endif /* ACE_HAS_PTHREADS */
+#else
+ ACE_UNUSED_ARG (thr_id);
+ ACE_NOTSUP_RETURN (-1);
+#endif /* ACE_HAS_PACE */
+}
+
+ACE_INLINE int
+ACE_OS::sigwait (sigset_t *set, int *sig)
+{
+ ACE_OS_TRACE ("ACE_OS::sigwait");
+ int local_sig;
+ if (sig == 0)
+ sig = &local_sig;
+#if defined (ACE_HAS_PACE) && !defined (ACE_WIN32)
+ errno = ::pace_sigwait (set, sig);
+ return errno == 0 ? *sig : -1;
+#elif defined (ACE_HAS_THREADS)
+# if (defined (__FreeBSD__) && (__FreeBSD__ < 3)) || defined (CHORUS) || defined (ACE_PSOS) || defined (__MACOSX__)
+ ACE_UNUSED_ARG (set);
+ ACE_NOTSUP_RETURN (-1);
+# elif (defined (ACE_HAS_STHREADS) && !defined (_POSIX_PTHREAD_SEMANTICS))
+ *sig = ::sigwait (set);
+ return *sig;
+# elif defined (ACE_HAS_PTHREADS)
+ // LynxOS and Digital UNIX have their own hoops to jump through.
+# if defined (__Lynx__)
+ // Second arg is a void **, which we don't need (the selected
+ // signal number is returned).
+ *sig = ::sigwait (set, 0);
+ return *sig;
+# elif defined (DIGITAL_UNIX) && defined (__DECCXX_VER)
+ // DEC cxx (but not g++) needs this direct call to its internal
+ // sigwait (). This allows us to #undef sigwait, so that we can
+ // have ACE_OS::sigwait. cxx gets confused by ACE_OS::sigwait
+ // if sigwait is _not_ #undef'ed.
+ errno = ::_Psigwait (set, sig);
+ return errno == 0 ? *sig : -1;
+# else /* ! __Lynx __ && ! (DIGITAL_UNIX && __DECCXX_VER) */
+# if (defined (ACE_HAS_PTHREADS_DRAFT4) || (defined (ACE_HAS_PTHREADS_DRAFT6)) && !defined(ACE_HAS_FSU_PTHREADS)) || (defined (_UNICOS) && _UNICOS == 9)
+# if defined (HPUX_10)
+ *sig = cma_sigwait (set);
+# else
+ *sig = ::sigwait (set);
+# endif /* HPUX_10 */
+ return *sig;
+# elif defined(ACE_HAS_FSU_PTHREADS)
+ return ::sigwait (set, sig);
+# else /* this is draft 7 or std */
+ errno = ::sigwait (set, sig);
+ return errno == 0 ? *sig : -1;
+# endif /* ACE_HAS_PTHREADS_DRAFT4, 6 */
+# endif /* ! __Lynx__ && ! (DIGITAL_UNIX && __DECCXX_VER) */
+# elif defined (ACE_HAS_WTHREADS)
+ ACE_UNUSED_ARG (set);
+ ACE_NOTSUP_RETURN (-1);
+# elif defined (VXWORKS)
+ // Second arg is a struct siginfo *, which we don't need (the
+ // selected signal number is returned). Third arg is timeout: 0
+ // means forever.
+ *sig = ::sigtimedwait (set, 0, 0);
+ return *sig;
+# endif /* __FreeBSD__ */
+#else
+ ACE_UNUSED_ARG (set);
+ ACE_UNUSED_ARG (sig);
+ ACE_NOTSUP_RETURN (-1);
+#endif /* ACE_HAS_PACE */
+}
+
+ACE_INLINE int
+ACE_OS::sigtimedwait (const sigset_t *set,
+ siginfo_t *info,
+ const ACE_Time_Value *timeout)
+{
+ ACE_OS_TRACE ("ACE_OS::sigtimedwait");
+#if defined (ACE_HAS_PACE) && !defined (ACE_WIN32)
+ timespec ts;
+ timespec *tsp;
+ if (timeout !=0)
+ {
+ ts = *timeout;
+ tsp = &ts;
+ }
+ else
+ tsp = 0;
+ ACE_OSCALL_RETURN (::pace_sigtimedwait (set, info, tsp),
+ int, -1);
+#elif defined (ACE_HAS_SIGTIMEDWAIT)
+ timespec_t ts;
+ timespec_t *tsp;
+
+ if (timeout != 0)
+ {
+ ts = *timeout; // Calls ACE_Time_Value::operator timespec_t().
+ tsp = &ts;
+ }
+ else
+ tsp = 0;
+
+ ACE_OSCALL_RETURN (::sigtimedwait (set, info, tsp),
+ int, -1);
+#else
+ ACE_UNUSED_ARG (set);
+ ACE_UNUSED_ARG (info);
+ ACE_UNUSED_ARG (timeout);
+ ACE_NOTSUP_RETURN (-1);
+#endif /* ACE_HAS_PACE */
+}
+
+ACE_INLINE void
+ACE_OS::thr_testcancel (void)
+{
+ ACE_OS_TRACE ("ACE_OS::thr_testcancel");
+#if defined (ACE_HAS_THREADS)
+# if defined (ACE_HAS_PTHREADS) && !defined (ACE_LACKS_PTHREAD_CANCEL)
+#if defined(ACE_HAS_PTHREADS_DRAFT6)
+ ::pthread_testintr ();
+#else /* ACE_HAS_PTHREADS_DRAFT6 */
+ ::pthread_testcancel ();
+#endif /* !ACE_HAS_PTHREADS_DRAFT6 */
+# elif defined (ACE_HAS_STHREADS)
+# elif defined (ACE_HAS_WTHREADS)
+# elif defined (VXWORKS) || defined (ACE_PSOS)
+# else
+ // no-op: can't use ACE_NOTSUP_RETURN because there is no return value
+# endif /* ACE_HAS_PTHREADS */
+#else
+#endif /* ACE_HAS_THREADS */
+}
+
+ACE_INLINE int
+ACE_OS::thr_sigsetmask (int how,
+ const sigset_t *nsm,
+ sigset_t *osm)
+{
+ ACE_OS_TRACE ("ACE_OS::thr_sigsetmask");
+#if defined (ACE_HAS_PACE) && !defined (ACE_WIN32)
+ ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::pace_pthread_sigmask
+ (how, nsm, osm),
+ ace_result_), int, -1);
+#elif defined (ACE_HAS_THREADS)
+# if defined (ACE_LACKS_PTHREAD_THR_SIGSETMASK)
+ // DCE threads and Solaris 2.4 have no such function.
+ ACE_UNUSED_ARG (osm);
+ ACE_UNUSED_ARG (nsm);
+ ACE_UNUSED_ARG (how);
+
+ ACE_NOTSUP_RETURN (-1);
+# elif defined (ACE_HAS_SIGTHREADMASK)
+ ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::sigthreadmask (how, nsm, osm),
+ ace_result_), int, -1);
+# elif defined (ACE_HAS_STHREADS)
+ ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::thr_sigsetmask (how, nsm, osm),
+ ace_result_),
+ int, -1);
+# elif defined (ACE_HAS_PTHREADS)
+# if defined (AIX)
+ ACE_OSCALL_RETURN (sigthreadmask (how, nsm, osm), int, -1);
+ // Draft 4 and 6 implementations will sometimes have a sigprocmask () that
+ // modifies the calling thread's mask only. If this is not so for your
+ // platform, define ACE_LACKS_PTHREAD_THR_SIGSETMASK.
+# elif defined(ACE_HAS_PTHREADS_DRAFT4) || \
+ defined (ACE_HAS_PTHREADS_DRAFT6) || (defined (_UNICOS) && _UNICOS == 9)
+ ACE_OSCALL_RETURN (::sigprocmask (how, nsm, osm), int, -1);
+# elif !defined (ACE_LACKS_PTHREAD_SIGMASK)
+ ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::pthread_sigmask (how, nsm, osm),
+ ace_result_), int, -1);
+# endif /* AIX */
+
+#if 0
+ /* Don't know if anyt platform actually needs this... */
+ // as far as I can tell, this is now pthread_sigaction() -- jwr
+ ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::pthread_sigaction (how, nsm, osm),
+ ace_result_), int, -1);
+#endif /* 0 */
+
+# elif defined (ACE_HAS_WTHREADS) || defined (ACE_PSOS)
+ ACE_UNUSED_ARG (osm);
+ ACE_UNUSED_ARG (nsm);
+ ACE_UNUSED_ARG (how);
+
+ ACE_NOTSUP_RETURN (-1);
+# elif defined (VXWORKS)
+ switch (how)
+ {
+ case SIG_BLOCK:
+ case SIG_UNBLOCK:
+ {
+ // get the old mask
+ *osm = ::sigsetmask (*nsm);
+ // create a new mask: the following assumes that sigset_t is 4 bytes,
+ // which it is on VxWorks 5.2, so bit operations are done simply . . .
+ ::sigsetmask (how == SIG_BLOCK ? (*osm |= *nsm) : (*osm &= ~*nsm));
+ break;
+ }
+ case SIG_SETMASK:
+ *osm = ::sigsetmask (*nsm);
+ break;
+ default:
+ return -1;
+ }
+
+ return 0;
+# else /* Should not happen. */
+ ACE_UNUSED_ARG (how);
+ ACE_UNUSED_ARG (nsm);
+ ACE_UNUSED_ARG (osm);
+ ACE_NOTSUP_RETURN (-1);
+# endif /* ACE_LACKS_PTHREAD_THR_SIGSETMASK */
+#else
+ ACE_UNUSED_ARG (how);
+ ACE_UNUSED_ARG (nsm);
+ ACE_UNUSED_ARG (osm);
+ ACE_NOTSUP_RETURN (-1);
+#endif /* ACE_HAS_PACE */
+}
+
+ACE_INLINE int
+ACE_OS::thr_kill (ACE_thread_t thr_id, int signum)
+{
+ ACE_OS_TRACE ("ACE_OS::thr_kill");
+#if defined (ACE_HAS_PACE) && !defined (ACE_WIN32)
+ ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::pace_pthread_kill (thr_id, signum),
+ ace_result_), int, -1);
+#elif defined (ACE_HAS_THREADS)
+# if defined (ACE_HAS_PTHREADS)
+# if defined (ACE_HAS_PTHREADS_DRAFT4) || defined(ACE_LACKS_PTHREAD_KILL)
+ ACE_UNUSED_ARG (signum);
+ ACE_UNUSED_ARG (thr_id);
+ ACE_NOTSUP_RETURN (-1);
+# else
+ ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::pthread_kill (thr_id, signum),
+ ace_result_),
+ int, -1);
+# endif /* ACE_HAS_PTHREADS_DRAFT4 */
+# elif defined (ACE_HAS_STHREADS)
+ ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::thr_kill (thr_id, signum),
+ ace_result_),
+ int, -1);
+# elif defined (ACE_HAS_WTHREADS) || defined (ACE_PSOS)
+ ACE_UNUSED_ARG (signum);
+ ACE_UNUSED_ARG (thr_id);
+
+ ACE_NOTSUP_RETURN (-1);
+# elif defined (VXWORKS)
+ ACE_hthread_t tid;
+ ACE_OSCALL (::taskNameToId (thr_id), int, ERROR, tid);
+
+ if (tid == ERROR)
+ return -1;
+ else
+ ACE_OSCALL_RETURN (::kill (tid, signum), int, -1);
+
+# else /* This should not happen! */
+ ACE_UNUSED_ARG (thr_id);
+ ACE_UNUSED_ARG (signum);
+ ACE_NOTSUP_RETURN (-1);
+# endif /* ACE_HAS_STHREADS */
+#else
+ ACE_UNUSED_ARG (thr_id);
+ ACE_UNUSED_ARG (signum);
+ ACE_NOTSUP_RETURN (-1);
+#endif /* ACE_HAS_PACE */
+}
+
+ACE_INLINE size_t
+ACE_OS::thr_min_stack (void)
+{
+ ACE_OS_TRACE ("ACE_OS::thr_min_stack");
+#if defined (ACE_HAS_THREADS)
+# if defined (ACE_HAS_STHREADS)
+# if defined (ACE_HAS_THR_MINSTACK)
+ // Tandem did some weirdo mangling of STHREAD names...
+ ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::thr_minstack (),
+ ace_result_),
+ int, -1);
+# else
+ ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::thr_min_stack (),
+ ace_result_),
+ int, -1);
+# endif /* !ACE_HAS_THR_MINSTACK */
+# elif defined (ACE_HAS_PTHREADS)
+# if defined (_SC_THREAD_STACK_MIN)
+ return (size_t) ACE_OS::sysconf (_SC_THREAD_STACK_MIN);
+# elif defined (PTHREAD_STACK_MIN)
+ return PTHREAD_STACK_MIN;
+# else
+ ACE_NOTSUP_RETURN (0);
+# endif /* _SC_THREAD_STACK_MIN */
+# elif defined (ACE_HAS_WTHREADS)
+ ACE_NOTSUP_RETURN (0);
+# elif defined (ACE_PSOS)
+ // there does not appear to be a way to get the
+ // task stack size except at task creation
+ ACE_NOTSUP_RETURN (0);
+# elif defined (VXWORKS)
+ TASK_DESC taskDesc;
+ STATUS status;
+
+ ACE_hthread_t tid;
+ ACE_OS::thr_self (tid);
+
+# if defined (ACE_HAS_PACE)
+ // pthread_min_stack is not a POSIX function. So use the thread ID from
+ // the pace_pthread_t structure.
+ ACE_OSCALL (ACE_ADAPT_RETVAL (::taskInfoGet (tid->tid, &taskDesc),
+ status),
+ STATUS, -1, status);
+# else
+ ACE_OSCALL (ACE_ADAPT_RETVAL (::taskInfoGet (tid, &taskDesc),
+ status),
+ STATUS, -1, status);
+# endif /* ACE_HAS_PACE */
+ return status == OK ? taskDesc.td_stackSize : 0;
+# else /* Should not happen... */
+ ACE_NOTSUP_RETURN (0);
+# endif /* ACE_HAS_STHREADS */
+#else
+ ACE_NOTSUP_RETURN (0);
+#endif /* ACE_HAS_THREADS */
+}
+
+ACE_INLINE int
+ACE_OS::thr_setconcurrency (int hint)
+{
+ ACE_OS_TRACE ("ACE_OS::thr_setconcurrency");
+#if defined (ACE_HAS_THREADS)
+# if defined (ACE_HAS_STHREADS)
+ ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::thr_setconcurrency (hint),
+ ace_result_),
+ int, -1);
+# elif defined (ACE_HAS_PTHREADS)
+ ACE_UNUSED_ARG (hint);
+ ACE_NOTSUP_RETURN (-1);
+# elif defined (ACE_HAS_WTHREADS)
+ ACE_UNUSED_ARG (hint);
+
+ ACE_NOTSUP_RETURN (-1);
+# elif defined (VXWORKS) || defined (ACE_PSOS)
+ ACE_UNUSED_ARG (hint);
+ ACE_NOTSUP_RETURN (-1);
+# endif /* ACE_HAS_STHREADS */
+#else
+ ACE_UNUSED_ARG (hint);
+ ACE_NOTSUP_RETURN (-1);
+#endif /* ACE_HAS_THREADS */
+}
+
+ACE_INLINE int
+ACE_OS::thr_setprio (ACE_hthread_t thr_id, int prio)
+{
+ ACE_OS_TRACE ("ACE_OS::thr_setprio");
+#if defined (ACE_HAS_PACE) && !defined (ACE_WIN32)
+ struct sched_param param;
+ int policy = 0;
+ int result;
+ ACE_OSCALL (ACE_ADAPT_RETVAL (::pace_pthread_getschedparam
+ (thr_id, &policy, &param),
+ result), int, -1, result);
+
+ if (result == -1)
+ return result; // error in pthread_getschedparam
+ param.sched_priority = prio;
+# if defined (ACE_WIN32)
+ int ace_result_ = 0;
+# endif /* ACE_WIN32 */
+ ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::pace_pthread_setschedparam
+ (thr_id, policy, &param),
+ ace_result_), int, -1);
+#elif defined (ACE_HAS_THREADS)
+# if (defined (ACE_HAS_PTHREADS) && !defined (ACE_LACKS_SETSCHED))
+
+# if defined (ACE_HAS_PTHREADS_DRAFT4)
+ int result;
+ result = ::pthread_setprio(thr_id, prio);
+ return (result == -1 ? -1 : 0);
+# elif defined (ACE_HAS_PTHREADS_DRAFT6)
+ pthread_attr_t attr;
+ if (pthread_getschedattr (thr_id, &attr) == -1)
+ return -1;
+ if (pthread_attr_setprio (attr, prio) == -1)
+ return -1;
+ return pthread_setschedattr (thr_id, attr);
+# else
+ struct sched_param param;
+ int policy = 0;
+ int result;
+
+ ACE_OSCALL (ACE_ADAPT_RETVAL (::pthread_getschedparam (thr_id, &policy, &param),
+ result), // not sure if use of result here is cool, cjc
+ int, -1, result);
+ if (result == -1)
+ return result; // error in pthread_getschedparam
+ param.sched_priority = prio;
+ ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::pthread_setschedparam (thr_id, policy, &param),
+ result),
+ int, -1);
+# endif /* ACE_HAS_PTHREADS_DRAFT4 */
+# elif defined (ACE_HAS_STHREADS)
+ ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::thr_setprio (thr_id, prio),
+ ace_result_),
+ int, -1);
+# elif defined (ACE_HAS_WTHREADS)
+ ACE_WIN32CALL_RETURN (ACE_ADAPT_RETVAL (::SetThreadPriority (thr_id, prio),
+ ace_result_),
+ int, -1);
+# elif defined (ACE_PSOS)
+ u_long oldprio;
+ ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::t_setpri (thr_id, prio, &oldprio),
+ ace_result_),
+ int, -1);
+# elif defined (VXWORKS)
+ ACE_OSCALL_RETURN (::taskPrioritySet (thr_id, prio), int, -1);
+# else
+ // For example, platforms that support Pthreads but LACK_SETSCHED.
+ ACE_UNUSED_ARG (thr_id);
+ ACE_UNUSED_ARG (prio);
+ ACE_NOTSUP_RETURN (-1);
+# endif /* ACE_HAS_STHREADS */
+#else
+ ACE_UNUSED_ARG (thr_id);
+ ACE_UNUSED_ARG (prio);
+ ACE_NOTSUP_RETURN (-1);
+#endif /* ACE_HAS_PACE */
+}
+
+ACE_INLINE int
+ACE_OS::thr_suspend (ACE_hthread_t target_thread)
+{
+ ACE_OS_TRACE ("ACE_OS::thr_suspend");
+#if defined (ACE_HAS_THREADS)
+# if defined (ACE_HAS_STHREADS)
+ ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::thr_suspend (target_thread), ace_result_), int, -1);
+# elif defined (ACE_HAS_PTHREADS)
+# if defined (ACE_HAS_PTHREADS_UNIX98_EXT)
+ ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (pthread_suspend (target_thread),
+ ace_result_),
+ int, -1);
+# else
+ ACE_UNUSED_ARG (target_thread);
+ ACE_NOTSUP_RETURN (-1);
+# endif /* ACE_HAS_PTHREADS_UNIX98_EXT */
+# elif defined (ACE_HAS_WTHREADS)
+ if (::SuspendThread (target_thread) != ACE_SYSCALL_FAILED)
+ return 0;
+ else
+ ACE_FAIL_RETURN (-1);
+ /* NOTREACHED */
+# elif defined (ACE_PSOS)
+ ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::t_suspend (target_thread), ace_result_), int, -1);
+# elif defined (VXWORKS)
+# if defined (ACE_HAS_PACE)
+ // pthread_suspend (like pthread_continue) is not an official POSIX
+ // function. We get this for free with ACE. So use the thread ID from
+ // the pace_pthread_t structure.
+ ACE_OSCALL_RETURN (::taskSuspend (target_thread->tid), int, -1);
+# else
+ ACE_OSCALL_RETURN (::taskSuspend (target_thread), int, -1);
+# endif /* ACE_HAS_PACE */
+# endif /* ACE_HAS_STHREADS */
+#else
+ ACE_UNUSED_ARG (target_thread);
+ ACE_NOTSUP_RETURN (-1);
+#endif /* ACE_HAS_THREADS */
+}
+
+ACE_INLINE void
+ACE_OS::thr_yield (void)
+{
+ ACE_OS_TRACE ("ACE_OS::thr_yield");
+#if defined (ACE_HAS_PACE) && !defined (ACE_WIN32)
+ ::pace_sched_yield ();
+#elif defined (ACE_HAS_THREADS)
+# if defined (ACE_HAS_PTHREADS)
+# if defined (ACE_HAS_PTHREADS_STD)
+ // Note - this is a POSIX.4 function - not a POSIX.1c function...
+ ::sched_yield ();
+# elif defined (ACE_HAS_PTHREADS_DRAFT6)
+ ::pthread_yield (NULL);
+# else /* Draft 4 and 7 */
+ ::pthread_yield ();
+# endif /* ACE_HAS_PTHREADS_STD */
+# elif defined (ACE_HAS_STHREADS)
+ ::thr_yield ();
+# elif defined (ACE_HAS_WTHREADS)
+ ::Sleep (0);
+# elif defined (VXWORKS)
+ // An argument of 0 to ::taskDelay doesn't appear to yield the
+ // current thread.
+ // Now, it does seem to work. The context_switch_time test
+ // works fine with task_delay set to 0.
+ ::taskDelay (0);
+# endif /* ACE_HAS_STHREADS */
+#else
+ ;
+#endif /* ACE_HAS_PACE */
+}
+
+ACE_INLINE int
+ACE_OS::priority_control (ACE_idtype_t idtype, ACE_id_t id, int cmd, void *arg)
+{
+ ACE_OS_TRACE ("ACE_OS::priority_control");
+#if defined (ACE_HAS_PRIOCNTL)
+ ACE_OSCALL_RETURN (priocntl (idtype, id, cmd, ACE_static_cast (caddr_t, arg)),
+ int, -1);
+#else /* ! ACE_HAS_PRIOCNTL*/
+ ACE_UNUSED_ARG (idtype);
+ ACE_UNUSED_ARG (id);
+ ACE_UNUSED_ARG (cmd);
+ ACE_UNUSED_ARG (arg);
+ ACE_NOTSUP_RETURN (-1);
+#endif /* ! ACE_HAS_PRIOCNTL*/
+}
+
+ACE_INLINE void
+ACE_OS::rewind (FILE *fp)
+{
+#if defined (ACE_HAS_PACE)
+ ::pace_rewind (fp);
+#elif !defined (ACE_HAS_WINCE)
+ ACE_OS_TRACE ("ACE_OS::rewind");
+ ::rewind (fp);
+#else
+ // In WinCE, "FILE *" is actually a HANDLE.
+ ::SetFilePointer (fp, 0L, 0L, FILE_BEGIN);
+#endif /* ACE_HAS_PACE */
+}
+
+ACE_INLINE ssize_t
+ACE_OS::readv (ACE_HANDLE handle,
+ iovec *iov,
+ int iovlen)
+{
+ ACE_OS_TRACE ("ACE_OS::readv");
+#if defined (ACE_LACKS_READV)
+ ACE_OSCALL_RETURN (ACE_OS::readv_emulation (handle, iov, iovlen),
+ ssize_t,
+ -1);
+#else /* ACE_LACKS_READV */
+ ACE_OSCALL_RETURN (::readv (handle, iov, iovlen), ssize_t, -1);
+#endif /* ACE_LACKS_READV */
+}
+
+ACE_INLINE ssize_t
+ACE_OS::writev (ACE_HANDLE handle,
+ const iovec *iov,
+ int iovcnt)
+{
+ ACE_OS_TRACE ("ACE_OS::writev");
+#if defined (ACE_LACKS_WRITEV)
+ ACE_OSCALL_RETURN (ACE_OS::writev_emulation (handle,
+ (ACE_WRITEV_TYPE *) iov,
+ iovcnt), int, -1);
+#else /* ACE_LACKS_WRITEV */
+ ACE_OSCALL_RETURN (::writev (handle,
+ (ACE_WRITEV_TYPE *) iov,
+ iovcnt), int, -1);
+#endif /* ACE_LACKS_WRITEV */
+}
+
+ACE_INLINE ssize_t
+ACE_OS::recvv (ACE_HANDLE handle,
+ iovec *buffers,
+ int n)
+{
+#if defined (ACE_HAS_WINSOCK2)
+
+ DWORD bytes_received = 0;
+ int result = 1;
+
+ // Winsock 2 has WSARecv and can do this directly, but Winsock 1 needs
+ // to do the recvs piece-by-piece.
+
+# if (ACE_HAS_WINSOCK2 != 0)
+ DWORD flags = 0;
+ result = ::WSARecv ((SOCKET) handle,
+ (WSABUF *) buffers,
+ n,
+ &bytes_received,
+ &flags,
+ 0,
+ 0);
+# else
+ int i, chunklen;
+ char *chunkp = 0;
+
+ // Step through the buffers requested by caller; for each one, cycle
+ // through reads until it's filled or an error occurs.
+ for (i = 0; i < n && result > 0; i++)
+ {
+ chunkp = buffers[i].iov_base; // Point to part of chunk being read
+ chunklen = buffers[i].iov_len; // Track how much to read to chunk
+ while (chunklen > 0 && result > 0)
+ {
+ result = ::recv ((SOCKET) handle, chunkp, chunklen, 0);
+ if (result > 0)
+ {
+ chunkp += result;
+ chunklen -= result;
+ bytes_received += result;
+ }
+ }
+ }
+# endif /* ACE_HAS_WINSOCK2 != 0 */
+
+ if (result == SOCKET_ERROR)
+ {
+ ACE_OS::set_errno_to_wsa_last_error ();
+ return -1;
+ }
+ else
+ return (ssize_t) bytes_received;
+#else
+ return ACE_OS::readv (handle, buffers, n);
+#endif /* ACE_HAS_WINSOCK2 */
+}
+
+ACE_INLINE ssize_t
+ACE_OS::sendv (ACE_HANDLE handle,
+ const iovec *buffers,
+ int n)
+{
+#if defined (ACE_HAS_WINSOCK2)
+ DWORD bytes_sent = 0;
+ int result = 0;
+
+ // Winsock 2 has WSASend and can do this directly, but Winsock 1
+ // needs to do the sends one-by-one.
+# if (ACE_HAS_WINSOCK2 != 0)
+ result = ::WSASend ((SOCKET) handle,
+ (WSABUF *) buffers,
+ n,
+ &bytes_sent,
+ 0,
+ 0,
+ 0);
+# else
+ int i;
+ for (i = 0; i < n && result != SOCKET_ERROR; i++)
+ {
+ result = ::send ((SOCKET) handle,
+ buffers[i].iov_base,
+ buffers[i].iov_len,
+ 0);
+ bytes_sent += buffers[i].iov_len; // Gets ignored on error anyway
+ }
+# endif /* ACE_HAS_WINSOCK2 != 0 */
+
+ if (result == SOCKET_ERROR)
+ {
+ ACE_OS::set_errno_to_wsa_last_error ();
+ return -1;
+ }
+ else
+ return (ssize_t) bytes_sent;
+
+#else
+ return ACE_OS::writev (handle, buffers, n);
+#endif /* ACE_HAS_WINSOCK2 */
+}
+
+ACE_INLINE int
+ACE_OS::poll (struct pollfd *pollfds, u_long len, const ACE_Time_Value *timeout)
+{
+ ACE_OS_TRACE ("ACE_OS::poll");
+#if defined (ACE_HAS_POLL)
+ int to = timeout == 0 ? -1 : int (timeout->msec ());
+ ACE_OSCALL_RETURN (::poll (pollfds, len, to), int, -1);
+#else
+ ACE_UNUSED_ARG (timeout);
+ ACE_UNUSED_ARG (len);
+ ACE_UNUSED_ARG (pollfds);
+
+ ACE_NOTSUP_RETURN (-1);
+#endif /* ACE_HAS_POLL */
+}
+
+ACE_INLINE int
+ACE_OS::poll (struct pollfd *pollfds, u_long len, const ACE_Time_Value &timeout)
+{
+ ACE_OS_TRACE ("ACE_OS::poll");
+#if defined (ACE_HAS_POLL)
+ ACE_OSCALL_RETURN (::poll (pollfds, len, int (timeout.msec ())), int, -1);
+#else
+ ACE_UNUSED_ARG (timeout);
+ ACE_UNUSED_ARG (len);
+ ACE_UNUSED_ARG (pollfds);
+
+ ACE_NOTSUP_RETURN (-1);
+#endif /* ACE_HAS_POLL */
+}
+
+ACE_INLINE char *
+ACE_OS::compile (const char *instring, char *expbuf, char *endbuf)
+{
+ ACE_OS_TRACE ("ACE_OS::compile");
+#if defined (ACE_HAS_REGEX)
+ ACE_OSCALL_RETURN (::compile (instring, expbuf, endbuf), char *, 0);
+#else
+ ACE_UNUSED_ARG (instring);
+ ACE_UNUSED_ARG (expbuf);
+ ACE_UNUSED_ARG (endbuf);
+
+ ACE_NOTSUP_RETURN (0);
+#endif /* ACE_HAS_REGEX */
+}
+
+ACE_INLINE long
+ACE_OS::filesize (const ACE_TCHAR *filename)
+{
+ ACE_OS_TRACE ("ACE_OS::filesize");
+
+ ACE_HANDLE h = ACE_OS::open (filename, O_RDONLY);
+ if (h != ACE_INVALID_HANDLE)
+ {
+ long size = ACE_OS::filesize (h);
+ ACE_OS::close (h);
+ return size;
+ }
+ else
+ return -1;
+}
+
+ACE_INLINE int
+ACE_OS::closesocket (ACE_HANDLE handle)
+{
+ ACE_OS_TRACE ("ACE_OS::closesocket");
+#if defined (ACE_WIN32)
+ ACE_SOCKCALL_RETURN (::closesocket ((SOCKET) handle), int, -1);
+#elif defined (ACE_PSOS_DIAB_PPC)
+ ACE_OSCALL_RETURN (::pna_close (handle), int, -1);
+#else
+ ACE_OSCALL_RETURN (::close (handle), int, -1);
+#endif /* ACE_WIN32 */
+}
+
+ACE_INLINE int
+ACE_OS::access (const char *path, int amode)
+{
+ ACE_OS_TRACE ("ACE_OS::access");
+#if defined (ACE_HAS_PACE)
+ ACE_OSCALL_RETURN (::pace_access (path, amode), int, -1);
+#elif defined (ACE_LACKS_ACCESS)
+ ACE_UNUSED_ARG (path);
+ ACE_UNUSED_ARG (amode);
+ ACE_NOTSUP_RETURN (-1);
+#elif defined (ACE_HAS_WINCE)
+ // @@ WINCE: There should be a Win32 API that can do this.
+ // Hard coded read access here.
+ FILE* handle = ACE_OS::fopen (path, ACE_LIB_TEXT ("r"));
+ ACE_UNUSED_ARG (amode);
+
+ ACE_OS::fclose (handle);
+ return (handle == ACE_INVALID_HANDLE ? -1 : 0);
+#else
+ ACE_OSCALL_RETURN (::access (path, amode), int, -1);
+#endif /* ACE_HAS_PACE */
+}
+
+
+#if defined (ACE_HAS_WCHAR)
+ACE_INLINE int
+ACE_OS::access (const wchar_t *path, int amode)
+{
+#if defined (ACE_WIN32) && !defined (ACE_HAS_WINCE)
+ ACE_OSCALL_RETURN (::_waccess (path, amode), int, -1);
+#else /* ACE_WIN32 && !ACE_HAS_WINCE */
+ return ACE_OS::access (ACE_Wide_To_Ascii (path).char_rep (), amode);
+#endif /* ACE_WIN32 && !ACE_HAS_WINCE */
+}
+#endif /* ACE_HAS_WCHAR */
+
+ACE_INLINE ACE_HANDLE
+ACE_OS::creat (const ACE_TCHAR *filename, mode_t mode)
+{
+ ACE_OS_TRACE ("ACE_OS::creat");
+#if defined (ACE_HAS_PACE)
+ ACE_OSCALL_RETURN (::pace_creat (filename, mode),
+ ACE_HANDLE, ACE_INVALID_HANDLE);
+#elif defined (ACE_WIN32)
+ return ACE_OS::open (filename, mode);
+#elif defined(ACE_PSOS)
+ ACE_OSCALL_RETURN(::create_f((char *)filename, 1024,
+ S_IRUSR | S_IWUSR | S_IXUSR),
+ ACE_HANDLE, ACE_INVALID_HANDLE);
+#elif defined(ACE_PSOS_TM)
+ ACE_UNUSED_ARG (filename);
+ ACE_UNUSED_ARG (mode);
+ ACE_NOTSUP_RETURN (-1);
+#elif defined(ACE_PSOS)
+ ACE_UNUSED_ARG (filename);
+ ACE_UNUSED_ARG (mode);
+ ACE_NOTSUP_RETURN (-1);
+#else
+ ACE_OSCALL_RETURN (::creat (filename, mode),
+ ACE_HANDLE, ACE_INVALID_HANDLE);
+#endif /* ACE_HAS_PACE */
+}
+
+#if !defined (ACE_WIN32) && !defined (VXWORKS) && !defined (CHORUS) && !defined (ACE_PSOS)
+// Don't inline on those platforms because this function contains
+// string literals, and some compilers, e.g., g++, don't handle those
+// efficiently in unused inline functions.
+ACE_INLINE int
+ACE_OS::uname (ACE_utsname *name)
+{
+ ACE_OS_TRACE ("ACE_OS::uname");
+#if defined (ACE_HAS_PACE)
+ ACE_OSCALL_RETURN (::pace_uname (name), int, -1);
+#else
+ ACE_OSCALL_RETURN (::uname (name), int, -1);
+#endif /* ACE_HAS_PACE */
+}
+#endif /* ! ACE_WIN32 && ! VXWORKS && ! CHORUS */
+
+ACE_INLINE int
+ACE_OS::hostname (char name[], size_t maxnamelen)
+{
+ ACE_OS_TRACE ("ACE_OS::hostname");
+#if defined (ACE_HAS_PHARLAP)
+ // PharLap only can do net stuff with the RT version.
+# if defined (ACE_HAS_PHARLAP_RT)
+ // @@This is not at all reliable... requires ethernet and BOOTP to be used.
+ // A more reliable way is to go thru the devices w/ EtsTCPGetDeviceCfg until
+ // a legit IP address is found, then get its name w/ gethostbyaddr.
+ ACE_SOCKCALL_RETURN (gethostname (name, maxnamelen), int, SOCKET_ERROR);
+# else
+ ACE_UNUSED_ARG (name);
+ ACE_UNUSED_ARG (maxnamelen);
+ ACE_NOTSUP_RETURN (-1);
+# endif /* ACE_HAS_PHARLAP_RT */
+#elif defined (VXWORKS) || defined (ACE_HAS_WINCE)
+ ACE_OSCALL_RETURN (::gethostname (name, maxnamelen), int, -1);
+#elif defined (ACE_WIN32)
+ ACE_WIN32CALL_RETURN (ACE_ADAPT_RETVAL (::GetComputerNameA (name,
+ LPDWORD (&maxnamelen)),
+ ace_result_), int, -1);
+#elif defined (CHORUS)
+ if (::gethostname (name, maxnamelen) == -1)
+ return -1;
+ else
+ {
+ if (ACE_OS::strlen (name) == 0)
+ {
+ // Try the HOST environment variable.
+ ACE_TCHAR *const hostenv = ::getenv (ACE_LIB_TEXT ("HOST"));
+ if (hostenv)
+ ACE_OS::strsncpy (name, hostenv, maxnamelen);
+ }
+ return 0;
+ }
+#else /* ACE_HAS_PHARLAP */
+ ACE_utsname host_info;
+
+ if (ACE_OS::uname (&host_info) == -1)
+ return -1;
+ else
+ {
+ ACE_OS::strsncpy (name, host_info.nodename, maxnamelen);
+ return 0;
+ }
+#endif /* ACE_HAS_PHARLAP */
+}
+
+#if defined (ACE_HAS_WCHAR)
+ACE_INLINE int
+ACE_OS::hostname (wchar_t name[], size_t maxnamelen)
+{
+#if defined (ACE_WIN32) && !defined (ACE_HAS_WINCE)
+ ACE_WIN32CALL_RETURN (ACE_ADAPT_RETVAL (GetComputerNameW (name,
+ LPDWORD (&maxnamelen)),
+ ace_result_), int, -1);
+#else /* ACE_WIN32 && !ACE_HAS_WINCE */
+ // Emulate using the char version
+ char *char_name = 0;
+ int result = 0;
+
+ ACE_NEW_RETURN (char_name, char[maxnamelen], -1);
+
+ result = ACE_OS::hostname(char_name, maxnamelen);
+ ACE_OS::strcpy (name, ACE_Ascii_To_Wide (char_name).wchar_rep ());
+
+ delete [] char_name;
+ return result;
+#endif /* ACE_WIN32 && !ACE_HAS_WINCE */
+}
+#endif /* ACE_HAS_WCHAR */
+
+ACE_INLINE int
+ACE_OS::msgctl (int msqid, int cmd, struct msqid_ds *val)
+{
+ ACE_OS_TRACE ("ACE_OS::msgctl");
+#if defined (ACE_HAS_SYSV_IPC)
+ ACE_OSCALL_RETURN (::msgctl (msqid, cmd, val), int, -1);
+#else
+ ACE_UNUSED_ARG (msqid);
+ ACE_UNUSED_ARG (cmd);
+ ACE_UNUSED_ARG (val);
+
+ ACE_NOTSUP_RETURN (-1);
+#endif /* ACE_HAS_SYSV_IPC */
+}
+
+ACE_INLINE int
+ACE_OS::msgget (key_t key, int msgflg)
+{
+ ACE_OS_TRACE ("ACE_OS::msgget");
+#if defined (ACE_HAS_SYSV_IPC)
+ ACE_OSCALL_RETURN (::msgget (key, msgflg), int, -1);
+#else
+ ACE_UNUSED_ARG (key);
+ ACE_UNUSED_ARG (msgflg);
+
+ ACE_NOTSUP_RETURN (-1);
+#endif /* ACE_HAS_SYSV_IPC */
+}
+
+ACE_INLINE int
+ACE_OS::msgrcv (int int_id, void *buf, size_t len,
+ long type, int flags)
+{
+ ACE_OS_TRACE ("ACE_OS::msgrcv");
+#if defined (ACE_HAS_SYSV_IPC)
+# if defined (ACE_LACKS_POSIX_PROTOTYPES) || defined (ACE_LACKS_SOME_POSIX_PROTOTYPES)
+ ACE_OSCALL_RETURN (::msgrcv (int_id, (msgbuf *) buf, len, type, flags),
+ int, -1);
+# else
+ ACE_OSCALL_RETURN (::msgrcv (int_id, buf, len, type, flags),
+ int, -1);
+# endif /* ACE_LACKS_POSIX_PROTOTYPES */
+#else
+ ACE_UNUSED_ARG (int_id);
+ ACE_UNUSED_ARG (buf);
+ ACE_UNUSED_ARG (len);
+ ACE_UNUSED_ARG (type);
+ ACE_UNUSED_ARG (flags);
+
+ ACE_NOTSUP_RETURN (-1);
+#endif /* ACE_HAS_SYSV_IPC */
+}
+
+ACE_INLINE int
+ACE_OS::msgsnd (int int_id, const void *buf, size_t len, int flags)
+{
+ ACE_OS_TRACE ("ACE_OS::msgsnd");
+#if defined (ACE_HAS_SYSV_IPC)
+# if defined (ACE_HAS_NONCONST_MSGSND)
+ ACE_OSCALL_RETURN (::msgsnd (int_id, (void *) buf, len, flags), int, -1);
+# elif defined (ACE_LACKS_POSIX_PROTOTYPES) || defined (ACE_LACKS_SOME_POSIX_PROTOTYPES)
+ ACE_OSCALL_RETURN (::msgsnd (int_id, (msgbuf *) buf, len, flags), int, -1);
+# else
+ ACE_OSCALL_RETURN (::msgsnd (int_id, buf, len, flags), int, -1);
+# endif /* ACE_LACKS_POSIX_PROTOTYPES || ACE_HAS_NONCONST_MSGSND */
+#else
+ ACE_UNUSED_ARG (int_id);
+ ACE_UNUSED_ARG (buf);
+ ACE_UNUSED_ARG (len);
+ ACE_UNUSED_ARG (flags);
+
+ ACE_NOTSUP_RETURN (-1);
+#endif /* ACE_HAS_SYSV_IPC */
+}
+
+ACE_INLINE u_int
+ACE_OS::alarm (u_int secs)
+{
+ ACE_OS_TRACE ("ACE_OS::alarm");
+#if defined (ACE_HAS_PACE)
+ return ::pace_alarm (secs);
+#elif defined (ACE_WIN32) || defined (VXWORKS) || defined (CHORUS) || defined (ACE_PSOS)
+ ACE_UNUSED_ARG (secs);
+
+ ACE_NOTSUP_RETURN (0);
+#else
+ return ::alarm (secs);
+#endif /* ACE_HAS_PACE */
+}
+
+ACE_INLINE u_int
+ACE_OS::ualarm (u_int usecs, u_int interval)
+{
+ ACE_OS_TRACE ("ACE_OS::ualarm");
+
+#if defined (ACE_HAS_UALARM)
+ return ::ualarm (usecs, interval);
+#elif !defined (ACE_LACKS_UNIX_SIGNALS)
+ ACE_UNUSED_ARG (interval);
+ return ::alarm (usecs * ACE_ONE_SECOND_IN_USECS);
+#else
+ ACE_UNUSED_ARG (usecs);
+ ACE_UNUSED_ARG (interval);
+ ACE_NOTSUP_RETURN (0);
+#endif /* ACE_HAS_UALARM */
+}
+
+ACE_INLINE u_int
+ACE_OS::ualarm (const ACE_Time_Value &tv,
+ const ACE_Time_Value &tv_interval)
+{
+ ACE_OS_TRACE ("ACE_OS::ualarm");
+
+#if defined (ACE_HAS_UALARM)
+ u_int usecs = (tv.sec () * ACE_ONE_SECOND_IN_USECS) + tv.usec ();
+ u_int interval = (tv_interval.sec () * ACE_ONE_SECOND_IN_USECS) + tv_interval.usec ();
+ return ::ualarm (usecs, interval);
+#elif !defined (ACE_LACKS_UNIX_SIGNALS)
+ ACE_UNUSED_ARG (tv_interval);
+ return ::alarm (tv.sec ());
+#else
+ ACE_UNUSED_ARG (tv_interval);
+ ACE_UNUSED_ARG (tv);
+ ACE_NOTSUP_RETURN (0);
+#endif /* ACE_HAS_UALARM */
+}
+
+ACE_INLINE int
+ACE_OS::dlclose (ACE_SHLIB_HANDLE handle)
+{
+ ACE_OS_TRACE ("ACE_OS::dlclose");
+#if defined (ACE_HAS_SVR4_DYNAMIC_LINKING)
+
+# if !defined (ACE_HAS_AUTOMATIC_INIT_FINI)
+ // SunOS4 does not automatically call _fini()!
+ void *ptr;
+
+ ACE_OSCALL (::dlsym (handle, ACE_LIB_TEXT ("_fini")), void *, 0, ptr);
+
+ if (ptr != 0)
+ (*((int (*)(void)) ptr)) (); // Call _fini hook explicitly.
+# endif /* ACE_HAS_AUTOMATIC_INIT_FINI */
+#if defined (_M_UNIX)
+ ACE_OSCALL_RETURN (::_dlclose (handle), int, -1);
+#else /* _MUNIX */
+ ACE_OSCALL_RETURN (::dlclose (handle), int, -1);
+#endif /* _M_UNIX */
+#elif defined (ACE_WIN32)
+ ACE_WIN32CALL_RETURN (ACE_ADAPT_RETVAL (::FreeLibrary (handle), ace_result_), int, -1);
+#elif defined (__hpux)
+ // HP-UX 10.x and 32-bit 11.00 do not pay attention to the ref count
+ // when unloading a dynamic lib. So, if the ref count is more than
+ // 1, do not unload the lib. This will cause a library loaded more
+ // than once to not be unloaded until the process runs down, but
+ // that's life. It's better than unloading a library that's in use.
+ // So far as I know, there's no way to decrement the refcnt that the
+ // kernel is looking at - the shl_descriptor is a copy of what the
+ // kernel has, not the actual struct. On 64-bit HP-UX using dlopen,
+ // this problem has been fixed.
+ struct shl_descriptor desc;
+ if (shl_gethandle_r (handle, &desc) == -1)
+ return -1;
+ if (desc.ref_count > 1)
+ return 0;
+# if defined(__GNUC__) || __cplusplus >= 199707L
+ ACE_OSCALL_RETURN (::shl_unload (handle), int, -1);
+# else
+ ACE_OSCALL_RETURN (::cxxshl_unload (handle), int, -1);
+# endif /* aC++ vs. Hp C++ */
+#else
+ ACE_UNUSED_ARG (handle);
+ ACE_NOTSUP_RETURN (-1);
+#endif /* ACE_HAS_SVR4_DYNAMIC_LINKING */
+}
+
+ACE_INLINE ACE_TCHAR *
+ACE_OS::dlerror (void)
+{
+ ACE_OS_TRACE ("ACE_OS::dlerror");
+# if defined (ACE_HAS_SVR4_DYNAMIC_LINKING)
+#if defined(_M_UNIX)
+ ACE_OSCALL_RETURN ((char *)::_dlerror (), char *, 0);
+#else /* _M_UNIX */
+ ACE_OSCALL_RETURN ((char *)::dlerror (), char *, 0);
+#endif /* _M_UNIX */
+# elif defined (__hpux)
+ ACE_OSCALL_RETURN (::strerror(errno), char *, 0);
+# elif defined (ACE_WIN32)
+ static ACE_TCHAR buf[128];
+# if defined (ACE_HAS_PHARLAP)
+ ACE_OS::sprintf (buf, "error code %d", GetLastError());
+# else
+ ACE_TEXT_FormatMessage (FORMAT_MESSAGE_FROM_SYSTEM,
+ NULL,
+ ::GetLastError (),
+ 0,
+ buf,
+ sizeof buf / sizeof buf[0],
+ NULL);
+# endif /* ACE_HAS_PHARLAP */
+ return buf;
+# else
+ ACE_NOTSUP_RETURN (0);
+# endif /* ACE_HAS_SVR4_DYNAMIC_LINKING */
+}
+
+ACE_INLINE ACE_SHLIB_HANDLE
+ACE_OS::dlopen (const ACE_TCHAR *fname,
+ int mode)
+{
+ ACE_OS_TRACE ("ACE_OS::dlopen");
+
+ // Get the correct OS type.
+ ACE_DL_TYPE filename = ACE_const_cast (ACE_DL_TYPE, fname);
+
+# if defined (ACE_HAS_SVR4_DYNAMIC_LINKING)
+ void *handle;
+# if defined (ACE_HAS_SGIDLADD)
+ ACE_OSCALL (::sgidladd (filename, mode), void *, 0, handle);
+# elif defined (_M_UNIX)
+ ACE_OSCALL (::_dlopen (filename, mode), void *, 0, handle);
+# else
+ ACE_OSCALL (::dlopen (filename, mode), void *, 0, handle);
+# endif /* ACE_HAS_SGIDLADD */
+# if !defined (ACE_HAS_AUTOMATIC_INIT_FINI)
+ if (handle != 0)
+ {
+ void *ptr;
+ // Some systems (e.g., SunOS4) do not automatically call _init(), so
+ // we'll have to call it manually.
+
+ ACE_OSCALL (::dlsym (handle, ACE_LIB_TEXT ("_init")), void *, 0, ptr);
+
+ if (ptr != 0 && (*((int (*)(void)) ptr)) () == -1) // Call _init hook explicitly.
+ {
+ // Close down the handle to prevent leaks.
+ ::dlclose (handle);
+ return 0;
+ }
+ }
+# endif /* ACE_HAS_AUTOMATIC_INIT_FINI */
+ return handle;
+# elif defined (ACE_WIN32)
+ ACE_UNUSED_ARG (mode);
+
+ ACE_WIN32CALL_RETURN (ACE_TEXT_LoadLibrary (filename), ACE_SHLIB_HANDLE, 0);
+# elif defined (__hpux)
+
+# if defined(__GNUC__) || __cplusplus >= 199707L
+ ACE_OSCALL_RETURN (::shl_load(filename, mode, 0L), ACE_SHLIB_HANDLE, 0);
+# else
+ ACE_OSCALL_RETURN (::cxxshl_load(filename, mode, 0L), ACE_SHLIB_HANDLE, 0);
+# endif /* aC++ vs. Hp C++ */
+
+# else
+ ACE_UNUSED_ARG (filename);
+ ACE_UNUSED_ARG (mode);
+ ACE_NOTSUP_RETURN (0);
+# endif /* ACE_HAS_SVR4_DYNAMIC_LINKING */
+}
+
+ACE_INLINE void *
+ACE_OS::dlsym (ACE_SHLIB_HANDLE handle,
+ const ACE_TCHAR *sname)
+{
+ ACE_OS_TRACE ("ACE_OS::dlsym");
+
+ // Get the correct OS type.
+#if defined (ACE_HAS_WINCE)
+ const wchar_t *symbolname = sname;
+#elif defined (ACE_HAS_CHARPTR_DL)
+ char *symbolname = ACE_const_cast (char *, sname);
+#elif !defined (ACE_WIN32) || !defined (ACE_USES_WCHAR)
+ const char *symbolname = sname;
+#endif /* ACE_HAS_CHARPTR_DL */
+
+# if defined (ACE_HAS_SVR4_DYNAMIC_LINKING)
+
+# if defined (ACE_LACKS_POSIX_PROTOTYPES)
+ ACE_OSCALL_RETURN (::dlsym (handle, symbolname), void *, 0);
+# elif defined (ACE_USES_ASM_SYMBOL_IN_DLSYM)
+ int l = ACE_OS::strlen (symbolname) + 2;
+ char *asm_symbolname = 0;
+ ACE_NEW_RETURN (asm_symbolname, char[l], 0);
+ ACE_OS::strcpy (asm_symbolname, "_") ;
+ ACE_OS::strcpy (asm_symbolname + 1, symbolname) ;
+ void *ace_result;
+ ACE_OSCALL (::dlsym (handle, asm_symbolname), void *, 0, ace_result);
+ delete [] asm_symbolname;
+ return ace_result;
+# elif defined (_M_UNIX)
+ ACE_OSCALL_RETURN (::_dlsym (handle, symbolname), void *, 0);
+# else
+ ACE_OSCALL_RETURN (::dlsym (handle, symbolname), void *, 0);
+# endif /* ACE_LACKS_POSIX_PROTOTYPES */
+
+# elif defined (ACE_WIN32) && defined (ACE_USES_WCHAR) && !defined (ACE_HAS_WINCE)
+
+ ACE_WIN32CALL_RETURN (::GetProcAddress (handle, ACE_TEXT_ALWAYS_CHAR (sname)), void *, 0);
+
+# elif defined (ACE_WIN32)
+
+ ACE_WIN32CALL_RETURN (::GetProcAddress (handle, symbolname), void *, 0);
+
+# elif defined (__hpux)
+
+ void *value;
+ int status;
+ shl_t _handle = handle;
+ ACE_OSCALL (::shl_findsym(&_handle, symbolname, TYPE_UNDEFINED, &value), int, -1, status);
+ return status == 0 ? value : NULL;
+
+# else
+
+ ACE_UNUSED_ARG (handle);
+ ACE_UNUSED_ARG (symbolname);
+ ACE_NOTSUP_RETURN (0);
+
+# endif /* ACE_HAS_SVR4_DYNAMIC_LINKING */
+}
+
+ACE_INLINE int
+ACE_OS::step (const char *str, char *expbuf)
+{
+ ACE_OS_TRACE ("ACE_OS::step");
+#if defined (ACE_HAS_REGEX)
+ ACE_OSCALL_RETURN (::step (str, expbuf), int, -1);
+#else
+ ACE_UNUSED_ARG (str);
+ ACE_UNUSED_ARG (expbuf);
+
+ ACE_NOTSUP_RETURN (-1);
+#endif /* ACE_HAS_REGEX */
+}
+
+ACE_INLINE long
+ACE_OS::sysinfo (int cmd, char *buf, long count)
+{
+ ACE_OS_TRACE ("ACE_OS::sysinfo");
+#if defined (ACE_HAS_SYSINFO)
+ ACE_OSCALL_RETURN (::sysinfo (cmd, buf, count), long, -1);
+#else
+ ACE_UNUSED_ARG (cmd);
+ ACE_UNUSED_ARG (buf);
+ ACE_UNUSED_ARG (count);
+
+ ACE_NOTSUP_RETURN (0);
+#endif /* ACE_HAS_SYSINFO */
+}
+
+ACE_INLINE ssize_t
+ACE_OS::write (ACE_HANDLE handle, const void *buf, size_t nbyte)
+{
+ ACE_OS_TRACE ("ACE_OS::write");
+#if defined (ACE_HAS_PACE)
+ ACE_OSCALL_RETURN (::pace_write (handle, buf, nbyte), ssize_t, -1);
+#elif defined (ACE_WIN32)
+ DWORD bytes_written; // This is set to 0 byte WriteFile.
+
+ if (::WriteFile (handle, buf, nbyte, &bytes_written, 0))
+ return (ssize_t) bytes_written;
+ else
+ ACE_FAIL_RETURN (-1);
+#elif defined (ACE_PSOS)
+# if defined (ACE_PSOS_LACKS_PHILE)
+ ACE_UNUSED_ARG (handle);
+ ACE_UNUSED_ARG (buf);
+ ACE_UNUSED_ARG (nbyte);
+ ACE_NOTSUP_RETURN (-1);
+# else
+ if(::write_f (handle, (void *) buf, nbyte) == 0)
+ return (ssize_t) nbyte;
+ else
+ return -1;
+# endif /* defined (ACE_PSOS_LACKS_PHILE) */
+#else
+# if defined (ACE_LACKS_POSIX_PROTOTYPES)
+ ACE_OSCALL_RETURN (::write (handle, (const char *) buf, nbyte), ssize_t, -1);
+# elif defined (ACE_PSOS)
+ ACE_OSCALL_RETURN (::write_f(handle, (void *) buf, nbyte), ssize_t, -1);
+# elif defined (ACE_HAS_CHARPTR_SOCKOPT)
+ ACE_OSCALL_RETURN (::write (handle, (char *) buf, nbyte), ssize_t, -1);
+# else
+ ACE_OSCALL_RETURN (::write (handle, buf, nbyte), ssize_t, -1);
+# endif /* ACE_LACKS_POSIX_PROTOTYPES */
+#endif /* ACE_HAS_PACE */
+}
+
+ACE_INLINE ssize_t
+ACE_OS::write (ACE_HANDLE handle, const void *buf, size_t nbyte,
+ ACE_OVERLAPPED *overlapped)
+{
+ ACE_OS_TRACE ("ACE_OS::write");
+ overlapped = overlapped;
+#if defined (ACE_WIN32)
+ DWORD bytes_written; // This is set to 0 byte WriteFile.
+
+ if (::WriteFile (handle, buf, nbyte, &bytes_written, overlapped))
+ return (ssize_t) bytes_written;
+ else
+ return -1;
+#else
+ return ACE_OS::write (handle, buf, nbyte);
+#endif /* ACE_WIN32 */
+}
+
+ACE_INLINE ssize_t
+ACE_OS::read (ACE_HANDLE handle, void *buf, size_t len)
+{
+ ACE_OS_TRACE ("ACE_OS::read");
+#if defined (ACE_HAS_PACE)
+ int result;
+ ACE_OSCALL (::pace_read (handle, buf, len), ssize_t, -1, result);
+ if (result == -1 && errno == EAGAIN)
+ errno = EWOULDBLOCK;
+ return result;
+#elif defined (ACE_WIN32)
+ DWORD ok_len;
+ if (::ReadFile (handle, buf, len, &ok_len, 0))
+ return (ssize_t) ok_len;
+ else
+ ACE_FAIL_RETURN (-1);
+#elif defined (ACE_PSOS)
+# if defined (ACE_PSOS_LACKS_PHILE)
+ ACE_UNUSED_ARG (handle);
+ ACE_UNUSED_ARG (buf);
+ ACE_UNUSED_ARG (len);
+ ACE_NOTSUP_RETURN (-1);
+# else
+ u_long count;
+ u_long result = ::read_f (handle, buf, len, &count);
+ if (result != 0)
+ return ACE_static_cast (ssize_t, -1);
+ else
+ return ACE_static_cast (ssize_t, count == len ? count : 0);
+# endif /* defined (ACE_PSOS_LACKS_PHILE */
+#else
+
+ int result;
+
+# if defined (ACE_LACKS_POSIX_PROTOTYPES) || defined (ACE_HAS_CHARPTR_SOCKOPT)
+ ACE_OSCALL (::read (handle, (char *) buf, len), ssize_t, -1, result);
+# else
+ ACE_OSCALL (::read (handle, buf, len), ssize_t, -1, result);
+# endif /* ACE_LACKS_POSIX_PROTOTYPES */
+ if (result == -1 && errno == EAGAIN)
+ errno = EWOULDBLOCK;
+ return result;
+#endif /* ACE_HAS_PACE */
+}
+
+ACE_INLINE ssize_t
+ACE_OS::read (ACE_HANDLE handle, void *buf, size_t len,
+ ACE_OVERLAPPED *overlapped)
+{
+ ACE_OS_TRACE ("ACE_OS::read");
+ overlapped = overlapped;
+#if defined (ACE_WIN32)
+ DWORD ok_len;
+ return ::ReadFile (handle, buf, len, &ok_len, overlapped) ? (ssize_t) ok_len : -1;
+#else
+ return ACE_OS::read (handle, buf, len);
+#endif /* ACE_WIN32 */
+}
+
+ACE_INLINE int
+ACE_OS::readlink (const char *path, char *buf, size_t bufsiz)
+{
+ ACE_OS_TRACE ("ACE_OS::readlink");
+# if defined (ACE_LACKS_READLINK) || \
+ defined (ACE_HAS_WINCE) || defined (ACE_WIN32)
+ ACE_UNUSED_ARG (path);
+ ACE_UNUSED_ARG (buf);
+ ACE_UNUSED_ARG (bufsiz);
+ ACE_NOTSUP_RETURN (-1);
+# else
+# if !defined(ACE_HAS_NONCONST_READLINK)
+ ACE_OSCALL_RETURN (::readlink (path, buf, bufsiz), int, -1);
+# else
+ ACE_OSCALL_RETURN (::readlink ((char *)path, buf, bufsiz), int, -1);
+# endif
+# endif /* ACE_LACKS_READLINK */
+}
+
+ACE_INLINE int
+ACE_OS::getmsg (ACE_HANDLE handle,
+ struct strbuf *ctl,
+ struct strbuf *data,
+ int *flags)
+{
+ ACE_OS_TRACE ("ACE_OS::getmsg");
+#if defined (ACE_HAS_STREAM_PIPES)
+ ACE_OSCALL_RETURN (::getmsg (handle, ctl, data, flags), int, -1);
+#else
+ ACE_UNUSED_ARG (handle);
+ ACE_UNUSED_ARG (ctl);
+ ACE_UNUSED_ARG (data);
+ ACE_UNUSED_ARG (flags);
+
+ // I'm not sure how to implement this correctly.
+ ACE_NOTSUP_RETURN (-1);
+#endif /* ACE_HAS_STREAM_PIPES */
+}
+
+ACE_INLINE int
+ACE_OS::getpmsg (ACE_HANDLE handle,
+ struct strbuf *ctl,
+ struct strbuf *data,
+ int *band,
+ int *flags)
+{
+ ACE_OS_TRACE ("ACE_OS::getpmsg");
+#if defined (ACE_HAS_STREAM_PIPES)
+ ACE_OSCALL_RETURN (::getpmsg (handle, ctl, data, band, flags), int, -1);
+#else
+ ACE_UNUSED_ARG (handle);
+ ACE_UNUSED_ARG (ctl);
+ ACE_UNUSED_ARG (data);
+ ACE_UNUSED_ARG (band);
+ ACE_UNUSED_ARG (flags);
+
+ // I'm not sure how to implement this correctly.
+ ACE_NOTSUP_RETURN (-1);
+#endif /* ACE_HAS_STREAM_PIPES */
+}
+
+ACE_INLINE int
+ACE_OS::getrusage (int who, struct rusage *ru)
+{
+ ACE_OS_TRACE ("ACE_OS::getrusage");
+
+#if defined (ACE_HAS_SYSCALL_GETRUSAGE)
+ // This nonsense is necessary for HP/UX...
+ ACE_OSCALL_RETURN (::syscall (SYS_GETRUSAGE, who, ru), int, -1);
+#elif defined (ACE_HAS_GETRUSAGE)
+# if defined (ACE_WIN32)
+ ACE_UNUSED_ARG (who);
+
+ FILETIME dummy_1;
+ FILETIME dummy_2;
+ ACE_WIN32CALL_RETURN (ACE_ADAPT_RETVAL (::GetProcessTimes (::GetCurrentProcess(),
+ &dummy_1, // start
+ &dummy_2, // exited
+ &ru->ru_stime,
+ &ru->ru_utime),
+ ace_result_),
+ int, -1);
+# else
+# if defined (ACE_HAS_RUSAGE_WHO_ENUM)
+ ACE_OSCALL_RETURN (::getrusage ((ACE_HAS_RUSAGE_WHO_ENUM) who, ru), int, -1);
+# else
+ ACE_OSCALL_RETURN (::getrusage (who, ru), int, -1);
+# endif /* ACE_HAS_RUSAGE_WHO_ENUM */
+# endif /* ACE_WIN32 */
+#else
+ who = who;
+ ru = ru;
+ ACE_NOTSUP_RETURN (-1);
+#endif /* ACE_HAS_SYSCALL_GETRUSAGE */
+}
+
+ACE_INLINE int
+ACE_OS::isastream (ACE_HANDLE handle)
+{
+ ACE_OS_TRACE ("ACE_OS::isastream");
+#if defined (ACE_HAS_STREAM_PIPES)
+ ACE_OSCALL_RETURN (::isastream (handle), int, -1);
+#else
+ ACE_UNUSED_ARG (handle);
+
+ ACE_NOTSUP_RETURN (-1);
+#endif /* ACE_HAS_STREAM_PIPES */
+}
+
+// Implements simple read/write control for pages. Affects a page if
+// part of the page is referenced. Currently PROT_READ, PROT_WRITE,
+// and PROT_RDWR has been mapped in OS.h. This needn't have anything
+// to do with a mmap region.
+
+ACE_INLINE int
+ACE_OS::mprotect (void *addr, size_t len, int prot)
+{
+ ACE_OS_TRACE ("ACE_OS::mprotect");
+#if defined (ACE_HAS_PACE)
+ ACE_OSCALL_RETURN (::pace_mprotect (addr, len, prot), int, -1);
+#elif defined (ACE_WIN32) && !defined (ACE_HAS_PHARLAP)
+ DWORD dummy; // Sigh!
+ return ::VirtualProtect(addr, len, prot, &dummy) ? 0 : -1;
+#elif !defined (ACE_LACKS_MPROTECT)
+ ACE_OSCALL_RETURN (::mprotect ((ACE_MMAP_TYPE) addr, len, prot), int, -1);
+#else
+ ACE_UNUSED_ARG (addr);
+ ACE_UNUSED_ARG (len);
+ ACE_UNUSED_ARG (prot);
+ ACE_NOTSUP_RETURN (-1);
+#endif /* ACE_HAS_PACE */
+}
+
+ACE_INLINE int
+ACE_OS::msync (void *addr, size_t len, int sync)
+{
+ ACE_OS_TRACE ("ACE_OS::msync");
+#if defined (ACE_HAS_PACE)
+ ACE_OSCALL_RETURN (::pace_msync (addr, len, sync), int, -1);
+#elif defined (ACE_WIN32) && !defined (ACE_HAS_PHARLAP)
+ ACE_UNUSED_ARG (sync);
+
+ ACE_WIN32CALL_RETURN (ACE_ADAPT_RETVAL (::FlushViewOfFile (addr, len), ace_result_), int, -1);
+#elif !defined (ACE_LACKS_MSYNC)
+# if !defined (ACE_HAS_BROKEN_NETBSD_MSYNC)
+ ACE_OSCALL_RETURN (::msync ((ACE_MMAP_TYPE) addr, len, sync), int, -1);
+# else
+ ACE_OSCALL_RETURN (::msync ((ACE_MMAP_TYPE) addr, len), int, -1);
+ ACE_UNUSED_ARG (sync);
+# endif /* ACE_HAS_BROKEN_NETBSD_MSYNC */
+#else
+ ACE_UNUSED_ARG (addr);
+ ACE_UNUSED_ARG (len);
+ ACE_UNUSED_ARG (sync);
+ ACE_NOTSUP_RETURN (-1);
+#endif /* ACE_HAS_PACE */
+}
+
+ACE_INLINE int
+ACE_OS::munmap (void *addr, size_t len)
+{
+ ACE_OS_TRACE ("ACE_OS::munmap");
+#if defined (ACE_HAS_PACE) && !defined (ACE_WIN32)
+ ACE_OSCALL_RETURN (::pace_munmap (addr, len), int, -1);
+#elif defined (ACE_WIN32)
+ ACE_UNUSED_ARG (len);
+
+ ACE_WIN32CALL_RETURN (ACE_ADAPT_RETVAL (::UnmapViewOfFile (addr), ace_result_), int, -1);
+#elif !defined (ACE_LACKS_MMAP)
+ ACE_OSCALL_RETURN (::munmap ((ACE_MMAP_TYPE) addr, len), int, -1);
+#else
+ ACE_UNUSED_ARG (addr);
+ ACE_UNUSED_ARG (len);
+ ACE_NOTSUP_RETURN (-1);
+#endif /* ACE_HAS_PACE */
+}
+
+ACE_INLINE int
+ACE_OS::madvise (caddr_t addr, size_t len, int advice)
+{
+ ACE_OS_TRACE ("ACE_OS::madvise");
+#if defined (ACE_WIN32)
+ ACE_UNUSED_ARG (addr);
+ ACE_UNUSED_ARG (len);
+ ACE_UNUSED_ARG (advice);
+
+ ACE_NOTSUP_RETURN (-1);
+#elif !defined (ACE_LACKS_MADVISE)
+ ACE_OSCALL_RETURN (::madvise (addr, len, advice), int, -1);
+#else
+ ACE_UNUSED_ARG (addr);
+ ACE_UNUSED_ARG (len);
+ ACE_UNUSED_ARG (advice);
+ ACE_NOTSUP_RETURN (-1);
+#endif /* ACE_WIN32 */
+}
+
+ACE_INLINE int
+ACE_OS::putmsg (ACE_HANDLE handle, const struct strbuf *ctl,
+ const struct strbuf *data, int flags)
+{
+ ACE_OS_TRACE ("ACE_OS::putmsg");
+#if defined (ACE_HAS_STREAM_PIPES)
+ ACE_OSCALL_RETURN (::putmsg (handle,
+ (ACE_STRBUF_TYPE) ctl,
+ (ACE_STRBUF_TYPE) data,
+ flags), int, -1);
+#else
+ ACE_UNUSED_ARG (flags);
+ if (ctl == 0 && data == 0)
+ {
+ errno = EINVAL;
+ return 0;
+ }
+ // Handle the two easy cases.
+ else if (ctl != 0)
+ return ACE_OS::write (handle, ctl->buf, ctl->len);
+ else if (data != 0)
+ return ACE_OS::write (handle, data->buf, data->len);
+ else
+ {
+ // This is the hard case.
+ char *buf;
+ ACE_NEW_RETURN (buf, char [ctl->len + data->len], -1);
+ ACE_OS::memcpy (buf, ctl->buf, ctl->len);
+ ACE_OS::memcpy (buf + ctl->len, data->buf, data->len);
+ int result = ACE_OS::write (handle, buf, ctl->len + data->len);
+ delete [] buf;
+ return result;
+ }
+#endif /* ACE_HAS_STREAM_PIPES */
+}
+
+ACE_INLINE int
+ACE_OS::putpmsg (ACE_HANDLE handle,
+ const struct strbuf *ctl,
+ const struct strbuf *data,
+ int band,
+ int flags)
+{
+ ACE_OS_TRACE ("ACE_OS::putpmsg");
+#if defined (ACE_HAS_STREAM_PIPES)
+ ACE_OSCALL_RETURN (::putpmsg (handle,
+ (ACE_STRBUF_TYPE) ctl,
+ (ACE_STRBUF_TYPE) data,
+ band, flags), int, -1);
+#else
+ ACE_UNUSED_ARG (flags);
+ ACE_UNUSED_ARG (band);
+ return ACE_OS::putmsg (handle, ctl, data, flags);
+#endif /* ACE_HAS_STREAM_PIPES */
+}
+
+ACE_INLINE int
+ACE_OS::semctl (int int_id, int semnum, int cmd, semun value)
+{
+ ACE_OS_TRACE ("ACE_OS::semctl");
+#if defined (ACE_HAS_SYSV_IPC)
+ ACE_OSCALL_RETURN (::semctl (int_id, semnum, cmd, value), int, -1);
+#else
+ ACE_UNUSED_ARG (int_id);
+ ACE_UNUSED_ARG (semnum);
+ ACE_UNUSED_ARG (cmd);
+ ACE_UNUSED_ARG (value);
+
+ ACE_NOTSUP_RETURN (-1);
+#endif /* ACE_HAS_SYSV_IPC */
+}
+
+ACE_INLINE int
+ACE_OS::semget (key_t key, int nsems, int flags)
+{
+ ACE_OS_TRACE ("ACE_OS::semget");
+#if defined (ACE_HAS_SYSV_IPC)
+ ACE_OSCALL_RETURN (::semget (key, nsems, flags), int, -1);
+#else
+ ACE_UNUSED_ARG (key);
+ ACE_UNUSED_ARG (nsems);
+ ACE_UNUSED_ARG (flags);
+
+ ACE_NOTSUP_RETURN (-1);
+#endif /* ACE_HAS_SYSV_IPC */
+}
+
+ACE_INLINE int
+ACE_OS::semop (int int_id, struct sembuf *sops, size_t nsops)
+{
+ ACE_OS_TRACE ("ACE_OS::semop");
+#if defined (ACE_HAS_SYSV_IPC)
+ ACE_OSCALL_RETURN (::semop (int_id, sops, nsops), int, -1);
+#else
+ ACE_UNUSED_ARG (int_id);
+ ACE_UNUSED_ARG (sops);
+ ACE_UNUSED_ARG (nsops);
+
+ ACE_NOTSUP_RETURN (-1);
+#endif /* ACE_HAS_SYSV_IPC */
+}
+
+ACE_INLINE void *
+ACE_OS::shmat (int int_id, void *shmaddr, int shmflg)
+{
+ ACE_OS_TRACE ("ACE_OS::shmat");
+#if defined (ACE_HAS_SYSV_IPC)
+# if defined (ACE_LACKS_POSIX_PROTOTYPES) || defined (ACE_LACKS_SOME_POSIX_PROTOTYPES)
+ ACE_OSCALL_RETURN (::shmat (int_id, (char *)shmaddr, shmflg), void *, (void *) -1);
+# else
+ ACE_OSCALL_RETURN (::shmat (int_id, shmaddr, shmflg), void *, (void *) -1);
+# endif /* ACE_LACKS_POSIX_PROTOTYPES */
+#else
+ ACE_UNUSED_ARG (int_id);
+ ACE_UNUSED_ARG (shmaddr);
+ ACE_UNUSED_ARG (shmflg);
+
+ ACE_NOTSUP_RETURN ((void *) -1);
+#endif /* ACE_HAS_SYSV_IPC */
+}
+
+ACE_INLINE int
+ACE_OS::shmctl (int int_id, int cmd, struct shmid_ds *buf)
+{
+ ACE_OS_TRACE ("ACE_OS::shmctl");
+#if defined (ACE_HAS_SYSV_IPC)
+ ACE_OSCALL_RETURN (::shmctl (int_id, cmd, buf), int, -1);
+#else
+ ACE_UNUSED_ARG (buf);
+ ACE_UNUSED_ARG (cmd);
+ ACE_UNUSED_ARG (int_id);
+
+ ACE_NOTSUP_RETURN (-1);
+#endif /* ACE_HAS_SYSV_IPC */
+}
+
+ACE_INLINE int
+ACE_OS::shmdt (void *shmaddr)
+{
+ ACE_OS_TRACE ("ACE_OS::shmdt");
+#if defined (ACE_HAS_SYSV_IPC)
+ ACE_OSCALL_RETURN (::shmdt ((char *) shmaddr), int, -1);
+#else
+ ACE_UNUSED_ARG (shmaddr);
+
+ ACE_NOTSUP_RETURN (-1);
+#endif /* ACE_HAS_SYSV_IPC */
+}
+
+ACE_INLINE int
+ACE_OS::shmget (key_t key, int size, int flags)
+{
+ ACE_OS_TRACE ("ACE_OS::shmget");
+#if defined (ACE_HAS_SYSV_IPC)
+ ACE_OSCALL_RETURN (::shmget (key, size, flags), int, -1);
+#else
+ ACE_UNUSED_ARG (flags);
+ ACE_UNUSED_ARG (size);
+ ACE_UNUSED_ARG (key);
+
+ ACE_NOTSUP_RETURN (-1);
+#endif /* ACE_HAS_SYSV_IPC */
+}
+
+ACE_INLINE void
+ACE_OS::tzset (void)
+{
+#if defined (ACE_HAS_PACE)
+ ::pace_tzset ();
+# elif !defined (ACE_HAS_WINCE) && !defined (VXWORKS) && !defined (ACE_PSOS) && ! defined(__rtems__)
+# if defined (ACE_WIN32)
+ ::_tzset (); // For Win32.
+# else
+ ::tzset (); // For UNIX platforms.
+# endif /* ACE_WIN32 */
+# else
+ errno = ENOTSUP;
+# endif /* ACE_HAS_PACE */
+}
+
+ACE_INLINE long
+ACE_OS::timezone (void)
+{
+ return ::ace_timezone ();
+}
+
+#if !defined (ACE_LACKS_DIFFTIME)
+ACE_INLINE double
+ACE_OS::difftime (time_t t1, time_t t0)
+{
+ return ::ace_difftime (t1, t0);
+}
+#endif /* ! ACE_LACKS_DIFFTIME */
+
+ACE_INLINE ACE_TCHAR *
+ACE_OS::ctime (const time_t *t)
+{
+ ACE_OS_TRACE ("ACE_OS::ctime");
+#if defined (ACE_HAS_PACE)
+ ACE_OSCALL_RETURN (::pace_ctime (t), char*, 0);
+#elif defined (ACE_HAS_BROKEN_CTIME)
+ ACE_OSCALL_RETURN (::asctime (::localtime (t)), char *, 0);
+#elif defined(ACE_PSOS) && ! defined (ACE_PSOS_HAS_TIME)
+ return "ctime-return";
+#elif defined (ACE_HAS_WINCE)
+ ACE_TCHAR buf[26]; // 26 is a "magic number" ;)
+ return ACE_OS::ctime_r (t, buf, 26);
+#elif defined (ACE_USES_WCHAR)
+ ACE_OSCALL_RETURN (::_wctime (t), wchar_t *, 0);
+#else
+ ACE_OSCALL_RETURN (::ctime (t), char *, 0);
+# endif /* ACE_HAS_PACE */
+}
+
+#if !defined (ACE_HAS_WINCE) /* CE version in OS.cpp */
+ACE_INLINE ACE_TCHAR *
+ACE_OS::ctime_r (const time_t *t, ACE_TCHAR *buf, int buflen)
+{
+ ACE_OS_TRACE ("ACE_OS::ctime_r");
+#if defined (ACE_HAS_PACE)
+ ACE_UNUSED_ARG (buflen);
+ ACE_OSCALL_RETURN (::pace_ctime_r (t, buf), ACE_TCHAR*, 0);
+#elif defined (ACE_HAS_REENTRANT_FUNCTIONS)
+# if defined (ACE_HAS_2_PARAM_ASCTIME_R_AND_CTIME_R)
+ ACE_TCHAR *result;
+# if defined (DIGITAL_UNIX)
+ ACE_OSCALL (::_Pctime_r (t, buf), ACE_TCHAR *, 0, result);
+# else /* DIGITAL_UNIX */
+ ACE_OSCALL (::ctime_r (t, buf), ACE_TCHAR *, 0, result);
+# endif /* DIGITAL_UNIX */
+ if (result != 0)
+ // This needs to be <ACE_OS::strncpy> rather than
+ // <ACE_OS::strsncpy> to avoid problems on certain platforms.
+ ACE_OS::strncpy (buf, result, buflen);
+ return buf;
+# else /* ACE_HAS_2_PARAM_ASCTIME_R_AND_CTIME_R */
+
+# if defined (ACE_CTIME_R_RETURNS_INT)
+ return (::ctime_r (t, buf, buflen) == -1 ? 0 : buf);
+# else /* ACE_CTIME_R_RETURNS_INT */
+ ACE_OSCALL_RETURN (::ctime_r (t, buf, buflen), ACE_TCHAR *, 0);
+# endif /* ACE_CTIME_R_RETURNS_INT */
+
+# endif /* ACE_HAS_2_PARAM_ASCTIME_R_AND_CTIME_R */
+#else /* ACE_HAS_REENTRANT_FUNCTIONS */
+# if defined (ACE_PSOS) && ! defined (ACE_PSOS_HAS_TIME)
+ ACE_OS::strsncpy (buf, "ctime-return", buflen);
+ return buf;
+# else /* ACE_PSOS && !ACE_PSOS_HAS_TIME */
+
+ ACE_TCHAR *result;
+# if defined (ACE_USES_WCHAR)
+ ACE_OSCALL (::_wctime (t), wchar_t *, 0, result);
+# else /* ACE_WIN32 */
+ ACE_OSCALL (::ctime (t), char *, 0, result);
+# endif /* ACE_WIN32 */
+ if (result != 0)
+ // This needs to be <ACE_OS::strncpy> rather than
+ // <ACE_OS::strsncpy> to avoid problems on certain platforms.
+ ACE_OS::strncpy (buf, result, buflen);
+ return buf;
+# endif /* ACE_PSOS && !ACE_PSOS_HAS_TIME */
+#endif /* ACE_HAS_PACE */
+}
+#endif /* !ACE_HAS_WINCE */
+
+ACE_INLINE struct tm *
+ACE_OS::localtime (const time_t *t)
+{
+#if defined (ACE_HAS_PACE)
+ ACE_OSCALL_RETURN (::pace_localtime (t), pace_tm*, 0);
+#elif !defined (ACE_HAS_WINCE) && !defined(ACE_PSOS) || defined (ACE_PSOS_HAS_TIME)
+ ACE_OS_TRACE ("ACE_OS::localtime");
+ ACE_OSCALL_RETURN (::localtime (t), struct tm *, 0);
+#else
+ // @@ Don't you start wondering what kind of functions
+ // does WinCE really support?
+ ACE_UNUSED_ARG (t);
+ ACE_NOTSUP_RETURN (0);
+#endif /* ACE_HAS_PACE */
+}
+
+ACE_INLINE struct tm *
+ACE_OS::gmtime (const time_t *t)
+{
+#if defined (ACE_HAS_PACE)
+ ACE_OSCALL_RETURN (::pace_gmtime (t), pace_tm*, 0);
+#elif !defined (ACE_HAS_WINCE) && !defined (ACE_PSOS) || defined (ACE_PSOS_HAS_TIME)
+ ACE_OS_TRACE ("ACE_OS::gmtime");
+ ACE_OSCALL_RETURN (::gmtime (t), struct tm *, 0);
+#else
+ // @@ WinCE doesn't have gmtime also.
+ ACE_UNUSED_ARG (t);
+ ACE_NOTSUP_RETURN (0);
+#endif /* ACE_HAS_PACE */
+}
+
+ACE_INLINE struct tm *
+ACE_OS::gmtime_r (const time_t *t, struct tm *res)
+{
+ ACE_OS_TRACE ("ACE_OS::gmtime_r");
+#if defined (ACE_HAS_PACE)
+ ACE_OSCALL_RETURN (::pace_gmtime_r (t, res), pace_tm*, 0);
+#elif defined (ACE_HAS_REENTRANT_FUNCTIONS)
+# if defined (DIGITAL_UNIX)
+ ACE_OSCALL_RETURN (::_Pgmtime_r (t, res), struct tm *, 0);
+# elif defined (HPUX_10)
+ return (::gmtime_r (t, res) == 0 ? res : (struct tm *) 0);
+# else
+ ACE_OSCALL_RETURN (::gmtime_r (t, res), struct tm *, 0);
+# endif /* DIGITAL_UNIX */
+#elif !defined (ACE_HAS_WINCE) && !defined(ACE_PSOS) || defined (ACE_PSOS_HAS_TIME)
+ struct tm *result;
+ ACE_OSCALL (::gmtime (t), struct tm *, 0, result) ;
+ if (result != 0)
+ *res = *result;
+ return res;
+#else
+ // @@ Same as ACE_OS::gmtime (), you need to implement it
+ // yourself.
+ ACE_UNUSED_ARG (t);
+ ACE_UNUSED_ARG (res);
+ ACE_NOTSUP_RETURN (0);
+#endif /* ACE_HAS_PACE */
+}
+
+ACE_INLINE char *
+ACE_OS::asctime (const struct tm *t)
+{
+#if defined (ACE_HAS_PACE)
+ ACE_OSCALL_RETURN (::pace_asctime (t), char*, 0);
+#elif !defined (ACE_HAS_WINCE) && !defined(ACE_PSOS) || defined (ACE_PSOS_HAS_TIME)
+ ACE_OS_TRACE ("ACE_OS::asctime");
+ ACE_OSCALL_RETURN (::asctime (t), char *, 0);
+#else
+ // @@ WinCE doesn't have gmtime also.
+ ACE_UNUSED_ARG (t);
+ ACE_NOTSUP_RETURN (0);
+#endif /* ACE_HAS_PACE */
+}
+
+ACE_INLINE char *
+ACE_OS::asctime_r (const struct tm *t, char *buf, int buflen)
+{
+ ACE_OS_TRACE ("ACE_OS::asctime_r");
+#if defined (ACE_HAS_PACE)
+ ACE_UNUSED_ARG (buflen);
+ ACE_OSCALL_RETURN (::pace_asctime_r (t, buf), char*, 0);
+#elif defined (ACE_HAS_REENTRANT_FUNCTIONS)
+# if defined (ACE_HAS_2_PARAM_ASCTIME_R_AND_CTIME_R)
+ char *result;
+# if defined (DIGITAL_UNIX)
+ ACE_OSCALL (::_Pasctime_r (t, buf), char *, 0, result);
+# else
+ ACE_OSCALL (::asctime_r (t, buf), char *, 0, result);
+# endif /* DIGITAL_UNIX */
+ ACE_OS::strsncpy (buf, result, buflen);
+ return buf;
+# else
+# if defined (HPUX_10)
+ return (::asctime_r(t, buf, buflen) == 0 ? buf : (char *)0);
+# else
+ ACE_OSCALL_RETURN (::asctime_r (t, buf, buflen), char *, 0);
+# endif /* HPUX_10 */
+# endif /* ACE_HAS_2_PARAM_ASCTIME_R_AND_CTIME_R */
+#elif ! defined (ACE_HAS_WINCE) && !defined(ACE_PSOS) || defined (ACE_PSOS_HAS_TIME)
+ char *result;
+ ACE_OSCALL (::asctime (t), char *, 0, result);
+ ACE_OS::strsncpy (buf, result, buflen);
+ return buf;
+#else
+ // @@ Same as ACE_OS::asctime (), you need to implement it
+ // yourself.
+ ACE_UNUSED_ARG (t);
+ ACE_UNUSED_ARG (buf);
+ ACE_UNUSED_ARG (buflen);
+ ACE_NOTSUP_RETURN (0);
+#endif /* ACE_HAS_PACE */
+}
+
+ACE_INLINE size_t
+ACE_OS::strftime (char *s, size_t maxsize, const char *format,
+ const struct tm *timeptr)
+{
+#if defined (ACE_HAS_PACE)
+ return ::pace_strftime (s, maxsize, format, timeptr);
+#elif !defined (ACE_HAS_WINCE) && !defined(ACE_PSOS) || defined (ACE_PSOS_HAS_TIME)
+ return ::strftime (s, maxsize, format, timeptr);
+#else
+ ACE_UNUSED_ARG (s);
+ ACE_UNUSED_ARG (maxsize);
+ ACE_UNUSED_ARG (format);
+ ACE_UNUSED_ARG (timeptr);
+ ACE_NOTSUP_RETURN (0);
+#endif /* ACE_HAS_PACE */
+}
+
+ACE_INLINE int
+ACE_OS::flock_init (ACE_OS::ace_flock_t *lock,
+ int flags,
+ const ACE_TCHAR *name,
+ mode_t perms)
+{
+ ACE_OS_TRACE ("ACE_OS::flock_init");
+#if defined (CHORUS)
+ lock->lockname_ = 0;
+ // Let's see if it already exists.
+ lock->handle_ = ACE_OS::shm_open (name,
+ flags | O_CREAT | O_EXCL,
+ perms);
+ if (lock->handle_ == ACE_INVALID_HANDLE)
+ {
+ if (errno == EEXIST)
+ // It's already there, so we'll just open it.
+ lock->handle_ = ACE_OS::shm_open (name,
+ flags | O_CREAT,
+ ACE_DEFAULT_FILE_PERMS);
+ else
+ return -1;
+ }
+ else
+ {
+ // We own this shared memory object! Let's set its size.
+ if (ACE_OS::ftruncate (lock->handle_,
+ sizeof (ACE_mutex_t)) == -1)
+ return -1;
+ // Note that only the owner can destroy a file lock...
+ ACE_ALLOCATOR_RETURN (lock->lockname_,
+ ACE_OS::strdup (name),
+ -1);
+ }
+ if (lock->handle_ == ACE_INVALID_HANDLE)
+ return -1;
+
+ lock->process_lock_ =
+ (ACE_mutex_t *) ACE_OS::mmap (0,
+ sizeof (ACE_mutex_t),
+ PROT_RDWR,
+ MAP_SHARED,
+ lock->handle_,
+ 0);
+ if (lock->process_lock_ == MAP_FAILED)
+ return -1;
+
+ if (lock->lockname_
+ // Only initialize it if we're the one who created it.
+ && ACE_OS::mutex_init (lock->process_lock_,
+ USYNC_PROCESS,
+ name,
+ 0) != 0)
+ return -1;
+ return 0;
+#else
+#if defined (ACE_WIN32)
+ // Once initialized, these values are never changed.
+ lock->overlapped_.Internal = 0;
+ lock->overlapped_.InternalHigh = 0;
+ lock->overlapped_.OffsetHigh = 0;
+ lock->overlapped_.hEvent = NULL;
+#endif /* ACE_WIN32 */
+ lock->handle_ = ACE_INVALID_HANDLE;
+ lock->lockname_ = 0;
+
+ if (name != 0)
+ {
+ ACE_OSCALL (ACE_OS::open (name, flags, perms),
+ ACE_HANDLE,
+ ACE_INVALID_HANDLE,
+ lock->handle_);
+ lock->lockname_ = ACE_OS::strdup (name);
+ return lock->handle_ == ACE_INVALID_HANDLE ? -1 : 0;
+ }
+ else
+ return 0;
+#endif /* CHORUS */
+}
+
+#if defined (ACE_WIN32)
+ACE_INLINE void
+ACE_OS::adjust_flock_params (ACE_OS::ace_flock_t *lock,
+ short whence,
+ off_t &start,
+ off_t &len)
+{
+ switch (whence)
+ {
+ case SEEK_SET:
+ break;
+ case SEEK_CUR:
+ start += SetFilePointer (lock->handle_, 0, 0, FILE_CURRENT);
+ break;
+ case SEEK_END:
+ start += ::GetFileSize (lock->handle_, NULL);
+ break;
+ }
+ lock->overlapped_.Offset = start;
+ if (len == 0)
+ len = ::GetFileSize (lock->handle_,
+ NULL) - start;
+}
+#endif /* ACE_WIN32 */
+
+ACE_INLINE int
+ACE_OS::flock_wrlock (ACE_OS::ace_flock_t *lock,
+ short whence,
+ off_t start,
+ off_t len)
+{
+ ACE_OS_TRACE ("ACE_OS::flock_wrlock");
+#if defined (ACE_WIN32) && !defined (ACE_HAS_WINCE)
+ ACE_OS::adjust_flock_params (lock, whence, start, len);
+# if defined (ACE_HAS_WINNT4) && (ACE_HAS_WINNT4 != 0)
+ ACE_WIN32CALL_RETURN (ACE_ADAPT_RETVAL (::LockFileEx (lock->handle_,
+ LOCKFILE_EXCLUSIVE_LOCK,
+ 0,
+ len,
+ 0,
+ &lock->overlapped_),
+ ace_result_), int, -1);
+# else /* ACE_HAS_WINNT4 && (ACE_HAS_WINNT4 != 0) */
+ ACE_WIN32CALL_RETURN (ACE_ADAPT_RETVAL (::LockFile (lock->handle_,
+ lock->overlapped_.Offset,
+ 0,
+ len,
+ 0),
+ ace_result_), int, -1);
+# endif /* ACE_HAS_WINNT4 && (ACE_HAS_WINNT4 != 0) */
+#elif defined (CHORUS)
+ ACE_UNUSED_ARG (whence);
+ ACE_UNUSED_ARG (start);
+ ACE_UNUSED_ARG (len);
+ return ACE_OS::mutex_lock (lock->process_lock_);
+#elif defined (ACE_LACKS_FILELOCKS)
+ ACE_UNUSED_ARG (lock);
+ ACE_UNUSED_ARG (whence);
+ ACE_UNUSED_ARG (start);
+ ACE_UNUSED_ARG (len);
+ ACE_NOTSUP_RETURN (-1);
+#else
+ lock->lock_.l_whence = whence;
+ lock->lock_.l_start = start;
+ lock->lock_.l_len = len;
+ lock->lock_.l_type = F_WRLCK; // set write lock
+ // block, if no access
+ ACE_OSCALL_RETURN (ACE_OS::fcntl (lock->handle_, F_SETLKW,
+ ACE_reinterpret_cast (long, &lock->lock_)),
+ int, -1);
+#endif /* ACE_WIN32 */
+}
+
+ACE_INLINE int
+ACE_OS::flock_rdlock (ACE_OS::ace_flock_t *lock,
+ short whence,
+ off_t start,
+ off_t len)
+{
+ ACE_OS_TRACE ("ACE_OS::flock_rdlock");
+#if defined (ACE_WIN32) && !defined (ACE_HAS_WINCE)
+ ACE_OS::adjust_flock_params (lock, whence, start, len);
+# if defined (ACE_HAS_WINNT4) && (ACE_HAS_WINNT4 != 0)
+ ACE_WIN32CALL_RETURN (ACE_ADAPT_RETVAL (::LockFileEx (lock->handle_,
+ 0,
+ 0,
+ len,
+ 0,
+ &lock->overlapped_),
+ ace_result_), int, -1);
+# else /* ACE_HAS_WINNT4 && (ACE_HAS_WINNT4 != 0) */
+ ACE_WIN32CALL_RETURN (ACE_ADAPT_RETVAL (::LockFile (lock->handle_,
+ lock->overlapped_.Offset,
+ 0,
+ len,
+ 0),
+ ace_result_), int, -1);
+# endif /* ACE_HAS_WINNT4 && (ACE_HAS_WINNT4 != 0) */
+#elif defined (CHORUS)
+ ACE_UNUSED_ARG (whence);
+ ACE_UNUSED_ARG (start);
+ ACE_UNUSED_ARG (len);
+ return ACE_OS::mutex_lock (lock->process_lock_);
+#elif defined (ACE_LACKS_FILELOCKS)
+ ACE_UNUSED_ARG (lock);
+ ACE_UNUSED_ARG (whence);
+ ACE_UNUSED_ARG (start);
+ ACE_UNUSED_ARG (len);
+ ACE_NOTSUP_RETURN (-1);
+#else
+ lock->lock_.l_whence = whence;
+ lock->lock_.l_start = start;
+ lock->lock_.l_len = len;
+ lock->lock_.l_type = F_RDLCK; // set read lock
+ // block, if no access
+ ACE_OSCALL_RETURN (ACE_OS::fcntl (lock->handle_, F_SETLKW,
+ ACE_reinterpret_cast (long, &lock->lock_)),
+ int, -1);
+#endif /* ACE_WIN32 */
+}
+
+ACE_INLINE int
+ACE_OS::flock_trywrlock (ACE_OS::ace_flock_t *lock,
+ short whence,
+ off_t start,
+ off_t len)
+{
+ ACE_OS_TRACE ("ACE_OS::ace_flock_trywrlock");
+#if defined (ACE_WIN32) && !defined (ACE_HAS_WINCE)
+# if defined (ACE_HAS_WINNT4) && (ACE_HAS_WINNT4 != 0)
+ ACE_OS::adjust_flock_params (lock, whence, start, len);
+ ACE_WIN32CALL_RETURN (ACE_ADAPT_RETVAL (::LockFileEx (lock->handle_,
+ LOCKFILE_FAIL_IMMEDIATELY | LOCKFILE_EXCLUSIVE_LOCK,
+ 0,
+ len,
+ 0,
+ &lock->overlapped_),
+ ace_result_), int, -1);
+# else /* ACE_HAS_WINNT4 && (ACE_HAS_WINNT4 != 0) */
+ ACE_UNUSED_ARG (lock);
+ ACE_UNUSED_ARG (whence);
+ ACE_UNUSED_ARG (start);
+ ACE_UNUSED_ARG (len);
+ ACE_NOTSUP_RETURN (-1);
+# endif /* ACE_HAS_WINNT4 && (ACE_HAS_WINNT4 != 0) */
+#elif defined (CHORUS)
+ ACE_UNUSED_ARG (whence);
+ ACE_UNUSED_ARG (start);
+ ACE_UNUSED_ARG (len);
+ return ACE_OS::mutex_trylock (lock->process_lock_);
+#elif defined (ACE_LACKS_FILELOCKS)
+ ACE_UNUSED_ARG (lock);
+ ACE_UNUSED_ARG (whence);
+ ACE_UNUSED_ARG (start);
+ ACE_UNUSED_ARG (len);
+ ACE_NOTSUP_RETURN (-1);
+#else
+ lock->lock_.l_whence = whence;
+ lock->lock_.l_start = start;
+ lock->lock_.l_len = len;
+ lock->lock_.l_type = F_WRLCK; // set write lock
+
+ int result = 0;
+ // Does not block, if no access, returns -1 and set errno = EBUSY;
+ ACE_OSCALL (ACE_OS::fcntl (lock->handle_,
+ F_SETLK,
+ ACE_reinterpret_cast (long, &lock->lock_)),
+ int, -1, result);
+
+# if ! defined (ACE_PSOS)
+ if (result == -1 && (errno == EACCES || errno == EAGAIN))
+ errno = EBUSY;
+# endif /* ! defined (ACE_PSOS) */
+
+ return result;
+#endif /* ACE_WIN32 */
+}
+
+ACE_INLINE int
+ACE_OS::flock_tryrdlock (ACE_OS::ace_flock_t *lock,
+ short whence,
+ off_t start,
+ off_t len)
+{
+ ACE_OS_TRACE ("ACE_OS::ace_flock_tryrdlock");
+#if defined (ACE_WIN32) && !defined (ACE_HAS_WINCE)
+# if defined (ACE_HAS_WINNT4) && (ACE_HAS_WINNT4 != 0)
+ ACE_OS::adjust_flock_params (lock, whence, start, len);
+ ACE_WIN32CALL_RETURN (ACE_ADAPT_RETVAL (::LockFileEx (lock->handle_,
+ LOCKFILE_FAIL_IMMEDIATELY,
+ 0,
+ len,
+ 0,
+ &lock->overlapped_),
+ ace_result_), int, -1);
+# else /* ACE_HAS_WINNT4 && (ACE_HAS_WINNT4 != 0) */
+ ACE_UNUSED_ARG (lock);
+ ACE_UNUSED_ARG (whence);
+ ACE_UNUSED_ARG (start);
+ ACE_UNUSED_ARG (len);
+ ACE_NOTSUP_RETURN (-1);
+# endif /* ACE_HAS_WINNT4 && (ACE_HAS_WINNT4 != 0) */
+#elif defined (CHORUS)
+ ACE_UNUSED_ARG (whence);
+ ACE_UNUSED_ARG (start);
+ ACE_UNUSED_ARG (len);
+ return ACE_OS::mutex_trylock (lock->process_lock_);
+#elif defined (ACE_LACKS_FILELOCKS)
+ ACE_UNUSED_ARG (lock);
+ ACE_UNUSED_ARG (whence);
+ ACE_UNUSED_ARG (start);
+ ACE_UNUSED_ARG (len);
+ ACE_NOTSUP_RETURN (-1);
+#else
+ lock->lock_.l_whence = whence;
+ lock->lock_.l_start = start;
+ lock->lock_.l_len = len;
+ lock->lock_.l_type = F_RDLCK; // set read lock
+
+ int result = 0;
+ // Does not block, if no access, returns -1 and set errno = EBUSY;
+ ACE_OSCALL (ACE_OS::fcntl (lock->handle_, F_SETLK,
+ ACE_reinterpret_cast (long, &lock->lock_)),
+ int, -1, result);
+
+# if ! defined (ACE_PSOS)
+ if (result == -1 && (errno == EACCES || errno == EAGAIN))
+ errno = EBUSY;
+# endif /* ! defined (ACE_PSOS) */
+
+ return result;
+#endif /* ACE_WIN32 */
+}
+
+ACE_INLINE int
+ACE_OS::flock_unlock (ACE_OS::ace_flock_t *lock,
+ short whence,
+ off_t start,
+ off_t len)
+{
+ ACE_OS_TRACE ("ACE_OS::flock_unlock");
+#if defined (ACE_WIN32) && !defined (ACE_HAS_WINCE)
+ ACE_OS::adjust_flock_params (lock, whence, start, len);
+ ACE_WIN32CALL_RETURN (ACE_ADAPT_RETVAL (::UnlockFile (lock->handle_,
+ lock->overlapped_.Offset,
+ 0,
+ len,
+ 0),
+ ace_result_), int, -1);
+#elif defined (CHORUS)
+ ACE_UNUSED_ARG (whence);
+ ACE_UNUSED_ARG (start);
+ ACE_UNUSED_ARG (len);
+ return ACE_OS::mutex_unlock (lock->process_lock_);
+#elif defined (ACE_LACKS_FILELOCKS)
+ ACE_UNUSED_ARG (lock);
+ ACE_UNUSED_ARG (whence);
+ ACE_UNUSED_ARG (start);
+ ACE_UNUSED_ARG (len);
+ ACE_NOTSUP_RETURN (-1);
+#else
+ lock->lock_.l_whence = whence;
+ lock->lock_.l_start = start;
+ lock->lock_.l_len = len;
+ lock->lock_.l_type = F_UNLCK; // Unlock file.
+
+ // release lock
+ ACE_OSCALL_RETURN (ACE_OS::fcntl (lock->handle_, F_SETLK,
+ ACE_reinterpret_cast (long, &lock->lock_)),
+ int, -1);
+#endif /* ACE_WIN32 */
+}
+
+ACE_INLINE int
+ACE_OS::flock_destroy (ACE_OS::ace_flock_t *lock,
+ int unlink_file)
+{
+ ACE_OS_TRACE ("ACE_OS::flock_destroy");
+ if (lock->handle_ != ACE_INVALID_HANDLE)
+ {
+ ACE_OS::flock_unlock (lock);
+ // Close the handle.
+ ACE_OS::close (lock->handle_);
+ lock->handle_ = ACE_INVALID_HANDLE;
+#if defined (CHORUS)
+ // Are we the owner?
+ if (lock->process_lock_ && lock->lockname_ != 0)
+ {
+ // Only destroy the lock if we're the owner
+ ACE_OS::mutex_destroy (lock->process_lock_);
+ ACE_OS::munmap (lock->process_lock_,
+ sizeof (ACE_mutex_t));
+ if (unlink_file)
+ ACE_OS::shm_unlink (lock->lockname_);
+ ACE_OS::free (ACE_static_cast (void *,
+ ACE_const_cast (ACE_TCHAR *,
+ lock->lockname_)));
+ }
+ else if (lock->process_lock_)
+ // Just unmap the memory.
+ ACE_OS::munmap (lock->process_lock_,
+ sizeof (ACE_mutex_t));
+#else
+ if (lock->lockname_ != 0)
+ {
+ if (unlink_file)
+ ACE_OS::unlink (lock->lockname_);
+ ACE_OS::free (ACE_static_cast (void *,
+ ACE_const_cast (ACE_TCHAR *,
+ lock->lockname_)));
+ }
+#endif /* CHORUS */
+ lock->lockname_ = 0;
+ }
+ return 0;
+}
+
+ACE_INLINE int
+ACE_OS::execv (const char *path,
+ char *const argv[])
+{
+ ACE_OS_TRACE ("ACE_OS::execv");
+#if defined (ACE_HAS_PACE)
+ ACE_OSCALL_RETURN (::pace_execv (path, argv), int, -1);
+#elif defined (ACE_LACKS_EXEC)
+ ACE_UNUSED_ARG (path);
+ ACE_UNUSED_ARG (argv);
+
+ ACE_NOTSUP_RETURN (-1);
+#elif defined (CHORUS)
+ KnCap cactorcap;
+ int result = ::afexecv (path, &cactorcap, 0, argv);
+ if (result != -1)
+ ACE_OS::actorcaps_[result] = cactorcap;
+ return result;
+#elif defined (ACE_WIN32)
+# if defined (__BORLANDC__) /* VSB */
+ return ::execv (path, argv);
+# elif defined (__MINGW32__)
+ return ::_execv (path, (char *const *) argv);
+# else
+ return ::_execv (path, (const char *const *) argv);
+# endif /* __BORLANDC__ */
+#elif defined (ACE_LACKS_POSIX_PROTOTYPES)
+ ACE_OSCALL_RETURN (::execv (path, (const char **) argv), int, -1);
+#else
+ ACE_OSCALL_RETURN (::execv (path, argv), int, -1);
+#endif /* ACE_HAS_PACE */
+}
+
+ACE_INLINE int
+ACE_OS::execve (const char *path,
+ char *const argv[],
+ char *const envp[])
+{
+ ACE_OS_TRACE ("ACE_OS::execve");
+#if defined (ACE_HAS_PACE)
+ ACE_OSCALL_RETURN (::pace_execve (path, argv, envp), int, -1);
+#elif defined (ACE_LACKS_EXEC)
+ ACE_UNUSED_ARG (path);
+ ACE_UNUSED_ARG (argv);
+ ACE_UNUSED_ARG (envp);
+
+ ACE_NOTSUP_RETURN (-1);
+#elif defined(CHORUS)
+ KnCap cactorcap;
+ int result = ::afexecve (path, &cactorcap, 0, argv, envp);
+ if (result != -1)
+ ACE_OS::actorcaps_[result] = cactorcap;
+ return result;
+#elif defined (ACE_WIN32)
+# if defined (__BORLANDC__) /* VSB */
+ return ::execve (path, argv, envp);
+# elif defined (__MINGW32__)
+ return ::_execve (path, (char *const *) argv, (char *const *) envp);
+# else
+ return ::_execve (path, (const char *const *) argv, (const char *const *) envp);
+# endif /* __BORLANDC__ */
+#elif defined (ACE_LACKS_POSIX_PROTOTYPES)
+ ACE_OSCALL_RETURN (::execve (path, (const char **) argv, (char **) envp), int, -1);
+#else
+ ACE_OSCALL_RETURN (::execve (path, argv, envp), int, -1);
+#endif /* ACE_HAS_PACE */
+}
+
+ACE_INLINE int
+ACE_OS::execvp (const char *file,
+ char *const argv[])
+{
+ ACE_OS_TRACE ("ACE_OS::execvp");
+#if defined (ACE_HAS_PACE)
+ ACE_OSCALL_RETURN (::pace_execvp (file, argv), int, -1);
+#elif defined (ACE_LACKS_EXEC)
+ ACE_UNUSED_ARG (file);
+ ACE_UNUSED_ARG (argv);
+
+ ACE_NOTSUP_RETURN (-1);
+#elif defined(CHORUS)
+ KnCap cactorcap;
+ int result = ::afexecvp (file, &cactorcap, 0, argv);
+ if (result != -1)
+ ACE_OS::actorcaps_[result] = cactorcap;
+ return result;
+#elif defined (ACE_WIN32)
+# if defined (__BORLANDC__) /* VSB */
+ return ::execvp (file, argv);
+# elif defined (__MINGW32__)
+ return ::_execvp (file, (char *const *) argv);
+# else
+ return ::_execvp (file, (const char *const *) argv);
+# endif /* __BORLANDC__ */
+#elif defined (ACE_LACKS_POSIX_PROTOTYPES)
+ ACE_OSCALL_RETURN (::execvp (file, (const char **) argv), int, -1);
+#else
+ ACE_OSCALL_RETURN (::execvp (file, argv), int, -1);
+#endif /* ACE_HAS_PACE */
+}
+
+#if !defined (ACE_HAS_WINCE)
+ACE_INLINE FILE *
+ACE_OS::fdopen (ACE_HANDLE handle, const ACE_TCHAR *mode)
+{
+ ACE_OS_TRACE ("ACE_OS::fdopen");
+#if defined (ACE_HAS_PACE) && !defined (ACE_WIN32)
+ ACE_OSCALL_RETURN (::pace_fdopen (handle, mode), FILE*, 0);
+# elif defined (ACE_WIN32)
+ // kernel file handle -> FILE* conversion...
+ // Options: _O_APPEND, _O_RDONLY and _O_TEXT are lost
+
+ FILE *file = 0;
+
+ int crt_handle = ::_open_osfhandle ((long) handle, 0);
+
+ if (crt_handle != -1)
+ {
+# if defined(__BORLANDC__) /* VSB */
+ file = ::_fdopen (crt_handle, (char *) mode);
+# elif defined (ACE_USES_WCHAR)
+ file = ::_wfdopen (crt_handle, mode);
+# else
+ file = ::_fdopen (crt_handle, mode);
+# endif /* __BORLANDC__ */
+
+ if (!file)
+ {
+# if (defined(__BORLANDC__) && __BORLANDC__ >= 0x0530)
+ ::_rtl_close (crt_handle);
+# else
+ ::_close (crt_handle);
+# endif /* (defined(__BORLANDC__) && __BORLANDC__ >= 0x0530) */
+ }
+ }
+
+ return file;
+# elif defined (ACE_PSOS)
+ // @@ it may be possible to implement this for pSOS,
+ // but it isn't obvious how to do this (perhaps via
+ // f_stat to glean the default volume, and then open_fn ?)
+ ACE_UNUSED_ARG (handle);
+ ACE_UNUSED_ARG (mode);
+ ACE_NOTSUP_RETURN (0);
+# else
+ ACE_OSCALL_RETURN (::fdopen (handle, mode), FILE *, 0);
+# endif /* ACE_HAS_PACE */
+}
+#endif /* ! ACE_HAS_WINCE */
+
+ACE_INLINE int
+ACE_OS::getrlimit (int resource, struct rlimit *rl)
+{
+ ACE_OS_TRACE ("ACE_OS::getrlimit");
+
+#if defined (ACE_LACKS_RLIMIT)
+ ACE_UNUSED_ARG (resource);
+ ACE_UNUSED_ARG (rl);
+
+ ACE_NOTSUP_RETURN (-1);
+#else
+# if defined (ACE_HAS_RLIMIT_RESOURCE_ENUM)
+ ACE_OSCALL_RETURN (::getrlimit ((ACE_HAS_RLIMIT_RESOURCE_ENUM) resource, rl), int, -1);
+# else
+ ACE_OSCALL_RETURN (::getrlimit (resource, rl), int, -1);
+# endif /* ACE_HAS_RLIMIT_RESOURCE_ENUM */
+#endif /* ACE_LACKS_RLIMIT */
+}
+
+ACE_INLINE int
+ACE_OS::setrlimit (int resource, ACE_SETRLIMIT_TYPE *rl)
+{
+ ACE_OS_TRACE ("ACE_OS::setrlimit");
+
+#if defined (ACE_LACKS_RLIMIT)
+ ACE_UNUSED_ARG (resource);
+ ACE_UNUSED_ARG (rl);
+
+ ACE_NOTSUP_RETURN (-1);
+#else
+# if defined (ACE_HAS_RLIMIT_RESOURCE_ENUM)
+ ACE_OSCALL_RETURN (::setrlimit ((ACE_HAS_RLIMIT_RESOURCE_ENUM) resource, rl), int, -1);
+# else
+ ACE_OSCALL_RETURN (::setrlimit (resource, rl), int, -1);
+# endif /* ACE_HAS_RLIMIT_RESOURCE_ENUM */
+#endif /* ACE_LACKS_RLIMIT */
+}
+
+ACE_INLINE int
+ACE_OS::socketpair (int domain, int type,
+ int protocol, ACE_HANDLE sv[2])
+{
+ ACE_OS_TRACE ("ACE_OS::socketpair");
+#if defined (ACE_WIN32) || defined (ACE_LACKS_SOCKETPAIR)
+ ACE_UNUSED_ARG (domain);
+ ACE_UNUSED_ARG (type);
+ ACE_UNUSED_ARG (protocol);
+ ACE_UNUSED_ARG (sv);
+
+ ACE_NOTSUP_RETURN (-1);
+#else
+ ACE_OSCALL_RETURN (::socketpair (domain, type, protocol, sv),
+ int, -1);
+#endif /* ACE_WIN32 */
+}
+
+ACE_INLINE ACE_HANDLE
+ACE_OS::dup (ACE_HANDLE handle)
+{
+ ACE_OS_TRACE ("ACE_OS::dup");
+#if defined (ACE_HAS_PACE)
+ ACE_OSCALL_RETURN (::pace_dup (handle), ACE_HANDLE, ACE_INVALID_HANDLE);
+#elif defined (ACE_WIN32) && !defined (ACE_HAS_WINCE)
+ ACE_HANDLE new_fd;
+ if (::DuplicateHandle(::GetCurrentProcess (),
+ handle,
+ ::GetCurrentProcess(),
+ &new_fd,
+ 0,
+ TRUE,
+ DUPLICATE_SAME_ACCESS))
+ return new_fd;
+ else
+ ACE_FAIL_RETURN (ACE_INVALID_HANDLE);
+ /* NOTREACHED */
+#elif defined (VXWORKS) || defined (ACE_PSOS)
+ ACE_UNUSED_ARG (handle);
+ ACE_NOTSUP_RETURN (-1);
+#elif defined (ACE_HAS_WINCE)
+ ACE_UNUSED_ARG (handle);
+ ACE_NOTSUP_RETURN (0);
+#else
+ ACE_OSCALL_RETURN (::dup (handle), ACE_HANDLE, ACE_INVALID_HANDLE);
+#endif /* ACE_HAS_PACE */
+}
+
+ACE_INLINE int
+ACE_OS::dup2 (ACE_HANDLE oldhandle, ACE_HANDLE newhandle)
+{
+ ACE_OS_TRACE ("ACE_OS::dup2");
+#if defined (ACE_HAS_PACE)
+ ACE_OSCALL_RETURN (::pace_dup2 (oldhandle, newhandle), int, -1);
+#elif defined (ACE_WIN32) || defined (VXWORKS) || defined (ACE_PSOS)
+ // msvcrt has _dup2 ?!
+ ACE_UNUSED_ARG (oldhandle);
+ ACE_UNUSED_ARG (newhandle);
+
+ ACE_NOTSUP_RETURN (-1);
+#else
+ ACE_OSCALL_RETURN (::dup2 (oldhandle, newhandle), int, -1);
+#endif /* ACE_HAS_PACE */
+}
+
+#if defined (ghs) && defined (ACE_HAS_PENTIUM) && !defined (ACE_WIN32)
+ extern "C" ACE_hrtime_t ACE_gethrtime ();
+#endif /* ghs && ACE_HAS_PENTIUM */
+
+ACE_INLINE ACE_hrtime_t
+ACE_OS::gethrtime (const ACE_HRTimer_Op op)
+{
+ ACE_OS_TRACE ("ACE_OS::gethrtime");
+#if defined (ACE_HAS_HI_RES_TIMER)
+ ACE_UNUSED_ARG (op);
+ return ::gethrtime ();
+#elif defined (ACE_HAS_AIX_HI_RES_TIMER)
+ ACE_UNUSED_ARG (op);
+ timebasestruct_t tb;
+
+ ::read_real_time(&tb, TIMEBASE_SZ);
+ ::time_base_to_time(&tb, TIMEBASE_SZ);
+
+ return ACE_hrtime_t(tb.tb_high) * ACE_ONE_SECOND_IN_NSECS + tb.tb_low;
+#elif defined (ghs) && defined (ACE_HAS_PENTIUM) && !defined (ACE_WIN32)
+ ACE_UNUSED_ARG (op);
+ // Use .obj/gethrtime.o, which was compiled with g++.
+ return ACE_gethrtime ();
+#elif (defined(__KCC) || defined (__GNUG__)) && !defined (__MINGW32__) && defined (ACE_HAS_PENTIUM)
+ ACE_UNUSED_ARG (op);
+
+# if defined (ACE_LACKS_LONGLONG_T)
+ double now;
+# else /* ! ACE_LACKS_LONGLONG_T */
+ ACE_hrtime_t now;
+# endif /* ! ACE_LACKS_LONGLONG_T */
+
+ // See comments about the RDTSC Pentium instruction for the ACE_WIN32
+ // version of ACE_OS::gethrtime (), below.
+ //
+ // Read the high-res tick counter directly into memory variable "now".
+ // The A constraint signifies a 64-bit int.
+ asm volatile ("rdtsc" : "=A" (now) : : "memory");
+
+# if defined (ACE_LACKS_LONGLONG_T)
+ ACE_UINT32 least, most;
+ ACE_OS::memcpy (&least, &now, sizeof (ACE_UINT32));
+ ACE_OS::memcpy (&most, (u_char *) &now + sizeof (ACE_UINT32),
+ sizeof (ACE_UINT32));
+
+ ACE_hrtime_t ret (least, most);
+ return ret;
+# else /* ! ACE_LACKS_LONGLONG_T */
+ return now;
+# endif /* ! ACE_LACKS_LONGLONG_T */
+#elif defined (linux) && defined (ACE_HAS_ALPHA_TIMER)
+ // NOTE: alphas only have a 32 bit tick (cycle) counter. The rpcc
+ // instruction actually reads 64 bits, but the high 32 bits are
+ // implementation-specific. Linux and Digital Unix, for example,
+ // use them for virtual tick counts, i.e., taking into account only
+ // the time that the process was running. This information is from
+ // David Mosberger's article, see comment below.
+ ACE_UINT32 now;
+
+ // The following statement is based on code published by:
+ // Mosberger, David, "How to Make Your Applications Fly, Part 1",
+ // Linux Journal Issue 42, October 1997, page 50. It reads the
+ // high-res tick counter directly into the memory variable.
+ asm volatile ("rpcc %0" : "=r" (now) : : "memory");
+
+ return now;
+#elif defined (ACE_WIN32)
+ ACE_UNUSED_ARG(op);
+ LARGE_INTEGER freq;
+
+ ::QueryPerformanceCounter (&freq);
+
+# if defined (ACE_LACKS_LONGLONG_T)
+ ACE_UINT64 uint64_freq(freq.u.LowPart, ACE_static_cast (unsigned int, freq.u.HighPart));
+ return uint64_freq;
+# else
+ return freq.QuadPart;
+# endif //ACE_LACKS_LONGLONG_T
+
+#elif defined (CHORUS)
+ if (op == ACE_OS::ACE_HRTIMER_GETTIME)
+ {
+ struct timespec ts;
+
+ ACE_OS::clock_gettime (CLOCK_REALTIME, &ts);
+
+ // Carefully create the return value to avoid arithmetic overflow
+ // if ACE_hrtime_t is ACE_U_LongLong.
+ ACE_hrtime_t now = ts.tv_sec;
+ now *= ACE_U_ONE_SECOND_IN_NSECS;
+ now += ts.tv_nsec;
+
+ return now;
+ }
+ else
+ {
+ // Use the sysBench timer on Chorus. On MVME177, at least, it only
+ // has 32 bits. Be careful, because using it disables interrupts!
+ ACE_UINT32 now;
+ if (::sysBench (op, (int *) &now) == K_OK)
+ {
+ now *= 1000u /* nanoseconds/microsecond */;
+ return (ACE_hrtime_t) now;
+ }
+ else
+ {
+ // Something went wrong. Just return 0.
+ return (ACE_hrtime_t) 0;
+ }
+ }
+
+#elif defined (ACE_HAS_POWERPC_TIMER) && (defined (ghs) || defined (__GNUG__))
+ // PowerPC w/ GreenHills or g++.
+
+ ACE_UNUSED_ARG (op);
+ u_long most;
+ u_long least;
+ ACE_OS::readPPCTimeBase (most, least);
+#if defined (ACE_LACKS_LONGLONG_T)
+ return ACE_U_LongLong (least, most);
+#else /* ! ACE_LACKS_LONGLONG_T */
+ return 0x100000000llu * most + least;
+#endif /* ! ACE_LACKS_LONGLONG_T */
+
+#elif defined (ACE_HAS_CLOCK_GETTIME) || defined (ACE_PSOS)
+ // e.g., VxWorks (besides POWERPC && GreenHills) . . .
+ ACE_UNUSED_ARG (op);
+ struct timespec ts;
+
+ ACE_OS::clock_gettime (CLOCK_REALTIME, &ts);
+
+ // Carefully create the return value to avoid arithmetic overflow
+ // if ACE_hrtime_t is ACE_U_LongLong.
+ return ACE_static_cast (ACE_hrtime_t, ts.tv_sec) *
+ ACE_U_ONE_SECOND_IN_NSECS + ACE_static_cast (ACE_hrtime_t, ts.tv_nsec);
+#else
+ ACE_UNUSED_ARG (op);
+ const ACE_Time_Value now = ACE_OS::gettimeofday ();
+
+ // Carefully create the return value to avoid arithmetic overflow
+ // if ACE_hrtime_t is ACE_U_LongLong.
+ return (ACE_static_cast (ACE_hrtime_t, now.sec ()) * (ACE_UINT32) 1000000 +
+ ACE_static_cast (ACE_hrtime_t, now.usec ())) * (ACE_UINT32) 1000;
+#endif /* ACE_HAS_HI_RES_TIMER */
+}
+
+ACE_INLINE int
+ACE_OS::fdetach (const char *file)
+{
+ ACE_OS_TRACE ("ACE_OS::fdetach");
+#if defined (ACE_HAS_STREAM_PIPES)
+ ACE_OSCALL_RETURN (::fdetach (file), int, -1);
+#else
+ ACE_UNUSED_ARG (file);
+
+ ACE_NOTSUP_RETURN (-1);
+#endif /* ACE_HAS_STREAM_PIPES */
+}
+
+ACE_INLINE int
+ACE_OS::fattach (int handle, const char *path)
+{
+ ACE_OS_TRACE ("ACE_OS::fattach");
+#if defined (ACE_HAS_STREAM_PIPES)
+ ACE_OSCALL_RETURN (::fattach (handle, path), int, -1);
+#else
+ ACE_UNUSED_ARG (handle);
+ ACE_UNUSED_ARG (path);
+
+ ACE_NOTSUP_RETURN (-1);
+#endif /* ACE_HAS_STREAM_PIPES */
+}
+
+ACE_INLINE pid_t
+ACE_OS::fork (void)
+{
+ ACE_OS_TRACE ("ACE_OS::fork");
+#if defined (ACE_HAS_PACE)
+ ACE_OSCALL_RETURN (::pace_fork (), pid_t, -1);
+#elif defined (ACE_LACKS_FORK)
+ ACE_NOTSUP_RETURN (pid_t (-1));
+#else
+ ACE_OSCALL_RETURN (::fork (), pid_t, -1);
+#endif /* ACE_HAS_PACE */
+}
+
+ACE_INLINE int
+ACE_OS::getpagesize (void)
+{
+ ACE_OS_TRACE ("ACE_OS::getpagesize");
+#if defined (ACE_WIN32) && !defined (ACE_HAS_PHARLAP)
+ SYSTEM_INFO sys_info;
+ ::GetSystemInfo (&sys_info);
+ return (int) sys_info.dwPageSize;
+#elif defined (_SC_PAGESIZE)
+ return (int) ::sysconf (_SC_PAGESIZE);
+#elif defined (ACE_HAS_GETPAGESIZE)
+ return ::getpagesize ();
+#else
+ // Use the default set in config.h
+ return ACE_PAGE_SIZE;
+#endif /* ACE_WIN32 */
+}
+
+ACE_INLINE int
+ACE_OS::allocation_granularity (void)
+{
+#if defined (ACE_WIN32)
+ SYSTEM_INFO sys_info;
+ ::GetSystemInfo (&sys_info);
+ return (int) sys_info.dwAllocationGranularity;
+#else
+ return ACE_OS::getpagesize ();
+#endif /* ACE_WIN32 */
+}
+
+ACE_INLINE pid_t
+ACE_OS::getpid (void)
+{
+ // ACE_OS_TRACE ("ACE_OS::getpid");
+#if defined (ACE_HAS_PACE)
+ ACE_OSCALL_RETURN (::pace_getpid (), int , -1);
+#elif defined (ACE_WIN32)
+ return ::GetCurrentProcessId ();
+#elif defined (VXWORKS) || defined (ACE_PSOS)
+ // getpid() is not supported: just one process anyways
+ return 0;
+#elif defined (CHORUS)
+ return (pid_t) (::agetId ());
+#else
+ ACE_OSCALL_RETURN (::getpid (), int, -1);
+#endif /* ACE_HAS_PACE */
+}
+
+ACE_INLINE pid_t
+ACE_OS::getpgid (pid_t pid)
+{
+ ACE_OS_TRACE ("ACE_OS::getpgid");
+#if defined (ACE_LACKS_GETPGID)
+ ACE_UNUSED_ARG (pid);
+ ACE_NOTSUP_RETURN (-1);
+#elif defined (VXWORKS) || defined (ACE_PSOS)
+ // getpgid() is not supported, only one process anyway.
+ ACE_UNUSED_ARG (pid);
+ return 0;
+#elif defined (linux) && __GLIBC__ > 1 && __GLIBC_MINOR__ >= 0
+ // getpgid() is from SVR4, which appears to be the reason why GLIBC
+ // doesn't enable its prototype by default.
+ // Rather than create our own extern prototype, just use the one
+ // that is visible (ugh).
+ ACE_OSCALL_RETURN (::__getpgid (pid), pid_t, -1);
+#else
+ ACE_OSCALL_RETURN (::getpgid (pid), pid_t, -1);
+#endif /* ACE_WIN32 */
+}
+
+ACE_INLINE pid_t
+ACE_OS::getppid (void)
+{
+ ACE_OS_TRACE ("ACE_OS::getppid");
+#if defined (ACE_HAS_PACE)
+ ACE_OSCALL_RETURN (::pace_getppid (), pid_t, -1);
+#elif defined (ACE_LACKS_GETPPID)
+ ACE_NOTSUP_RETURN (-1);
+#elif defined (VXWORKS) || defined (ACE_PSOS)
+ // getppid() is not supported, only one process anyway.
+ return 0;
+#else
+ ACE_OSCALL_RETURN (::getppid (), pid_t, -1);
+#endif /* ACE_WIN32 */
+}
+
+ACE_INLINE int
+ACE_OS::setpgid (pid_t pid, pid_t pgid)
+{
+ ACE_OS_TRACE ("ACE_OS::setpgid");
+#if defined (ACE_HAS_PACE)
+ ACE_OSCALL_RETURN (::pace_setpgid (pid, pgid), int, -1);
+#elif defined (ACE_LACKS_SETPGID)
+ ACE_UNUSED_ARG (pid);
+ ACE_UNUSED_ARG (pgid);
+ ACE_NOTSUP_RETURN (-1);
+#elif defined (VXWORKS) || defined (ACE_PSOS)
+ // <setpgid> is not supported, only one process anyway.
+ ACE_UNUSED_ARG (pid);
+ ACE_UNUSED_ARG (pgid);
+ return 0;
+#else
+ ACE_OSCALL_RETURN (::setpgid (pid, pgid), int, -1);
+#endif /* ACE_HAS_PACE */
+}
+
+ACE_INLINE int
+ACE_OS::setreuid (uid_t ruid, uid_t euid)
+{
+ ACE_OS_TRACE ("ACE_OS::setreuid");
+#if defined (ACE_LACKS_SETREUID)
+ ACE_UNUSED_ARG (ruid);
+ ACE_UNUSED_ARG (euid);
+ ACE_NOTSUP_RETURN (-1);
+#elif defined (VXWORKS) || defined (ACE_PSOS)
+ // <setpgid> is not supported, only one process anyway.
+ ACE_UNUSED_ARG (ruid);
+ ACE_UNUSED_ARG (euid);
+ return 0;
+#else
+ ACE_OSCALL_RETURN (::setreuid (ruid, euid), int, -1);
+#endif /* ACE_WIN32 */
+}
+
+ACE_INLINE int
+ACE_OS::setregid (gid_t rgid, gid_t egid)
+{
+ ACE_OS_TRACE ("ACE_OS::setregid");
+#if defined (ACE_LACKS_SETREGID)
+ ACE_UNUSED_ARG (rgid);
+ ACE_UNUSED_ARG (egid);
+ ACE_NOTSUP_RETURN (-1);
+#elif defined (VXWORKS) || defined (ACE_PSOS)
+ // <setregid> is not supported, only one process anyway.
+ ACE_UNUSED_ARG (rgid);
+ ACE_UNUSED_ARG (egid);
+ return 0;
+#else
+ ACE_OSCALL_RETURN (::setregid (rgid, egid), int, -1);
+#endif /* ACE_WIN32 */
+}
+
+ACE_INLINE off_t
+ACE_OS::lseek (ACE_HANDLE handle, off_t offset, int whence)
+{
+ ACE_OS_TRACE ("ACE_OS::lseek");
+#if defined (ACE_HAS_PACE)
+ ACE_OSCALL_RETURN (::pace_lseek (handle, offset, whence), pace_off_t, -1);
+#elif defined (ACE_WIN32)
+# if SEEK_SET != FILE_BEGIN || SEEK_CUR != FILE_CURRENT || SEEK_END != FILE_END
+ //#error Windows NT is evil AND rude!
+ switch (whence)
+ {
+ case SEEK_SET:
+ whence = FILE_BEGIN;
+ break;
+ case SEEK_CUR:
+ whence = FILE_CURRENT;
+ break;
+ case SEEK_END:
+ whence = FILE_END;
+ break;
+ default:
+ errno = EINVAL;
+ return ACE_static_cast (off_t, -1); // rather safe than sorry
+ }
+# endif /* SEEK_SET != FILE_BEGIN || SEEK_CUR != FILE_CURRENT || SEEK_END != FILE_END */
+ DWORD result = ::SetFilePointer (handle, offset, NULL, whence);
+ if (result == ACE_SYSCALL_FAILED)
+ ACE_FAIL_RETURN (ACE_static_cast (off_t, -1));
+ else
+ return result;
+#elif defined (ACE_PSOS)
+# if defined (ACE_PSOS_LACKS_PHILE)
+ ACE_UNUSED_ARG (handle);
+ ACE_UNUSED_ARG (offset);
+ ACE_UNUSED_ARG (whence);
+ ACE_NOTSUP_RETURN (ACE_static_cast (off_t, -1));
+# else
+ unsigned long oldptr, newptr, result;
+ // seek to the requested position
+ result = ::lseek_f (handle, whence, offset, &oldptr);
+ if (result != 0)
+ {
+ errno = result;
+ return ACE_static_cast (off_t, -1);
+ }
+ // now do a dummy seek to the current position to obtain the position
+ result = ::lseek_f (handle, SEEK_CUR, 0, &newptr);
+ if (result != 0)
+ {
+ errno = result;
+ return ACE_static_cast (off_t, -1);
+ }
+ return ACE_static_cast (off_t, newptr);
+# endif /* defined (ACE_PSOS_LACKS_PHILE */
+#else
+ ACE_OSCALL_RETURN (::lseek (handle, offset, whence), off_t, -1);
+#endif /* ACE_HAS_PACE */
+}
+
+#if defined (ACE_HAS_LLSEEK) || defined (ACE_HAS_LSEEK64)
+ACE_INLINE ACE_LOFF_T
+ACE_OS::llseek (ACE_HANDLE handle, ACE_LOFF_T offset, int whence)
+{
+ ACE_OS_TRACE ("ACE_OS::llseek");
+
+#if ACE_SIZEOF_LONG == 8
+ /* The native lseek is 64 bit. Use it. */
+ return ACE_OS::lseek (handle, offset, whence);
+#elif defined (ACE_HAS_LLSEEK) && defined (ACE_HAS_LSEEK64)
+# error Either ACE_HAS_LSEEK64 and ACE_HAS_LLSEEK should be defined, not both!
+#elif defined (ACE_HAS_LSEEK64)
+ ACE_OSCALL_RETURN (::lseek64 (handle, offset, whence), ACE_LOFF_T, -1);
+#elif defined (ACE_HAS_LLSEEK)
+ # if defined (ACE_WIN32)
+ LARGE_INTEGER li;
+ li.QuadPart = offset;
+ li.LowPart = ::SetFilePointer (handle, li.LowPart, &li.HighPart, whence);
+ if (li.LowPart == 0xFFFFFFFF && GetLastError() != NO_ERROR)
+ li.QuadPart = -1;
+ return li.QuadPart;
+ # else
+ ACE_OSCALL_RETURN (::llseek (handle, offset, whence), ACE_LOFF_T, -1);
+ # endif /* WIN32 */
+#endif
+}
+#endif /* ACE_HAS_LLSEEK || ACE_HAS_LSEEK64 */
+
+ACE_INLINE int
+ACE_OS::fseek (FILE *fp, long offset, int whence)
+{
+#if defined (ACE_HAS_PACE)
+ ACE_OSCALL_RETURN (::pace_fseek (fp, offset, whence), int, -1);
+#elif defined (ACE_HAS_WINCE)
+ return ACE_OS::lseek (fp, offset, whence);
+#else /* ACE_HAS_WINCE */
+# if defined (ACE_WIN32)
+# if SEEK_SET != FILE_BEGIN || SEEK_CUR != FILE_CURRENT || SEEK_END != FILE_END
+ //#error Windows NT is evil AND rude!
+ switch (whence)
+ {
+ case SEEK_SET:
+ whence = FILE_BEGIN;
+ break;
+ case SEEK_CUR:
+ whence = FILE_CURRENT;
+ break;
+ case SEEK_END:
+ whence = FILE_END;
+ break;
+ default:
+ errno = EINVAL;
+ return -1; // rather safe than sorry
+ }
+# endif /* SEEK_SET != FILE_BEGIN || SEEK_CUR != FILE_CURRENT || SEEK_END != FILE_END */
+# endif /* ACE_WIN32 */
+ ACE_OSCALL_RETURN (::fseek (fp, offset, whence), int, -1);
+#endif /* ACE_HAS_PACE */
+}
+
+ACE_INLINE pid_t
+ACE_OS::waitpid (pid_t pid,
+ ACE_exitcode *status,
+ int wait_options,
+ ACE_HANDLE handle)
+{
+ ACE_OS_TRACE ("ACE_OS::waitpid");
+#if defined (ACE_HAS_PACE) && !defined (ACE_WIN32)
+ ACE_UNUSED_ARG (handle);
+ ACE_OSCALL_RETURN (::pace_waitpid (pid, status, wait_options), int, -1);
+#elif defined (VXWORKS) || defined (ACE_PSOS)
+ ACE_UNUSED_ARG (pid);
+ ACE_UNUSED_ARG (status);
+ ACE_UNUSED_ARG (wait_options);
+ ACE_UNUSED_ARG (handle);
+
+ ACE_NOTSUP_RETURN (0);
+#elif defined (ACE_WIN32)
+ int blocking_period = ACE_BIT_ENABLED (wait_options, WNOHANG)
+ ? 0 /* don't hang */
+ : INFINITE;
+
+ ACE_HANDLE phandle = handle;
+
+ if (phandle == 0)
+ {
+ phandle = ::OpenProcess (SYNCHRONIZE,
+ FALSE,
+ pid);
+
+ if (phandle == 0)
+ {
+ ACE_OS::set_errno_to_last_error ();
+ return -1;
+ }
+ }
+
+ pid_t result = pid;
+
+ // Don't try to get the process exit status if wait failed so we can
+ // keep the original error code intact.
+ switch (::WaitForSingleObject (phandle,
+ blocking_period))
+ {
+ case WAIT_OBJECT_0:
+ if (status != 0)
+ // The error status of <GetExitCodeProcess> is nonetheless
+ // not tested because we don't know how to return the value.
+ ::GetExitCodeProcess (phandle,
+ status);
+ break;
+ case WAIT_TIMEOUT:
+ errno = ETIME;
+ result = 0;
+ break;
+ default:
+ ACE_OS::set_errno_to_last_error ();
+ result = -1;
+ }
+ if (handle == 0)
+ ::CloseHandle (phandle);
+ return result;
+#elif defined (CHORUS)
+ ACE_UNUSED_ARG (status);
+ ACE_UNUSED_ARG (wait_options);
+ ACE_UNUSED_ARG (handle);
+ ACE_OSCALL_RETURN (::await (&ACE_OS::actorcaps_[pid]),
+ pid_t, -1);
+#else
+ ACE_UNUSED_ARG (handle);
+ ACE_OSCALL_RETURN (::waitpid (pid, status, wait_options),
+ pid_t, -1);
+#endif /* ACE_HAS_PACE */
+}
+
+ACE_INLINE pid_t
+ACE_OS::wait (pid_t pid,
+ ACE_exitcode *status,
+ int wait_options,
+ ACE_HANDLE handle)
+{
+ ACE_OS_TRACE ("ACE_OS::wait");
+ return ACE_OS::waitpid (pid,
+ status,
+ wait_options,
+ handle);
+}
+
+ACE_INLINE pid_t
+ACE_OS::wait (int *status)
+{
+ ACE_OS_TRACE ("ACE_OS::wait");
+#if defined (ACE_HAS_PACE)
+ ACE_OSCALL_RETURN (::pace_wait (status), pace_pid_t, -1);
+#elif defined (ACE_WIN32) || defined (VXWORKS) || defined(CHORUS) || defined (ACE_PSOS)
+ ACE_UNUSED_ARG (status);
+
+ ACE_NOTSUP_RETURN (0);
+#else
+# if defined (ACE_HAS_UNION_WAIT)
+ ACE_OSCALL_RETURN (::wait ((union wait *) status), pid_t, -1);
+# else
+ ACE_OSCALL_RETURN (::wait (status), pid_t, -1);
+# endif /* ACE_HAS_UNION_WAIT */
+#endif /* ACE_HAS_PACE */
+}
+
+ACE_INLINE int
+ACE_OS::ioctl (ACE_HANDLE handle,
+ int cmd,
+ void *val)
+{
+ ACE_OS_TRACE ("ACE_OS::ioctl");
+
+#if defined (ACE_WIN32)
+ ACE_SOCKET sock = (ACE_SOCKET) handle;
+ ACE_SOCKCALL_RETURN (::ioctlsocket (sock, cmd, (u_long *) val), int, -1);
+#elif defined (VXWORKS)
+ ACE_OSCALL_RETURN (::ioctl (handle, cmd, ACE_reinterpret_cast (int, val)),
+ int, -1);
+#elif defined (ACE_PSOS)
+ ACE_OSCALL_RETURN (::ioctl (handle, cmd, (char *) val), int, -1);
+#elif defined (__CYGWIN32__)
+ ACE_UNUSED_ARG (handle);
+ ACE_UNUSED_ARG (cmd);
+ ACE_UNUSED_ARG (val);
+ ACE_NOTSUP_RETURN (-1);
+#else
+ ACE_OSCALL_RETURN (::ioctl (handle, cmd, val), int, -1);
+#endif /* ACE_WIN32 */
+}
+
+ACE_INLINE int
+ACE_OS::kill (pid_t pid, int signum)
+{
+ ACE_OS_TRACE ("ACE_OS::kill");
+#if defined (ACE_HAS_PACE)
+ ACE_OSCALL_RETURN (::pace_kill (pid, signum), int, -1);
+#elif defined (ACE_WIN32) || defined (CHORUS) || defined (ACE_PSOS)
+ ACE_UNUSED_ARG (pid);
+ ACE_UNUSED_ARG (signum);
+ ACE_NOTSUP_RETURN (-1);
+#else
+ ACE_OSCALL_RETURN (::kill (pid, signum), int, -1);
+#endif /* ACE_HAS_PACE */
+}
+
+ACE_INLINE int
+ACE_OS::sigaction (int signum,
+ const struct sigaction *nsa,
+ struct sigaction *osa)
+{
+ ACE_OS_TRACE ("ACE_OS::sigaction");
+ if (signum == 0)
+ return 0;
+#if defined (ACE_HAS_PACE) && !defined (ACE_WIN32)
+ ACE_OSCALL_RETURN (::pace_sigaction (signum, nsa, osa), int, -1);
+#elif defined (ACE_WIN32) && !defined (ACE_HAS_WINCE)
+ struct sigaction sa;
+
+ if (osa == 0)
+ osa = &sa;
+
+ if (nsa == 0)
+ {
+ osa->sa_handler = ::signal (signum, SIG_IGN);
+ ::signal (signum, osa->sa_handler);
+ }
+ else
+ osa->sa_handler = ::signal (signum, nsa->sa_handler);
+ return osa->sa_handler == SIG_ERR ? -1 : 0;
+#elif defined (CHORUS) || defined (ACE_HAS_WINCE) || defined(ACE_PSOS)
+ ACE_UNUSED_ARG (signum);
+ ACE_UNUSED_ARG (nsa);
+ ACE_UNUSED_ARG (osa);
+ ACE_NOTSUP_RETURN (-1);
+#elif defined (ACE_LACKS_POSIX_PROTOTYPES) || defined (ACE_LACKS_SOME_POSIX_PROTOTYPES)
+ ACE_OSCALL_RETURN (::sigaction (signum, (struct sigaction*) nsa, osa), int, -1);
+#else
+ ACE_OSCALL_RETURN (::sigaction (signum, nsa, osa), int, -1);
+#endif /* ACE_HAS_PACE */
+}
+
+ACE_INLINE ACE_TCHAR *
+ACE_OS::getcwd (ACE_TCHAR *buf, size_t size)
+{
+ ACE_OS_TRACE ("ACE_OS::getcwd");
+#if defined (ACE_HAS_PACE)
+ ACE_OSCALL_RETURN (::pace_getcwd (buf, size), char*, 0);
+#elif defined (ACE_PSOS_LACKS_PHILE)
+ ACE_UNUSED_ARG (buf);
+ ACE_UNUSED_ARG (size);
+ ACE_NOTSUP_RETURN ( (char*)-1);
+#elif defined (ACE_PSOS)
+
+ static char pathbuf [BUFSIZ];
+
+ // blank the path buffer
+ ACE_OS::memset (pathbuf, '\0', BUFSIZ);
+
+ // the following was suggested in the documentation for get_fn ()
+ u_long result;
+ char cur_dir_name [BUFSIZ] = ".";
+
+ u_long cur_dir = 0, prev_dir = 0;
+ while ((ACE_OS::strlen (pathbuf) < BUFSIZ) &&
+ (ACE_OS::strlen (cur_dir_name) < BUFSIZ - ACE_OS::strlen ("/..")))
+ {
+ // get the current directory handle
+ result = ::get_fn (cur_dir_name, &cur_dir);
+
+ // check whether we're at the root: this test is
+ // really lame, but the get_fn documentation says
+ // *either* condition indicates you're trying to
+ // move above the root.
+ if ((result != 0) || ( cur_dir == prev_dir))
+ {
+ break;
+ }
+
+ // change name to the parent directory
+ ACE_OS::strcat (cur_dir_name, "/..");
+
+ // open the parent directory
+ XDIR xdir;
+ result = ::open_dir (cur_dir_name, &xdir);
+ if (result != 0)
+ {
+ return 0;
+ }
+
+ // look for an entry that matches the current directory handle
+ struct dirent dir_entry;
+ while (1)
+ {
+ // get the next directory entry
+ result = ::read_dir (&xdir, &dir_entry);
+ if (result != 0)
+ {
+ return 0;
+ }
+
+ // check for a match
+ if (dir_entry.d_filno == cur_dir)
+ {
+ // prefix the previous path with the entry's name and break
+ if (ACE_OS::strlen (pathbuf) + ACE_OS::strlen (dir_entry.d_name) < BUFSIZ)
+ {
+ ACE_OS::strcpy (pathbuf + ACE_OS::strlen (dir_entry.d_name), pathbuf);
+ ACE_OS::strcpy (pathbuf, dir_entry.d_name);
+ break;
+ }
+ else
+ {
+ // we're out of room in the buffer
+ return 0;
+ }
+ }
+ }
+
+ // close the parent directory
+ result = ::close_dir (&xdir);
+ if (result != 0)
+ {
+ return 0;
+ }
+
+ // save the current directory handle as the previous
+ prev_dir = cur_dir;
+ }
+
+ // return the path, if there is one
+ return (ACE_OS::strlen (pathbuf) > 0) ? pathbuf : (char *) 0;
+#elif defined (ACE_HAS_WINCE)
+ ACE_UNUSED_ARG (buf);
+ ACE_UNUSED_ARG (size);
+ ACE_NOTSUP_RETURN (0);
+#elif defined (ACE_WIN32) && defined (ACE_USES_WCHAR)
+ return ::_wgetcwd (buf, size);
+#else
+ ACE_OSCALL_RETURN (::getcwd (buf, size), char *, 0);
+#endif /* ACE_HAS_PACE */
+}
+
+ACE_INLINE int
+ACE_OS::sleep (u_int seconds)
+{
+ ACE_OS_TRACE ("ACE_OS::sleep");
+#if defined (ACE_HAS_PACE)
+ ACE_OSCALL_RETURN (::pace_sleep (seconds), int, -1);
+#elif defined (ACE_WIN32)
+ ::Sleep (seconds * ACE_ONE_SECOND_IN_MSECS);
+ return 0;
+#if 0
+#elif defined (HPUX_10) && defined (ACE_HAS_PTHREADS_DRAFT4)
+ // On HP-UX 10, _CMA_NOWRAPPERS_ disables the mapping from sleep to cma_sleep
+ // which makes sleep() put the whole process to sleep, and keeps it from
+ // noticing pending cancels. So, in this case, use pthread_delay_np
+ struct timespec rqtp;
+ rqtp.tv_sec = seconds;
+ rqtp.tv_nsec = 0L;
+ return pthread_delay_np (&rqtp);
+#endif /* 0 */
+#elif defined (ACE_HAS_CLOCK_GETTIME)
+ struct timespec rqtp;
+ // Initializer doesn't work with Green Hills 1.8.7
+ rqtp.tv_sec = seconds;
+ rqtp.tv_nsec = 0L;
+ ACE_OSCALL_RETURN (::nanosleep (&rqtp, 0), int, -1);
+#elif defined (ACE_PSOS)
+ timeval wait;
+ wait.tv_sec = seconds;
+ wait.tv_usec = 0;
+ ACE_OSCALL_RETURN (::select (0, 0, 0, 0, &wait), int, -1);
+#else
+ ACE_OSCALL_RETURN (::sleep (seconds), int, -1);
+#endif /* ACE_WIN32 */
+}
+
+ACE_INLINE int
+ACE_OS::sleep (const ACE_Time_Value &tv)
+{
+ ACE_OS_TRACE ("ACE_OS::sleep");
+#if defined (ACE_WIN32)
+ ::Sleep (tv.msec ());
+ return 0;
+#else
+# if defined (ACE_HAS_NONCONST_SELECT_TIMEVAL)
+ // Copy the timeval, because this platform doesn't declare the timeval
+ // as a pointer to const.
+ timeval tv_copy = tv;
+ ACE_OSCALL_RETURN (::select (0, 0, 0, 0, &tv_copy), int, -1);
+# else /* ! ACE_HAS_NONCONST_SELECT_TIMEVAL */
+ const timeval *tvp = tv;
+ ACE_OSCALL_RETURN (::select (0, 0, 0, 0, tvp), int, -1);
+# endif /* ACE_HAS_NONCONST_SELECT_TIMEVAL */
+#endif /* ACE_WIN32 */
+}
+
+ACE_INLINE int
+ACE_OS::nanosleep (const struct timespec *requested,
+ struct timespec *remaining)
+{
+ ACE_OS_TRACE ("ACE_OS::nanosleep");
+#if defined (ACE_HAS_PACE)
+ return ::pace_nanosleep (requested, remaining);
+#elif defined (ACE_HAS_CLOCK_GETTIME)
+ // ::nanosleep () is POSIX 1003.1b. So is ::clock_gettime (). So,
+ // if ACE_HAS_CLOCK_GETTIME is defined, then ::nanosleep () should
+ // be available on the platform. On Solaris 2.x, both functions
+ // require linking with -lposix4.
+ return ::nanosleep ((ACE_TIMESPEC_PTR) requested, remaining);
+#elif defined (ACE_PSOS)
+# if ! defined (ACE_PSOS_DIAB_MIPS)
+ double ticks = KC_TICKS2SEC * requested->tv_sec +
+ ( ACE_static_cast (double, requested->tv_nsec) *
+ ACE_static_cast (double, KC_TICKS2SEC) ) /
+ ACE_static_cast (double, ACE_ONE_SECOND_IN_NSECS);
+
+ if (ticks > ACE_static_cast (double, ACE_PSOS_Time_t::max_ticks))
+ {
+ ticks -= ACE_static_cast (double, ACE_PSOS_Time_t::max_ticks);
+ remaining->tv_sec = ACE_static_cast (time_t,
+ (ticks /
+ ACE_static_cast (double,
+ KC_TICKS2SEC)));
+ ticks -= ACE_static_cast (double, remaining->tv_sec) *
+ ACE_static_cast (double, KC_TICKS2SEC);
+
+ remaining->tv_nsec =
+ ACE_static_cast (long,
+ (ticks * ACE_static_cast (double,
+ ACE_ONE_SECOND_IN_NSECS)) /
+ ACE_static_cast (double, KC_TICKS2SEC));
+
+ ::tm_wkafter (ACE_PSOS_Time_t::max_ticks);
+ }
+ else
+ {
+ remaining->tv_sec = 0;
+ remaining->tv_nsec = 0;
+ ::tm_wkafter (ACE_static_cast (u_long, ticks));
+ }
+
+ // tm_wkafter always returns 0
+# endif /* ACE_PSOS_DIAB_MIPS */
+ return 0;
+#else
+ ACE_UNUSED_ARG (remaining);
+
+ // Convert into seconds and microseconds.
+# if ! defined(ACE_HAS_BROKEN_TIMESPEC_MEMBERS)
+ ACE_Time_Value tv (requested->tv_sec,
+ requested->tv_nsec / 1000);
+# else
+ ACE_Time_Value tv (requested->ts_sec,
+ requested->ts_nsec / 1000);
+# endif /* ACE_HAS_BROKEN_TIMESPEC_MEMBERS */
+ return ACE_OS::sleep (tv);
+#endif /* ACE_HAS_CLOCK_GETTIME */
+}
+
+ACE_INLINE int
+ACE_OS::mkdir (const ACE_TCHAR *path, mode_t mode)
+{
+#if defined (ACE_HAS_PACE)
+ ACE_OSCALL_RETURN (::pace_mkdir (path, mode), int, -1);
+#elif defined (ACE_PSOS_LACKS_PHILE)
+ ACE_UNUSED_ARG (path);
+ ACE_UNUSED_ARG (mode);
+ ACE_NOTSUP_RETURN (-1);
+#elif defined (ACE_PSOS)
+ //The pSOS make_dir fails if the last character is a '/'
+ int location;
+ char *phile_path;
+
+ phile_path = (char *)ACE_OS::malloc(strlen(path));
+ if (phile_path == 0)
+ {
+ ACE_OS::printf ("malloc in make_dir failed: [%X]\n",
+ errno);
+ return -1;
+ }
+ else
+ ACE_OS::strcpy (phile_path, path);
+
+ location = ACE_OS::strlen(phile_path);
+ if(phile_path[location-1] == '/')
+ {
+ phile_path[location-1] = 0;
+ }
+
+ u_long result;
+ result = ::make_dir ((char *) phile_path, mode);
+ if (result == 0x2011) // Directory already exists
+ {
+ result = 0;
+ }
+ else if (result != 0)
+ {
+ result = -1;
+ }
+
+ ACE_OS::free(phile_path);
+ return result;
+
+#elif defined (VXWORKS)
+ ACE_UNUSED_ARG (mode);
+ ACE_OSCALL_RETURN (::mkdir ((char *) path), int, -1);
+#elif defined (ACE_WIN32) && defined (__IBMCPP__) && (__IBMCPP__ >= 400)
+ ACE_UNUSED_ARG (mode);
+ ACE_OSCALL_RETURN (::_mkdir ((char *) path), int, -1);
+#elif defined (ACE_HAS_WINCE)
+ ACE_UNUSED_ARG (mode);
+ ACE_WIN32CALL_RETURN (ACE_ADAPT_RETVAL (::CreateDirectory (path, NULL),
+ ace_result_),
+ int, -1);
+#elif defined (ACE_WIN32) && defined (ACE_USES_WCHAR)
+ ACE_UNUSED_ARG (mode);
+ ACE_OSCALL_RETURN (::_wmkdir (path), int, -1);
+#elif defined (ACE_WIN32)
+ ACE_UNUSED_ARG (mode);
+ ACE_OSCALL_RETURN (::mkdir (path), int, -1);
+#else
+ ACE_OSCALL_RETURN (::mkdir (path, mode), int, -1);
+#endif /* ACE_HAS_PACE */
+}
+
+ACE_INLINE char *
+ACE_OS::getenv (const char *symbol)
+{
+ ACE_OS_TRACE ("ACE_OS::getenv");
+#if defined (ACE_LACKS_ENV)
+ ACE_UNUSED_ARG (symbol);
+ ACE_NOTSUP_RETURN (0);
+#elif defined (ACE_HAS_PACE)
+ ACE_OSCALL_RETURN (::pace_getenv (symbol), char*, 0);
+#elif defined (ACE_PSOS)
+ ACE_UNUSED_ARG (symbol);
+ ACE_NOTSUP_RETURN (0);
+#else /* ACE_PSOS */
+ ACE_OSCALL_RETURN (::getenv (symbol), char *, 0);
+#endif /* ACE_HAS_PACE */
+}
+
+#if defined (ACE_HAS_WCHAR) && defined (ACE_WIN32)
+ACE_INLINE wchar_t *
+ACE_OS::getenv (const wchar_t *symbol)
+{
+#if defined (ACE_LACKS_ENV)
+ ACE_UNUSED_ARG (symbol);
+ ACE_NOTSUP_RETURN (0);
+#else
+ ACE_OSCALL_RETURN (::_wgetenv (symbol), wchar_t *, 0);
+#endif /* ACE_LACKS_ENV */
+}
+#endif /* ACE_HAS_WCHAR && ACE_WIN32 */
+
+ACE_INLINE int
+ACE_OS::putenv (const ACE_TCHAR *string)
+{
+ ACE_OS_TRACE ("ACE_OS::putenv");
+#if defined (ACE_LACKS_ENV)
+ ACE_UNUSED_ARG (string);
+ ACE_NOTSUP_RETURN (0);
+#elif defined (ACE_HAS_WINCE) || defined (ACE_PSOS)
+ // WinCE and pSOS don't have the concept of environment variables.
+ ACE_UNUSED_ARG (string);
+ ACE_NOTSUP_RETURN (-1);
+#elif defined (ACE_WIN32) && defined (ACE_USES_WCHAR)
+ ACE_OSCALL_RETURN (::_wputenv (string), int, -1);
+#else /* ! ACE_HAS_WINCE && ! ACE_PSOS */
+ // VxWorks declares ::putenv with a non-const arg.
+ ACE_OSCALL_RETURN (::putenv ((char *) string), int, -1);
+#endif /* ACE_HAS_WINCE */
+}
+
+ACE_INLINE
+ACE_Str_Buf::ACE_Str_Buf (void *b, int l, int max)
+{
+ this->maxlen = max;
+ this->len = l;
+ this->buf = (char *) b;
+}
+
+ACE_INLINE
+ACE_Str_Buf::ACE_Str_Buf (strbuf &sb)
+{
+ this->maxlen = sb.maxlen;
+ this->len = sb.len;
+ this->buf = sb.buf;
+}
+
+ACE_INLINE u_int
+ACE_OS::wslen (const WChar *s)
+{
+ u_int len = 0;
+
+ while (*s++ != 0)
+ len++;
+
+ return len;
+}
+
+ACE_INLINE ACE_OS::WChar *
+ACE_OS::wscpy (WChar *dest, const WChar *src)
+{
+ WChar *original_dest = dest;
+
+ while ((*dest++ = *src++) != 0)
+ continue;
+
+ return original_dest;
+}
+
+ACE_INLINE int
+ACE_OS::wscmp (const WChar *s, const WChar *t)
+{
+ const WChar *scan1 = s;
+ const WChar *scan2 = t;
+
+ while (*scan1 != 0 && *scan1 == *scan2)
+ {
+ ++scan1;
+ ++scan2;
+ }
+
+ return *scan1 - *scan2;
+}
+
+ACE_INLINE int
+ACE_OS::wsncmp (const WChar *s, const WChar *t, size_t len)
+{
+ const WChar *scan1 = s;
+ const WChar *scan2 = t;
+
+ while (len != 0 && *scan1 != 0 && *scan1 == *scan2)
+ {
+ ++scan1;
+ ++scan2;
+ --len;
+ }
+
+ return len == 0 ? 0 : *scan1 - *scan2;
+}
+
+#if defined (ACE_LACKS_COND_T) && defined (ACE_HAS_THREADS) && (!defined (ACE_HAS_PACE) || defined (ACE_WIN32))
+ACE_INLINE long
+ACE_cond_t::waiters (void) const
+{
+ return this->waiters_;
+}
+#endif /* ACE_LACKS_COND_T && ACE_HAS_THREADS && ! ACE_HAS_PACE */
+
+#if 0
+ACE_INLINE int
+ACE_OS::thr_continue (const ACE_Thread_ID &thr_id)
+{
+ ACE_OS_TRACE ("ACE_OS::thr_continue");
+ return ACE_OS::thr_continue (thr_id.id ());
+}
+
+ACE_INLINE int
+ACE_OS::thr_create (ACE_THR_FUNC func,
+ void *args,
+ long flags,
+ ACE_Thread_ID *thr_id,
+ long priority,
+ void *stack,
+ size_t stacksize);
+{
+ ACE_OS_TRACE ("ACE_OS::thr_create");
+ ACE_thread_t thread_id;
+ ACE_hthread_t thread_handle;
+
+ int result = ACE_OS::thr_create (func, args, flags,
+ &thread_id, &thread_handle,
+ priority, stack, stacksize);
+ if (result == -1)
+ return -1;
+ else if (thr_id != 0)
+ {
+ thr_id->id (thread_id);
+ thr_id->handle (thread_handle);
+ return result;
+ }
+}
+
+ACE_INLINE int
+ACE_OS::thr_getprio (const ACE_Thread_ID &thr_id, int &prio)
+{
+ ACE_OS_TRACE ("ACE_OS::thr_getprio");
+ return ACE_OS::thr_getprio (thr_id.handle (), prio);
+}
+
+ACE_INLINE int
+ACE_OS::thr_join (const ACE_Thread_ID &thr_id, void **status)
+{
+# if defined (ACE_WIN32)
+ return ACE_OS::thr_join (thr_id.handle (), status);
+# else
+ return ACE_OS::thr_join (thr_id.id (), status);
+# endif /* ACE_WIN32 */
+}
+
+ACE_INLINE int
+ACE_OS::thr_cancel (const ACE_Thread_ID &thr_id)
+{
+ return ACE_OS::thr_cancel (thr_id.id ());
+}
+
+ACE_INLINE int
+ACE_OS::thr_kill (const ACE_Thread_ID &thr_id, int signum)
+{
+ return ACE_OS::thr_kill (thr_id.id (), signum);
+}
+
+ACE_INLINE ACE_Thread_ID
+ACE_OS::thr_self (void)
+{
+ ACE_hthread_t thr_handle;
+ ACE_OS::thr_self (thr_handle);
+ ACE_thread_t thr_id = ACE_OS::thr_self ();
+
+ return ACE_Thread_ID (thr_id, thr_handle);
+}
+
+ACE_INLINE int
+ACE_OS::thr_setprio (const ACE_Thread_ID &thr_id, int prio)
+{
+ ACE_OS_TRACE ("ACE_OS::thr_setprio");
+ return ACE_OS::thr_setprio (thr_id.handle (), prio);
+}
+
+ACE_INLINE int
+ACE_OS::thr_suspend (const ACE_Thread_ID &thr_id)
+{
+ return ACE_OS::thr_suspend (thr_id.handle ());
+}
+
+#endif /* 0 */
+
+ACE_INLINE int
+ACE_OS::sigaddset (sigset_t *s, int signum)
+{
+ ACE_OS_TRACE ("ACE_OS::sigaddset");
+#if defined (ACE_HAS_PACE) && !defined (ACE_WIN32)
+ ACE_OSCALL_RETURN (::pace_sigaddset (s, signum), int, -1);
+#elif defined (ACE_LACKS_SIGSET) || defined (ACE_LACKS_SIGSET_DEFINITIONS)
+ if (s == NULL)
+ {
+ errno = EFAULT;
+ return -1;
+ }
+ else if (signum < 1 || signum >= ACE_NSIG)
+ {
+ errno = EINVAL;
+ return -1; // Invalid signum, return error
+ }
+# if defined (ACE_PSOS) && defined (__DIAB) && ! defined(ACE_PSOS_DIAB_MIPS) && !defined (ACE_PSOS_DIAB_PPC)
+ // treat 0th u_long of sigset_t as high bits,
+ // and 1st u_long of sigset_t as low bits.
+ if (signum <= ACE_BITS_PER_ULONG)
+ s->s[1] |= (1 << (signum - 1));
+ else
+ s->s[0] |= (1 << (signum - ACE_BITS_PER_ULONG - 1));
+# else
+ *s |= (1 << (signum - 1)) ;
+# endif /* defined (ACE_PSOS) && defined (__DIAB) */
+ return 0 ;
+#else
+ ACE_OSCALL_RETURN (::sigaddset (s, signum), int, -1);
+#endif /* ACE_HAS_PACE */
+}
+
+ACE_INLINE int
+ACE_OS::sigdelset (sigset_t *s, int signum)
+{
+#if defined (ACE_HAS_PACE) && !defined (ACE_WIN32)
+ ACE_OSCALL_RETURN (::pace_sigdelset (s, signum), int, -1);
+#elif defined (ACE_LACKS_SIGSET) || defined (ACE_LACKS_SIGSET_DEFINITIONS)
+ if (s == NULL)
+ {
+ errno = EFAULT;
+ return -1;
+ }
+ else if (signum < 1 || signum >= ACE_NSIG)
+ {
+ errno = EINVAL;
+ return -1; // Invalid signum, return error
+ }
+# if defined (ACE_PSOS) && defined (__DIAB) && ! defined (ACE_PSOS_DIAB_MIPS) && !defined (ACE_PSOS_DIAB_PPC)
+ // treat 0th u_long of sigset_t as high bits,
+ // and 1st u_long of sigset_t as low bits.
+ if (signum <= ACE_BITS_PER_ULONG)
+ s->s[1] &= ~(1 << (signum - 1));
+ else
+ s->s[0] &= ~(1 << (signum - ACE_BITS_PER_ULONG - 1));
+# else
+ *s &= ~(1 << (signum - 1)) ;
+# endif /* defined (ACE_PSOS) && defined (__DIAB) */
+ return 0;
+#else
+ ACE_OSCALL_RETURN (::sigdelset (s, signum), int, -1);
+#endif /* ACE_HAS_PACE */
+}
+
+ACE_INLINE int
+ACE_OS::sigemptyset (sigset_t *s)
+{
+#if defined (ACE_HAS_PACE) && !defined (ACE_WIN32)
+ ACE_OSCALL_RETURN (::pace_sigemptyset (s), int, -1);
+#elif defined (ACE_LACKS_SIGSET) || defined (ACE_LACKS_SIGSET_DEFINITIONS)
+ if (s == NULL)
+ {
+ errno = EFAULT;
+ return -1;
+ }
+# if defined (ACE_PSOS) && defined (__DIAB) && ! defined (ACE_PSOS_DIAB_MIPS) && !defined (ACE_PSOS_DIAB_PPC)
+ s->s[0] = 0;
+ s->s[1] = 0;
+# else
+ *s = 0 ;
+# endif /* defined (ACE_PSOS) && defined (__DIAB) */
+ return 0 ;
+#else
+ ACE_OSCALL_RETURN (::sigemptyset (s), int, -1);
+#endif /* ACE_HAS_PACE */
+}
+
+ACE_INLINE int
+ACE_OS::sigfillset (sigset_t *s)
+{
+#if defined (ACE_HAS_PACE) && !defined (ACE_WIN32)
+ ACE_OSCALL_RETURN (::pace_sigfillset (s), int, -1);
+#elif defined (ACE_LACKS_SIGSET) || defined (ACE_LACKS_SIGSET_DEFINITIONS)
+ if (s == NULL)
+ {
+ errno = EFAULT;
+ return -1;
+ }
+# if defined (ACE_PSOS) && defined (__DIAB) && ! defined (ACE_PSOS_DIAB_MIPS) && !defined (ACE_PSOS_DIAB_PPC)
+ s->s[0] = ~(u_long) 0;
+ s->s[1] = ~(u_long) 0;
+# else
+ *s = ~(sigset_t) 0;
+# endif /* defined (ACE_PSOS) && defined (__DIAB) */
+ return 0 ;
+#else
+ ACE_OSCALL_RETURN (::sigfillset (s), int, -1);
+#endif /* ACE_HAS_PACE */
+}
+
+ACE_INLINE int
+ACE_OS::sigismember (sigset_t *s, int signum)
+{
+#if defined (ACE_HAS_PACE) && !defined (ACE_WIN32)
+ ACE_OSCALL_RETURN (::pace_sigismember (s, signum), int, -1);
+#elif defined (ACE_LACKS_SIGSET) || defined (ACE_LACKS_SIGSET_DEFINITIONS)
+ if (s == NULL)
+ {
+ errno = EFAULT;
+ return -1;
+ }
+ else if (signum < 1 || signum >= ACE_NSIG)
+ {
+ errno = EINVAL;
+ return -1; // Invalid signum, return error
+ }
+# if defined (ACE_PSOS) && defined (__DIAB) && ! defined (ACE_PSOS_DIAB_MIPS) && !defined (ACE_PSOS_DIAB_PPC)
+ // treat 0th u_long of sigset_t as high bits,
+ // and 1st u_long of sigset_t as low bits.
+ if (signum <= ACE_BITS_PER_ULONG)
+ return ((s->s[1] & (1 << (signum - 1))) != 0);
+ else
+ return ((s->s[0] & (1 << (signum - ACE_BITS_PER_ULONG - 1))) != 0);
+# else
+ return ((*s & (1 << (signum - 1))) != 0) ;
+# endif /* defined (ACE_PSOS) && defined (__DIAB) */
+#else
+# if defined (ACE_HAS_SIGISMEMBER_BUG)
+ if (signum < 1 || signum >= ACE_NSIG)
+ {
+ errno = EINVAL;
+ return -1; // Invalid signum, return error
+ }
+# endif /* ACE_HAS_SIGISMEMBER_BUG */
+ ACE_OSCALL_RETURN (::sigismember (s, signum), int, -1);
+#endif /* ACE_HAS_PACE */
+}
+
+ACE_INLINE int
+ACE_OS::sigsuspend (const sigset_t *sigset)
+{
+#if defined (ACE_HAS_PACE) && !defined (ACE_WIN32)
+ ACE_OSCALL_RETURN (::pace_sigsuspend (sigset), int, -1);
+#elif defined (ACE_HAS_SIGSUSPEND)
+ sigset_t s;
+
+ if (sigset == 0)
+ {
+ sigset = &s;
+ ACE_OS::sigemptyset (&s);
+ }
+ ACE_OSCALL_RETURN (::sigsuspend (sigset), int, -1);
+#else
+ ACE_UNUSED_ARG (sigset);
+ ACE_NOTSUP_RETURN (-1);
+#endif /* ACE_HAS_PACE */
+}
+
+ACE_INLINE int
+ACE_OS::sigprocmask (int how, const sigset_t *nsp, sigset_t *osp)
+{
+#if defined (ACE_HAS_PACE) && !defined (ACE_WIN32)
+ ACE_OSCALL_RETURN (::pace_sigprocmask (how, nsp, osp), int, -1);
+#elif defined (ACE_LACKS_SIGSET) || defined (ACE_LACKS_SIGSET_DEFINITIONS)
+ ACE_UNUSED_ARG (how);
+ ACE_UNUSED_ARG (nsp);
+ ACE_UNUSED_ARG (osp);
+ ACE_NOTSUP_RETURN (-1);
+#else
+# if defined (ACE_LACKS_POSIX_PROTOTYPES)
+ ACE_OSCALL_RETURN (::sigprocmask (how, (int*) nsp, osp), int, -1);
+# else
+ ACE_OSCALL_RETURN (::sigprocmask (how, nsp, osp), int, -1);
+# endif /* ACE_LACKS_POSIX_PROTOTYPES */
+#endif /* ACE_HAS_PACE */
+}
+
+ACE_INLINE int
+ACE_OS::pthread_sigmask (int how, const sigset_t *nsp, sigset_t *osp)
+{
+#if defined (ACE_HAS_PACE) && !defined (ACE_WIN32)
+ ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::pace_pthread_sigmask (how, nsp, osp),
+ ace_result_), int, -1);
+#elif defined (ACE_HAS_PTHREADS_STD) && !defined (ACE_LACKS_PTHREAD_SIGMASK)
+ ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::pthread_sigmask (how, nsp, osp),
+ ace_result_),
+ int,
+ -1);
+#else /* !ACE_HAS_PTHREADS_STD */
+ ACE_UNUSED_ARG (how);
+ ACE_UNUSED_ARG (nsp);
+ ACE_UNUSED_ARG (osp);
+ ACE_NOTSUP_RETURN (-1);
+#endif /* ACE_HAS_PACE */
+}
+
+// ****************************************************************
+
+#if defined (ACE_PSOS)
+ACE_INLINE int
+isatty (int h)
+{
+ return ACE_OS::isatty (h);
+}
+#if defined (fileno)
+#undef fileno
+#endif /* defined (fileno)*/
+ACE_INLINE ACE_HANDLE
+fileno (FILE *fp)
+{
+ return (ACE_HANDLE) fp;
+}
+#endif /* defined (ACE_PSOS) */
+
+ACE_INLINE
+ACE_Cleanup::ACE_Cleanup (void)
+{
+}
+
+ACE_INLINE void *
+ACE_OS::bsearch (const void *key,
+ const void *base,
+ size_t nel,
+ size_t size,
+ ACE_COMPARE_FUNC compar)
+{
+#if defined (ACE_HAS_PACE)
+ return ::pace_bsearch (key, base, nel, size, compar);
+#elif !defined (ACE_LACKS_BSEARCH)
+ return ::bsearch (key, base, nel, size, compar);
+#else
+ ACE_UNUSED_ARG (key);
+ ACE_UNUSED_ARG (base);
+ ACE_UNUSED_ARG (nel);
+ ACE_UNUSED_ARG (size);
+ ACE_UNUSED_ARG (compar);
+ ACE_NOTSUP_RETURN (NULL);
+#endif /* ACE_HAS_PACE */
+}
+
+ACE_INLINE void
+ACE_OS::qsort (void *base,
+ size_t nel,
+ size_t width,
+ ACE_COMPARE_FUNC compar)
+{
+#if defined (ACE_HAS_PACE)
+ ::pace_qsort (base, nel, width, compar);
+#elif !defined (ACE_LACKS_QSORT)
+ ::qsort (base, nel, width, compar);
+#else
+ ACE_UNUSED_ARG (base);
+ ACE_UNUSED_ARG (nel);
+ ACE_UNUSED_ARG (width);
+ ACE_UNUSED_ARG (compar);
+#endif /* ACE_HAS_PACE */
+}
+
+ACE_INLINE int
+ACE_OS::setuid (uid_t uid)
+{
+ ACE_OS_TRACE ("ACE_OS::setuid");
+#if defined (ACE_HAS_PACE)
+ ACE_OSCALL_RETURN (::pace_setuid (uid), int, -1);
+# elif defined (VXWORKS) || defined (ACE_PSOS)
+ // setuid() is not supported: just one user anyways
+ ACE_UNUSED_ARG (uid);
+ return 0;
+# elif defined (ACE_WIN32) || defined(CHORUS)
+ ACE_UNUSED_ARG (uid);
+ ACE_NOTSUP_RETURN (-1);
+# else
+ ACE_OSCALL_RETURN (::setuid (uid), int, -1);
+# endif /* ACE_HAS_PACE */
+}
+
+ACE_INLINE uid_t
+ACE_OS::getuid (void)
+{
+ ACE_OS_TRACE ("ACE_OS::getuid");
+#if defined (ACE_HAS_PACE)
+ ACE_OSCALL_RETURN (::pace_getuid (), pace_uid_t, (pace_uid_t) -1);
+# elif defined (VXWORKS) || defined (ACE_PSOS)
+ // getuid() is not supported: just one user anyways
+ return 0;
+# elif defined (ACE_WIN32) || defined(CHORUS)
+ ACE_NOTSUP_RETURN (ACE_static_cast (uid_t, -1));
+# else
+ ACE_OSCALL_RETURN (::getuid (), uid_t, (uid_t) -1);
+# endif /* ACE_HAS_PACE */
+}
+
+ACE_INLINE int
+ACE_OS::setgid (gid_t gid)
+{
+ ACE_OS_TRACE ("ACE_OS::setgid");
+#if defined (ACE_HAS_PACE)
+ ACE_OSCALL_RETURN (::pace_setgid (gid), int, -1);
+# elif defined (VXWORKS) || defined (ACE_PSOS)
+ // setgid() is not supported: just one user anyways
+ ACE_UNUSED_ARG (gid);
+ return 0;
+# elif defined (ACE_WIN32) || defined(CHORUS)
+ ACE_UNUSED_ARG (gid);
+ ACE_NOTSUP_RETURN (-1);
+# else
+ ACE_OSCALL_RETURN (::setgid (gid), int, -1);
+# endif /* ACE_HAS_PACE */
+}
+
+ACE_INLINE gid_t
+ACE_OS::getgid (void)
+{
+ ACE_OS_TRACE ("ACE_OS::getgid");
+#if defined (ACE_HAS_PACE)
+ ACE_OSCALL_RETURN (::pace_getgid (), pace_gid_t, (pace_gid_t) -1);
+# elif defined (VXWORKS) || defined (ACE_PSOS)
+ // getgid() is not supported: just one user anyways
+ return 0;
+# elif defined (ACE_WIN32) || defined(CHORUS)
+ ACE_NOTSUP_RETURN (ACE_static_cast (gid_t, -1));
+# else
+ ACE_OSCALL_RETURN (::getgid (), gid_t, (gid_t) -1);
+# endif /* ACE_HAS_PACE */
+}
+
+ACE_INLINE ACE_EXIT_HOOK
+ACE_OS::set_exit_hook (ACE_EXIT_HOOK exit_hook)
+{
+ ACE_EXIT_HOOK old_hook = exit_hook_;
+ exit_hook_ = exit_hook;
+ return old_hook;
+}
+
+ACE_INLINE int
+ACE_OS::isatty (int handle)
+{
+#if defined (ACE_HAS_PACE)
+ ACE_OSCALL_RETURN (::pace_isatty (handle), int, -1);
+# elif defined (ACE_LACKS_ISATTY)
+ ACE_UNUSED_ARG (handle);
+ return 0;
+# elif defined (ACE_WIN32)
+ ACE_OS_TRACE ("ACE_OS::isatty");
+ return ::_isatty (handle);
+# else
+ ACE_OS_TRACE ("ACE_OS::isatty");
+ ACE_OSCALL_RETURN (::isatty (handle), int, -1);
+# endif /* defined (ACE_LACKS_ISATTY) */
+}
+
+#if defined (ACE_WIN32)
+ACE_INLINE int
+ACE_OS::isatty (ACE_HANDLE handle)
+{
+#if defined (ACE_LACKS_ISATTY)
+ ACE_UNUSED_ARG (handle);
+ return 0;
+#else
+ int fd = ::_open_osfhandle ((long) handle, 0);
+ return ::_isatty (fd);
+#endif /* ACE_LACKS_ISATTY */
+}
+
+ACE_INLINE void
+ACE_OS::fopen_mode_to_open_mode_converter (ACE_TCHAR x, int &hmode)
+{
+ switch (x)
+ {
+ case ACE_LIB_TEXT ('r'):
+ if (ACE_BIT_DISABLED (hmode, _O_RDWR))
+ {
+ ACE_CLR_BITS (hmode, _O_WRONLY);
+ ACE_SET_BITS (hmode, _O_RDONLY);
+ }
+ break;
+ case ACE_LIB_TEXT ('w'):
+ if (ACE_BIT_DISABLED (hmode, _O_RDWR))
+ {
+ ACE_CLR_BITS (hmode, _O_RDONLY);
+ ACE_SET_BITS (hmode, _O_WRONLY);
+ }
+ ACE_SET_BITS (hmode, _O_CREAT | _O_TRUNC);
+ break;
+ case ACE_LIB_TEXT ('a'):
+ if (ACE_BIT_DISABLED (hmode, _O_RDWR))
+ {
+ ACE_CLR_BITS (hmode, _O_RDONLY);
+ ACE_SET_BITS (hmode, _O_WRONLY);
+ }
+ ACE_SET_BITS (hmode, _O_CREAT | _O_APPEND);
+ break;
+ case ACE_LIB_TEXT ('+'):
+ ACE_CLR_BITS (hmode, _O_RDONLY | _O_WRONLY);
+ ACE_SET_BITS (hmode, _O_RDWR);
+ break;
+ case ACE_LIB_TEXT ('t'):
+ ACE_CLR_BITS (hmode, _O_BINARY);
+ ACE_SET_BITS (hmode, _O_TEXT);
+ break;
+ case ACE_LIB_TEXT ('b'):
+ ACE_CLR_BITS (hmode, _O_TEXT);
+ ACE_SET_BITS (hmode, _O_BINARY);
+ break;
+ }
+}
+#endif /* ACE_WIN32 */
+
+// Return a dynamically allocated duplicate of <str>, substituting the
+// environment variable if <str[0] == '$'>. Note that the pointer is
+// allocated with <ACE_OS::malloc> and must be freed by
+// <ACE_OS::free>.
+
+ACE_INLINE ACE_TCHAR *
+ACE_OS::strenvdup (const ACE_TCHAR *str)
+{
+# if defined (ACE_LACKS_ENV)
+ ACE_UNUSED_ARG (str);
+ ACE_NOTSUP_RETURN (0);
+#elif defined (ACE_HAS_WINCE)
+ // WinCE doesn't have environment variables so we just skip it.
+ return ACE_OS::strdup (str);
+#else
+ ACE_TCHAR *temp = 0;
+
+ if (str[0] == ACE_LIB_TEXT ('$')
+ && (temp = ACE_OS::getenv (&str[1])) != 0)
+ return ACE_OS::strdup (temp);
+ else
+ return ACE_OS::strdup (str);
+#endif /* ACE_HAS_WINCE */
+}
+
+ACE_INLINE int
+ACE_Countdown_Time::start (void)
+{
+ if (this->max_wait_time_ != 0)
+ {
+ this->start_time_ = ACE_OS::gettimeofday ();
+ this->stopped_ = 0;
+ }
+ return 0;
+}
+
+ACE_INLINE int
+ACE_Countdown_Time::stop (void)
+{
+ if (this->max_wait_time_ != 0 && this->stopped_ == 0)
+ {
+ ACE_Time_Value elapsed_time =
+ ACE_OS::gettimeofday () - this->start_time_;
+
+ if (*this->max_wait_time_ > elapsed_time)
+ *this->max_wait_time_ -= elapsed_time;
+ else
+ {
+ // Used all of timeout.
+ *this->max_wait_time_ = ACE_Time_Value::zero;
+ // errno = ETIME;
+ }
+ this->stopped_ = 1;
+ }
+ return 0;
+}
+
+ACE_INLINE int
+ACE_Countdown_Time::update (void)
+{
+ return this->stop () == 0 && this->start ();
+}
+
+#if defined (ACE_WIN32)
+ACE_INLINE const OSVERSIONINFO &
+ACE_OS::get_win32_versioninfo ()
+{
+ return ACE_OS::win32_versioninfo_;
+}
+
+ACE_INLINE HINSTANCE
+ACE_OS::get_win32_resource_module ()
+{
+ return ACE_OS::win32_resource_module_;
+}
+
+ACE_INLINE void
+ACE_OS::set_win32_resource_module (HINSTANCE instance)
+{
+ ACE_OS::win32_resource_module_ = instance;
+}
+#endif /* ACE_WIN32 */
diff --git a/ace/OS/OS_Dirent.cpp b/ace/OS/OS_Dirent.cpp
new file mode 100644
index 00000000000..a14966fc7b3
--- /dev/null
+++ b/ace/OS/OS_Dirent.cpp
@@ -0,0 +1,235 @@
+// $Id$
+
+#include "OS.h"
+#include "OS_Dirent.h"
+#include "OS_String.h"
+#include "OS_Memory.h"
+
+#if 0
+#include "ace/Logging/Log_Msg.h"
+#endif
+
+ACE_RCSID(ace, OS_Dirent, "$Id$")
+
+#if !defined (ACE_HAS_INLINED_OSCALLS)
+# include "OS_Dirent.inl"
+#endif /* ACE_HAS_INLINED_OS_CALLS */
+
+ACE_DIR *
+ACE_OS_Dirent::opendir_emulation (const ACE_TCHAR *filename)
+{
+#if defined (ACE_WIN32)
+ ACE_DIR *dir;
+ ACE_TCHAR extra[3] = {0,0,0};
+
+/*
+ Note: the semantics of the win32 function FindFirstFile take the
+ basename(filename) as a pattern to be matched within the dirname(filename).
+ This is contrary to the behavior of the posix function readdir which treats
+ basename(filename) as a directory to be opened and read.
+
+ For this reason, we append a slash-star or backslash-star to the supplied
+ filename so the result is that FindFirstFile will do what we need.
+
+ According to the documentation for FindFirstFile, either a '/' or a '\' may
+ be used as a directory name separator.
+
+ Of course, it is necessary to ensure that this is only done if the trailing
+ filespec is not already there.
+
+ Phil Mesnier
+*/
+
+ size_t lastchar = ACE_OS_String::strlen (filename);
+ if (lastchar > 0)
+ {
+ if (filename[lastchar-1] != '*')
+ {
+ if (filename[lastchar-1] != '/' && filename[lastchar-1] != '\\')
+ ACE_OS_String::strcpy (extra, ACE_LIB_TEXT ("/*"));
+ else
+ ACE_OS_String::strcpy (extra, ACE_LIB_TEXT ("*"));
+ }
+ }
+
+ ACE_NEW_RETURN (dir, ACE_DIR, 0);
+ ACE_NEW_RETURN (dir->directory_name_,
+ ACE_TCHAR[lastchar + ACE_OS_String::strlen (extra) + 1],
+ 0);
+ ACE_OS_String::strcpy (dir->directory_name_, filename);
+ if (extra[0])
+ ACE_OS_String::strcat (dir->directory_name_, extra);
+ dir->current_handle_ = INVALID_HANDLE_VALUE;
+ dir->started_reading_ = 0;
+ dir->dirent_ = 0;
+ return dir;
+#else /* ACE_WIN32 */
+ ACE_UNUSED_ARG (filename);
+ ACE_NOTSUP_RETURN (0);
+#endif /* ACE_WIN32 */
+}
+
+void
+ACE_OS_Dirent::closedir_emulation (ACE_DIR *d)
+{
+#if defined (ACE_WIN32)
+ if (d->current_handle_ != INVALID_HANDLE_VALUE)
+ ::FindClose (d->current_handle_);
+
+ d->current_handle_ = INVALID_HANDLE_VALUE;
+ d->started_reading_ = 0;
+ ACE_OS_Memory::free (d->dirent_);
+#else /* ACE_WIN32 */
+ ACE_UNUSED_ARG (d);
+#endif /* ACE_WIN32 */
+}
+
+dirent *
+ACE_OS_Dirent::readdir_emulation (ACE_DIR *d)
+{
+#if defined (ACE_WIN32)
+ ACE_OS_Memory::free (d->dirent_);
+ d->dirent_ = 0;
+
+ if (!d->started_reading_)
+ {
+ d->current_handle_ = ACE_TEXT_FindFirstFile (d->directory_name_,
+ &(d->fdata_));
+
+ if (d->current_handle_ != INVALID_HANDLE_VALUE)
+ {
+ // Skip "." and ".."
+ int retval = 1;
+ while (*d->fdata_.cFileName == '.'
+ && retval
+ && d->fdata_.dwFileAttributes == FILE_ATTRIBUTE_DIRECTORY)
+ retval = ACE_TEXT_FindNextFile (d->current_handle_, &d->fdata_);
+ if (retval == 0)
+ {
+ ::FindClose (d->current_handle_);
+ d->current_handle_ = INVALID_HANDLE_VALUE;
+ }
+ }
+
+ d->started_reading_ = 1;
+ }
+ else
+ {
+ int retval = ACE_TEXT_FindNextFile (d->current_handle_,
+ &(d->fdata_));
+ if (retval == 0)
+ {
+ // Make sure to close the handle explicitly to avoid a leak!
+ ::FindClose (d->current_handle_);
+ d->current_handle_ = INVALID_HANDLE_VALUE;
+ }
+ }
+
+ if (d->current_handle_ != INVALID_HANDLE_VALUE)
+ {
+ d->dirent_ = (dirent *)
+ ACE_OS_Memory::malloc (sizeof (dirent)
+ + ((ACE_OS_String::strlen (d->fdata_.cFileName) + 1
+ * sizeof (ACE_TCHAR))));
+ ACE_OS_String::strcpy (d->dirent_->d_name, d->fdata_.cFileName);
+ d->dirent_->d_reclen = sizeof (dirent)
+ + (ACE_OS_String::strlen (d->dirent_->d_name) * sizeof (ACE_TCHAR));
+ return d->dirent_;
+ }
+ else
+ return 0;
+#else /* ACE_WIN32 */
+ ACE_UNUSED_ARG (d);
+ ACE_NOTSUP_RETURN (0);
+#endif /* ACE_WIN32 */
+}
+
+extern "C"
+{
+ typedef int (*ACE_SCANDIR_COMPARATOR) (const void *, const void *);
+}
+
+int
+ACE_OS_Dirent::scandir_emulation (const ACE_TCHAR *dirname,
+ dirent **namelist[],
+ int (*selector) (const dirent *entry),
+ int (*comparator) (const dirent **f1,
+ const dirent **f2))
+{
+ ACE_DIR *dirp = ACE_OS_Dirent::opendir (dirname);
+
+ if (dirp == 0)
+ return -1;
+ // A sanity check here. "namelist" had better not be zero.
+ else if (namelist == 0)
+ return -1;
+
+ dirent **vector = 0;
+ dirent *dp;
+ int arena_size = 0;
+
+ int nfiles = 0;
+ int fail = 0;
+
+ // @@ This code shoulduse readdir_r() rather than readdir().
+ for (dp = ACE_OS_Dirent::readdir (dirp);
+ dp != 0;
+ dp = ACE_OS_Dirent::readdir (dirp))
+ {
+ if (selector && (*selector)(dp) == 0)
+ continue;
+
+ // If we get here, we have a dirent that the user likes.
+ if (nfiles == arena_size)
+ {
+ dirent **newv;
+ if (arena_size == 0)
+ arena_size = 10;
+ else
+ arena_size *= 2;
+
+ newv = (dirent **) ACE_OS_Memory::realloc (vector,
+ arena_size * sizeof (dirent *));
+ if (newv == 0)
+ {
+ fail = 1;
+ break;
+ }
+ vector = newv;
+ }
+
+ int dsize =
+ sizeof (dirent) +
+ ((ACE_OS_String::strlen (dp->d_name) + 1) * sizeof (ACE_TCHAR));
+ dirent *newdp = (dirent *) ACE_OS_Memory::malloc (dsize);
+
+ if (newdp == 0)
+ {
+ fail = 1;
+ break;
+ }
+
+ vector[nfiles++] = (dirent *) ACE_OS_String::memcpy (newdp, dp, dsize);
+ }
+
+ if (fail)
+ {
+ ACE_OS_Dirent::closedir (dirp);
+ while (nfiles-- > 0)
+ ACE_OS_Memory::free (vector[nfiles]);
+ ACE_OS_Memory::free (vector);
+ return -1;
+ }
+
+ ACE_OS_Dirent::closedir (dirp);
+
+ *namelist = vector;
+
+ if (comparator)
+ ACE_OS::qsort (*namelist,
+ nfiles,
+ sizeof (dirent *),
+ (ACE_SCANDIR_COMPARATOR) comparator);
+
+ return nfiles;
+}
diff --git a/ace/OS/OS_Dirent.h b/ace/OS/OS_Dirent.h
new file mode 100644
index 00000000000..e4c257e6111
--- /dev/null
+++ b/ace/OS/OS_Dirent.h
@@ -0,0 +1,130 @@
+// -*- C++ -*-
+
+//=============================================================================
+/**
+ * @file OS_Dirent.h
+ *
+ * $Id$
+ *
+ * @author Doug Schmidt <schmidt@cs.wustl.edu>
+ * @author Jesper S. M|ller<stophph@diku.dk>
+ * @author and a cast of thousands...
+ */
+//=============================================================================
+
+#ifndef ACE_OS_DIRENT_H
+#define ACE_OS_DIRENT_H
+#include "ace/pre.h"
+
+#include "ace/config-all.h"
+#include "OS_Export.h"
+
+#if !defined (ACE_LACKS_PRAGMA_ONCE)
+# pragma once
+#endif /* ACE_LACKS_PRAGMA_ONCE */
+
+#if !defined (ACE_WIN32) && !defined (ACE_PSOS) && !defined (ACE_HAS_WINCE)
+# include /**/ <sys/types.h>
+# if !defined (ACE_LACKS_UNISTD_H)
+# include /**/ <unistd.h> // VxWorks needs this to compile
+# endif /* !ACE_LACKS_UNISTD_H */
+# include /**/ <dirent.h>
+#endif /* !ACE_WIN32 && !ACE_PSOS */
+
+// At least compile on some of the platforms without <ACE_DIR> info yet.
+# if !defined (ACE_HAS_DIRENT)
+typedef int ACE_DIR;
+struct dirent {
+};
+# endif /* ACE_HAS_DIRENT */
+
+#if defined (ACE_LACKS_STRUCT_DIR)
+struct dirent {
+ unsigned short d_ino;
+ unsigned short d_off;
+ unsigned short d_reclen;
+ ACE_TCHAR d_name[1];
+};
+
+struct ACE_DIR {
+ /// The name of the directory we are looking into
+ ACE_TCHAR *directory_name_;
+
+ /// Remember the handle between calls.
+ HANDLE current_handle_;
+
+ /// The struct for the results
+ dirent *dirent_;
+
+ /// The struct for intermediate results.
+ ACE_TEXT_WIN32_FIND_DATA fdata_;
+
+ /// A flag to remember if we started reading already.
+ int started_reading_;
+};
+#elif defined (ACE_PSOS) && !defined (ACE_PSOS_DIAB_PPC)
+// Create our own definition of the DIR struct, like what
+// is available in the newer DIAB PPC header files
+struct ACE_DIR
+{
+ /// The directory handle
+ XDIR xdir;
+
+ /// The directory entry
+ struct dirent dirent;
+};
+#else
+typedef DIR ACE_DIR;
+# endif /* ACE_LACKS_STRUCT_DIR */
+
+#if defined rewinddir
+# undef rewinddir
+#endif /* rewinddir */
+
+/**
+ * @class ACE_OS_Dirent
+ *
+ * @brief This class is a wrapper for the dirent.h operations
+ *
+ */
+class ACE_OS_Export ACE_OS_Dirent
+{
+public:
+ static ACE_DIR *opendir (const ACE_TCHAR *filename);
+ static void closedir (ACE_DIR *);
+ static dirent *readdir (ACE_DIR *);
+ static int readdir_r (ACE_DIR *dirp,
+ dirent *entry,
+ dirent **result);
+ static long telldir (ACE_DIR *);
+ static void seekdir (ACE_DIR *,
+ long loc);
+ static void rewinddir (ACE_DIR *);
+
+ static int scandir (const ACE_TCHAR *dirname,
+ dirent **namelist[],
+ int (*selector) (const dirent *filename),
+ int (*comparator) (const dirent **f1,
+ const dirent **f2));
+private:
+ // Win32 emulation functions
+ static ACE_DIR *opendir_emulation (const ACE_TCHAR *filename);
+ static int scandir_emulation (const ACE_TCHAR *dirname,
+ dirent **namelist[],
+ int (*selector)(const dirent *entry),
+ int (*comparator)(const dirent **f1,
+ const dirent**f2));
+ static void closedir_emulation (ACE_DIR *);
+ static dirent *readdir_emulation (ACE_DIR *);
+};
+
+# if defined (ACE_HAS_INLINED_OSCALLS)
+# if defined (ACE_INLINE)
+# undef ACE_INLINE
+# endif /* ACE_INLINE */
+# define ACE_INLINE inline
+# include "OS_Dirent.inl"
+# endif /* ACE_HAS_INLINED_OSCALLS */
+
+#include "ace/post.h"
+#endif /* ACE_OS_DIRENT_H */
diff --git a/ace/OS/OS_Dirent.inl b/ace/OS/OS_Dirent.inl
new file mode 100644
index 00000000000..e6ab9dc82e1
--- /dev/null
+++ b/ace/OS/OS_Dirent.inl
@@ -0,0 +1,201 @@
+// -*- C++ -*-
+// $Id$
+
+#if defined (ACE_HAS_PACE)
+#include /**/ "pace/dirent.h"
+#endif /* ACE_HAS_PACE */
+ACE_INLINE ACE_DIR *
+ACE_OS_Dirent::opendir (const ACE_TCHAR *filename)
+{
+#if defined (ACE_HAS_PACE) && !defined (ACE_WIN32)
+ return pace_opendir (filename);
+#elif defined (ACE_HAS_DIRENT)
+# if defined (ACE_PSOS)
+ // The pointer to the <ACE_DIR> buffer *must* be passed to
+ // <ACE_OS_Dirent::closedir> to free it and avoid a memory leak.
+ ACE_DIR *dir;
+ u_long result;
+ ACE_NEW_RETURN (dir, ACE_DIR, 0);
+ result = ::open_dir (ACE_const_cast (ACE_TCHAR *,
+ filename),
+ &dir->xdir);
+ if (result == 0)
+ return dir;
+ else
+ {
+ errno = result;
+ return 0;
+ }
+# else /* ! ACE_PSOS */
+# if defined (ACE_WIN32)
+ return ::ACE_OS_Dirent::opendir_emulation (filename);
+# else /* ! ACE_WIN32 */
+ // VxWorks' ::opendir () is declared with a non-const argument.
+ return ::opendir (ACE_const_cast (ACE_TCHAR *, filename));
+# endif /* ACE_WIN32 */
+# endif /* ACE_PSOS */
+#else
+ ACE_UNUSED_ARG (filename);
+ ACE_NOTSUP_RETURN (0);
+#endif /* ACE_HAS_PACE */
+}
+
+ACE_INLINE void
+ACE_OS_Dirent::closedir (ACE_DIR *d)
+{
+#if defined (ACE_HAS_PACE) && !defined (ACE_WIN32)
+ pace_closedir (d);
+#elif defined (ACE_HAS_DIRENT)
+# if defined (ACE_PSOS)
+
+ u_long result = ::close_dir (&(d->xdir));
+ delete d;
+ if (result != 0)
+ errno = result;
+
+# else /* ! ACE_PSOS */
+
+# if defined (ACE_WIN32)
+ ACE_OS_Dirent::closedir_emulation (d);
+ delete [] d->directory_name_;
+ delete d;
+# else /* ACE_WIN32 */
+ ::closedir (d);
+# endif /* ACE_WIN32 */
+
+# endif /* ACE_PSOS */
+#else /* ACE_HAS_DIRENT */
+ ACE_UNUSED_ARG (d);
+#endif /* ACE_HAS_PACE */
+}
+
+ACE_INLINE struct dirent *
+ACE_OS_Dirent::readdir (ACE_DIR *d)
+{
+#if defined (ACE_HAS_PACE) && !defined (ACE_WIN32)
+ return pace_readdir (d);
+#elif defined (ACE_HAS_DIRENT)
+# if defined (ACE_PSOS)
+
+ u_long result = ::read_dir (&d->xdir, &d->dirent);
+ if (0 == result)
+ return &d->dirent;
+ else
+ {
+ errno = result;
+ return 0;
+ }
+
+# else /* ! ACE_PSOS */
+# if defined (ACE_WIN32)
+ return ACE_OS_Dirent::readdir_emulation (d);
+# else /* defined (ACE_WIN32) */
+ return ::readdir (d);
+# endif /* defined (ACE_WIN32) */
+# endif /* ACE_PSOS */
+#else
+ ACE_UNUSED_ARG (d);
+ ACE_NOTSUP_RETURN (0);
+#endif /* ACE_HAS_PACE */
+}
+
+ACE_INLINE int
+ACE_OS_Dirent::readdir_r (ACE_DIR *dirp,
+ struct dirent *entry,
+ struct dirent **result)
+{
+#if defined (ACE_HAS_PACE) && !defined (ACE_WIN32)
+ return pace_readdir_r (dirp, entry, result);
+# elif !defined (ACE_HAS_REENTRANT_FUNCTIONS)
+ ACE_UNUSED_ARG (entry);
+ // <result> has better not be 0!
+ *result = ACE_OS_Dirent::readdir (dirp);
+ return 0;
+# elif defined (ACE_HAS_DIRENT) && !defined (ACE_LACKS_READDIR_R)
+# if (defined (sun) && (defined (_POSIX_PTHREAD_SEMANTICS) || \
+ (_FILE_OFFSET_BITS == 64))) || \
+ (!defined (sun) && (defined (ACE_HAS_PTHREADS_STD) || \
+ defined (ACE_HAS_PTHREADS_DRAFT7) || \
+ defined (__USE_POSIX) || \
+ defined (HPUX_11)))
+# if defined (__GNUG__) && defined (DIGITAL_UNIX)
+ return readdir_r (dirp, entry, result);
+# else
+ return ::readdir_r (dirp, entry, result);
+# endif /* defined (__GNUG__) && defined (DIGITAL_UNIX) */
+# else /* ! POSIX.1c - this is draft 4 or draft 6 */
+# if defined (HPUX_10) /* But HP 10.x doesn't follow the draft either */
+ *result = entry;
+ return ::readdir_r (dirp, entry);
+# else
+ // <result> had better not be 0!
+ *result = ::readdir_r (dirp, entry);
+ return 0;
+# endif /* HPUX_10 */
+# endif /* ! POSIX.1c */
+#else /* ! ACE_HAS_DIRENT || ACE_LACKS_READDIR_R */
+ ACE_UNUSED_ARG (dirp);
+ ACE_UNUSED_ARG (entry);
+ ACE_UNUSED_ARG (result);
+ ACE_NOTSUP_RETURN (0);
+
+#endif /* ACE_HAS_PACE */
+}
+
+ACE_INLINE long
+ACE_OS_Dirent::telldir (ACE_DIR *d)
+{
+#if defined (ACE_HAS_DIRENT) && !defined (ACE_LACKS_TELLDIR)
+ return ::telldir (d);
+#else /* ! ACE_HAS_DIRENT || ACE_LACKS_TELLDIR */
+ ACE_UNUSED_ARG (d);
+ ACE_NOTSUP_RETURN (-1);
+#endif /* ! ACE_HAS_DIRENT || ACE_LACKS_TELLDIR */
+}
+
+ACE_INLINE void
+ACE_OS_Dirent::seekdir (ACE_DIR *d, long loc)
+{
+#if defined (ACE_HAS_DIRENT) && !defined (ACE_LACKS_SEEKDIR)
+ ::seekdir (d, loc);
+#else /* ! ACE_HAS_DIRENT || ACE_LACKS_SEEKDIR */
+ ACE_UNUSED_ARG (d);
+ ACE_UNUSED_ARG (loc);
+#endif /* ! ACE_HAS_DIRENT || ACE_LACKS_SEEKDIR */
+}
+
+ACE_INLINE void
+ACE_OS_Dirent::rewinddir (ACE_DIR *d)
+{
+#if defined (ACE_HAS_PACE) && !defined (ACE_WIN32)
+ pace_rewinddir (d);
+#elif defined (ACE_HAS_DIRENT)
+# if defined (ACE_LACKS_SEEKDIR)
+# if defined (ACE_LACKS_REWINDDIR)
+ ACE_UNUSED_ARG (d);
+# else /* ! defined (ACE_LACKS_REWINDDIR) */
+ ::rewinddir (d);
+# endif /* ! defined (ACE_LACKS_REWINDDIR) */
+# else /* ! ACE_LACKS_SEEKDIR */
+ // We need to implement <rewinddir> using <seekdir> since it's often
+ // defined as a macro...
+ ::seekdir (d, long (0));
+# endif /* ! ACE_LACKS_SEEKDIR */
+#else
+ ACE_UNUSED_ARG (d);
+#endif /* ACE_HAS_DIRENT */
+}
+
+ACE_INLINE int
+ACE_OS_Dirent::scandir (const ACE_TCHAR *dirname,
+ struct dirent **namelist[],
+ int (*selector)(const struct dirent *),
+ int (*comparator) (const struct dirent **f1,
+ const struct dirent **f2))
+{
+#if defined (ACE_HAS_SCANDIR)
+ return ::scandir (dirname, namelist, selector, comparator);
+#else /* ! defined ( ACE_HAS_SCANDIR) */
+ return ACE_OS_Dirent::scandir_emulation (dirname, namelist, selector, comparator);
+#endif /* ACE_HAS_SCANDIR */
+}
diff --git a/ace/OS/OS_Errno.cpp b/ace/OS/OS_Errno.cpp
new file mode 100644
index 00000000000..4ae509f6e68
--- /dev/null
+++ b/ace/OS/OS_Errno.cpp
@@ -0,0 +1,33 @@
+// -*- C++ -*-
+// $Id$
+
+#include "OS_Errno.h"
+
+ACE_RCSID(ace, OS_Errno, "$Id$")
+
+#if !defined (ACE_HAS_INLINED_OSCALLS)
+# include "OS_Errno.inl"
+#endif /* ACE_HAS_INLINED_OS_CALLS */
+
+#if defined (ACE_HAS_WINCE_BROKEN_ERRNO)
+
+ACE_CE_Errno *ACE_CE_Errno::instance_ = 0;
+DWORD ACE_CE_Errno::errno_key_ = 0xffffffff;
+
+void
+ACE_CE_Errno::init ()
+{
+ ACE_NEW (ACE_CE_Errno::instance_,
+ ACE_CE_Errno ());
+ ACE_CE_Errno::errno_key_ = TlsAlloc ();
+}
+
+void
+ACE_CE_Errno::fini ()
+{
+ TlsFree (ACE_CE_Errno::errno_key_);
+ delete ACE_CE_Errno::instance_;
+ ACE_CE_Errno::instance_ = 0;
+}
+
+#endif /* ACE_HAS_WINCE_BROKEN_ERRNO */
diff --git a/ace/OS/OS_Errno.h b/ace/OS/OS_Errno.h
new file mode 100644
index 00000000000..4adfef97762
--- /dev/null
+++ b/ace/OS/OS_Errno.h
@@ -0,0 +1,143 @@
+// -*- C++ -*-
+
+//=============================================================================
+/**
+ * @file OS_Errno.h
+ *
+ * $Id$
+ *
+ * @author (Originally in OS.h)Doug Schmidt <schmidt@cs.wustl.edu>
+ */
+//=============================================================================
+
+#ifndef ACE_OS_ERRNO_H
+#define ACE_OS_ERRNO_H
+#include "ace/pre.h"
+
+#include "ace/config.h"
+#include "OS_Export.h"
+
+#if !defined (ACE_LACKS_PRAGMA_ONCE)
+# pragma once
+#endif /* ACE_LACKS_PRAGMA_ONCE */
+
+#if defined (ACE_HAS_H_ERRNO)
+void herror (const char *str);
+#endif /* ACE_HAS_H_ERRNO */
+
+#if !defined (ACE_HAS_WINCE)
+# include /**/ <errno.h>
+#endif /* ACE_HAS_WINCE */
+
+#if !defined (ACE_WIN32) && !defined (ACE_PSOS) && defined (ACE_LACKS_T_ERRNO)
+extern int t_errno;
+#endif /* ACE_WIN32 && !ACE_PSOS && ACE_LACKS_T_ERRNO */
+
+#if !defined (ENOSYS)
+# define ENOSYS EFAULT /* Operation not supported or unknown error. */
+#endif /* !ENOSYS */
+
+#if !defined (ENOTSUP)
+# define ENOTSUP ENOSYS /* Operation not supported. */
+#endif /* !ENOTSUP */
+
+#if defined (ACE_HAS_WINCE_BROKEN_ERRNO)
+/**
+ * @class ACE_CE_Errno
+ *
+ * Some versions of CE don't support <errno> and some versions'
+ * implementations are busted. So we implement our own.
+ * Our implementation takes up one Tls key, however, it does not
+ * allocate memory fromt the heap so there's no problem with cleanin
+ * up the errno when a thread exit.
+ */
+class ACE_OS_Export ACE_CE_Errno
+{
+public:
+ ACE_CE_Errno () {}
+ static void init ();
+ static void fini ();
+ static ACE_CE_Errno *instance ();
+
+ operator int (void) const;
+ int operator= (int);
+
+private:
+ static ACE_CE_Errno *instance_;
+ static DWORD errno_key_;
+};
+
+# define errno (* (ACE_CE_Errno::instance ()))
+#endif /* ACE_HAS_WINCE_BROKEN_ERRNO */
+
+#if defined (ACE_HAS_WINCE_BROKEN_ERRNO)
+# define ACE_ERRNO_TYPE ACE_CE_Errno
+#else
+# define ACE_ERRNO_TYPE int
+#endif /* ACE_HAS_WINCE */
+
+/**
+ * @class ACE_Errno_Guard
+ *
+ * @brief Provides a wrapper to improve performance when thread-specific
+ * errno must be saved and restored in a block of code.
+ *
+ * The typical use-case for this is the following:
+ * int error = errno;
+ * call_some_function_that_might_change_errno ();
+ * errno = error;
+ * This can be replaced with
+ * {
+ * ACE_Errno_Guard guard (errno);
+ * call_some_function_that_might_change_errno ();
+ * }
+ * This implementation is more elegant and more efficient since it
+ * avoids an unnecessary second access to thread-specific storage
+ * by caching a pointer to the value of errno in TSS.
+ */
+class ACE_OS_Export ACE_Errno_Guard
+{
+public:
+ /// Stash the value of <error> into <error_> and initialize the
+ /// <errno_ptr_> to the address of <errno_ref>.
+ ACE_Errno_Guard (ACE_ERRNO_TYPE &errno_ref,
+ int error);
+
+ /// Stash the value of <errno> into <error_> and initialize the
+ /// <errno_ptr_> to the address of <errno_ref>.
+ ACE_Errno_Guard (ACE_ERRNO_TYPE &errno_ref);
+
+ /// Reset the value of <errno> to <error>.
+ ~ACE_Errno_Guard (void);
+
+#if defined (ACE_HAS_WINCE_BROKEN_ERRNO)
+ /// Assign <errno_ref> to <error_>.
+ int operator= (const ACE_ERRNO_TYPE &errno_ref);
+#endif /* ACE_HAS_WINCE_BROKEN_ERRNO */
+
+ /// Assign <error> to <error_>.
+ int operator= (int error);
+
+ /// Compare <error> with <error_> for equality.
+ int operator== (int error);
+
+ /// Compare <error> with <error_> for inequality.
+ int operator!= (int error);
+
+private:
+#if defined (ACE_MT_SAFE)
+ ACE_ERRNO_TYPE *errno_ptr_;
+#endif /* ACE_MT_SAFE */
+ int error_;
+};
+
+#if defined (ACE_HAS_INLINED_OSCALLS)
+# if defined (ACE_INLINE)
+# undef ACE_INLINE
+# endif /* ACE_INLINE */
+# define ACE_INLINE inline
+# include "OS_Errno.inl"
+#endif /* ACE_HAS_INLINED_OSCALLS */
+
+#include "ace/post.h"
+#endif /* ACE_OS_ERRNO_H */
diff --git a/ace/OS/OS_Errno.inl b/ace/OS/OS_Errno.inl
new file mode 100644
index 00000000000..1fb222075be
--- /dev/null
+++ b/ace/OS/OS_Errno.inl
@@ -0,0 +1,87 @@
+// -*- C++ -*-
+// $Id$
+
+#if defined (ACE_HAS_WINCE_BROKEN_ERRNO)
+
+ACE_INLINE ACE_CE_Errno *
+ACE_CE_Errno::instance ()
+{
+ // This should be inlined.
+ return ACE_CE_Errno::instance_;
+}
+
+ACE_INLINE
+ACE_CE_Errno::operator int (void) const
+{
+ return (int) TlsGetValue (ACE_CE_Errno::errno_key_);
+}
+
+ACE_INLINE int
+ACE_CE_Errno::operator= (int x)
+{
+ // error checking?
+ TlsSetValue (ACE_CE_Errno::errno_key_, (void *) x);
+ return x;
+}
+
+#endif /* ACE_HAS_WINCE_BROKEN_ERRNO */
+
+ACE_INLINE
+ACE_Errno_Guard::ACE_Errno_Guard (ACE_ERRNO_TYPE &errno_ref,
+ int error)
+ :
+#if defined (ACE_MT_SAFE)
+ errno_ptr_ (&errno_ref),
+#endif /* ACE_MT_SAFE */
+ error_ (error)
+{
+#if !defined(ACE_MT_SAFE)
+ ACE_UNUSED_ARG (errno_ref);
+#endif /* ACE_MT_SAFE */
+}
+
+ACE_INLINE
+ACE_Errno_Guard::ACE_Errno_Guard (ACE_ERRNO_TYPE &errno_ref)
+ :
+#if defined (ACE_MT_SAFE)
+ errno_ptr_ (&errno_ref),
+#endif /* ACE_MT_SAFE */
+ error_ (errno_ref)
+{
+}
+
+ACE_INLINE
+ACE_Errno_Guard::~ACE_Errno_Guard (void)
+{
+#if defined (ACE_MT_SAFE)
+ *errno_ptr_ = this->error_;
+#else
+ errno = this->error_;
+#endif /* ACE_MT_SAFE */
+}
+
+#if defined (ACE_HAS_WINCE_BROKEN_ERRNO)
+ACE_INLINE int
+ACE_Errno_Guard::operator= (const ACE_ERRNO_TYPE &error)
+{
+ return this->error_ = error;
+}
+#endif /* ACE_HAS_WINCE_BROKEN_ERRNO */
+
+ACE_INLINE int
+ACE_Errno_Guard::operator= (int error)
+{
+ return this->error_ = error;
+}
+
+ACE_INLINE int
+ACE_Errno_Guard::operator== (int error)
+{
+ return this->error_ == error;
+}
+
+ACE_INLINE int
+ACE_Errno_Guard::operator!= (int error)
+{
+ return this->error_ != error;
+}
diff --git a/ace/OS/OS_Export.h b/ace/OS/OS_Export.h
new file mode 100644
index 00000000000..bc6841996c8
--- /dev/null
+++ b/ace/OS/OS_Export.h
@@ -0,0 +1,46 @@
+// -*- C++ -*-
+// $Id$
+// Definition for Win32 Export directives.
+// This file is generated automatically by
+// generate_export_file.pl
+// ------------------------------
+#if !defined (ACE_OS_EXPORT_H)
+#define ACE_OS_EXPORT_H
+
+#include "ace/config-all.h"
+
+#if defined (ACE_AS_STATIC_LIBS)
+# if !defined (ACE_OS_HAS_DLL)
+# define ACE_OS_HAS_DLL 0
+# endif /* ! ACE_OS_HAS_DLL */
+#else
+# if !defined (ACE_OS_HAS_DLL)
+# define ACE_OS_HAS_DLL 1
+# endif /* ! ACE_OS_HAS_DLL */
+#endif /* ACE_AS_STATIC_LIB */
+
+#if defined (ACE_OS_HAS_DLL)
+# if (ACE_OS_HAS_DLL == 1)
+# if defined (ACE_OS_BUILD_DLL)
+# define ACE_OS_Export ACE_Proper_Export_Flag
+# define ACE_OS_SINGLETON_DECLARATION(T) ACE_EXPORT_SINGLETON_DECLARATION (T)
+# define ACE_OS_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) ACE_EXPORT_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK)
+# else
+# define ACE_OS_Export ACE_Proper_Import_Flag
+# define ACE_OS_SINGLETON_DECLARATION(T) ACE_IMPORT_SINGLETON_DECLARATION (T)
+# define ACE_OS_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) ACE_IMPORT_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK)
+# endif /* ACE_OS_BUILD_DLL */
+# else
+# define ACE_OS_Export
+# define ACE_OS_SINGLETON_DECLARATION(T)
+# define ACE_OS_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK)
+# endif /* ! ACE_OS_HAS_DLL == 1 */
+#else
+# define ACE_OS_Export
+# define ACE_OS_SINGLETON_DECLARATION(T)
+# define ACE_OS_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK)
+#endif /* ACE_OS_HAS_DLL */
+
+#endif /* ACE_OS_EXPORT_H */
+
+// End of auto generated file.
diff --git a/ace/OS/OS_Log_Msg_Attributes.cpp b/ace/OS/OS_Log_Msg_Attributes.cpp
new file mode 100644
index 00000000000..62bbfe3adda
--- /dev/null
+++ b/ace/OS/OS_Log_Msg_Attributes.cpp
@@ -0,0 +1,9 @@
+// $Id$
+
+#include "OS_Log_Msg_Attributes.h"
+
+#if !defined (ACE_HAS_INLINED_OSCALLS)
+# include "OS_Log_Msg_Attributes.inl"
+#endif /* ACE_HAS_INLINED_OS_CALLS */
+
+ACE_RCSID(ace, OS_Log_Msg_Attributes, "$Id$")
diff --git a/ace/OS/OS_Log_Msg_Attributes.h b/ace/OS/OS_Log_Msg_Attributes.h
new file mode 100644
index 00000000000..094850a7012
--- /dev/null
+++ b/ace/OS/OS_Log_Msg_Attributes.h
@@ -0,0 +1,89 @@
+// -*- C++ -*-
+
+//=============================================================================
+/**
+ * @file OS_Log_Msg_Attributes.h
+ *
+ * $Id$
+ *
+ * @author Carlos O'Ryan
+ */
+//=============================================================================
+
+
+#ifndef ACE_OS_LOG_MSG_ATTRIBUTES_H
+#define ACE_OS_LOG_MSG_ATTRIBUTES_H
+#include "ace/pre.h"
+
+#include "ace/config-all.h"
+#include "ace/streams.h"
+#include /**/ <stdarg.h> // LynxOS requires this before stdio.h
+#include /**/ <stdio.h>
+
+#if !defined (ACE_LACKS_PRAGMA_ONCE)
+# pragma once
+#endif /* ACE_LACKS_PRAGMA_ONCE */
+
+#if !defined (ACE_OSTREAM_TYPE)
+# if defined (ACE_LACKS_IOSTREAM_TOTALLY)
+# define ACE_OSTREAM_TYPE FILE
+# else /* ! ACE_LACKS_IOSTREAM_TOTALLY */
+# define ACE_OSTREAM_TYPE ostream
+# endif /* ! ACE_LACKS_IOSTREAM_TOTALLY */
+#endif /* ! ACE_OSTREAM_TYPE */
+
+
+#include "OS_Export.h"
+
+/// The attributes required by ACE_Log_Msg.
+/**
+ * When a new thread is created the TSS resources for the Log_Msg
+ * class in the new thread may be inherited by the creator thread.
+ * The base_attributes are encapsulated in this class to simplify their
+ * manipulation and destruction.
+ *
+ * The contents of the class must be made available to the OS layer,
+ * because they are part of the thread descriptor.
+ */
+class ACE_OS_Export ACE_OS_Log_Msg_Attributes
+{
+public:
+ /// Constructor
+ ACE_OS_Log_Msg_Attributes (void);
+
+protected:
+ friend class ACE_Log_Msg;
+
+ /// Ostream where the new TSS Log_Msg will use.
+ ACE_OSTREAM_TYPE *ostream_;
+
+ /// Priority_mask to be used in new TSS Log_Msg.
+ unsigned long priority_mask_;
+
+ /// Are we allowing tracing in this thread?
+ int tracing_enabled_;
+
+ /// Indicates whether we should restart system calls that are
+ /// interrupted.
+ int restart_;
+
+ /// Depth of the nesting for printing traces.
+ int trace_depth_;
+
+# if defined (ACE_HAS_WIN32_STRUCTURAL_EXCEPTIONS)
+ /// Structured exception handling Callbacks, only used under Win32
+ ACE_SEH_EXCEPT_HANDLER seh_except_selector_;
+ ACE_SEH_EXCEPT_HANDLER seh_except_handler_;
+# endif /* ACE_HAS_WIN32_STRUCTURAL_EXCEPTIONS */
+};
+
+# if defined (ACE_HAS_INLINED_OSCALLS)
+# if defined (ACE_INLINE)
+# undef ACE_INLINE
+# endif /* ACE_INLINE */
+# define ACE_INLINE inline
+# include "OS_Log_Msg_Attributes.inl"
+# endif /* ACE_HAS_INLINED_OSCALLS */
+
+#include "ace/post.h"
+#endif /* ACE_OS_LOG_MSG_ATTRIBUTES_H */
diff --git a/ace/OS/OS_Log_Msg_Attributes.inl b/ace/OS/OS_Log_Msg_Attributes.inl
new file mode 100644
index 00000000000..d79e7fe90f8
--- /dev/null
+++ b/ace/OS/OS_Log_Msg_Attributes.inl
@@ -0,0 +1,6 @@
+// $Id$
+
+ACE_INLINE
+ACE_OS_Log_Msg_Attributes::ACE_OS_Log_Msg_Attributes (void)
+{
+}
diff --git a/ace/OS/OS_Memory.cpp b/ace/OS/OS_Memory.cpp
new file mode 100644
index 00000000000..8eb3ab2b308
--- /dev/null
+++ b/ace/OS/OS_Memory.cpp
@@ -0,0 +1,13 @@
+// $Id$
+
+#include "OS_Memory.h"
+
+ACE_RCSID(ace, OS_Memory, "$Id$")
+
+#if !defined (ACE_HAS_INLINED_OSCALLS)
+# include "OS_Memory.inl"
+#else /* !ACE_HAS_INLINED_OSCALLS */
+#if defined (__hpux) && !defined (__GNUG__)
+static int shut_up_aCC = 0;
+#endif /* HPUX && !g++ */
+#endif /* !ACE_HAS_INLINED_OS_CALLS */
diff --git a/ace/OS/OS_Memory.h b/ace/OS/OS_Memory.h
new file mode 100644
index 00000000000..cdd0833b626
--- /dev/null
+++ b/ace/OS/OS_Memory.h
@@ -0,0 +1,123 @@
+// -*- C++ -*-
+
+//=============================================================================
+/**
+ * @file OS_Memory.h
+ *
+ * $Id$
+ *
+ * @author Doug Schmidt <schmidt@cs.wustl.edu>
+ * @author Jesper S. M|ller<stophph@diku.dk>
+ * @author and a cast of thousands...
+ */
+//=============================================================================
+
+#ifndef ACE_OS_MEMORY_H
+#define ACE_OS_MEMORY_H
+#include "ace/pre.h"
+
+#include "ace/config-all.h"
+
+#if !defined (ACE_LACKS_PRAGMA_ONCE)
+# pragma once
+#endif /* ACE_LACKS_PRAGMA_ONCE */
+
+#include "OS_Export.h"
+#if defined (ACE_HAS_PACE)
+# include /**/ "pace/stdlib.h"
+#endif /* ACE_HAS_PACE */
+#include /**/ <stddef.h>
+
+# if !defined (ACE_MALLOC_ALIGN)
+# define ACE_MALLOC_ALIGN ((int) sizeof (long))
+# endif /* ACE_MALLOC_ALIGN */
+
+# if !defined (ACE_HAS_POSITION_INDEPENDENT_POINTERS)
+# define ACE_HAS_POSITION_INDEPENDENT_POINTERS 1
+# endif /* ACE_HAS_POSITION_INDEPENDENT_POINTERS */
+
+// Allow an installation to replace the lowest-level allocation
+// functions without changing the source of ACE.
+//
+// To do this, simple #define ACE_*_FUNC macros in config.h to
+// the names of the site-specific functions, e.g.,
+//
+// #define ACE_MALLOC_FUNC dlmalloc
+// #define ACE_CALLOC_FUNC dlcalloc
+// #define ACE_FREE_FUNC dlfree
+// #define ACE_REALLOC_FUNC dlrealloc
+//
+// For completeness' sake, you should probably put
+// #define ACE_HAS_STRDUP_EMULATION
+// too, so that you guarantee that strdup() calls your desired mallocator
+// and not the system mallocator.
+//
+# if defined (ACE_HAS_PACE)
+# if !defined (ACE_MALLOC_FUNC)
+# define ACE_MALLOC_FUNC pace_malloc
+# endif
+# if !defined (ACE_CALLOC_FUNC)
+# define ACE_CALLOC_FUNC pace_calloc
+# endif
+# if !defined (ACE_FREE_FUNC)
+# define ACE_FREE_FUNC pace_free
+# endif
+# if !defined (ACE_REALLOC_FUNC)
+# define ACE_REALLOC_FUNC pace_realloc
+# endif
+
+# if defined (ACE_HAS_OLD_MALLOC)
+typedef char *ACE_MALLOC_T;
+# else
+typedef void *ACE_MALLOC_T;
+# endif /* ACE_HAS_OLD_MALLOC */
+
+# else
+
+# if !defined (ACE_MALLOC_FUNC)
+# define ACE_MALLOC_FUNC ::malloc
+# endif
+# if !defined (ACE_CALLOC_FUNC)
+# define ACE_CALLOC_FUNC ::calloc
+# endif
+# if !defined (ACE_FREE_FUNC)
+# define ACE_FREE_FUNC ::free
+# endif
+# if !defined (ACE_REALLOC_FUNC)
+# define ACE_REALLOC_FUNC ::realloc
+# endif
+
+# if defined (ACE_HAS_OLD_MALLOC)
+typedef char *ACE_MALLOC_T;
+# else
+typedef void *ACE_MALLOC_T;
+# endif /* ACE_HAS_OLD_MALLOC */
+#endif /* ACE_HAS_PACE */
+
+/**
+ * @class ACE_OS_Memory
+ *
+ * @brief This class is a wrapper for dynamic memory operations.
+ *
+ */
+class ACE_OS_Export ACE_OS_Memory
+{
+public:
+ // = A set of wrappers for memory managment.
+ static void *sbrk (int brk);
+ static void *calloc (size_t elements, size_t sizeof_elements);
+ static void *malloc (size_t);
+ static void *realloc (void *, size_t);
+ static void free (void *);
+};
+
+# if defined (ACE_HAS_INLINED_OSCALLS)
+# if defined (ACE_INLINE)
+# undef ACE_INLINE
+# endif /* ACE_INLINE */
+# define ACE_INLINE inline
+# include "OS_Memory.inl"
+# endif /* ACE_HAS_INLINED_OSCALLS */
+
+#include "ace/post.h"
+#endif /* ACE_OS_MEMORY_H */
diff --git a/ace/OS/OS_Memory.inl b/ace/OS/OS_Memory.inl
new file mode 100644
index 00000000000..510a281346c
--- /dev/null
+++ b/ace/OS/OS_Memory.inl
@@ -0,0 +1,50 @@
+// $Id$
+
+#if ! defined (ACE_PSOS_DIAB_MIPS)
+# include /**/ <stdlib.h>
+#endif /* ! ACE_PSOS_DIAB_MIPS */
+
+#if !defined (ACE_LACKS_UNISTD_H) && !defined (ACE_PSOS)
+# include /**/ <unistd.h>
+#endif /* !ACE_LACKS_UNISTD_H && !ACE_PSOS */
+
+ACE_INLINE void *
+ACE_OS_Memory::sbrk (int brk)
+{
+#if defined (ACE_LACKS_SBRK)
+ ACE_UNUSED_ARG (brk);
+ ACE_NOTSUP_RETURN (0);
+#else
+ ACE_OSCALL_RETURN (::sbrk (brk), void *, 0);
+#endif /* VXWORKS */
+}
+
+ACE_INLINE void *
+ACE_OS_Memory::malloc (size_t nbytes)
+{
+ return ACE_MALLOC_FUNC (nbytes);
+}
+
+ACE_INLINE void *
+ACE_OS_Memory::calloc (size_t elements, size_t sizeof_elements)
+{
+#if !defined (ACE_HAS_WINCE)
+ return ACE_CALLOC_FUNC (elements, sizeof_elements);
+#else
+ // @@ This will probably not work since it doesn't consider
+ // alignment properly.
+ return ACE_MALLOC_FUNC (elements * sizeof_elements);
+#endif /* ACE_HAS_WINCE */
+}
+
+ACE_INLINE void *
+ACE_OS_Memory::realloc (void *ptr, size_t nbytes)
+{
+ return ACE_REALLOC_FUNC (ACE_MALLOC_T (ptr), nbytes);
+}
+
+ACE_INLINE void
+ACE_OS_Memory::free (void *ptr)
+{
+ ACE_FREE_FUNC (ACE_MALLOC_T (ptr));
+}
diff --git a/ace/OS/OS_QoS.cpp b/ace/OS/OS_QoS.cpp
new file mode 100644
index 00000000000..a6cca321436
--- /dev/null
+++ b/ace/OS/OS_QoS.cpp
@@ -0,0 +1,471 @@
+//=============================================================================
+///**
+// * @file OS_QoS.cpp
+// *
+// * $Id$
+// *
+// * @brief Contains OS specific data structures for QoS networking.
+// *
+// * @author Craig Rodrigues <crodrigu@bbn.com>
+// */
+//=============================================================================
+
+#include "OS_QoS.h"
+
+ACE_Flow_Spec::ACE_Flow_Spec (u_long token_rate,
+ u_long token_bucket_size,
+ u_long peak_bandwidth,
+ u_long latency,
+ u_long delay_variation,
+ ACE_SERVICE_TYPE service_type,
+ u_long max_sdu_size,
+ u_long minimum_policed_size,
+ int ttl,
+ int priority)
+{
+#if defined (ACE_HAS_WINSOCK2) && (ACE_HAS_WINSOCK2 != 0)
+ this->TokenRate = token_rate;
+ this->TokenBucketSize = token_bucket_size;
+ this->PeakBandwidth = peak_bandwidth;
+ this->Latency = latency;
+ this->DelayVariation = delay_variation;
+#if defined(ACE_HAS_WINSOCK2_GQOS)
+ this->ServiceType = service_type;
+ this->MaxSduSize = max_sdu_size;
+ this->MinimumPolicedSize = minimum_policed_size;
+#else
+ ACE_UNUSED_ARG (service_type);
+ ACE_UNUSED_ARG (max_sdu_size);
+ ACE_UNUSED_ARG (minimum_policed_size);
+#endif /* ACE_HAS_WINSOCK2_GQOS */
+ ACE_UNUSED_ARG (ttl);
+ ACE_UNUSED_ARG (priority);
+#else
+
+ this->token_rate_ = token_rate;
+ this->token_bucket_size_ = token_bucket_size;
+ this->peak_bandwidth_ = peak_bandwidth;
+ this->latency_ = latency;
+ this->delay_variation_ = delay_variation;
+ this->service_type_ = service_type;
+ this->max_sdu_size_ = max_sdu_size;
+ this->minimum_policed_size_ = minimum_policed_size;
+ this->ttl_ = ttl;
+ this->priority_ = priority;
+
+#endif /* defined (ACE_HAS_WINSOCK2) && (ACE_HAS_WINSOCK2 != 0) */
+}
+
+ACE_Flow_Spec::ACE_Flow_Spec (void)
+{
+#if defined (ACE_HAS_WINSOCK2) && (ACE_HAS_WINSOCK2 != 0) && \
+ defined (ACE_HAS_WINSOCK2_GQOS)
+ this->TokenRate = 0;
+ this->TokenBucketSize = 0;
+ this->PeakBandwidth = 0;
+ this->Latency = 0;
+ this->DelayVariation = 0;
+#if defined(ACE_HAS_WINSOCK2_GQOS)
+ this->ServiceType = 0;
+ this->MaxSduSize = 0;
+ this->MinimumPolicedSize = 0;
+#endif /* ACE_HAS_WINSOCK2_GQOS */
+#else
+
+ this->token_rate_ = 0;
+ this->token_bucket_size_ = 0;
+ this->peak_bandwidth_ = 0;
+ this->latency_ = 0;
+ this->delay_variation_ = 0;
+ this->service_type_ = 0;
+ this->max_sdu_size_ = 0;
+ this->minimum_policed_size_ = 0;
+ this->ttl_ = 0;
+ this->priority_ = 0;
+
+#endif /* defined (ACE_HAS_WINSOCK2) && (ACE_HAS_WINSOCK2 != 0) */
+}
+
+u_long
+ACE_Flow_Spec::token_rate (void) const
+{
+#if defined (ACE_HAS_WINSOCK2) && (ACE_HAS_WINSOCK2 != 0)
+ return this->TokenRate;
+#else
+ return this->token_rate_;
+#endif /* ACE_HAS_WINSOCK2 */
+}
+
+void
+ACE_Flow_Spec::token_rate (u_long tr)
+{
+#if defined (ACE_HAS_WINSOCK2) && (ACE_HAS_WINSOCK2 != 0)
+ this->TokenRate = tr;
+#else
+ this->token_rate_ = tr;
+#endif /* ACE_HAS_WINSOCK2 */
+}
+
+u_long
+ACE_Flow_Spec::token_bucket_size (void) const
+{
+#if defined (ACE_HAS_WINSOCK2) && (ACE_HAS_WINSOCK2 != 0)
+ return this->TokenBucketSize;
+#else
+ return this->token_bucket_size_;
+#endif /* ACE_HAS_WINSOCK2 */
+}
+
+void
+ACE_Flow_Spec::token_bucket_size (u_long tbs)
+{
+#if defined (ACE_HAS_WINSOCK2) && (ACE_HAS_WINSOCK2 != 0)
+ this->TokenBucketSize = tbs;
+#else
+ this->token_bucket_size_ = tbs;
+#endif /* ACE_HAS_WINSOCK2 */
+}
+
+u_long
+ACE_Flow_Spec::peak_bandwidth (void) const
+{
+#if defined (ACE_HAS_WINSOCK2) && (ACE_HAS_WINSOCK2 != 0)
+ return this->PeakBandwidth;
+#else
+ return this->peak_bandwidth_;
+#endif /* ACE_HAS_WINSOCK2 */
+}
+
+void
+ACE_Flow_Spec::peak_bandwidth (u_long pb)
+{
+#if defined (ACE_HAS_WINSOCK2) && (ACE_HAS_WINSOCK2 != 0)
+ this->PeakBandwidth = pb;
+#else
+ this->peak_bandwidth_ = pb;
+#endif /* ACE_HAS_WINSOCK2 */
+}
+
+u_long
+ACE_Flow_Spec::latency (void) const
+{
+#if defined (ACE_HAS_WINSOCK2) && (ACE_HAS_WINSOCK2 != 0)
+ return this->Latency;
+#else
+ return this->latency_;
+#endif /* ACE_HAS_WINSOCK2 */
+}
+
+void
+ACE_Flow_Spec::latency (u_long l)
+{
+#if defined (ACE_HAS_WINSOCK2) && (ACE_HAS_WINSOCK2 != 0)
+ this->Latency = l;
+#else
+ this->latency_ = l;
+#endif /* ACE_HAS_WINSOCK2 */
+}
+
+u_long
+ACE_Flow_Spec::delay_variation (void) const
+{
+#if defined (ACE_HAS_WINSOCK2) && (ACE_HAS_WINSOCK2 != 0)
+ return this->DelayVariation;
+#else
+ return this->delay_variation_;
+#endif /* ACE_HAS_WINSOCK2 */
+}
+void
+ACE_Flow_Spec::delay_variation (u_long dv)
+{
+#if defined (ACE_HAS_WINSOCK2) && (ACE_HAS_WINSOCK2 != 0)
+ this->DelayVariation = dv;
+#else
+ this->delay_variation_ = dv;
+#endif /* ACE_HAS_WINSOCK2 */
+}
+
+ACE_SERVICE_TYPE
+ACE_Flow_Spec::service_type (void) const
+{
+#if defined (ACE_HAS_WINSOCK2) && (ACE_HAS_WINSOCK2 != 0) && \
+ defined (ACE_HAS_WINSOCK2_GQOS)
+ return this->ServiceType;
+#else
+ return this->service_type_;
+#endif /* ACE_HAS_WINSOCK2 */
+}
+
+void
+ACE_Flow_Spec::service_type (ACE_SERVICE_TYPE st)
+{
+#if defined (ACE_HAS_WINSOCK2) && (ACE_HAS_WINSOCK2 != 0) && \
+ defined (ACE_HAS_WINSOCK2_GQOS)
+ this->ServiceType = st;
+#else
+ this->service_type_ = st;
+#endif /* ACE_HAS_WINSOCK2 */
+}
+
+u_long
+ACE_Flow_Spec::max_sdu_size (void) const
+{
+#if defined (ACE_HAS_WINSOCK2) && (ACE_HAS_WINSOCK2 != 0) && \
+ defined (ACE_HAS_WINSOCK2_GQOS)
+ return this->MaxSduSize;
+#else
+ return this->max_sdu_size_;
+#endif /* ACE_HAS_WINSOCK2 */
+}
+
+void
+ACE_Flow_Spec::max_sdu_size (u_long mss)
+{
+#if defined (ACE_HAS_WINSOCK2) && (ACE_HAS_WINSOCK2 != 0) && \
+ defined (ACE_HAS_WINSOCK2_GQOS)
+ this->MaxSduSize = mss;
+#else
+ this->max_sdu_size_ = mss;
+#endif /* ACE_HAS_WINSOCK2 */
+}
+
+u_long
+ACE_Flow_Spec::minimum_policed_size (void) const
+{
+#if defined (ACE_HAS_WINSOCK2) && (ACE_HAS_WINSOCK2 != 0) && \
+ defined (ACE_HAS_WINSOCK2_GQOS)
+ return this->MinimumPolicedSize;
+#else
+ return this->minimum_policed_size_;
+#endif /* ACE_HAS_WINSOCK2 */
+}
+
+void
+ACE_Flow_Spec::minimum_policed_size (u_long mps)
+{
+#if defined (ACE_HAS_WINSOCK2) && (ACE_HAS_WINSOCK2 != 0) && \
+ defined (ACE_HAS_WINSOCK2_GQOS)
+ this->MinimumPolicedSize = mps;
+#else
+ this->minimum_policed_size_ = mps;
+#endif /* ACE_HAS_WINSOCK2 */
+}
+
+int
+ACE_Flow_Spec::ttl (void) const
+{
+#if defined (ACE_HAS_WINSOCK2) && (ACE_HAS_WINSOCK2 != 0) && \
+ defined (ACE_HAS_WINSOCK2_GQOS)
+ ACE_NOTSUP_RETURN (-1);
+#else
+ return this->ttl_;
+#endif /* ACE_HAS_WINSOCK2 */
+}
+
+void
+ACE_Flow_Spec::ttl (int t)
+{
+#if defined (ACE_HAS_WINSOCK2) && (ACE_HAS_WINSOCK2 != 0) && \
+ defined (ACE_HAS_WINSOCK2_GQOS)
+ ACE_UNUSED_ARG (t);
+ // TBD...
+#else
+ this->ttl_ = t;
+#endif /* ACE_HAS_WINSOCK2 */
+}
+
+int
+ACE_Flow_Spec::priority (void) const
+{
+#if defined (ACE_HAS_WINSOCK2) && (ACE_HAS_WINSOCK2 != 0) && \
+ defined (ACE_HAS_WINSOCK2_GQOS)
+ ACE_NOTSUP_RETURN (-1);
+#else
+ return this->priority_;
+#endif /* ACE_HAS_WINSOCK2 */
+}
+
+void
+ACE_Flow_Spec::priority (int p)
+{
+#if defined (ACE_HAS_WINSOCK2) && (ACE_HAS_WINSOCK2 != 0) && \
+ defined (ACE_HAS_WINSOCK2_GQOS)
+ ACE_UNUSED_ARG (p);
+ // TBD...
+#else
+ this->priority_ = p;
+#endif /* ACE_HAS_WINSOCK2 */
+}
+
+ACE_QoS::ACE_QoS (void)
+#if defined (ACE_HAS_WINSOCK2) && (ACE_HAS_WINSOCK2 != 0)
+#else
+ : sending_flowspec_ (0),
+ receiving_flowspec_ (0)
+#endif /* ACE_HAS_WINSOCK2 */
+{
+}
+
+ACE_Flow_Spec*
+ACE_QoS::sending_flowspec (void) const
+{
+#if defined (ACE_HAS_WINSOCK2) && (ACE_HAS_WINSOCK2 != 0)
+ return &((ACE_Flow_Spec &) this->SendingFlowspec);
+#else
+ return this->sending_flowspec_;
+#endif /* ACE_HAS_WINSOCK2 */
+}
+
+void
+ACE_QoS::sending_flowspec (ACE_Flow_Spec *fs)
+{
+#if defined (ACE_HAS_WINSOCK2) && (ACE_HAS_WINSOCK2 != 0)
+ this->SendingFlowspec = (FLOWSPEC) (*fs);
+#else
+ this->sending_flowspec_ = fs;
+#endif /* ACE_HAS_WINSOCK2 */
+}
+
+ACE_Flow_Spec*
+ACE_QoS::receiving_flowspec (void) const
+{
+#if defined (ACE_HAS_WINSOCK2) && (ACE_HAS_WINSOCK2 != 0)
+ return &((ACE_Flow_Spec &) this->ReceivingFlowspec);
+#else
+ return receiving_flowspec_;
+#endif /* ACE_HAS_WINSOCK2 */
+}
+
+void
+ACE_QoS::receiving_flowspec (ACE_Flow_Spec *fs)
+{
+#if defined (ACE_HAS_WINSOCK2) && (ACE_HAS_WINSOCK2 != 0)
+ this->ReceivingFlowspec = (FLOWSPEC) (*fs);
+#else
+ this->receiving_flowspec_ = fs;
+#endif /* ACE_HAS_WINSOCK2 */
+}
+
+iovec
+ACE_QoS::provider_specific (void) const
+{
+#if defined (ACE_HAS_WINSOCK2) && (ACE_HAS_WINSOCK2 != 0)
+ return (iovec&) this->ProviderSpecific;
+#else
+ ACE_NOTSUP_RETURN (iovec ());
+#endif /* ACE_HAS_WINSOCK2 */
+}
+
+void
+ACE_QoS::provider_specific (const iovec &ps)
+{
+#if defined (ACE_HAS_WINSOCK2) && (ACE_HAS_WINSOCK2 != 0)
+ this->ProviderSpecific = (WSABUF) ((iovec &) ps);
+#else
+ ACE_UNUSED_ARG (ps);
+#endif /* ACE_HAS_WINSOCK2 */
+}
+
+ACE_QoS_Params::ACE_QoS_Params (iovec *caller_data,
+ iovec *callee_data,
+ ACE_QoS *socket_qos,
+ ACE_QoS *group_socket_qos,
+ u_long flags)
+ : caller_data_ (caller_data),
+ callee_data_ (callee_data),
+ socket_qos_ (socket_qos),
+ group_socket_qos_ (group_socket_qos),
+ flags_ (flags)
+{
+}
+
+iovec *
+ACE_QoS_Params::caller_data (void) const
+{
+ return this->caller_data_;
+}
+
+void
+ACE_QoS_Params::caller_data (iovec *cd)
+{
+ this->caller_data_ = cd;
+}
+
+iovec *
+ACE_QoS_Params::callee_data (void) const
+{
+ return this->callee_data_;
+}
+
+void
+ACE_QoS_Params::callee_data (iovec *cd)
+{
+ this->callee_data_ = cd;
+}
+
+ACE_QoS *
+ACE_QoS_Params::socket_qos (void) const
+{
+ return this->socket_qos_;
+}
+
+void
+ACE_QoS_Params::socket_qos (ACE_QoS *sq)
+{
+ this->socket_qos_ = sq;
+}
+
+ACE_QoS *
+ACE_QoS_Params::group_socket_qos (void) const
+{
+ return this->group_socket_qos_;
+}
+
+void
+ACE_QoS_Params::group_socket_qos (ACE_QoS *gsq)
+{
+ this->group_socket_qos_ = gsq;
+}
+
+u_long
+ACE_QoS_Params::flags (void) const
+{
+ return this->flags_;
+}
+
+void
+ACE_QoS_Params::flags (u_long f)
+{
+ this->flags_ = f;
+}
+
+ACE_Accept_QoS_Params::ACE_Accept_QoS_Params (ACE_QOS_CONDITION_FUNC qos_condition_callback,
+ u_long callback_data)
+ : qos_condition_callback_ (qos_condition_callback),
+ callback_data_ (callback_data)
+{
+}
+
+ACE_QOS_CONDITION_FUNC
+ACE_Accept_QoS_Params::qos_condition_callback (void) const
+{
+ return this->qos_condition_callback_;
+}
+
+void
+ACE_Accept_QoS_Params::qos_condition_callback (ACE_QOS_CONDITION_FUNC qcc)
+{
+ this->qos_condition_callback_ = qcc;
+}
+
+u_long
+ACE_Accept_QoS_Params::callback_data (void) const
+{
+ return this->callback_data_;
+}
+
+void
+ACE_Accept_QoS_Params::callback_data (u_long cd)
+{
+ this->callback_data_ = cd;
+}
diff --git a/ace/OS/OS_QoS.h b/ace/OS/OS_QoS.h
new file mode 100644
index 00000000000..93d6b29d4a4
--- /dev/null
+++ b/ace/OS/OS_QoS.h
@@ -0,0 +1,386 @@
+// -*- C++ -*-
+
+//=============================================================================
+/**
+ * @file OS_QoS.h
+ *
+ * $Id$
+ *
+ * @brief Contains OS specific data structures for QoS networking.
+ *
+ * @author Craig Rodrigues <crodrigu@bbn.com>
+ */
+//=============================================================================
+
+#ifndef ACE_OS_QOS_H
+#define ACE_OS_QOS_H
+#include "ace/pre.h"
+
+#include "OS.h"
+
+#if !defined (ACE_LACKS_PRAGMA_ONCE)
+# pragma once
+#endif /* ACE_LACKS_PRAGMA_ONCE */
+
+#if defined (ACE_HAS_WINSOCK2) && (ACE_HAS_WINSOCK2 != 0)
+#if defined (ACE_HAS_WINSOCK2_GQOS)
+typedef SERVICETYPE ACE_SERVICE_TYPE;
+#else
+typedef u_long ACE_SERVICE_TYPE;
+#endif /* ACE_HAS_WINSOCK2_GQOS */
+
+
+#define ACE_OVERLAPPED_SOCKET_FLAG WSA_FLAG_OVERLAPPED
+
+#define ACE_XP1_QOS_SUPPORTED XP1_QOS_SUPPORTED
+#define ACE_XP1_SUPPORT_MULTIPOINT XP1_SUPPORT_MULTIPOINT
+
+#define ACE_BASEERR WSABASEERR
+#define ACE_ENOBUFS WSAENOBUFS
+#define ACE_FROM_PROTOCOL_INFO FROM_PROTOCOL_INFO
+#define ACE_FLAG_MULTIPOINT_C_ROOT WSA_FLAG_MULTIPOINT_C_ROOT
+#define ACE_FLAG_MULTIPOINT_C_LEAF WSA_FLAG_MULTIPOINT_C_LEAF
+#define ACE_FLAG_MULTIPOINT_D_ROOT WSA_FLAG_MULTIPOINT_D_ROOT
+#define ACE_FLAG_MULTIPOINT_D_LEAF WSA_FLAG_MULTIPOINT_D_LEAF
+
+#define ACE_QOS_NOT_SPECIFIED QOS_NOT_SPECIFIED
+#define ACE_SERVICETYPE_NOTRAFFIC SERVICETYPE_NOTRAFFIC
+#define ACE_SERVICETYPE_CONTROLLEDLOAD SERVICETYPE_CONTROLLEDLOAD
+#define ACE_SERVICETYPE_GUARANTEED SERVICETYPE_GUARANTEED
+
+#define ACE_JL_SENDER_ONLY JL_SENDER_ONLY
+#define ACE_JL_BOTH JL_BOTH
+
+#define ACE_SIO_GET_QOS SIO_GET_QOS
+#define ACE_SIO_MULTIPOINT_LOOPBACK SIO_MULTIPOINT_LOOPBACK
+#define ACE_SIO_MULTICAST_SCOPE SIO_MULTICAST_SCOPE
+#define ACE_SIO_SET_QOS SIO_SET_QOS
+
+#else
+typedef u_long ACE_SERVICE_TYPE;
+
+#define ACE_OVERLAPPED_SOCKET_FLAG 0
+#define ACE_XP1_QOS_SUPPORTED 0x00002000
+#define ACE_XP1_SUPPORT_MULTIPOINT 0x00000400
+
+#define ACE_BASEERR 10000
+#define ACE_ENOBUFS (ACE_BASEERR+55)
+
+#define ACE_FROM_PROTOCOL_INFO (-1)
+
+#define ACE_FLAG_MULTIPOINT_C_ROOT 0x02
+#define ACE_FLAG_MULTIPOINT_C_LEAF 0x04
+#define ACE_FLAG_MULTIPOINT_D_ROOT 0x08
+#define ACE_FLAG_MULTIPOINT_D_LEAF 0x10
+
+#define ACE_QOS_NOT_SPECIFIED 0xFFFFFFFF
+#define ACE_SERVICETYPE_NOTRAFFIC 0x00000000 /* No data in this */
+ /* direction. */
+#define ACE_SERVICETYPE_CONTROLLEDLOAD 0x00000001 /* Controlled Load. */
+#define ACE_SERVICETYPE_GUARANTEED 0x00000003 /* Guaranteed. */
+
+#define ACE_JL_SENDER_ONLY 0x01
+#define ACE_JL_BOTH 0x04
+
+#define ACE_SIO_GET_QOS (0x40000000 | 0x08000000 | 7)
+#define ACE_SIO_MULTIPOINT_LOOPBACK (0x08000000 | 9)
+#define ACE_SIO_MULTICAST_SCOPE (0x08000000 | 10)
+#define ACE_SIO_SET_QOS (0x08000000 | 11)
+
+#endif /* ACE_HAS_WINSOCK2 && ACE_HAS_WINSOCK2 != 0 */
+
+
+
+
+/**
+ * @class ACE_Flow_Spec
+ *
+ * @brief Wrapper class that defines the flow spec QoS information,
+ * which is used by IntServ (RSVP) and DiffServ.
+ */
+class ACE_OS_Export ACE_Flow_Spec
+#if defined (ACE_HAS_WINSOCK2) && (ACE_HAS_WINSOCK2 != 0)
+ : public FLOWSPEC
+#endif /* ACE_HAS_WINSOCK2 */
+{
+public:
+ /// Default constructor.
+ ACE_Flow_Spec (void);
+
+ /// Constructor that initializes all the fields.
+ ACE_Flow_Spec (u_long token_rate,
+ u_long token_bucket_size,
+ u_long peak_bandwidth,
+ u_long latency,
+ u_long delay_variation,
+ ACE_SERVICE_TYPE service_type,
+ u_long max_sdu_size,
+ u_long minimum_policed_size,
+ int ttl,
+ int priority);
+
+ /// Get the token rate in bytes/sec.
+ u_long token_rate (void) const;
+
+ /// Set the token rate in bytes/sec.
+ void token_rate (u_long tr);
+
+ /// Get the token bucket size in bytes.
+ u_long token_bucket_size (void) const;
+
+ /// Set the token bucket size in bytes.
+ void token_bucket_size (u_long tbs);
+
+ /// Get the PeakBandwidth in bytes/sec.
+ u_long peak_bandwidth (void) const;
+
+ /// Set the PeakBandwidth in bytes/sec.
+ void peak_bandwidth (u_long pb);
+
+ /// Get the latency in microseconds.
+ u_long latency (void) const;
+
+ /// Set the latency in microseconds.
+ void latency (u_long l);
+
+ /// Get the delay variation in microseconds.
+ u_long delay_variation (void) const;
+
+ /// Set the delay variation in microseconds.
+ void delay_variation (u_long dv);
+
+ /// Get the service type.
+ ACE_SERVICE_TYPE service_type (void) const;
+
+ /// Set the service type.
+ void service_type (ACE_SERVICE_TYPE st);
+
+ /// Get the maximum SDU size in bytes.
+ u_long max_sdu_size (void) const;
+
+ /// Set the maximum SDU size in bytes.
+ void max_sdu_size (u_long mss);
+
+ /// Get the minimum policed size in bytes.
+ u_long minimum_policed_size (void) const;
+
+ /// Set the minimum policed size in bytes.
+ void minimum_policed_size (u_long mps);
+
+ /// Get the time-to-live.
+ int ttl (void) const;
+
+ /// Set the time-to-live.
+ void ttl (int t);
+
+ /// Get the priority.
+ int priority (void) const;
+
+ /// Set the priority.
+ void priority (int p);
+
+#if defined (ACE_HAS_WINSOCK2) && (ACE_HAS_WINSOCK2 != 0) && \
+ defined (ACE_HAS_WINSOCK2_GQOS)
+#else
+private:
+ u_long token_rate_;
+ u_long token_bucket_size_;
+ u_long peak_bandwidth_;
+ u_long latency_;
+ u_long delay_variation_;
+ ACE_SERVICE_TYPE service_type_;
+ u_long max_sdu_size_;
+ u_long minimum_policed_size_;
+ int ttl_;
+ int priority_;
+#endif /* defined (ACE_HAS_WINSOCK2) && (ACE_HAS_WINSOCK2 != 0) && \
+ defined (ACE_HAS_WINSOCK2_GQOS) */
+};
+
+/**
+ * @class ACE_QoS
+ *
+ * @brief Wrapper class that holds the sender and receiver flow spec
+ * information, which is used by IntServ (RSVP) and DiffServ.
+ */
+class ACE_OS_Export ACE_QoS
+#if defined (ACE_HAS_WINSOCK2) && (ACE_HAS_WINSOCK2 != 0)
+ : public QOS
+#endif /* ACE_HAS_WINSOCK2 */
+{
+public:
+ /// Constructor
+ ACE_QoS (void);
+
+ /// Get the flow spec for data sending.
+ ACE_Flow_Spec *sending_flowspec (void) const;
+
+ /// Set the flow spec for data sending.
+ void sending_flowspec (ACE_Flow_Spec *fs);
+
+ /// Get the flow spec for data receiving.
+ ACE_Flow_Spec *receiving_flowspec (void) const;
+
+ /// Set the flow spec for data receiving.
+ void receiving_flowspec (ACE_Flow_Spec *fs);
+
+ /// Get the provider specific information.
+ iovec provider_specific (void) const;
+
+ /// Set the provider specific information.
+ void provider_specific (const iovec &ps);
+
+#if defined (ACE_HAS_WINSOCK2) && (ACE_HAS_WINSOCK2 != 0)
+#else
+private:
+
+ ACE_Flow_Spec *sending_flowspec_;
+ ACE_Flow_Spec *receiving_flowspec_;
+#endif
+
+};
+
+/**
+ * @class ACE_QoS_Params
+ *
+ * @brief Wrapper class that simplifies the information passed to the QoS
+ * enabled <ACE_OS::connect> and <ACE_OS::join_leaf> methods.
+ */
+class ACE_OS_Export ACE_QoS_Params
+{
+public:
+ /**
+ * Initialize the data members. The <caller_data> is a pointer to
+ * the user data that is to be transferred to the peer during
+ * connection establishment. The <callee_data> is a pointer to the
+ * user data that is to be transferred back from the peer during
+ * connection establishment. The_<socket_qos> is a pointer to the
+ * flow specifications for the socket, one for each direction. The
+ * <group_socket_qos> is a pointer to the flow speicfications for
+ * the socket group, if applicable. The_<flags> indicate if we're a
+ * sender, receiver, or both.
+ */
+ ACE_QoS_Params (iovec *caller_data = 0,
+ iovec *callee_data = 0,
+ ACE_QoS *socket_qos = 0,
+ ACE_QoS *group_socket_qos = 0,
+ u_long flags = 0);
+
+ /// Get caller data.
+ iovec *caller_data (void) const;
+
+ /// Set caller data.
+ void caller_data (iovec *);
+
+ /// Get callee data.
+ iovec *callee_data (void) const;
+
+ /// Set callee data.
+ void callee_data (iovec *);
+
+ /// Get socket qos.
+ ACE_QoS *socket_qos (void) const;
+
+ /// Set socket qos.
+ void socket_qos (ACE_QoS *);
+
+ /// Get group socket qos.
+ ACE_QoS *group_socket_qos (void) const;
+
+ /// Set group socket qos.
+ void group_socket_qos (ACE_QoS *);
+
+ /// Get flags.
+ u_long flags (void) const;
+
+ /// Set flags.
+ void flags (u_long);
+
+private:
+ /// A pointer to the user data that is to be transferred to the peer
+ /// during connection establishment.
+ iovec *caller_data_;
+
+ /// A pointer to the user data that is to be transferred back from
+ /// the peer during connection establishment.
+ iovec *callee_data_;
+
+ /// A pointer to the flow speicfications for the socket, one for each
+ /// direction.
+ ACE_QoS *socket_qos_;
+
+ /// A pointer to the flow speicfications for the socket group, if
+ /// applicable.
+ ACE_QoS *group_socket_qos_;
+
+ /// Flags that indicate if we're a sender, receiver, or both.
+ u_long flags_;
+};
+
+// Callback function that's used by the QoS-enabled <ACE_OS::accept>
+// method.
+typedef int (*ACE_QOS_CONDITION_FUNC) (iovec *caller_id,
+ iovec *caller_data,
+ ACE_QoS *socket_qos,
+ ACE_QoS *group_socket_qos,
+ iovec *callee_id,
+ iovec *callee_data,
+ ACE_SOCK_GROUP *g,
+ u_long callbackdata);
+
+
+/**
+ * @class ACE_Accept_QoS_Params
+ *
+ * @brief Wrapper class that simplifies the information passed to the QoS
+ * enabled <ACE_OS::accept> method.
+ */
+class ACE_OS_Export ACE_Accept_QoS_Params
+{
+public:
+ /**
+ * Initialize the data members. The <qos_condition_callback> is the
+ * address of an optional, application-supplied condition function
+ * that will make an accept/reject decision based on the caller
+ * information pass in as parameters, and optionally create or join
+ * a socket group by assinging an appropriate value to the result
+ * parameter <g> of this function. The <callback_data> data is
+ * passed back to the application as a condition function parameter,
+ * i.e., it is an Asynchronous Completion Token (ACT).
+ */
+ ACE_Accept_QoS_Params (ACE_QOS_CONDITION_FUNC qos_condition_callback = 0,
+ u_long callback_data = 0);
+
+ /// Get QoS condition callback.
+ ACE_QOS_CONDITION_FUNC qos_condition_callback (void) const;
+
+ /// Set QoS condition callback.
+ void qos_condition_callback (ACE_QOS_CONDITION_FUNC qcc);
+
+ /// Get callback data.
+ u_long callback_data (void) const;
+
+ /// Set callback data.
+ void callback_data (u_long cd);
+
+private:
+ /**
+ * This is the address of an optional, application-supplied
+ * condition function that will make an accept/reject decision based
+ * on the caller information pass in as parameters, and optionally
+ * create or join a socket group by assinging an appropriate value
+ * to the result parameter <g> of this function.
+ */
+ ACE_QOS_CONDITION_FUNC qos_condition_callback_;
+
+ /**
+ * This data is passed back to the application as a condition
+ * function parameter, i.e., it is an Asynchronous Completion Token
+ * (ACT).
+ */
+ u_long callback_data_;
+};
+
+
+#include "ace/post.h"
+#endif /* ACE_OS_QOS_H */
diff --git a/ace/OS/OS_String.cpp b/ace/OS/OS_String.cpp
new file mode 100644
index 00000000000..2d1350f5372
--- /dev/null
+++ b/ace/OS/OS_String.cpp
@@ -0,0 +1,1023 @@
+//=============================================================================
+/**
+ * @file OS_String.cpp
+ *
+ * $Id$
+ *
+ * @brief Contains definitions for class ACE_OS_String.
+ */
+//=============================================================================
+
+#include "OS_String.h"
+#include "OS_Memory.h"
+
+ACE_RCSID (ace, OS_String, "$Id$")
+
+#if !defined (ACE_HAS_INLINED_OSCALLS)
+# include "OS_String.inl"
+#endif /* ACE_HAS_INLINED_OS_CALLS */
+
+#if defined (ACE_LACKS_WCSDUP_PROTOTYPE)
+extern "C" wchar_t *wcsdup __P ((__const wchar_t *__s));
+#endif /* ACE_LACKS_WCSDUP_PROTOTYPE */
+
+
+const char *
+ACE_OS_String::strnstr (const char *s1, const char *s2, size_t len2)
+{
+ // Substring length
+ size_t len1 = ACE_OS_String::strlen (s1);
+
+ // Check if the substring is longer than the string being searched.
+ if (len2 > len1)
+ return 0;
+
+ // Go upto <len>
+ size_t len = len1 - len2;
+
+ for (size_t i = 0; i <= len; i++)
+ {
+ if (ACE_OS_String::memcmp (s1 + i, s2, len2) == 0)
+ // Found a match! Return the index.
+ return s1 + i;
+ }
+
+ return 0;
+}
+
+const ACE_WCHAR_T *
+ACE_OS_String::strnstr (const ACE_WCHAR_T *s1, const ACE_WCHAR_T *s2, size_t len2)
+{
+ // Substring length
+ size_t len1 = ACE_OS_String::strlen (s1);
+
+ // Check if the substring is longer than the string being searched.
+ if (len2 > len1)
+ return 0;
+
+ // Go upto <len>
+ size_t len = len1 - len2;
+
+ for (size_t i = 0; i <= len; i++)
+ {
+ if (ACE_OS_String::memcmp (s1 + i, s2, len2 * sizeof (ACE_WCHAR_T)) == 0)
+ // Found a match! Return the index.
+ return s1 + i;
+ }
+
+ return 0;
+}
+
+char *
+ACE_OS_String::strdup (const char *s)
+{
+#if defined (ACE_HAS_STRDUP_EMULATION)
+ char *t = (char *) ACE_OS_Memory::malloc (ACE_OS_String::strlen (s) + 1);
+ if (t == 0)
+ return 0;
+
+ return ACE_OS_String::strcpy (t, s);
+#else
+ return ::strdup (s);
+#endif /* ACE_HAS_STRDUP_EMULATION */
+}
+
+#if defined (ACE_HAS_WCHAR)
+wchar_t *
+ACE_OS_String::strdup (const wchar_t *s)
+{
+# if defined (ACE_LACKS_WCSDUP)
+ wchar_t *buffer =
+ (wchar_t *) ACE_OS_Memory::malloc ((ACE_OS_String::strlen (s) + 1)
+ * sizeof (wchar_t));
+ if (buffer == 0)
+ return 0;
+
+ return ACE_OS_String::strcpy (buffer, s);
+# elif defined (ACE_WCSDUP_EQUIVALENT)
+ return ACE_WCSDUP_EQUIVALENT (s);
+# else /* ACE_LACKS_WCSDUP */
+# if defined (__MINGW32__)
+ return ::wcsdup (ACE_const_cast(wchar_t*, s));
+# else /* __MINGW32__ */
+ return ::wcsdup (s);
+# endif /* __MINGW32__ */
+# endif /* ACE_LACKS_WCSDUP */
+}
+#endif /* ACE_HAS_WCHAR */
+
+#if defined (ACE_LACKS_STRERROR)
+/**
+ * Just returns "Unknown Error" all the time.
+ */
+char *
+ACE_OS_String::strerror_emulation (int errnum)
+{
+ return "Unknown Error";
+}
+#endif /* ACE_LACKS_STRERROR */
+
+#if defined (ACE_LACKS_STRCHR)
+char *
+ACE_OS_String::strchr_emulation (char *s, int c)
+{
+ for (;;++s)
+ {
+ if (*s == c)
+ return s;
+ if (*s == 0)
+ return 0;
+ }
+}
+
+const char *
+ACE_OS_String::strchr_emulation (const char *s, int c)
+{
+ for (;;++s)
+ {
+ if (*s == c)
+ return s;
+ if (*s == 0)
+ return 0;
+ }
+}
+#endif /* ACE_LACKS_STRCHR */
+
+const char *
+ACE_OS_String::strnchr (const char *s, int c, size_t len)
+{
+ for (size_t i = 0; i < len; i++)
+ if (s[i] == c)
+ return s + i;
+
+ return 0;
+}
+
+const ACE_WCHAR_T *
+ACE_OS_String::strnchr (const ACE_WCHAR_T *s, ACE_WINT_T c, size_t len)
+{
+ for (size_t i = 0; i < len; i++)
+ if (s[i] == ACE_static_cast(ACE_WCHAR_T, c))
+ return s + i;
+
+ return 0;
+}
+
+#if defined (ACE_LACKS_STRRCHR)
+char *
+ACE_OS_String::strrchr_emulation (char *s, int c)
+{
+ char *p = s + ACE_OS_String::strlen (s);
+
+ while (*p != c)
+ if (p == s)
+ return 0;
+ else
+ p--;
+
+ return p;
+}
+
+const char *
+ACE_OS_String::strrchr_emulation (const char *s, int c)
+{
+ const char *p = s + ACE_OS_String::strlen (s);
+
+ while (*p != c)
+ if (p == s)
+ return 0;
+ else
+ p--;
+
+ return p;
+}
+#endif /* ACE_LACKS_STRRCHR */
+
+#if defined (ACE_HAS_WCHAR) && defined (ACE_LACKS_WCSRCHR)
+const wchar_t *
+ACE_OS_String::wcsrchr_emulation (const wchar_t *s, wint_t c)
+{
+ const wchar_t *p = s + ACE_OS_String::strlen (s);
+
+ while (*p != ACE_static_cast (wchar_t, c))
+ if (p == s)
+ return 0;
+ else
+ p--;
+
+ return p;
+}
+
+wchar_t *
+ACE_OS_String::wcsrchr_emulation (wchar_t *s, wint_t c)
+{
+ wchar_t *p = s + ACE_OS_String::strlen (s);
+
+ while (*p != ACE_static_cast(wchar_t, c))
+ if (p == s)
+ return 0;
+ else
+ p--;
+
+ return p;
+}
+#endif /* ACE_HAS_WCHAR && ACE_LACKS_WCSRCHR */
+
+char *
+ACE_OS_String::strecpy (char *s, const char *t)
+{
+ register char *dscan = s;
+ register const char *sscan = t;
+
+ while ((*dscan++ = *sscan++) != '\0')
+ continue;
+
+ return dscan;
+}
+
+#if defined (ACE_HAS_WCHAR)
+wchar_t *
+ACE_OS_String::strecpy (wchar_t *s, const wchar_t *t)
+{
+ register wchar_t *dscan = s;
+ register const wchar_t *sscan = t;
+
+ while ((*dscan++ = *sscan++) != ACE_TEXT_WIDE ('\0'))
+ continue;
+
+ return dscan;
+}
+#endif /* ACE_HAS_WCHAR */
+
+#if defined (ACE_LACKS_STRCSPN)
+size_t
+ACE_OS_String::strcspn_emulation (const char *s, const char *reject)
+{
+ const char *scan;
+ const char *rej_scan;
+ int count = 0;
+
+ for (scan = s; *scan; scan++)
+ {
+
+ for (rej_scan = reject; *rej_scan; rej_scan++)
+ if (*scan == *rej_scan)
+ return count;
+
+ count++;
+ }
+
+ return count;
+}
+#endif /* ACE_LACKS_STRCSPN */
+
+#if defined (ACE_LACKS_STRCASECMP)
+int
+ACE_OS_String::strcasecmp_emulation (const char *s, const char *t)
+{
+ const char *scan1 = s;
+ const char *scan2 = t;
+
+ while (*scan1 != 0
+ && ACE_OS_String::to_lower (*scan1)
+ == ACE_OS_String::to_lower (*scan2))
+ {
+ ++scan1;
+ ++scan2;
+ }
+
+ // The following case analysis is necessary so that characters which
+ // look negative collate low against normal characters but high
+ // against the end-of-string NUL.
+
+ if (*scan1 == '\0' && *scan2 == '\0')
+ return 0;
+ else if (*scan1 == '\0')
+ return -1;
+ else if (*scan2 == '\0')
+ return 1;
+ else
+ return ACE_OS_String::to_lower (*scan1) - ACE_OS_String::to_lower (*scan2);
+}
+#endif /* ACE_LACKS_STRCASECMP */
+
+#if defined (ACE_HAS_WCHAR) && defined (ACE_LACKS_WCSICMP)
+int
+ACE_OS_String::wcsicmp_emulation (const wchar_t *s, const wchar_t *t)
+{
+ const wchar_t *scan1 = s;
+ const wchar_t *scan2 = t;
+
+ while (*scan1 != 0
+ && ACE_OS_String::to_lower (*scan1)
+ == ACE_OS_String::to_lower (*scan2))
+ {
+ ++scan1;
+ ++scan2;
+ }
+
+ // The following case analysis is necessary so that characters which
+ // look negative collate low against normal characters but high
+ // against the end-of-string NUL.
+
+ if (*scan1 == '\0' && *scan2 == '\0')
+ return 0;
+ else if (*scan1 == '\0')
+ return -1;
+ else if (*scan2 == '\0')
+ return 1;
+ else
+ return ACE_OS_String::to_lower (*scan1) - ACE_OS_String::to_lower (*scan2);
+}
+#endif /* ACE_HAS_WCHAR && ACE_LACKS_WCSICMP */
+
+#if defined (ACE_LACKS_STRCASECMP)
+int
+ACE_OS_String::strncasecmp_emulation (const char *s,
+ const char *t,
+ size_t len)
+{
+ const char *scan1 = s;
+ const char *scan2 = t;
+ size_t count = 0;
+
+ while (count++ < len
+ && *scan1 != 0
+ && ACE_OS_String::to_lower (*scan1)
+ == ACE_OS_String::to_lower (*scan2))
+ {
+ ++scan1;
+ ++scan2;
+ }
+
+ if (count > len)
+ return 0;
+
+ // The following case analysis is necessary so that characters which
+ // look negative collate low against normal characters but high
+ // against the end-of-string NUL.
+
+ if (*scan1 == '\0' && *scan2 == '\0')
+ return 0;
+ else if (*scan1 == '\0')
+ return -1;
+ else if (*scan2 == '\0')
+ return 1;
+ else
+ return ACE_OS_String::to_lower (*scan1) - ACE_OS_String::to_lower (*scan2);
+}
+#endif /* ACE_LACKS_STRCASECMP */
+
+#if defined (ACE_HAS_WCHAR) && defined (ACE_LACKS_WCSNICMP)
+int
+ACE_OS_String::wcsnicmp_emulation (const wchar_t *s,
+ const wchar_t *t,
+ size_t len)
+{
+ const wchar_t *scan1 = s;
+ const wchar_t *scan2 = t;
+ size_t count = 0;
+
+ while (count++ < len
+ && *scan1 != 0
+ && ACE_OS_String::to_lower (*scan1)
+ == ACE_OS_String::to_lower (*scan2))
+ {
+ ++scan1;
+ ++scan2;
+ }
+
+ if (count > len)
+ return 0;
+
+ // The following case analysis is necessary so that characters which
+ // look negative collate low against normal characters but high
+ // against the end-of-string NUL.
+
+ if (*scan1 == '\0' && *scan2 == '\0')
+ return 0;
+ else if (*scan1 == '\0')
+ return -1;
+ else if (*scan2 == '\0')
+ return 1;
+ else
+ return ACE_OS_String::to_lower (*scan1) - ACE_OS_String::to_lower (*scan2);
+}
+#endif /* ACE_HAS_WCHAR && ACE_LACKS_WCSNICMP */
+
+#if !defined (ACE_HAS_REENTRANT_FUNCTIONS)
+char *
+ACE_OS_String::strtok_r_emulation (char *s, const char *tokens, char **lasts)
+{
+ if (s == 0)
+ s = *lasts;
+ else
+ *lasts = s;
+ if (*s == 0) // We have reached the end
+ return 0;
+ int l_org = ACE_OS_String::strlen (s);
+ s = ::strtok (s, tokens);
+ if (s == 0)
+ return 0;
+ int l_sub = ACE_OS_String::strlen (s);
+ *lasts = s + l_sub;
+ if (l_sub != l_org)
+ *lasts += 1;
+ return s ;
+}
+#endif /* !ACE_HAS_REENTRANT_FUNCTIONS */
+
+#if !defined (ACE_HAS_MEMCHR)
+const void *
+ACE_OS_String::memchr_emulation (const void *s, int c, size_t len)
+{
+ const unsigned char *t = (const unsigned char *) s;
+ const unsigned char *e = (const unsigned char *) s + len;
+
+ while (t < e)
+ if (((int) *t) == c)
+ return t;
+ else
+ t++;
+
+ return 0;
+}
+#endif /*ACE_HAS_MEMCHR*/
+
+#if !defined (ACE_HAS_ITOA)
+char *
+ACE_OS_String::itoa_emulation (int value, char *string, int radix)
+{
+ char *e = string;
+ char *b = string;
+
+ // Short circuit if 0
+
+ if (value == 0)
+ {
+ string[0] = '0';
+ string[1] = 0;
+ return string;
+ }
+
+ // If negative and base 10, print a - and then do the
+ // number.
+
+ if (value < 0 && radix == 10)
+ {
+ string[0] = '-';
+ b++;
+ }
+
+ // Convert to base <radix>, but in reverse order
+
+ while (value != 0)
+ {
+ int mod = value % radix;
+ value = value / radix;
+
+ *e++ = (mod < 10) ? '0' + mod : 'a' + mod - 10;
+ }
+
+ *e-- = 0;
+
+ // Now reverse the string to get the correct result
+
+ while (e > b)
+ {
+ char temp = *e;
+ *e = *b;
+ *b = temp;
+ ++b;
+ --e;
+ }
+
+ return string;
+}
+#endif /* !ACE_HAS_ITOA */
+
+#if defined (ACE_HAS_WCHAR) && defined (ACE_LACKS_ITOW)
+wchar_t *
+ACE_OS_String::itow_emulation (int value, wchar_t *string, int radix)
+{
+ wchar_t *e = string;
+ wchar_t *b = string;
+
+ // Short circuit if 0
+
+ if (value == 0)
+ {
+ string[0] = '0';
+ string[1] = 0;
+ return string;
+ }
+
+ // If negative and base 10, print a - and then do the
+ // number.
+
+ if (value < 0 && radix == 10)
+ {
+ string[0] = '-';
+ b++;
+ }
+
+ // Convert to base <radix>, but in reverse order
+
+ while (value != 0)
+ {
+ int mod = value % radix;
+ value = value / radix;
+
+ *e++ = (mod < 10) ? '0' + mod : 'a' + mod - 10;
+ }
+
+ *e-- = 0;
+
+ // Now reverse the string to get the correct result
+
+ while (e > b)
+ {
+ wchar_t temp = *e;
+ *e = *b;
+ *b = temp;
+ ++b;
+ --e;
+ }
+
+ return string;
+}
+#endif /* ACE_HAS_WCHAR && ACE_LACKS_ITOW */
+
+#if defined (ACE_HAS_WCHAR) && defined (ACE_LACKS_WCSCSPN)
+size_t
+ACE_OS_String::wcscspn_emulation (const wchar_t *s, const wchar_t *reject)
+{
+ const wchar_t *scan;
+ const wchar_t *rej_scan;
+ int count = 0;
+
+ for (scan = s; *scan; scan++)
+ {
+
+ for (rej_scan = reject; *rej_scan; rej_scan++)
+ if (*scan == *rej_scan)
+ return count;
+
+ count++;
+ }
+
+ return count;
+}
+#endif /* ACE_HAS_WCHAR && ACE_LACKS_WCSCSPN */
+
+// The following wcs*_emulation methods were created based on BSD code:
+/*-
+ * Copyright (c) 1991, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * James W. Williams of NASA Goddard Space Flight Center.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+
+
+
+#if defined (ACE_HAS_WCHAR) && defined (ACE_LACKS_WCSCAT)
+wchar_t *
+ACE_OS_String::wcscat_emulation (wchar_t *destination,
+ const wchar_t *source)
+{
+ wchar_t *save = destination;
+
+ for (; *destination; ++destination);
+ while ((*destination++ = *source++));
+ return save;
+}
+#endif /* ACE_HAS_WCHAR && ACE_LACKS_WCSCAT */
+
+#if defined (ACE_LACKS_STRSPN)
+size_t
+ACE_OS_String::strspn_emulation (const char *string,
+ const char *charset)
+{
+ const char *p = string;
+ const char *spanp;
+ wchar_t c, sc;
+
+ // Skip any characters in charset, excluding the terminating \0.
+cont:
+ c = *p++;
+ for (spanp = charset; (sc = *spanp++) != 0;)
+ if (sc == c)
+ goto cont;
+ return (p - 1 - string);
+}
+#endif /* ACE_LACKS_STRSPN */
+
+#if defined (ACE_HAS_WCHAR) && defined (ACE_LACKS_WCSSPN)
+size_t
+ACE_OS_String::wcsspn_emulation (const wchar_t *string,
+ const wchar_t *charset)
+{
+ const wchar_t *p = string;
+ const wchar_t *spanp;
+ wchar_t c, sc;
+
+ // Skip any characters in charset, excluding the terminating \0.
+cont:
+ c = *p++;
+ for (spanp = charset; (sc = *spanp++) != 0;)
+ if (sc == c)
+ goto cont;
+ return (p - 1 - string);
+}
+#endif /* ACE_HAS_WCHAR && ACE_LACKS_WCSSPN */
+
+#if defined (ACE_HAS_WCHAR) && defined (ACE_LACKS_WCSSTR)
+wchar_t *
+ACE_OS_String::wcsstr_emulation (const wchar_t *string,
+ const wchar_t *charset)
+{
+ wchar_t c, sc;
+ size_t len;
+
+ if ((c = *charset++) != 0)
+ {
+ len = strlen(charset);
+ do
+ {
+ do
+ {
+ if ((sc = *string++) == 0)
+ return NULL;
+ } while (sc != c);
+ } while (strncmp(string, charset, len) != 0);
+ string--;
+ }
+
+ return ACE_const_cast (wchar_t *, string);
+}
+#endif /* ACE_HAS_WCHAR && ACE_LACKS_WCSSTR */
+
+#if !defined (ACE_HAS_WCHAR) || defined (ACE_LACKS_WCSLEN)
+size_t
+ACE_OS_String::wcslen_emulation (const ACE_WCHAR_T *string)
+{
+ const ACE_WCHAR_T *s;
+
+ for (s = string; *s; ++s);
+ return s - string;
+}
+#endif /* !ACE_HAS_WCHAR || ACE_LACKS_WCSLEN */
+
+#if !defined (ACE_HAS_WCHAR) || defined (ACE_LACKS_WCSNCPY)
+ACE_WCHAR_T *
+ACE_OS_String::wcsncpy_emulation (ACE_WCHAR_T *destination,
+ const ACE_WCHAR_T *source,
+ size_t len)
+{
+ if (len != 0)
+ {
+ ACE_WCHAR_T *d = destination;
+ const ACE_WCHAR_T *s = source;
+
+ do
+ {
+ if ((*d++ = *s++) == 0)
+ {
+ // NUL pad the remaining n-1 bytes
+ while (--len != 0)
+ *d++ = 0;
+ break;
+ }
+ } while (--len != 0);
+ }
+
+ return destination;
+}
+#endif /* !ACE_HAS_WCHAR || ACE_LACKS_WCSNCPY */
+
+#if !defined (ACE_HAS_WCHAR) || defined (ACE_LACKS_WCSCMP)
+int
+ACE_OS_String::wcscmp_emulation (const ACE_WCHAR_T *string1,
+ const ACE_WCHAR_T *string2)
+{
+ while (*string1 == *string2++)
+ if (*string1++ == 0)
+ return (0);
+ return (*string1 - *--string2);
+}
+#endif /* !ACE_HAS_WCHAR || ACE_LACKS_WCSCMP */
+
+#if defined (ACE_HAS_WCHAR) && defined (ACE_LACKS_WCSCPY)
+wchar_t *
+ACE_OS_String::wcscpy_emulation (wchar_t *destination,
+ const wchar_t *source)
+{
+ wchar_t *save = destination;
+
+ for (; (*destination = *source); ++source, ++destination);
+ return save;
+}
+#endif /* ACE_HAS_WCHAR && ACE_LACKS_WCSCPY */
+
+#if defined (ACE_LACKS_STRPBRK)
+char *
+ACE_OS_String::strpbrk_emulation (const char *string,
+ const char *charset)
+{
+ const char *scanp;
+ int c, sc;
+
+ while ((c = *string++) != 0)
+ {
+ for (scanp = charset; (sc = *scanp++) != 0;)
+ if (sc == c)
+ return ACE_const_cast (char *, string - 1);
+ }
+
+ return NULL;
+}
+#endif /* ACE_LACKS_STRPBRK */
+
+#if defined (ACE_HAS_WCHAR) && defined (ACE_LACKS_WCSPBRK)
+wchar_t *
+ACE_OS_String::wcspbrk_emulation (const wchar_t *string,
+ const wchar_t *charset)
+{
+ const wchar_t *scanp;
+ int c, sc;
+
+ while ((c = *string++) != 0)
+ {
+ for (scanp = charset; (sc = *scanp++) != 0;)
+ if (sc == c)
+ return ACE_const_cast (wchar_t *, string - 1);
+ }
+
+ return NULL;
+}
+#endif /* ACE_HAS_WCHAR && ACE_LACKS_WCSPBRK */
+
+#if !defined (ACE_HAS_WCHAR) || defined (ACE_LACKS_WCSNCAT)
+ACE_WCHAR_T *
+ACE_OS_String::wcsncat_emulation (ACE_WCHAR_T *destination,
+ const ACE_WCHAR_T *source,
+ size_t count)
+{
+ if (count != 0)
+ {
+ ACE_WCHAR_T *d = destination;
+ const ACE_WCHAR_T *s = source;
+
+ while (*d != 0)
+ d++;
+
+ do
+ {
+ if ((*d = *s++) == 0)
+ break;
+
+ d++;
+ } while (--count != 0);
+
+ *d = 0;
+ }
+
+ return destination;
+}
+#endif /* !ACE_HAS_WCHAR || ACE_LACKS_WCSCAT */
+
+#if defined (ACE_HAS_WCHAR) && defined (ACE_LACKS_WCSCHR)
+wchar_t *
+ACE_OS_String::wcschr_emulation (const wchar_t *string, wint_t c)
+{
+ for (;*string ; ++string)
+ if (*string == ACE_static_cast (wchar_t, c))
+ return ACE_const_cast (wchar_t *, string);
+
+ return NULL;
+}
+#endif /* ACE_HAS_WCHAR && ACE_LACKS_WCSCHR */
+
+#if !defined (ACE_HAS_WCHAR) || defined (ACE_LACKS_WCSNCMP)
+int
+ACE_OS_String::wcsncmp_emulation (const ACE_WCHAR_T *s1,
+ const ACE_WCHAR_T *s2,
+ size_t len)
+{
+ if (len == 0)
+ return 0;
+
+ do
+ {
+ if (*s1 != *s2++)
+ return (*s1 - *--s2);
+ if (*s1++ == 0)
+ break;
+ } while (--len != 0);
+
+ return 0;
+}
+#endif /* !ACE_HAS_WCHAR || ACE_LACKS_WCSNCMP */
+
+#if defined (ACE_LACKS_STRTOL)
+long
+ACE_OS_String::strtol_emulation (const char *nptr, char **endptr, int base)
+{
+ register const char *s = nptr;
+ register unsigned long acc;
+ register int c;
+ register unsigned long cutoff;
+ register int neg = 0, any, cutlim;
+
+ /*
+ * Skip white space and pick up leading +/- sign if any.
+ * If base is 0, allow 0x for hex and 0 for octal, else
+ * assume decimal; if base is already 16, allow 0x.
+ */
+ do {
+ c = *s++;
+ } while (isspace(c));
+ if (c == '-') {
+ neg = 1;
+ c = *s++;
+ } else if (c == '+')
+ c = *s++;
+ if ((base == 0 || base == 16) &&
+ c == '0' && (*s == 'x' || *s == 'X')) {
+ c = s[1];
+ s += 2;
+ base = 16;
+ }
+ if (base == 0)
+ base = c == '0' ? 8 : 10;
+
+ /*
+ * Compute the cutoff value between legal numbers and illegal
+ * numbers. That is the largest legal value, divided by the
+ * base. An input number that is greater than this value, if
+ * followed by a legal input character, is too big. One that
+ * is equal to this value may be valid or not; the limit
+ * between valid and invalid numbers is then based on the last
+ * digit. For instance, if the range for longs is
+ * [-2147483648..2147483647] and the input base is 10,
+ * cutoff will be set to 214748364 and cutlim to either
+ * 7 (neg==0) or 8 (neg==1), meaning that if we have accumulated
+ * a value > 214748364, or equal but the next digit is > 7 (or 8),
+ * the number is too big, and we will return a range error.
+ *
+ * Set any if any `digits' consumed; make it negative to indicate
+ * overflow.
+ */
+ cutoff = neg ? -(unsigned long)LONG_MIN : LONG_MAX;
+ cutlim = cutoff % (unsigned long)base;
+ cutoff /= (unsigned long)base;
+ for (acc = 0, any = 0;; c = *s++) {
+ if (isdigit(c))
+ c -= '0';
+ else if (isalpha(c))
+ c -= isupper(c) ? 'A' - 10 : 'a' - 10;
+ else
+ break;
+ if (c >= base)
+ break;
+ if (any < 0 || acc > cutoff || acc == cutoff && c > cutlim)
+ any = -1;
+ else {
+ any = 1;
+ acc *= base;
+ acc += c;
+ }
+ }
+ if (any < 0) {
+ acc = neg ? LONG_MIN : LONG_MAX;
+ errno = ERANGE;
+ } else if (neg)
+ acc = -acc;
+ if (endptr != 0)
+ *endptr = any ? (char *)s - 1 : (char *)nptr;
+ return (acc);
+}
+#endif /* ACE_LACKS_STRTOL */
+
+#if defined (ACE_LACKS_STRTOUL)
+unsigned long
+ACE_OS_String::strtoul_emulation (const char *nptr,
+ char **endptr,
+ register int base)
+{
+ register const char *s = nptr;
+ register unsigned long acc;
+ register int c;
+ register unsigned long cutoff;
+ register int neg = 0, any, cutlim;
+
+ /*
+ * See strtol for comments as to the logic used.
+ */
+ do {
+ c = *s++;
+ } while (isspace(c));
+ if (c == '-') {
+ neg = 1;
+ c = *s++;
+ } else if (c == '+')
+ c = *s++;
+ if ((base == 0 || base == 16) &&
+ c == '0' && (*s == 'x' || *s == 'X')) {
+ c = s[1];
+ s += 2;
+ base = 16;
+ }
+ if (base == 0)
+ base = c == '0' ? 8 : 10;
+ cutoff = (unsigned long)ULONG_MAX / (unsigned long)base;
+ cutlim = (unsigned long)ULONG_MAX % (unsigned long)base;
+ for (acc = 0, any = 0;; c = *s++) {
+ if (isdigit(c))
+ c -= '0';
+ else if (isalpha(c))
+ c -= isupper(c) ? 'A' - 10 : 'a' - 10;
+ else
+ break;
+ if (c >= base)
+ break;
+ if (any < 0 || acc > cutoff || acc == cutoff && c > cutlim)
+ any = -1;
+ else {
+ any = 1;
+ acc *= base;
+ acc += c;
+ }
+ }
+ if (any < 0) {
+ acc = ULONG_MAX;
+ errno = ERANGE;
+ } else if (neg)
+ acc = -acc;
+ if (endptr != 0)
+ *endptr = any ? (char *)s - 1 : (char *)nptr;
+ return (acc);
+}
+#endif /* ACE_LACKS_STRTOUL */
+
+char *
+ACE_OS_String::strsncpy (char *dst, const char *src, size_t maxlen)
+{
+ register char *rdst = dst;
+ register const char *rsrc = src;
+ register size_t rmaxlen = maxlen;
+
+ if (rmaxlen > 0)
+ {
+ *rdst = '\0';
+ if (rsrc != 0)
+ strncat (rdst, rsrc, --rmaxlen);
+ }
+ return dst;
+}
+
+ACE_WCHAR_T *
+ACE_OS_String::strsncpy (ACE_WCHAR_T *dst, const ACE_WCHAR_T *src, size_t maxlen)
+{
+ register ACE_WCHAR_T *rdst = dst;
+ register const ACE_WCHAR_T *rsrc = src;
+ register size_t rmaxlen = maxlen;
+
+ if (rmaxlen > 0)
+ {
+ *rdst = ACE_TEXT_WIDE ('\0');
+ if (rsrc != 0)
+ strncat (rdst, rsrc ,--rmaxlen);
+ }
+ return dst;
+}
diff --git a/ace/OS/OS_String.h b/ace/OS/OS_String.h
new file mode 100644
index 00000000000..701622c4386
--- /dev/null
+++ b/ace/OS/OS_String.h
@@ -0,0 +1,596 @@
+// -*- C++ -*-
+//=============================================================================
+/**
+ * @file OS_String.h
+ *
+ * $Id$
+ *
+ * @brief Contains definition of class ACE_OS_String.
+ *
+ * @author Doug Schmidt <schmidt@cs.wustl.edu>
+ * @author Jesper S. M|ller <stophph@diku.dk>
+ * @author and a cast of thousands...
+ */
+//=============================================================================
+
+#ifndef ACE_OS_STRING_H
+#define ACE_OS_STRING_H
+#include "ace/pre.h"
+
+#include "ace/config-all.h"
+
+#if !defined (ACE_LACKS_PRAGMA_ONCE)
+# pragma once
+#endif /* ACE_LACKS_PRAGMA_ONCE */
+
+#include "Basic_Types.h"
+#include /**/ <stddef.h>
+
+#if defined (ACE_USES_STD_NAMESPACE_FOR_STDC_LIB) && \
+ (ACE_USES_STD_NAMESPACE_FOR_STDC_LIB != 0)
+using std::size_t;
+using std::wint_t;
+#endif /* ACE_USES_STD_NAMESPACE_FOR_STDC_LIB */
+
+/**
+ * @class ACE_OS_String
+ *
+ * @brief This class includes functions available in string.h and ctype.h.
+ */
+class ACE_OS_Export ACE_OS_String
+{
+public:
+ /** @name Functions from <cstring>
+ *
+ * Included are the functions defined in <cstring> and their <cwchar>
+ * equivalents.
+ *
+ * @todo To be complete, we should add strcoll, and strxfrm.
+ */
+ //@{
+
+ /// Finds characters in a buffer (const void version).
+ static const void *memchr (const void *s, int c, size_t len);
+
+ /// Finds characters in a buffer (void version).
+ static void *memchr (void *s, int c, size_t len);
+
+ /// Compares two buffers.
+ static int memcmp (const void *t, const void *s, size_t len);
+
+ /// Copies one buffer to another.
+ static void *memcpy (void *t, const void *s, size_t len);
+
+ /// Moves one buffer to another.
+ static void *memmove (void *t, const void *s, size_t len);
+
+ /// Fills a buffer with a character value.
+ static void *memset (void *s, int c, size_t len);
+
+ /// Appends a string to another string (char version).
+ static char *strcat (char *s, const char *t);
+
+#if defined (ACE_HAS_WCHAR)
+ /// Appends a string to another string (wchar_t version).
+ static wchar_t *strcat (wchar_t *s, const wchar_t *t);
+#endif /* ACE_HAS_WCHAR */
+
+ /// Finds the first occurance of a character in a string (const char
+ /// version).
+ static const char *strchr (const char *s, int c);
+
+#if defined (ACE_HAS_WCHAR)
+ /// Finds the first occurance of a character in a string (const wchar_t
+ /// version).
+ static const wchar_t *strchr (const wchar_t *s, wint_t c);
+#endif /* ACE_HAS_WCHAR */
+
+ /// Finds the first occurance of a character in a string (char version).
+ static char *strchr (char *s, int c);
+
+#if defined (ACE_HAS_WCHAR)
+ /// Finds the first occurance of a character in a string (wchar_t version).
+ static wchar_t *strchr (wchar_t *s, wint_t c);
+#endif /* ACE_HAS_WCHAR */
+
+ /// Compares two strings (char version).
+ static int strcmp (const char *s, const char *t);
+
+ /// Compares two strings (wchar_t version).
+ static int strcmp (const ACE_WCHAR_T *s, const ACE_WCHAR_T *t);
+
+ /// Copies a string (char version).
+ static char *strcpy (char *s, const char *t);
+
+#if defined (ACE_HAS_WCHAR)
+ /// Copies a string (wchar_t version).
+ static wchar_t *strcpy (wchar_t *s, const wchar_t *t);
+#endif /* ACE_HAS_WCHAR */
+
+ /// Searches for the first substring without any of the specified
+ /// characters and returns the size of the substring (char version).
+ static size_t strcspn (const char *s, const char *reject);
+
+#if defined (ACE_HAS_WCHAR)
+ /// Searches for the first substring without any of the specified
+ /// characters and returns the size of the substring (wchar_t version).
+ static size_t strcspn (const wchar_t *s, const wchar_t *reject);
+#endif /* ACE_HAS_WCHAR */
+
+ /// Returns a system error message.
+ static char *strerror (int errnum);
+
+ /// Finds the length of a string (char version).
+ static size_t strlen (const char *s);
+
+ /// Finds the length of a string (ACE_WCHAR_T version).
+ static size_t strlen (const ACE_WCHAR_T *s);
+
+ /// Appends part of a string to another string (char version).
+ static char *strncat (char *s, const char *t, size_t len);
+
+ /// Appends part of a string to another string (wchar_t version).
+ static ACE_WCHAR_T *strncat (ACE_WCHAR_T *s, const ACE_WCHAR_T *t, size_t len);
+
+ /// Compares two arrays (char version).
+ static int strncmp (const char *s, const char *t, size_t len);
+
+ /// Compares two arrays (wchar_t version).
+ static int strncmp (const ACE_WCHAR_T *s, const ACE_WCHAR_T *t, size_t len);
+
+ /// Copies an array (char version)
+ static char *strncpy (char *s, const char *t, size_t len);
+
+ /// Copies an array (ACE_WCHAR_T version)
+ static ACE_WCHAR_T *strncpy (ACE_WCHAR_T *s, const ACE_WCHAR_T *t, size_t len);
+
+ /// Searches for characters in a string (const char version).
+ static const char *strpbrk (const char *s1, const char *s2);
+
+#if defined (ACE_HAS_WCHAR)
+ /// Searches for characters in a string (const wchar_t version).
+ static const wchar_t *strpbrk (const wchar_t *s1, const wchar_t *s2);
+#endif /* ACE_HAS_WCHAR */
+
+ /// Searches for characters in a string (char version).
+ static char *strpbrk (char *s1, const char *s2);
+
+#if defined (ACE_HAS_WCHAR)
+ /// Searches for characters in a string (wchar_t version).
+ static wchar_t *strpbrk (wchar_t *s1, const wchar_t *s2);
+#endif /* ACE_HAS_WCHAR */
+
+ /// Finds the last occurance of a character in a string (const char
+ /// version).
+ static const char *strrchr (const char *s, int c);
+
+#if defined (ACE_HAS_WCHAR)
+ /// Finds the last occurance of a character in a string (const wchar_t
+ /// version).
+ static const wchar_t *strrchr (const wchar_t *s, wint_t c);
+#endif /* ACE_HAS_WCHAR */
+
+ /// Finds the last occurance of a character in a string (char version).
+ static char *strrchr (char *s, int c);
+
+#if defined (ACE_HAS_WCHAR)
+ /// Finds the last occurance of a character in a string (wchar_t version).
+ static wchar_t *strrchr (wchar_t *s, wint_t c);
+#endif /* ACE_HAS_WCHAR */
+
+ /// Searches for the first substring containing only the specified
+ /// characters and returns the size of the substring (char version).
+ static size_t strspn (const char *s1, const char *s2);
+
+#if defined (ACE_HAS_WCHAR)
+ /// Searches for the first substring containing only the specified
+ /// characters and returns the size of the substring (wchar_t version).
+ static size_t strspn (const wchar_t *s1, const wchar_t *s2);
+#endif /* ACE_HAS_WCHAR */
+
+ /// Finds the first occurance of a substring in a string (const char
+ /// version).
+ static const char *strstr (const char *s, const char *t);
+
+#if defined (ACE_HAS_WCHAR)
+ /// Finds the first occurance of a substring in a string (const wchar_t
+ /// version).
+ static const wchar_t *strstr (const wchar_t *s, const wchar_t *t);
+#endif /* ACE_HAS_WCHAR */
+
+ /// Finds the first occurance of a substring in a string (char version).
+ static char *strstr (char *s, const char *t);
+
+#if defined (ACE_HAS_WCHAR)
+ /// Finds the first occurance of a substring in a string (wchar_t version).
+ static wchar_t *strstr (wchar_t *s, const wchar_t *t);
+#endif /* ACE_HAS_WCHAR */
+
+ /// Finds the next token in a string (char version).
+ static char *strtok (char *s, const char *tokens);
+
+#if defined (ACE_HAS_WCHAR) && !defined (ACE_LACKS_WCSTOK)
+ /// Finds the next token in a string (wchar_t version).
+ static wchar_t *strtok (wchar_t *s, const wchar_t *tokens);
+#endif /* ACE_HAS_WCHAR && !ACE_LACKS_WCSTOK */
+
+ //@}
+
+ /** @name Functions from <cctype>
+ *
+ * Included are the functions defined in <cctype> and their <cwctype>
+ * equivalents.
+ *
+ * Since they are often implemented as macros, we don't use the same name
+ * here. Instead, we change by prepending "ace_" (with the exception of
+ * to_lower).
+ *
+ * @todo To be complete, we should add: isalnum, isalpha, iscntrl
+ * isdigit, isgraph, islower, ispunct, isupper, isxdigit, and toupper.
+ */
+ //@{
+
+ /// Returns true if the character is a printable character.
+ static int ace_isprint (const ACE_TCHAR c);
+
+ /// Returns true if the character is a space character.
+ static int ace_isspace (const ACE_TCHAR c);
+
+ /// Converts a character to lower case (char version).
+ static int to_lower (int c);
+
+#if defined (ACE_HAS_WCHAR) && !defined (ACE_LACKS_TOWLOWER)
+ /// Converts a character to lower case (wchar_t version).
+ static wint_t to_lower (wint_t c);
+#endif /* ACE_HAS_WCHAR && !ACE_LACKS_TOWLOWER */
+
+ //@}
+
+ /** @name Non-standard functions
+ *
+ * These functions aren't in the standard.
+ *
+ */
+ //@{
+
+ /// Converts an integer to a string.
+ static char *itoa (int value, char *string, int radix);
+
+#if defined (ACE_HAS_WCHAR)
+ /// Converts an integer to a string.
+ static wchar_t *itoa (int value, wchar_t *string, int radix);
+#endif /* ACE_HAS_WCHAR */
+
+ /// Compares two strings (case insensitive const char version).
+ static int strcasecmp (const char *s, const char *t);
+
+#if defined (ACE_HAS_WCHAR)
+ /// Compares two strings (case insensitive const wchar_t version).
+ static int strcasecmp (const wchar_t *s, const wchar_t *t);
+#endif /* ACE_HAS_WCHAR */
+
+ /// Finds the first occurance of a character in an array (const char
+ /// version).
+ static const char *strnchr (const char *s, int c, size_t len);
+
+ /// Finds the first occurance of a character in an array (const ACE_WCHAR_T
+ /// version).
+ static const ACE_WCHAR_T *strnchr (const ACE_WCHAR_T *s, ACE_WINT_T c, size_t len);
+
+ /// Finds the first occurance of a character in an array (char version).
+ static char *strnchr (char *s, int c, size_t len);
+
+ /// Finds the first occurance of a character in an array (ACE_WCHAR_T version).
+ static ACE_WCHAR_T *strnchr (ACE_WCHAR_T *s, ACE_WINT_T c, size_t len);
+
+ /// Compares two arrays (case insensitive const char version).
+ static int strncasecmp (const char *s, const char *t, size_t len);
+
+#if defined (ACE_HAS_WCHAR)
+ /// Compares two arrays (case insensitive const wchar_t version).
+ static int strncasecmp (const wchar_t *s, const wchar_t *t, size_t len);
+#endif /* ACE_HAS_WCHAR */
+
+ /// Copies a string, but returns a pointer to the end of the
+ /// copied region (char version).
+ static char *strecpy (char *des, const char *src);
+
+#if defined (ACE_HAS_WCHAR)
+ /// Copies a string, but returns a pointer to the end of the
+ /// copied region (wchar_t version).
+ static wchar_t *strecpy (wchar_t *s, const wchar_t *t);
+#endif /* ACE_HAS_WCHAR */
+
+ /// This is a "safe" c string copy function (char version).
+ /**
+ * Unlike strncpy() this function will always add a terminating '\0'
+ * char if maxlen > 0. So the user doesn't has to provide an extra
+ * '\0' if the user wants a '\0' terminated dst. The function
+ * doesn't check for a 0 <dst>, because this will give problems
+ * anyway. When <src> is 0 an empty string is made. We do not
+ * "touch" *<dst> if maxlen is 0. Returns <dst>. Care should be
+ * taken when replacing strncpy() calls, because in some cases a
+ * strncpy() user is using the "not '\0' terminating" feature from
+ * strncpy(). This happens most when the call to strncpy() was
+ * optimized by using a maxlen which is 1 smaller than the size
+ * because there's always written a '\0' inside this last position.
+ * Very seldom it's possible that the '\0' padding feature from
+ * strncpy() is needed.
+ */
+ static char *strsncpy (char *dst,
+ const char *src,
+ size_t maxlen);
+
+ /// This is a "safe" c string copy function (wchar_t version).
+ /**
+ * Unlike strncpy() this function will always add a terminating '\0'
+ * char if maxlen > 0. So the user doesn't has to provide an extra
+ * '\0' if the user wants a '\0' terminated dst. The function
+ * doesn't check for a 0 <dst>, because this will give problems
+ * anyway. When <src> is 0 an empty string is made. We do not
+ * "touch" *<dst> if maxlen is 0. Returns <dst>. Care should be
+ * taken when replacing strncpy() calls, because in some cases a
+ * strncpy() user is using the "not '\0' terminating" feature from
+ * strncpy(). This happens most when the call to strncpy() was
+ * optimized by using a maxlen which is 1 smaller than the size
+ * because there's always written a '\0' inside this last position.
+ * Very seldom it's possible that the '\0' padding feature from
+ * strncpy() is needed.
+ */
+ static ACE_WCHAR_T *strsncpy (ACE_WCHAR_T *dst,
+ const ACE_WCHAR_T *src,
+ size_t maxlen);
+
+ /// Finds the first occurance of a substring in an array (const char
+ /// version).
+ static const char *strnstr (const char *s, const char *t, size_t len);
+
+ /// Finds the first occurance of a substring in an array (const wchar_t
+ /// version).
+ static const ACE_WCHAR_T *strnstr (const ACE_WCHAR_T *s,
+ const ACE_WCHAR_T *t,
+ size_t len);
+
+ /// Finds the first occurance of a substring in an array (char version).
+ static char *strnstr (char *s, const char *t, size_t len);
+
+ /// Finds the first occurance of a substring in an array (wchar_t version).
+ static ACE_WCHAR_T *strnstr (ACE_WCHAR_T *s, const ACE_WCHAR_T *t, size_t len);
+
+ /// Returns a malloced duplicated string (char version).
+ static char *strdup (const char *s);
+
+#if defined (ACE_HAS_WCHAR)
+ /// Returns a malloced duplicated string (wchar_t version).
+ static wchar_t *strdup (const wchar_t *s);
+#endif /* ACE_HAS_WCHAR */
+
+ /// Finds the next token in a string (safe char version).
+ static char *strtok_r (char *s, const char *tokens, char **lasts);
+
+#if !defined (ACE_LACKS_STRTOD)
+ /// Converts a string to a double value (char version).
+ static double strtod (const char *s, char **endptr);
+#endif /* !ACE_LACKS_STRTOD */
+
+#if defined (ACE_HAS_WCHAR) && !defined (ACE_LACKS_WCSTOD)
+ /// Converts a string to a double value (wchar_t version).
+ static double strtod (const wchar_t *s, wchar_t **endptr);
+#endif /* ACE_HAS_WCHAR && !ACE_LACKS_WCSTOD */
+
+ /// Converts a string to a long value (char version).
+ static long strtol (const char *s, char **ptr, int base);
+
+#if defined (ACE_HAS_WCHAR) && !defined (ACE_LACKS_WCSTOL)
+ /// Converts a string to a long value (wchar_t version).
+ static long strtol (const wchar_t *s, wchar_t **ptr, int base);
+#endif /* ACE_HAS_WCHAR && !ACE_LACKS_WCSTOL */
+
+ /// Converts a string to an unsigned long value (char version).
+ static unsigned long strtoul (const char *s, char **ptr, int base);
+
+#if defined (ACE_HAS_WCHAR) && !defined (ACE_LACKS_WCSTOUL)
+ /// Converts a string to an unsigned long value (wchar_t version).
+ static unsigned long strtoul (const wchar_t *s, wchar_t **ptr, int base);
+#endif /* ACE_HAS_WCHAR && !ACE_LACKS_WCSTOUL */
+
+ //@}
+
+private:
+
+ /** @name Emulation
+ *
+ * These methods are provided for platforms that do not have a native
+ * implementation.
+ */
+ //@{
+
+#if !defined (ACE_HAS_ITOA)
+ /// Emulated itoa - Converts an integer to a string.
+ static char *itoa_emulation (int value, char *string, int radix);
+#endif /* !ACE_HAS_ITOA */
+
+#if defined (ACE_HAS_WCHAR) && defined (ACE_LACKS_ITOW)
+ /// Emulated itow - Converts an integer to a string.
+ static wchar_t *itow_emulation (int value, wchar_t *string, int radix);
+#endif /* ACE_HAS_WCHAR && ACE_LACKS_ITOW */
+
+#if !defined (ACE_HAS_MEMCHR)
+ /// Emulated memchr - Finds a character in a buffer.
+ static const void *memchr_emulation (const void *s, int c, size_t len);
+#endif /* ACE_HAS_MEMCHR */
+
+#if defined (ACE_LACKS_STRCASECMP)
+ /// Emulated strcasecmp - Performs a case insensitive comparison of strings.
+ static int strcasecmp_emulation (const char *s, const char *t);
+
+ /// Emulated strncasecmp - Performs a case insensitvie comparison of arrays.
+ static int strncasecmp_emulation (const char *s, const char *t, size_t len);
+#endif /* ACE_LACKS_STRCASECMP */
+
+#if defined (ACE_LACKS_STRCSPN)
+ /// Emulated strcspn - Finds a substring in a string.
+ static size_t strcspn_emulation (const char *s, const char *reject);
+#endif /* ACE_LACKS_STRCSPN */
+
+#if defined (ACE_LACKS_STRCHR)
+ /// Emulated strchr (char version) - Finds the first occurance of a
+ /// character in a string.
+ static char *strchr_emulation (char *s, int c);
+
+ /// Emulated strchr (const char version) - Finds the first occurance of a
+ /// character in a string.
+ static const char *strchr_emulation (const char *s, int c);
+#endif /* ACE_LACKS_STRCHR */
+
+#if defined (ACE_LACKS_STRERROR)
+ /// Emulated strerror - Returns a system error message.
+ static char *strerror_emulation (int errnum);
+#endif /* ACE_LACKS_STRERROR */
+
+#if defined (ACE_LACKS_STRPBRK)
+ /// Emulated strpbrk - Searches for characters in a string.
+ static char *strpbrk_emulation (const char *string,
+ const char *charset);
+#endif /* ACE_LACKS_STRPBRK */
+
+#if defined (ACE_LACKS_STRRCHR)
+ /// Emulated strrchr (char version) - Finds the last occurance of a
+ /// character in a string.
+ static char *strrchr_emulation (char *s, int c);
+
+ /// Emulated strrchr (const char version) - Finds the last occurance of a
+ /// character in a string.
+ static const char *strrchr_emulation (const char *s, int c);
+#endif /* ACE_LACKS_STRRCHR */
+
+#if !defined (ACE_HAS_REENTRANT_FUNCTIONS)
+ /// Emulated strtok_r.
+ static char *strtok_r_emulation (char *s, const char *tokens, char **lasts);
+#endif /* !ACE_HAS_REENTRANT_FUNCTIONS */
+
+#if defined (ACE_LACKS_STRSPN)
+ /// Emulated wcsspn.
+ static size_t strspn_emulation (const char *string,
+ const char *charset);
+#endif /* ACE_LACKS_STRSPN */
+
+#if defined (ACE_LACKS_STRTOL)
+ static long strtol_emulation (const char *nptr, char **endptr, int base);
+#endif /* ACE_LACKS_STRTOL */
+
+#if defined (ACE_LACKS_STRTOUL)
+ static unsigned long strtoul_emulation (const char *nptr,
+ char **endptr,
+ int base);
+#endif /* ACE_LACKS_STRTOUL */
+
+#if defined (ACE_HAS_WCHAR) && defined (ACE_LACKS_WCSCAT)
+ /// Emulated wcscat - Appends a string.
+ static wchar_t *wcscat_emulation (wchar_t *destination,
+ const wchar_t *source);
+#endif /* ACE_HAS_WCHAR && ACE_LACKS_WCSCAT */
+
+#if defined (ACE_HAS_WCHAR) && defined (ACE_LACKS_WCSCHR)
+ /// Emulated wcschr - Finds a character in a string.
+ static wchar_t *wcschr_emulation (const wchar_t *string, wint_t c);
+#endif /* ACE_HAS_WCHAR && ACE_LACKS_WCSCHR */
+
+#if !defined (ACE_HAS_WCHAR) || defined (ACE_LACKS_WCSCMP)
+ /// Emulated wcscmp - Compares strings.
+ static int wcscmp_emulation (const ACE_WCHAR_T *string1, const ACE_WCHAR_T *string2);
+#endif /* !ACE_HAS_WCHAR || ACE_LACKS_WCSCMP */
+
+#if defined (ACE_HAS_WCHAR) && defined (ACE_LACKS_WCSCPY)
+ /// Emulated wcscpy - Copies a string.
+ static wchar_t *wcscpy_emulation (wchar_t *destination,
+ const wchar_t *source);
+#endif /* ACE_HAS_WCHAR && ACE_LACKS_WCSCPY */
+
+#if defined (ACE_HAS_WCHAR) && defined (ACE_LACKS_WCSICMP)
+ /// Emulated wcsicmp - Performs a case insensitive comparison of strings.
+ static int wcsicmp_emulation (const wchar_t *string1,
+ const wchar_t *string2);
+#endif /* ACE_HAS_WCHAR && ACE_LACKS_WCSICMP */
+
+#if !defined (ACE_HAS_WCHAR) || defined (ACE_LACKS_WCSLEN)
+ /// Emulated wcslen - Returns the length of a string.
+ static size_t wcslen_emulation (const ACE_WCHAR_T *string);
+#endif /* !ACE_HAS_WCHAR || ACE_LACKS_WCSLEN */
+
+#if !defined (ACE_HAS_WCHAR) || defined (ACE_LACKS_WCSNCAT)
+ /// Emulated wcscat - Appends a string.
+ static ACE_WCHAR_T *wcsncat_emulation (ACE_WCHAR_T *destination,
+ const ACE_WCHAR_T *source,
+ size_t count);
+#endif /* !ACE_HAS_WCHAR || ACE_LACKS_WCSCAT */
+
+#if !defined (ACE_HAS_WCHAR) || defined (ACE_LACKS_WCSNCMP)
+ /// Emulated wcsncmp - Compares two arrays.
+ static int wcsncmp_emulation (const ACE_WCHAR_T *string1,
+ const ACE_WCHAR_T *string2,
+ size_t len);
+#endif /* !ACE_HAS_WCHAR || ACE_LACKS_WCSNCMP */
+
+#if !defined (ACE_HAS_WCHAR) || defined (ACE_LACKS_WCSNCPY)
+ /// Emulated wcsncpy - Copies an array.
+ static ACE_WCHAR_T *wcsncpy_emulation (ACE_WCHAR_T *destination,
+ const ACE_WCHAR_T *source,
+ size_t len);
+#endif /* !ACE_HAS_WCHAR || ACE_LACKS_WCSNCPY */
+
+#if defined (ACE_HAS_WCHAR) && defined (ACE_LACKS_WCSNICMP)
+ /// Emulated wcsnicmp - Performs a case insensitive comparison of two
+ /// arrays
+ static int wcsnicmp_emulation (const wchar_t *string1,
+ const wchar_t *string2,
+ size_t len);
+#endif /* ACE_HAS_WCHAR && ACE_LACKS_WCSNICMP */
+
+#if defined (ACE_HAS_WCHAR) && defined (ACE_LACKS_WCSPBRK)
+ /// Emulated wcspbrk - Searches for characters in a string.
+ static wchar_t *wcspbrk_emulation (const wchar_t *string,
+ const wchar_t *charset);
+#endif /* ACE_HAS_WCHAR && ACE_LACKS_WCSPBRK */
+
+#if defined (ACE_HAS_WCHAR) && defined (ACE_LACKS_WCSRCHR)
+ /// Emulated wcsrchr (wchar_t version) - Finds the last occurance of a
+ /// character in a string.
+ static wchar_t *wcsrchr_emulation (wchar_t *string, wint_t c);
+
+ /// Emulated wcsrchr (const wchar_t version) - Finds the last occurance of a
+ /// character in a string.
+ static const wchar_t *wcsrchr_emulation (const wchar_t *string, wint_t c);
+#endif /* ACE_HAS_WCHAR && ACE_LACKS_WCSRCHR */
+
+#if defined (ACE_HAS_WCHAR) && defined (ACE_LACKS_WCSCSPN)
+ /// Emulated wcscspn.
+ static size_t wcscspn_emulation (const wchar_t *string,
+ const wchar_t *reject);
+#endif /* ACE_HAS_WCHAR && ACE_LACKS_WCSCSPN */
+
+#if defined (ACE_HAS_WCHAR) && defined (ACE_LACKS_WCSSPN)
+ /// Emulated wcsspn.
+ static size_t wcsspn_emulation (const wchar_t *string,
+ const wchar_t *charset);
+#endif /* ACE_HAS_WCHAR && ACE_LACKS_WCSSPN */
+
+#if defined (ACE_HAS_WCHAR) && defined (ACE_LACKS_WCSSTR)
+ /// Emulated wcsstr - Performs a case insensitive comparison of two strings.
+ static wchar_t *wcsstr_emulation (const wchar_t *string,
+ const wchar_t *charset);
+#endif /* ACE_HAS_WCHAR && ACE_LACKS_WCSSTR */
+
+ //@}
+};
+
+# if defined (ACE_HAS_INLINED_OSCALLS)
+# if defined (ACE_INLINE)
+# undef ACE_INLINE
+# endif /* ACE_INLINE */
+# define ACE_INLINE inline
+# include "OS_String.inl"
+# endif /* ACE_HAS_INLINED_OSCALLS */
+
+#include "ace/post.h"
+#endif /* ACE_OS_STRING_H */
diff --git a/ace/OS/OS_String.inl b/ace/OS/OS_String.inl
new file mode 100644
index 00000000000..b240c334a8b
--- /dev/null
+++ b/ace/OS/OS_String.inl
@@ -0,0 +1,731 @@
+// -*- C++ -*-
+//=============================================================================
+/**
+ * @file OS_String.inl
+ *
+ * $Id$
+ *
+ * @brief Contains inline definitions for class ACE_OS_String.
+ */
+//=============================================================================
+
+#if defined (ACE_HAS_PACE)
+# include /**/ "pace/string.h"
+# include /**/ "pace/ctype.h"
+# include /**/ "pace/stdlib.h"
+#endif /* ACE_HAS_PACE */
+
+// Matthew Stevens 7-10-95 Fix GNU GCC 2.7 for memchr() problem.
+#if defined (ACE_HAS_GNU_CSTRING_H)
+// Define this file to keep /usr/include/memory.h from being included.
+# include /**/ <cstring>
+#else
+# if !defined (ACE_LACKS_MEMORY_H)
+# include /**/ <memory.h>
+# endif /* !ACE_LACKS_MEMORY_H */
+#endif /* ACE_HAS_GNU_CSTRING_H */
+
+#if !defined (ACE_PSOS_DIAB_MIPS)
+# include /**/ <stdlib.h>
+# include /**/ <string.h>
+#endif /* !ACE_PSOS_DIAB_MIPS */
+
+// We need strings.h on some platforms (qnx-neutrino, for example)
+// to get the declaration for strcasecmp
+#if defined (ACE_HAS_STRINGS)
+# include /**/ <strings.h>
+#endif /* ACE_HAS_STRINGS */
+
+#include /**/ <ctype.h>
+
+ACE_INLINE const void *
+ACE_OS_String::memchr (const void *s, int c, size_t len)
+{
+#if defined (ACE_HAS_PACE)
+ return pace_memchr (s, c, len);
+#elif defined (ACE_HAS_MEMCHR)
+ return ::memchr (s, c, len);
+#else /* ACE_HAS_MEMCHR */
+ return ACE_OS_String::memchr_emulation (s, c, len);
+#endif /* ACE_HAS_MEMCHR */
+}
+
+ACE_INLINE void *
+ACE_OS_String::memchr (void *s, int c, size_t len)
+{
+ return ACE_const_cast (void *,
+ ACE_OS_String::memchr (ACE_static_cast (const void *, s), c, len));
+}
+
+
+ACE_INLINE int
+ACE_OS_String::memcmp (const void *t, const void *s, size_t len)
+{
+#if defined (ACE_HAS_PACE)
+ return pace_memcmp (t, s, len);
+#else
+ return ::memcmp (t, s, len);
+#endif /* ACE_HAS_PACE */
+}
+
+
+ACE_INLINE void *
+ACE_OS_String::memcpy (void *t, const void *s, size_t len)
+{
+#if defined (ACE_HAS_PACE)
+ return pace_memcpy (t, s, len);
+#else
+ return ::memcpy (t, s, len);
+#endif /* ACE_HAS_PACE */
+}
+
+ACE_INLINE void *
+ACE_OS_String::memmove (void *t, const void *s, size_t len)
+{
+#if defined (ACE_HAS_PACE)
+ return pace_memmove (t, s, len);
+#else
+ return ::memmove (t, s, len);
+#endif /* ACE_HAS_PACE */
+}
+
+ACE_INLINE void *
+ACE_OS_String::memset (void *s, int c, size_t len)
+{
+#if defined (ACE_HAS_PACE)
+ return pace_memset (s, c, len);
+#else
+ return ::memset (s, c, len);
+#endif /* ACE_HAS_PACE */
+}
+
+ACE_INLINE char *
+ACE_OS_String::strcat (char *s, const char *t)
+{
+#if defined (ACE_HAS_PACE)
+ return pace_strcat (s, t);
+#else
+ return ::strcat (s, t);
+#endif /* ACE_HAS_PACE */
+}
+
+#if defined (ACE_HAS_WCHAR)
+ACE_INLINE wchar_t *
+ACE_OS_String::strcat (wchar_t *s, const wchar_t *t)
+{
+# if defined (ACE_LACKS_WCSCAT)
+ return ACE_OS_String::wcscat_emulation (s, t);
+# else /* ACE_LACKS_WCSCAT */
+ return ::wcscat (s, t);
+# endif /* ACE_LACKS_WCSCAT */
+}
+#endif /* ACE_HAS_WCHAR */
+
+ACE_INLINE const char *
+ACE_OS_String::strchr (const char *s, int c)
+{
+#if defined (ACE_HAS_PACE)
+ return pace_strchr (s, c);
+#elif defined (ACE_LACKS_STRCHR)
+ return ACE_OS_String::strchr_emulation (s, c);
+#else /* ! ACE_LACKS_STRCHR */
+ return (const char *) ::strchr (s, c);
+#endif /* ACE_HAS_PACE */
+}
+
+#if defined (ACE_HAS_WCHAR)
+ACE_INLINE const wchar_t *
+ACE_OS_String::strchr (const wchar_t *s, wint_t c)
+{
+# if defined (ACE_LACKS_WCSCHR)
+ return ACE_OS_String::wcschr_emulation (s, c);
+# else /* ACE_LACKS_WCSCHR */
+ return ::wcschr (s, c);
+# endif /* ACE_LACKS_WCSCHR */
+}
+#endif /* ACE_HAS_WCHAR */
+
+ACE_INLINE char *
+ACE_OS_String::strchr (char *s, int c)
+{
+#if defined (ACE_HAS_PACE)
+ return pace_strchr (s, c);
+#elif defined (ACE_LACKS_STRCHR)
+ return ACE_OS_String::strchr_emulation (s, c);
+#else /* ! ACE_LACKS_STRCHR */
+ return ::strchr (s, c);
+#endif /* ACE_HAS_PACE */
+}
+
+#if defined (ACE_HAS_WCHAR)
+ACE_INLINE wchar_t *
+ACE_OS_String::strchr (wchar_t *s, wint_t c)
+{
+ return ACE_const_cast (wchar_t *,
+ ACE_OS_String::strchr (ACE_static_cast (const wchar_t *, s), c));
+}
+#endif /* ACE_HAS_WCHAR */
+
+ACE_INLINE int
+ACE_OS_String::strcmp (const char *s, const char *t)
+{
+#if defined (ACE_HAS_PACE)
+ return pace_strcmp (s, t);
+#else
+ return ::strcmp (s, t);
+#endif /* ACE_HAS_PACE */
+}
+
+ACE_INLINE int
+ACE_OS_String::strcmp (const ACE_WCHAR_T *s, const ACE_WCHAR_T *t)
+{
+# if !defined (ACE_HAS_WCHAR) || defined (ACE_LACKS_WCSCMP)
+ return ACE_OS_String::wcscmp_emulation (s, t);
+# else /* !ACE_HAS_WCHAR || ACE_LACKS_WCSCMP */
+ return ::wcscmp (s, t);
+# endif /* !ACE_HAS_WCHAR || ACE_LACKS_WCSCMP */
+}
+
+ACE_INLINE char *
+ACE_OS_String::strcpy (char *s, const char *t)
+{
+#if defined (ACE_HAS_PACE)
+ return pace_strcpy (s, t);
+#else /* ACE_HAS_PACE */
+ return ::strcpy (s, t);
+#endif /* ACE_HAS_PACE */
+}
+
+#if defined (ACE_HAS_WCHAR)
+ACE_INLINE wchar_t *
+ACE_OS_String::strcpy (wchar_t *s, const wchar_t *t)
+{
+# if defined (ACE_LACKS_WCSCPY)
+ return ACE_OS_String::wcscpy_emulation (s, t);
+# else /* ACE_LACKS_WCSCPY */
+ return ::wcscpy (s, t);
+# endif /* ACE_LACKS_WCSCPY */
+}
+#endif /* ACE_HAS_WCHAR */
+
+ACE_INLINE size_t
+ACE_OS_String::strcspn (const char *s, const char *reject)
+{
+#if defined (ACE_HAS_PACE)
+ return pace_strcspn (s, reject);
+#elif defined (ACE_LACKS_STRCSPN)
+ return ACE_OS_String::strcspn_emulation (s, reject);
+#else /* ACE_LACKS_STRCSPN */
+ return ::strcspn (s, reject);
+#endif /* ACE_LACKS_STRCSPN */
+}
+
+#if defined (ACE_HAS_WCHAR)
+ACE_INLINE size_t
+ACE_OS_String::strcspn (const wchar_t *s, const wchar_t *reject)
+{
+# if defined (ACE_LACKS_WCSCSPN)
+ return ACE_OS_String::wcscspn_emulation (s, reject);
+# else /* ACE_LACKS_WCSCSPN */
+ return ::wcscspn (s, reject);
+# endif /* ACE_LACKS_WCSCSPN */
+}
+#endif /* ACE_HAS_WCHAR */
+
+ACE_INLINE char *
+ACE_OS_String::strerror (int errnum)
+{
+#if defined (ACE_LACKS_STRERROR)
+ return ACE_OS_String::strerror_emulation (errnum);
+#else /* ACE_LACKS_STRERROR */
+ return ::strerror (errnum);
+#endif /* ACE_LACKS_STRERROR */
+}
+
+ACE_INLINE size_t
+ACE_OS_String::strlen (const char *s)
+{
+#if defined (ACE_HAS_PACE)
+ return pace_strlen (s);
+#else /* ACE_HAS_PACE */
+ return ::strlen (s);
+#endif /* ACE_HAS_PACE */
+}
+
+ACE_INLINE size_t
+ACE_OS_String::strlen (const ACE_WCHAR_T *s)
+{
+# if !defined (ACE_HAS_WCHAR) || defined (ACE_LACKS_WCSLEN)
+ return ACE_OS_String::wcslen_emulation (s);
+# else /* !ACE_HAS_WCHAR || ACE_LACKS_WCSLEN */
+ return ::wcslen (s);
+# endif /* !ACE_HAS_WCHAR || ACE_LACKS_WCSLEN */
+}
+
+ACE_INLINE char *
+ACE_OS_String::strncat (char *s, const char *t, size_t len)
+{
+#if defined (ACE_HAS_PACE)
+ return pace_strncat (s, t, len);
+#else /* ACE_HAS_PACE */
+ return ::strncat (s, t, len);
+#endif /* ACE_HAS_PACE */
+}
+
+ACE_INLINE ACE_WCHAR_T *
+ACE_OS_String::strncat (ACE_WCHAR_T *s, const ACE_WCHAR_T *t, size_t len)
+{
+# if !defined (ACE_HAS_WCHAR) || defined (ACE_LACKS_WCSNCAT)
+ return ACE_OS_String::wcsncat_emulation (s, t, len);
+# else /* !ACE_HAS_WCHAR || ACE_LACKS_WCSNCAT */
+ return ::wcsncat (s, t, len);
+# endif /* !ACE_HAS_WCHAR || ACE_LACKS_WCSNCAT */
+}
+
+ACE_INLINE int
+ACE_OS_String::strncmp (const char *s, const char *t, size_t len)
+{
+#if defined (ACE_HAS_PACE)
+ return pace_strncmp (s, t, len);
+#else /* ACE_HAS_PACE */
+ return ::strncmp (s, t, len);
+#endif /* ACE_HAS_PACE */
+}
+
+ACE_INLINE int
+ACE_OS_String::strncmp (const ACE_WCHAR_T *s, const ACE_WCHAR_T *t, size_t len)
+{
+# if !defined (ACE_HAS_WCHAR) || defined (ACE_LACKS_WCSNCMP)
+ return ACE_OS_String::wcsncmp_emulation (s, t, len);
+# else /* !ACE_HAS_WCHAR || ACE_LACKS_WCSNCMP */
+ return ::wcsncmp (s, t, len);
+# endif /* !ACE_HAS_WCHAR || ACE_LACKS_WCSNCMP */
+}
+
+ACE_INLINE char *
+ACE_OS_String::strncpy (char *s, const char *t, size_t len)
+{
+#if defined (ACE_HAS_PACE)
+ return pace_strncpy (s, t, len);
+#else /* ACE_HAS_PACE */
+ return ::strncpy (s, t, len);
+#endif /* ACE_HAS_PACE */
+}
+
+ACE_INLINE ACE_WCHAR_T *
+ACE_OS_String::strncpy (ACE_WCHAR_T *s, const ACE_WCHAR_T *t, size_t len)
+{
+# if !defined (ACE_HAS_WCHAR) || defined (ACE_LACKS_WCSNCPY)
+ return ACE_OS_String::wcsncpy_emulation (s, t, len);
+# else /* !ACE_HAS_WCHAR || ACE_LACKS_WCSNCPY */
+ return ::wcsncpy (s, t, len);
+# endif /* !ACE_HAS_WCHAR || ACE_LACKS_WCSNCPY */
+}
+
+ACE_INLINE const char *
+ACE_OS_String::strpbrk (const char *s1, const char *s2)
+{
+#if defined (ACE_HAS_PACE)
+ return (const char*) pace_strpbrk (s1, s2);
+#elif defined (ACE_LACKS_STRPBRK)
+ return ACE_OS_String::strpbrk_emulation (s1, s2);
+#else /* ACE_HAS_PACE */
+ return (const char *) ::strpbrk (s1, s2);
+#endif /* ACE_HAS_PACE */
+}
+
+#if defined (ACE_HAS_WCHAR)
+ACE_INLINE const wchar_t *
+ACE_OS_String::strpbrk (const wchar_t *s, const wchar_t *t)
+{
+# if defined (ACE_LACKS_WCSPBRK)
+ return ACE_OS_String::wcspbrk_emulation (s, t);
+# else /* ACE_LACKS_WCSPBRK */
+ return ::wcspbrk (s, t);
+# endif /* ACE_LACKS_WCSPBRK */
+}
+#endif /* ACE_HAS_WCHAR */
+
+ACE_INLINE char *
+ACE_OS_String::strpbrk (char *s1, const char *s2)
+{
+#if defined (ACE_HAS_PACE)
+ return pace_strpbrk (s1, s2);
+#elif defined (ACE_LACKS_STRPBRK)
+ return ACE_OS_String::strpbrk_emulation (s1, s2);
+#else /* ACE_HAS_PACE */
+ return ::strpbrk (s1, s2);
+#endif /* ACE_HAS_PACE */
+}
+
+#if defined (ACE_HAS_WCHAR)
+ACE_INLINE wchar_t *
+ACE_OS_String::strpbrk (wchar_t *s, const wchar_t *t)
+{
+ return ACE_const_cast (wchar_t *,
+ ACE_OS_String::strpbrk (ACE_static_cast (const wchar_t *, s), t));
+}
+#endif /* ACE_HAS_WCHAR */
+
+ACE_INLINE const char *
+ACE_OS_String::strrchr (const char *s, int c)
+{
+#if defined (ACE_HAS_PACE)
+ return (const char*) pace_strrchr (s, c);
+#elif defined (ACE_LACKS_STRRCHR)
+ return ACE_OS_String::strrchr_emulation (s, c);
+#else /* ! ACE_LACKS_STRRCHR */
+ return (const char *) ::strrchr (s, c);
+#endif /* ! ACE_LACKS_STRRCHR */
+}
+
+#if defined (ACE_HAS_WCHAR)
+ACE_INLINE const wchar_t *
+ACE_OS_String::strrchr (const wchar_t *s, wint_t c)
+{
+#if defined (ACE_LACKS_WCSRCHR)
+ return ACE_OS_String::wcsrchr_emulation (s, c);
+#else /* ! ACE_LACKS_WCSRCHR */
+ return (const wchar_t *) ::wcsrchr (s, c);
+#endif /* ! ACE_LACKS_WCSRCHR */
+}
+#endif /* ACE_HAS_WCHAR */
+
+ACE_INLINE char *
+ACE_OS_String::strrchr (char *s, int c)
+{
+#if defined (ACE_HAS_PACE)
+ return pace_strrchr (s, c);
+#elif defined (ACE_LACKS_STRRCHR)
+ return ACE_OS_String::strrchr_emulation (s, c);
+#else /* ! ACE_LACKS_STRRCHR */
+ return ::strrchr (s, c);
+#endif /* ! ACE_LACKS_STRRCHR */
+}
+
+#if defined (ACE_HAS_WCHAR)
+ACE_INLINE wchar_t *
+ACE_OS_String::strrchr (wchar_t *s, wint_t c)
+{
+ return ACE_const_cast (wchar_t *,
+ ACE_OS_String::strrchr (ACE_static_cast (const wchar_t *, s), c));
+}
+#endif /* ACE_HAS_WCHAR */
+
+ACE_INLINE size_t
+ACE_OS_String::strspn (const char *s, const char *t)
+{
+#if defined (ACE_HAS_PACE)
+ return pace_strspn (s, t);
+#elif defined (ACE_LACKS_STRSPN)
+ return ACE_OS_String::strspn_emulation (s, t);
+#else /* ACE_HAS_PACE */
+ return ::strspn (s, t);
+#endif /* ACE_HAS_PACE */
+}
+
+#if defined (ACE_HAS_WCHAR)
+ACE_INLINE size_t
+ACE_OS_String::strspn (const wchar_t *s, const wchar_t *t)
+{
+# if defined (ACE_LACKS_WCSSPN)
+ return ACE_OS_String::wcsspn_emulation (s, t);
+# else /* ACE_LACKS_WCSSPN */
+ return ::wcsspn (s, t);
+# endif /* ACE_LACKS_WCSSPN */
+}
+#endif /* ACE_HAS_WCHAR */
+
+ACE_INLINE const char *
+ACE_OS_String::strstr (const char *s, const char *t)
+{
+#if defined (ACE_HAS_PACE)
+ return pace_strstr (s, t);
+#else /* ACE_HAS_PACE */
+ return (const char *) ::strstr (s, t);
+#endif /* ACE_HAS_PACE */
+}
+
+#if defined (ACE_HAS_WCHAR)
+ACE_INLINE const wchar_t *
+ACE_OS_String::strstr (const wchar_t *s, const wchar_t *t)
+{
+# if defined (ACE_LACKS_WCSSTR)
+ return ACE_OS_String::wcsstr_emulation (s, t);
+# else /* ACE_LACKS_WCSSTR */
+# if defined (ACE_HAS_XPG4_MULTIBYTE_CHAR)
+ return (const wchar_t *) ::wcswcs (s, t);
+# else
+ return (const wchar_t *) ::wcsstr (s, t);
+# endif /* ACE_HAS_XPG4_MULTIBYTE_CHAR */
+# endif /* ACE_LACKS_WCSSTR */
+}
+#endif /* ACE_HAS_WCHAR */
+
+ACE_INLINE char *
+ACE_OS_String::strstr (char *s, const char *t)
+{
+#if defined (ACE_HAS_PACE)
+ return pace_strstr (s, t);
+#else /* ACE_HAS_PACE */
+ return ::strstr (s, t);
+#endif /* ACE_HAS_PACE */
+}
+
+#if defined (ACE_HAS_WCHAR)
+ACE_INLINE wchar_t *
+ACE_OS_String::strstr (wchar_t *s, const wchar_t *t)
+{
+# if defined (ACE_LACKS_WCSSTR)
+ return ACE_OS_String::wcsstr_emulation (s, t);
+# else /* ACE_LACKS_WCSSTR */
+# if defined (ACE_HAS_XPG4_MULTIBYTE_CHAR)
+ return ::wcswcs (s, t);
+# else
+ return ::wcsstr (s, t);
+# endif /* ACE_HAS_XPG4_MULTIBYTE_CHAR */
+# endif /* ACE_LACKS_WCSSTR */
+}
+#endif /* ACE_HAS_WCHAR */
+
+ACE_INLINE char *
+ACE_OS_String::strtok (char *s, const char *tokens)
+{
+#if defined (ACE_HAS_PACE)
+ return pace_strtok (s, tokens);
+#else /* ACE_HAS_PACE */
+ return ::strtok (s, tokens);
+#endif /* ACE_HAS_PACE */
+}
+
+#if defined (ACE_HAS_WCHAR) && !defined (ACE_LACKS_WCSTOK)
+ACE_INLINE wchar_t *
+ACE_OS_String::strtok (wchar_t *s, const wchar_t *tokens)
+{
+ return ::wcstok (s, tokens);
+}
+#endif /* ACE_HAS_WCHAR && !ACE_LACKS_WCSTOK */
+
+ACE_INLINE int
+ACE_OS_String::ace_isprint (const ACE_TCHAR c)
+{
+#if defined (ACE_USES_WCHAR)
+ return iswprint (c);
+#elif defined (ACE_HAS_PACE)
+ return pace_isprint (c);
+#else /* ACE_USES_WCHAR */
+ return isprint (c);
+#endif /* ACE_USES_WCHAR */
+}
+
+ACE_INLINE int
+ACE_OS_String::ace_isspace (const ACE_TCHAR c)
+{
+#if defined (ACE_USES_WCHAR)
+ return iswspace (c);
+#elif defined (ACE_HAS_PACE)
+ return pace_isspace (c);
+#else /* ACE_HAS_PACE */
+ return isspace (c);
+#endif /* ACE_HAS_PACE */
+}
+
+ACE_INLINE int
+ACE_OS_String::to_lower (int c)
+{
+#if defined (ACE_HAS_PACE)
+ return pace_tolower (c);
+#else /* ACE_HAS_PACE */
+ return tolower (c);
+#endif /* ACE_HAS_PACE */
+}
+
+#if defined (ACE_HAS_WCHAR) && !defined (ACE_LACKS_TOWLOWER)
+ACE_INLINE wint_t
+ACE_OS_String::to_lower (wint_t c)
+{
+ return towlower (c);
+}
+#endif /* ACE_HAS_WCHAR && !ACE_LACKS_TOWLOWER */
+
+ACE_INLINE char *
+ACE_OS_String::itoa (int value, char *string, int radix)
+{
+#if !defined (ACE_HAS_ITOA)
+ return ACE_OS_String::itoa_emulation (value, string, radix);
+#elif defined (ACE_ITOA_EQUIVALENT)
+ return ACE_ITOA_EQUIVALENT (value, string, radix);
+#else /* !ACE_HAS_ITOA */
+ return ::itoa (value, string, radix);
+#endif /* !ACE_HAS_ITOA */
+}
+
+#if defined (ACE_HAS_WCHAR)
+ACE_INLINE wchar_t *
+ACE_OS_String::itoa (int value, wchar_t *string, int radix)
+{
+#if defined (ACE_LACKS_ITOW)
+ return ACE_OS_String::itow_emulation (value, string, radix);
+#else /* ACE_LACKS_ITOW */
+ return ::_itow (value, string, radix);
+#endif /* ACE_LACKS_ITOW */
+}
+#endif /* ACE_HAS_WCHAR */
+
+ACE_INLINE int
+ACE_OS_String::strcasecmp (const char *s, const char *t)
+{
+#if defined (ACE_LACKS_STRCASECMP)
+ return ACE_OS_String::strcasecmp_emulation (s, t);
+#elif defined (ACE_STRCASECMP_EQUIVALENT)
+ return ACE_STRCASECMP_EQUIVALENT (s, t);
+#else /* ACE_LACKS_STRCASECMP */
+ return ::strcasecmp (s, t);
+#endif /* ACE_LACKS_STRCASECMP */
+}
+
+#if defined (ACE_HAS_WCHAR)
+ACE_INLINE int
+ACE_OS_String::strcasecmp (const wchar_t *s, const wchar_t *t)
+{
+# if defined (ACE_LACKS_WCSICMP)
+ return ACE_OS_String::wcsicmp_emulation (s, t);
+# else /* ACE_LACKS_WCSICMP */
+ return ::_wcsicmp (s, t);
+# endif /* ACE_LACKS_WCSICMP */
+}
+#endif /* ACE_HAS_WCHAR */
+
+ACE_INLINE char *
+ACE_OS_String::strnchr (char *s, int c, size_t len)
+{
+#if defined ACE_PSOS_DIAB_PPC /* Compiler problem Diab 4.2b */
+ const char *const_char_s = s;
+ return ACE_const_cast (char *,
+ ACE_OS_String::strnchr (const_char_s, c, len));
+#else
+ return ACE_const_cast (char *,
+ ACE_OS_String::strnchr (ACE_static_cast (const char *, s), c, len));
+#endif
+}
+
+ACE_INLINE ACE_WCHAR_T *
+ACE_OS_String::strnchr (ACE_WCHAR_T *s, ACE_WINT_T c, size_t len)
+{
+ return ACE_const_cast (ACE_WCHAR_T *,
+ ACE_OS_String::strnchr (ACE_static_cast (const ACE_WCHAR_T *, s), c, len));
+}
+
+ACE_INLINE int
+ACE_OS_String::strncasecmp (const char *s, const char *t, size_t len)
+{
+#if defined (ACE_LACKS_STRCASECMP)
+ return ACE_OS_String::strncasecmp_emulation (s, t, len);
+#elif defined (ACE_STRNCASECMP_EQUIVALENT)
+ return ACE_STRNCASECMP_EQUIVALENT (s, t, len);
+#else /* ACE_LACKS_STRCASECMP */
+ return ::strncasecmp (s, t, len);
+#endif /* ACE_LACKS_STRCASECMP */
+}
+
+#if defined (ACE_HAS_WCHAR)
+ACE_INLINE int
+ACE_OS_String::strncasecmp (const wchar_t *s, const wchar_t *t, size_t len)
+{
+#if defined (ACE_LACKS_WCSNICMP)
+ return ACE_OS_String::wcsnicmp_emulation (s, t, len);
+#else /* ACE_LACKS_WCSNICMP */
+ return ::_wcsnicmp (s, t, len);
+#endif /* ACE_LACKS_WCSNICMP */
+}
+#endif /* ACE_HAS_WCHAR */
+
+ACE_INLINE char *
+ACE_OS_String::strnstr (char *s, const char *t, size_t len)
+{
+#if defined ACE_PSOS_DIAB_PPC /* Compiler problem Diab 4.2b */
+ const char *const_char_s=s;
+ return (char *) ACE_OS_String::strnstr (const_char_s, t, len);
+#else
+ return (char *) ACE_OS_String::strnstr ((const char *) s, t, len);
+#endif
+}
+
+ACE_INLINE ACE_WCHAR_T *
+ACE_OS_String::strnstr (ACE_WCHAR_T *s, const ACE_WCHAR_T *t, size_t len)
+{
+ return ACE_const_cast (ACE_WCHAR_T *,
+ ACE_OS_String::strnstr (ACE_static_cast (const ACE_WCHAR_T *, s), t, len));
+}
+
+ACE_INLINE char *
+ACE_OS_String::strtok_r (char *s, const char *tokens, char **lasts)
+{
+#if defined (ACE_HAS_PACE)
+ return pace_strtok_r (s, tokens, lasts);
+#elif defined (ACE_HAS_REENTRANT_FUNCTIONS)
+ return ::strtok_r (s, tokens, lasts);
+#else
+ return ACE_OS_String::strtok_r_emulation (s, tokens, lasts);
+#endif /* (ACE_HAS_REENTRANT_FUNCTIONS) */
+}
+
+#if !defined (ACE_LACKS_STRTOD)
+ACE_INLINE double
+ACE_OS_String::strtod (const char *s, char **endptr)
+{
+#if defined (ACE_HAS_PACE)
+ return pace_strtod (s, endptr);
+#else /* ACE_HAS_PACE */
+ return ::strtod (s, endptr);
+#endif /* ACE_HAS_PACE */
+}
+#endif /* !ACE_LACKS_STRTOD */
+
+#if defined (ACE_HAS_WCHAR) && !defined (ACE_LACKS_WCSTOD)
+ACE_INLINE double
+ACE_OS_String::strtod (const wchar_t *s, wchar_t **endptr)
+{
+ return ::wcstod (s, endptr);
+}
+#endif /* ACE_HAS_WCHAR && !ACE_LACKS_WCSTOD */
+
+ACE_INLINE long
+ACE_OS_String::strtol (const char *s, char **ptr, int base)
+{
+#if defined (ACE_HAS_PACE)
+ return pace_strtol (s, ptr, base);
+#elif defined (ACE_LACKS_STRTOL)
+ return ACE_OS_String::strtol_emulation (s, ptr, base);
+#else /* ACE_HAS_PACE */
+ return ::strtol (s, ptr, base);
+#endif /* ACE_HAS_PACE */
+}
+
+#if defined (ACE_HAS_WCHAR) && !defined (ACE_LACKS_WCSTOL)
+ACE_INLINE long
+ACE_OS_String::strtol (const wchar_t *s, wchar_t **ptr, int base)
+{
+ return ::wcstol (s, ptr, base);
+}
+#endif /* ACE_HAS_WCHAR && !ACE_LACKS_WCSTOL */
+
+ACE_INLINE unsigned long
+ACE_OS_String::strtoul (const char *s, char **ptr, int base)
+{
+#if defined (ACE_HAS_PACE)
+ return pace_strtoul (s, ptr, base);
+#elif defined (ACE_LACKS_STRTOUL)
+ return ACE_OS_String::strtoul_emulation (s, ptr, base);
+#else /* ACE_HAS_PACE */
+ return ::strtoul (s, ptr, base);
+#endif /* ACE_HAS_PACE */
+}
+
+#if defined (ACE_HAS_WCHAR) && !defined (ACE_LACKS_WCSTOUL)
+ACE_INLINE unsigned long
+ACE_OS_String::strtoul (const wchar_t *s, wchar_t **ptr, int base)
+{
+ return ::wcstoul (s, ptr, base);
+}
+#endif /* ACE_HAS_WCHAR && !ACE_LACKS_WCSTOUL */
diff --git a/ace/OS/OS_TLI.cpp b/ace/OS/OS_TLI.cpp
new file mode 100644
index 00000000000..629e6d49b3e
--- /dev/null
+++ b/ace/OS/OS_TLI.cpp
@@ -0,0 +1,13 @@
+// $Id$
+
+#include "OS_TLI.h"
+
+ACE_RCSID(ace, OS_TLI, "$Id$")
+
+#if !defined (ACE_HAS_INLINED_OSCALLS)
+# include "OS_TLI.inl"
+#else /* !ACE_HAS_INLINED_OSCALLS */
+#if defined (__hpux) && !defined (__GNUG__)
+static int shut_up_aCC = 0;
+#endif /* HPUX && !g++ */
+#endif /* !ACE_HAS_INLINED_OS_CALLS */
diff --git a/ace/OS/OS_TLI.h b/ace/OS/OS_TLI.h
new file mode 100644
index 00000000000..a022f2e97cc
--- /dev/null
+++ b/ace/OS/OS_TLI.h
@@ -0,0 +1,195 @@
+// -*- C++ -*-
+
+//=============================================================================
+/**
+ * @file OS_TLI.h
+ *
+ * $Id$
+ *
+ * @author Doug Schmidt <schmidt@cs.wustl.edu>
+ */
+//=============================================================================
+
+
+#ifndef ACE_OS_TLI_H
+#define ACE_OS_TLI_H
+#include "ace/pre.h"
+
+#include "ace/config-all.h"
+#include "OS_Export.h"
+
+#if !defined (ACE_LACKS_PRAGMA_ONCE)
+# pragma once
+#endif /* ACE_LACKS_PRAGMA_ONCE */
+
+# if !defined (ACE_HAS_TLI)
+// Dummies to help compilation.
+struct t_call { };
+struct t_bind { };
+struct t_info { };
+struct t_optmgmt { };
+struct t_discon { };
+struct t_unitdata { };
+struct t_uderr { };
+struct netbuf { };
+
+# else /* !ACE_WIN32 */
+
+# if !defined (ACE_HAS_TLI_PROTOTYPES)
+
+// Define ACE_TLI headers for systems that don't prototype them....
+extern "C"
+{
+ int t_accept(int fildes, int resfd, struct t_call *call);
+ char *t_alloc(int fildes, int struct_type, int fields);
+ int t_bind(int fildes, struct t_bind *req, struct t_bind *ret);
+ int t_close(int fildes);
+ int t_connect(int fildes, struct t_call *sndcall,
+ struct t_call *rcvcall);
+ void t_error(const char *errmsg);
+ int t_free(char *ptr, int struct_type);
+ int t_getinfo(int fildes, struct t_info *info);
+ int t_getname (int fildes, struct netbuf *namep, int type);
+ int t_getstate(int fildes);
+ int t_listen(int fildes, struct t_call *call);
+ int t_look(int fildes);
+ int t_open(char *path, int oflag, struct t_info *info);
+ int t_optmgmt(int fildes, struct t_optmgmt *req,
+ struct t_optmgmt *ret);
+ int t_rcv(int fildes, char *buf, unsigned int nbytes, int *flags);
+ int t_rcvconnect(int fildes, struct t_call *call);
+ int t_rcvdis(int fildes, struct t_discon *discon);
+ int t_rcvrel(int fildes);
+ int t_rcvudata(int fildes, struct t_unitdata *unitdata, int *flags);
+ int t_rcvuderr(int fildes, struct t_uderr *uderr);
+ int t_snd(int fildes, const char *buf, unsigned int nbytes, int flags);
+ int t_snddis(int fildes, struct t_call *call);
+ int t_sndrel(int fildes);
+ int t_sndudata(int fildes, struct t_unitdata *unitdata);
+ int t_sync(int fildes);
+ int t_unbind(int fildes);
+}
+# endif /* !ACE_HAS_TLI_PROTOTYPES */
+
+# if defined (ACE_HAS_TIUSER_H) || defined (ACE_HAS_XTI) || defined (ACE_HAS_FORE_ATM_XTI)
+# if defined (ACE_HAS_BROKEN_XTI_MACROS)
+# undef TCP_NODELAY
+# undef TCP_MAXSEG
+# endif /* ACE_HAS_BROKEN_XTI_MACROS */
+# if defined (ACE_HAS_TIUSER_H_BROKEN_EXTERN_C)
+extern "C" {
+# endif /* ACE_HAS_TIUSER_H_BROKEN_EXTERN_C */
+# if defined (ACE_HAS_FORE_ATM_XTI)
+# include /**/ <fore_xti/xti_user_types.h>
+# include /**/ <fore_xti/xti.h>
+# include /**/ <fore_xti/xti_atm.h>
+# include /**/ <fore_xti/netatm/atm.h>
+# include /**/ <fore_xti/ans.h>
+# elif defined (ACE_HAS_TIUSER_H)
+# include /**/ <tiuser.h>
+# elif defined (ACE_HAS_SYS_XTI_H)
+# define class ace_xti_class
+# include /**/ <sys/xti.h>
+# undef class
+# else
+# include /**/ <xti.h>
+# endif /* ACE_HAS_FORE_ATM_XTI */
+# if defined (ACE_HAS_TIUSER_H_BROKEN_EXTERN_C)
+}
+# endif /* ACE_HAS_TIUSER_H_BROKEN_EXTERN_C */
+# endif /* ACE_HAS_TIUSER_H || ACE_HAS_XTI */
+
+// Apparently this particular prototype is missing in so many
+// platforms that is just better to declare it ourselves.
+extern "C" int t_getname (int, struct netbuf *, int);
+
+# endif /* ACE_WIN32 */
+
+// If the xti.h file redefines the function names, do it now, else
+// when the function definitions are encountered, they won't match the
+// declaration here.
+
+# if defined (ACE_REDEFINES_XTI_FUNCTIONS)
+# include /**/ <xti.h>
+# if defined (UNIXWARE_2_0) /* They apparently forgot one... */
+extern "C" int _xti_error(char *);
+# endif /* UNIXWARE */
+# endif /* ACE_REDEFINES_XTI_FUNCTIONS */
+
+/**
+ * @class ACE_OS_TLI
+ *
+ * @brief This class is a wrapper for the TLI operations
+ *
+ */
+class ACE_OS_Export ACE_OS_TLI
+{
+public:
+ // = A set of wrappers for TLI.
+ static int t_accept (ACE_HANDLE fildes,
+ ACE_HANDLE resfd,
+ struct t_call
+ *call);
+ static char *t_alloc (ACE_HANDLE fildes,
+ int struct_type,
+ int
+ fields);
+ static int t_bind (ACE_HANDLE fildes,
+ struct t_bind *req,
+ struct
+ t_bind *ret);
+ static int t_close (ACE_HANDLE fildes);
+ static int t_connect (ACE_HANDLE fildes,
+ struct t_call *sndcall,
+ struct t_call *rcvcall);
+ static void t_error (const char *errmsg);
+ static int t_free (char *ptr,
+ int struct_type);
+ static int t_getinfo (ACE_HANDLE fildes,
+ struct t_info *info);
+ static int t_getname (ACE_HANDLE fildes,
+ struct netbuf *namep,
+ int type);
+ static int t_getstate (ACE_HANDLE fildes);
+ static int t_listen (ACE_HANDLE fildes,
+ struct t_call *call);
+ static int t_look (ACE_HANDLE fildes);
+ static ACE_HANDLE t_open (char *path,
+ int oflag,
+ struct t_info *info);
+ static int t_optmgmt (ACE_HANDLE fildes,
+ struct t_optmgmt *req,
+ struct t_optmgmt *ret);
+ static int t_rcv (ACE_HANDLE fildes,
+ char *buf,
+ unsigned int nbytes,
+ int *flags);
+ static int t_rcvdis (ACE_HANDLE fildes,
+ struct t_discon *discon);
+ static int t_rcvrel (ACE_HANDLE fildes);
+ static int t_rcvudata (ACE_HANDLE fildes,
+ struct t_unitdata *unitdata,
+ int *flags);
+ static int t_rcvuderr (ACE_HANDLE fildes,
+ struct t_uderr *uderr);
+ static int t_snd (ACE_HANDLE fildes,
+ const char *buf,
+ unsigned int nbytes,
+ int flags);
+ static int t_snddis (ACE_HANDLE fildes,
+ struct t_call *call);
+ static int t_sndrel (ACE_HANDLE fildes);
+ static int t_sync (ACE_HANDLE fildes);
+ static int t_unbind (ACE_HANDLE fildes);
+};
+
+# if defined (ACE_HAS_INLINED_OSCALLS)
+# if defined (ACE_INLINE)
+# undef ACE_INLINE
+# endif /* ACE_INLINE */
+# define ACE_INLINE inline
+# include "OS_TLI.inl"
+# endif /* ACE_HAS_INLINED_OSCALLS */
+
+#include "ace/post.h"
+#endif /* ACE_OS_TLI_H */
diff --git a/ace/OS/OS_TLI.inl b/ace/OS/OS_TLI.inl
new file mode 100644
index 00000000000..7fe5fa1b80a
--- /dev/null
+++ b/ace/OS/OS_TLI.inl
@@ -0,0 +1,343 @@
+/* -*- C++ -*- */
+// $Id$
+
+ACE_INLINE int
+ACE_OS_TLI::t_accept (ACE_HANDLE handle,
+ ACE_HANDLE reshandle,
+ struct t_call *call)
+{
+#if defined (ACE_HAS_TLI)
+ ACE_OSCALL_RETURN (::t_accept (handle, reshandle, call), int, -1);
+#else
+ ACE_UNUSED_ARG (call);
+ ACE_UNUSED_ARG (reshandle);
+ ACE_UNUSED_ARG (handle);
+
+ ACE_NOTSUP_RETURN (-1);
+#endif /* ACE_HAS_TLI */
+}
+
+ACE_INLINE char *
+ACE_OS_TLI::t_alloc (ACE_HANDLE handle, int struct_type,
+ int fields)
+{
+#if defined (ACE_HAS_TLI)
+ ACE_OSCALL_RETURN (::t_alloc (handle, struct_type, fields),
+ char *, 0);
+#else
+ ACE_UNUSED_ARG (fields);
+ ACE_UNUSED_ARG (struct_type);
+ ACE_UNUSED_ARG (handle);
+
+ ACE_NOTSUP_RETURN (0);
+#endif /* ACE_HAS_TLI */
+}
+
+ACE_INLINE int
+ACE_OS_TLI::t_bind (ACE_HANDLE handle, struct t_bind *req,
+ struct t_bind *ret)
+{
+#if defined (ACE_HAS_TLI)
+ ACE_OSCALL_RETURN (::t_bind (handle, req, ret), int, -1);
+#else
+ ACE_UNUSED_ARG (ret);
+ ACE_UNUSED_ARG (req);
+ ACE_UNUSED_ARG (handle);
+
+ ACE_NOTSUP_RETURN (-1);
+#endif /* ACE_HAS_TLI */
+}
+
+ACE_INLINE int
+ACE_OS_TLI::t_close (ACE_HANDLE handle)
+{
+#if defined (ACE_HAS_TLI)
+ ACE_OSCALL_RETURN (::t_close (handle), int, -1);
+#else
+ ACE_UNUSED_ARG (handle);
+
+ ACE_NOTSUP_RETURN (-1);
+#endif /* ACE_HAS_TLI */
+}
+
+ACE_INLINE int
+ACE_OS_TLI::t_connect(ACE_HANDLE fildes,
+ struct t_call *sndcall,
+ struct t_call *rcvcall)
+{
+#if defined (ACE_HAS_TLI)
+ ACE_OSCALL_RETURN (::t_connect (fildes, sndcall, rcvcall), int, -1);
+#else
+ ACE_UNUSED_ARG (fildes);
+ ACE_UNUSED_ARG (sndcall);
+ ACE_UNUSED_ARG (rcvcall);
+
+ ACE_NOTSUP_RETURN (-1);
+#endif /* ACE_HAS_TLI */
+}
+
+ACE_INLINE void
+ACE_OS_TLI::t_error (const char *errmsg)
+{
+#if defined (ACE_HAS_TLI)
+#if defined (ACE_HAS_BROKEN_T_ERROR)
+ ::t_error (ACE_const_cast (char *, errmsg));
+#else
+ ::t_error (errmsg);
+#endif /* ACE_HAS_BROKEN_T_ERROR */
+#else
+ ACE_UNUSED_ARG (errmsg);
+#endif /* ACE_HAS_TLI */
+}
+
+ACE_INLINE int
+ACE_OS_TLI::t_free (char *ptr, int struct_type)
+{
+#if defined (ACE_HAS_TLI)
+ if (ptr == 0)
+ return 0;
+ ACE_OSCALL_RETURN (::t_free (ptr, struct_type), int, -1);
+#else
+ ACE_UNUSED_ARG (struct_type);
+ ACE_UNUSED_ARG (ptr);
+
+ ACE_NOTSUP_RETURN (-1);
+#endif /* ACE_HAS_TLI */
+}
+
+ACE_INLINE int
+ACE_OS_TLI::t_getinfo (ACE_HANDLE handle, struct t_info *info)
+{
+#if defined (ACE_HAS_TLI)
+ ACE_OSCALL_RETURN (::t_getinfo (handle, info), int, -1);
+#else
+ ACE_UNUSED_ARG (info);
+ ACE_UNUSED_ARG (handle);
+
+ ACE_NOTSUP_RETURN (-1);
+#endif /* ACE_HAS_TLI */
+}
+
+ACE_INLINE int
+ACE_OS_TLI::t_getname (ACE_HANDLE handle,
+ struct netbuf *namep,
+ int type)
+{
+#if defined (ACE_HAS_SVR4_TLI)
+ ACE_OSCALL_RETURN (::t_getname (handle, namep, type), int, -1);
+#else
+ ACE_UNUSED_ARG (handle);
+ ACE_UNUSED_ARG (namep);
+ ACE_UNUSED_ARG (type);
+
+ ACE_NOTSUP_RETURN (-1);
+#endif /* ACE_HAS_SVR4_TLI */
+}
+
+ACE_INLINE int
+ACE_OS_TLI::t_getstate (ACE_HANDLE handle)
+{
+#if defined (ACE_HAS_TLI)
+ ACE_OSCALL_RETURN (::t_getstate (handle), int, -1);
+#else
+ ACE_UNUSED_ARG (handle);
+
+ ACE_NOTSUP_RETURN (-1);
+#endif /* ACE_HAS_TLI */
+}
+
+ACE_INLINE int
+ACE_OS_TLI::t_listen (ACE_HANDLE handle, struct t_call *call)
+{
+#if defined (ACE_HAS_TLI)
+ ACE_OSCALL_RETURN (::t_listen (handle, call), int, -1);
+#else
+ ACE_UNUSED_ARG (handle);
+ ACE_UNUSED_ARG (call);
+
+ ACE_NOTSUP_RETURN (-1);
+#endif /* ACE_HAS_TLI */
+}
+
+ACE_INLINE int
+ACE_OS_TLI::t_look (ACE_HANDLE handle)
+{
+#if defined (ACE_HAS_TLI)
+ ACE_OSCALL_RETURN (::t_look (handle), int, -1);
+#else
+ ACE_UNUSED_ARG (handle);
+
+ ACE_NOTSUP_RETURN (-1);
+#endif /* ACE_HAS_TLI */
+}
+
+ACE_INLINE ACE_HANDLE
+ACE_OS_TLI::t_open (char *path, int oflag, struct t_info *info)
+{
+#if defined (ACE_HAS_TLI)
+ ACE_OSCALL_RETURN (::t_open (path, oflag, info), ACE_HANDLE, ACE_INVALID_HANDLE);
+#else
+ ACE_UNUSED_ARG (path);
+ ACE_UNUSED_ARG (oflag);
+ ACE_UNUSED_ARG (info);
+
+ ACE_NOTSUP_RETURN (ACE_INVALID_HANDLE);
+#endif /* ACE_HAS_TLI */
+}
+
+ACE_INLINE int
+ACE_OS_TLI::t_optmgmt (ACE_HANDLE handle,
+ struct t_optmgmt *req,
+ struct t_optmgmt *ret)
+{
+#if defined (ACE_HAS_TLI)
+ ACE_OSCALL_RETURN (::t_optmgmt (handle, req, ret), int, -1);
+#else
+ ACE_UNUSED_ARG (handle);
+ ACE_UNUSED_ARG (req);
+ ACE_UNUSED_ARG (ret);
+
+ ACE_NOTSUP_RETURN (-1);
+#endif /* ACE_HAS_TLI */
+}
+
+ACE_INLINE int
+ACE_OS_TLI::t_rcv (ACE_HANDLE handle,
+ char *buf,
+ unsigned int nbytes,
+ int *flags)
+{
+#if defined (ACE_HAS_TLI)
+ ACE_OSCALL_RETURN (::t_rcv (handle, buf, nbytes, flags),
+ int, -1);
+#else
+ ACE_UNUSED_ARG (handle);
+ ACE_UNUSED_ARG (buf);
+ ACE_UNUSED_ARG (nbytes);
+ ACE_UNUSED_ARG (flags);
+
+ ACE_NOTSUP_RETURN (-1);
+#endif /* ACE_HAS_TLI */
+}
+
+ACE_INLINE int
+ACE_OS_TLI::t_rcvdis (ACE_HANDLE handle, struct t_discon *discon)
+{
+#if defined (ACE_HAS_TLI)
+ ACE_OSCALL_RETURN (::t_rcvdis (handle, discon), int, -1);
+#else
+ ACE_UNUSED_ARG (handle);
+ ACE_UNUSED_ARG (discon);
+
+ ACE_NOTSUP_RETURN (-1);
+#endif /* ACE_HAS_TLI */
+}
+
+ACE_INLINE int
+ACE_OS_TLI::t_rcvrel (ACE_HANDLE handle)
+{
+#if defined (ACE_HAS_TLI)
+ ACE_OSCALL_RETURN (::t_rcvrel (handle), int, -1);
+#else
+ ACE_UNUSED_ARG (handle);
+
+ ACE_NOTSUP_RETURN (-1);
+#endif /* ACE_HAS_TLI */
+}
+
+ACE_INLINE int
+ACE_OS_TLI::t_rcvudata (ACE_HANDLE handle,
+ struct t_unitdata *unitdata,
+ int *flags)
+{
+#if defined (ACE_HAS_TLI)
+ ACE_OSCALL_RETURN (::t_rcvudata (handle, unitdata, flags),
+ int, -1);
+#else
+ ACE_UNUSED_ARG (handle);
+ ACE_UNUSED_ARG (unitdata);
+ ACE_UNUSED_ARG (flags);
+
+ ACE_NOTSUP_RETURN (-1);
+#endif /* ACE_HAS_TLI */
+}
+
+ACE_INLINE int
+ACE_OS_TLI::t_rcvuderr (ACE_HANDLE handle, struct t_uderr *uderr)
+{
+#if defined (ACE_HAS_TLI)
+ ACE_OSCALL_RETURN (::t_rcvuderr (handle, uderr), int, -1);
+#else
+ ACE_UNUSED_ARG (handle);
+ ACE_UNUSED_ARG (uderr);
+
+ ACE_NOTSUP_RETURN (-1);
+#endif /* ACE_HAS_TLI */
+}
+
+ACE_INLINE int
+ACE_OS_TLI::t_snd (ACE_HANDLE handle,
+ const char *buf,
+ unsigned int nbytes,
+ int flags)
+{
+#if defined (ACE_HAS_TLI)
+ ACE_OSCALL_RETURN (::t_snd (handle, (char *) buf, nbytes, flags), int, -1);
+#else
+ ACE_UNUSED_ARG (handle);
+ ACE_UNUSED_ARG (buf);
+ ACE_UNUSED_ARG (nbytes);
+ ACE_UNUSED_ARG (flags);
+
+ ACE_NOTSUP_RETURN (-1);
+#endif /* ACE_HAS_TLI */
+}
+
+ACE_INLINE int
+ACE_OS_TLI::t_snddis (ACE_HANDLE handle, struct t_call *call)
+{
+#if defined (ACE_HAS_TLI)
+ ACE_OSCALL_RETURN (::t_snddis (handle, call), int, -1);
+#else
+ ACE_UNUSED_ARG (handle);
+ ACE_UNUSED_ARG (call);
+
+ ACE_NOTSUP_RETURN (-1);
+#endif /* ACE_HAS_TLI */
+}
+
+ACE_INLINE int
+ACE_OS_TLI::t_sndrel (ACE_HANDLE handle)
+{
+#if defined (ACE_HAS_TLI)
+ ACE_OSCALL_RETURN (::t_sndrel (handle), int, -1);
+#else
+ ACE_UNUSED_ARG (handle);
+
+ ACE_NOTSUP_RETURN (-1);
+#endif /* ACE_HAS_TLI */
+}
+
+ACE_INLINE int
+ACE_OS_TLI::t_sync (ACE_HANDLE handle)
+{
+#if defined (ACE_HAS_TLI)
+ ACE_OSCALL_RETURN (::t_sync (handle), int, -1);
+#else
+ ACE_UNUSED_ARG (handle);
+
+ ACE_NOTSUP_RETURN (-1);
+#endif /* ACE_HAS_TLI */
+}
+
+ACE_INLINE int
+ACE_OS_TLI::t_unbind (ACE_HANDLE handle)
+{
+#if defined (ACE_HAS_TLI)
+ ACE_OSCALL_RETURN (::t_unbind (handle), int, -1);
+#else
+ ACE_UNUSED_ARG (handle);
+
+ ACE_NOTSUP_RETURN (-1);
+#endif /* ACE_HAS_TLI */
+}
diff --git a/ace/OS/OS_Thread_Adapter.cpp b/ace/OS/OS_Thread_Adapter.cpp
new file mode 100644
index 00000000000..82ff206147c
--- /dev/null
+++ b/ace/OS/OS_Thread_Adapter.cpp
@@ -0,0 +1,178 @@
+// $Id$
+
+#include "OS_Thread_Adapter.h"
+#include "Thread_Hook.h"
+#include "OS.h"
+
+ACE_RCSID(ace, OS_Thread_Adapter, "$Id$")
+
+#if !defined (ACE_HAS_INLINED_OSCALLS)
+# include "OS_Thread_Adapter.inl"
+#endif /* ACE_HAS_INLINED_OS_CALLS */
+
+ACE_OS_Thread_Adapter::ACE_OS_Thread_Adapter (
+ ACE_THR_FUNC user_func
+ , void *arg
+ , ACE_THR_C_FUNC entry_point
+# if defined (ACE_HAS_WIN32_STRUCTURAL_EXCEPTIONS)
+ , ACE_SEH_EXCEPT_HANDLER selector
+ , ACE_SEH_EXCEPT_HANDLER handler
+# endif /* ACE_HAS_WIN32_STRUCTURAL_EXCEPTIONS */
+ )
+ : ACE_Base_Thread_Adapter (user_func, arg, entry_point
+# if defined (ACE_HAS_WIN32_STRUCTURAL_EXCEPTIONS)
+ , 0
+ , selector
+ , handler
+# endif /* ACE_HAS_WIN32_STRUCTURAL_EXCEPTIONS */
+ )
+{
+}
+
+ACE_OS_Thread_Adapter::~ACE_OS_Thread_Adapter (void)
+{
+}
+
+void *
+ACE_OS_Thread_Adapter::invoke (void)
+{
+ // Inherit the logging features if the parent thread has an
+ // ACE_Log_Msg instance in thread-specific storage.
+ this->inherit_log_msg ();
+
+ // Extract the arguments.
+ ACE_THR_FUNC_INTERNAL func =
+ ACE_reinterpret_cast (ACE_THR_FUNC_INTERNAL, this->user_func_);
+ void *arg = this->arg_;
+
+ // Delete ourselves since we don't need <this> anymore. Make sure
+ // not to access <this> anywhere below this point.
+ delete this;
+
+#if defined (ACE_NEEDS_LWP_PRIO_SET)
+ // On SunOS, the LWP priority needs to be set in order to get
+ // preemption when running in the RT class. This is the ACE way to
+ // do that . . .
+ ACE_hthread_t thr_handle;
+ ACE_OS::thr_self (thr_handle);
+ int prio;
+
+ // thr_getprio () on the current thread should never fail.
+ ACE_OS::thr_getprio (thr_handle, prio);
+
+ // ACE_OS::thr_setprio () has the special logic to set the LWP priority,
+ // if running in the RT class.
+ ACE_OS::thr_setprio (prio);
+
+#endif /* ACE_NEEDS_LWP_PRIO_SET */
+
+ void *status = 0;
+
+ ACE_SEH_TRY
+ {
+ ACE_SEH_TRY
+ {
+ ACE_Thread_Hook *hook =
+ ACE_OS_Object_Manager::thread_hook ();
+
+ if (hook)
+ // Invoke the start hook to give the user a chance to
+ // perform some initialization processing before the
+ // <func> is invoked.
+ status = hook->start (ACE_reinterpret_cast (ACE_THR_FUNC, func),
+ arg);
+ else
+ {
+ // Call thread entry point.
+#if defined (ACE_PSOS)
+ (*func) (arg);
+#else /* ! ACE_PSOS */
+ status = ACE_reinterpret_cast (void *, (*func) (arg));
+#endif /* ACE_PSOS */
+ }
+#if defined (ACE_PSOS)
+ // pSOS task functions do not return a value.
+ status = 0;
+#endif /* ACE_PSOS */
+ }
+
+#if defined (ACE_HAS_WIN32_STRUCTURAL_EXCEPTIONS)
+ ACE_SEH_EXCEPT (ACE_OS_Object_Manager::seh_except_selector ()(
+ (void *) GetExceptionInformation ()))
+ {
+ ACE_OS_Object_Manager::seh_except_handler ()(0);
+ }
+#endif /* ACE_HAS_WIN32_STRUCTURAL_EXCEPTIONS */
+ }
+
+ ACE_SEH_FINALLY
+ {
+ // If we changed this to 1, change the respective if in
+ // Task::svc_run to 0.
+#if 0
+ // Call the <Task->close> hook.
+ if (func == ACE_reinterpret_cast (ACE_THR_FUNC_INTERNAL,
+ ACE_Task_Base::svc_run))
+ {
+ ACE_Task_Base *task_ptr = (ACE_Task_Base *) arg;
+ ACE_Thread_Manager *thr_mgr_ptr = task_ptr->thr_mgr ();
+
+ // This calls the Task->close () hook.
+ task_ptr->cleanup (task_ptr, 0);
+
+ // This prevents a second invocation of the cleanup code
+ // (called later by <ACE_Thread_Manager::exit>.
+ thr_mgr_ptr->at_exit (task_ptr, 0, 0);
+ }
+#endif /* 0 */
+
+#if defined (ACE_WIN32) || defined (ACE_HAS_TSS_EMULATION)
+ // Call TSS destructors.
+ ACE_OS::cleanup_tss (0 /* not main thread */);
+
+# if defined (ACE_WIN32)
+ // Exit the thread. Allow CWinThread-destructor to be invoked
+ // from AfxEndThread. _endthreadex will be called from
+ // AfxEndThread so don't exit the thread now if we are running
+ // an MFC thread.
+# if defined (ACE_HAS_MFC) && (ACE_HAS_MFC != 0)
+ // Not spawned by ACE_Thread_Manager, use the old buggy
+ // version. You should seriously consider using
+ // ACE_Thread_Manager to spawn threads. The following code
+ // is know to cause some problem.
+ CWinThread *pThread = ::AfxGetThread ();
+
+ if (!pThread || pThread->m_nThreadID != ACE_OS::thr_self ())
+ ACE_ENDTHREADEX (status);
+ else
+ ::AfxEndThread ((DWORD)status);
+# else
+ ACE_ENDTHREADEX (status);
+# endif /* ACE_HAS_MFC && ACE_HAS_MFS != 0*/
+# endif /* ACE_WIN32 */
+#endif /* ACE_WIN32 || ACE_HAS_TSS_EMULATION */
+
+#if defined (ACE_PSOS)
+ // This sequence of calls is documented by ISI as the proper way to
+ // clean up a pSOS task. They affect different components, so only
+ // try the ones for components that are built with ACE.
+# if defined (SC_PREPC) && (SC_PREPC == YES)
+ ::fclose (0); // Return pREPC+ resources
+# endif /* SC_PREPC */
+# if defined (SC_PHILE) && (SC_PHILE == YES)
+ ::close_f (0); // Return pHILE+ resources
+# endif /* SC_PHILE */
+# if defined (SC_PNA) && (SC_PNA == YES)
+ ::close (0); // Return pNA+ resources
+# endif /* SC_PNA */
+# if defined (SC_SC_PREPC) && (SC_PREPC == YES)
+ ::free (-1); // Return pREPC+ memory
+# endif /* SC_PREPC */
+ status = ::t_delete (0); // Suicide - only returns on error
+#endif /* ACE_PSOS */
+
+ return status;
+ }
+
+ ACE_NOTREACHED (return status);
+}
diff --git a/ace/OS/OS_Thread_Adapter.h b/ace/OS/OS_Thread_Adapter.h
new file mode 100644
index 00000000000..9132556c18c
--- /dev/null
+++ b/ace/OS/OS_Thread_Adapter.h
@@ -0,0 +1,78 @@
+
+//=============================================================================
+/**
+ * @file Thread_Adapter.h
+ *
+ * $Id$
+ *
+ * @author Carlos O'Ryan <coryan@uci.edu>
+ */
+//=============================================================================
+
+#ifndef ACE_OS_THREAD_ADAPTER_H
+#define ACE_OS_THREAD_ADAPTER_H
+#include "ace/pre.h"
+
+#include "Base_Thread_Adapter.h"
+
+#if !defined (ACE_LACKS_PRAGMA_ONCE)
+# pragma once
+#endif /* ACE_LACKS_PRAGMA_ONCE */
+
+#include "OS_Export.h"
+
+/**
+ * @class ACE_OS_Thread_Adapter
+ *
+ * @brief Converts a C++ function into a function <ace_thread_adapter>
+ * function that can be called from a thread creation routine
+ * (e.g., <pthread_create> or <_beginthreadex>) that expects an
+ * extern "C" entry point. This class also makes it possible to
+ * transparently provide hooks to register a thread with an
+ * <ACE_Thread_Manager>.
+ *
+ * This class is used in <ACE_OS::thr_create>. In general, the
+ * thread that creates an object of this class is different from
+ * the thread that calls <invoke> on this object. Therefore,
+ * the <invoke> method is responsible for deleting itself.
+ */
+class ACE_OS_Export ACE_OS_Thread_Adapter : public ACE_Base_Thread_Adapter
+{
+public:
+ ACE_OS_Thread_Adapter (ACE_THR_FUNC user_func,
+ void *arg,
+ ACE_THR_C_FUNC entry_point = (ACE_THR_C_FUNC) ace_thread_adapter
+# if defined (ACE_HAS_WIN32_STRUCTURAL_EXCEPTIONS)
+ , ACE_SEH_EXCEPT_HANDLER selector = 0
+ , ACE_SEH_EXCEPT_HANDLER handler = 0
+# endif /* ACE_HAS_WIN32_STRUCTURAL_EXCEPTIONS */
+ /// Constructor.
+ );
+
+ /**
+ * Execute the <user_func_> with the <arg>. This function deletes
+ * <this>, thereby rendering the object useless after the call
+ * returns.
+ */
+ virtual void *invoke (void);
+
+private:
+ /// Ensure that this object must be allocated on the heap.
+ ~ACE_OS_Thread_Adapter (void);
+
+private:
+ /// Friend declaration to avoid compiler warning: only defines a private
+ /// destructor and has no friends.
+ friend class ACE_Thread_Adapter_Has_Private_Destructor;
+};
+
+# if defined (ACE_HAS_INLINED_OSCALLS)
+# if defined (ACE_INLINE)
+# undef ACE_INLINE
+# endif /* ACE_INLINE */
+# define ACE_INLINE inline
+# include "OS_Thread_Adapter.inl"
+# endif /* ACE_HAS_INLINED_OSCALLS */
+
+#include "ace/post.h"
+#endif /* ACE_THREAD_ADAPTER_H */
diff --git a/ace/OS/OS_Thread_Adapter.inl b/ace/OS/OS_Thread_Adapter.inl
new file mode 100644
index 00000000000..cfa1da318d3
--- /dev/null
+++ b/ace/OS/OS_Thread_Adapter.inl
@@ -0,0 +1 @@
+// $Id$
diff --git a/ace/OS/Sched_Params.cpp b/ace/OS/Sched_Params.cpp
new file mode 100644
index 00000000000..77c472faa54
--- /dev/null
+++ b/ace/OS/Sched_Params.cpp
@@ -0,0 +1,321 @@
+// $Id$
+
+// ============================================================================
+//
+// = LIBRARY
+// ACE
+//
+// = FILENAME
+// Sched_Params.cpp
+//
+// = CREATION DATE
+// 28 January 1997
+//
+// = AUTHOR
+// David Levine
+//
+// ============================================================================
+
+#include "Sched_Params.h"
+
+#if !defined (__ACE_INLINE__)
+#include "Sched_Params.i"
+#endif /* __ACE_INLINE__ */
+
+ACE_RCSID(ace, Sched_Params, "$Id$")
+
+int
+ACE_Sched_Params::priority_min (const Policy policy,
+ const int scope)
+{
+#if defined (ACE_HAS_PRIOCNTL) && defined (ACE_HAS_STHREADS)
+ ACE_UNUSED_ARG (scope);
+
+ // Assume that ACE_SCHED_OTHER indicates TS class, and that other
+ // policies indicate RT class.
+
+ // Call ACE_OS::priority_control only for processes (lightweight
+ // or otherwise). Calling ACE_OS::priority_control for thread
+ // priorities gives incorrect results.
+ if (scope == ACE_SCOPE_PROCESS || scope == ACE_SCOPE_LWP)
+ {
+ if (policy == ACE_SCHED_OTHER)
+ {
+ // Get the priority class ID and attributes.
+ pcinfo_t pcinfo;
+ // The following is just to avoid Purify warnings about unitialized
+ // memory reads.
+ ACE_OS::memset (&pcinfo, 0, sizeof pcinfo);
+ ACE_OS::strcpy (pcinfo.pc_clname, "TS");
+
+ if (ACE_OS::priority_control (P_ALL /* ignored */,
+ P_MYID /* ignored */,
+ PC_GETCID,
+ (char *) &pcinfo) == -1)
+ // Just hope that priority range wasn't configured from -1
+ // .. 1
+ return -1;
+
+ // OK, now we've got the class ID in pcinfo.pc_cid. In
+ // addition, the maximum configured time-share priority is in
+ // ((tsinfo_t *) pcinfo.pc_clinfo)->ts_maxupri. The minimum
+ // priority is just the negative of that.
+
+ return -((tsinfo_t *) pcinfo.pc_clinfo)->ts_maxupri;
+ }
+ else
+ return 0;
+ }
+ else
+ {
+ // Here we handle the case for ACE_SCOPE_THREAD. Calling
+ // ACE_OS::priority_control for thread scope gives incorrect
+ // results.
+ switch (policy)
+ {
+ case ACE_SCHED_FIFO:
+ return ACE_THR_PRI_FIFO_MIN;
+ case ACE_SCHED_RR:
+ return ACE_THR_PRI_RR_MIN;
+ case ACE_SCHED_OTHER:
+ default:
+ return ACE_THR_PRI_OTHER_MIN;
+ }
+ }
+#elif defined (ACE_HAS_PTHREADS) && !defined(ACE_LACKS_SETSCHED)
+
+ switch (scope)
+ {
+ case ACE_SCOPE_THREAD:
+ switch (policy)
+ {
+ case ACE_SCHED_FIFO:
+ return ACE_THR_PRI_FIFO_MIN;
+ case ACE_SCHED_RR:
+ return ACE_THR_PRI_RR_MIN;
+#if !defined (CHORUS) // SCHED_OTHRE and SCHED_RR have same value
+ case ACE_SCHED_OTHER:
+#endif /* CHORUS */
+ default:
+ return ACE_THR_PRI_OTHER_MIN;
+ }
+
+ case ACE_SCOPE_PROCESS:
+ default:
+ switch (policy)
+ {
+ case ACE_SCHED_FIFO:
+ return ACE_PROC_PRI_FIFO_MIN;
+ case ACE_SCHED_RR:
+ return ACE_PROC_PRI_RR_MIN;
+#if !defined (CHORUS) // SCHED_OTHRE and SCHED_RR have same value
+ case ACE_SCHED_OTHER:
+#endif /* CHORUS */
+ default:
+ return ACE_PROC_PRI_OTHER_MIN;
+ }
+ }
+
+#elif defined (ACE_HAS_WTHREADS)
+ ACE_UNUSED_ARG (policy);
+ ACE_UNUSED_ARG (scope);
+ return THREAD_PRIORITY_IDLE;
+#elif defined (VXWORKS)
+ ACE_UNUSED_ARG (policy);
+ ACE_UNUSED_ARG (scope);
+ return 255;
+#else
+ ACE_UNUSED_ARG (policy);
+ ACE_UNUSED_ARG (scope);
+ ACE_NOTSUP_RETURN (-1);
+#endif /* ACE_HAS_PRIOCNTL && defined (ACE_HAS_STHREADS) */
+}
+
+int
+ACE_Sched_Params::priority_max (const Policy policy,
+ const int scope)
+{
+#if defined (ACE_HAS_PRIOCNTL) && defined (ACE_HAS_STHREADS)
+ ACE_UNUSED_ARG (scope);
+
+ // Call ACE_OS::priority_control only for processes (lightweight
+ // or otherwise). Calling ACE_OS::priority_control for thread
+ // priorities gives incorrect results.
+ if (scope == ACE_SCOPE_PROCESS || scope == ACE_SCOPE_LWP)
+ {
+ // Assume that ACE_SCHED_OTHER indicates TS class, and that other
+ // policies indicate RT class.
+
+ // Get the priority class ID and attributes.
+ pcinfo_t pcinfo;
+ // The following is just to avoid Purify warnings about unitialized
+ // memory reads.
+ ACE_OS::memset (&pcinfo, 0, sizeof pcinfo);
+ ACE_OS::strcpy (pcinfo.pc_clname,
+ policy == ACE_SCHED_OTHER ? "TS" : "RT");
+
+ if (ACE_OS::priority_control (P_ALL /* ignored */,
+ P_MYID /* ignored */,
+ PC_GETCID,
+ (char *) &pcinfo) == -1)
+ return -1;
+
+ // OK, now we've got the class ID in pcinfo.pc_cid. In addition,
+ // the maximum configured real-time priority is in ((rtinfo_t *)
+ // pcinfo.pc_clinfo)->rt_maxpri, or similarly for the TS class.
+
+ return policy == ACE_SCHED_OTHER
+ ? ((tsinfo_t *) pcinfo.pc_clinfo)->ts_maxupri
+ : ((rtinfo_t *) pcinfo.pc_clinfo)->rt_maxpri;
+ }
+ else
+ {
+ // Here we handle the case for ACE_SCOPE_THREAD. Calling
+ // ACE_OS::priority_control for thread scope gives incorrect
+ // results.
+ switch (policy)
+ {
+ case ACE_SCHED_FIFO:
+ return ACE_THR_PRI_FIFO_MAX;
+ case ACE_SCHED_RR:
+ return ACE_THR_PRI_RR_MAX;
+ case ACE_SCHED_OTHER:
+ default:
+ return ACE_THR_PRI_OTHER_MAX;
+ }
+ }
+#elif defined(ACE_HAS_PTHREADS) && !defined(ACE_LACKS_SETSCHED)
+
+ switch (scope)
+ {
+ case ACE_SCOPE_THREAD:
+ switch (policy)
+ {
+ case ACE_SCHED_FIFO:
+ return ACE_THR_PRI_FIFO_MAX;
+ case ACE_SCHED_RR:
+ return ACE_THR_PRI_RR_MAX;
+#if !defined (CHORUS) // SCHED_OTHRE and SCHED_RR have same value
+ case ACE_SCHED_OTHER:
+#endif /* CHORUS */
+ default:
+ return ACE_THR_PRI_OTHER_MAX;
+ }
+
+ case ACE_SCOPE_PROCESS:
+ default:
+ switch (policy)
+ {
+ case ACE_SCHED_FIFO:
+ return ACE_PROC_PRI_FIFO_MAX;
+ case ACE_SCHED_RR:
+ return ACE_PROC_PRI_RR_MAX;
+#if !defined (CHORUS) // SCHED_OTHRE and SCHED_RR have same value
+ case ACE_SCHED_OTHER:
+#endif /* CHORUS */
+ default:
+ return ACE_PROC_PRI_OTHER_MAX;
+ }
+ }
+
+#elif defined (ACE_HAS_WTHREADS)
+ ACE_UNUSED_ARG (policy);
+ ACE_UNUSED_ARG (scope);
+ return THREAD_PRIORITY_TIME_CRITICAL;
+#elif defined (VXWORKS)
+ ACE_UNUSED_ARG (policy);
+ ACE_UNUSED_ARG (scope);
+ return 0;
+#else
+ ACE_UNUSED_ARG (policy);
+ ACE_UNUSED_ARG (scope);
+ ACE_NOTSUP_RETURN (-1);
+#endif /* ACE_HAS_PRIOCNTL && defined (ACE_HAS_STHREADS) */
+}
+
+int
+ACE_Sched_Params::next_priority (const Policy policy,
+ const int priority,
+ const int scope)
+{
+#if defined (VXWORKS)
+ return priority > priority_max (policy, scope)
+ ? priority - 1
+ : priority_max (policy, scope);
+#elif defined (ACE_HAS_WTHREADS)
+ ACE_UNUSED_ARG (policy);
+ ACE_UNUSED_ARG (scope);
+ switch (priority)
+ {
+ case THREAD_PRIORITY_IDLE:
+ return THREAD_PRIORITY_LOWEST;
+ case THREAD_PRIORITY_LOWEST:
+ return THREAD_PRIORITY_BELOW_NORMAL;
+ case THREAD_PRIORITY_BELOW_NORMAL:
+ return THREAD_PRIORITY_NORMAL;
+ case THREAD_PRIORITY_NORMAL:
+ return THREAD_PRIORITY_ABOVE_NORMAL;
+ case THREAD_PRIORITY_ABOVE_NORMAL:
+ return THREAD_PRIORITY_HIGHEST;
+ case THREAD_PRIORITY_HIGHEST:
+ return THREAD_PRIORITY_TIME_CRITICAL;
+ case THREAD_PRIORITY_TIME_CRITICAL:
+ return THREAD_PRIORITY_TIME_CRITICAL;
+ default:
+ return priority; // unknown priority: should never get here
+ }
+#elif defined(ACE_HAS_THREADS) && !defined(ACE_LACKS_SETSCHED)
+ // including STHREADS, and PTHREADS
+ const int max = priority_max (policy, scope);
+ return priority < max ? priority + 1 : max;
+#else
+ ACE_UNUSED_ARG (policy);
+ ACE_UNUSED_ARG (scope);
+ ACE_UNUSED_ARG (priority);
+ ACE_NOTSUP_RETURN (-1);
+#endif /* ACE_HAS_THREADS */
+}
+
+int
+ACE_Sched_Params::previous_priority (const Policy policy,
+ const int priority,
+ const int scope)
+{
+#if defined (VXWORKS)
+ return priority < priority_min (policy, scope)
+ ? priority + 1
+ : priority_min (policy, scope);
+#elif defined (ACE_HAS_WTHREADS)
+ ACE_UNUSED_ARG (policy);
+ ACE_UNUSED_ARG (scope);
+ switch (priority)
+ {
+ case THREAD_PRIORITY_IDLE:
+ return THREAD_PRIORITY_IDLE;
+ case THREAD_PRIORITY_LOWEST:
+ return THREAD_PRIORITY_IDLE;
+ case THREAD_PRIORITY_BELOW_NORMAL:
+ return THREAD_PRIORITY_LOWEST;
+ case THREAD_PRIORITY_NORMAL:
+ return THREAD_PRIORITY_BELOW_NORMAL;
+ case THREAD_PRIORITY_ABOVE_NORMAL:
+ return THREAD_PRIORITY_NORMAL;
+ case THREAD_PRIORITY_HIGHEST:
+ return THREAD_PRIORITY_ABOVE_NORMAL;
+ case THREAD_PRIORITY_TIME_CRITICAL:
+ return THREAD_PRIORITY_HIGHEST;
+ default:
+ return priority; // unknown priority: should never get here
+ }
+#elif defined (ACE_HAS_THREADS) && !defined(ACE_LACKS_SETSCHED)
+ // including STHREADS and PTHREADS
+ const int min = priority_min (policy, scope);
+
+ return priority > min ? priority - 1 : min;
+#else
+ ACE_UNUSED_ARG (policy);
+ ACE_UNUSED_ARG (scope);
+ ACE_UNUSED_ARG (priority);
+ ACE_NOTSUP_RETURN (-1);
+#endif /* ACE_HAS_THREADS */
+}
diff --git a/ace/OS/Sched_Params.h b/ace/OS/Sched_Params.h
new file mode 100644
index 00000000000..884c7e088d2
--- /dev/null
+++ b/ace/OS/Sched_Params.h
@@ -0,0 +1,225 @@
+/* -*- C++ -*- */
+
+//=============================================================================
+/**
+ * @file Sched_Params.h
+ *
+ * $Id$
+ *
+ * @author David Levine <levine@cs.wustl.edu>
+ * @author Carlos O'Ryan <coryan@uci.edu>
+ */
+//=============================================================================
+
+#ifndef ACE_SCHED_PARAMS_H
+#define ACE_SCHED_PARAMS_H
+#include "ace/pre.h"
+
+#include "OS.h"
+
+#if !defined (ACE_LACKS_PRAGMA_ONCE)
+# pragma once
+#endif /* ACE_LACKS_PRAGMA_ONCE */
+
+/**
+ * @class ACE_Sched_Params
+ *
+ * @brief Container for scheduling-related parameters.
+ *
+ * ACE_Sched_Params are passed via <ACE_OS::sched_params> to the
+ * OS to specify scheduling parameters. These parameters include
+ * scheduling policy, such as FIFO (ACE_SCHED_FIFO), round-robin
+ * (ACE_SCHED_RR), or an implementation-defined "OTHER"
+ * (ACE_SCHED_OTHER), to which many systems default; priority;
+ * and a time-slice quantum for round-robin scheduling. A
+ * "scope" parameter specifies whether the ACE_Sched_Params
+ * applies to the current process, current lightweight process
+ * (LWP) (on Solaris), or current thread. Please see the "NOTE"
+ * below about not all combinations of parameters being legal on
+ * a particular platform.
+ * For the case of thread priorities, it is intended that
+ * <ACE_OS::sched_params> usually be called from <main> before
+ * any threads have been spawned. If spawned threads inherit
+ * their parent's priority (I think that's the default behavior
+ * for all of our platforms), then this sets the default base
+ * priority. Individual thread priorities can be adjusted as
+ * usual using <ACE_OS::thr_prio> or via the ACE_Thread
+ * interface. See the parameter descriptions in the private:
+ * section below.
+ * NOTE: this class does not do any checking of parameters. It
+ * is just a container class. If it is constructed with values
+ * that are not supported on a platform, the call to
+ * <ACE_OS::sched_params> will fail by returning -1 with EINVAL
+ * (available through <ACE_OS::last_error>).
+ */
+class ACE_Export ACE_Sched_Params
+{
+ // NOTE: Solaris 2.5.x threads in the RT class must set the
+ // priority of their LWP. The only way to do that through ACE is
+ // for the RT thread itself to call <ACE_OS::thr_setprio> with
+ // it's own priority.
+
+ // OS Scheduling parameters are complicated and often confusing.
+ // Many thanks to Thilo Kielmann
+ // <kielmann@informatik.uni-siegen.de> for his careful review of
+ // this class design, thoughtful comments, and assistance with
+ // implementation, especially for PTHREADS platforms. Please
+ // send any comments or corrections to the ACE developers.
+public:
+ typedef int Policy;
+
+ // = Initialization and termination methods.
+ /// Constructor.
+ ACE_Sched_Params (const Policy policy,
+ const ACE_Sched_Priority priority,
+ const int scope = ACE_SCOPE_THREAD,
+ const ACE_Time_Value &quantum = ACE_Time_Value::zero);
+
+ /// Termination.
+ ~ACE_Sched_Params (void);
+
+ // = Get/Set methods:
+
+ // = Get/Set policy
+ Policy policy (void) const;
+ void policy (const Policy);
+
+ // = Get/Set priority.
+ ACE_Sched_Priority priority (void) const;
+ void priority (const ACE_Sched_Priority);
+
+ // = Get/Set scope.
+ int scope (void) const;
+ void scope(const int);
+
+ // = Get/Set quantum.
+ const ACE_Time_Value &quantum (void) const;
+ void quantum (const ACE_Time_Value &);
+
+ // = Accessors for OS-specific priorities.
+ // These return priority values for ACE_SCHED_OTHER if the Policy value
+ // is invalid.
+ static int priority_min (const Policy,
+ const int scope = ACE_SCOPE_THREAD);
+ static int priority_max (const Policy,
+ const int scope = ACE_SCOPE_THREAD);
+
+ /**
+ * The next higher priority. "Higher" refers to scheduling priority,
+ * not to the priority value itself. (On some platforms, higher scheduling
+ * priority is indicated by a lower priority value.) If "priority" is
+ * already the highest priority (for the specified policy), then it is
+ * returned.
+ */
+ static int next_priority (const Policy,
+ const int priority,
+ const int scope = ACE_SCOPE_THREAD);
+
+ /**
+ * The previous, lower priority. "Lower" refers to scheduling priority,
+ * not to the priority value itself. (On some platforms, lower scheduling
+ * priority is indicated by a higher priority value.) If "priority" is
+ * already the lowest priority (for the specified policy), then it is
+ * returned.
+ */
+ static int previous_priority (const Policy,
+ const int priority,
+ const int scope = ACE_SCOPE_THREAD);
+
+private:
+ /// Scheduling policy.
+ Policy policy_;
+
+ /// Default <priority_>: for setting the priority for the process, LWP,
+ /// or thread, as indicated by the scope_ parameter.
+ ACE_Sched_Priority priority_;
+
+ /**
+ * <scope_> must be one of the following:
+ * ACE_SCOPE_PROCESS: sets the scheduling policy for the
+ * process, and the process priority. On some platforms,
+ * such as Win32, the scheduling policy can _only_ be
+ * set at process scope.
+ * ACE_SCOPE_LWP: lightweight process scope, only used with
+ * Solaris threads.
+ * ACE_SCOPE_THREAD: sets the scheduling policy for the thread,
+ * if the OS supports it, such as with Posix threads, and the
+ * thread priority.
+ * NOTE: I don't think that these are the same as POSIX
+ * contention scope. POSIX users who are interested in,
+ * and understand, contention scope will have to set it
+ * by using system calls outside of ACE.
+ */
+ int scope_;
+
+ /**
+ * The <quantum_> is for time slicing. An ACE_Time_Value of 0 has
+ * special significance: it means time-slicing is disabled; with
+ * that, a thread that is running on a CPU will continue to run
+ * until it blocks or is preempted. Currently ignored if the OS
+ * doesn't directly support time slicing, such as on VxWorks, or
+ * setting the quantum (can that be done on Win32?).
+ */
+ ACE_Time_Value quantum_;
+};
+
+/**
+ * @class ACE_Sched_Priority_Iterator
+ *
+ * @brief An iterator over the OS-defined scheduling priorities.
+ *
+ * The order of priorities (numeric value vs. importance) is OS
+ * dependant, it can be the case that the priorities are not even
+ * contigous. This class permits iteration over priorities using
+ * the iterator pattern.
+ */
+class ACE_Export ACE_Sched_Priority_Iterator
+{
+public:
+ /// Initialize the iterator, the arguments define the scheduling
+ /// policy and scope for the priorities (see ACE_Sched_Param).
+ ACE_Sched_Priority_Iterator (const ACE_Sched_Params::Policy &policy,
+ int scope = ACE_SCOPE_THREAD);
+
+ /// Default dtor.
+ ~ACE_Sched_Priority_Iterator (void);
+
+ /// Check if there are more priorities.
+ int more (void) const;
+
+ /// Return the current priority.
+ int priority (void) const;
+
+ /// Move to the next priority.
+ /// The iteration is from lowest to highest importance.
+ void next (void);
+
+ /// Accessor for the scheduling policy over which we are iterating.
+ const ACE_Sched_Params::Policy &policy (void) const;
+
+ /// Accessor for the scheduling
+ int scope (void) const;
+
+private:
+ /// The Scheduling policy (FIFO, RR, etc.) and scheduling scope
+ /// (PROCESS, SYSTEM) we are iterating on.
+ ACE_Sched_Params::Policy policy_;
+ int scope_;
+
+ /// The current priority.
+ int priority_;
+
+ /**
+ * This is set to 1 when there are no more priorities. Cannot easily
+ * compare against the highest priority on platforms were priorities
+ * are non-contigous or descending.
+ */
+ int done_;
+};
+
+#if defined (__ACE_INLINE__)
+#include "Sched_Params.i"
+#endif /* __ACE_INLINE__ */
+
+#include "ace/post.h"
+#endif /* ACE_SCHED_PARAMS_H */
diff --git a/ace/OS/Sched_Params.i b/ace/OS/Sched_Params.i
new file mode 100644
index 00000000000..041f9cb1648
--- /dev/null
+++ b/ace/OS/Sched_Params.i
@@ -0,0 +1,136 @@
+/* -*- C++ -*- */
+// $Id$
+
+// ============================================================================
+//
+// = LIBRARY
+// ACE
+//
+// = FILENAME
+// Sched_Params.i
+//
+// = CREATION DATE
+// 28 January 1997
+//
+// = AUTHOR
+// David Levine
+//
+// ============================================================================
+
+ACE_INLINE
+ACE_Sched_Params::ACE_Sched_Params (
+ const Policy policy,
+ const ACE_Sched_Priority priority,
+ const int scope,
+ const ACE_Time_Value &quantum)
+ : policy_ (policy),
+ priority_ (priority),
+ scope_ (scope),
+ quantum_ (quantum)
+{
+}
+
+ACE_INLINE ACE_Sched_Params::~ACE_Sched_Params (void)
+{
+}
+
+ACE_INLINE ACE_Sched_Params::Policy
+ACE_Sched_Params::policy (void) const
+{
+ return this->policy_;
+}
+
+ACE_INLINE void
+ACE_Sched_Params::policy (const ACE_Sched_Params::Policy policy)
+{
+ this->policy_ = policy;
+}
+
+ACE_INLINE ACE_Sched_Priority
+ACE_Sched_Params::priority (void) const
+{
+ return this->priority_;
+}
+
+ACE_INLINE void
+ACE_Sched_Params::priority (const ACE_Sched_Priority priority)
+{
+ this->priority_ = priority;
+}
+
+ACE_INLINE int
+ACE_Sched_Params::scope (void) const
+{
+ return this->scope_;
+}
+
+ACE_INLINE void
+ACE_Sched_Params::scope (const int scope)
+{
+ this->scope_ = scope;
+}
+
+ACE_INLINE const ACE_Time_Value &
+ACE_Sched_Params::quantum (void) const
+{
+ return this->quantum_;
+}
+
+ACE_INLINE void
+ACE_Sched_Params::quantum (const ACE_Time_Value &quant)
+{
+ this->quantum_ = quant;
+}
+
+ACE_INLINE const ACE_Sched_Params::Policy &
+ACE_Sched_Priority_Iterator::policy (void) const
+{
+ return this->policy_;
+}
+
+ACE_INLINE int
+ACE_Sched_Priority_Iterator::scope (void) const
+{
+ return this->scope_;
+}
+
+ACE_INLINE
+ACE_Sched_Priority_Iterator::ACE_Sched_Priority_Iterator (const ACE_Sched_Params::Policy &policy,
+ int scope)
+ : policy_ (policy),
+ scope_ (scope),
+ priority_ (0),
+ done_ (0)
+{
+ priority_ = ACE_Sched_Params::priority_min (this->policy (), this->scope ());
+}
+
+ACE_INLINE
+ACE_Sched_Priority_Iterator::~ACE_Sched_Priority_Iterator (void)
+{
+}
+
+ACE_INLINE int
+ACE_Sched_Priority_Iterator::more (void) const
+{
+ return !this->done_;
+}
+
+ACE_INLINE int
+ACE_Sched_Priority_Iterator::priority (void) const
+{
+ return this->priority_;
+}
+
+ACE_INLINE void
+ACE_Sched_Priority_Iterator::next (void)
+{
+ if (this->done_)
+ return;
+
+ int old_priority = this->priority_;
+ priority_ = ACE_Sched_Params::next_priority (this->policy (),
+ this->priority (),
+ this->scope ());
+ this->done_ = old_priority == priority_;
+}
diff --git a/ace/OS/Thread_Hook.cpp b/ace/OS/Thread_Hook.cpp
new file mode 100644
index 00000000000..733fa98d7b0
--- /dev/null
+++ b/ace/OS/Thread_Hook.cpp
@@ -0,0 +1,25 @@
+// $Id$
+
+#include "Thread_Hook.h"
+#include "OS.h"
+
+ACE_RCSID(ace, Thread_Hook, "$Id$")
+
+void *
+ACE_Thread_Hook::start (ACE_THR_FUNC func,
+ void *arg)
+{
+ return (func) (arg);
+}
+
+ACE_Thread_Hook *
+ACE_Thread_Hook::thread_hook (ACE_Thread_Hook *hook)
+{
+ return ACE_OS_Object_Manager::thread_hook (hook);
+}
+
+ACE_Thread_Hook *
+ACE_Thread_Hook::thread_hook (void)
+{
+ return ACE_OS_Object_Manager::thread_hook ();
+}
diff --git a/ace/OS/Thread_Hook.h b/ace/OS/Thread_Hook.h
new file mode 100644
index 00000000000..d1a9510a137
--- /dev/null
+++ b/ace/OS/Thread_Hook.h
@@ -0,0 +1,56 @@
+
+//=============================================================================
+/**
+ * @file Thread_Hook.h
+ *
+ * $Id$
+ *
+ * @author Carlos O'Ryan <coryan@uci.edu>
+ */
+//=============================================================================
+
+
+#ifndef ACE_THREAD_HOOK_H
+#define ACE_THREAD_HOOK_H
+#include "ace/pre.h"
+
+#include "ace/config-all.h"
+
+#if !defined (ACE_LACKS_PRAGMA_ONCE)
+# pragma once
+#endif /* ACE_LACKS_PRAGMA_ONCE */
+
+#include "OS_Export.h"
+
+/**
+ * @class ACE_Thread_Hook
+ *
+ * @brief This class makes it possible to provide user-defined "start"
+ * hooks that are called before the thread entry point function
+ * is invoked.
+ */
+class ACE_OS_Export ACE_Thread_Hook
+{
+
+public:
+ /**
+ * This method can be overridden in a subclass to customize this
+ * pre-function call "hook" invocation that can perform
+ * initialization processing before the thread entry point <func>
+ * method is called back. The <func> and <arg> passed into the
+ * start hook are the same as those passed by the application that
+ * spawned the thread.
+ */
+ virtual void *start (ACE_THR_FUNC func,
+ void *arg);
+
+ /// sets the system wide thread hook, returns the previous thread
+ /// hook or 0 if none is set.
+ static ACE_Thread_Hook *thread_hook (ACE_Thread_Hook *hook);
+
+ /// Returns the current system thread hook.
+ static ACE_Thread_Hook *thread_hook (void);
+};
+
+#include "ace/post.h"
+#endif /* ACE_THREAD_HOOK_H */
diff --git a/ace/OS/gethrtime.cpp b/ace/OS/gethrtime.cpp
new file mode 100644
index 00000000000..dcad95e8b64
--- /dev/null
+++ b/ace/OS/gethrtime.cpp
@@ -0,0 +1,58 @@
+// $Id$
+//
+// Build this file with g++. It can be linked in to a ACE application
+// that was compiled with GreenHills. It wouldn't be necessary if I
+// knew a way to correctly move values from registers to a 64-bit
+// variable in GHS asm code. That's easy with g++ asm.
+
+#include "OS.h"
+
+ACE_RCSID(ace, gethrtime, "$Id$")
+
+extern "C"
+ACE_hrtime_t
+ACE_gethrtime (void)
+{
+#if defined (ACE_HAS_PENTIUM)
+ // ACE_TRACE ("ACE_gethrtime");
+
+#if defined (ACE_LACKS_LONGLONG_T)
+ double now;
+#else /* ! ACE_LACKS_LONGLONG_T */
+ ACE_hrtime_t now;
+#endif /* ! ACE_LACKS_LONGLONG_T */
+
+ // See comments about the RDTSC Pentium instruction for the
+ // ACE_WIN32 version of ACE_OS::gethrtime () in ace/OS.i.
+ //
+ // Read the high-res tick counter directly into memory variable
+ // "now". The A constraint signifies a 64-bit int.
+#if defined (__GNUG__)
+ asm volatile ("rdtsc" : "=A" (now) : : "memory");
+// #elif defined (ghs)
+// The following doesn't work. For now, this file must be compile with g++.
+// asm ("rdtsc");
+// asm ("movl %edx,-16(%ebp)");
+// asm ("movl %eax,-12(%ebp)");
+#else
+# error unsupported compiler
+#endif
+
+#if defined (ACE_LACKS_LONGLONG_T)
+ // ACE_U_LongLong doesn't have the same layout as now, so construct
+ // it "properly".
+ ACE_UINT32 least, most;
+ ACE_OS::memcpy (&least, &now, sizeof (ACE_UINT32));
+ ACE_OS::memcpy (&most, (unsigned char *) &now + sizeof (ACE_UINT32),
+ sizeof (ACE_UINT32));
+
+ const ACE_hrtime_t ret (least, most);
+ return ret;
+#else /* ! ACE_LACKS_LONGLONG_T */
+ return now;
+#endif /* ! ACE_LACKS_LONGLONG_T */
+
+#else /* ! ACE_HAS_PENTIUM */
+# error This file can _only_ be compiled with ACE_HAS_PENTIUM.
+#endif /* ! ACE_HAS_PENTIUM */
+}