summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordhinton <dhinton@ae88bc3d-4319-0410-8dbf-d08b4c9d3795>2003-10-27 20:35:23 +0000
committerdhinton <dhinton@ae88bc3d-4319-0410-8dbf-d08b4c9d3795>2003-10-27 20:35:23 +0000
commit6731b3d1f01cfbaace2507db5ca9b16ab9fbf43b (patch)
tree0d41f06518b4cce20684cd3f138f5c5e970bd1e2
parent0566e28b44588af282f0448df07f6fdf81e7ed7b (diff)
downloadATCD-6731b3d1f01cfbaace2507db5ca9b16ab9fbf43b.tar.gz
ChangeLogTag:Mon Oct 27 20:43:33 UTC 2003 Don Hinton <dhinton@dresystems.com>
-rw-r--r--ChangeLog5
-rw-r--r--ace/Basic_Types.h45
-rw-r--r--ace/Cleanup.cpp187
-rw-r--r--ace/Cleanup.h125
-rw-r--r--ace/Cleanup.inl5
-rw-r--r--ace/Default_Constants.h16
-rw-r--r--ace/Global_Macros.h279
-rw-r--r--ace/Handle_Set.cpp16
-rw-r--r--ace/Log_Msg.cpp8
-rw-r--r--ace/Metrics_Cache.h2
-rw-r--r--ace/Mutex.h10
-rw-r--r--ace/OS.cpp7606
-rw-r--r--ace/OS.h4296
-rw-r--r--ace/OS.i11059
-rw-r--r--ace/OS_Dirent.cpp267
-rw-r--r--ace/OS_Dirent.h36
-rw-r--r--ace/OS_Dirent.inl189
-rw-r--r--ace/OS_Memory.cpp29
-rw-r--r--ace/OS_Memory.h16
-rw-r--r--ace/OS_Memory.inl11
-rw-r--r--ace/OS_NS_Thread.cpp3495
-rw-r--r--ace/OS_NS_Thread.h1723
-rw-r--r--ace/OS_NS_Thread.inl4588
-rw-r--r--ace/OS_NS_arpa_inet.cpp58
-rw-r--r--ace/OS_NS_arpa_inet.h59
-rw-r--r--ace/OS_NS_arpa_inet.inl121
-rw-r--r--ace/OS_NS_ctype.cpp9
-rw-r--r--ace/OS_NS_ctype.h75
-rw-r--r--ace/OS_NS_ctype.inl35
-rw-r--r--ace/OS_NS_dirent.cpp277
-rw-r--r--ace/OS_NS_dirent.h79
-rw-r--r--ace/OS_NS_dirent.inl189
-rw-r--r--ace/OS_NS_dlfcn.cpp9
-rw-r--r--ace/OS_NS_dlfcn.h55
-rw-r--r--ace/OS_NS_dlfcn.inl247
-rw-r--r--ace/OS_NS_errno.cpp9
-rw-r--r--ace/OS_NS_errno.h51
-rw-r--r--ace/OS_NS_errno.inl62
-rw-r--r--ace/OS_NS_fcntl.cpp252
-rw-r--r--ace/OS_NS_fcntl.h82
-rw-r--r--ace/OS_NS_fcntl.inl15
-rw-r--r--ace/OS_NS_macros.h67
-rw-r--r--ace/OS_NS_math.cpp9
-rw-r--r--ace/OS_NS_math.h50
-rw-r--r--ace/OS_NS_math.inl18
-rw-r--r--ace/OS_NS_netdb.cpp357
-rw-r--r--ace/OS_NS_netdb.h103
-rw-r--r--ace/OS_NS_netdb.inl526
-rw-r--r--ace/OS_NS_poll.cpp9
-rw-r--r--ace/OS_NS_poll.h52
-rw-r--r--ace/OS_NS_poll.inl37
-rw-r--r--ace/OS_NS_pwd.cpp9
-rw-r--r--ace/OS_NS_pwd.h63
-rw-r--r--ace/OS_NS_pwd.inl131
-rw-r--r--ace/OS_NS_regex.cpp9
-rw-r--r--ace/OS_NS_regex.h52
-rw-r--r--ace/OS_NS_regex.inl32
-rw-r--r--ace/OS_NS_signal.cpp22
-rw-r--r--ace/OS_NS_signal.h110
-rw-r--r--ace/OS_NS_signal.inl269
-rw-r--r--ace/OS_NS_stdio.cpp341
-rw-r--r--ace/OS_NS_stdio.h307
-rw-r--r--ace/OS_NS_stdio.inl927
-rw-r--r--ace/OS_NS_stdlib.cpp398
-rw-r--r--ace/OS_NS_stdlib.h193
-rw-r--r--ace/OS_NS_stdlib.inl389
-rw-r--r--ace/OS_NS_string.cpp387
-rw-r--r--ace/OS_NS_string.h402
-rw-r--r--ace/OS_NS_string.inl491
-rw-r--r--ace/OS_NS_strings.cpp75
-rw-r--r--ace/OS_NS_strings.h69
-rw-r--r--ace/OS_NS_strings.inl49
-rw-r--r--ace/OS_NS_stropts.cpp191
-rw-r--r--ace/OS_NS_stropts.h146
-rw-r--r--ace/OS_NS_stropts.inl187
-rw-r--r--ace/OS_NS_sys_mman.cpp9
-rw-r--r--ace/OS_NS_sys_mman.h73
-rw-r--r--ace/OS_NS_sys_mman.inl316
-rw-r--r--ace/OS_NS_sys_msg.cpp9
-rw-r--r--ace/OS_NS_sys_msg.h60
-rw-r--r--ace/OS_NS_sys_msg.inl76
-rw-r--r--ace/OS_NS_sys_resource.cpp9
-rw-r--r--ace/OS_NS_sys_resource.h53
-rw-r--r--ace/OS_NS_sys_resource.inl74
-rw-r--r--ace/OS_NS_sys_select.cpp9
-rw-r--r--ace/OS_NS_sys_select.h57
-rw-r--r--ace/OS_NS_sys_select.inl57
-rw-r--r--ace/OS_NS_sys_shm.cpp15
-rw-r--r--ace/OS_NS_sys_shm.h56
-rw-r--r--ace/OS_NS_sys_shm.inl63
-rw-r--r--ace/OS_NS_sys_socket.cpp153
-rw-r--r--ace/OS_NS_sys_socket.h223
-rw-r--r--ace/OS_NS_sys_socket.inl734
-rw-r--r--ace/OS_NS_sys_stat.cpp9
-rw-r--r--ace/OS_NS_sys_stat.h79
-rw-r--r--ace/OS_NS_sys_stat.inl311
-rw-r--r--ace/OS_NS_sys_time.cpp9
-rw-r--r--ace/OS_NS_sys_time.h45
-rw-r--r--ace/OS_NS_sys_time.inl70
-rw-r--r--ace/OS_NS_sys_uio.cpp112
-rw-r--r--ace/OS_NS_sys_uio.h65
-rw-r--r--ace/OS_NS_sys_uio.inl33
-rw-r--r--ace/OS_NS_sys_utsname.cpp225
-rw-r--r--ace/OS_NS_sys_utsname.h63
-rw-r--r--ace/OS_NS_sys_utsname.inl26
-rw-r--r--ace/OS_NS_sys_wait.cpp8
-rw-r--r--ace/OS_NS_sys_wait.h74
-rw-r--r--ace/OS_NS_sys_wait.inl103
-rw-r--r--ace/OS_NS_time.cpp808
-rw-r--r--ace/OS_NS_time.h317
-rw-r--r--ace/OS_NS_time.inl486
-rw-r--r--ace/OS_NS_unistd.cpp710
-rw-r--r--ace/OS_NS_unistd.h264
-rw-r--r--ace/OS_NS_unistd.inl1220
-rw-r--r--ace/OS_NS_wchar.cpp368
-rw-r--r--ace/OS_NS_wchar.h162
-rw-r--r--ace/OS_NS_wchar.inl81
-rw-r--r--ace/OS_String.cpp1050
-rw-r--r--ace/OS_String.h594
-rw-r--r--ace/OS_String.inl653
-rw-r--r--ace/OS_TLI.h58
-rw-r--r--ace/OS_TLI.inl84
-rw-r--r--ace/OS_main.h203
-rw-r--r--ace/Object_Manager.h10
-rw-r--r--ace/Object_Manager_Base.cpp504
-rw-r--r--ace/Object_Manager_Base.h267
-rw-r--r--ace/Object_Manager_Base.inl2
-rw-r--r--ace/SOCK.h24
-rw-r--r--ace/Signal.h3
-rw-r--r--ace/TTY_IO.h12
-rw-r--r--ace/Time_Value.cpp14
-rw-r--r--ace/Time_Value.h44
-rw-r--r--ace/Time_Value.inl47
-rw-r--r--ace/Timeprobe.h7
-rw-r--r--ace/ace.mpc42
-rw-r--r--ace/config-all.h7
-rw-r--r--ace/config-vxworks5.x.h4
-rw-r--r--ace/os_include/arpa/os_inet.h100
-rw-r--r--ace/os_include/netinet/os_in.h48
-rw-r--r--ace/os_include/netinet/os_tcp.h14
-rw-r--r--ace/os_include/os_dirent.h7
-rw-r--r--ace/os_include/os_dlfcn.h7
-rw-r--r--ace/os_include/os_fcntl.h8
-rw-r--r--ace/os_include/os_limits.h18
-rw-r--r--ace/os_include/os_pthread.h3
-rw-r--r--ace/os_include/os_signal.h57
-rw-r--r--ace/os_include/os_stdio.h8
-rw-r--r--ace/os_include/os_stdlib.h6
-rw-r--r--ace/os_include/os_string.h25
-rw-r--r--ace/os_include/os_strings.h10
-rw-r--r--ace/os_include/os_stropts.h44
-rw-r--r--ace/os_include/os_time.h11
-rw-r--r--ace/os_include/os_ucontext.h4
-rw-r--r--ace/os_include/os_unistd.h63
-rw-r--r--ace/os_include/sys/os_mman.h26
-rw-r--r--ace/os_include/sys/os_resource.h40
-rw-r--r--ace/os_include/sys/os_select.h9
-rw-r--r--ace/os_include/sys/os_sem.h20
-rw-r--r--ace/os_include/sys/os_socket.h50
-rw-r--r--ace/os_include/sys/os_stat.h2
-rw-r--r--ace/os_include/sys/os_time.h12
-rw-r--r--ace/os_include/sys/os_times.h2
-rw-r--r--ace/os_include/sys/os_types.h11
-rw-r--r--ace/os_include/sys/os_uio.h14
-rw-r--r--ace/os_include/sys/os_wait.h54
165 files changed, 28201 insertions, 25969 deletions
diff --git a/ChangeLog b/ChangeLog
index ade62544951..03f1e96074f 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+Mon Oct 27 20:43:33 UTC 2003 Don Hinton <dhinton@dresystems.com>
+
+ * ?
+ Beaucoup des changement...
+
Sat Oct 25 10:51:23 UTC 2003 Johnny Willemsen <jwillemsen@remedy.nl>
* ace/config-win32-common.h: Fixed compile problem in this file
diff --git a/ace/Basic_Types.h b/ace/Basic_Types.h
index 988bc3c2db8..09d01a9969f 100644
--- a/ace/Basic_Types.h
+++ b/ace/Basic_Types.h
@@ -257,51 +257,6 @@ typedef unsigned long ptrdiff_t; // evc3, PocketPC don't defined ptrdiff_t
# endif
typedef ptrdiff_t ptr_arith_t;
-// 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 */
-# 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__) ||\
- defined (ARM) || defined (_M_IA64)
- // 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_LACKS_LONGLONG_T)
// This throws away the high 32 bits. It's very unlikely that a
diff --git a/ace/Cleanup.cpp b/ace/Cleanup.cpp
index fc532b41367..bd3480d5f3b 100644
--- a/ace/Cleanup.cpp
+++ b/ace/Cleanup.cpp
@@ -1,4 +1,189 @@
// -*- C++ -*-
// $Id$
-// This is a placeholder.
+#include "ace/Cleanup.h"
+
+ACE_RCSID(ace, Cleanup, "$Id$")
+
+#if !defined (ACE_HAS_INLINED_OSCALLS)
+# include "ace/Cleanup.inl"
+#endif /* ACE_HAS_INLINED_OS_CALLS */
+
+#include "ace/OS_Memory.h"
+
+void
+ACE_Cleanup::cleanup (void *)
+{
+ delete this;
+}
+
+
+ACE_Cleanup::~ACE_Cleanup (void)
+{
+}
+
+/*****************************************************************************/
+
+extern "C" void
+ace_cleanup_destroyer (ACE_Cleanup *object, void *param)
+{
+ object->cleanup (param);
+}
+
+/*****************************************************************************/
+
+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
+ *
+ * @brief For maintaining a list of ACE_Cleanup_Info items.
+ *
+ * For internal use by ACE_Object_Manager.
+ */
+class ACE_Cleanup_Info_Node
+{
+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_);
+ }
+}
+
+
diff --git a/ace/Cleanup.h b/ace/Cleanup.h
index fc532b41367..953b6ae5fb1 100644
--- a/ace/Cleanup.h
+++ b/ace/Cleanup.h
@@ -1,4 +1,125 @@
// -*- C++ -*-
-// $Id$
-// This is a placeholder.
+//=============================================================================
+/**
+ * @file Cleanup.h
+ *
+ * $Id$
+ *
+ * @author Douglas C. Schmidt <schmidt@cs.wustl.edu>
+ * @author Jesper S. M|ller<stophph@diku.dk>
+ * @author and a cast of thousands...
+ *
+ * Originally in OS.h.
+ */
+//=============================================================================
+
+#ifndef ACE_CLEANUP_H
+# define ACE_CLEANUP_H
+
+# include /**/ "ace/pre.h"
+
+# include "ace/config-all.h"
+
+# if !defined (ACE_LACKS_PRAGMA_ONCE)
+# pragma once
+# endif /* ACE_LACKS_PRAGMA_ONCE */
+
+#include "ace/OS_Export.h"
+/**
+ * @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_;
+};
+
+# if defined (ACE_HAS_INLINED_OSCALLS)
+# if defined (ACE_INLINE)
+# undef ACE_INLINE
+# endif /* ACE_INLINE */
+# define ACE_INLINE inline
+# include "ace/Cleanup.inl"
+# endif /* ACE_HAS_INLINED_OSCALLS */
+
+# include /**/ "ace/post.h"
+#endif /* ACE_CLEANUP_H */
diff --git a/ace/Cleanup.inl b/ace/Cleanup.inl
index fc532b41367..841c715bf1a 100644
--- a/ace/Cleanup.inl
+++ b/ace/Cleanup.inl
@@ -1,4 +1,7 @@
// -*- C++ -*-
// $Id$
-// This is a placeholder.
+ACE_INLINE
+ACE_Cleanup::ACE_Cleanup (void)
+{
+}
diff --git a/ace/Default_Constants.h b/ace/Default_Constants.h
index bf50f37b98b..c095ed94964 100644
--- a/ace/Default_Constants.h
+++ b/ace/Default_Constants.h
@@ -326,14 +326,8 @@
// A simple free list which doen't allocate/deallocate elements.
# define ACE_PURE_FREE_LIST 2
-# if defined (INTEGRITY)
-# define ACE_MAX_USERID 32
-# endif
-
# if defined (ACE_WIN32)
-#define ACE_MAX_USERID 32
-
// This is necessary to work around bugs with Win32 non-blocking
// connects...
# if !defined (ACE_NON_BLOCKING_BUG_DELAY)
@@ -523,5 +517,15 @@ const unsigned int ACE_CONNECTOR_HANDLER_MAP_SIZE = 16;
#define ACE_DEFAULT_LOCALNAME ACE_LIB_TEXT (ACE_DEFAULT_LOCALNAME_A)
#define ACE_DEFAULT_GLOBALNAME ACE_LIB_TEXT (ACE_DEFAULT_GLOBALNAME_A)
+# if defined (ACE_WIN32)
+ // The "null" device on Win32.
+# define ACE_DEV_NULL "nul"
+# define ACE_SYSCALL_FAILED 0xFFFFFFFF
+# else /* !ACE_WIN32 */
+ // The "null" device on UNIX.
+# define ACE_DEV_NULL "/dev/null"
+# define ACE_SYSCALL_FAILED -1
+# endif /* ACE_WIN32 */
+
#include /**/ "ace/post.h"
#endif /*ACE_DEFAULT_CONSTANTS_H*/
diff --git a/ace/Global_Macros.h b/ace/Global_Macros.h
index 8eb9ca8a47b..784427fdd1e 100644
--- a/ace/Global_Macros.h
+++ b/ace/Global_Macros.h
@@ -645,7 +645,20 @@ _make_##SERVICE_CLASS (ACE_Service_Object_Exterminator *gobbler) \
# define ACE_SVC_FACTORY_DEFINE(X) ACE_FACTORY_DEFINE (ACE_Svc, X)
//@}
-#if !defined (ACE_WIN32)
+#if defined (ACE_WIN32)
+// These are used in SPIPE_Acceptor/Connector, but are ignored at runtime.
+# if defined (ACE_HAS_WINCE)
+# if !defined (PIPE_TYPE_MESSAGE)
+# define PIPE_TYPE_MESSAGE 0
+# endif
+# if !defined (PIPE_READMODE_MESSAGE)
+# define PIPE_READMODE_MESSAGE 0
+# endif
+# if !defined (PIPE_WAIT)
+# define PIPE_WAIT 0
+# endif
+# endif /* ACE_HAS_WINCE */
+#else /* !ACE_WIN32 */
// Add some typedefs and macros to enhance Win32 conformance...
# if !defined (LPSECURITY_ATTRIBUTES)
# define LPSECURITY_ATTRIBUTES int
@@ -692,7 +705,8 @@ _make_##SERVICE_CLASS (ACE_Service_Object_Exterminator *gobbler) \
# if !defined(PIPE_TYPE_MESSAGE)
# define PIPE_TYPE_MESSAGE 0
# endif /* !defined PIPE_TYPE_MESSAGE */
-#endif /* !ACE_WIN32 */
+#endif /* ACE_WIN32 */
+
// Some useful abstrations for expressions involving
// ACE_Allocator.malloc (). The difference between ACE_NEW_MALLOC*
@@ -727,6 +741,35 @@ _make_##SERVICE_CLASS (ACE_Service_Object_Exterminator *gobbler) \
else { new (POINTER) CONSTRUCTOR; } \
} while (0)
+/* ACE_Metrics */
+#if defined ACE_LACKS_ARRAY_PLACEMENT_NEW
+# define ACE_NEW_MALLOC_ARRAY_RETURN(POINTER,ALLOCATOR,CONSTRUCTOR,COUNT,RET_VAL) \
+ do { POINTER = ALLOCATOR; \
+ if (POINTER == 0) { errno = ENOMEM; return RET_VAL;} \
+ else { for (u_int i = 0; i < COUNT; ++i) \
+ {new (POINTER) CONSTRUCTOR; ++POINTER;} \
+ POINTER -= COUNT;} \
+ } while (0)
+# define ACE_NEW_MALLOC_ARRAY(POINTER,ALLOCATOR,CONSTRUCTOR,COUNT) \
+ do { POINTER = ALLOCATOR; \
+ if (POINTER == 0) { errno = ENOMEM; return;} \
+ else { for (u_int i = 0; i < COUNT; ++i) \
+ {new (POINTER) CONSTRUCTOR; ++POINTER;} \
+ POINTER -= COUNT;} \
+ } while (0)
+#else /* ! defined ACE_LACKS_ARRAY_PLACEMENT_NEW */
+# define ACE_NEW_MALLOC_ARRAY_RETURN(POINTER,ALLOCATOR,CONSTRUCTOR,COUNT,RET_VAL) \
+ do { POINTER = ALLOCATOR; \
+ if (POINTER == 0) { errno = ENOMEM; return RET_VAL;} \
+ else { new (POINTER) CONSTRUCTOR [COUNT]; } \
+ } while (0)
+# define ACE_NEW_MALLOC_ARRAY(POINTER,ALLOCATOR,CONSTRUCTOR,COUNT) \
+ do { POINTER = ALLOCATOR; \
+ if (POINTER == 0) { errno = ENOMEM; return;} \
+ else { new (POINTER) CONSTRUCTOR [COUNT]; } \
+ } while (0)
+#endif /* defined ACE_LACKS_ARRAY_PLACEMENT_NEW */
+
// This is being placed here temporarily to help stablelize the builds, but will
// be moved out along with the above macros as part of the subsetting. dhinton
# if !defined (ACE_HAS_WINCE)
@@ -741,6 +784,238 @@ _make_##SERVICE_CLASS (ACE_Service_Object_Exterminator *gobbler) \
# define ACE_NOOP(x)
+#if defined (ACE_PSOS)
+# define ACE_SEH_TRY if (1)
+# define ACE_SEH_EXCEPT(X) while (0)
+# define ACE_SEH_FINALLY if (1)
+#elif defined (ACE_WIN32)
+# 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 /* ACE_HAS_WIN32_STRUCTURAL_EXCEPTIONS */
+# else /* !ACE_WIN32 && ACE_PSOS */
+# define ACE_SEH_TRY if (1)
+# define ACE_SEH_EXCEPT(X) while (0)
+# define ACE_SEH_FINALLY if (1)
+#endif /* ACE_WIN32 && ACE_PSOS */
+
+
+// These should probably be put into a seperate header.
+
+// 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_SOCK_SEQPACK_*
+# define ACE_SOCK_SEQPACK_ACCEPTOR ACE_SOCK_SEQPACK_Acceptor
+# define ACE_SOCK_SEQPACK_CONNECTOR ACE_SOCK_SEQPACK_Connector
+# define ACE_SOCK_SEQPACK_ASSOCIATION ACE_SOCK_SEQPACK_Association
+
+// 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_SOCK_SEQPACK_*
+# define ACE_SOCK_SEQPACK_ACCEPTOR ACE_SOCK_SEQPACK_Acceptor, ACE_INET_Addr
+# define ACE_SOCK_SEQPACK_CONNECTOR ACE_SOCK_SEQPACK_Connector, ACE_INET_Addr
+# define ACE_SOCK_SEQPACK_ASSOCIATION ACE_SOCK_SEQPACK_Association, 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 */
+
#include /**/ "ace/post.h"
#endif /*ACE_GLOBAL_MACROS_H*/
diff --git a/ace/Handle_Set.cpp b/ace/Handle_Set.cpp
index 1456a351faf..4f3f31fdc36 100644
--- a/ace/Handle_Set.cpp
+++ b/ace/Handle_Set.cpp
@@ -13,6 +13,22 @@ ACE_RCSID(ace, Handle_Set, "$Id$")
ACE_ALLOC_HOOK_DEFINE(ACE_Handle_Set)
+ // ACE_MSB_MASK is only used here.
+# 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 */
+
#if defined (__BORLANDC__) && !defined (ACE_WIN32)
// The Borland C++ compiler on Linux also doesn't have fds_bits, but has __fds_bits.
#define fds_bits __fds_bits
diff --git a/ace/Log_Msg.cpp b/ace/Log_Msg.cpp
index 2ed4b844043..a3f54995f28 100644
--- a/ace/Log_Msg.cpp
+++ b/ace/Log_Msg.cpp
@@ -33,6 +33,14 @@ ACE_RCSID(ace, Log_Msg, "$Id$")
ACE_ALLOC_HOOK_DEFINE(ACE_Log_Msg)
+// only used here... dhinton
+#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_MT_SAFE) && (ACE_MT_SAFE != 0)
int ACE_Log_Msg::key_created_ = 0;
# if defined (ACE_HAS_THREAD_SPECIFIC_STORAGE) || \
diff --git a/ace/Metrics_Cache.h b/ace/Metrics_Cache.h
index 26c6881f6b8..5ef4208421f 100644
--- a/ace/Metrics_Cache.h
+++ b/ace/Metrics_Cache.h
@@ -14,7 +14,7 @@
#ifndef ACE_METRICS_CACHE_H
#define ACE_METRICS_CACHE_H
-#include "ace/OS.h"
+#include "ace/Timeprobe.h"
#if !defined (ACE_LACKS_PRAGMA_ONCE)
# pragma once
diff --git a/ace/Mutex.h b/ace/Mutex.h
index 610b1880bbe..1ba1a35f6ba 100644
--- a/ace/Mutex.h
+++ b/ace/Mutex.h
@@ -24,6 +24,16 @@
#include "ace/OS.h"
+# 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)
+
class ACE_Time_Value;
/**
diff --git a/ace/OS.cpp b/ace/OS.cpp
index d2c1ec2af99..6ec74ee26c5 100644
--- a/ace/OS.cpp
+++ b/ace/OS.cpp
@@ -1,12 +1,11 @@
// $Id$
-
#include "ace/OS.h"
#include "ace/Sched_Params.h"
#include "ace/OS_Thread_Adapter.h"
#if !defined (ACE_HAS_WINCE)
-#include "ace/OS_QoS.h"
+# include "ace/OS_QoS.h"
#endif // ACE_HAS_WINCE
// Perhaps we should *always* include ace/OS.i in order to make sure
@@ -15,1603 +14,8 @@
# include "ace/OS.i"
#endif /* ACE_HAS_INLINED_OS_CALLS */
-#if defined(INTEGRITY) && defined(ACE_HAS_SHM_OPEN)
-char* shm_area_name = "ACE_Area";
-char* shm_area_password = "******";
-#endif
-
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)
- {
-#if defined (ACE_DISABLES_THREAD_LIBRARY_CALLS) && (ACE_DISABLES_THREAD_LIBRARY_CALLS == 1)
- ::DisableThreadLibraryCalls (instance);
-#endif /* ACE_DISABLES_THREAD_LIBRARY_CALLS */
- 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
- *
- * 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.
- *
- * For internal use only by ACE_OS.
- */
-class ACE_OS_Thread_Mutex_Guard
-{
-public:
- /// Implicitly and automatically acquire the lock.
- ACE_OS_Thread_Mutex_Guard (ACE_thread_mutex_t &m);
-
- /// Implicitly release the lock.
- ~ACE_OS_Thread_Mutex_Guard (void);
-
- /// Explicitly acquire the lock.
- int acquire (void);
-
- /// Explicitly release the lock.
- int release (void);
-
-protected:
- /// Reference to the mutex.
- ACE_thread_mutex_t &lock_;
-
- /// Keeps track of whether we acquired the lock or failed.
- int owner_;
-
- // = 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
- *
- * @brief For internal use only by ACE_OS.
- *
- * 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.
- */
-class ACE_OS_Recursive_Thread_Mutex_Guard
-{
-public:
- /// Implicitly and automatically acquire the lock.
- ACE_OS_Recursive_Thread_Mutex_Guard (ACE_recursive_thread_mutex_t &m);
-
- /// Implicitly release the lock.
- ~ACE_OS_Recursive_Thread_Mutex_Guard (void);
-
- /// Explicitly acquire the lock.
- int acquire (void);
-
- /// Explicitly release the lock.
- int release (void);
-
-protected:
- /// Reference to the mutex.
- ACE_recursive_thread_mutex_t &lock_;
-
- /// Keeps track of whether we acquired the lock or failed.
- int owner_;
-
- // = 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;
-
-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
- *
- * @brief For maintaining a list of ACE_Cleanup_Info items.
- *
- * For internal use by ACE_Object_Manager.
- */
-class ACE_Cleanup_Info_Node
-{
-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_);
- }
-}
-
-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
-# if defined (VER_PLATFORM_WIN32_CE)
- || vinfo.dwPlatformId == VER_PLATFORM_WIN32_CE
-# endif
- )
- {
- // Get information from the two structures
- const ACE_TCHAR *os;
- if (vinfo.dwPlatformId == VER_PLATFORM_WIN32_NT)
- os = ACE_LIB_TEXT ("Windows NT %d.%d");
- else
- os = ACE_LIB_TEXT ("Windows CE %d.%d");
- ACE_OS::sprintf (name->release,
- os,
- (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;
-# if defined PROCESSOR_ARCHITECTURE_IA64
- case PROCESSOR_ARCHITECTURE_IA64:
- ACE_OS_String::strcpy (processor, ACE_LIB_TEXT ("Itanium"));
- ACE_OS::sprintf (subtype, ACE_LIB_TEXT ("%d"),
- sinfo.wProcessorLevel);
- break;
-# endif
-# if defined PROCESSOR_ARCHITECTURE_ARM
- case PROCESSOR_ARCHITECTURE_ARM:
- ACE_OS_String::strcpy (processor, ACE_LIB_TEXT ("ARM"));
- ACE_OS::sprintf (subtype, ACE_LIB_TEXT ("%d"),
- sinfo.wProcessorLevel);
- break;
-# endif
- 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;
-}
-
-// Leave this in the global scope to allow
-// users to adjust the delay value.
-int ACE_THR_JOIN_DELAY = 5;
-
-int
-ACE_OS::thr_join (ACE_hthread_t thr_handle,
- ACE_THR_FUNC_RETURN *status)
-{
- // We can't get the status of the thread
- if (status != 0)
- {
- *status = 0;
- }
-
- // This method can not support joining all threads
- if (ACE_OS::thr_cmp (thr_handle, ACE_OS::NULL_hthread))
- {
- ACE_NOTSUP_RETURN (-1);
- }
-
- int retval = ESRCH;
- ACE_hthread_t current;
- ACE_OS::thr_self (current);
-
- // Make sure we are not joining ourself
- if (ACE_OS::thr_cmp (thr_handle, current))
- {
- retval = EDEADLK;
- }
- else
- {
- // Whether the task exists or not
- // we will return a successful value
- retval = 0;
-
- // Verify that the task id still exists
- while (taskIdVerify (thr_handle) == OK)
- {
- // Wait a bit to see if the task is still active.
- ACE_OS::sleep (ACE_THR_JOIN_DELAY);
- }
- }
-
- // Adapt the return value into errno and return value.
- // The ACE_ADAPT_RETVAL macro doesn't exactly do what
- // we need to do here, so we do it manually.
- if (retval != 0)
- {
- errno = retval;
- retval = -1;
- }
-
- return retval;
-}
-
-int
-ACE_OS::thr_join (ACE_thread_t waiter_id,
- ACE_thread_t *thr_id,
- ACE_THR_FUNC_RETURN *status)
-{
- thr_id = 0;
- return ACE_OS::thr_join (taskNameToId (waiter_id), status);
-}
-#endif /* VXWORKS */
-
-void
-ACE_OS::ace_flock_t::dump (void) const
-{
-#if defined (ACE_HAS_DUMP)
- 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 */
-#endif /* ACE_HAS_DUMP */
-}
-
-void
-ACE_OS::mutex_lock_cleanup (void *mutex)
-{
- ACE_OS_TRACE ("ACE_OS::mutex_lock_cleanup");
-#if 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_THREADS */
-}
-
-#if defined (ACE_USES_WCHAR)
-void ACE_OS::checkUnicodeFormat (FILE* fp)
-{
- if (fp != 0)
- {
- // Due to the ACE_TCHAR definition, all default input files, such as
- // svc.conf, have to be in Unicode format (small endian) on WinCE
- // because ACE has all 'char' converted into ACE_TCHAR.
- // However, for TAO, ASCII files, such as IOR file, can still be read and
- // be written without any error since given buffers are all in 'char' type
- // instead of ACE_TCHAR. Therefore, it is user's reponsibility to select
- // correct buffer type.
-
- // At this point, check if the file is Unicode or not.
- WORD first_two_bytes;
- int numRead = ACE_OS::fread(&first_two_bytes, sizeof(WORD), 1, fp);
-
- if (numRead == 1)
- {
- if ((first_two_bytes != 0xFFFE) && // not a small endian Unicode file
- (first_two_bytes != 0xFEFF)) // not a big endian Unicode file
- {
- ACE_OS::fseek(fp, 0, FILE_BEGIN); // set file pointer back to the beginning
- }
- }
- // if it is a Unicode file, file pointer will be right next to the first two-bytes
- }
-}
-#endif // ACE_USES_WCHAR
-
-#if 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)
- {
-# if defined (ACE_HAS_WINCE)
- FILE *fp = ::_wfdopen (handle, mode);
- if (fp != 0)
- {
- checkUnicodeFormat(fp);
- return fp;
- }
-# else
- hmode &= _O_TEXT | _O_RDONLY | _O_APPEND;
-# if defined (ACE_WIN64)
- int fd = _open_osfhandle (intptr_t (handle), hmode);
-# else
- int fd = _open_osfhandle (long (handle), hmode);
-# endif /* ACE_WIN64 */
- 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 != 0)
- {
-# if defined (ACE_USES_WCHAR)
- checkUnicodeFormat(fp);
-# endif // ACE_USES_WCHAR
- return fp;
- }
- _close (fd);
- }
-# endif // ACE_HAS_WINCE
-
- ACE_OS::close (handle);
- }
- return 0;
-}
-#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");
- int result = 0;
- va_list ap;
- va_start (ap, format);
- ACE_OSCALL (::vfprintf (fp, format, ap), int, -1, result);
- va_end (ap);
- return result;
-}
-
-#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);
- ACE_OSCALL (::vprintf (format, ap), int, -1, result);
- 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);
- ACE_OSCALL (ACE_SPRINTF_ADAPTER (::vsprintf (buf, format, ap)), int, -1, result);
- 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 (_XOPEN_SOURCE) && (_XOPEN_SOURCE >= 500)
-
- // The XPG4/UNIX98/C99 signature of the wide-char sprintf has a
- // maxlen argument. Since this method doesn't supply one, pass in
- // the max possible length. If this isn't ok, use ACE_OS::snprintf().
- int result;
- va_list ap;
- va_start (ap, format);
- ACE_OSCALL (::vswprintf (buf, ULONG_MAX, format, ap), int, -1, result);
- va_end (ap);
- return result;
-
-# elif defined (ACE_WIN32)
- // Windows has vswprintf, but the signature is from the older ISO C
- // standard. Also see ACE_OS::snprintf() for more info on this.
-
- 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 */
-
-int
-ACE_OS::snprintf (char *buf, size_t maxlen, const char *format, ...)
-{
- // ACE_OS_TRACE ("ACE_OS::snprintf");
-#if defined (ACE_HAS_SNPRINTF)
- int result;
- va_list ap;
- va_start (ap, format);
-# if defined (ACE_WIN32)
- ACE_OSCALL (ACE_SPRINTF_ADAPTER (::_vsnprintf (buf, maxlen, format, ap)),
- int, -1, result);
- // Win32 doesn't 0-terminate the string if it overruns maxlen.
- if (result == -1)
- buf[maxlen-1] = '\0';
-# else
- ACE_OSCALL (ACE_SPRINTF_ADAPTER (::vsnprintf (buf, maxlen, format, ap)),
- int, -1, result);
-# endif /* ACE_WIN32 */
- va_end (ap);
- // In out-of-range conditions, C99 defines vsnprintf to return the number
- // of characters that would have been written if enough space was available.
- // Earlier variants of the vsnprintf() (e.g. UNIX98) defined it to return
- // -1. This method follows the C99 standard, but needs to guess at the
- // value; uses maxlen + 1.
- if (result == -1)
- result = ACE_static_cast (int, (maxlen + 1));
- return result;
-
-#else
- ACE_UNUSED_ARG (buf);
- ACE_UNUSED_ARG (maxlen);
- ACE_UNUSED_ARG (format);
- ACE_NOTSUP_RETURN (-1);
-#endif /* ACE_HAS_SNPRINTF */
-}
-
-#if defined (ACE_HAS_WCHAR)
-int
-ACE_OS::snprintf (wchar_t *buf, size_t maxlen, const wchar_t *format, ...)
-{
- // ACE_OS_TRACE ("ACE_OS::snprintf");
-#if (defined (_XOPEN_SOURCE) && (_XOPEN_SOURCE >= 500)) || defined (ACE_WIN32)
- int result;
- va_list ap;
- va_start (ap, format);
-# if defined (ACE_WIN32)
- // Microsoft's vswprintf() doesn't have the maxlen argument that
- // XPG4/UNIX98 define. They do, however, recommend use of _vsnwprintf()
- // as a substitute, which does have the same signature as the UNIX98 one.
- ACE_OSCALL (ACE_SPRINTF_ADAPTER (::_vsnwprintf (buf, maxlen, format, ap)),
- int, -1, result);
- // Win32 doesn't 0-terminate the string if it overruns maxlen.
- if (result == -1)
- buf[maxlen-1] = '\0';
-# else
- ACE_OSCALL (ACE_SPRINTF_ADAPTER (::vswprintf (buf, maxlen, format, ap)),
- int, -1, result);
-# endif /* ACE_WIN32 */
- va_end (ap);
- // In out-of-range conditions, C99 defines vsnprintf to return the number
- // of characters that would have been written if enough space was available.
- // Earlier variants of the vsnprintf() (e.g. UNIX98) defined it to return
- // -1. This method follows the C99 standard, but needs to guess at the
- // value; uses maxlen + 1.
- if (result == -1)
- result = ACE_static_cast (int, (maxlen + 1));
- return result;
-
-#else
- ACE_UNUSED_ARG (buf);
- ACE_UNUSED_ARG (maxlen);
- ACE_UNUSED_ARG (format);
- ACE_NOTSUP_RETURN (-1);
-#endif /* ACE_HAS_SNPRINTF */
-}
-#endif /* ACE_HAS_WCHAR */
-
-char *
-ACE_OS::gets (char *str, int n)
-{
- ACE_OS_TRACE ("ACE_OS::gets");
- 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;
-}
-
-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 (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 ||
- sched_params.policy () == ACE_SCHED_RR)
- ? 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 /* CHORUS */
-}
-
-// = 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.
@@ -1621,888 +25,8 @@ 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)
-{
-#if defined (ACE_HAS_DUMP)
- // 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 */
-#endif /* ACE_HAS_DUMP */
-}
-
-// 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
- *
- * @brief Singleton that knows how to clean up all the thread-specific
- * resources for Win32.
- *
- * All this nonsense is required since Win32 doesn't
- * automatically cleanup thread-specific storage on thread exit,
- * unlike real operating systems... ;-)
- */
-class ACE_TSS_Cleanup
-{
-public:
- static ACE_TSS_Cleanup *instance (void);
-
- ~ACE_TSS_Cleanup (void);
-
- /// Cleanup the thread-specific objects. Does _NOT_ exit the thread.
- void exit (void *status);
-
- /// Insert a <key, destructor> tuple into the table.
- int insert (ACE_thread_key_t key, void (*destructor)(void *), void *inst);
-
- /// Remove a <key, destructor> tuple from the table.
- int remove (ACE_thread_key_t key);
-
- /// Detaches a tss_instance from its key.
- int detach (void *inst);
-
- /// Mark a key as being used by this thread.
- void key_used (ACE_thread_key_t key);
-
- /// Free all keys left in the table before destruction.
- int free_all_keys_left (void);
-
- /// Indication of whether the ACE_TSS_CLEANUP_LOCK is usable, and
- /// therefore whether we are in static constructor/destructor phase
- /// or not.
- static int lockable () { return instance_ != 0; }
-
-protected:
- void dump (void);
-
- /// Ensure singleton.
- ACE_TSS_Cleanup (void);
-
-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;
-
- /// Table of <ACE_TSS_Info>'s.
- ACE_TSS_TABLE table_;
-
- /// Key for the thread-specific array of whether each TSS key is in use.
- ACE_thread_key_t in_use_;
-
- /// Accessor for this threads ACE_TSS_Keys instance.
- ACE_TSS_Keys *tss_keys ();
-
-#if defined (ACE_HAS_TSS_EMULATION)
- /// 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 ().
- ACE_thread_key_t in_use_key_;
-#endif /* ACE_HAS_TSS_EMULATION */
-
- // = Static data.
- /// Pointer to the singleton instance.
- static ACE_TSS_Cleanup *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 test/clear the in "use bit" if the program is
- // shutting down. Doing so will cause a new ACE_TSS object to be
- // created again.
- if (!ACE_OS_Object_Manager::shutting_down ())
- tss_keys ()->test_and_clear (info.key_);
- info.key_in_use (0);
- 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.key_in_use ())
- key_info.key_in_use (1);
- else
- ++key_info.thread_count_;
- }
-}
-
-void
-ACE_TSS_Cleanup::dump (void)
-{
-#if defined (ACE_HAS_DUMP)
- // 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 ();
-#endif /* ACE_HAS_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) \
+# 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)
@@ -2513,7 +37,7 @@ struct __IBMCPP__thread_params {
LPVOID args;
};
-#pragma handler(initThread)
+# pragma handler(initThread)
extern "C" DWORD __stdcall __IBMCPP__initThread(void *arg)
{
// Must reset 387 since using CreateThread
@@ -2541,1950 +65,23 @@ HANDLE WINAPI __IBMCPP__beginthreadex(void *stack,
thr_id);
}
-#define ACE_BEGINTHREADEX(STACK, STACKSIZE, 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) \
+# define ACE_BEGINTHREADEX(STACK, STACKSIZE, ENTRY_POINT, ARGS, FLAGS, THR_ID) \
CreateThread (0, 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) \
+# 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) */
-
-
- 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 defined (ACE_HAS_PTHREAD_SETSTACK)
- if ((stacksize != 0) && (stack != 0))
-# else
- if (stacksize != 0)
-# endif /* ACE_HAS_PTHREAD_SETSTACK */
- {
- 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 defined (ACE_HAS_PTHREAD_SETSTACK)
- if (ACE_ADAPT_RETVAL(pthread_attr_setstack (&attr, stack, size), result) == -1)
-# else
- if (ACE_ADAPT_RETVAL(pthread_attr_setstacksize (&attr, size), result) == -1)
-# endif /* ACE_HAS_PTHREAD_SETSTACK */
-# 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_HAS_PTHREAD_SETSTACK)
-# 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 */
-# endif /* ACE_HAS_PTHREAD_SETSTACK */
-
- // *** 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,
- ACE_static_cast
- (u_int, 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 */
-}
-
-void
-ACE_OS::thr_exit (ACE_THR_FUNC_RETURN status)
-{
- ACE_OS_TRACE ("ACE_OS::thr_exit");
-#if 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 (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 (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_THREADS */
-}
-
-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 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_THREADS */
-}
-
-int
-ACE_OS::thr_keyfree (ACE_thread_key_t key)
-{
- ACE_OS_TRACE ("ACE_OS::thr_keyfree");
-# if 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_THREADS */
-}
-
-# 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_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_THREADS */
-}
-# 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 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_THREADS */
-}
-
-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 ("%p%d"),
- 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;
-
- size_t 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_String::strlen (temp);
- else
-#endif /* ACE_LACKS_ENV */
- buf_len += ACE_OS_String::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,
- int &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 != ACE_LIB_TEXT ('\0') && *cp != ACE_LIB_TEXT ('#'))
- {
- // Skip whitespace..
- while (ACE_OS::ace_isspace (*cp))
- cp++;
-
- // Increment count and move to next whitespace..
- if (*cp != ACE_LIB_TEXT ('\0'))
- argc++;
-
- while (*cp != ACE_LIB_TEXT ('\0') && !ACE_OS::ace_isspace (*cp))
- {
- // Grok quotes....
- if (*cp == ACE_LIB_TEXT ('\'') || *cp == ACE_LIB_TEXT ('"'))
- {
- ACE_TCHAR quote = *cp;
-
- // Scan past the string..
- for (cp++; *cp != ACE_LIB_TEXT ('\0') && *cp != quote; cp++)
- continue;
-
- // '\0' implies unmatched quote..
- if (*cp == ACE_LIB_TEXT ('\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 (int 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 != ACE_LIB_TEXT ('\0') && !ACE_OS::ace_isspace (*ptr))
- if (*ptr == ACE_LIB_TEXT ('\'') || *ptr == ACE_LIB_TEXT ('"'))
- {
- ACE_TCHAR quote = *ptr++;
-
- while (*ptr != ACE_LIB_TEXT ('\0') && *ptr != quote)
- *cp++ = *ptr++;
-
- if (*ptr == quote)
- ptr++;
- }
- else
- *cp++ = *ptr++;
-
- *cp = ACE_LIB_TEXT ('\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;
- ssize_t 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 (0, 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 (0, 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() */
+#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.
@@ -4552,8 +149,6 @@ spa (FUNCPTR entry, ...)
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)
@@ -4669,7 +264,6 @@ spae (FUNCPTR entry, ...)
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.
@@ -4714,1918 +308,9 @@ spaef (FUNCPTR entry, ...)
// Return the return value of the invoked ace_main routine.
return ret;
}
-# endif /* VXWORKS */
-
-# if !defined (ACE_HAS_SIGINFO_T)
-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_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;
-}
-
-void
-ACE_Thread_ID::to_string (char* thr_id)
-{
-
- char format[128]; // Converted format string
- char *fp; // Current format pointer
- fp = format;
- *fp++ = '%'; // Copy in the %
-
-#if defined (ACE_WIN32)
- ACE_OS::strcpy (fp, "u");
- ACE_OS::sprintf (thr_id,
- format,
- ACE_static_cast(unsigned,
- ACE_OS::thr_self ()));
-#elif defined (ACE_AIX_VERS) && (ACE_AIX_VERS <= 402)
- // AIX's pthread_t (ACE_hthread_t) is a pointer, and it's
- // a little ugly to send that through a %u format. So,
- // get the kernel thread ID (tid_t) via thread_self() and
- // display that instead.
- // This isn't conditionalized on ACE_HAS_THREAD_SELF because
- // 1. AIX 4.2 doesn't have that def anymore (it messes up
- // other things)
- // 2. OSF/1 V3.2 has that def, and I'm not sure what affect
- // this would have on that.
- // -Steve Huston, 19-Aug-97
- ACE_OS::strcpy (fp, "u");
- ACE_OS::sprintf (thr_id, format, thread_self());
-#elif defined (DIGITAL_UNIX)
- ACE_OS::strcpy (fp, "u");
- ACE_OS::sprintf (thr_id, format,
-# if defined (ACE_HAS_THREADS)
- pthread_getselfseq_np ()
-# else
- ACE_Thread::self ()
-# endif /* ACE_HAS_THREADS */
- );
-#else
- ACE_hthread_t t_id;
- ACE_OS::thr_self (t_id);
-
-# if defined (ACE_HAS_PTHREADS_DRAFT4) && defined (HPUX_10)
- ACE_OS::strcpy (fp, "u");
- // HP-UX 10.x DCE's thread ID is a pointer. Grab the
- // more meaningful, readable, thread ID. This will match
- // the one seen in the debugger as well.
- ACE_OS::sprintf (thr_id, format,
- pthread_getunique_np(&t_id));
-# elif defined (ACE_MVS)
- // MVS's pthread_t is a struct... yuck. So use the ACE 5.0
- // code for it.
- ACE_OS::strcpy (fp, "u");
- ACE_OS::sprintf (thr_id, format, t_id);
-# else
- // Yes, this is an ugly C-style cast, but the correct
- // C++ cast is different depending on whether the t_id
- // is an integral type or a pointer type. FreeBSD uses
- // a pointer type, but doesn't have a _np function to
- // get an integral type, like the OSes above.
- ACE_OS::strcpy (fp, "lu");
- ACE_OS::sprintf (thr_id, format, (unsigned long)t_id);
-# endif /* ACE_HAS_PTHREADS_DRAFT4 && HPUX_10 */
-
-#endif /* ACE_WIN32 */
-}
-
-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;
- }
-#elif defined (VXWORKS)
- // inet_aton() returns OK (0) on success and ERROR (-1) on failure.
- // Must reset errno first. Refer to WindRiver SPR# 34949, SPR# 36026
- ::errnoSet(0);
- int result = ERROR;
- ACE_OSCALL (::inet_aton ((char*)host_name, addr), int, ERROR, result);
- return (result == ERROR) ? 0 : 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;
- }
-#elif defined (ACE_HAS_WINCE)
- // This is really stupid, converting FILETIME to timeval back and
- // forth. It assumes FILETIME and DWORDLONG are the same structure
- // internally.
-
- TIME_ZONE_INFORMATION pTz;
-
- const unsigned short int __mon_yday[2][13] =
- {
- /* Normal years. */
- { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365 },
- /* Leap years. */
- { 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366 }
- };
-
- ULARGE_INTEGER _100ns;
- ::GetTimeZoneInformation (&pTz);
-
- _100ns.QuadPart = (DWORDLONG) *t * 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);
-
- res->tm_hour = systime.wHour;
-
- if(pTz.DaylightBias!=0)
- res->tm_isdst = 1;
- else
- res->tm_isdst = 1;
-
- int iLeap;
- iLeap = (res->tm_year % 4 == 0 && (res->tm_year% 100 != 0 || res->tm_year % 400 == 0));
- // based on leap select which group to use
-
- res->tm_mday = systime.wDay;
- res->tm_min = systime.wMinute;
- res->tm_mon = systime.wMonth;
- res->tm_sec = systime.wSecond;
- res->tm_wday = systime.wDayOfWeek;
- res->tm_yday = __mon_yday[iLeap][systime.wMonth] + systime.wDay;
- res->tm_year = systime.wYear;// this the correct year but bias the value to start at the 1900
- res->tm_year = res->tm_year - 1900;
-
- 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,
- 0,
- FILE_CURRENT);
-
- if (original_position == 0xFFFFFFFF)
- return -1;
-
- // Go to the correct position
- DWORD altered_position = ::SetFilePointer (handle,
- offset,
- 0,
- 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,
- ACE_static_cast (DWORD, 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,
- 0);
- if (result == FALSE)
- return -1;
-
-# endif /* ACE_HAS_WINNT4 && (ACE_HAS_WINNT4 != 0) */
-
- // Reset the original file pointer position
- if (::SetFilePointer (handle,
- original_position,
- 0,
- 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,
- 0,
- FILE_CURRENT);
-
- if (original_position == 0xFFFFFFFF)
- return -1;
-
- // Go to the correct position
- DWORD altered_position = ::SetFilePointer (handle,
- offset,
- 0,
- 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,
- ACE_static_cast (DWORD, 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,
- 0);
- if (result == FALSE)
- return -1;
-
-# endif /* ACE_HAS_WINNT4 && (ACE_HAS_WINNT4 != 0) */
-
- // Reset the original file pointer position
- if (::SetFilePointer (handle,
- original_position,
- 0,
- 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) */
-#elif defined (INTEGRITY)
- ACE_UNUSED_ARG (sa);
- if(!strcmp(filename,ACE_DEV_NULL)) {
- ACE_OSCALL_RETURN (::AllocateNullConsoleDescriptor(), ACE_HANDLE, -1);
- }
- else {
- ACE_OSCALL_RETURN (::open (filename, mode, perms), ACE_HANDLE, -1);
- }
-#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.
- {
- errno = ERANGE;
- 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 */
-
-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);
-# elif defined (ACE_HAS_WINCE)
- SYSTEMTIME t_sys;
- FILETIME t_file;
- t_sys.wSecond = t->tm_sec;
- t_sys.wMinute = t->tm_min;
- t_sys.wHour = t->tm_hour;
- t_sys.wDay = t->tm_mday;
- t_sys.wMonth = t->tm_mon + 1; // SYSTEMTIME is 1-indexed, tm is 0-indexed
- t_sys.wYear = t->tm_year + 1900; // SYSTEMTIME is real; tm is since 1900
- t_sys.wDayOfWeek = t->tm_wday; // Ignored in below function call.
- if (SystemTimeToFileTime (&t_sys, &t_file) == 0)
- return -1;
- ACE_Time_Value tv (t_file);
- return tv.sec ();
-# 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 */
-}
-
-# 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 defined (ACE_LACKS_COND_T) && ! defined (ACE_PSOS_DIAB_MIPS)
-// 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_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.
- ACE_WIN32CALL (ACE_ADAPT_RETVAL (::SignalObjectAndWait (external_mutex->proc_mutex_,
- cv->sema_, INFINITE, FALSE),
- result),
- int, -1, result);
- 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_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.
- result = ::SignalObjectAndWait (external_mutex->proc_mutex_,
- cv->sema_,
- msec_timeout,
- FALSE);
- 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_,
- timeout);
-# 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_,
- timeout);
-
- 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 */
+#endif /* VXWORKS */
-# if defined (__DGUX) && defined (ACE_HAS_THREADS) && defined (_POSIX4A_DRAFT10_SOURCE)
+#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)
@@ -6639,1237 +324,40 @@ extern "C" int __d10_sigwait (const sigset_t *set, int *sig)
*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,
- 0,
- ::GetLastError (),
- MAKELANGID (LANG_NEUTRAL,
- SUBLANG_DEFAULT),
- // Default language
- (ACE_TCHAR *) &lpMsgBuf,
- 0,
- 0);
- ::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
- *
- * @brief Ensure that the <ACE_OS_Object_Manager> gets initialized at
- * program startup, and destroyed at program termination.
- *
- * 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.
- */
-class ACE_OS_Object_Manager_Manager
-{
-public:
- /// Constructor.
- ACE_OS_Object_Manager_Manager (void);
-
- /// Destructor.
- ~ACE_OS_Object_Manager_Manager (void);
-
-private:
- /// Save the main thread ID, so that destruction can be suppressed.
- ACE_thread_t saved_main_thread_id_;
-};
-
-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 */
-
-// 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 */
-
-#if !defined (ACE_HAS_WINCE)
-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 */
-}
-#endif // ACE_HAS_WINCE
-
-long
-ACE_OS::num_processors (void)
-{
- ACE_OS_TRACE ("ACE_OS::num_processors");
-#if defined (ACE_HAS_PHARLAP)
- return 1;
-#elif defined (ACE_WIN32) || defined (ACE_WIN64)
- SYSTEM_INFO sys_info;
- ::GetSystemInfo (&sys_info);
- return sys_info.dwNumberOfProcessors;
-#elif defined (linux) || defined (sun)
- return ::sysconf (_SC_NPROCESSORS_CONF);
-#else
- ACE_NOTSUP_RETURN (-1);
-#endif
-}
-
-long
-ACE_OS::num_processors_online (void)
-{
- ACE_OS_TRACE ("ACE_OS::num_processors_online");
-#if defined (ACE_HAS_PHARLAP)
- return 1;
-#elif defined (ACE_WIN32) || defined (ACE_WIN64)
- SYSTEM_INFO sys_info;
- ::GetSystemInfo (&sys_info);
- return sys_info.dwNumberOfProcessors;
-#elif defined (linux) || defined (sun)
- return ::sysconf (_SC_NPROCESSORS_ONLN);
-#elif defined (__hpux)
- struct pst_dynamic psd;
- if (::pstat_getdynamic (&psd, sizeof (psd), (size_t) 1, 0) != -1)
- return psd.psd_proc_cnt;
- else
- return -1;
-#else
- ACE_NOTSUP_RETURN (-1);
-#endif
-}
-
-// Include if_arp so that getmacaddr can use the
-// arp structure.
-#if defined (sun)
-# include /**/ <net/if_arp.h>
-#endif
-
-int
-ACE_OS::getmacaddress (struct macaddr_node_t *node)
-{
- ACE_OS_TRACE ("ACE_OS::getmacaddress");
-
-#if defined (ACE_WIN32) && !defined (ACE_HAS_WINCE)
-
- /** Define a structure for use with the netbios routine */
- struct ADAPTERSTAT
- {
- ADAPTER_STATUS adapt;
- NAME_BUFFER NameBuff [30];
- };
-
- NCB ncb;
- LANA_ENUM lenum;
- unsigned char result;
-
- ACE_OS::memset (&ncb, 0, sizeof(ncb));
- ncb.ncb_command = NCBENUM;
- ncb.ncb_buffer = ACE_reinterpret_cast (unsigned char*,&lenum);
- ncb.ncb_length = sizeof(lenum);
-
- result = Netbios (&ncb);
-
- for(int i = 0; i < lenum.length; i++)
- {
- ACE_OS::memset (&ncb, 0, sizeof(ncb));
- ncb.ncb_command = NCBRESET;
- ncb.ncb_lana_num = lenum.lana [i];
-
- /** Reset the netbios */
- result = Netbios (&ncb);
-
- if (ncb.ncb_retcode != NRC_GOODRET)
- {
- return -1;
- }
-
- ADAPTERSTAT adapter;
- ACE_OS::memset (&ncb, 0, sizeof (ncb));
-# if defined (__BORLANDC__) || defined (__MINGW32__)
- ACE_OS::strcpy (ACE_reinterpret_cast (char*, ncb.ncb_callname), "*");
-# else
- ACE_OS::strcpy (ACE_static_cast (char*, ncb.ncb_callname), "*");
-# endif /* __BORLANDC__ || __MINGW32__ */
- ncb.ncb_command = NCBASTAT;
- ncb.ncb_lana_num = lenum.lana[i];
- ncb.ncb_buffer = ACE_reinterpret_cast (unsigned char*, &adapter);
- ncb.ncb_length = sizeof (adapter);
-
- result = Netbios (&ncb);
-
- if (result == 0)
- {
- ACE_OS::memcpy (node->node,
- adapter.adapt.adapter_address,
- 6);
- return 0;
- }
- }
- return 0;
-#elif defined (sun)
-
- /** obtain the local host name */
- char hostname [MAXHOSTNAMELEN];
- ACE_OS::hostname (hostname, sizeof (hostname));
-
- /** Get the hostent to use with ioctl */
- struct hostent *phost =
- ACE_OS::gethostbyname (hostname);
-
- if (phost == 0)
- {
- return -1;
- }
-
- ACE_HANDLE handle =
- ACE_OS::socket (PF_INET, SOCK_DGRAM, IPPROTO_UDP);
-
- if (handle == ACE_INVALID_HANDLE)
- {
- return -1;
- }
-
- char **paddrs = phost->h_addr_list;
-
- struct arpreq ar;
-
- struct sockaddr_in *psa =
- (struct sockaddr_in *)&(ar.arp_pa);
-
- ACE_OS::memset (&ar,
- 0,
- sizeof (struct arpreq));
-
- psa->sin_family = AF_INET;
-
- ACE_OS::memcpy (&(psa->sin_addr),
- *paddrs,
- sizeof (struct in_addr));
-
- if (ACE_OS::ioctl (handle,
- SIOCGARP,
- &ar) == -1)
- {
- return -1;
- }
-
- ACE_OS::close (handle);
-
- ACE_OS::memcpy (node->node,
- ar.arp_ha.sa_data,
- 6);
-
- return 0;
-
-#elif defined (linux)
-
- struct ifreq ifr;
-
- ACE_HANDLE handle =
- ACE_OS::socket (PF_INET, SOCK_DGRAM, 0);
-
- if (handle == ACE_INVALID_HANDLE)
- {
- return -1;
- }
-
- ACE_OS::strcpy (ifr.ifr_name, "eth0");
-
- if (ACE_OS::ioctl (handle/*s*/, SIOCGIFHWADDR, &ifr) < 0)
- {
- ACE_OS::close (handle);
- return -1;
- }
-
- struct sockaddr* sa =
- (struct sockaddr *) &ifr.ifr_addr;
-
- ACE_OS::memcpy (node->node,
- sa->sa_data,
- 6);
-
- return 0;
-
-#else
- ACE_UNUSED_ARG (node);
- ACE_NOTSUP_RETURN (-1);
-#endif
-}
+#endif /* __DGUX && PTHREADS && _POSIX4A_DRAFT10_SOURCE */
+
+
+// include new cpps
+#include "ace/Cleanup.cpp"
+#include "ace/Object_Manager_Base.cpp"
+#include "ace/OS_NS_arpa_inet.cpp"
+#include "ace/OS_NS_ctype.cpp"
+#include "ace/OS_NS_dirent.cpp"
+#include "ace/OS_NS_dlfcn.cpp"
+#include "ace/OS_NS_errno.cpp"
+#include "ace/OS_NS_fcntl.cpp"
+#include "ace/OS_NS_math.cpp"
+#include "ace/OS_NS_netdb.cpp"
+#include "ace/OS_NS_poll.cpp"
+#include "ace/OS_NS_pwd.cpp"
+#include "ace/OS_NS_signal.cpp"
+#include "ace/OS_NS_stdio.cpp"
+#include "ace/OS_NS_stdlib.cpp"
+#include "ace/OS_NS_string.cpp"
+#include "ace/OS_NS_strings.cpp"
+#include "ace/OS_NS_stropts.cpp"
+#include "ace/OS_NS_sys_mman.cpp"
+#include "ace/OS_NS_sys_msg.cpp"
+#include "ace/OS_NS_sys_resource.cpp"
+#include "ace/OS_NS_sys_select.cpp"
+#include "ace/OS_NS_sys_shm.cpp"
+#include "ace/OS_NS_sys_socket.cpp"
+#include "ace/OS_NS_sys_stat.cpp"
+#include "ace/OS_NS_sys_time.cpp"
+#include "ace/OS_NS_sys_uio.cpp"
+#include "ace/OS_NS_sys_utsname.cpp"
+#include "ace/OS_NS_sys_wait.cpp"
+#include "ace/OS_NS_Thread.cpp"
+#include "ace/OS_NS_time.cpp"
+#include "ace/OS_NS_unistd.cpp"
+#include "ace/OS_NS_wchar.cpp"
diff --git a/ace/OS.h b/ace/OS.h
index d8a01951cb0..c1d6ed5984a 100644
--- a/ace/OS.h
+++ b/ace/OS.h
@@ -19,14 +19,45 @@
#include "ace/config-all.h"
-#if defined (ACE_HAS_VIRTUAL_TIME)
-#include "ace/os_include/sys/os_times.h"
-#endif /*ACE_HAS_VIRTUAL_TIME*/
-
#if !defined (ACE_LACKS_PRAGMA_ONCE)
# pragma once
#endif /* ACE_LACKS_PRAGMA_ONCE */
+#include "ace/Cleanup.h"
+#include "ace/Object_Manager_Base.h"
+#include "ace/OS_main.h"
+#include "ace/OS_NS_arpa_inet.h"
+#include "ace/OS_NS_ctype.h"
+#include "ace/OS_NS_dirent.h"
+#include "ace/OS_NS_dlfcn.h"
+#include "ace/OS_NS_errno.h"
+#include "ace/OS_NS_fcntl.h"
+#include "ace/OS_NS_math.h"
+#include "ace/OS_NS_netdb.h"
+#include "ace/OS_NS_poll.h"
+#include "ace/OS_NS_pwd.h"
+#include "ace/OS_NS_signal.h"
+#include "ace/OS_NS_stdio.h"
+#include "ace/OS_NS_stdlib.h"
+#include "ace/OS_NS_string.h"
+#include "ace/OS_NS_strings.h"
+#include "ace/OS_NS_stropts.h"
+#include "ace/OS_NS_sys_mman.h"
+#include "ace/OS_NS_sys_msg.h"
+#include "ace/OS_NS_sys_resource.h"
+#include "ace/OS_NS_sys_select.h"
+#include "ace/OS_NS_sys_shm.h"
+#include "ace/OS_NS_sys_socket.h"
+#include "ace/OS_NS_sys_stat.h"
+#include "ace/OS_NS_sys_time.h"
+#include "ace/OS_NS_sys_uio.h"
+#include "ace/OS_NS_sys_utsname.h"
+#include "ace/OS_NS_sys_wait.h"
+#include "ace/OS_NS_Thread.h"
+#include "ace/OS_NS_time.h"
+#include "ace/OS_NS_unistd.h"
+#include "ace/OS_NS_wchar.h"
+
// Include the split up ACE_OS classes
#include "ace/OS_Dirent.h"
#include "ace/OS_String.h"
@@ -66,16 +97,18 @@ class ACE_Timeout_Manager;
// //
///////////////////////////////////////////
-# if defined (ACE_PSOS)
+#include "ace/os_include/netinet/os_tcp.h"
+#include "ace/os_include/sys/os_stat.h"
+#include "ace/os_include/os_stropts.h"
+#include "ace/os_include/os_unistd.h"
+#include "ace/os_include/sys/os_wait.h"
-# if defined (ACE_PSOSIM)
-# include /**/ "ace/sys_conf.h" /* system configuration file */
+# if defined (ACE_PSOS)
+# include /**/ "ace/sys_conf.h" /* system configuration file */
+# include /**/ <pna.h> /* pNA+ TCP/IP Network Manager calls */
+# if defined (ACE_PSOSIM)
# include /**/ <psos.h> /* pSOS+ system calls */
-# include /**/ <pna.h> /* pNA+ TCP/IP Network Manager calls */
-
-
-
/* include <rpc.h> pRPC+ Remote Procedure Call Library calls */
/* are not supported by pSOSim */
/* */
@@ -85,115 +118,17 @@ class ACE_Timeout_Manager;
/* 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 "ace/os_include/sys/os_stat.h"
-# include "ace/os_include/os_stropts.h" // instead of <sys/ioctl.h>
-# include "ace/os_include/netinet/os_tcp.h"
-
# else
-
-# 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 "ace/os_include/os_unistd.h" /* Diab Data supplied file system calls */
-# else
+# if !defined (ACE_PSOS_USES_DIAB_SYS_CALLS)
# include /**/ <prepc.h>
# endif /* ACE_PSOS_USES_DIAB_SYS_CALLS */
-# include "ace/os_include/sys/os_wait.h" /* Diab Data supplied header file */
# endif /* ACE_PSOS_DIAB_MIPS */
-
# endif /* defined (ACE_PSOSIM) */
-
-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
-{
- /// Semaphore handle. This is allocated by pSOS.
- u_long sema_;
-
- /// Name of the semaphore: really a 32 bit number to pSOS
- char name_[4];
-} ACE_sema_t;
-
-# define ACE_SEH_TRY if (1)
-# define ACE_SEH_EXCEPT(X) while (0)
-# define ACE_SEH_FINALLY if (1)
-
-#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) **********************************************/
// This needs to go here *first* to avoid problems with AIX.
@@ -201,264 +136,6 @@ private:
# include "ace/os_include/os_pthread.h"
# endif /* ACE_HAS_PTHREADS */
-// 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_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 */
-
-/**
- * @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);
-
- /// Returns 1 if we've already been stopped, else 0.
- int stopped (void) const;
-
-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_;
-};
-
-// 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_SOCK_SEQPACK_*
-# define ACE_SOCK_SEQPACK_ACCEPTOR ACE_SOCK_SEQPACK_Acceptor
-# define ACE_SOCK_SEQPACK_CONNECTOR ACE_SOCK_SEQPACK_Connector
-# define ACE_SOCK_SEQPACK_ASSOCIATION ACE_SOCK_SEQPACK_Association
-
-// 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_SOCK_SEQPACK_*
-# define ACE_SOCK_SEQPACK_ACCEPTOR ACE_SOCK_SEQPACK_Acceptor, ACE_INET_Addr
-# define ACE_SOCK_SEQPACK_CONNECTOR ACE_SOCK_SEQPACK_Connector, ACE_INET_Addr
-# define ACE_SOCK_SEQPACK_ASSOCIATION ACE_SOCK_SEQPACK_Association, 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 */
-
# if defined (ACE_HAS_PROC_FS)
# include /**/ <sys/procfs.h>
# endif /* ACE_HAS_PROC_FS */
@@ -467,650 +144,12 @@ private:
# include "ace/os_include/os_semaphore.h"
# endif /* ACE_HAS_POSIX_SEM */
-# include "ace/os_include/sys/os_types.h" // /**/ <types.h>
-
-# include "ace/os_include/os_stddef.h" // WinCE .NET puts it in stddef.h
+#include "ace/os_include/sys/os_types.h"
+#include "ace/os_include/os_stddef.h"
#if !defined (ACE_LACKS_UNISTD_H)
# include "ace/os_include/os_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)
-// moved to pthread.h
-# 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)
-# include /**/ <sysLib.h> // for sysClkRateGet()
-# include /**/ <taskLib.h>
-# include /**/ <taskHookLib.h>
-
-// make sure these are included for VXWORKS.
-// @todo move these to a common place, perhaps the top of the file.
-#include "ace/os_include/os_fcntl.h"
-#include "ace/os_include/os_netdb.h"
-#include "ace/os_include/os_semaphore.h"
-#include "ace/os_include/os_signal.h"
-#include "ace/os_include/os_stdio.h"
-#include "ace/os_include/os_stdlib.h"
-#include "ace/os_include/os_stropts.h"
-#include "ace/os_include/os_unistd.h"
-#include "ace/os_include/arpa/os_inet.h"
-#include "ace/os_include/sys/os_select.h"
-#include "ace/os_include/sys/os_socket.h"
-
-// 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_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 */
-
-typedef SEM_ID ACE_mutex_t;
-// 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
-{
- /// Semaphore handle. This is allocated by VxWorks.
- SEM_ID sema_;
-
- /// Name of the semaphore: always NULL with VxWorks.
- char *name_;
-} ACE_sema_t;
-# endif /* !ACE_HAS_POSIX_SEM */
-typedef char * ACE_thread_t;
-typedef int ACE_hthread_t;
-// 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;
-
-typedef struct
-{
- /// Either USYNC_THREAD or USYNC_PROCESS
- int type_;
- union
- {
- HANDLE proc_mutex_;
- CRITICAL_SECTION thr_mutex_;
- };
-} ACE_mutex_t;
-
-// Wrapper for NT Events.
-typedef HANDLE ACE_event_t;
-
-# if defined (ACE_WIN32)
-//@@ 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 /* 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)
-/**
- * @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;
-};
-
-struct ACE_OS_Export ACE_mutexattr_t
-{
- int type;
-};
-# 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 */
-
-// Recursive mutex support.
-//
-// There are two parts to this:
-// 1. The mutex type itself. This is based on whether or not the
-// platform supports recursive mutexes natively or they're emulated.
-// 2. Support for using the recursive mutex with a condition variable.
-// When a thread waits on a condition variable, it has to relinquish
-// the lock and wait atomically, then reacquire it after the condition
-// variable is signaled. In non-recursive mutexes, the platform
-// handles this automatically. But in recursive mutexes, especially
-// when emulated, the recursion count needs to be maintained across
-// the wait. Since another thread needs to be able to acquire the
-// lock, it needs to appear free, even if the waiting thread had done
-// multiple acquires. Thus, there's another structure to hold this
-// information, and is used with the recursive_mutex_cond_unlock()
-// and recursive_mutex_cond_relock() methods to maintain the expected
-// state when the wait finishes.
-#if defined (ACE_HAS_RECURSIVE_MUTEXES)
-typedef ACE_thread_mutex_t ACE_recursive_thread_mutex_t;
-# if defined (ACE_WIN32)
-// Windows has recursive mutexes, but doesn't have condition variables,
-// so there's no built-in support for this. Thus, the condition-related
-// unlock/relock is augmented in ACE.
-struct ACE_recursive_mutex_state
-{
- // On Windows the augmented processing is simply unlocking/relocking
- // the recursive locks - the condition handles a single lock ok.
- LONG relock_count_;
-};
-# else
-// No need for special handling; just need a type for method signatures.
-typedef int ACE_recursive_mutex_state;
-# endif /* ACE_WIN32 */
-#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_;
-};
-
-// Since recursive mutex is emulated, the state saving needs to be handled
-// in ACE as well. These members save those from ACE_recursive_thread_mutex_t.
-struct ACE_recursive_mutex_state
-{
- int nesting_level_;
- ACE_thread_t owner_id_;
-};
-#endif /* ACE_HAS_RECURSIVE_MUTEXES */
-
-# 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;
-typedef int ACE_recursive_mutex_state;
-# 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 unsigned 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 "ace/os_include/os_stdarg.h"
@@ -1162,11 +201,6 @@ protected:
# endif /* ACE_HAS_BYTESEX_H */
# include "ace/Basic_Types.h"
-// 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_UTIME)
# include "ace/os_include/os_utime.h"
# endif /* ACE_HAS_UTIME */
@@ -1177,39 +211,10 @@ static const ACE_UINT32 ACE_U_ONE_SECOND_IN_NSECS = 1000000000U;
# include "ace/os_include/sys/os_timeb.h"
# endif /* ACE_HAS_WINCE */
-# 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 /* ACE_HAS_WIN32_STRUCTURAL_EXCEPTIONS */
-
-// The "null" device on Win32.
-# define ACE_DEV_NULL "nul"
-
# if defined (ACE_HAS_WINSOCK2) && (ACE_HAS_WINSOCK2 != 0)
# include "ace/os_include/netinet/os_in.h" // <ws2tcpip.h>
# endif /* ACE_HAS_WINSOCK2 */
-
-
# if !defined (ACE_HAS_WINCE)
# include "ace/os_include/os_time.h"
# include "ace/os_include/sys/os_stat.h" // <direct.h>
@@ -1218,126 +223,8 @@ static const ACE_UINT32 ACE_U_ONE_SECOND_IN_NSECS = 1000000000U;
# include "ace/os_include/os_fcntl.h"
-typedef DWORD ACE_thread_t;
-typedef HANDLE ACE_hthread_t;
-
-# 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.
-
-// These are used in SPIPE_Acceptor/Connector, but are ignored at runtime.
-# if defined (ACE_HAS_WINCE)
-# if !defined (PIPE_TYPE_MESSAGE)
-# define PIPE_TYPE_MESSAGE 0
-# endif
-# if !defined (PIPE_READMODE_MESSAGE)
-# define PIPE_READMODE_MESSAGE 0
-# endif
-# if !defined (PIPE_WAIT)
-# define PIPE_WAIT 0
-# endif
-# endif /* ACE_HAS_WINCE */
-
-# 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.
-
-
-typedef int ACE_idtype_t;
-typedef DWORD ACE_id_t;
-# define ACE_SELF (0)
-typedef int ACE_pri_t;
-
-# elif defined (ACE_PSOS)
-
-typedef ACE_UINT64 ACE_hrtime_t;
-
# else /* !defined (ACE_WIN32) && !defined (ACE_PSOS) */
-# if defined (m88k)
-# define RUSAGE_SELF 1
-# endif /* m88k */
-
-// Be consistent with Winsock naming
-# 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)
-
-// The "null" device on UNIX.
-# define ACE_DEV_NULL "/dev/null"
-
-/**
- * @class ACE_event_t
- *
- * @brief 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.
- unsigned long waiting_threads_;
-};
-
-
-# if defined (ACE_VXWORKS) && ACE_VXWORKS <= 0x540
- // 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 /* ! (ACE_VXWORKS) && ACE_VXWORKS <= 0x540 */
-# include "ace/os_include/arpa/os_inet.h"
-# endif /* ! (ACE_VXWORKS) && ACE_VXWORKS <= 0x540 */
-
-# 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 "ace/os_include/netinet/os_tcp.h"
-# endif /* ACE_LACKS_TCP_H */
-
# if defined (CHORUS)
# include /**/ <chorus.h>
# if !defined(CHORUS_4)
@@ -1354,15 +241,7 @@ protected:
# include "ace/os_include/sys/os_wait.h"
# include "ace/os_include/os_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));
-# if !defined(CHORUS_4)
-typedef void (*__sighandler_t)(int); // keep Signal compilation happy
-# endif
# elif defined (CYGWIN32)
# include "ace/os_include/sys/os_uio.h"
# include "ace/os_include/os_fcntl.h" // <sys/file.h>
@@ -1380,9 +259,6 @@ typedef void (*__sighandler_t)(int); // keep Signal compilation happy
// sets O_NDELAY
# include /**/ <unix.h>
# include "ace/os_include/os_limits.h" // <sys/param.h> /* for NBBY */
-# if !defined (NFDBITS)
-# define NFDBITS (sizeof(fd_mask) * NBBY) /* bits per mask */
-# endif /* ! NFDBITS */
# elif defined(__rtems__)
# include "ace/os_include/os_fcntl.h" // <sys/file.h>
# include "ace/os_include/sys/os_resource.h"
@@ -1392,11 +268,6 @@ typedef void (*__sighandler_t)(int); // keep Signal compilation happy
# include "ace/os_include/sys/os_wait.h"
# include "ace/os_include/os_pwd.h"
-extern "C"
-{
- int select (int n, fd_set *readfds, fd_set *writefds,
- fd_set *exceptfds, const struct timeval *timeout);
-};
# elif ! defined (VXWORKS) && ! defined (INTEGRITY)
# include "ace/os_include/sys/os_uio.h"
# include "ace/os_include/sys/os_ipc.h"
@@ -1433,18 +304,6 @@ extern "C"
# 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 "ace/os_include/os_aio.h"
# endif /* ACE_HAS_AIO_CALLS */
@@ -1467,730 +326,26 @@ extern "C"
# include "ace/os_include/os_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 "ace/os_include/os_stropts.h"
-# undef _XOPEN_EXTENDED_SOURCE
-# else
-# include "ace/os_include/os_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 "ace/os_include/sys/os_select.h"
# endif /* ACE_HAS_SELECT_H */
-// 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 */
-
# include "ace/os_include/sys/os_msg.h"
# 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) */
-# 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 "ace/os_include/sys/os_utsname.h"
-typedef struct utsname ACE_utsname;
-# endif /* ACE_LACKS_UTSNAME_T */
-
-
-# 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 (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 (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)
-# elif defined(__BORLANDC__) && (__BORLANDC__ >= 0x600)
-# define ACE_NSIG _NSIG
-# 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 (_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 */
-
-
-
-
-// Create some useful typedefs.
-
-typedef const char **SYS_SIGLIST;
-
-# 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)
-struct ACE_OS_Export siginfo_t
-{
- siginfo_t (ACE_HANDLE handle);
- siginfo_t (ACE_HANDLE *handles); // JCEJ 12/23/96
-
- /// Win32 HANDLE that has become signaled.
- ACE_HANDLE si_handle_;
-
- /// Array of Win32 HANDLEs all of which have become signaled.
- ACE_HANDLE *si_handles_;
-};
-# 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 */
-
-/**
- * @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);
-
- void to_string (char*);
-
-
- // != 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__) && !defined (INTEGRITY)
-// 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
- {
- /// IP multicast address of group
- struct in_addr imr_multiaddr;
- /// Local IP address of interface
- struct in_addr imr_interface;
- };
-# endif /* ! ACE_HAS_IP_MULTICAST && ACE_LACKS_IP_ADD_MEMBERSHIP */
-
-# if !defined (ACE_HAS_STRBUF_T)
-struct strbuf
-{
- /// No. of bytes in buffer.
- int maxlen;
- /// No. of bytes returned.
- int len;
- /// Pointer to data.
- void *buf;
-};
-# 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 */
-
-# 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 "ace/os_include/os_syslog.h"
# endif /* !defined (ACE_WIN32) && !defined (ACE_LACKS_UNIX_SYSLOG) */
-# if defined (ACE_WIN32) && !defined (ACE_HAS_WINCE) && !defined (__BORLANDC__)
- typedef struct _stat ACE_stat;
-# else
- typedef struct stat ACE_stat;
-# endif /* ACE_WIN32 */
-
-// We need this for MVS...
-extern "C" {
- typedef int (*ACE_COMPARE_FUNC)(const void *, const void *);
-}
-
-#if defined (ACE_HAS_WINCE)
-// WinCE doesn't have most of the standard C library time functions. It
-// also doesn't define struct tm. SYSTEMTIME has pretty much the same
-// info though, so we can map it when needed. Define struct tm here and
-// use it when needed. This is taken from the standard C library.
-struct tm {
- int tm_sec;
- int tm_min;
- int tm_hour;
- int tm_mday; // Day of the month
- int tm_mon;
- int tm_year;
- int tm_wday; // Day of the week
- int tm_yday; // Day in the year
- int tm_isdst; // >0 if dst in effet; 0 if not; <0 if unknown
-};
-#endif /* ACE_HAS_WINCE */
-
-
-/// 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 (VXWORKS) && !defined (ACE_PSOS) && !defined (CHORUS)
-# if defined (ACE_HAS_WINCE)
- TIME_ZONE_INFORMATION tz;
- GetTimeZoneInformation (&tz);
- return tz.Bias * 60;
-# elif defined (ACE_WIN32)
- return _timezone; // For Win32.
-# elif ( defined (__Lynx__) || defined (__FreeBSD__) || defined (ACE_HAS_SUNOS4_GETTIMEOFDAY) ) && ( !defined (__linux__) )
- 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__ ... */
-# if defined (__linux__)
- // Under Linux, gettimeofday() does not correctly set the timezone
- // struct, so we should use the global variable <timezone>.
- // However, it is initialized by tzset(). I assume other systems
- // are the same (i.e., tzset() needs to be called to set
- // <timezone>), but since no one is complaining, I will only make
- // the change for Linux.
- ::tzset();
-# endif
- 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_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_PSOS !ACE_PSOS_HAS_TIME */
-}
-#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.
+ * @namespace ACE_OS
*
- * @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 */
-
-#if !defined (ACE_HAS_WINCE)
-// forward declarations of QoS data structures
-class ACE_QoS;
-class ACE_QoS_Params;
-class ACE_Accept_QoS_Params;
-#endif // ACE_HAS_WINCE
-
-#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) */
-/**
- * On some platforms clearerr is a macro. Defining ACE_OS::clearerr()
- * becomes really hard, as there is no way to save the macro
- * definition using the pre-processor.
- */
-#if !defined (ACE_LACKS_CLEARERR)
-#if defined (clearerr)
-#define __ace_clearerr_hack
-inline void __ace_clearerr(FILE *stream)
-{
- clearerr(stream);
-}
-#undef clearerr
-#endif /* defined (clearerr) */
-#endif /* !ACE_LACKS_CLEARERR */
-
-/**
- * @class ACE_OS
- *
- * @brief This class defines an OS independent programming API that
+ * @brief This namespace 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.
@@ -2204,2223 +359,35 @@ inline void __ace_clearerr(FILE *stream)
* 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
+namespace ACE_OS
{
- 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_OS_Export 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);
+ 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);
+ 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);
+ 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);
+ void set_win32_resource_module (HINSTANCE);
# endif /* ACE_WIN32 */
// = A set of wrappers for miscellaneous operations.
- static int atoi (const char *s);
-
- struct macaddr_node_t {
- unsigned char node[6];
- };
-
- /**
- * Get the first adapter found on the machine.
- */
- static int getmacaddress (struct macaddr_node_t *node);
-
-# if defined (ACE_HAS_WCHAR)
- static int atoi (const wchar_t *s);
-# endif /* ACE_HAS_WCHAR */
-
-#if defined (atop)
-#undef atop
-#endif /* atop */
-
- static void *atop (const char *s);
-
-# if defined (ACE_HAS_WCHAR)
- static void *atop (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,
- int &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);
-
-# if defined (ACE_USES_WCHAR)
- // If fp points to the Unicode format file, the file pointer will be moved right next
- // to the Unicode header (2 types). Otherwise, file pointer will be at the beginning.
- static void checkUnicodeFormat (FILE* fp);
-# endif // ACE_USES_WCHAR
-
- 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 snprintf (char *buf, size_t maxlen, 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 snprintf (wchar_t *buf, size_t maxlen, 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 fgetc (FILE* fp);
-
-#if !defined (ACE_LACKS_CLEARERR)
- static void clearerr (FILE* fp);
-#endif /* !ACE_LACKS_CLEARERR */
-
-#if defined (ACE_HAS_WCHAR)
- static wint_t fgetwc (FILE* fp);
- static wint_t ungetwc (wint_t c, FILE* fp);
-#endif /* ACE_HAS_WCHAR */
-
- static int fseek (FILE *fp,
- long offset,
- int ptrname);
- static long ftell (FILE* fp);
- static int fgetpos (FILE* fp, fpos_t* pos);
- static int fsetpos (FILE* fp, fpos_t* pos);
- 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);
-
- 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);
- //@}
-
- //@{
- /// 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[]);
- //@}
-
- /**
- * 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.
-
- // Get the current time.
- static time_t mktime (struct tm *timeptr);
-
- // 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 map_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);
- // These two methods are primarily in support of
- // ACE_Condition<ACE_Recursive_Thread_Mutex> and should probably not
- // be called outside that context.
- static int recursive_mutex_cond_unlock (ACE_recursive_thread_mutex_t *m,
- ACE_recursive_mutex_state &state);
- static void recursive_mutex_cond_relock (ACE_recursive_thread_mutex_t *m,
- ACE_recursive_mutex_state &state);
- //@}
-
- //@{ @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);
-
-#if !defined (ACE_HAS_WINCE)
- /// 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);
-#endif // ACE_HAS_WINCE
-
- 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
- * read 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,
- u_int 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);
-
-#if !defined (ACE_HAS_WINCE)
- /**
- * 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);
-#endif // ACE_HAS_WINCE
-
- /// BSD-style <connect> (no QoS).
- static int connect (ACE_HANDLE handle,
- struct sockaddr *addr,
- int addrlen);
-
-#if !defined (ACE_HAS_WINCE)
- /**
- * 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);
-#endif // ACE_HAS_WINCE
-
- 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);
-
-#if !defined (ACE_HAS_WINCE)
- /// 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);
-#endif // ACE_HAS_WINCE
-
- static int listen (ACE_HANDLE handle,
- int backlog);
- static int recv (ACE_HANDLE handle,
- char *buf,
- size_t len,
- int flags = 0);
- static int recvfrom (ACE_HANDLE handle,
- char *buf,
- size_t 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,
- size_t len,
- int flags = 0);
- static int sendto (ACE_HANDLE handle,
- const char *buf,
- size_t 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
- typedef ACE_WCHAR_T 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,
- ACE_THR_FUNC_RETURN *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_join (ACE_hthread_t waiter_id,
- ACE_THR_FUNC_RETURN *status);
- static int thr_join (ACE_thread_t waiter_id,
- ACE_thread_t *thr_id,
- ACE_THR_FUNC_RETURN *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_getprio (ACE_hthread_t id,
- int &priority);
- static int thr_getprio (ACE_hthread_t id,
- int &priority,
- int &policy);
- static int thr_setprio (ACE_hthread_t id,
- int priority,
- int policy = -1);
- 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 (ACE_THR_FUNC_RETURN 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 int sigwaitinfo (const sigset_t *set,
- siginfo_t *info);
- 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 */
-
- /// Get the number of CPUs configured in the machine.
- static long num_processors (void);
-
- /// Get the number of CPUs currently online.
- static long num_processors_online (void);
-
-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 */
-
-};
-
-/**
- * @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 () implementation 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 */
-
-# if 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_THR_C_FUNC */
-
-# 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_WMAIN)
-# define ACE_WMAIN wmain
-# endif /* ! ACE_WMAIN */
-
-# if defined (ACE_WIN32) && defined (ACE_USES_WCHAR)
-# define ACE_TMAIN wmain
-# else
-# define ACE_TMAIN main
-# endif
-
-# 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
-
-# elif defined (ACE_HAS_WINCE)
-
-# if defined (ACE_TMAIN) // Use WinMain on CE; others give warning/error.
-# undef ACE_TMAIN
-# endif // ACE_TMAIN
-
-// CE only gets a command line string; no argv. So we need to convert it
-// when the main entrypoint expects argc/argv. ACE_ARGV supports this.
-# include "ace/ARGV.h"
-
-// Support for ACE_TMAIN, which is a recommended way. It would be nice if
-// CE had CommandLineToArgvW()... but it's only on NT3.5 and up.
-
-# define ACE_TMAIN \
-ace_main_i (int, ACE_TCHAR *[]); /* forward declaration */ \
-int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int nCmdShow) \
-{ \
- ACE_TCHAR cmdline[1024]; \
- ACE_OS::strcpy (cmdline, ACE_LIB_TEXT ("program ")); \
- ACE_OS::strcat (cmdline, lpCmdLine); \
- ACE_ARGV ce_argv (cmdline); \
- ACE::init (); \
- ACE_MAIN_OBJECT_MANAGER \
- int i = ace_main_i (ce_argv.argc (), ce_argv.argv ()); \
- ACE::fini (); \
- return i; \
-} \
-int ace_main_i
-
-// Support for wchar_t but still can't fit to CE because of the command
-// line parameters.
-# define wmain \
-ace_main_i (int, ACE_TCHAR *[]); /* forward declaration */ \
-int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int nCmdShow) \
-{ \
- ACE_TCHAR cmdline[1024]; \
- ACE_OS::strcpy (cmdline, ACE_LIB_TEXT ("program ")); \
- ACE_OS::strcat (cmdline, lpCmdLine); \
- ACE_ARGV ce_argv (cmdline); \
- ACE::init (); \
- ACE_MAIN_OBJECT_MANAGER \
- int i = ace_main_i (ce_argv.argc (), ce_argv.argv ()); \
- ACE::fini (); \
- return i; \
-} \
-int ace_main_i
-
-// Supporting legacy 'main' is A LOT easier for users than changing existing
-// code on WinCE. Unfortunately, evc 3 can't grok a #include within the macro
-// expansion, so it needs to go out here.
-# include "ace/Argv_Type_Converter.h"
-# define main \
-ace_main_i (int, char *[]); /* forward declaration */ \
-int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int nCmdShow) \
-{ \
- ACE_TCHAR cmdline[1024]; \
- ACE_OS::strcpy (cmdline, ACE_LIB_TEXT ("program ")); \
- ACE_OS::strcat (cmdline, lpCmdLine); \
- ACE_ARGV ce_argv (cmdline); \
- ACE::init (); \
- ACE_MAIN_OBJECT_MANAGER \
- ACE_Argv_Type_Converter command_line (ce_argv.argc (), ce_argv.argv ()); \
- int i = ace_main_i (command_line.get_argc(), command_line.get_ASCII_argv());\
- ACE::fini (); \
- return i; \
-} \
-int ace_main_i
-
-# else
-# define main \
-ace_main_i (int, char *[]); /* forward declaration */ \
-int \
-ACE_MAIN (int argc, char *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)
-# define wmain \
-ace_main_i (int, ACE_TCHAR *[]); /* forward declaration */ \
-int \
-ACE_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 */
+}; /* namespace ACE_OS */
# if defined (ACE_HAS_INLINED_OSCALLS)
# if defined (ACE_INLINE)
@@ -4430,159 +397,6 @@ ace_main_i
# include "ace/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_POSIX_REALTIME_SIGNALS)
- // = 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_POSIX_REALTIME_SIGNALS */
-
- // 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 */
-
-/**
- * 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
-
-# if defined (ACE_LACKS_SYS_NERR)
-extern ACE_OS_Export int sys_nerr;
-# endif /* ACE_LACKS_SYS_NERR */
-
-/* ACE_Metrics */
-#if defined ACE_LACKS_ARRAY_PLACEMENT_NEW
-# define ACE_NEW_MALLOC_ARRAY_RETURN(POINTER,ALLOCATOR,CONSTRUCTOR,COUNT,RET_VAL) \
- do { POINTER = ALLOCATOR; \
- if (POINTER == 0) { errno = ENOMEM; return RET_VAL;} \
- else { for (u_int i = 0; i < COUNT; ++i) \
- {new (POINTER) CONSTRUCTOR; ++POINTER;} \
- POINTER -= COUNT;} \
- } while (0)
-# define ACE_NEW_MALLOC_ARRAY(POINTER,ALLOCATOR,CONSTRUCTOR,COUNT) \
- do { POINTER = ALLOCATOR; \
- if (POINTER == 0) { errno = ENOMEM; return;} \
- else { for (u_int i = 0; i < COUNT; ++i) \
- {new (POINTER) CONSTRUCTOR; ++POINTER;} \
- POINTER -= COUNT;} \
- } while (0)
-#else /* ! defined ACE_LACKS_ARRAY_PLACEMENT_NEW */
-# define ACE_NEW_MALLOC_ARRAY_RETURN(POINTER,ALLOCATOR,CONSTRUCTOR,COUNT,RET_VAL) \
- do { POINTER = ALLOCATOR; \
- if (POINTER == 0) { errno = ENOMEM; return RET_VAL;} \
- else { new (POINTER) CONSTRUCTOR [COUNT]; } \
- } while (0)
-# define ACE_NEW_MALLOC_ARRAY(POINTER,ALLOCATOR,CONSTRUCTOR,COUNT) \
- do { POINTER = ALLOCATOR; \
- if (POINTER == 0) { errno = ENOMEM; return;} \
- else { new (POINTER) CONSTRUCTOR [COUNT]; } \
- } while (0)
-#endif /* defined ACE_LACKS_ARRAY_PLACEMENT_NEW */
-
-/* Enable ACE Timeprobes */
-#if defined (ACE_ENABLE_TIMEPROBES)
- #if !defined (ACE_COMPILE_TIMEPROBES)
- #define ACE_COMPILE_TIMEPROBES
- #endif /* ACE_COMPILE_TIMEPROBES */
-#endif /* ACE_ENABLE_TIMEPROBES */
-
#if defined (ACE_LEGACY_MODE)
# include "ace/Log_Msg.h"
# include "ace/Thread_Hook.h"
diff --git a/ace/OS.i b/ace/OS.i
index 2e8b70274a0..01b4e40c58b 100644
--- a/ace/OS.i
+++ b/ace/OS.i
@@ -6,89 +6,10 @@
# 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)) \
- || (defined (_XOPEN_SOURCE) && defined (__GNUC__))
-
-# 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
- || _XOPEN_SOURCE && __GNUC__ */
-
-#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>
@@ -114,120 +35,10 @@ 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 */
-ACE_INLINE int
-ACE_OS::fcntl (ACE_HANDLE handle, int cmd, long arg)
-{
- ACE_OS_TRACE ("ACE_OS::fcntl");
-# if 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_LACKS_FCNTL */
-}
-
-#if !defined (ACE_LACKS_CHDIR)
-ACE_INLINE int
-ACE_OS::chdir (const char *path)
-{
- ACE_OS_TRACE ("ACE_OS::chdir");
-#if 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 /* VXWORKS */
-}
-
-#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_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_LACKS_MKFIFO */
-}
-
#if !defined (ACE_WIN32)
// Matthew Stevens 7-10-95 Fix GNU GCC 2.7 for memchr() problem.
@@ -244,24 +55,6 @@ ACE_OS::mkfifo (const ACE_TCHAR *file, mode_t mode)
# endif /* VXWORKS */
# endif /* ACE_HAS_GNU_CSTRING_H */
-// These prototypes are chronically lacking from many versions of
-// UNIX.
-#if !defined (ACE_HAS_ISASTREAM_PROTO)
-extern "C" int isastream (int);
-#endif /* ACE_HAS_ISASTREAM_PROTO */
-
-# 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
@@ -287,103 +80,6 @@ extern "C" char *mktemp (char *);
# include /**/ <ifaddrs.h>
# endif /* ACE_HAS_GETIFADDRS */
-// 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_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 /* ACE_PSOS_LACKS_PHILE */
-}
-
-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 /* ACE_LACKS_LSTAT */
-}
-
-ACE_INLINE int
-ACE_OS::fsync (ACE_HANDLE handle)
-{
- ACE_OS_TRACE ("ACE_OS::fsync");
-# if defined (ACE_LACKS_FSYNC)
- ACE_UNUSED_ARG (handle);
- ACE_NOTSUP_RETURN (-1);
-# else
- ACE_OSCALL_RETURN (::fsync (handle), int, -1);
-# endif /* ACE_LACKS_FSYNC */
-}
-
-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) || defined (INTEGRITY)
- 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 (VXWORKS) || defined (ACE_PSOS) || defined (INTEGRITY)
- ACE_UNUSED_ARG (fds);
- ACE_NOTSUP_RETURN (-1);
-# else
- ACE_OSCALL_RETURN (::pipe (fds), int, -1);
-# endif /* VXWORKS || ACE_PSOS */
-}
# if defined (DIGITAL_UNIX)
extern "C" {
@@ -406,71 +102,8 @@ extern "C" {
}
#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_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_REENTRANT_FUNCTIONS */
-}
-
-ACE_INLINE pid_t
-ACE_OS::setsid (void)
-{
- ACE_OS_TRACE ("ACE_OS::setsid");
-# if defined (VXWORKS) || defined (CHORUS) || defined (ACE_PSOS) || defined (INTEGRITY)
- ACE_NOTSUP_RETURN (-1);
-# else
- ACE_OSCALL_RETURN (::setsid (), int, -1);
-# endif /* VXWORKS || CHORUS || ACE_PSOS */
-}
-
-ACE_INLINE mode_t
-ACE_OS::umask (mode_t cmask)
-{
- ACE_OS_TRACE ("ACE_OS::umask");
-# if defined (VXWORKS) || defined (ACE_PSOS) || defined (INTEGRITY)
- ACE_UNUSED_ARG (cmask);
- ACE_NOTSUP_RETURN ((mode_t)-1);
-# else
- return ::umask (cmask); // This call shouldn't fail...
-# endif /* VXWORKS || ACE_PSOS */
-}
-
#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)
{
@@ -493,10706 +126,14 @@ ACE_OS::default_win32_security_attributes (LPSECURITY_ATTRIBUTES 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_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_WINCE && !__IBMCPP__ */
-}
-
-ACE_INLINE int
-ACE_OS::rand_r (ACE_RANDR_TYPE& seed)
-{
- ACE_OS_TRACE ("ACE_OS::rand_r");
-
- long new_seed = (long)(seed);
- if (new_seed == 0)
- new_seed = 0x12345987;
- long temp = new_seed / 127773;
- new_seed = 16807 * (new_seed - temp * 127773) - 2836 * temp;
- if (new_seed < 0)
- new_seed += 2147483647;
- (seed) = (unsigned int)new_seed;
- return (int)(new_seed & RAND_MAX);
-}
-
-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_WINCE)
- ACE_OS_TRACE ("ACE_OS::umask");
- ACE_OSCALL_RETURN (::_umask (cmask), mode_t, -1);
-# else
- ACE_NOTSUP_RETURN (-1);
-# endif /* ACE_HAS_WINCE */
-}
-
-ACE_INLINE int
-ACE_OS::fstat (ACE_HANDLE handle, ACE_stat *stp)
-{
- ACE_OS_TRACE ("ACE_OS::fstat");
-# if 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 ();
- 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) |
- (fdata.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY ? S_IFDIR : S_IFREG);
- }
- 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 /* 1 */
-}
-
#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_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_CLOCK_GETTIME */
-}
-
-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 (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 /* VXWORKS */
-}
-
-ACE_INLINE time_t
-ACE_OS::time (time_t *tloc)
-{
-#if !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_WINCE */
-}
-
-ACE_INLINE void
-ACE_OS::srand (u_int seed)
-{
- ACE_OS_TRACE ("ACE_OS::srand");
- ::srand (seed);
-}
-
-ACE_INLINE int
-ACE_OS::rand (void)
-{
- ACE_OS_TRACE ("ACE_OS::rand");
- ACE_OSCALL_RETURN (::rand (), int, -1);
-}
-
-ACE_INLINE int
-ACE_OS::unlink (const ACE_TCHAR *path)
-{
- ACE_OS_TRACE ("ACE_OS::unlink");
-# if 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 /* VXWORKS */
-}
-
-ACE_INLINE int
-ACE_OS::rename (const ACE_TCHAR *old_name,
- const ACE_TCHAR *new_name,
- int flags)
-{
-# if defined (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_LACKS_RENAME */
-}
-
-ACE_INLINE ACE_TCHAR *
-ACE_OS::tempnam (const ACE_TCHAR *dir, const ACE_TCHAR *pfx)
-{
- ACE_OS_TRACE ("ACE_OS::tempnam");
-#if 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 (ACE_WIN32) && ((defined (__BORLANDC__) && !defined(ACE_USES_WCHAR)) || defined (__IBMCPP__)))
- ACE_OSCALL_RETURN (::_tempnam ((char *) dir, (char *) pfx), char *, 0);
-#elif defined(ACE_WIN32) && 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 /* ACE_HAS_WINCE || ACE_LACKS_TEMPNAM */
- ACE_OSCALL_RETURN (::tempnam (dir, pfx), char *, 0);
-#endif /* VXWORKS */
-}
-
#if defined (ACE_HAS_SHM_OPEN) && defined(INTEGRITY)
#include "ace/os_include/sys/os_mman.h"
#endif
-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_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_SHM_OPEN */
-}
-
-ACE_INLINE int
-ACE_OS::shm_unlink (const ACE_TCHAR *path)
-{
- ACE_OS_TRACE ("ACE_OS::shm_unlink");
-# if 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_SHM_OPEN */
-}
-
-#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 (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 /* VXWORKS */
-}
-
-ACE_INLINE void
-ACE_OS::abort (void)
-{
-#if !defined (ACE_HAS_WINCE)
- ::abort ();
-#else
- // @@ CE doesn't support abort?
- exit (1);
-#endif /* !ACE_HAS_WINCE */
-}
-
-ACE_INLINE int
-ACE_OS::vsprintf (char *buffer, const char *format, va_list argptr)
-{
- return ACE_SPRINTF_ADAPTER (::vsprintf (buffer, format, argptr));
-}
-
-#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_WIN32) || defined (VXWORKS) || defined (ACE_PSOS) || defined (INTEGRITY)
- ACE_UNUSED_ARG (name);
- ACE_NOTSUP_RETURN (-1);
-#else
- ACE_OSCALL_RETURN (::sysconf (name), long, -1);
-#endif /* ACE_WIN32 || VXWORKS || ACE_PSOS */
-}
-
-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_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_THREADS */
-}
-
-#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_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_THREADS */
-}
-
-ACE_INLINE int
-ACE_OS::mutex_lock (ACE_mutex_t *m)
-{
- // ACE_OS_TRACE ("ACE_OS::mutex_lock");
-#if 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_THREADS */
-}
-
-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_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_THREADS */
-}
-
-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_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_THREADS */
-}
-
-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)
- 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)
- 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)
- 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)
- return ACE_OS::mutex_lock (m);
-# elif defined (VXWORKS) || defined (ACE_PSOS)
- return mutex_lock (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,
- 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)
- 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 */
-#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)
- 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)
- 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 !defined (ACE_LACKS_COND_T)
-// 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_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_THREADS */
-}
-
-ACE_INLINE int
-ACE_OS::condattr_init (ACE_condattr_t &attributes,
- int type)
-{
- ACE_UNUSED_ARG (type);
-# if defined (ACE_HAS_THREADS)
-# 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 */
-
-# else
- ACE_UNUSED_ARG (attributes);
- ACE_UNUSED_ARG (type);
- ACE_NOTSUP_RETURN (-1);
-# endif /* ACE_HAS_THREADS */
-}
-
-ACE_INLINE int
-ACE_OS::condattr_destroy (ACE_condattr_t &attributes)
-{
-#if defined (ACE_HAS_THREADS)
-# 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_THREADS */
-}
-
-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_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_THREADS */
-}
-
-#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_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_THREADS */
-}
-
-ACE_INLINE int
-ACE_OS::cond_broadcast (ACE_cond_t *cv)
-{
- ACE_OS_TRACE ("ACE_OS::cond_broadcast");
-# if 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_THREADS */
-}
-
-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_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_THREADS */
-}
-
-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_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_THREADS */
-}
-#endif /* !ACE_LACKS_COND_T */
-
-ACE_INLINE int
-ACE_OS::thr_equal (ACE_thread_t t1, ACE_thread_t t2)
-{
-#if 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_PTHREADS */
-}
-
-ACE_INLINE void
-ACE_OS::thr_self (ACE_hthread_t &self)
-{
- ACE_OS_TRACE ("ACE_OS::thr_self");
-#if 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_THREADS */
-}
-
-ACE_INLINE ACE_thread_t
-ACE_OS::thr_self (void)
-{
- // ACE_OS_TRACE ("ACE_OS::thr_self");
-#if 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_THREADS */
-}
-
-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 */
-}
-
-// This method is used to prepare the recursive mutex for releasing
-// when waiting on a condition variable. If the platform doesn't have
-// native recursive mutex and condition variable support, then ACE needs
-// to save the recursion state around the wait and also ensure that the
-// wait and lock release are atomic. recursive_mutex_cond_relock()
-// is the inverse of this method.
-ACE_INLINE int
-ACE_OS::recursive_mutex_cond_unlock (ACE_recursive_thread_mutex_t *m,
- ACE_recursive_mutex_state &state)
-{
-#if defined (ACE_HAS_THREADS)
- ACE_OS_TRACE ("ACE_OS::recursive_mutex_cond_unlock");
-# if defined (ACE_HAS_RECURSIVE_MUTEXES)
- // Windows need special handling since it has recursive mutexes, but
- // does not integrate them into a condition variable.
-# if defined (ACE_WIN32)
- // For Windows, the OS takes care of the mutex and its recursion. We just
- // need to release the lock one fewer times than this thread has acquired
- // it. Remember how many times, and reacquire it that many more times when
- // the condition is signaled.
- state.relock_count_ = 0;
- while (m->LockCount > 0
-# if !defined (ACE_HAS_WINCE) /* WinCE doesn't have RecursionCount */
- && m->RecursionCount > 1
-# endif
- )
- {
- // This may fail if the current thread doesn't own the mutex. If it
- // does fail, it'll be on the first try, so don't worry about resetting
- // the state.
- if (ACE_OS::recursive_mutex_unlock (m) == -1)
- return -1;
- ++state.relock_count_;
- }
-# else /* not ACE_WIN32 */
- // prevent warnings for unused variables
- ACE_UNUSED_ARG (state);
- ACE_UNUSED_ARG (m);
-# endif /* ACE_WIN32 */
- return 0;
-# else /* ACE_HAS_RECURSIVE_MUTEXES */
- // For platforms without recursive mutexes, we obtain the nesting mutex
- // to gain control over the mutex internals. Then set the internals to say
- // the mutex is available. If there are waiters, signal the condition
- // to notify them (this is mostly like the recursive_mutex_unlock() method).
- // Then, return with the nesting mutex still held. The condition wait
- // will release it atomically, allowing mutex waiters to continue.
- // Note that this arrangement relies on the fact that on return from
- // the condition wait, this thread will again own the nesting mutex
- // and can either set the mutex internals directly or get in line for
- // the mutex... this part is handled in recursive_mutex_cond_relock().
- if (ACE_OS::thread_mutex_lock (&m->nesting_mutex_) == -1)
- return -1;
-
-# if !defined (ACE_NDEBUG)
- if (m->nesting_level_ == 0
- || ACE_OS::thr_equal (ACE_OS::thr_self (), m->owner_id_) == 0)
- {
- ACE_OS::thread_mutex_unlock (&m->nesting_mutex_);
- errno = EINVAL;
- return -1;
- }
-# endif /* ACE_NDEBUG */
-
- // To make error recovery a bit easier, signal the condition now. Any
- // waiter won't regain control until the mutex is released, which won't
- // be until the caller returns and does the wait on the condition.
- if (ACE_OS::cond_signal (&m->lock_available_) == -1)
- {
- // Save/restore errno.
- ACE_Errno_Guard error (errno);
- ACE_OS::thread_mutex_unlock (&m->nesting_mutex_);
- return -1;
- }
-
- // Ok, the nesting_mutex_ lock is still held, the condition has been
- // signaled... reset the nesting info and return _WITH_ the lock
- // held. The lock will be released when the condition waits, in the
- // caller.
- state.nesting_level_ = m->nesting_level_;
- state.owner_id_ = m->owner_id_;
- 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 (state);
- ACE_NOTSUP_RETURN (-1);
-#endif /* ACE_HAS_THREADS */
-}
-
-
-// This method is called after waiting on a condition variable when a
-// recursive mutex must be reacquired. If the platform doesn't natively
-// integrate recursive mutexes and condition variables, it's taken care
-// of here (inverse of ACE_OS::recursive_mutex_cond_unlock).
-ACE_INLINE void
-ACE_OS::recursive_mutex_cond_relock (ACE_recursive_thread_mutex_t *m,
- ACE_recursive_mutex_state &state)
-{
-#if defined (ACE_HAS_THREADS)
- ACE_OS_TRACE ("ACE_OS::recursive_mutex_cond_relock");
-# if defined (ACE_HAS_RECURSIVE_MUTEXES)
- // Windows need special handling since it has recursive mutexes, but
- // does not integrate them into a condition variable.
- // On entry, the OS has already reacquired the lock for us. Just
- // reacquire it the proper number of times so the recursion is the same as
- // before waiting on the condition.
-# if defined (ACE_WIN32)
- while (state.relock_count_ > 0)
- {
- ACE_OS::recursive_mutex_lock (m);
- --state.relock_count_;
- }
- return;
-# else /* not ACE_WIN32 */
- // prevent warnings for unused variables
- ACE_UNUSED_ARG (state);
- ACE_UNUSED_ARG (m);
-
-# endif /* ACE_WIN32 */
-# else
- // Without recursive mutex support, it's somewhat trickier. On entry,
- // the current thread holds the nesting_mutex_, but another thread may
- // still be holding the ACE_recursive_mutex_t. If so, mimic the code
- // in ACE_OS::recursive_mutex_lock that waits to acquire the mutex.
- // After acquiring it, restore the nesting counts and release the
- // nesting mutex. This will restore the conditions to what they were
- // before calling ACE_OS::recursive_mutex_cond_unlock().
- while (m->nesting_level_ > 0)
- ACE_OS::cond_wait (&m->lock_available_, &m->nesting_mutex_);
-
- // At this point, we still have nesting_mutex_ and the mutex is free.
- m->nesting_level_ = state.nesting_level_;
- m->owner_id_ = state.owner_id_;
- ACE_OS::thread_mutex_unlock (&m->nesting_mutex_);
- return;
-# endif /* ACE_HAS_RECURSIVE_MUTEXES */
-#else
- ACE_UNUSED_ARG (m);
- ACE_UNUSED_ARG (state);
- return;
-#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_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_POSIX_SEM */
-}
-
-// 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_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_WIN32 */
-}
-
-// 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, 0), 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_WIN32)
- if (::SetFilePointer (handle, offset, 0, 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_WIN32 */
-}
-
-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_WIN32) && !defined (ACE_HAS_PHARLAP)
-
-# if defined(ACE_HAS_WINCE)
- ACE_UNUSED_ARG (addr);
- if (ACE_BIT_ENABLED (flags, MAP_FIXED)) // not supported
- {
- errno = EINVAL;
- return MAP_FAILED;
- }
-# else
- if (!ACE_BIT_ENABLED (flags, MAP_FIXED))
- addr = 0;
- else if (addr == 0) // can not map to address 0
- {
- errno = EINVAL;
- return MAP_FAILED;
- }
-# endif
-
- 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))
- {
-# if !defined(ACE_HAS_WINCE)
- prot = PAGE_WRITECOPY;
-# endif // ACE_HAS_WINCE
- 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, and the desired name is valid, do we try
- // CreateFileMapping.
-
- *file_mapping = ACE_TEXT_OpenFileMapping (nt_flags,
- 0,
- file_mapping_name);
- if (*file_mapping != 0
- || (::GetLastError () == ERROR_INVALID_NAME
- && ::GetLastError () == ERROR_FILE_NOT_FOUND))
- 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
- 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
- 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_WIN32 && !ACE_HAS_PHARLAP */
-}
-
-// 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_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_POSIX_SEM */
-}
-
-#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_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_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_POSIX_SEM */
-}
-
-ACE_INLINE int
-ACE_OS::sema_post (ACE_sema_t *s, u_int release_count)
-{
-#if defined (ACE_WIN32) && !defined (ACE_USES_WINCE_SEMA_SIMULATION)
- // Win32 supports this natively.
- ACE_WIN32CALL_RETURN (ACE_ADAPT_RETVAL (::ReleaseSemaphore (*s, release_count, 0),
- ace_result_), int, -1);
-#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_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_POSIX_SEM */
-}
-
-ACE_INLINE int
-ACE_OS::sema_wait (ACE_sema_t *s)
-{
- ACE_OS_TRACE ("ACE_OS::sema_wait");
-# if 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_POSIX_SEM */
-}
-
-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 == 0)
- 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 == 0)
- 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_++;
-
- ACE_Time_Value absolute_timeout = *timeout;
-
- // cond_timewait() expects absolute time, check
- // <use_absolute_time> flag.
- if (use_absolute_time == 0)
- absolute_timeout += ACE_OS::gettimeofday ();
-
- if (ACE_OS::cond_timedwait (&event->condition_,
- &event->lock_,
- &absolute_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),
- ACE_static_cast (int, 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, size_t 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,
- ACE_static_cast (int, 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,
- size_t 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, len, flags,
- (struct sockaddr_in *) addr, (ACE_SOCKET_LEN *) addrlen),
- int, -1);
-# else
- ACE_SOCKCALL_RETURN (::recvfrom ((ACE_SOCKET) handle, buf, len, flags,
- (struct sockaddr *) addr, (ACE_SOCKET_LEN *) addrlen),
- int, -1);
-# endif /* defined ACE_PSOS_DIAB_PPC */
-#elif defined (ACE_WIN32)
- int shortened_len = ACE_static_cast (int, len);
- int result = ::recvfrom ((ACE_SOCKET) handle,
- buf,
- shortened_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 shortened_len;
- else
- return -1;
- }
- else
- return result;
-#else /* non Win32 and non PSOS */
- ACE_SOCKCALL_RETURN (::recvfrom ((ACE_SOCKET) handle, buf, 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, size_t 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,
- ACE_static_cast (int, 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);
- if (result != 0) {
- ACE_OS::set_errno_to_last_error ();
- }
- 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,
- size_t 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
-# if defined (ACE_WIN32)
- ACE_SOCKCALL_RETURN (::sendto ((ACE_SOCKET) handle, buf,
- ACE_static_cast (int, len), flags,
- ACE_const_cast (struct sockaddr *, addr), addrlen),
- int, -1);
-# else
- ACE_SOCKCALL_RETURN (::sendto ((ACE_SOCKET) handle, buf, len, flags,
- ACE_const_cast (struct sockaddr *, addr), addrlen),
- int, -1);
-# endif /* ACE_WIN32 */
-#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);
- if (result != 0) {
- ACE_OS::set_errno_to_last_error ();
- }
- 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");
-
- #if defined (ACE_HAS_WINSOCK2) && (ACE_HAS_WINSOCK2 != 0) && defined(SO_REUSEPORT)
- // To work around an inconsistency with Microsofts implementation of
- // sockets, we will check for SO_REUSEADDR, and ignore it. Winsock
- // always behaves as if SO_REUSEADDR=1. Some implementations have the
- // same behaviour as Winsock, but use a new name for it. SO_REUSEPORT.
- // If you want the normal behaviour for SO_REUSEADDR=0, then NT 4 sp4 and later
- // supports SO_EXCLUSIVEADDRUSE. This also requires using an updated Platform SDK
- // so it was decided to ignore the option for now. (Especially since ACE always
- // sets SO_REUSEADDR=1, which we can mimic by doing nothing.)
- if (level == SOL_SOCKET) {
- if (optname == SO_REUSEADDR) {
- return 0; // Not supported by Winsock
- }
- if (optname == SO_REUSEPORT) {
- optname = SO_REUSEADDR;
- }
- }
- #endif /*ACE_HAS_WINSOCK2*/
-
- 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)
-{
- ACE_OSCALL_RETURN (::atoi (s), int, -1);
-}
-
-#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 void *
-ACE_OS::atop (const char *s)
-{
- ACE_TRACE ("ACE_OS::atop");
- // It would be nice to make use of Basic_Types.h here, but that
- // file relies on OS.h. Fortunately, most platforms have int
- // the same as pointer size (IA32, IA64), with Win64 being the
- // exception.
-#if defined (ACE_WIN64)
- __int64 ip = ::_atoi64 (s);
-#else
- int ip = ::atoi (s);
-#endif /* ACE_WIN64 */
- void *p = ACE_reinterpret_cast (void *, ip);
- return p;
-}
-
-#if defined (ACE_HAS_WCHAR)
-ACE_INLINE void *
-ACE_OS::atop (const wchar_t *s)
-{
-# if defined (ACE_WIN64)
- __int64 ip = ::_wtoi64 (s);
-# else
- int ip = ACE_OS::atoi (s);
-# endif /* ACE_WIN64 */
- void *p = ACE_reinterpret_cast (void *, ip);
- return p;
-}
-#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)
-{
- ACE_OS_TRACE ("ACE_OS::fclose");
- ACE_OSCALL_RETURN (::fclose (fp), int, -1);
-}
-
-ACE_INLINE ACE_TCHAR *
-ACE_OS::fgets (ACE_TCHAR *buf, int size, FILE *fp)
-{
- ACE_OS_TRACE ("ACE_OS::fgets");
-#if 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_WIN32 && ACE_USES_WCHAR */
-}
-
-#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)
-{
- ACE_OS_TRACE ("ACE_OS::fopen");
- ACE_OSCALL_RETURN (::fopen (filename, mode), FILE *, 0);
-}
-#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_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 /* ACE_WIN32 && ACE_USES_WCHAR */
-}
-
-ACE_INLINE int
-ACE_OS::fflush (FILE *fp)
-{
- ACE_OS_TRACE ("ACE_OS::fflush");
-#if defined (VXWORKS)
- if (fp == 0)
- {
- // Do not allow fflush(0) on VxWorks
- return 0;
- }
-#endif /* VXWORKS */
-
- ACE_OSCALL_RETURN (::fflush (fp), int, -1);
-}
-
-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_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_LACKS_POSIX_PROTOTYPES */
-}
-
-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_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_LACKS_POSIX_PROTOTYPES */
-}
-
-ACE_INLINE int
-ACE_OS::truncate (const ACE_TCHAR *filename,
- off_t offset)
-{
- ACE_OS_TRACE ("ACE_OS::truncate");
-#if 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,
- 0,
- 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_WIN32 */
-}
-
-// Accessors to PWD file.
-
-ACE_INLINE struct passwd *
-ACE_OS::getpwnam (const char *name)
-{
-#if !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_LACKS_PWD_FUNCTIONS */
-}
-
-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_POSIX_GETPWNAM_R)
- struct passwd *result;
- int status;
-
- status = ::getpwnam_r (name, pwent, buffer, buflen, &result);
-
- 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_POSIX_GETPWNAM_R */
-}
-
-// DNS accessors.
-
-#if !defined (VXWORKS)
-ACE_INLINE struct hostent *
-ACE_OS::gethostbyaddr_r (const char *addr,
- int length,
- int type,
- struct 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,
- struct 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);
-#endif /* ACE_WIN32 */
- errno = error;
-}
-
-ACE_INLINE void
-ACE_OS::perror (const ACE_TCHAR *s)
-{
- ACE_OS_TRACE ("ACE_OS::perror");
-#if 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_WINCE */
-}
-
-ACE_INLINE int
-ACE_OS::puts (const ACE_TCHAR *s)
-{
- ACE_OS_TRACE ("ACE_OS::puts");
-#if 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_WIN32 && ACE_USES_WCHAR */
-}
-
-ACE_INLINE int
-ACE_OS::fputs (const ACE_TCHAR *s, FILE *stream)
-{
- ACE_OS_TRACE ("ACE_OS::fputs");
-#if 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_WIN32 && ACE_USES_WCHAR */
-}
-
-ACE_INLINE ACE_SignalHandler
-ACE_OS::signal (int signum, ACE_SignalHandler func)
-{
- if (signum == 0)
- return 0;
- else
-#if 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_PSOS && !ACE_PSOS_TM && !ACE_PSOS_DIAB_MIPS && !ACE_PSOS_DIAB_PPC */
-}
-
-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_PTHREAD_CONTINUE)
- 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_PTHREAD_CONTINUE */
-# 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)
- ACE_OSCALL_RETURN (::taskResume (target_thread), int, -1);
-# 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_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_PTHREADS */
-}
-
-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 id, int &priority, int &policy)
-{
- ACE_OS_TRACE ("ACE_OS::thr_getprio");
- ACE_UNUSED_ARG (policy);
-#if defined (ACE_HAS_THREADS)
-# if (defined (ACE_HAS_PTHREADS) && !defined (ACE_LACKS_SETSCHED))
-
-# if defined (ACE_HAS_PTHREADS_DRAFT4)
- int result;
- result = ::pthread_getprio (id);
- if (result != -1)
- {
- priority = result;
- return 0;
- }
- else
- return -1;
-# elif defined (ACE_HAS_PTHREADS_DRAFT6)
-
- pthread_attr_t attr;
- if (pthread_getschedattr (id, &attr) == 0)
- {
- priority = pthread_attr_getprio(&attr);
- return 0;
- }
- return -1;
-# else
-
- struct sched_param param;
- int result;
-
- ACE_OSCALL (ACE_ADAPT_RETVAL (::pthread_getschedparam (id, &policy, &param),
- result), int,
- -1, result);
- priority = param.sched_priority;
- return result;
-# endif /* ACE_HAS_PTHREADS_DRAFT4 */
-# elif defined (ACE_HAS_STHREADS)
- ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::thr_getprio (id, &priority), ace_result_), int, -1);
-# elif defined (ACE_HAS_WTHREADS)
- priority = ::GetThreadPriority (id);
- if (priority == 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 (id, 0, (u_long *) &priority), ace_result_), int, -1);
-# elif defined (VXWORKS)
- ACE_OSCALL_RETURN (::taskPriorityGet (id, &priority), int, -1);
-# else
- ACE_UNUSED_ARG (id);
- ACE_UNUSED_ARG (priority);
- ACE_NOTSUP_RETURN (-1);
-# endif /* ACE_HAS_STHREADS */
-#else
- ACE_UNUSED_ARG (id);
- ACE_UNUSED_ARG (priority);
- ACE_NOTSUP_RETURN (-1);
-#endif /* ACE_HAS_THREADS */
-}
-
-ACE_INLINE int
-ACE_OS::thr_getprio (ACE_hthread_t id, int &priority)
-{
- ACE_OS_TRACE ("ACE_OS::thr_getprio");
- int policy = 0;
- return ACE_OS::thr_getprio (id, priority, policy);
-}
-
-#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 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 (*data == 0 && (error = ::GetLastError ()) != NO_ERROR)
- return -1;
- else
- 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_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 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 (*data == 0 && (error = ::GetLastError ()) != NO_ERROR)
- return -1;
- else
- 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_THREADS */
-}
-
-#if !defined (VXWORKS)
-ACE_INLINE int
-ACE_OS::thr_join (ACE_hthread_t thr_handle,
- ACE_THR_FUNC_RETURN *status)
-{
- ACE_OS_TRACE ("ACE_OS::thr_join");
-#if 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)
- ACE_THR_FUNC_RETURN 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, status) != FALSE)
- {
- ::CloseHandle (thr_handle);
- return 0;
- }
- ACE_FAIL_RETURN (-1);
- /* NOTREACHED */
-# elif 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_THREADS */
-}
-
-ACE_INLINE int
-ACE_OS::thr_join (ACE_thread_t waiter_id,
- ACE_thread_t *thr_id,
- ACE_THR_FUNC_RETURN *status)
-{
- ACE_OS_TRACE ("ACE_OS::thr_join");
-#if 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 (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_THREADS */
-}
-#endif /* !VXWORKS */
-
-ACE_INLINE int
-ACE_OS::thr_setcancelstate (int new_state, int *old_state)
-{
- ACE_OS_TRACE ("ACE_OS::thr_setcancelstate");
-#if 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_THREADS */
-}
-
-ACE_INLINE int
-ACE_OS::thr_setcanceltype (int new_type, int *old_type)
-{
- ACE_OS_TRACE ("ACE_OS::thr_setcanceltype");
-#if 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_THREADS */
-}
-
-ACE_INLINE int
-ACE_OS::thr_cancel (ACE_thread_t thr_id)
-{
- ACE_OS_TRACE ("ACE_OS::thr_cancel");
-#if 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_THREADS */
-}
-
-ACE_INLINE int
-ACE_OS::sigwait (sigset_t *sset, int *sig)
-{
- ACE_OS_TRACE ("ACE_OS::sigwait");
- int local_sig;
- if (sig == 0)
- sig = &local_sig;
-#if defined (ACE_HAS_THREADS)
-# if (defined (__FreeBSD__) && (__FreeBSD__ < 3)) || defined (CHORUS) || defined (ACE_PSOS)
- ACE_UNUSED_ARG (sset);
- ACE_NOTSUP_RETURN (-1);
-# elif (defined (ACE_HAS_STHREADS) && !defined (_POSIX_PTHREAD_SEMANTICS))
- *sig = ::sigwait (sset);
- 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 (sset, 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 (sset, 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 (sset);
-# else
- *sig = ::sigwait (sset);
-# endif /* HPUX_10 */
- return *sig;
-# elif defined(ACE_HAS_FSU_PTHREADS)
- return ::sigwait (sset, sig);
-# elif defined(CYGWIN32)
- // Cygwin has sigwait definition, but it is not implemented
- ACE_UNUSED_ARG (sset);
- ACE_NOTSUP_RETURN (-1);
-# else /* this is draft 7 or std */
- errno = ::sigwait (sset, 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 (sset);
- 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 (sset, 0, 0);
- return *sig;
-# endif /* __FreeBSD__ */
-#else
- ACE_UNUSED_ARG (sset);
- ACE_UNUSED_ARG (sig);
- ACE_NOTSUP_RETURN (-1);
-#endif /* ACE_HAS_THREADS */
-}
-
-ACE_INLINE int
-ACE_OS::sigtimedwait (const sigset_t *sset,
- siginfo_t *info,
- const ACE_Time_Value *timeout)
-{
- ACE_OS_TRACE ("ACE_OS::sigtimedwait");
-#if 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 (sset, info, tsp),
- int, -1);
-#else
- ACE_UNUSED_ARG (sset);
- ACE_UNUSED_ARG (info);
- ACE_UNUSED_ARG (timeout);
- ACE_NOTSUP_RETURN (-1);
-#endif /* ACE_HAS_SIGTIMEDWAIT */
-}
-
-ACE_INLINE int
-ACE_OS::sigwaitinfo (const sigset_t *sset,
- siginfo_t *info)
-{
- ACE_OS_TRACE ("ACE_OS::sigwaitinfo");
- // If this platform has sigtimedwait, it should have sigwaitinfo as well.
- // If this isn't true somewhere, let me know and I'll fix this.
- // -Steve Huston <shuston@riverace.com>.
-#if defined (ACE_HAS_SIGTIMEDWAIT)
- ACE_OSCALL_RETURN (::sigwaitinfo (sset, info), int, -1);
-#else
- ACE_UNUSED_ARG (sset);
- ACE_UNUSED_ARG (info);
- ACE_NOTSUP_RETURN (-1);
-#endif /* ACE_HAS_SIGTIMEDWAIT */
-}
-
-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_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_THREADS */
-}
-
-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_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_THREADS */
-}
-
-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);
-
- ACE_OSCALL (ACE_ADAPT_RETVAL (::taskInfoGet (tid, &taskDesc),
- status),
- STATUS, -1, status);
- 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 id, int priority, int policy)
-{
- ACE_OS_TRACE ("ACE_OS::thr_setprio");
- ACE_UNUSED_ARG (policy);
-#if defined (ACE_HAS_THREADS)
-# if (defined (ACE_HAS_PTHREADS) && !defined (ACE_LACKS_SETSCHED))
-
-# if defined (ACE_HAS_PTHREADS_DRAFT4)
- int result;
- result = ::pthread_setprio (id, priority);
- return (result == -1 ? -1 : 0);
-# elif defined (ACE_HAS_PTHREADS_DRAFT6)
- pthread_attr_t attr;
- if (pthread_getschedattr (id, &attr) == -1)
- return -1;
- if (pthread_attr_setprio (attr, priority) == -1)
- return -1;
- return pthread_setschedattr (id, attr);
-# else
- int result;
- struct sched_param param;
- memset ((void *) &param, 0, sizeof param);
-
- // If <policy> is -1, we don't want to use it for
- // pthread_setschedparam(). Instead, obtain policy from
- // pthread_getschedparam().
- if (policy == -1)
- {
- ACE_OSCALL (ACE_ADAPT_RETVAL (::pthread_getschedparam (id, &policy, &param),
- result),
- int, -1, result);
- if (result == -1)
- return result;
- }
-
- param.sched_priority = priority;
-
- ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::pthread_setschedparam (id, policy, &param),
- ace_result_),
- int, -1);
-# endif /* ACE_HAS_PTHREADS_DRAFT4 */
-# elif defined (ACE_HAS_STHREADS)
- ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::thr_setprio (id, priority),
- ace_result_),
- int, -1);
-# elif defined (ACE_HAS_WTHREADS)
- ACE_WIN32CALL_RETURN (ACE_ADAPT_RETVAL (::SetThreadPriority (id, priority),
- ace_result_),
- int, -1);
-# elif defined (ACE_PSOS)
- u_long oldpriority;
- ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::t_setpri (id, priority, &oldpriority),
- ace_result_),
- int, -1);
-# elif defined (VXWORKS)
- ACE_OSCALL_RETURN (::taskPrioritySet (id, priority), int, -1);
-# else
- // For example, platforms that support Pthreads but LACK_SETSCHED.
- ACE_UNUSED_ARG (id);
- ACE_UNUSED_ARG (priority);
- ACE_NOTSUP_RETURN (-1);
-# endif /* ACE_HAS_STHREADS */
-#else
- ACE_UNUSED_ARG (id);
- ACE_UNUSED_ARG (priority);
- ACE_NOTSUP_RETURN (-1);
-#endif /* ACE_HAS_THREADS */
-}
-
-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_PTHREAD_SUSPEND)
- 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_PTHREAD_SUSPEND */
-# 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)
- ACE_OSCALL_RETURN (::taskSuspend (target_thread), int, -1);
-# 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_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 (0);
-# 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_THREADS */
-}
-
-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_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_WINCE */
-}
-
-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);
- // Gets ignored on error anyway
- bytes_sent += buffers[i].iov_len;
-
- // If the transfer isnt complete just drop out of the loop.
- if (result < (int)buffers[i].iov_len)
- break;
- }
-# 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_LACKS_ACCESS)
-# if 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 (ACE_TEXT_CHAR_TO_TCHAR(path), ACE_LIB_TEXT ("r"));
- ACE_UNUSED_ARG (amode);
-
- ACE_OS::fclose (handle);
- return (handle == ACE_INVALID_HANDLE ? -1 : 0);
-# elif defined (VXWORKS)
- FILE* handle = ACE_OS::fopen (ACE_TEXT_CHAR_TO_TCHAR(path), ACE_LIB_TEXT ("r"));
- ACE_UNUSED_ARG (amode);
- if (handle != 0)
- {
- ACE_OS::fclose (handle);
- return 0;
- }
- return (-1);
-# else
- ACE_UNUSED_ARG (path);
- ACE_UNUSED_ARG (amode);
- ACE_NOTSUP_RETURN (-1);
-# endif // ACE_HAS_WINCE
-#else
- ACE_OSCALL_RETURN (::access (path, amode), int, -1);
-#endif /* ACE_LACKS_ACCESS */
-}
-
-
-#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_WIN32)
- return ACE_OS::open (filename, O_CREAT|O_TRUNC|O_WRONLY, 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_WIN32 */
-}
-
-#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)
-{
-#if defined (INTEGRITY)
- if(!name) {
- errno = EFAULT;
- return -1;
- }
- strcpy(name->sysname,"INTEGRITY");
- int status = gethostname(name->nodename,_SYS_NMLN);
- strcpy(name->release,"4.0");
- strcpy(name->version,"4.0.9");
- strcpy(name->machine,"a standard name");
- return status;
-#else
- ACE_OS_TRACE ("ACE_OS::uname");
- ACE_OSCALL_RETURN (::uname (name), int, -1);
-#endif
-}
-#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_WIN32) || defined (VXWORKS) || defined (CHORUS) || defined (ACE_PSOS)
- ACE_UNUSED_ARG (secs);
-
- ACE_NOTSUP_RETURN (0);
-#else
- return ::alarm (secs);
-#endif /* ACE_WIN32 || VXWORKS || CHORUS || ACE_PSOS */
-}
-
-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_LACKS_DLCLOSE)
- ACE_UNUSED_ARG (handle);
- return 0;
-#elif 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) || defined (VXWORKS)
- 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,
- 0,
- ::GetLastError (),
- 0,
- buf,
- sizeof buf / sizeof buf[0],
- 0);
-# 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++ */
-# elif defined (VXWORKS)
- MODULE* handle;
- // Open readonly
- ACE_HANDLE filehandle = ACE_OS::open (filename,
- O_RDONLY,
- ACE_DEFAULT_FILE_PERMS);
-
- if (filehandle != ACE_INVALID_HANDLE)
- {
- ACE_OS::last_error(0);
- ACE_OSCALL ( ::loadModule (filehandle, mode ), MODULE *, 0, handle);
- int loaderror = ACE_OS::last_error();
- ACE_OS::close (filehandle);
-
- if ( (loaderror != 0) && (handle != 0) )
- {
- // ouch something went wrong most likely unresolved externals
- ::unldByModuleId ( handle, 0 );
- handle = 0;
- }
- }
- else
- {
- // couldn't open file
- handle = 0;
- }
- return handle;
-# 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");
-
-#if defined (ACE_HAS_DLSYM_SEGFAULT_ON_INVALID_HANDLE)
- // Check if the handle is valid before making any calls using it.
- if (handle == ACE_SHLIB_INVALID_HANDLE)
- return 0;
-#endif /* ACE_HAS_DLSYM_SEGFAULT_ON_INVALID_HANDLE */
-
- // 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 : 0;
-
-# elif defined (VXWORKS)
-
- // For now we use the VxWorks global symbol table
- // which resolves the most recently loaded symbols .. which resolve mostly what we want..
- ACE_UNUSED_ARG (handle);
- SYM_TYPE symtype;
- void *value = 0;
- STATUS status;
- ACE_OSCALL (::symFindByName(sysSymTbl, symbolname, (char **)&value, &symtype), int, -1, status);
-
- return status == OK ? value : 0;
-
-# 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_WIN32)
- DWORD bytes_written; // This is set to 0 byte WriteFile.
-
- // Strictly correctly, we should loop writing all the data if more
- // than a DWORD length can hold.
- DWORD short_nbyte = ACE_static_cast (DWORD, nbyte);
- if (::WriteFile (handle, buf, short_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_WIN32 */
-}
-
-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.
-
- DWORD short_nbyte = ACE_static_cast (DWORD, nbyte);
- if (::WriteFile (handle, buf, short_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_WIN32)
- DWORD ok_len;
- if (::ReadFile (handle, buf, ACE_static_cast (DWORD, 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_WIN32 */
-}
-
-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;
- DWORD short_len = ACE_static_cast (DWORD, len);
- if (::ReadFile (handle, buf, short_len, &ok_len, overlapped))
- return (ssize_t) ok_len;
- else
- ACE_FAIL_RETURN (-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_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_WIN32 && !ACE_HAS_PHARLAP */
-}
-
-ACE_INLINE int
-ACE_OS::msync (void *addr, size_t len, int sync)
-{
- ACE_OS_TRACE ("ACE_OS::msync");
-#if 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_WIN32 && !ACE_HAS_PHARLAP */
-}
-
-ACE_INLINE int
-ACE_OS::munmap (void *addr, size_t len)
-{
- ACE_OS_TRACE ("ACE_OS::munmap");
-#if 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_WIN32 */
-}
-
-ACE_INLINE int
-ACE_OS::madvise (caddr_t addr, size_t len, int map_advice)
-{
- ACE_OS_TRACE ("ACE_OS::madvise");
-#if defined (ACE_WIN32)
- ACE_UNUSED_ARG (addr);
- ACE_UNUSED_ARG (len);
- ACE_UNUSED_ARG (map_advice);
-
- ACE_NOTSUP_RETURN (-1);
-#elif !defined (ACE_LACKS_MADVISE)
- ACE_OSCALL_RETURN (::madvise (addr, len, map_advice), int, -1);
-#else
- ACE_UNUSED_ARG (addr);
- ACE_UNUSED_ARG (len);
- ACE_UNUSED_ARG (map_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_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_WINCE && !VXWORKS && !ACE_PSOS && !__rtems__ */
-}
-
-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 */
-
-// Magic number declaration and definition for ctime and ctime_r ()
-static const int ctime_buf_size = 26;
-
-ACE_INLINE ACE_TCHAR *
-ACE_OS::ctime (const time_t *t)
-{
- ACE_OS_TRACE ("ACE_OS::ctime");
-#if 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)
- static ACE_TCHAR buf [ctime_buf_size];
- return ACE_OS::ctime_r (t,
- buf,
- ctime_buf_size);
-#elif defined (ACE_USES_WCHAR)
- ACE_OSCALL_RETURN (::_wctime (t), wchar_t *, 0);
-#else
- ACE_OSCALL_RETURN (::ctime (t), char *, 0);
-# endif /* ACE_HAS_BROKEN_CTIME */
-}
-
-#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_REENTRANT_FUNCTIONS)
-# if defined (ACE_HAS_2_PARAM_ASCTIME_R_AND_CTIME_R)
- if (buflen < ctime_buf_size)
- {
- errno = ERANGE;
- return 0;
- }
-# if defined (DIGITAL_UNIX)
- ACE_OSCALL_RETURN (::_Pctime_r (t, buf), ACE_TCHAR *, 0);
-# else /* DIGITAL_UNIX */
- ACE_OSCALL_RETURN (::ctime_r (t, buf), ACE_TCHAR *, 0);
-# endif /* DIGITAL_UNIX */
- 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 */
- if (buflen < ctime_buf_size)
- {
- errno = ERANGE;
- return 0;
- }
-
- ACE_TCHAR *result;
-# if defined (ACE_USES_WCHAR)
- ACE_OSCALL (::_wctime (t), wchar_t *, 0, result);
-# else /* ACE_USES_WCHAR */
- ACE_OSCALL (::ctime (t), char *, 0, result);
-# endif /* ACE_USES_WCHAR */
- if (result != 0)
- ACE_OS::strsncpy (buf, result, buflen);
- return buf;
-# endif /* ACE_PSOS && !ACE_PSOS_HAS_TIME */
-#endif /* ACE_HAS_REENTRANT_FUNCTIONS */
-}
-#endif /* !ACE_HAS_WINCE */
-
-ACE_INLINE struct tm *
-ACE_OS::localtime (const time_t *t)
-{
-#if !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_WINCE && !ACE_PSOS || ACE_PSOS_HAS_TIME */
-}
-
-ACE_INLINE struct tm *
-ACE_OS::gmtime (const time_t *t)
-{
-#if !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_WINCE && !ACE_PSOS || ACE_PSOS_HAS_TIME */
-}
-
-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_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_REENTRANT_FUNCTIONS */
-}
-
-ACE_INLINE char *
-ACE_OS::asctime (const struct tm *t)
-{
-#if !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_WINCE && !ACE_PSOS || ACE_PSOS_HAS_TIME */
-}
-
-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_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_REENTRANT_FUNCTIONS */
-}
-
-ACE_INLINE size_t
-ACE_OS::strftime (char *s, size_t maxsize, const char *format,
- const struct tm *timeptr)
-{
-#if !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_WINCE && !ACE_PSOS || ACE_PSOS_HAS_TIME */
-}
-
-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 = 0;
-#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_, 0);
- break;
- }
- lock->overlapped_.Offset = start;
- if (len == 0)
- len = ::GetFileSize (lock->handle_,
- 0) - 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_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_LACKS_EXEC */
-}
-
-ACE_INLINE int
-ACE_OS::execve (const char *path,
- char *const argv[],
- char *const envp[])
-{
- ACE_OS_TRACE ("ACE_OS::execve");
-#if 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_LACKS_EXEC */
-}
-
-ACE_INLINE int
-ACE_OS::execvp (const char *file,
- char *const argv[])
-{
- ACE_OS_TRACE ("ACE_OS::execvp");
-#if 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_LACKS_EXEC */
-}
-
-ACE_INLINE FILE *
-ACE_OS::fdopen (ACE_HANDLE handle, const ACE_TCHAR *mode)
-{
- ACE_OS_TRACE ("ACE_OS::fdopen");
-# if defined (ACE_HAS_WINCE)
- ACE_OSCALL_RETURN (::_wfdopen (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;
-
-# if defined (ACE_WIN64)
- int crt_handle = ::_open_osfhandle (intptr_t (handle), 0);
-# else
- int crt_handle = ::_open_osfhandle (long (handle), 0);
-# endif /* ACE_WIN64 */
-
- 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_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_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_WIN32 && !ACE_HAS_WINCE */
-}
-
-ACE_INLINE int
-ACE_OS::dup2 (ACE_HANDLE oldhandle, ACE_HANDLE newhandle)
-{
- ACE_OS_TRACE ("ACE_OS::dup2");
-#if 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_WIN32 || VXWORKS || ACE_PSOS */
-}
-
-#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_LACKS_FORK)
- ACE_NOTSUP_RETURN (pid_t (-1));
-#else
- ACE_OSCALL_RETURN (::fork (), pid_t, -1);
-#endif /* ACE_LACKS_FORK */
-}
-
-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_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_WIN32 */
-}
-
-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_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_LACKS_GETPPID */
-}
-
-ACE_INLINE int
-ACE_OS::setpgid (pid_t pid, pid_t pgid)
-{
- ACE_OS_TRACE ("ACE_OS::setpgid");
-#if 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_LACKS_SETPGID */
-}
-
-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_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, 0, 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_WIN32 */
-}
-
-#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_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);
-}
-
-ACE_INLINE long
-ACE_OS::ftell (FILE* fp)
-{
- ACE_OSCALL_RETURN (::ftell (fp), long, -1);
-}
-
-ACE_INLINE int
-ACE_OS::fgetpos (FILE* fp, fpos_t* pos)
-{
- ACE_OSCALL_RETURN (::fgetpos (fp, pos), int, -1);
-}
-
-ACE_INLINE int
-ACE_OS::fsetpos (FILE* fp, fpos_t* pos)
-{
- ACE_OSCALL_RETURN (::fsetpos (fp, pos), int, -1);
-}
-
-ACE_INLINE int
-ACE_OS::fgetc (FILE* fp)
-{
- ACE_OSCALL_RETURN (::fgetc (fp), int, -1);
-}
-
-#if !defined (ACE_LACKS_CLEARERR)
-ACE_INLINE void
-ACE_OS::clearerr (FILE* fp)
-{
-#if defined (__ace_clearerr_hack)
- __ace_clearerr(fp);
-#else
- ::clearerr(fp);
-#endif /* __ace_clearerr_hack */
-}
-#endif /* !ACE_LACKS_CLEARERR */
-
-#if defined (ACE_HAS_WCHAR)
-
-ACE_INLINE wint_t
-ACE_OS::fgetwc (FILE* fp)
-{
-#if defined (ACE_LACKS_FGETWC)
- ACE_UNUSED_ARG (fp);
- ACE_NOTSUP_RETURN (0);
-#else
- ACE_OSCALL_RETURN (::fgetwc (fp), wint_t, WEOF);
-#endif /* ACE_LACKS_FGETWC */
-}
-
-ACE_INLINE wint_t
-ACE_OS::ungetwc (wint_t c, FILE* fp)
-{
-#if defined (ACE_LACKS_FGETWC)
- ACE_UNUSED_ARG (c);
- ACE_UNUSED_ARG (fp);
- ACE_NOTSUP_RETURN (0);
-#else
- ACE_OSCALL_RETURN (::ungetwc (c, fp), wint_t, WEOF);
-#endif /* ACE_LACKS_FGETWC */
-}
-
-#endif /* ACE_HAS_WCHAR */
-
-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 (VXWORKS) || defined (ACE_PSOS) || defined (INTEGRITY)
- 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 /* VXWORKS || ACE_PSOS */
-}
-
-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_WIN32) || defined (VXWORKS) || defined(CHORUS) || defined (ACE_PSOS) || defined (INTEGRITY)
- 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_WIN32 || VXWORKS || CHORUS || ACE_PSOS */
-}
-
-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);
-#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_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_WIN32 || CHORUS || ACE_PSOS */
-}
-
-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_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_WIN32 !ACE_HAS_WINCE */
-}
-
-ACE_INLINE ACE_TCHAR *
-ACE_OS::getcwd (ACE_TCHAR *buf, size_t size)
-{
- ACE_OS_TRACE ("ACE_OS::getcwd");
-#if 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)
-# if defined (ACE_USES_WCHAR)
- return ::_wgetcwd (buf, ACE_static_cast (int, size));
-# else
- return ::getcwd (buf, ACE_static_cast (int, size));
-# endif /* ACE_USES_WCHAR */
-#else
- ACE_OSCALL_RETURN (::getcwd (buf, size), char *, 0);
-#endif /* ACE_PSOS_LACKS_PHILE */
-}
-
-ACE_INLINE int
-ACE_OS::sleep (u_int seconds)
-{
- ACE_OS_TRACE ("ACE_OS::sleep");
-#if 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_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_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, 0),
- 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_PSOS_LACKS_PHILE */
-}
-
-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_PSOS)
- ACE_UNUSED_ARG (symbol);
- ACE_NOTSUP_RETURN (0);
-#else /* ACE_PSOS */
- ACE_OSCALL_RETURN (::getenv (symbol), char *, 0);
-#endif /* ACE_LACKS_ENV */
-}
-
-#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 */
-
-#if defined(INTEGRITY)
-extern "C" {
- int putenv(char *string);
-}
-#endif
-
-ACE_INLINE int
-ACE_OS::putenv (const ACE_TCHAR *string)
-{
- ACE_OS_TRACE ("ACE_OS::putenv");
-#if 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_LACKS_ENV)
- ACE_UNUSED_ARG (string);
- ACE_NOTSUP_RETURN (0);
-#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)
-ACE_INLINE long
-ACE_cond_t::waiters (void) const
-{
- return this->waiters_;
-}
-#endif /* ACE_LACKS_COND_T && ACE_HAS_THREADS */
-
-#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, ACE_THR_FUNC_RETURN *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_LACKS_SIGSET) || defined (ACE_LACKS_SIGSET_DEFINITIONS)
- if (s == 0)
- {
- 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_LACKS_SIGSET || ACE_LACKS_SIGSET_DEFINITIONS */
-}
-
-ACE_INLINE int
-ACE_OS::sigdelset (sigset_t *s, int signum)
-{
-#if defined (ACE_LACKS_SIGSET) || defined (ACE_LACKS_SIGSET_DEFINITIONS)
- if (s == 0)
- {
- 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_LACKS_SIGSET || ACE_LACKS_SIGSET_DEFINITIONS */
-}
-
-ACE_INLINE int
-ACE_OS::sigemptyset (sigset_t *s)
-{
-#if defined (ACE_LACKS_SIGSET) || defined (ACE_LACKS_SIGSET_DEFINITIONS)
- if (s == 0)
- {
- 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_LACKS_SIGSET || ACE_LACKS_SIGSET_DEFINITIONS */
-}
-
-ACE_INLINE int
-ACE_OS::sigfillset (sigset_t *s)
-{
-#if defined (ACE_LACKS_SIGSET) || defined (ACE_LACKS_SIGSET_DEFINITIONS)
- if (s == 0)
- {
- 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_LACKS_SIGSET || ACE_LACKS_SIGSET_DEFINITIONS */
-}
-
-ACE_INLINE int
-ACE_OS::sigismember (sigset_t *s, int signum)
-{
-#if defined (ACE_LACKS_SIGSET) || defined (ACE_LACKS_SIGSET_DEFINITIONS)
- if (s == 0)
- {
- 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_LACKS_SIGSET || ACE_LACKS_SIGSET_DEFINITIONS */
-}
-
-ACE_INLINE int
-ACE_OS::sigsuspend (const sigset_t *sigset)
-{
-#if 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_SIGSUSPEND */
-}
-
-ACE_INLINE int
-ACE_OS::sigprocmask (int how, const sigset_t *nsp, sigset_t *osp)
-{
-#if 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_LACKS_SIGSET || ACE_LACKS_SIGSET_DEFINITIONS */
-}
-
-ACE_INLINE int
-ACE_OS::pthread_sigmask (int how, const sigset_t *nsp, sigset_t *osp)
-{
-#if 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_LACKS_PTHREAD_SIGMASK */
- ACE_UNUSED_ARG (how);
- ACE_UNUSED_ARG (nsp);
- ACE_UNUSED_ARG (osp);
- ACE_NOTSUP_RETURN (-1);
-#endif /* ACE_HAS_PTHREADS_STD && !ACE_LACKS_PTHREAD_SIGMASK */
-}
-
// ****************************************************************
-#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_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 (0);
-#endif /* ACE_LACKS_BSEARCH */
-}
-
-ACE_INLINE void
-ACE_OS::qsort (void *base,
- size_t nel,
- size_t width,
- ACE_COMPARE_FUNC compar)
-{
-#if !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_LACKS_QSORT */
-}
-
-ACE_INLINE int
-ACE_OS::setuid (uid_t uid)
-{
- ACE_OS_TRACE ("ACE_OS::setuid");
-#if defined (VXWORKS) || defined (ACE_PSOS) || defined (INTEGRITY)
- // 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 /* VXWORKS || ACE_PSOS */
-}
-
-ACE_INLINE uid_t
-ACE_OS::getuid (void)
-{
- ACE_OS_TRACE ("ACE_OS::getuid");
-#if defined (VXWORKS) || defined (ACE_PSOS) || defined (INTEGRITY)
- // 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 /* VXWORKS || ACE_PSOS */
-}
-
-ACE_INLINE int
-ACE_OS::setgid (gid_t gid)
-{
- ACE_OS_TRACE ("ACE_OS::setgid");
-#if defined (VXWORKS) || defined (ACE_PSOS) || defined (INTEGRITY)
- // 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 /* VXWORKS || ACE_PSOS */
-}
-
-ACE_INLINE gid_t
-ACE_OS::getgid (void)
-{
- ACE_OS_TRACE ("ACE_OS::getgid");
-#if defined (VXWORKS) || defined (ACE_PSOS) || defined (INTEGRITY)
- // 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 /* VXWORKS || ACE_PSOS */
-}
-
-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_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
-# if defined (ACE_WIN64)
- int fd = ::_open_osfhandle (intptr_t (handle), 0);
-# else
- int fd = ::_open_osfhandle (long (handle), 0);
-# endif /* ACE_WIN64 */
-
- int status = ::_isatty (fd);
- ::_close (fd);
- return status;
-#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_HAS_WINCE)
- // WinCE doesn't have environment variables so we just skip it.
- return ACE_OS::strdup (str);
-#elif defined (ACE_LACKS_ENV)
- ACE_UNUSED_ARG (str);
- ACE_NOTSUP_RETURN (0);
-#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::stopped (void) const
-{
- return stopped_;
-}
-
-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 ()
diff --git a/ace/OS_Dirent.cpp b/ace/OS_Dirent.cpp
index 6941272d452..8ca959263ed 100644
--- a/ace/OS_Dirent.cpp
+++ b/ace/OS_Dirent.cpp
@@ -1,24 +1,6 @@
// $Id$
#include "ace/OS_Dirent.h"
-#include "ace/OS_String.h"
-#include "ace/OS_Memory.h"
-#include "ace/Log_Msg.h"
-#include "ace/OS.h"
-
-/*
- These definitions are missing on the original VC6 distribution. The new
- headers that define these are available in the Platform SDK and are defined
- for those that don't have it.
- */
-#if defined (ACE_WIN32)
-# if !defined (INVALID_FILE_ATTRIBUTES)
-# define INVALID_FILE_ATTRIBUTES ((DWORD)-1)
-# endif /* INVALID_FILE_ATTRIBUTES */
-# if !defined (INVALID_SET_FILE_POINTER)
-# define INVALID_SET_FILE_POINTER ((DWORD)-1)
-# endif /* INVALID_SET_FILE_POINTER */
-#endif /* ACE_WIN32 */
ACE_RCSID(ace, OS_Dirent, "$Id$")
@@ -26,252 +8,3 @@ ACE_RCSID(ace, OS_Dirent, "$Id$")
# include "ace/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};
-
- // Check if filename is a directory.
- DWORD fileAttribute = ACE_TEXT_GetFileAttributes (filename);
- if (fileAttribute == INVALID_FILE_ATTRIBUTES
- || !(fileAttribute & FILE_ATTRIBUTE_DIRECTORY))
- return 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;
- if (d->dirent_ != 0)
- {
- ACE_OS_Memory::free (d->dirent_->d_name);
- 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)
- if (d->dirent_ != 0)
- {
- ACE_OS_Memory::free (d->dirent_->d_name);
- ACE_OS_Memory::free (d->dirent_);
- d->dirent_ = 0;
- }
-
- if (!d->started_reading_)
- {
- d->current_handle_ = ACE_TEXT_FindFirstFile (d->directory_name_,
- &d->fdata_);
- 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));
-
- if (d->dirent_ != 0)
- {
- d->dirent_->d_name = (ACE_TCHAR*)
- ACE_OS_Memory::malloc ((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);
- }
-
- 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;
- }
-
-#if defined (ACE_LACKS_STRUCT_DIR)
- dirent *newdp = (dirent *) ACE_OS_Memory::malloc (sizeof (dirent));
-#else
- int dsize =
- sizeof (dirent) +
- ((ACE_OS_String::strlen (dp->d_name) + 1) * sizeof (ACE_TCHAR));
- dirent *newdp = (dirent *) ACE_OS_Memory::malloc (dsize);
-#endif /* ACE_LACKS_STRUCT_DIR */
-
- if (newdp == 0)
- {
- fail = 1;
- break;
- }
-
-#if defined (ACE_LACKS_STRUCT_DIR)
- newdp->d_name = (ACE_TCHAR*) ACE_OS_Memory::malloc (
- (ACE_OS_String::strlen (dp->d_name) + 1) * sizeof (ACE_TCHAR));
-
- if (newdp->d_name == 0)
- {
- fail = 1;
- ACE_OS_Memory::free (newdp);
- break;
- }
-
- // Don't use memcpy here since d_name is now a pointer
- newdp->d_ino = dp->d_ino;
- newdp->d_off = dp->d_off;
- newdp->d_reclen = dp->d_reclen;
- ACE_OS_String::strcpy (newdp->d_name, dp->d_name);
- vector[nfiles++] = newdp;
-#else
- vector[nfiles++] = (dirent *) ACE_OS_String::memcpy (newdp, dp, dsize);
-#endif /* ACE_LACKS_STRUCT_DIR */
- }
-
- if (fail)
- {
- ACE_OS_Dirent::closedir (dirp);
- while (nfiles-- > 0)
- {
-#if defined (ACE_LACKS_STRUCT_DIR)
- ACE_OS_Memory::free (vector[nfiles]->d_name);
-#endif /* ACE_LACKS_STRUCT_DIR */
- 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_Dirent.h b/ace/OS_Dirent.h
index 3c0fb782d03..85fa4be0fe9 100644
--- a/ace/OS_Dirent.h
+++ b/ace/OS_Dirent.h
@@ -26,42 +26,16 @@
#include "ace/os_include/os_dirent.h"
#include "ace/os_include/sys/os_types.h"
+#include "ace/OS_NS_dirent.h"
/**
- * @class ACE_OS_Dirent
+ * @namespace 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,
- struct dirent *entry,
- struct 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,
- struct dirent **namelist[],
- int (*selector) (const struct dirent *filename),
- int (*comparator) (const struct dirent **f1,
- const struct 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 *);
-};
+#define ACE_OS_Dirent ACE_OS
+namespace ACE_OS {
+}; /* namespace ACE_OS */
# if defined (ACE_HAS_INLINED_OSCALLS)
# if defined (ACE_INLINE)
diff --git a/ace/OS_Dirent.inl b/ace/OS_Dirent.inl
index 314f33f32da..7f2b3228624 100644
--- a/ace/OS_Dirent.inl
+++ b/ace/OS_Dirent.inl
@@ -1,192 +1,3 @@
// -*- C++ -*-
// $Id$
-ACE_INLINE ACE_DIR *
-ACE_OS_Dirent::opendir (const ACE_TCHAR *filename)
-{
-#if 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_DIRENT */
-}
-
-ACE_INLINE void
-ACE_OS_Dirent::closedir (ACE_DIR *d)
-{
-#if 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_DIRENT */
-}
-
-ACE_INLINE struct dirent *
-ACE_OS_Dirent::readdir (ACE_DIR *d)
-{
-#if 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_DIRENT */
-}
-
-ACE_INLINE int
-ACE_OS_Dirent::readdir_r (ACE_DIR *dirp,
- struct dirent *entry,
- struct dirent **result)
-{
-#if !defined (ACE_HAS_REENTRANT_FUNCTIONS)
- ACE_UNUSED_ARG (entry);
- // <result> has better not be 0!
- *result = ACE_OS_Dirent::readdir (dirp);
- if (*result)
- return 0; // Keep iterating
- else
- return 1; // Oops, some type of error!
-#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 (__FreeBSD__) || \
- 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_REENTRANT_FUNCTIONS */
-}
-
-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_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_Memory.cpp b/ace/OS_Memory.cpp
index aed484de9d8..5847657bb46 100644
--- a/ace/OS_Memory.cpp
+++ b/ace/OS_Memory.cpp
@@ -14,32 +14,3 @@ static int shut_up_aCC = 0;
#include "ace/os_include/os_stdlib.h"
-void *
-ACE_OS_Memory::malloc (size_t nbytes)
-{
- return ACE_MALLOC_FUNC (nbytes);
-}
-
-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 */
-}
-
-void *
-ACE_OS_Memory::realloc (void *ptr, size_t nbytes)
-{
- return ACE_REALLOC_FUNC (ACE_MALLOC_T (ptr), nbytes);
-}
-
-void
-ACE_OS_Memory::free (void *ptr)
-{
- ACE_FREE_FUNC (ACE_MALLOC_T (ptr));
-}
diff --git a/ace/OS_Memory.h b/ace/OS_Memory.h
index e914deebd1a..fa842b000ea 100644
--- a/ace/OS_Memory.h
+++ b/ace/OS_Memory.h
@@ -232,22 +232,18 @@ typedef void *ACE_MALLOC_T;
((char *) ACE_align_binary (((ptrdiff_t) (ptr)), (alignment)))
//@}
+#include "ace/OS_NS_stdlib.h"
+
/**
- * @class ACE_OS_Memory
+ * @namespace ACE_OS_Memory
*
* @brief This class is a wrapper for dynamic memory operations.
*
*/
-class ACE_OS_Export ACE_OS_Memory
+#define ACE_OS_Memory ACE_OS
+namespace ACE_OS
{
-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 *);
-};
+} /* namespace ACE_OS */
# if defined (ACE_HAS_INLINED_OSCALLS)
# if defined (ACE_INLINE)
diff --git a/ace/OS_Memory.inl b/ace/OS_Memory.inl
index a0cb82573e9..3c4912199de 100644
--- a/ace/OS_Memory.inl
+++ b/ace/OS_Memory.inl
@@ -1,16 +1,7 @@
+// -*- C++ -*-
// $Id$
#if !defined (ACE_LACKS_SBRK)
# include "ace/os_include/os_unistd.h"
#endif /* !ACE_LACKS_SBRK */
-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 */
-}
diff --git a/ace/OS_NS_Thread.cpp b/ace/OS_NS_Thread.cpp
index fc532b41367..3521af1323c 100644
--- a/ace/OS_NS_Thread.cpp
+++ b/ace/OS_NS_Thread.cpp
@@ -1,4 +1,3497 @@
// -*- C++ -*-
// $Id$
-// This is a placeholder.
+#include "ace/OS_NS_Thread.h"
+
+ACE_RCSID(ace, OS_NS_Thread, "$Id$")
+
+#if !defined (ACE_HAS_INLINED_OSCALLS)
+# include "ace/OS_NS_Thread.inl"
+#endif /* ACE_HAS_INLINED_OS_CALLS */
+
+#include "ace/OS_NS_stdio.h"
+#include "ace/Sched_Params.h"
+#include "ace/OS_Memory.h"
+#include "ace/OS_Thread_Adapter.h"
+
+// 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;
+}
+
+void
+ACE_Thread_ID::to_string (char* thr_id)
+{
+
+ char format[128]; // Converted format string
+ char *fp; // Current format pointer
+ fp = format;
+ *fp++ = '%'; // Copy in the %
+
+#if defined (ACE_WIN32)
+ ACE_OS::strcpy (fp, "u");
+ ACE_OS::sprintf (thr_id,
+ format,
+ ACE_static_cast(unsigned,
+ ACE_OS::thr_self ()));
+#elif defined (ACE_AIX_VERS) && (ACE_AIX_VERS <= 402)
+ // AIX's pthread_t (ACE_hthread_t) is a pointer, and it's
+ // a little ugly to send that through a %u format. So,
+ // get the kernel thread ID (tid_t) via thread_self() and
+ // display that instead.
+ // This isn't conditionalized on ACE_HAS_THREAD_SELF because
+ // 1. AIX 4.2 doesn't have that def anymore (it messes up
+ // other things)
+ // 2. OSF/1 V3.2 has that def, and I'm not sure what affect
+ // this would have on that.
+ // -Steve Huston, 19-Aug-97
+ ACE_OS::strcpy (fp, "u");
+ ACE_OS::sprintf (thr_id, format, thread_self());
+#elif defined (DIGITAL_UNIX)
+ ACE_OS::strcpy (fp, "u");
+ ACE_OS::sprintf (thr_id, format,
+# if defined (ACE_HAS_THREADS)
+ pthread_getselfseq_np ()
+# else
+ ACE_Thread::self ()
+# endif /* ACE_HAS_THREADS */
+ );
+#else
+ ACE_hthread_t t_id;
+ ACE_OS::thr_self (t_id);
+
+# if defined (ACE_HAS_PTHREADS_DRAFT4) && defined (HPUX_10)
+ ACE_OS::strcpy (fp, "u");
+ // HP-UX 10.x DCE's thread ID is a pointer. Grab the
+ // more meaningful, readable, thread ID. This will match
+ // the one seen in the debugger as well.
+ ACE_OS::sprintf (thr_id, format,
+ pthread_getunique_np(&t_id));
+# elif defined (ACE_MVS)
+ // MVS's pthread_t is a struct... yuck. So use the ACE 5.0
+ // code for it.
+ ACE_OS::strcpy (fp, "u");
+ ACE_OS::sprintf (thr_id, format, t_id);
+# else
+ // Yes, this is an ugly C-style cast, but the correct
+ // C++ cast is different depending on whether the t_id
+ // is an integral type or a pointer type. FreeBSD uses
+ // a pointer type, but doesn't have a _np function to
+ // get an integral type, like the OSes above.
+ ACE_OS::strcpy (fp, "lu");
+ ACE_OS::sprintf (thr_id, format, (unsigned long)t_id);
+# endif /* ACE_HAS_PTHREADS_DRAFT4 && HPUX_10 */
+
+#endif /* ACE_WIN32 */
+}
+
+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);
+}
+
+/*****************************************************************************/
+
+#if defined (ACE_WIN32) || defined (ACE_HAS_TSS_EMULATION) || (defined (ACE_PSOS) && defined (ACE_PSOS_HAS_TSS))
+
+#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 */
+
+/*****************************************************************************/
+
+#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)
+{
+# if defined (ACE_HAS_DUMP)
+ // 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 */
+# endif /* ACE_HAS_DUMP */
+}
+
+// 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
+ *
+ * @brief Singleton that knows how to clean up all the thread-specific
+ * resources for Win32.
+ *
+ * All this nonsense is required since Win32 doesn't
+ * automatically cleanup thread-specific storage on thread exit,
+ * unlike real operating systems... ;-)
+ */
+class ACE_TSS_Cleanup
+{
+public:
+ static ACE_TSS_Cleanup *instance (void);
+
+ ~ACE_TSS_Cleanup (void);
+
+ /// Cleanup the thread-specific objects. Does _NOT_ exit the thread.
+ void exit (void *status);
+
+ /// Insert a <key, destructor> tuple into the table.
+ int insert (ACE_thread_key_t key, void (*destructor)(void *), void *inst);
+
+ /// Remove a <key, destructor> tuple from the table.
+ int remove (ACE_thread_key_t key);
+
+ /// Detaches a tss_instance from its key.
+ int detach (void *inst);
+
+ /// Mark a key as being used by this thread.
+ void key_used (ACE_thread_key_t key);
+
+ /// Free all keys left in the table before destruction.
+ int free_all_keys_left (void);
+
+ /// Indication of whether the ACE_TSS_CLEANUP_LOCK is usable, and
+ /// therefore whether we are in static constructor/destructor phase
+ /// or not.
+ static int lockable () { return instance_ != 0; }
+
+protected:
+ void dump (void);
+
+ /// Ensure singleton.
+ ACE_TSS_Cleanup (void);
+
+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;
+
+ /// Table of <ACE_TSS_Info>'s.
+ ACE_TSS_TABLE table_;
+
+ /// Key for the thread-specific array of whether each TSS key is in use.
+ ACE_thread_key_t in_use_;
+
+ /// Accessor for this threads ACE_TSS_Keys instance.
+ ACE_TSS_Keys *tss_keys ();
+
+# if defined (ACE_HAS_TSS_EMULATION)
+ /// 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 ().
+ ACE_thread_key_t in_use_key_;
+# endif /* ACE_HAS_TSS_EMULATION */
+
+ // = Static data.
+ /// Pointer to the singleton instance.
+ static ACE_TSS_Cleanup *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 test/clear the in "use bit" if the program is
+ // shutting down. Doing so will cause a new ACE_TSS object to be
+ // created again.
+ if (!ACE_OS_Object_Manager::shutting_down ())
+ tss_keys ()->test_and_clear (info.key_);
+ info.key_in_use (0);
+ 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.key_in_use ())
+ key_info.key_in_use (1);
+ else
+ ++key_info.thread_count_;
+ }
+}
+
+void
+ACE_TSS_Cleanup::dump (void)
+{
+# if defined (ACE_HAS_DUMP)
+ // 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 ();
+# endif /* ACE_HAS_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;
+}
+
+#endif /* ACE_WIN32 || ACE_HAS_TSS_EMULATION || (ACE_PSOS && ACE_PSOS_HAS_TSS) */
+
+/*****************************************************************************/
+
+// = 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 */
+
+/*****************************************************************************/
+
+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_LACKS_COND_T) && ! defined (ACE_PSOS_DIAB_MIPS)
+// 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.
+
+// @@ 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_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_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 */
+}
+
+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_wait (ACE_cond_t *cv,
+ ACE_mutex_t *external_mutex)
+{
+ ACE_OS_TRACE ("ACE_OS::cond_wait");
+# if 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.
+ ACE_WIN32CALL (ACE_ADAPT_RETVAL (::SignalObjectAndWait (external_mutex->proc_mutex_,
+ cv->sema_, INFINITE, FALSE),
+ result),
+ int, -1, result);
+ 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_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.
+ result = ::SignalObjectAndWait (external_mutex->proc_mutex_,
+ cv->sema_,
+ msec_timeout,
+ FALSE);
+ 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_,
+ timeout);
+# 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_,
+ timeout);
+
+ 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 */
+
+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 */
+}
+
+void
+ACE_OS::mutex_lock_cleanup (void *mutex)
+{
+ ACE_OS_TRACE ("ACE_OS::mutex_lock_cleanup");
+#if 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_THREADS */
+}
+
+#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 */
+
+int
+ACE_OS::sched_params (const ACE_Sched_Params &sched_params,
+ ACE_id_t id)
+{
+ ACE_OS_TRACE ("ACE_OS::sched_params");
+#if 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 ||
+ sched_params.policy () == ACE_SCHED_RR)
+ ? 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 /* CHORUS */
+}
+
+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_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) */
+
+
+ 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 defined (ACE_HAS_PTHREAD_SETSTACK)
+ if ((stacksize != 0) && (stack != 0))
+# else
+ if (stacksize != 0)
+# endif /* ACE_HAS_PTHREAD_SETSTACK */
+ {
+ 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 defined (ACE_HAS_PTHREAD_SETSTACK)
+ if (ACE_ADAPT_RETVAL(pthread_attr_setstack (&attr, stack, size), result) == -1)
+# else
+ if (ACE_ADAPT_RETVAL(pthread_attr_setstacksize (&attr, size), result) == -1)
+# endif /* ACE_HAS_PTHREAD_SETSTACK */
+# 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_HAS_PTHREAD_SETSTACK)
+# 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 */
+# endif /* ACE_HAS_PTHREAD_SETSTACK */
+
+ // *** 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,
+ ACE_static_cast
+ (u_int, 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 */
+}
+
+void
+ACE_OS::thr_exit (ACE_THR_FUNC_RETURN status)
+{
+ ACE_OS_TRACE ("ACE_OS::thr_exit");
+#if 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 (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 (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_THREADS */
+}
+
+#if defined (VXWORKS)
+// Leave this in the global scope to allow
+// users to adjust the delay value.
+int ACE_THR_JOIN_DELAY = 5;
+
+int
+ACE_OS::thr_join (ACE_hthread_t thr_handle,
+ ACE_THR_FUNC_RETURN *status)
+{
+ // We can't get the status of the thread
+ if (status != 0)
+ {
+ *status = 0;
+ }
+
+ // This method can not support joining all threads
+ if (ACE_OS::thr_cmp (thr_handle, ACE_OS::NULL_hthread))
+ {
+ ACE_NOTSUP_RETURN (-1);
+ }
+
+ int retval = ESRCH;
+ ACE_hthread_t current;
+ ACE_OS::thr_self (current);
+
+ // Make sure we are not joining ourself
+ if (ACE_OS::thr_cmp (thr_handle, current))
+ {
+ retval = EDEADLK;
+ }
+ else
+ {
+ // Whether the task exists or not
+ // we will return a successful value
+ retval = 0;
+
+ // Verify that the task id still exists
+ while (taskIdVerify (thr_handle) == OK)
+ {
+ // Wait a bit to see if the task is still active.
+ ACE_OS::sleep (ACE_THR_JOIN_DELAY);
+ }
+ }
+
+ // Adapt the return value into errno and return value.
+ // The ACE_ADAPT_RETVAL macro doesn't exactly do what
+ // we need to do here, so we do it manually.
+ if (retval != 0)
+ {
+ errno = retval;
+ retval = -1;
+ }
+
+ return retval;
+}
+
+int
+ACE_OS::thr_join (ACE_thread_t waiter_id,
+ ACE_thread_t *thr_id,
+ ACE_THR_FUNC_RETURN *status)
+{
+ thr_id = 0;
+ return ACE_OS::thr_join (taskNameToId (waiter_id), status);
+}
+#endif /* VXWORKS */
+
+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 */
+}
+
+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 */
+}
+
+#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_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_THREADS */
+}
+#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 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_THREADS */
+}
+
+int
+ACE_OS::thr_keyfree (ACE_thread_key_t key)
+{
+ ACE_OS_TRACE ("ACE_OS::thr_keyfree");
+#if 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_THREADS */
+}
+
+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;
+}
+
+#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 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_THREADS */
+}
+
+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 ("%p%d"),
+ object,
+ ACE_static_cast (int, ACE_OS::getpid ()));
+ ACE_OS::strsncpy (name,
+ temp_name,
+ length);
+}
+
diff --git a/ace/OS_NS_Thread.h b/ace/OS_NS_Thread.h
index fc532b41367..b9480257c6a 100644
--- a/ace/OS_NS_Thread.h
+++ b/ace/OS_NS_Thread.h
@@ -1,4 +1,1723 @@
// -*- C++ -*-
-// $Id$
-// This is a placeholder.
+//=============================================================================
+/**
+ * @file OS_NS_Thread.h
+ *
+ * $Id$
+ *
+ * @author Douglas C. Schmidt <schmidt@cs.wustl.edu>
+ * @author Jesper S. M|ller<stophph@diku.dk>
+ * @author and a cast of thousands...
+ *
+ * Originally in OS.h.
+ */
+//=============================================================================
+
+#ifndef ACE_OS_NS_THREAD_H
+# define ACE_OS_NS_THREAD_H
+
+# include /**/ "ace/pre.h"
+
+# include "ace/config-all.h"
+
+# if !defined (ACE_LACKS_PRAGMA_ONCE)
+# pragma once
+# endif /* ACE_LACKS_PRAGMA_ONCE */
+
+# include "ace/Global_Macros.h"
+# include "ace/Default_Constants.h"
+# include "ace/os_include/os_pthread.h"
+# include "ace/Base_Thread_Adapter.h"
+# include "ace/os_include/sys/os_sem.h"
+# include "ace/OS_Memory.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_PSOS)
+// Use pSOS semaphores, wrapped . . .
+typedef struct
+{
+ /// Semaphore handle. This is allocated by pSOS.
+ u_long sema_;
+
+ /// Name of the semaphore: really a 32 bit number to pSOS
+ char name_[4];
+} ACE_sema_t;
+# endif /* ACE_PSOS */
+
+# if defined (ACE_PSOS)
+
+// Wrapper for NT events on pSOS.
+class ACE_OS_Export ACE_event_t
+{
+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 */
+
+# if defined (ACE_WIN32)
+typedef DWORD ACE_thread_t;
+typedef HANDLE ACE_hthread_t;
+# 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 */
+# endif /* ACE_WIN32 */
+
+# 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)
+// moved to pthread.h
+# 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)
+# include /**/ <sysLib.h> // for sysClkRateGet()
+# include /**/ <taskLib.h>
+# include /**/ <taskHookLib.h>
+
+// make sure these are included for VXWORKS.
+// @todo move these to a common place, perhaps the top of the file.
+# include "ace/os_include/os_fcntl.h"
+# include "ace/os_include/os_netdb.h"
+# include "ace/os_include/os_semaphore.h"
+# include "ace/os_include/os_signal.h"
+# include "ace/os_include/os_stdio.h"
+# include "ace/os_include/os_stdlib.h"
+# include "ace/os_include/os_stropts.h"
+# include "ace/os_include/os_unistd.h"
+# include "ace/os_include/arpa/os_inet.h"
+# include "ace/os_include/sys/os_select.h"
+# include "ace/os_include/sys/os_socket.h"
+
+// 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). */
+
+typedef SEM_ID ACE_mutex_t;
+// 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
+{
+ /// Semaphore handle. This is allocated by VxWorks.
+ SEM_ID sema_;
+
+ /// Name of the semaphore: always NULL with VxWorks.
+ char *name_;
+} ACE_sema_t;
+# endif /* !ACE_HAS_POSIX_SEM */
+typedef char * ACE_thread_t;
+typedef int ACE_hthread_t;
+// 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;
+
+typedef struct
+{
+ /// Either USYNC_THREAD or USYNC_PROCESS
+ int type_;
+ union
+ {
+ HANDLE proc_mutex_;
+ CRITICAL_SECTION thr_mutex_;
+ };
+} ACE_mutex_t;
+
+// Wrapper for NT Events.
+typedef HANDLE ACE_event_t;
+
+# if defined (ACE_WIN32)
+//@@ 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 /* 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)
+/**
+ * @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:
+
+ /// 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;
+};
+
+struct ACE_OS_Export ACE_mutexattr_t
+{
+ int type;
+};
+# 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:
+
+ 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 */
+
+// Recursive mutex support.
+//
+// There are two parts to this:
+// 1. The mutex type itself. This is based on whether or not the
+// platform supports recursive mutexes natively or they're emulated.
+// 2. Support for using the recursive mutex with a condition variable.
+// When a thread waits on a condition variable, it has to relinquish
+// the lock and wait atomically, then reacquire it after the condition
+// variable is signaled. In non-recursive mutexes, the platform
+// handles this automatically. But in recursive mutexes, especially
+// when emulated, the recursion count needs to be maintained across
+// the wait. Since another thread needs to be able to acquire the
+// lock, it needs to appear free, even if the waiting thread had done
+// multiple acquires. Thus, there's another structure to hold this
+// information, and is used with the recursive_mutex_cond_unlock()
+// and recursive_mutex_cond_relock() methods to maintain the expected
+// state when the wait finishes.
+# if defined (ACE_HAS_RECURSIVE_MUTEXES)
+typedef ACE_thread_mutex_t ACE_recursive_thread_mutex_t;
+# if defined (ACE_WIN32)
+// Windows has recursive mutexes, but doesn't have condition variables,
+// so there's no built-in support for this. Thus, the condition-related
+// unlock/relock is augmented in ACE.
+struct ACE_recursive_mutex_state
+{
+ // On Windows the augmented processing is simply unlocking/relocking
+ // the recursive locks - the condition handles a single lock ok.
+ LONG relock_count_;
+};
+# else
+// No need for special handling; just need a type for method signatures.
+typedef int ACE_recursive_mutex_state;
+# endif /* ACE_WIN32 */
+# 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_;
+};
+
+// Since recursive mutex is emulated, the state saving needs to be handled
+// in ACE as well. These members save those from ACE_recursive_thread_mutex_t.
+struct ACE_recursive_mutex_state
+{
+ int nesting_level_;
+ ACE_thread_t owner_id_;
+};
+# endif /* ACE_HAS_RECURSIVE_MUTEXES */
+
+# 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;
+typedef int ACE_recursive_mutex_state;
+# 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 unsigned 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 ***********************************************/
+
+/**
+ * @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);
+
+ void to_string (char*);
+
+
+ // != 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_;
+};
+
+// = 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;
+
+# if !defined (ACE_DEFAULT_SYNCH_TYPE)
+# if defined (VXWORKS)
+ // 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
+# else
+# define ACE_DEFAULT_SYNCH_TYPE USYNC_THREAD
+# endif /* VXWORKS */
+#endif /* ! ACE_DEFAULT_SYNCH_TYPE */
+
+// forward declaration
+class ACE_Sched_Params;
+class ACE_Time_Value;
+
+# if defined (ACE_PSOS)
+typedef u_long ACE_idtype_t;
+typedef u_long ACE_id_t;
+typedef u_long ACE_pri_t;
+# define ACE_SELF (0)
+# elif defined (ACE_WIN32)
+typedef int ACE_idtype_t;
+typedef DWORD ACE_id_t;
+typedef int ACE_pri_t;
+# define ACE_SELF (0)
+# else /* !defined (ACE_WIN32) && !defined (ACE_PSOS) */
+# 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 */
+# endif /* !defined (ACE_WIN32) && !defined (ACE_PSOS) */
+
+# 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 () implementation 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 */
+
+# if 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_THR_C_FUNC */
+
+// forward decl's
+class ACE_event_t;
+
+namespace ACE_OS {
+
+# if 0
+ //@{ @name A set of wrappers for threads (these are portable since they use the ACE_Thread_ID).
+ int thr_continue (const ACE_Thread_ID &thread);
+ 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);
+ int thr_getprio (ACE_Thread_ID thr_id,
+ int &prio,
+ int *policy = 0);
+ int thr_join (ACE_Thread_ID waiter_id,
+ ACE_THR_FUNC_RETURN *status);
+ int thr_kill (ACE_Thread_ID thr_id,
+ int signum);
+ ACE_Thread_ID thr_self (void);
+ int thr_setprio (ACE_Thread_ID thr_id,
+ int prio);
+ int thr_setprio (const ACE_Sched_Priority prio);
+ int thr_suspend (ACE_Thread_ID target_thread);
+ int thr_cancel (ACE_Thread_ID t_id);
+ //@}
+# endif /* 0 */
+
+
+ //@{ @name A set of wrappers for threads
+
+ /// This is necessary to deal with POSIX pthreads and their use of
+ /// structures for thread ids.
+ extern ACE_thread_t NULL_thread;
+
+ /// This is necessary to deal with POSIX pthreads and their use of
+ /// structures for thread handles.
+ extern ACE_hthread_t NULL_hthread;
+
+ /// This is necessary to deal with POSIX pthreads and their use of
+ /// structures for TSS keys.
+ extern 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.
+ KnCap actorcaps_[ACE_CHORUS_MAX_ACTORS];
+# endif /* CHORUS */
+ //@}
+
+ /**
+ * 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.
+ */
+ void cleanup_tss (const u_int main_thread);
+
+ //@{ @name A set of wrappers for condition variables.
+ int condattr_init (ACE_condattr_t &attributes,
+ int type = ACE_DEFAULT_SYNCH_TYPE);
+ int condattr_destroy (ACE_condattr_t &attributes);
+ int cond_broadcast (ACE_cond_t *cv);
+ int cond_destroy (ACE_cond_t *cv);
+ int cond_init (ACE_cond_t *cv,
+ short type = ACE_DEFAULT_SYNCH_TYPE,
+ const char *name = 0,
+ void *arg = 0);
+ int cond_init (ACE_cond_t *cv,
+ ACE_condattr_t &attributes,
+ const char *name = 0,
+ void *arg = 0);
+# if defined (ACE_HAS_WCHAR)
+ int cond_init (ACE_cond_t *cv,
+ short type,
+ const wchar_t *name,
+ void *arg = 0);
+ int cond_init (ACE_cond_t *cv,
+ ACE_condattr_t &attributes,
+ const wchar_t *name,
+ void *arg = 0);
+# endif /* ACE_HAS_WCHAR */
+ int cond_signal (ACE_cond_t *cv);
+ int cond_timedwait (ACE_cond_t *cv,
+ ACE_mutex_t *m,
+ ACE_Time_Value *);
+ int cond_wait (ACE_cond_t *cv,
+ ACE_mutex_t *m);
+# if defined (ACE_WIN32) && defined (ACE_HAS_WTHREADS)
+ int cond_timedwait (ACE_cond_t *cv,
+ ACE_thread_mutex_t *m,
+ ACE_Time_Value *);
+ int cond_wait (ACE_cond_t *cv,
+ ACE_thread_mutex_t *m);
+# endif /* ACE_WIN32 && ACE_HAS_WTHREADS */
+
+ //@{ @name A set of wrappers for auto-reset and manual events.
+
+ int event_destroy (ACE_event_t *event);
+
+ 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)
+ 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 */
+
+ int event_pulse (ACE_event_t *event);
+
+ int event_reset (ACE_event_t *event);
+
+ int event_signal (ACE_event_t *event);
+
+ int event_timedwait (ACE_event_t *event,
+ ACE_Time_Value *timeout,
+ int use_absolute_time = 1);
+
+ int event_wait (ACE_event_t *event);
+
+ //@}
+
+ int lwp_getparams (ACE_Sched_Params &);
+
+ int lwp_setparams (const ACE_Sched_Params &);
+
+
+ //@{ @name A set of wrappers for mutex locks.
+
+ int mutex_destroy (ACE_mutex_t *m);
+
+ 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)
+ 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 */
+
+ /// Win32 note: Abandoned mutexes are not treated differently. 0 is
+ /// returned since the calling thread does get the ownership.
+ 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.
+ 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.
+ */
+ 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.
+ */
+ int mutex_lock (ACE_mutex_t *m,
+ const ACE_Time_Value *timeout);
+
+ /// Handle asynchronous thread cancellation cleanup.
+ void mutex_lock_cleanup (void *mutex);
+
+ /// Win32 note: Abandoned mutexes are not treated differently. 0 is
+ /// returned since the calling thread does get the ownership.
+ 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.
+ int mutex_trylock (ACE_mutex_t *m,
+ int &abandoned);
+
+ int mutex_unlock (ACE_mutex_t *m);
+
+ //@}
+
+ /// Low-level interface to <priocntl>(2).
+ /**
+ * Can't call the following priocntl, because that's a macro on
+ * Solaris.
+ */
+ int priority_control (ACE_idtype_t, ACE_id_t, int, void *);
+
+ //@{ @name A set of wrappers for recursive mutex locks.
+
+ // These two methods are primarily in support of
+ // ACE_Condition<ACE_Recursive_Thread_Mutex> and should probably not
+ // be called outside that context.
+ int recursive_mutex_cond_unlock (ACE_recursive_thread_mutex_t *m,
+ ACE_recursive_mutex_state &state);
+
+ void recursive_mutex_cond_relock (ACE_recursive_thread_mutex_t *m,
+ ACE_recursive_mutex_state &state);
+
+ int recursive_mutex_destroy (ACE_recursive_thread_mutex_t *m);
+
+ int recursive_mutex_init (ACE_recursive_thread_mutex_t *m,
+ const ACE_TCHAR *name = 0,
+ ACE_mutexattr_t *arg = 0,
+ LPSECURITY_ATTRIBUTES sa = 0);
+
+ int recursive_mutex_lock (ACE_recursive_thread_mutex_t *m);
+
+ int recursive_mutex_trylock (ACE_recursive_thread_mutex_t *m);
+
+ int recursive_mutex_unlock (ACE_recursive_thread_mutex_t *m);
+
+ //@}
+
+
+ //@{ @name A set of wrappers for readers/writer locks.
+
+ int rw_rdlock (ACE_rwlock_t *rw);
+
+ int rw_tryrdlock (ACE_rwlock_t *rw);
+
+ int rw_trywrlock (ACE_rwlock_t *rw);
+
+ int rw_trywrlock_upgrade (ACE_rwlock_t *rw);
+
+ int rw_unlock (ACE_rwlock_t *rw);
+
+ int rw_wrlock (ACE_rwlock_t *rw);
+
+ int rwlock_destroy (ACE_rwlock_t *rw);
+
+ int rwlock_init (ACE_rwlock_t *rw,
+ int type = ACE_DEFAULT_SYNCH_TYPE,
+ const ACE_TCHAR *name = 0,
+ void *arg = 0);
+
+ //@}
+
+ //@{ @name Thread scheduler interface.
+ /// Set scheduling parameters. An id of ACE_SELF indicates, e.g.,
+ /// set the parameters on the calling thread.
+ int sched_params (const ACE_Sched_Params &, ACE_id_t id = ACE_SELF);
+ //@}
+
+ /// Find the schedling class ID that corresponds to the class name.
+ int scheduling_class (const char *class_name, ACE_id_t &);
+
+ //@{ @name A set of wrappers for semaphores.
+
+ int sema_destroy (ACE_sema_t *s);
+
+ 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)
+ 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 */
+
+ int sema_post (ACE_sema_t *s);
+
+ int sema_post (ACE_sema_t *s,
+ u_int release_count);
+
+ int sema_trywait (ACE_sema_t *s);
+
+ int sema_wait (ACE_sema_t *s);
+
+ int sema_wait (ACE_sema_t *s,
+ ACE_Time_Value &tv);
+
+ int sema_wait (ACE_sema_t *s,
+ ACE_Time_Value *tv);
+
+ //@}
+
+ //@{ @name A set of wrappers for System V semaphores.
+ int semctl (int int_id,
+ int semnum,
+ int cmd,
+ semun);
+ int semget (key_t key,
+ int nsems,
+ int flags);
+ int semop (int int_id,
+ struct sembuf *sops,
+ size_t nsops);
+ //@}
+
+ /// Friendly interface to <priocntl>(2).
+ int set_scheduling_params (const ACE_Sched_Params &,
+ ACE_id_t id = ACE_SELF);
+
+ int sigtimedwait (const sigset_t *set,
+ siginfo_t *info,
+ const ACE_Time_Value *timeout);
+
+ int sigwait (sigset_t *set,
+ int *sig = 0);
+
+ int sigwaitinfo (const sigset_t *set,
+ siginfo_t *info);
+
+ int thr_cancel (ACE_thread_t t_id);
+
+ int thr_cmp (ACE_hthread_t t1,
+ ACE_hthread_t t2);
+ // These are non-portable since they use ACE_thread_t and
+ // ACE_hthread_t and will go away in a future release.
+ 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.
+ */
+ 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);
+
+ int thr_equal (ACE_thread_t t1,
+ ACE_thread_t t2);
+
+ void thr_exit (ACE_THR_FUNC_RETURN status = 0);
+
+ int thr_getconcurrency (void);
+
+ int thr_getprio (ACE_hthread_t id,
+ int &priority);
+
+ int thr_getprio (ACE_hthread_t id,
+ int &priority,
+ int &policy);
+
+# if defined (ACE_HAS_TSS_EMULATION) && defined (ACE_HAS_THREAD_SPECIFIC_STORAGE)
+ int thr_getspecific (ACE_OS_thread_key_t key,
+ void **data);
+# endif /* ACE_HAS_TSS_EMULATION && ACE_HAS_THREAD_SPECIFIC_STORAGE */
+
+ int thr_getspecific (ACE_thread_key_t key,
+ void **data);
+
+ int thr_join (ACE_hthread_t waiter_id,
+ ACE_THR_FUNC_RETURN *status);
+
+ int thr_join (ACE_thread_t waiter_id,
+ ACE_thread_t *thr_id,
+ ACE_THR_FUNC_RETURN *status);
+
+ int thr_key_detach (void *inst);
+
+ int thr_key_used (ACE_thread_key_t key);
+
+# if defined (ACE_HAS_THR_C_DEST)
+# if defined (ACE_HAS_TSS_EMULATION) && defined (ACE_HAS_THREAD_SPECIFIC_STORAGE)
+ 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 */
+ 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)
+ 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 */
+ int thr_keycreate (ACE_thread_key_t *key,
+ ACE_THR_DEST,
+ void *inst = 0);
+# endif /* ACE_HAS_THR_C_DEST */
+
+ int thr_keyfree (ACE_thread_key_t key);
+
+ int thr_kill (ACE_thread_t thr_id,
+ int signum);
+
+ size_t thr_min_stack (void);
+
+ ACE_thread_t thr_self (void);
+
+ void thr_self (ACE_hthread_t &);
+
+ int thr_setcancelstate (int new_state,
+ int *old_state);
+
+ int thr_setcanceltype (int new_type,
+ int *old_type);
+
+ int thr_setconcurrency (int hint);
+
+ int thr_setprio (ACE_hthread_t id,
+ int priority,
+ int policy = -1);
+
+ int thr_setprio (const ACE_Sched_Priority prio);
+
+# if defined (ACE_HAS_TSS_EMULATION) && defined (ACE_HAS_THREAD_SPECIFIC_STORAGE)
+ int thr_setspecific (ACE_OS_thread_key_t key,
+ void *data);
+# endif /* ACE_HAS_TSS_EMULATION && ACE_HAS_THREAD_SPECIFIC_STORAGE */
+
+ int thr_setspecific (ACE_thread_key_t key,
+ void *data);
+
+ int thr_sigsetmask (int how,
+ const sigset_t *nsm,
+ sigset_t *osm);
+
+ int thr_suspend (ACE_hthread_t target_thread);
+
+ void thr_testcancel (void);
+
+ void thr_yield (void);
+
+ //@{ @name A set of wrappers for mutex locks that only work within a single process.
+
+ int thread_mutex_destroy (ACE_thread_mutex_t *m);
+
+ 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)
+ int thread_mutex_init (ACE_thread_mutex_t *m,
+ int type,
+ const wchar_t *name,
+ ACE_mutexattr_t *arg = 0);
+#endif /* ACE_HAS_WCHAR */
+
+ int thread_mutex_lock (ACE_thread_mutex_t *m);
+
+ int thread_mutex_lock (ACE_thread_mutex_t *m,
+ const ACE_Time_Value &timeout);
+
+ int thread_mutex_lock (ACE_thread_mutex_t *m,
+ const ACE_Time_Value *timeout);
+
+ int thread_mutex_trylock (ACE_thread_mutex_t *m);
+
+ int thread_mutex_unlock (ACE_thread_mutex_t *m);
+
+ //@}
+
+ /**
+ * 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>.
+ */
+ void unique_name (const void *object,
+ ACE_TCHAR *name,
+ size_t length);
+
+ //@}
+
+} /* namespace ACE_OS */
+
+/**
+ * @class ACE_event_t
+ *
+ * @brief Wrapper for NT events on UNIX.
+ */
+class ACE_OS_Export ACE_event_t
+{
+ friend int ACE_OS::event_init(ACE_event_t*, int, int, int, const char*, void*,int);
+ friend int ACE_OS::event_destroy(ACE_event_t*);
+ friend int ACE_OS::event_wait(ACE_event_t*);
+ friend int ACE_OS::event_timedwait(ACE_event_t*, ACE_Time_Value*, int);
+ friend int ACE_OS::event_signal(ACE_event_t*);
+ friend int ACE_OS::event_pulse(ACE_event_t*);
+ friend int ACE_OS::event_reset(ACE_event_t*);
+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.
+ unsigned long waiting_threads_;
+};
+
+#if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0)
+# 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)
+ {
+# if defined (ACE_DISABLES_THREAD_LIBRARY_CALLS) && (ACE_DISABLES_THREAD_LIBRARY_CALLS == 1)
+ ::DisableThreadLibraryCalls (instance);
+# endif /* ACE_DISABLES_THREAD_LIBRARY_CALLS */
+ 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
+ *
+ * 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.
+ *
+ * For internal use only by ACE_OS.
+ */
+class ACE_OS_Thread_Mutex_Guard
+{
+public:
+ /// Implicitly and automatically acquire the lock.
+ ACE_OS_Thread_Mutex_Guard (ACE_thread_mutex_t &m);
+
+ /// Implicitly release the lock.
+ ~ACE_OS_Thread_Mutex_Guard (void);
+
+ /// Explicitly acquire the lock.
+ int acquire (void);
+
+ /// Explicitly release the lock.
+ int release (void);
+
+protected:
+ /// Reference to the mutex.
+ ACE_thread_mutex_t &lock_;
+
+ /// Keeps track of whether we acquired the lock or failed.
+ int owner_;
+
+ // = 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 &);
+};
+
+/**
+ * @class ACE_OS_Recursive_Thread_Mutex_Guard
+ *
+ * @brief For internal use only by ACE_OS.
+ *
+ * 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.
+ */
+class ACE_OS_Recursive_Thread_Mutex_Guard
+{
+public:
+ /// Implicitly and automatically acquire the lock.
+ ACE_OS_Recursive_Thread_Mutex_Guard (ACE_recursive_thread_mutex_t &m);
+
+ /// Implicitly release the lock.
+ ~ACE_OS_Recursive_Thread_Mutex_Guard (void);
+
+ /// Explicitly acquire the lock.
+ int acquire (void);
+
+ /// Explicitly release the lock.
+ int release (void);
+
+protected:
+ /// Reference to the mutex.
+ ACE_recursive_thread_mutex_t &lock_;
+
+ /// Keeps track of whether we acquired the lock or failed.
+ int owner_;
+
+ // = 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 &);
+};
+
+// used in time and unistd
+# 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]);
+
+// used in Thread
+# 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]);
+
+// used in Thread
+# 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]);
+
+#else /* ! ACE_MT_SAFE */
+# define ACE_OS_GUARD
+# define ACE_TSS_CLEANUP_GUARD
+# define ACE_TSS_BASE_GUARD
+#endif /* ! ACE_MT_SAFE */
+
+# if defined (ACE_HAS_INLINED_OSCALLS)
+# if defined (ACE_INLINE)
+# undef ACE_INLINE
+# endif /* ACE_INLINE */
+# define ACE_INLINE inline
+# include "ace/OS_NS_Thread.inl"
+# endif /* ACE_HAS_INLINED_OSCALLS */
+
+# include /**/ "ace/post.h"
+#endif /* ACE_OS_NS_THREAD_H */
diff --git a/ace/OS_NS_Thread.inl b/ace/OS_NS_Thread.inl
index fc532b41367..3f158e8c4dc 100644
--- a/ace/OS_NS_Thread.inl
+++ b/ace/OS_NS_Thread.inl
@@ -1,4 +1,4590 @@
// -*- C++ -*-
// $Id$
-// This is a placeholder.
+#include "ace/OS_NS_macros.h"
+// for timespec_t, perhaps move it to os_time.h
+#include "ace/Time_Value.h"
+#include "ace/OS_NS_sys_time.h"
+#include "ace/OS_NS_string.h"
+#include "ace/OS_NS_unistd.h"
+
+#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_COND_T) && defined (ACE_HAS_THREADS)
+ACE_INLINE long
+ACE_cond_t::waiters (void) const
+{
+ return this->waiters_;
+}
+#endif /* ACE_LACKS_COND_T && ACE_HAS_THREADS */
+
+/*****************************************************************************/
+
+#if defined (ACE_HAS_TSS_EMULATION)
+
+# 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 */
+
+/*****************************************************************************/
+
+#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, ACE_THR_FUNC_RETURN *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 */
+
+#if !defined (ACE_LACKS_COND_T)
+// 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::condattr_destroy (ACE_condattr_t &attributes)
+{
+#if defined (ACE_HAS_THREADS)
+# 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_THREADS */
+}
+
+ACE_INLINE int
+ACE_OS::condattr_init (ACE_condattr_t &attributes,
+ int type)
+{
+ ACE_UNUSED_ARG (type);
+# if defined (ACE_HAS_THREADS)
+# 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 */
+
+# else
+ ACE_UNUSED_ARG (attributes);
+ ACE_UNUSED_ARG (type);
+ ACE_NOTSUP_RETURN (-1);
+# endif /* ACE_HAS_THREADS */
+}
+
+ACE_INLINE int
+ACE_OS::cond_broadcast (ACE_cond_t *cv)
+{
+ ACE_OS_TRACE ("ACE_OS::cond_broadcast");
+# if 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_THREADS */
+}
+
+ACE_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_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_THREADS */
+}
+
+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_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_THREADS */
+}
+
+#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_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_THREADS */
+}
+
+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_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_THREADS */
+}
+
+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_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_THREADS */
+}
+#endif /* !ACE_LACKS_COND_T */
+
+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_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 == 0)
+ 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 == 0)
+ 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_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 */
+}
+
+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_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_++;
+
+ ACE_Time_Value absolute_timeout = *timeout;
+
+ // cond_timewait() expects absolute time, check
+ // <use_absolute_time> flag.
+ if (use_absolute_time == 0)
+ absolute_timeout += ACE_OS::gettimeofday ();
+
+ if (ACE_OS::cond_timedwait (&event->condition_,
+ &event->lock_,
+ &absolute_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_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::mutex_destroy (ACE_mutex_t *m)
+{
+ ACE_OS_TRACE ("ACE_OS::mutex_destroy");
+#if 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_THREADS */
+}
+
+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_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_THREADS */
+}
+
+#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_lock (ACE_mutex_t *m)
+{
+ // ACE_OS_TRACE ("ACE_OS::mutex_lock");
+#if 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_THREADS */
+}
+
+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_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_trylock (ACE_mutex_t *m)
+{
+ ACE_OS_TRACE ("ACE_OS::mutex_trylock");
+#if 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_THREADS */
+}
+
+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_unlock (ACE_mutex_t *m)
+{
+ ACE_OS_TRACE ("ACE_OS::mutex_unlock");
+#if 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_THREADS */
+}
+
+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*/
+}
+
+// This method is used to prepare the recursive mutex for releasing
+// when waiting on a condition variable. If the platform doesn't have
+// native recursive mutex and condition variable support, then ACE needs
+// to save the recursion state around the wait and also ensure that the
+// wait and lock release are atomic. recursive_mutex_cond_relock()
+// is the inverse of this method.
+ACE_INLINE int
+ACE_OS::recursive_mutex_cond_unlock (ACE_recursive_thread_mutex_t *m,
+ ACE_recursive_mutex_state &state)
+{
+#if defined (ACE_HAS_THREADS)
+ ACE_OS_TRACE ("ACE_OS::recursive_mutex_cond_unlock");
+# if defined (ACE_HAS_RECURSIVE_MUTEXES)
+ // Windows need special handling since it has recursive mutexes, but
+ // does not integrate them into a condition variable.
+# if defined (ACE_WIN32)
+ // For Windows, the OS takes care of the mutex and its recursion. We just
+ // need to release the lock one fewer times than this thread has acquired
+ // it. Remember how many times, and reacquire it that many more times when
+ // the condition is signaled.
+ state.relock_count_ = 0;
+ while (m->LockCount > 0
+# if !defined (ACE_HAS_WINCE) /* WinCE doesn't have RecursionCount */
+ && m->RecursionCount > 1
+# endif
+ )
+ {
+ // This may fail if the current thread doesn't own the mutex. If it
+ // does fail, it'll be on the first try, so don't worry about resetting
+ // the state.
+ if (ACE_OS::recursive_mutex_unlock (m) == -1)
+ return -1;
+ ++state.relock_count_;
+ }
+# else /* not ACE_WIN32 */
+ // prevent warnings for unused variables
+ ACE_UNUSED_ARG (state);
+ ACE_UNUSED_ARG (m);
+# endif /* ACE_WIN32 */
+ return 0;
+# else /* ACE_HAS_RECURSIVE_MUTEXES */
+ // For platforms without recursive mutexes, we obtain the nesting mutex
+ // to gain control over the mutex internals. Then set the internals to say
+ // the mutex is available. If there are waiters, signal the condition
+ // to notify them (this is mostly like the recursive_mutex_unlock() method).
+ // Then, return with the nesting mutex still held. The condition wait
+ // will release it atomically, allowing mutex waiters to continue.
+ // Note that this arrangement relies on the fact that on return from
+ // the condition wait, this thread will again own the nesting mutex
+ // and can either set the mutex internals directly or get in line for
+ // the mutex... this part is handled in recursive_mutex_cond_relock().
+ if (ACE_OS::thread_mutex_lock (&m->nesting_mutex_) == -1)
+ return -1;
+
+# if !defined (ACE_NDEBUG)
+ if (m->nesting_level_ == 0
+ || ACE_OS::thr_equal (ACE_OS::thr_self (), m->owner_id_) == 0)
+ {
+ ACE_OS::thread_mutex_unlock (&m->nesting_mutex_);
+ errno = EINVAL;
+ return -1;
+ }
+# endif /* ACE_NDEBUG */
+
+ // To make error recovery a bit easier, signal the condition now. Any
+ // waiter won't regain control until the mutex is released, which won't
+ // be until the caller returns and does the wait on the condition.
+ if (ACE_OS::cond_signal (&m->lock_available_) == -1)
+ {
+ // Save/restore errno.
+ ACE_Errno_Guard error (errno);
+ ACE_OS::thread_mutex_unlock (&m->nesting_mutex_);
+ return -1;
+ }
+
+ // Ok, the nesting_mutex_ lock is still held, the condition has been
+ // signaled... reset the nesting info and return _WITH_ the lock
+ // held. The lock will be released when the condition waits, in the
+ // caller.
+ state.nesting_level_ = m->nesting_level_;
+ state.owner_id_ = m->owner_id_;
+ 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 (state);
+ ACE_NOTSUP_RETURN (-1);
+#endif /* ACE_HAS_THREADS */
+}
+
+
+// This method is called after waiting on a condition variable when a
+// recursive mutex must be reacquired. If the platform doesn't natively
+// integrate recursive mutexes and condition variables, it's taken care
+// of here (inverse of ACE_OS::recursive_mutex_cond_unlock).
+ACE_INLINE void
+ACE_OS::recursive_mutex_cond_relock (ACE_recursive_thread_mutex_t *m,
+ ACE_recursive_mutex_state &state)
+{
+#if defined (ACE_HAS_THREADS)
+ ACE_OS_TRACE ("ACE_OS::recursive_mutex_cond_relock");
+# if defined (ACE_HAS_RECURSIVE_MUTEXES)
+ // Windows need special handling since it has recursive mutexes, but
+ // does not integrate them into a condition variable.
+ // On entry, the OS has already reacquired the lock for us. Just
+ // reacquire it the proper number of times so the recursion is the same as
+ // before waiting on the condition.
+# if defined (ACE_WIN32)
+ while (state.relock_count_ > 0)
+ {
+ ACE_OS::recursive_mutex_lock (m);
+ --state.relock_count_;
+ }
+ return;
+# else /* not ACE_WIN32 */
+ // prevent warnings for unused variables
+ ACE_UNUSED_ARG (state);
+ ACE_UNUSED_ARG (m);
+
+# endif /* ACE_WIN32 */
+# else
+ // Without recursive mutex support, it's somewhat trickier. On entry,
+ // the current thread holds the nesting_mutex_, but another thread may
+ // still be holding the ACE_recursive_mutex_t. If so, mimic the code
+ // in ACE_OS::recursive_mutex_lock that waits to acquire the mutex.
+ // After acquiring it, restore the nesting counts and release the
+ // nesting mutex. This will restore the conditions to what they were
+ // before calling ACE_OS::recursive_mutex_cond_unlock().
+ while (m->nesting_level_ > 0)
+ ACE_OS::cond_wait (&m->lock_available_, &m->nesting_mutex_);
+
+ // At this point, we still have nesting_mutex_ and the mutex is free.
+ m->nesting_level_ = state.nesting_level_;
+ m->owner_id_ = state.owner_id_;
+ ACE_OS::thread_mutex_unlock (&m->nesting_mutex_);
+ return;
+# endif /* ACE_HAS_RECURSIVE_MUTEXES */
+#else
+ ACE_UNUSED_ARG (m);
+ ACE_UNUSED_ARG (state);
+ return;
+#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_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_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::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_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 */
+}
+
+// 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 */
+}
+
+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 */
+}
+
+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::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 */
+}
+
+#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::sema_destroy (ACE_sema_t *s)
+{
+ ACE_OS_TRACE ("ACE_OS::sema_destroy");
+# if 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_POSIX_SEM */
+}
+
+// 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_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_POSIX_SEM */
+}
+
+#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_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_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_POSIX_SEM */
+}
+
+ACE_INLINE int
+ACE_OS::sema_post (ACE_sema_t *s, u_int release_count)
+{
+#if defined (ACE_WIN32) && !defined (ACE_USES_WINCE_SEMA_SIMULATION)
+ // Win32 supports this natively.
+ ACE_WIN32CALL_RETURN (ACE_ADAPT_RETVAL (::ReleaseSemaphore (*s, release_count, 0),
+ ace_result_), int, -1);
+#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_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_POSIX_SEM */
+}
+
+ACE_INLINE int
+ACE_OS::sema_wait (ACE_sema_t *s)
+{
+ ACE_OS_TRACE ("ACE_OS::sema_wait");
+# if 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_POSIX_SEM */
+}
+
+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::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 int
+ACE_OS::sigtimedwait (const sigset_t *sset,
+ siginfo_t *info,
+ const ACE_Time_Value *timeout)
+{
+ ACE_OS_TRACE ("ACE_OS::sigtimedwait");
+#if 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 (sset, info, tsp),
+ int, -1);
+#else
+ ACE_UNUSED_ARG (sset);
+ ACE_UNUSED_ARG (info);
+ ACE_UNUSED_ARG (timeout);
+ ACE_NOTSUP_RETURN (-1);
+#endif /* ACE_HAS_SIGTIMEDWAIT */
+}
+
+ACE_INLINE int
+ACE_OS::sigwait (sigset_t *sset, int *sig)
+{
+ ACE_OS_TRACE ("ACE_OS::sigwait");
+ int local_sig;
+ if (sig == 0)
+ sig = &local_sig;
+#if defined (ACE_HAS_THREADS)
+# if (defined (__FreeBSD__) && (__FreeBSD__ < 3)) || defined (CHORUS) || defined (ACE_PSOS)
+ ACE_UNUSED_ARG (sset);
+ ACE_NOTSUP_RETURN (-1);
+# elif (defined (ACE_HAS_STHREADS) && !defined (_POSIX_PTHREAD_SEMANTICS))
+ *sig = ::sigwait (sset);
+ 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 (sset, 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 (sset, 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 (sset);
+# else
+ *sig = ::sigwait (sset);
+# endif /* HPUX_10 */
+ return *sig;
+# elif defined(ACE_HAS_FSU_PTHREADS)
+ return ::sigwait (sset, sig);
+# elif defined(CYGWIN32)
+ // Cygwin has sigwait definition, but it is not implemented
+ ACE_UNUSED_ARG (sset);
+ ACE_NOTSUP_RETURN (-1);
+# else /* this is draft 7 or std */
+ errno = ::sigwait (sset, 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 (sset);
+ 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 (sset, 0, 0);
+ return *sig;
+# endif /* __FreeBSD__ */
+#else
+ ACE_UNUSED_ARG (sset);
+ ACE_UNUSED_ARG (sig);
+ ACE_NOTSUP_RETURN (-1);
+#endif /* ACE_HAS_THREADS */
+}
+
+ACE_INLINE int
+ACE_OS::sigwaitinfo (const sigset_t *sset,
+ siginfo_t *info)
+{
+ ACE_OS_TRACE ("ACE_OS::sigwaitinfo");
+ // If this platform has sigtimedwait, it should have sigwaitinfo as well.
+ // If this isn't true somewhere, let me know and I'll fix this.
+ // -Steve Huston <shuston@riverace.com>.
+#if defined (ACE_HAS_SIGTIMEDWAIT)
+ ACE_OSCALL_RETURN (::sigwaitinfo (sset, info), int, -1);
+#else
+ ACE_UNUSED_ARG (sset);
+ ACE_UNUSED_ARG (info);
+ ACE_NOTSUP_RETURN (-1);
+#endif /* ACE_HAS_SIGTIMEDWAIT */
+}
+
+ACE_INLINE int
+ACE_OS::thr_cancel (ACE_thread_t thr_id)
+{
+ ACE_OS_TRACE ("ACE_OS::thr_cancel");
+#if 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_THREADS */
+}
+
+ACE_INLINE int
+ACE_OS::thr_cmp (ACE_hthread_t t1, ACE_hthread_t t2)
+{
+#if 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_PTHREADS */
+}
+
+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_PTHREAD_CONTINUE)
+ 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_PTHREAD_CONTINUE */
+# 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)
+ ACE_OSCALL_RETURN (::taskResume (target_thread), int, -1);
+# endif /* ACE_HAS_STHREADS */
+#else
+ ACE_UNUSED_ARG (target_thread);
+ ACE_NOTSUP_RETURN (-1);
+#endif /* ACE_HAS_THREADS */
+}
+
+ACE_INLINE int
+ACE_OS::thr_equal (ACE_thread_t t1, ACE_thread_t t2)
+{
+#if 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_PTHREADS */
+}
+
+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 id, int &priority, int &policy)
+{
+ ACE_OS_TRACE ("ACE_OS::thr_getprio");
+ ACE_UNUSED_ARG (policy);
+#if defined (ACE_HAS_THREADS)
+# if (defined (ACE_HAS_PTHREADS) && !defined (ACE_LACKS_SETSCHED))
+
+# if defined (ACE_HAS_PTHREADS_DRAFT4)
+ int result;
+ result = ::pthread_getprio (id);
+ if (result != -1)
+ {
+ priority = result;
+ return 0;
+ }
+ else
+ return -1;
+# elif defined (ACE_HAS_PTHREADS_DRAFT6)
+
+ pthread_attr_t attr;
+ if (pthread_getschedattr (id, &attr) == 0)
+ {
+ priority = pthread_attr_getprio(&attr);
+ return 0;
+ }
+ return -1;
+# else
+
+ struct sched_param param;
+ int result;
+
+ ACE_OSCALL (ACE_ADAPT_RETVAL (::pthread_getschedparam (id, &policy, &param),
+ result), int,
+ -1, result);
+ priority = param.sched_priority;
+ return result;
+# endif /* ACE_HAS_PTHREADS_DRAFT4 */
+# elif defined (ACE_HAS_STHREADS)
+ ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::thr_getprio (id, &priority), ace_result_), int, -1);
+# elif defined (ACE_HAS_WTHREADS)
+ priority = ::GetThreadPriority (id);
+ if (priority == 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 (id, 0, (u_long *) &priority), ace_result_), int, -1);
+# elif defined (VXWORKS)
+ ACE_OSCALL_RETURN (::taskPriorityGet (id, &priority), int, -1);
+# else
+ ACE_UNUSED_ARG (id);
+ ACE_UNUSED_ARG (priority);
+ ACE_NOTSUP_RETURN (-1);
+# endif /* ACE_HAS_STHREADS */
+#else
+ ACE_UNUSED_ARG (id);
+ ACE_UNUSED_ARG (priority);
+ ACE_NOTSUP_RETURN (-1);
+#endif /* ACE_HAS_THREADS */
+}
+
+ACE_INLINE int
+ACE_OS::thr_getprio (ACE_hthread_t id, int &priority)
+{
+ ACE_OS_TRACE ("ACE_OS::thr_getprio");
+ int policy = 0;
+ return ACE_OS::thr_getprio (id, priority, policy);
+}
+
+#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 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 (*data == 0 && (error = ::GetLastError ()) != NO_ERROR)
+ return -1;
+ else
+ 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_THREAD_SPECIFIC_STORAGE */
+
+#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 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 (*data == 0 && (error = ::GetLastError ()) != NO_ERROR)
+ return -1;
+ else
+ 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_THREADS */
+}
+
+#if !defined (VXWORKS)
+ACE_INLINE int
+ACE_OS::thr_join (ACE_hthread_t thr_handle,
+ ACE_THR_FUNC_RETURN *status)
+{
+ ACE_OS_TRACE ("ACE_OS::thr_join");
+#if 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)
+ ACE_THR_FUNC_RETURN 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, status) != FALSE)
+ {
+ ::CloseHandle (thr_handle);
+ return 0;
+ }
+ ACE_FAIL_RETURN (-1);
+ /* NOTREACHED */
+# elif 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_THREADS */
+}
+
+ACE_INLINE int
+ACE_OS::thr_join (ACE_thread_t waiter_id,
+ ACE_thread_t *thr_id,
+ ACE_THR_FUNC_RETURN *status)
+{
+ ACE_OS_TRACE ("ACE_OS::thr_join");
+#if 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 (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_THREADS */
+}
+#endif /* !VXWORKS */
+
+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_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_THREADS */
+}
+
+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);
+
+ ACE_OSCALL (ACE_ADAPT_RETVAL (::taskInfoGet (tid, &taskDesc),
+ status),
+ STATUS, -1, status);
+ 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 ACE_thread_t
+ACE_OS::thr_self (void)
+{
+ // ACE_OS_TRACE ("ACE_OS::thr_self");
+#if 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_THREADS */
+}
+
+ACE_INLINE void
+ACE_OS::thr_self (ACE_hthread_t &self)
+{
+ ACE_OS_TRACE ("ACE_OS::thr_self");
+#if 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_THREADS */
+}
+
+ACE_INLINE int
+ACE_OS::thr_setcancelstate (int new_state, int *old_state)
+{
+ ACE_OS_TRACE ("ACE_OS::thr_setcancelstate");
+#if 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_THREADS */
+}
+
+ACE_INLINE int
+ACE_OS::thr_setcanceltype (int new_type, int *old_type)
+{
+ ACE_OS_TRACE ("ACE_OS::thr_setcanceltype");
+#if 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_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 id, int priority, int policy)
+{
+ ACE_OS_TRACE ("ACE_OS::thr_setprio");
+ ACE_UNUSED_ARG (policy);
+#if defined (ACE_HAS_THREADS)
+# if (defined (ACE_HAS_PTHREADS) && !defined (ACE_LACKS_SETSCHED))
+
+# if defined (ACE_HAS_PTHREADS_DRAFT4)
+ int result;
+ result = ::pthread_setprio (id, priority);
+ return (result == -1 ? -1 : 0);
+# elif defined (ACE_HAS_PTHREADS_DRAFT6)
+ pthread_attr_t attr;
+ if (pthread_getschedattr (id, &attr) == -1)
+ return -1;
+ if (pthread_attr_setprio (attr, priority) == -1)
+ return -1;
+ return pthread_setschedattr (id, attr);
+# else
+ int result;
+ struct sched_param param;
+ memset ((void *) &param, 0, sizeof param);
+
+ // If <policy> is -1, we don't want to use it for
+ // pthread_setschedparam(). Instead, obtain policy from
+ // pthread_getschedparam().
+ if (policy == -1)
+ {
+ ACE_OSCALL (ACE_ADAPT_RETVAL (::pthread_getschedparam (id, &policy, &param),
+ result),
+ int, -1, result);
+ if (result == -1)
+ return result;
+ }
+
+ param.sched_priority = priority;
+
+ ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::pthread_setschedparam (id, policy, &param),
+ ace_result_),
+ int, -1);
+# endif /* ACE_HAS_PTHREADS_DRAFT4 */
+# elif defined (ACE_HAS_STHREADS)
+ ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::thr_setprio (id, priority),
+ ace_result_),
+ int, -1);
+# elif defined (ACE_HAS_WTHREADS)
+ ACE_WIN32CALL_RETURN (ACE_ADAPT_RETVAL (::SetThreadPriority (id, priority),
+ ace_result_),
+ int, -1);
+# elif defined (ACE_PSOS)
+ u_long oldpriority;
+ ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::t_setpri (id, priority, &oldpriority),
+ ace_result_),
+ int, -1);
+# elif defined (VXWORKS)
+ ACE_OSCALL_RETURN (::taskPrioritySet (id, priority), int, -1);
+# else
+ // For example, platforms that support Pthreads but LACK_SETSCHED.
+ ACE_UNUSED_ARG (id);
+ ACE_UNUSED_ARG (priority);
+ ACE_NOTSUP_RETURN (-1);
+# endif /* ACE_HAS_STHREADS */
+#else
+ ACE_UNUSED_ARG (id);
+ ACE_UNUSED_ARG (priority);
+ ACE_NOTSUP_RETURN (-1);
+#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_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_THREADS */
+}
+
+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_PTHREAD_SUSPEND)
+ 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_PTHREAD_SUSPEND */
+# 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)
+ ACE_OSCALL_RETURN (::taskSuspend (target_thread), int, -1);
+# endif /* ACE_HAS_STHREADS */
+#else
+ ACE_UNUSED_ARG (target_thread);
+ ACE_NOTSUP_RETURN (-1);
+#endif /* ACE_HAS_THREADS */
+}
+
+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 void
+ACE_OS::thr_yield (void)
+{
+ ACE_OS_TRACE ("ACE_OS::thr_yield");
+#if 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 (0);
+# 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_THREADS */
+}
+
+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)
+ 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_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)
+ 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)
+ 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_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)
+ return ACE_OS::mutex_lock (m);
+# elif defined (VXWORKS) || defined (ACE_PSOS)
+ return mutex_lock (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,
+ 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)
+ 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 */
+#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)
+ 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)
+ 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 defined (ACE_IS_SPLITTING)
+# define ACE_SPECIAL_INLINE
+# else
+# define ACE_SPECIAL_INLINE ACE_INLINE
+//# 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 ();
+}
+
+/*****************************************************************************/
+
+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 ();
+}
diff --git a/ace/OS_NS_arpa_inet.cpp b/ace/OS_NS_arpa_inet.cpp
index fc532b41367..b4040a0032c 100644
--- a/ace/OS_NS_arpa_inet.cpp
+++ b/ace/OS_NS_arpa_inet.cpp
@@ -1,4 +1,60 @@
// -*- C++ -*-
// $Id$
-// This is a placeholder.
+#include "ace/OS_NS_arpa_inet.h"
+
+ACE_RCSID(ace, OS_NS_arpa_inet, "$Id$")
+
+#if !defined (ACE_HAS_INLINED_OSCALLS)
+# include "ace/OS_NS_arpa_inet.inl"
+#endif /* ACE_HAS_INLINED_OS_CALLS */
+
+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;
+ }
+#elif defined (VXWORKS)
+ // inet_aton() returns OK (0) on success and ERROR (-1) on failure.
+ // Must reset errno first. Refer to WindRiver SPR# 34949, SPR# 36026
+ ::errnoSet(0);
+ int result = ERROR;
+ ACE_OSCALL (::inet_aton ((char*)host_name, addr), int, ERROR, result);
+ return (result == ERROR) ? 0 : 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 */
+}
+
+// All other platforms have this inlined in OS_NS_arpa_inet.inl
+#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) */
diff --git a/ace/OS_NS_arpa_inet.h b/ace/OS_NS_arpa_inet.h
index fc532b41367..f1bf66bd73d 100644
--- a/ace/OS_NS_arpa_inet.h
+++ b/ace/OS_NS_arpa_inet.h
@@ -1,4 +1,59 @@
// -*- C++ -*-
-// $Id$
-// This is a placeholder.
+//=============================================================================
+/**
+ * @file OS_NS_arpa_inet.h
+ *
+ * $Id$
+ *
+ * @author Douglas C. Schmidt <schmidt@cs.wustl.edu>
+ * @author Jesper S. M|ller<stophph@diku.dk>
+ * @author and a cast of thousands...
+ *
+ * Originally in OS.h.
+ */
+//=============================================================================
+
+#ifndef ACE_OS_NS_ARPA_INET_H
+# define ACE_OS_NS_ARPA_INET_H
+
+# include /**/ "ace/pre.h"
+
+# include "ace/config-all.h"
+
+# if !defined (ACE_LACKS_PRAGMA_ONCE)
+# pragma once
+# endif /* ACE_LACKS_PRAGMA_ONCE */
+
+#include "ace/os_include/arpa/os_inet.h"
+
+namespace ACE_OS {
+
+ unsigned long inet_addr (const char *name);
+
+ int inet_aton (const char *strptr,
+ struct in_addr *addr);
+
+ char *inet_ntoa (const struct in_addr addr);
+
+ const char *inet_ntop (int family,
+ const void *addrptr,
+ char *strptr,
+ size_t len);
+
+ int inet_pton (int family,
+ const char *strptr,
+ void *addrptr);
+
+}; /* namespace ACE_OS */
+
+# if defined (ACE_HAS_INLINED_OSCALLS)
+# if defined (ACE_INLINE)
+# undef ACE_INLINE
+# endif /* ACE_INLINE */
+# define ACE_INLINE inline
+# include "ace/OS_NS_arpa_inet.inl"
+# endif /* ACE_HAS_INLINED_OSCALLS */
+
+# include /**/ "ace/post.h"
+#endif /* ACE_OS_NS_ARPA_INET_H */
diff --git a/ace/OS_NS_arpa_inet.inl b/ace/OS_NS_arpa_inet.inl
index fc532b41367..ea427c7c1e7 100644
--- a/ace/OS_NS_arpa_inet.inl
+++ b/ace/OS_NS_arpa_inet.inl
@@ -1,4 +1,123 @@
// -*- C++ -*-
// $Id$
-// This is a placeholder.
+#include "ace/OS_NS_string.h"
+#include "ace/OS_NS_errno.h"
+#include "ace/OS_NS_stdio.h"
+
+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 */
+}
diff --git a/ace/OS_NS_ctype.cpp b/ace/OS_NS_ctype.cpp
index fc532b41367..6672e6e7460 100644
--- a/ace/OS_NS_ctype.cpp
+++ b/ace/OS_NS_ctype.cpp
@@ -1,4 +1,11 @@
// -*- C++ -*-
// $Id$
-// This is a placeholder.
+#include "ace/OS_NS_ctype.h"
+
+ACE_RCSID(ace, OS_NS_ctype, "$Id$")
+
+#if !defined (ACE_HAS_INLINED_OSCALLS)
+# include "ace/OS_NS_ctype.inl"
+#endif /* ACE_HAS_INLINED_OS_CALLS */
+
diff --git a/ace/OS_NS_ctype.h b/ace/OS_NS_ctype.h
index fc532b41367..b3e97796c1d 100644
--- a/ace/OS_NS_ctype.h
+++ b/ace/OS_NS_ctype.h
@@ -1,4 +1,75 @@
// -*- C++ -*-
-// $Id$
-// This is a placeholder.
+//=============================================================================
+/**
+ * @file OS_NS_ctype.h
+ *
+ * $Id$
+ *
+ * @author Douglas C. Schmidt <schmidt@cs.wustl.edu>
+ * @author Jesper S. M|ller<stophph@diku.dk>
+ * @author and a cast of thousands...
+ *
+ * Originally in OS.h.
+ */
+//=============================================================================
+
+#ifndef ACE_OS_NS_CTYPE_H
+# define ACE_OS_NS_CTYPE_H
+
+# include /**/ "ace/pre.h"
+
+# include "ace/config-all.h"
+
+# if !defined (ACE_LACKS_PRAGMA_ONCE)
+# pragma once
+# endif /* ACE_LACKS_PRAGMA_ONCE */
+
+#include "ace/os_include/os_ctype.h"
+
+namespace ACE_OS {
+
+ // these are non-standard names...
+
+ /** @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.
+ int ace_isprint (const ACE_TCHAR c);
+
+ /// Returns true if the character is a space character.
+ int ace_isspace (const ACE_TCHAR c);
+
+ /// Converts a character to lower case (char version).
+ int to_lower (int c);
+
+#if defined (ACE_HAS_WCHAR) && !defined (ACE_LACKS_TOWLOWER)
+ /// Converts a character to lower case (wchar_t version).
+ wint_t to_lower (wint_t c);
+#endif /* ACE_HAS_WCHAR && !ACE_LACKS_TOWLOWER */
+
+ //@}
+
+} /* namespace ACE_OS */
+
+# if defined (ACE_HAS_INLINED_OSCALLS)
+# if defined (ACE_INLINE)
+# undef ACE_INLINE
+# endif /* ACE_INLINE */
+# define ACE_INLINE inline
+# include "ace/OS_NS_ctype.inl"
+# endif /* ACE_HAS_INLINED_OSCALLS */
+
+# include /**/ "ace/post.h"
+#endif /* ACE_OS_NS_CTYPE_H */
diff --git a/ace/OS_NS_ctype.inl b/ace/OS_NS_ctype.inl
index fc532b41367..174c33ef4df 100644
--- a/ace/OS_NS_ctype.inl
+++ b/ace/OS_NS_ctype.inl
@@ -1,4 +1,37 @@
// -*- C++ -*-
// $Id$
-// This is a placeholder.
+ACE_INLINE int
+ACE_OS::ace_isprint (const ACE_TCHAR c)
+{
+#if defined (ACE_USES_WCHAR)
+ return iswprint (c);
+#else /* ACE_USES_WCHAR */
+ return isprint ((unsigned char) c);
+#endif /* ACE_USES_WCHAR */
+}
+
+ACE_INLINE int
+ACE_OS::ace_isspace (const ACE_TCHAR c)
+{
+#if defined (ACE_USES_WCHAR)
+ return iswspace (c);
+#else /* ACE_USES_WCHAR */
+ return isspace ((unsigned char) c);
+#endif /* ACE_USES_WCHAR */
+}
+
+ACE_INLINE int
+ACE_OS::to_lower (int c)
+{
+ return tolower (c);
+}
+
+#if defined (ACE_HAS_WCHAR) && !defined (ACE_LACKS_TOWLOWER)
+ACE_INLINE wint_t
+ACE_OS::to_lower (wint_t c)
+{
+ return towlower (c);
+}
+#endif /* ACE_HAS_WCHAR && !ACE_LACKS_TOWLOWER */
+
diff --git a/ace/OS_NS_dirent.cpp b/ace/OS_NS_dirent.cpp
index fc532b41367..bbf9c0fb2df 100644
--- a/ace/OS_NS_dirent.cpp
+++ b/ace/OS_NS_dirent.cpp
@@ -1,4 +1,279 @@
// -*- C++ -*-
// $Id$
-// This is a placeholder.
+#include "ace/OS_NS_dirent.h"
+
+ACE_RCSID(ace, OS_NS_dirent, "$Id$")
+
+#if !defined (ACE_HAS_INLINED_OSCALLS)
+# include "ace/OS_NS_dirent.inl"
+#endif /* ACE_HAS_INLINED_OS_CALLS */
+
+#include "ace/OS_NS_errno.h"
+#include "ace/OS_NS_string.h"
+#include "ace/Log_Msg.h"
+#include "ace/OS_NS_stdlib.h"
+
+extern "C"
+{
+ typedef int (*ACE_SCANDIR_COMPARATOR) (const void *, const void *);
+}
+
+/*
+ These definitions are missing on the original VC6 distribution. The new
+ headers that define these are available in the Platform SDK and are defined
+ for those that don't have it.
+ */
+#if defined (ACE_WIN32)
+# if !defined (INVALID_FILE_ATTRIBUTES)
+# define INVALID_FILE_ATTRIBUTES ((DWORD)-1)
+# endif /* INVALID_FILE_ATTRIBUTES */
+# if !defined (INVALID_SET_FILE_POINTER)
+# define INVALID_SET_FILE_POINTER ((DWORD)-1)
+# endif /* INVALID_SET_FILE_POINTER */
+#endif /* ACE_WIN32 */
+
+void
+ACE_OS::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;
+ if (d->dirent_ != 0)
+ {
+ ACE_OS::free (d->dirent_->d_name);
+ ACE_OS::free (d->dirent_);
+ }
+#else /* ACE_WIN32 */
+ ACE_UNUSED_ARG (d);
+#endif /* ACE_WIN32 */
+}
+
+ACE_DIR *
+ACE_OS::opendir_emulation (const ACE_TCHAR *filename)
+{
+#if defined (ACE_WIN32)
+ ACE_DIR *dir;
+ ACE_TCHAR extra[3] = {0,0,0};
+
+ // Check if filename is a directory.
+ DWORD fileAttribute = ACE_TEXT_GetFileAttributes (filename);
+ if (fileAttribute == INVALID_FILE_ATTRIBUTES
+ || !(fileAttribute & FILE_ATTRIBUTE_DIRECTORY))
+ return 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::strlen (filename);
+ if (lastchar > 0)
+ {
+ if (filename[lastchar-1] != '*')
+ {
+ if (filename[lastchar-1] != '/' && filename[lastchar-1] != '\\')
+ ACE_OS::strcpy (extra, ACE_LIB_TEXT ("/*"));
+ else
+ ACE_OS::strcpy (extra, ACE_LIB_TEXT ("*"));
+ }
+ }
+
+ ACE_NEW_RETURN (dir, ACE_DIR, 0);
+ ACE_NEW_RETURN (dir->directory_name_,
+ ACE_TCHAR[lastchar + ACE_OS::strlen (extra) + 1],
+ 0);
+ ACE_OS::strcpy (dir->directory_name_, filename);
+ if (extra[0])
+ ACE_OS::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 */
+}
+
+dirent *
+ACE_OS::readdir_emulation (ACE_DIR *d)
+{
+#if defined (ACE_WIN32)
+ if (d->dirent_ != 0)
+ {
+ ACE_OS::free (d->dirent_->d_name);
+ ACE_OS::free (d->dirent_);
+ d->dirent_ = 0;
+ }
+
+ if (!d->started_reading_)
+ {
+ d->current_handle_ = ACE_TEXT_FindFirstFile (d->directory_name_,
+ &d->fdata_);
+ 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::malloc (sizeof (dirent));
+
+ if (d->dirent_ != 0)
+ {
+ d->dirent_->d_name = (ACE_TCHAR*)
+ ACE_OS::malloc ((ACE_OS::strlen (d->fdata_.cFileName) + 1)
+ * sizeof (ACE_TCHAR));
+ ACE_OS::strcpy (d->dirent_->d_name, d->fdata_.cFileName);
+ d->dirent_->d_reclen = sizeof (dirent);
+ }
+
+ return d->dirent_;
+ }
+ else
+ return 0;
+#else /* ACE_WIN32 */
+ ACE_UNUSED_ARG (d);
+ ACE_NOTSUP_RETURN (0);
+#endif /* ACE_WIN32 */
+}
+
+int
+ACE_OS::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::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::readdir (dirp);
+ dp != 0;
+ dp = ACE_OS::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::realloc (vector,
+ arena_size * sizeof (dirent *));
+ if (newv == 0)
+ {
+ fail = 1;
+ break;
+ }
+ vector = newv;
+ }
+
+#if defined (ACE_LACKS_STRUCT_DIR)
+ dirent *newdp = (dirent *) ACE_OS::malloc (sizeof (dirent));
+#else
+ int dsize =
+ sizeof (dirent) +
+ ((ACE_OS::strlen (dp->d_name) + 1) * sizeof (ACE_TCHAR));
+ dirent *newdp = (dirent *) ACE_OS::malloc (dsize);
+#endif /* ACE_LACKS_STRUCT_DIR */
+
+ if (newdp == 0)
+ {
+ fail = 1;
+ break;
+ }
+
+#if defined (ACE_LACKS_STRUCT_DIR)
+ newdp->d_name = (ACE_TCHAR*) ACE_OS::malloc (
+ (ACE_OS::strlen (dp->d_name) + 1) * sizeof (ACE_TCHAR));
+
+ if (newdp->d_name == 0)
+ {
+ fail = 1;
+ ACE_OS::free (newdp);
+ break;
+ }
+
+ // Don't use memcpy here since d_name is now a pointer
+ newdp->d_ino = dp->d_ino;
+ newdp->d_off = dp->d_off;
+ newdp->d_reclen = dp->d_reclen;
+ ACE_OS::strcpy (newdp->d_name, dp->d_name);
+ vector[nfiles++] = newdp;
+#else
+ vector[nfiles++] = (dirent *) ACE_OS::memcpy (newdp, dp, dsize);
+#endif /* ACE_LACKS_STRUCT_DIR */
+ }
+
+ if (fail)
+ {
+ ACE_OS::closedir (dirp);
+ while (nfiles-- > 0)
+ {
+#if defined (ACE_LACKS_STRUCT_DIR)
+ ACE_OS::free (vector[nfiles]->d_name);
+#endif /* ACE_LACKS_STRUCT_DIR */
+ ACE_OS::free (vector[nfiles]);
+ }
+ ACE_OS::free (vector);
+ return -1;
+ }
+
+ ACE_OS::closedir (dirp);
+
+ *namelist = vector;
+
+ if (comparator)
+ ACE_OS::qsort (*namelist,
+ nfiles,
+ sizeof (dirent *),
+ (ACE_SCANDIR_COMPARATOR) comparator);
+
+ return nfiles;
+}
diff --git a/ace/OS_NS_dirent.h b/ace/OS_NS_dirent.h
index fc532b41367..2e355ac236c 100644
--- a/ace/OS_NS_dirent.h
+++ b/ace/OS_NS_dirent.h
@@ -1,4 +1,79 @@
// -*- C++ -*-
-// $Id$
-// This is a placeholder.
+//=============================================================================
+/**
+ * @file OS_NS_dirent.h
+ *
+ * $Id$
+ *
+ * @author Douglas C. Schmidt <schmidt@cs.wustl.edu>
+ * @author Jesper S. M|ller<stophph@diku.dk>
+ * @author and a cast of thousands...
+ *
+ * Originally in OS.h.
+ */
+//=============================================================================
+
+#ifndef ACE_OS_NS_DIRENT_H
+# define ACE_OS_NS_DIRENT_H
+
+# include /**/ "ace/pre.h"
+
+# include "ace/config-all.h"
+
+# if !defined (ACE_LACKS_PRAGMA_ONCE)
+# pragma once
+# endif /* ACE_LACKS_PRAGMA_ONCE */
+
+#include "ace/os_include/os_dirent.h"
+
+namespace ACE_OS {
+
+ void closedir (ACE_DIR *);
+
+ ACE_DIR *opendir (const ACE_TCHAR *filename);
+
+ dirent *readdir (ACE_DIR *);
+
+ int readdir_r (ACE_DIR *dirp,
+ struct dirent *entry,
+ struct dirent **result);
+
+ void rewinddir (ACE_DIR *);
+
+ int scandir (const ACE_TCHAR *dirname,
+ struct dirent **namelist[],
+ int (*selector) (const struct dirent *filename),
+ int (*comparator) (const struct dirent **f1,
+ const struct dirent **f2));
+
+ void seekdir (ACE_DIR *,
+ long loc);
+
+ long telldir (ACE_DIR *);
+
+ // Win32 emulation functions
+ ACE_DIR *opendir_emulation (const ACE_TCHAR *filename);
+
+ int scandir_emulation (const ACE_TCHAR *dirname,
+ dirent **namelist[],
+ int (*selector)(const dirent *entry),
+ int (*comparator)(const dirent **f1,
+ const dirent**f2));
+
+ void closedir_emulation (ACE_DIR *);
+
+ dirent *readdir_emulation (ACE_DIR *);
+
+} /* namespace ACE_OS */
+
+# if defined (ACE_HAS_INLINED_OSCALLS)
+# if defined (ACE_INLINE)
+# undef ACE_INLINE
+# endif /* ACE_INLINE */
+# define ACE_INLINE inline
+# include "ace/OS_NS_dirent.inl"
+# endif /* ACE_HAS_INLINED_OSCALLS */
+
+# include /**/ "ace/post.h"
+#endif /* ACE_OS_NS_DIRENT_H */
diff --git a/ace/OS_NS_dirent.inl b/ace/OS_NS_dirent.inl
index fc532b41367..520b23f5105 100644
--- a/ace/OS_NS_dirent.inl
+++ b/ace/OS_NS_dirent.inl
@@ -1,4 +1,191 @@
// -*- C++ -*-
// $Id$
-// This is a placeholder.
+ACE_INLINE void
+ACE_OS::closedir (ACE_DIR *d)
+{
+#if 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::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_DIRENT */
+}
+
+ACE_INLINE ACE_DIR *
+ACE_OS::opendir (const ACE_TCHAR *filename)
+{
+#if defined (ACE_HAS_DIRENT)
+# if defined (ACE_PSOS)
+ // The pointer to the <ACE_DIR> buffer *must* be passed to
+ // <ACE_OS::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::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_DIRENT */
+}
+
+ACE_INLINE struct dirent *
+ACE_OS::readdir (ACE_DIR *d)
+{
+#if 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::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_DIRENT */
+}
+
+ACE_INLINE int
+ACE_OS::readdir_r (ACE_DIR *dirp,
+ struct dirent *entry,
+ struct dirent **result)
+{
+#if !defined (ACE_HAS_REENTRANT_FUNCTIONS)
+ ACE_UNUSED_ARG (entry);
+ // <result> has better not be 0!
+ *result = ACE_OS::readdir (dirp);
+ if (*result)
+ return 0; // Keep iterating
+ else
+ return 1; // Oops, some type of error!
+#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 (__FreeBSD__) || \
+ 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_REENTRANT_FUNCTIONS */
+}
+
+ACE_INLINE void
+ACE_OS::rewinddir (ACE_DIR *d)
+{
+#if 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::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::scandir_emulation (dirname, namelist, selector, comparator);
+#endif /* ACE_HAS_SCANDIR */
+}
+ACE_INLINE void
+ACE_OS::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 long
+ACE_OS::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 */
+}
diff --git a/ace/OS_NS_dlfcn.cpp b/ace/OS_NS_dlfcn.cpp
index fc532b41367..d0707dde1c2 100644
--- a/ace/OS_NS_dlfcn.cpp
+++ b/ace/OS_NS_dlfcn.cpp
@@ -1,4 +1,11 @@
// -*- C++ -*-
// $Id$
-// This is a placeholder.
+#include "ace/OS_NS_dlfcn.h"
+
+ACE_RCSID(ace, OS_NS_dlfcn, "$Id$")
+
+#if !defined (ACE_HAS_INLINED_OSCALLS)
+# include "ace/OS_NS_dlfcn.inl"
+#endif /* ACE_HAS_INLINED_OS_CALLS */
+
diff --git a/ace/OS_NS_dlfcn.h b/ace/OS_NS_dlfcn.h
index fc532b41367..5698b227623 100644
--- a/ace/OS_NS_dlfcn.h
+++ b/ace/OS_NS_dlfcn.h
@@ -1,4 +1,55 @@
// -*- C++ -*-
-// $Id$
-// This is a placeholder.
+//=============================================================================
+/**
+ * @file OS_NS_dlfcn.h
+ *
+ * $Id$
+ *
+ * @author Douglas C. Schmidt <schmidt@cs.wustl.edu>
+ * @author Jesper S. M|ller<stophph@diku.dk>
+ * @author and a cast of thousands...
+ *
+ * Originally in OS.h.
+ */
+//=============================================================================
+
+#ifndef ACE_OS_NS_DLFCN_H
+# define ACE_OS_NS_DLFCN_H
+
+# include /**/ "ace/pre.h"
+
+# include "ace/config-all.h"
+
+# if !defined (ACE_LACKS_PRAGMA_ONCE)
+# pragma once
+# endif /* ACE_LACKS_PRAGMA_ONCE */
+
+#include "ace/os_include/os_dlfcn.h"
+
+namespace ACE_OS {
+
+ //@{ @name A set of wrappers for explicit dynamic linking.
+ int dlclose (ACE_SHLIB_HANDLE handle);
+
+ ACE_TCHAR *dlerror (void);
+
+ ACE_SHLIB_HANDLE dlopen (const ACE_TCHAR *filename,
+ int mode = ACE_DEFAULT_SHLIB_MODE);
+
+ void *dlsym (ACE_SHLIB_HANDLE handle,
+ const ACE_TCHAR *symbol);
+ //@}
+
+} /* namespace ACE_OS */
+
+# if defined (ACE_HAS_INLINED_OSCALLS)
+# if defined (ACE_INLINE)
+# undef ACE_INLINE
+# endif /* ACE_INLINE */
+# define ACE_INLINE inline
+# include "ace/OS_NS_dlfcn.inl"
+# endif /* ACE_HAS_INLINED_OSCALLS */
+
+# include /**/ "ace/post.h"
+#endif /* ACE_OS_NS_DLFCN_H */
diff --git a/ace/OS_NS_dlfcn.inl b/ace/OS_NS_dlfcn.inl
index fc532b41367..5257a61a411 100644
--- a/ace/OS_NS_dlfcn.inl
+++ b/ace/OS_NS_dlfcn.inl
@@ -1,4 +1,249 @@
// -*- C++ -*-
// $Id$
-// This is a placeholder.
+ACE_INLINE int
+ACE_OS::dlclose (ACE_SHLIB_HANDLE handle)
+{
+ ACE_OS_TRACE ("ACE_OS::dlclose");
+#if defined (ACE_LACKS_DLCLOSE)
+ ACE_UNUSED_ARG (handle);
+ return 0;
+#elif 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) || defined (VXWORKS)
+ 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,
+ 0,
+ ::GetLastError (),
+ 0,
+ buf,
+ sizeof buf / sizeof buf[0],
+ 0);
+# endif /* ACE_HAS_PHARLAP */
+ return buf;
+# else
+ ACE_NOTSUP_RETURN (0);
+# endif /* ACE_HAS_SVR4_DYNAMIC_LINKING */
+}
+
+# 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 */
+
+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++ */
+# elif defined (VXWORKS)
+ MODULE* handle;
+ // Open readonly
+ ACE_HANDLE filehandle = ACE_OS::open (filename,
+ O_RDONLY,
+ ACE_DEFAULT_FILE_PERMS);
+
+ if (filehandle != ACE_INVALID_HANDLE)
+ {
+ ACE_OS::last_error(0);
+ ACE_OSCALL ( ::loadModule (filehandle, mode ), MODULE *, 0, handle);
+ int loaderror = ACE_OS::last_error();
+ ACE_OS::close (filehandle);
+
+ if ( (loaderror != 0) && (handle != 0) )
+ {
+ // ouch something went wrong most likely unresolved externals
+ ::unldByModuleId ( handle, 0 );
+ handle = 0;
+ }
+ }
+ else
+ {
+ // couldn't open file
+ handle = 0;
+ }
+ return handle;
+# 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");
+
+#if defined (ACE_HAS_DLSYM_SEGFAULT_ON_INVALID_HANDLE)
+ // Check if the handle is valid before making any calls using it.
+ if (handle == ACE_SHLIB_INVALID_HANDLE)
+ return 0;
+#endif /* ACE_HAS_DLSYM_SEGFAULT_ON_INVALID_HANDLE */
+
+ // 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 : 0;
+
+# elif defined (VXWORKS)
+
+ // For now we use the VxWorks global symbol table
+ // which resolves the most recently loaded symbols .. which resolve mostly what we want..
+ ACE_UNUSED_ARG (handle);
+ SYM_TYPE symtype;
+ void *value = 0;
+ STATUS status;
+ ACE_OSCALL (::symFindByName(sysSymTbl, symbolname, (char **)&value, &symtype), int, -1, status);
+
+ return status == OK ? value : 0;
+
+# else
+
+ ACE_UNUSED_ARG (handle);
+ ACE_UNUSED_ARG (symbolname);
+ ACE_NOTSUP_RETURN (0);
+
+# endif /* ACE_HAS_SVR4_DYNAMIC_LINKING */
+}
diff --git a/ace/OS_NS_errno.cpp b/ace/OS_NS_errno.cpp
index fc532b41367..27a0901f32a 100644
--- a/ace/OS_NS_errno.cpp
+++ b/ace/OS_NS_errno.cpp
@@ -1,4 +1,11 @@
// -*- C++ -*-
// $Id$
-// This is a placeholder.
+#include "ace/OS_NS_errno.h"
+
+ACE_RCSID(ace, OS_NS_errno, "$Id$")
+
+#if !defined (ACE_HAS_INLINED_OSCALLS)
+# include "ace/OS_NS_errno.inl"
+#endif /* ACE_HAS_INLINED_OS_CALLS */
+
diff --git a/ace/OS_NS_errno.h b/ace/OS_NS_errno.h
index fc532b41367..d35ad6eb665 100644
--- a/ace/OS_NS_errno.h
+++ b/ace/OS_NS_errno.h
@@ -1,4 +1,51 @@
// -*- C++ -*-
-// $Id$
-// This is a placeholder.
+//=============================================================================
+/**
+ * @file OS_NS_errno.h
+ *
+ * $Id$
+ *
+ * @author Douglas C. Schmidt <schmidt@cs.wustl.edu>
+ * @author Jesper S. M|ller<stophph@diku.dk>
+ * @author and a cast of thousands...
+ *
+ * Originally in OS.h.
+ */
+//=============================================================================
+
+#ifndef ACE_OS_NS_ERRNO_H
+# define ACE_OS_NS_ERRNO_H
+
+# include /**/ "ace/pre.h"
+
+# include "ace/config-all.h"
+
+# if !defined (ACE_LACKS_PRAGMA_ONCE)
+# pragma once
+# endif /* ACE_LACKS_PRAGMA_ONCE */
+
+#include "ace/os_include/os_errno.h"
+
+namespace ACE_OS {
+
+ int last_error (void);
+
+ void last_error (int);
+
+ int set_errno_to_last_error (void);
+
+ int set_errno_to_wsa_last_error (void);
+
+} /* namespace ACE_OS */
+
+# if defined (ACE_HAS_INLINED_OSCALLS)
+# if defined (ACE_INLINE)
+# undef ACE_INLINE
+# endif /* ACE_INLINE */
+# define ACE_INLINE inline
+# include "ace/OS_NS_errno.inl"
+# endif /* ACE_HAS_INLINED_OSCALLS */
+
+# include /**/ "ace/post.h"
+#endif /* ACE_OS_NS_ERRNO_H */
diff --git a/ace/OS_NS_errno.inl b/ace/OS_NS_errno.inl
index fc532b41367..8e47ce38525 100644
--- a/ace/OS_NS_errno.inl
+++ b/ace/OS_NS_errno.inl
@@ -1,4 +1,64 @@
// -*- C++ -*-
// $Id$
-// This is a placeholder.
+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);
+#endif /* ACE_WIN32 */
+ errno = error;
+}
+
+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) */
+}
diff --git a/ace/OS_NS_fcntl.cpp b/ace/OS_NS_fcntl.cpp
index fc532b41367..e1e948c2d00 100644
--- a/ace/OS_NS_fcntl.cpp
+++ b/ace/OS_NS_fcntl.cpp
@@ -1,4 +1,254 @@
// -*- C++ -*-
// $Id$
-// This is a placeholder.
+#include "ace/OS_NS_fcntl.h"
+
+ACE_RCSID(ace, OS_NS_fcntl, "$Id$")
+
+#if !defined (ACE_HAS_INLINED_OSCALLS)
+# include "ace/OS_NS_fcntl.inl"
+#endif /* ACE_HAS_INLINED_OS_CALLS */
+
+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) */
+#elif defined (INTEGRITY)
+ ACE_UNUSED_ARG (sa);
+ if(!strcmp(filename,ACE_DEV_NULL)) {
+ ACE_OSCALL_RETURN (::AllocateNullConsoleDescriptor(), ACE_HANDLE, -1);
+ }
+ else {
+ ACE_OSCALL_RETURN (::open (filename, mode, perms), ACE_HANDLE, -1);
+ }
+#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 */
diff --git a/ace/OS_NS_fcntl.h b/ace/OS_NS_fcntl.h
index fc532b41367..027f4dd93c3 100644
--- a/ace/OS_NS_fcntl.h
+++ b/ace/OS_NS_fcntl.h
@@ -1,4 +1,82 @@
// -*- C++ -*-
-// $Id$
-// This is a placeholder.
+//=============================================================================
+/**
+ * @file OS_NS_fcntl.h
+ *
+ * $Id$
+ *
+ * @author Douglas C. Schmidt <schmidt@cs.wustl.edu>
+ * @author Jesper S. M|ller<stophph@diku.dk>
+ * @author and a cast of thousands...
+ *
+ * Originally in OS.h.
+ */
+//=============================================================================
+
+#ifndef ACE_OS_NS_FCNTL_H
+# define ACE_OS_NS_FCNTL_H
+
+# include /**/ "ace/pre.h"
+
+# include "ace/config-all.h"
+
+# if !defined (ACE_LACKS_PRAGMA_ONCE)
+# pragma once
+# endif /* ACE_LACKS_PRAGMA_ONCE */
+
+#include "ace/os_include/os_fcntl.h"
+#include "ace/Global_Macros.h" // for LPSECURITY_ATTRIBUTES :-(
+
+namespace ACE_OS {
+
+ int fcntl (ACE_HANDLE handle,
+ int cmd,
+ long arg = 0);
+
+ // 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.
+ ACE_HANDLE open (const char *filename,
+ int mode,
+ int perms = ACE_DEFAULT_OPEN_PERMS,
+ LPSECURITY_ATTRIBUTES sa = 0);
+#if defined (ACE_HAS_WCHAR)
+ ACE_HANDLE open (const wchar_t *filename,
+ int mode,
+ int perms = ACE_DEFAULT_OPEN_PERMS,
+ LPSECURITY_ATTRIBUTES sa = 0);
+#endif /* ACE_HAS_WCHAR */
+
+} /* namespace ACE_OS */
+
+# if defined (ACE_HAS_INLINED_OSCALLS)
+# if defined (ACE_INLINE)
+# undef ACE_INLINE
+# endif /* ACE_INLINE */
+# define ACE_INLINE inline
+# include "ace/OS_NS_fcntl.inl"
+# endif /* ACE_HAS_INLINED_OSCALLS */
+
+# include /**/ "ace/post.h"
+#endif /* ACE_OS_NS_FCNTL_H */
diff --git a/ace/OS_NS_fcntl.inl b/ace/OS_NS_fcntl.inl
index fc532b41367..3e0e4e14884 100644
--- a/ace/OS_NS_fcntl.inl
+++ b/ace/OS_NS_fcntl.inl
@@ -1,4 +1,17 @@
// -*- C++ -*-
// $Id$
-// This is a placeholder.
+ACE_INLINE int
+ACE_OS::fcntl (ACE_HANDLE handle, int cmd, long arg)
+{
+ ACE_OS_TRACE ("ACE_OS::fcntl");
+# if 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_LACKS_FCNTL */
+}
+
diff --git a/ace/OS_NS_macros.h b/ace/OS_NS_macros.h
index fc532b41367..c651d752ca8 100644
--- a/ace/OS_NS_macros.h
+++ b/ace/OS_NS_macros.h
@@ -1,4 +1,67 @@
// -*- C++ -*-
-// $Id$
-// This is a placeholder.
+//=============================================================================
+/**
+ * @file OS_NS_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...
+ *
+ * Originally in OS.h.
+ */
+//=============================================================================
+
+#ifndef ACE_OS_NS_MACROS_H
+# define ACE_OS_NS_MACROS_H
+
+# include /**/ "ace/pre.h"
+
+# include "ace/config-all.h"
+
+# if !defined (ACE_LACKS_PRAGMA_ONCE)
+# pragma once
+# endif /* ACE_LACKS_PRAGMA_ONCE */
+
+#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_WIN32)
+
+// 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 */
+
+#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)
+
+#endif /* !ACE_WIN32 */
+
+#endif /* ACE_OS_NS_MACROS_H */
diff --git a/ace/OS_NS_math.cpp b/ace/OS_NS_math.cpp
index fc532b41367..dc009cad8ba 100644
--- a/ace/OS_NS_math.cpp
+++ b/ace/OS_NS_math.cpp
@@ -1,4 +1,11 @@
// -*- C++ -*-
// $Id$
-// This is a placeholder.
+#include "ace/OS_NS_math.h"
+
+ACE_RCSID(ace, OS_NS_math, "$Id$")
+
+#if !defined (ACE_HAS_INLINED_OSCALLS)
+# include "ace/OS_NS_math.inl"
+#endif /* ACE_HAS_INLINED_OS_CALLS */
+
diff --git a/ace/OS_NS_math.h b/ace/OS_NS_math.h
index fc532b41367..fc6a8081e9f 100644
--- a/ace/OS_NS_math.h
+++ b/ace/OS_NS_math.h
@@ -1,4 +1,50 @@
// -*- C++ -*-
-// $Id$
-// This is a placeholder.
+//=============================================================================
+/**
+ * @file OS_NS_math.h
+ *
+ * $Id$
+ *
+ * @author Douglas C. Schmidt <schmidt@cs.wustl.edu>
+ * @author Jesper S. M|ller<stophph@diku.dk>
+ * @author and a cast of thousands...
+ *
+ * Originally in OS.h.
+ */
+//=============================================================================
+
+#ifndef ACE_OS_NS_MATH_H
+# define ACE_OS_NS_MATH_H
+
+# include /**/ "ace/pre.h"
+
+# include "ace/config-all.h"
+
+# if !defined (ACE_LACKS_PRAGMA_ONCE)
+# pragma once
+# endif /* ACE_LACKS_PRAGMA_ONCE */
+
+#include "ace/os_include/os_math.h"
+
+namespace ACE_OS {
+
+ /// This method computes the largest integral value not greater than x.
+ double floor (double x);
+
+ /// This method computes the smallest integral value not less than x.
+ double ceil (double x);
+
+
+} /* namespace ACE_OS */
+
+# if defined (ACE_HAS_INLINED_OSCALLS)
+# if defined (ACE_INLINE)
+# undef ACE_INLINE
+# endif /* ACE_INLINE */
+# define ACE_INLINE inline
+# include "ace/OS_NS_math.inl"
+# endif /* ACE_HAS_INLINED_OSCALLS */
+
+# include /**/ "ace/post.h"
+#endif /* ACE_OS_NS_MATH_H */
diff --git a/ace/OS_NS_math.inl b/ace/OS_NS_math.inl
index fc532b41367..9ff3151ab4f 100644
--- a/ace/OS_NS_math.inl
+++ b/ace/OS_NS_math.inl
@@ -1,4 +1,20 @@
// -*- C++ -*-
// $Id$
-// This is a placeholder.
+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;
+}
diff --git a/ace/OS_NS_netdb.cpp b/ace/OS_NS_netdb.cpp
index fc532b41367..61073801acc 100644
--- a/ace/OS_NS_netdb.cpp
+++ b/ace/OS_NS_netdb.cpp
@@ -1,4 +1,359 @@
// -*- C++ -*-
// $Id$
-// This is a placeholder.
+#include "ace/OS_NS_netdb.h"
+
+ACE_RCSID(ace, OS_NS_netdb, "$Id$")
+
+#if !defined (ACE_HAS_INLINED_OSCALLS)
+# include "ace/OS_NS_netdb.inl"
+#endif /* ACE_HAS_INLINED_OS_CALLS */
+
+#include "ace/os_include/net/os_if.h"
+#include "ace/OS_NS_unistd.h"
+#include "ace/OS_NS_stropts.h"
+#include "ace/OS_NS_sys_socket.h"
+
+#if defined (VXWORKS)
+
+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 (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::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 */
+
+// Include if_arp so that getmacaddr can use the
+// arp structure.
+#if defined (sun)
+# include /**/ <net/if_arp.h>
+#endif
+
+int
+ACE_OS::getmacaddress (struct macaddr_node_t *node)
+{
+ ACE_OS_TRACE ("ACE_OS::getmacaddress");
+
+#if defined (ACE_WIN32) && !defined (ACE_HAS_WINCE)
+
+ /** Define a structure for use with the netbios routine */
+ struct ADAPTERSTAT
+ {
+ ADAPTER_STATUS adapt;
+ NAME_BUFFER NameBuff [30];
+ };
+
+ NCB ncb;
+ LANA_ENUM lenum;
+ unsigned char result;
+
+ ACE_OS::memset (&ncb, 0, sizeof(ncb));
+ ncb.ncb_command = NCBENUM;
+ ncb.ncb_buffer = ACE_reinterpret_cast (unsigned char*,&lenum);
+ ncb.ncb_length = sizeof(lenum);
+
+ result = Netbios (&ncb);
+
+ for(int i = 0; i < lenum.length; i++)
+ {
+ ACE_OS::memset (&ncb, 0, sizeof(ncb));
+ ncb.ncb_command = NCBRESET;
+ ncb.ncb_lana_num = lenum.lana [i];
+
+ /** Reset the netbios */
+ result = Netbios (&ncb);
+
+ if (ncb.ncb_retcode != NRC_GOODRET)
+ {
+ return -1;
+ }
+
+ ADAPTERSTAT adapter;
+ ACE_OS::memset (&ncb, 0, sizeof (ncb));
+# if defined (__BORLANDC__) || defined (__MINGW32__)
+ ACE_OS::strcpy (ACE_reinterpret_cast (char*, ncb.ncb_callname), "*");
+# else
+ ACE_OS::strcpy (ACE_static_cast (char*, ncb.ncb_callname), "*");
+# endif /* __BORLANDC__ || __MINGW32__ */
+ ncb.ncb_command = NCBASTAT;
+ ncb.ncb_lana_num = lenum.lana[i];
+ ncb.ncb_buffer = ACE_reinterpret_cast (unsigned char*, &adapter);
+ ncb.ncb_length = sizeof (adapter);
+
+ result = Netbios (&ncb);
+
+ if (result == 0)
+ {
+ ACE_OS::memcpy (node->node,
+ adapter.adapt.adapter_address,
+ 6);
+ return 0;
+ }
+ }
+ return 0;
+#elif defined (sun)
+
+ /** obtain the local host name */
+ char hostname [MAXHOSTNAMELEN];
+ ACE_OS::hostname (hostname, sizeof (hostname));
+
+ /** Get the hostent to use with ioctl */
+ struct hostent *phost =
+ ACE_OS::gethostbyname (hostname);
+
+ if (phost == 0)
+ {
+ return -1;
+ }
+
+ ACE_HANDLE handle =
+ ACE_OS::socket (PF_INET, SOCK_DGRAM, IPPROTO_UDP);
+
+ if (handle == ACE_INVALID_HANDLE)
+ {
+ return -1;
+ }
+
+ char **paddrs = phost->h_addr_list;
+
+ struct arpreq ar;
+
+ struct sockaddr_in *psa =
+ (struct sockaddr_in *)&(ar.arp_pa);
+
+ ACE_OS::memset (&ar,
+ 0,
+ sizeof (struct arpreq));
+
+ psa->sin_family = AF_INET;
+
+ ACE_OS::memcpy (&(psa->sin_addr),
+ *paddrs,
+ sizeof (struct in_addr));
+
+ if (ACE_OS::ioctl (handle,
+ SIOCGARP,
+ &ar) == -1)
+ {
+ return -1;
+ }
+
+ ACE_OS::close (handle);
+
+ ACE_OS::memcpy (node->node,
+ ar.arp_ha.sa_data,
+ 6);
+
+ return 0;
+
+#elif defined (linux)
+
+ struct ifreq ifr;
+
+ ACE_HANDLE handle =
+ ACE_OS::socket (PF_INET, SOCK_DGRAM, 0);
+
+ if (handle == ACE_INVALID_HANDLE)
+ {
+ return -1;
+ }
+
+ ACE_OS::strcpy (ifr.ifr_name, "eth0");
+
+ if (ACE_OS::ioctl (handle/*s*/, SIOCGIFHWADDR, &ifr) < 0)
+ {
+ ACE_OS::close (handle);
+ return -1;
+ }
+
+ struct sockaddr* sa =
+ (struct sockaddr *) &ifr.ifr_addr;
+
+ ACE_OS::memcpy (node->node,
+ sa->sa_data,
+ 6);
+
+ return 0;
+
+#else
+ ACE_UNUSED_ARG (node);
+ ACE_NOTSUP_RETURN (-1);
+#endif
+}
+
+# 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) */
diff --git a/ace/OS_NS_netdb.h b/ace/OS_NS_netdb.h
index fc532b41367..234e16f3f6b 100644
--- a/ace/OS_NS_netdb.h
+++ b/ace/OS_NS_netdb.h
@@ -1,4 +1,103 @@
// -*- C++ -*-
-// $Id$
-// This is a placeholder.
+//=============================================================================
+/**
+ * @file OS_NS_netdb.h
+ *
+ * $Id$
+ *
+ * @author Douglas C. Schmidt <schmidt@cs.wustl.edu>
+ * @author Jesper S. M|ller<stophph@diku.dk>
+ * @author and a cast of thousands...
+ *
+ * Originally in OS.h.
+ */
+//=============================================================================
+
+#ifndef ACE_OS_NS_NETDB_H
+# define ACE_OS_NS_NETDB_H
+
+# include /**/ "ace/pre.h"
+
+# include "ace/config-all.h"
+
+# if !defined (ACE_LACKS_PRAGMA_ONCE)
+# pragma once
+# endif /* ACE_LACKS_PRAGMA_ONCE */
+
+#include "ace/os_include/os_netdb.h"
+
+namespace ACE_OS {
+
+ struct hostent *gethostbyaddr (const char *addr,
+ int length,
+ int type);
+
+ struct hostent *gethostbyaddr_r (const char *addr,
+ int length,
+ int type,
+ struct hostent *result,
+ ACE_HOSTENT_DATA buffer,
+ int *h_errnop);
+
+ struct hostent *gethostbyname (const char *name);
+
+ struct hostent *gethostbyname_r (const char *name,
+ struct hostent *result,
+ ACE_HOSTENT_DATA buffer,
+ int *h_errnop);
+
+
+ struct hostent *getipnodebyaddr (const void *src, size_t len,
+ int family);
+
+ struct hostent *getipnodebyname (const char *name, int family,
+ int flags = 0);
+
+ /**
+ * Get the first adapter found on the machine.
+ * @todo: this is really useless except for UUID, move there? dhinton
+ */
+ struct macaddr_node_t {
+ unsigned char node[6];
+ };
+
+ int getmacaddress (struct macaddr_node_t *node);
+
+ struct protoent *getprotobyname (const char *name);
+
+ struct protoent *getprotobyname_r (const char *name,
+ struct protoent *result,
+ ACE_PROTOENT_DATA buffer);
+
+ struct protoent *getprotobynumber (int proto);
+
+ struct protoent *getprotobynumber_r (int proto,
+ struct protoent *result,
+ ACE_PROTOENT_DATA buffer);
+
+ struct servent *getservbyname (const char *svc,
+ const char *proto);
+
+ struct servent *getservbyname_r (const char *svc,
+ const char *proto,
+ struct servent *result,
+ ACE_SERVENT_DATA buf);
+
+# if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0) && defined (ACE_LACKS_NETDB_REENTRANT_FUNCTIONS)
+ int netdb_acquire (void);
+ int netdb_release (void);
+# endif /* defined (ACE_MT_SAFE) && ACE_LACKS_NETDB_REENTRANT_FUNCTIONS */
+
+} /* namespace ACE_OS */
+
+# if defined (ACE_HAS_INLINED_OSCALLS)
+# if defined (ACE_INLINE)
+# undef ACE_INLINE
+# endif /* ACE_INLINE */
+# define ACE_INLINE inline
+# include "ace/OS_NS_netdb.inl"
+# endif /* ACE_HAS_INLINED_OSCALLS */
+
+# include /**/ "ace/post.h"
+#endif /* ACE_OS_NS_NETDB_H */
diff --git a/ace/OS_NS_netdb.inl b/ace/OS_NS_netdb.inl
index fc532b41367..983fe7df7d6 100644
--- a/ace/OS_NS_netdb.inl
+++ b/ace/OS_NS_netdb.inl
@@ -1,4 +1,528 @@
// -*- C++ -*-
// $Id$
-// This is a placeholder.
+#include "ace/OS_NS_macros.h"
+#include "ace/OS_NS_string.h"
+#include "ace/OS_NS_errno.h"
+
+#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 */
+
+#if !defined (VXWORKS)
+
+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::gethostbyaddr_r (const char *addr,
+ int length,
+ int type,
+ struct 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 (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::gethostbyname_r (const char *name,
+ struct 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) */
+}
+
+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),
+ ACE_static_cast (int, len),
+ family);
+
+ ACE_NOTSUP_RETURN (0);
+# endif /* ACE_PSOS */
+}
+
+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 */
+}
+
+#endif /* ! VXWORKS */
+
+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 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) */
+}
diff --git a/ace/OS_NS_poll.cpp b/ace/OS_NS_poll.cpp
index fc532b41367..c109c2f097e 100644
--- a/ace/OS_NS_poll.cpp
+++ b/ace/OS_NS_poll.cpp
@@ -1,4 +1,11 @@
// -*- C++ -*-
// $Id$
-// This is a placeholder.
+#include "ace/OS_NS_poll.h"
+
+ACE_RCSID(ace, OS_NS_poll, "$Id$")
+
+#if !defined (ACE_HAS_INLINED_OSCALLS)
+# include "ace/OS_NS_poll.inl"
+#endif /* ACE_HAS_INLINED_OS_CALLS */
+
diff --git a/ace/OS_NS_poll.h b/ace/OS_NS_poll.h
index fc532b41367..629fac2d4fe 100644
--- a/ace/OS_NS_poll.h
+++ b/ace/OS_NS_poll.h
@@ -1,4 +1,52 @@
// -*- C++ -*-
-// $Id$
-// This is a placeholder.
+//=============================================================================
+/**
+ * @file OS_NS_poll.h
+ *
+ * $Id$
+ *
+ * @author Douglas C. Schmidt <schmidt@cs.wustl.edu>
+ * @author Jesper S. M|ller<stophph@diku.dk>
+ * @author and a cast of thousands...
+ *
+ * Originally in OS.h.
+ */
+//=============================================================================
+
+#ifndef ACE_OS_NS_POLL_H
+# define ACE_OS_NS_POLL_H
+
+# include /**/ "ace/pre.h"
+
+# include "ace/config-all.h"
+
+# if !defined (ACE_LACKS_PRAGMA_ONCE)
+# pragma once
+# endif /* ACE_LACKS_PRAGMA_ONCE */
+
+#include "ace/os_include/os_poll.h"
+
+class ACE_Time_Value;
+
+namespace ACE_OS {
+
+ int poll (struct pollfd *pollfds,
+ unsigned long len,
+ const ACE_Time_Value *tv = 0);
+ int poll (struct pollfd *pollfds,
+ unsigned long len,
+ const ACE_Time_Value &tv);
+
+} /* namespace ACE_OS */
+
+# if defined (ACE_HAS_INLINED_OSCALLS)
+# if defined (ACE_INLINE)
+# undef ACE_INLINE
+# endif /* ACE_INLINE */
+# define ACE_INLINE inline
+# include "ace/OS_NS_poll.inl"
+# endif /* ACE_HAS_INLINED_OSCALLS */
+
+# include /**/ "ace/post.h"
+#endif /* ACE_OS_NS_POLL_H */
diff --git a/ace/OS_NS_poll.inl b/ace/OS_NS_poll.inl
index fc532b41367..59ce51f1bc9 100644
--- a/ace/OS_NS_poll.inl
+++ b/ace/OS_NS_poll.inl
@@ -1,4 +1,39 @@
// -*- C++ -*-
// $Id$
-// This is a placeholder.
+#include "ace/Time_Value.h"
+
+ACE_INLINE int
+ACE_OS::poll (struct pollfd *pollfds,
+ unsigned 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,
+ unsigned 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 */
+}
diff --git a/ace/OS_NS_pwd.cpp b/ace/OS_NS_pwd.cpp
index fc532b41367..61da06a1e7c 100644
--- a/ace/OS_NS_pwd.cpp
+++ b/ace/OS_NS_pwd.cpp
@@ -1,4 +1,11 @@
// -*- C++ -*-
// $Id$
-// This is a placeholder.
+#include "ace/OS_NS_pwd.h"
+
+ACE_RCSID(ace, OS_NS_pwd, "$Id$")
+
+#if !defined (ACE_HAS_INLINED_OSCALLS)
+# include "ace/OS_NS_pwd.inl"
+#endif /* ACE_HAS_INLINED_OS_CALLS */
+
diff --git a/ace/OS_NS_pwd.h b/ace/OS_NS_pwd.h
index fc532b41367..76a41ac5108 100644
--- a/ace/OS_NS_pwd.h
+++ b/ace/OS_NS_pwd.h
@@ -1,4 +1,63 @@
// -*- C++ -*-
-// $Id$
-// This is a placeholder.
+//=============================================================================
+/**
+ * @file OS_NS_pwd.h
+ *
+ * $Id$
+ *
+ * @author Douglas C. Schmidt <schmidt@cs.wustl.edu>
+ * @author Jesper S. M|ller<stophph@diku.dk>
+ * @author and a cast of thousands...
+ *
+ * Originally in OS.h.
+ */
+//=============================================================================
+
+#ifndef ACE_OS_NS_PWD_H
+# define ACE_OS_NS_PWD_H
+
+# include /**/ "ace/pre.h"
+
+# include "ace/config-all.h"
+
+# if !defined (ACE_LACKS_PRAGMA_ONCE)
+# pragma once
+# endif /* ACE_LACKS_PRAGMA_ONCE */
+
+#include "ace/os_include/os_pwd.h"
+
+# if defined (ACE_HAS_BROKEN_R_ROUTINES)
+# undef getpwnam_r
+# endif /* ACE_HAS_BROKEN_R_ROUTINES */
+
+namespace ACE_OS {
+
+
+ //@{ @name A set of wrappers for password routines.
+
+ void endpwent (void);
+
+ struct passwd *getpwent (void);
+
+ struct passwd *getpwnam (const char *user);
+
+ struct passwd *getpwnam_r (const char *name,
+ struct passwd *pwent,
+ char *buffer,
+ int buflen);
+ void setpwent (void);
+ //@}
+
+} /* namespace ACE_OS */
+
+# if defined (ACE_HAS_INLINED_OSCALLS)
+# if defined (ACE_INLINE)
+# undef ACE_INLINE
+# endif /* ACE_INLINE */
+# define ACE_INLINE inline
+# include "ace/OS_NS_pwd.inl"
+# endif /* ACE_HAS_INLINED_OSCALLS */
+
+# include /**/ "ace/post.h"
+#endif /* ACE_OS_NS_PWD_H */
diff --git a/ace/OS_NS_pwd.inl b/ace/OS_NS_pwd.inl
index fc532b41367..b5d10ec914b 100644
--- a/ace/OS_NS_pwd.inl
+++ b/ace/OS_NS_pwd.inl
@@ -1,4 +1,133 @@
// -*- C++ -*-
// $Id$
-// This is a placeholder.
+#include "ace/OS_NS_errno.h"
+
+// Accessors to PWD file.
+
+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 (const char *name)
+{
+#if !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_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_POSIX_GETPWNAM_R)
+ struct passwd *result;
+ int status;
+
+ status = ::getpwnam_r (name, pwent, buffer, buflen, &result);
+
+ 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_POSIX_GETPWNAM_R */
+}
+
+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 */
+}
diff --git a/ace/OS_NS_regex.cpp b/ace/OS_NS_regex.cpp
index fc532b41367..88fc9f3beb4 100644
--- a/ace/OS_NS_regex.cpp
+++ b/ace/OS_NS_regex.cpp
@@ -1,4 +1,11 @@
// -*- C++ -*-
// $Id$
-// This is a placeholder.
+#include "ace/OS_NS_regex.h"
+
+ACE_RCSID(ace, OS_NS_regex, "$Id$")
+
+#if !defined (ACE_HAS_INLINED_OSCALLS)
+# include "ace/OS_NS_regex.inl"
+#endif /* ACE_HAS_INLINED_OS_CALLS */
+
diff --git a/ace/OS_NS_regex.h b/ace/OS_NS_regex.h
index fc532b41367..a09240f9375 100644
--- a/ace/OS_NS_regex.h
+++ b/ace/OS_NS_regex.h
@@ -1,4 +1,52 @@
// -*- C++ -*-
-// $Id$
-// This is a placeholder.
+//=============================================================================
+/**
+ * @file OS_NS_regex.h
+ *
+ * $Id$
+ *
+ * @author Douglas C. Schmidt <schmidt@cs.wustl.edu>
+ * @author Jesper S. M|ller<stophph@diku.dk>
+ * @author and a cast of thousands...
+ *
+ * Originally in OS.h.
+ */
+//=============================================================================
+
+#ifndef ACE_OS_NS_REGEX_H
+# define ACE_OS_NS_REGEX_H
+
+# include /**/ "ace/pre.h"
+
+# include "ace/config-all.h"
+
+# if !defined (ACE_LACKS_PRAGMA_ONCE)
+# pragma once
+# endif /* ACE_LACKS_PRAGMA_ONCE */
+
+#include "ace/os_include/os_regex.h"
+
+namespace ACE_OS {
+
+ // non=standard..
+ //@{ @name A set of wrappers for regular expressions.
+ char *compile (const char *instring,
+ char *expbuf,
+ char *endbuf);
+ int step (const char *str,
+ char *expbuf);
+ //@}
+
+} /* namespace ACE_OS */
+
+# if defined (ACE_HAS_INLINED_OSCALLS)
+# if defined (ACE_INLINE)
+# undef ACE_INLINE
+# endif /* ACE_INLINE */
+# define ACE_INLINE inline
+# include "ace/OS_NS_regex.inl"
+# endif /* ACE_HAS_INLINED_OSCALLS */
+
+# include /**/ "ace/post.h"
+#endif /* ACE_OS_NS_REGEX_H */
diff --git a/ace/OS_NS_regex.inl b/ace/OS_NS_regex.inl
index fc532b41367..5a97d80c955 100644
--- a/ace/OS_NS_regex.inl
+++ b/ace/OS_NS_regex.inl
@@ -1,4 +1,34 @@
// -*- C++ -*-
// $Id$
-// This is a placeholder.
+#include "ace/OS_NS_errno.h"
+
+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 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 */
+}
+
diff --git a/ace/OS_NS_signal.cpp b/ace/OS_NS_signal.cpp
index fc532b41367..3dc5e1c56fe 100644
--- a/ace/OS_NS_signal.cpp
+++ b/ace/OS_NS_signal.cpp
@@ -1,4 +1,24 @@
// -*- C++ -*-
// $Id$
-// This is a placeholder.
+#include "ace/OS_NS_signal.h"
+
+ACE_RCSID(ace, OS_NS_signal, "$Id$")
+
+#if !defined (ACE_HAS_INLINED_OSCALLS)
+# include "ace/OS_NS_signal.inl"
+#endif /* ACE_HAS_INLINED_OS_CALLS */
+
+#if !defined (ACE_HAS_SIGINFO_T)
+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_SIGINFO_T */
diff --git a/ace/OS_NS_signal.h b/ace/OS_NS_signal.h
index fc532b41367..d26c02cb9bf 100644
--- a/ace/OS_NS_signal.h
+++ b/ace/OS_NS_signal.h
@@ -1,4 +1,110 @@
// -*- C++ -*-
-// $Id$
-// This is a placeholder.
+//=============================================================================
+/**
+ * @file OS_NS_signal.h
+ *
+ * $Id$
+ *
+ * @author Douglas C. Schmidt <schmidt@cs.wustl.edu>
+ * @author Jesper S. M|ller<stophph@diku.dk>
+ * @author and a cast of thousands...
+ *
+ * Originally in OS.h.
+ */
+//=============================================================================
+
+#ifndef ACE_OS_NS_SIGNAL_H
+# define ACE_OS_NS_SIGNAL_H
+
+# include /**/ "ace/pre.h"
+
+# include "ace/config-all.h"
+
+# if !defined (ACE_LACKS_PRAGMA_ONCE)
+# pragma once
+# endif /* ACE_LACKS_PRAGMA_ONCE */
+
+#include "ace/os_include/os_signal.h"
+
+# 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 */
+
+// Create some useful typedefs.
+// @todo: remove, not used dhinton
+//typedef const char **SYS_SIGLIST;
+
+# if !defined (ACE_HAS_SIGINFO_T)
+struct ACE_OS_Export siginfo_t
+{
+ siginfo_t (ACE_HANDLE handle);
+ siginfo_t (ACE_HANDLE *handles); // JCEJ 12/23/96
+
+ /// Win32 HANDLE that has become signaled.
+ ACE_HANDLE si_handle_;
+
+ /// Array of Win32 HANDLEs all of which have become signaled.
+ ACE_HANDLE *si_handles_;
+};
+# endif /* ACE_HAS_SIGINFO_T */
+
+namespace ACE_OS {
+
+ //@{ @name A set of wrappers for Signals.
+
+ int kill (pid_t pid,
+ int signum);
+
+ int pthread_sigmask (int how,
+ const sigset_t *nsp,
+ sigset_t *osp);
+
+ int sigaction (int signum,
+ const struct sigaction *nsa,
+ struct sigaction *osa);
+
+ int sigaddset (sigset_t *s,
+ int signum);
+
+ int sigdelset (sigset_t *s,
+ int signum);
+
+ int sigemptyset (sigset_t *s);
+
+ int sigfillset (sigset_t *s);
+
+ int sigismember (sigset_t *s,
+ int signum);
+
+ ACE_SignalHandler signal (int signum,
+ ACE_SignalHandler);
+
+ int sigprocmask (int how,
+ const sigset_t *nsp,
+ sigset_t *osp);
+
+ int sigsuspend (const sigset_t *set);
+
+ //@}
+
+} /* namespace ACE_OS */
+
+# if defined (ACE_HAS_INLINED_OSCALLS)
+# if defined (ACE_INLINE)
+# undef ACE_INLINE
+# endif /* ACE_INLINE */
+# define ACE_INLINE inline
+# include "ace/OS_NS_signal.inl"
+# endif /* ACE_HAS_INLINED_OSCALLS */
+
+# include /**/ "ace/post.h"
+#endif /* ACE_OS_NS_SIGNAL_H */
diff --git a/ace/OS_NS_signal.inl b/ace/OS_NS_signal.inl
index fc532b41367..31e116fae9b 100644
--- a/ace/OS_NS_signal.inl
+++ b/ace/OS_NS_signal.inl
@@ -1,4 +1,271 @@
// -*- C++ -*-
// $Id$
-// This is a placeholder.
+#include "ace/OS_NS_macros.h"
+#include "ace/OS_NS_errno.h"
+
+ACE_INLINE int
+ACE_OS::kill (pid_t pid, int signum)
+{
+ ACE_OS_TRACE ("ACE_OS::kill");
+#if 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_WIN32 || CHORUS || ACE_PSOS */
+}
+
+ACE_INLINE int
+ACE_OS::pthread_sigmask (int how, const sigset_t *nsp, sigset_t *osp)
+{
+#if 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_LACKS_PTHREAD_SIGMASK */
+ ACE_UNUSED_ARG (how);
+ ACE_UNUSED_ARG (nsp);
+ ACE_UNUSED_ARG (osp);
+ ACE_NOTSUP_RETURN (-1);
+#endif /* ACE_HAS_PTHREADS_STD && !ACE_LACKS_PTHREAD_SIGMASK */
+}
+
+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_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_WIN32 !ACE_HAS_WINCE */
+}
+
+ACE_INLINE int
+ACE_OS::sigaddset (sigset_t *s, int signum)
+{
+ ACE_OS_TRACE ("ACE_OS::sigaddset");
+#if defined (ACE_LACKS_SIGSET) || defined (ACE_LACKS_SIGSET_DEFINITIONS)
+ if (s == 0)
+ {
+ 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_LACKS_SIGSET || ACE_LACKS_SIGSET_DEFINITIONS */
+}
+
+ACE_INLINE int
+ACE_OS::sigdelset (sigset_t *s, int signum)
+{
+#if defined (ACE_LACKS_SIGSET) || defined (ACE_LACKS_SIGSET_DEFINITIONS)
+ if (s == 0)
+ {
+ 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_LACKS_SIGSET || ACE_LACKS_SIGSET_DEFINITIONS */
+}
+
+ACE_INLINE int
+ACE_OS::sigemptyset (sigset_t *s)
+{
+#if defined (ACE_LACKS_SIGSET) || defined (ACE_LACKS_SIGSET_DEFINITIONS)
+ if (s == 0)
+ {
+ 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_LACKS_SIGSET || ACE_LACKS_SIGSET_DEFINITIONS */
+}
+
+ACE_INLINE int
+ACE_OS::sigfillset (sigset_t *s)
+{
+#if defined (ACE_LACKS_SIGSET) || defined (ACE_LACKS_SIGSET_DEFINITIONS)
+ if (s == 0)
+ {
+ 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_LACKS_SIGSET || ACE_LACKS_SIGSET_DEFINITIONS */
+}
+
+ACE_INLINE int
+ACE_OS::sigismember (sigset_t *s, int signum)
+{
+#if defined (ACE_LACKS_SIGSET) || defined (ACE_LACKS_SIGSET_DEFINITIONS)
+ if (s == 0)
+ {
+ 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_LACKS_SIGSET || ACE_LACKS_SIGSET_DEFINITIONS */
+}
+
+ACE_INLINE ACE_SignalHandler
+ACE_OS::signal (int signum, ACE_SignalHandler func)
+{
+ if (signum == 0)
+ return 0;
+ else
+#if 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_PSOS && !ACE_PSOS_TM && !ACE_PSOS_DIAB_MIPS && !ACE_PSOS_DIAB_PPC */
+}
+
+ACE_INLINE int
+ACE_OS::sigprocmask (int how, const sigset_t *nsp, sigset_t *osp)
+{
+#if 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_LACKS_SIGSET || ACE_LACKS_SIGSET_DEFINITIONS */
+}
+
+ACE_INLINE int
+ACE_OS::sigsuspend (const sigset_t *sigset)
+{
+#if 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_SIGSUSPEND */
+}
diff --git a/ace/OS_NS_stdio.cpp b/ace/OS_NS_stdio.cpp
index fc532b41367..5a9a74b5ec3 100644
--- a/ace/OS_NS_stdio.cpp
+++ b/ace/OS_NS_stdio.cpp
@@ -1,4 +1,343 @@
// -*- C++ -*-
// $Id$
-// This is a placeholder.
+#include "ace/OS_NS_stdio.h"
+
+ACE_RCSID(ace, OS_NS_stdio, "$Id$")
+
+#if !defined (ACE_HAS_INLINED_OSCALLS)
+# include "ace/OS_NS_stdio.inl"
+#endif /* ACE_HAS_INLINED_OS_CALLS */
+
+void
+ACE_OS::ace_flock_t::dump (void) const
+{
+#if defined (ACE_HAS_DUMP)
+ 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 */
+#endif /* ACE_HAS_DUMP */
+}
+
+/*****************************************************************************/
+
+#if defined (ACE_USES_WCHAR)
+void ACE_OS::checkUnicodeFormat (FILE* fp)
+{
+ if (fp != 0)
+ {
+ // Due to the ACE_TCHAR definition, all default input files, such as
+ // svc.conf, have to be in Unicode format (small endian) on WinCE
+ // because ACE has all 'char' converted into ACE_TCHAR.
+ // However, for TAO, ASCII files, such as IOR file, can still be read
+ // and be written without any error since given buffers are all in 'char'
+ // type instead of ACE_TCHAR. Therefore, it is user's reponsibility to
+ // select correct buffer type.
+
+ // At this point, check if the file is Unicode or not.
+ WORD first_two_bytes;
+ int numRead = ACE_OS::fread(&first_two_bytes, sizeof(WORD), 1, fp);
+
+ if (numRead == 1)
+ {
+ if ((first_two_bytes != 0xFFFE) && // not a small endian Unicode file
+ (first_two_bytes != 0xFEFF)) // not a big endian Unicode file
+ {
+ // set file pointer back to the beginning
+ ACE_OS::fseek(fp, 0, FILE_BEGIN);
+ }
+ }
+ // if it is a Unicode file, file pointer will be right next to the first
+ // two-bytes
+ }
+}
+#endif // ACE_USES_WCHAR
+
+#if 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)
+ {
+# if defined (ACE_HAS_WINCE)
+ FILE *fp = ::_wfdopen (handle, mode);
+ if (fp != 0)
+ {
+ checkUnicodeFormat(fp);
+ return fp;
+ }
+# else
+ hmode &= _O_TEXT | _O_RDONLY | _O_APPEND;
+# if defined (ACE_WIN64)
+ int fd = _open_osfhandle (intptr_t (handle), hmode);
+# else
+ int fd = _open_osfhandle (long (handle), hmode);
+# endif /* ACE_WIN64 */
+ 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 != 0)
+ {
+# if defined (ACE_USES_WCHAR)
+ checkUnicodeFormat(fp);
+# endif // ACE_USES_WCHAR
+ return fp;
+ }
+ _close (fd);
+ }
+# endif // ACE_HAS_WINCE
+
+ ACE_OS::close (handle);
+ }
+ return 0;
+}
+#endif /* ACE_WIN32 */
+
+int
+ACE_OS::fprintf (FILE *fp, const char *format, ...)
+{
+ ACE_OS_TRACE ("ACE_OS::fprintf");
+ int result = 0;
+ va_list ap;
+ va_start (ap, format);
+ ACE_OSCALL (::vfprintf (fp, format, ap), int, -1, result);
+ va_end (ap);
+ return result;
+}
+
+#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 */
+
+char *
+ACE_OS::gets (char *str, int n)
+{
+ ACE_OS_TRACE ("ACE_OS::gets");
+ 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;
+}
+
+// The following *printf functions aren't inline because
+// they use varargs.
+
+int
+ACE_OS::printf (const char *format, ...)
+{
+ ACE_OS_TRACE ("ACE_OS::printf");
+ int result;
+ va_list ap;
+ va_start (ap, format);
+ ACE_OSCALL (::vprintf (format, ap), int, -1, result);
+ va_end (ap);
+ return result;
+}
+
+int
+ACE_OS::snprintf (char *buf, size_t maxlen, const char *format, ...)
+{
+ // ACE_OS_TRACE ("ACE_OS::snprintf");
+#if defined (ACE_HAS_SNPRINTF)
+ int result;
+ va_list ap;
+ va_start (ap, format);
+# if defined (ACE_WIN32)
+ ACE_OSCALL (ACE_SPRINTF_ADAPTER (::_vsnprintf (buf, maxlen, format, ap)),
+ int, -1, result);
+ // Win32 doesn't 0-terminate the string if it overruns maxlen.
+ if (result == -1)
+ buf[maxlen-1] = '\0';
+# else
+ ACE_OSCALL (ACE_SPRINTF_ADAPTER (::vsnprintf (buf, maxlen, format, ap)),
+ int, -1, result);
+# endif /* ACE_WIN32 */
+ va_end (ap);
+ // In out-of-range conditions, C99 defines vsnprintf to return the number
+ // of characters that would have been written if enough space was available.
+ // Earlier variants of the vsnprintf() (e.g. UNIX98) defined it to return
+ // -1. This method follows the C99 standard, but needs to guess at the
+ // value; uses maxlen + 1.
+ if (result == -1)
+ result = ACE_static_cast (int, (maxlen + 1));
+ return result;
+
+#else
+ ACE_UNUSED_ARG (buf);
+ ACE_UNUSED_ARG (maxlen);
+ ACE_UNUSED_ARG (format);
+ ACE_NOTSUP_RETURN (-1);
+#endif /* ACE_HAS_SNPRINTF */
+}
+
+#if defined (ACE_HAS_WCHAR)
+int
+ACE_OS::snprintf (wchar_t *buf, size_t maxlen, const wchar_t *format, ...)
+{
+ // ACE_OS_TRACE ("ACE_OS::snprintf");
+#if (defined (_XOPEN_SOURCE) && (_XOPEN_SOURCE >= 500)) || defined (ACE_WIN32)
+ int result;
+ va_list ap;
+ va_start (ap, format);
+# if defined (ACE_WIN32)
+ // Microsoft's vswprintf() doesn't have the maxlen argument that
+ // XPG4/UNIX98 define. They do, however, recommend use of _vsnwprintf()
+ // as a substitute, which does have the same signature as the UNIX98 one.
+ ACE_OSCALL (ACE_SPRINTF_ADAPTER (::_vsnwprintf (buf, maxlen, format, ap)),
+ int, -1, result);
+ // Win32 doesn't 0-terminate the string if it overruns maxlen.
+ if (result == -1)
+ buf[maxlen-1] = '\0';
+# else
+ ACE_OSCALL (ACE_SPRINTF_ADAPTER (::vswprintf (buf, maxlen, format, ap)),
+ int, -1, result);
+# endif /* ACE_WIN32 */
+ va_end (ap);
+ // In out-of-range conditions, C99 defines vsnprintf to return the number
+ // of characters that would have been written if enough space was available.
+ // Earlier variants of the vsnprintf() (e.g. UNIX98) defined it to return
+ // -1. This method follows the C99 standard, but needs to guess at the
+ // value; uses maxlen + 1.
+ if (result == -1)
+ result = ACE_static_cast (int, (maxlen + 1));
+ return result;
+
+#else
+ ACE_UNUSED_ARG (buf);
+ ACE_UNUSED_ARG (maxlen);
+ ACE_UNUSED_ARG (format);
+ ACE_NOTSUP_RETURN (-1);
+#endif /* ACE_HAS_SNPRINTF */
+}
+#endif /* ACE_HAS_WCHAR */
+
+int
+ACE_OS::sprintf (char *buf, const char *format, ...)
+{
+ // ACE_OS_TRACE ("ACE_OS::sprintf");
+
+ int result;
+ va_list ap;
+ va_start (ap, format);
+ ACE_OSCALL (ACE_SPRINTF_ADAPTER (::vsprintf (buf, format, ap)), int, -1, result);
+ 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 (_XOPEN_SOURCE) && (_XOPEN_SOURCE >= 500)
+
+ // The XPG4/UNIX98/C99 signature of the wide-char sprintf has a
+ // maxlen argument. Since this method doesn't supply one, pass in
+ // the max possible length. If this isn't ok, use ACE_OS::snprintf().
+ int result;
+ va_list ap;
+ va_start (ap, format);
+ ACE_OSCALL (::vswprintf (buf, ULONG_MAX, format, ap), int, -1, result);
+ va_end (ap);
+ return result;
+
+# elif defined (ACE_WIN32)
+ // Windows has vswprintf, but the signature is from the older ISO C
+ // standard. Also see ACE_OS::snprintf() for more info on this.
+
+ 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 */
diff --git a/ace/OS_NS_stdio.h b/ace/OS_NS_stdio.h
index fc532b41367..4081276f862 100644
--- a/ace/OS_NS_stdio.h
+++ b/ace/OS_NS_stdio.h
@@ -1,4 +1,307 @@
// -*- C++ -*-
-// $Id$
-// This is a placeholder.
+//=============================================================================
+/**
+ * @file OS_NS_stdio.h
+ *
+ * $Id$
+ *
+ * @author Douglas C. Schmidt <schmidt@cs.wustl.edu>
+ * @author Jesper S. M|ller<stophph@diku.dk>
+ * @author and a cast of thousands...
+ *
+ * Originally in OS.h.
+ */
+//=============================================================================
+
+#ifndef ACE_OS_NS_STDIO_H
+# define ACE_OS_NS_STDIO_H
+
+# include /**/ "ace/pre.h"
+
+# include "ace/config-all.h"
+
+# if !defined (ACE_LACKS_PRAGMA_ONCE)
+# pragma once
+# endif /* ACE_LACKS_PRAGMA_ONCE */
+
+#include "ace/os_include/os_stdio.h"
+#include "ace/os_include/os_fcntl.h"
+#include "ace/OS_Export.h"
+
+/**
+ * On some platforms clearerr is a macro. Defining ACE_OS::clearerr()
+ * becomes really hard, as there is no way to save the macro
+ * definition using the pre-processor.
+ */
+# if !defined (ACE_LACKS_CLEARERR)
+# if defined (clearerr)
+# define __ace_clearerr_hack
+inline void __ace_clearerr(FILE *stream)
+{
+ clearerr(stream);
+}
+# undef clearerr
+# endif /* defined (clearerr) */
+# endif /* !ACE_LACKS_CLEARERR */
+
+/// 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 (ACE_LACKS_FILELOCKS)
+# if ! defined (VXWORKS) && ! defined (ACE_PSOS) && ! defined (__rtems__) && !defined (INTEGRITY)
+// 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 */
+
+namespace ACE_OS {
+
+ /**
+ * @class ace_flock_t
+ *
+ * @brief OS file locking structure.
+ */
+ class ACE_OS_Export 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_USES_WCHAR)
+ // If fp points to the Unicode format file, the file pointer will be moved right next
+ // to the Unicode header (2 types). Otherwise, file pointer will be at the beginning.
+ void checkUnicodeFormat (FILE* fp);
+# endif // ACE_USES_WCHAR
+
+# if !defined (ACE_LACKS_CLEARERR)
+ void clearerr (FILE* fp);
+# endif /* !ACE_LACKS_CLEARERR */
+
+ //@{ @name Wrappers to obtain the current user id
+ // Legacy as per SUSV3
+# if !defined (ACE_LACKS_CUSERID)
+# if defined(cuserid)
+# undef cuserid
+# endif /* cuserid */
+
+ char *cuserid (char *user,
+ size_t maxlen = ACE_MAX_USERID);
+
+# if defined (ACE_HAS_WCHAR)
+ wchar_t *cuserid (wchar_t *user,
+ size_t maxlen = ACE_MAX_USERID);
+# endif /* ACE_HAS_WCHAR */
+# endif /* ACE_LACKS_CUSERID */
+ //@}
+
+ int fclose (FILE *fp);
+
+# if defined (fdopen)
+# undef fdopen
+# endif /* fdopen */
+
+ FILE *fdopen (ACE_HANDLE handle, const ACE_TCHAR *mode);
+
+ int fflush (FILE *fp);
+
+ int fgetc (FILE* fp);
+
+ int fgetpos (FILE* fp, fpos_t* pos);
+
+ ACE_TCHAR *fgets (ACE_TCHAR *buf, int size, FILE *fp);
+
+ //@{ @name A set of wrappers for file locks.
+
+# if defined (ACE_WIN32)
+ void flock_adjust_params (ace_flock_t *lock,
+ short whence,
+ off_t &start,
+ off_t &len);
+# endif /* ACE_WIN32 */
+
+ int flock_init (ace_flock_t *lock,
+ int flags = 0,
+ const ACE_TCHAR *name = 0,
+ mode_t perms = 0);
+
+ int flock_destroy (ace_flock_t *lock,
+ int unlink_file = 1);
+
+ int flock_rdlock (ace_flock_t *lock,
+ short whence = 0,
+ off_t start = 0,
+ off_t len = 0);
+
+ int flock_tryrdlock (ace_flock_t *lock,
+ short whence = 0,
+ off_t start = 0,
+ off_t len = 0);
+
+ int flock_trywrlock (ace_flock_t *lock,
+ short whence = 0,
+ off_t start = 0,
+ off_t len = 0);
+
+ int flock_unlock (ace_flock_t *lock,
+ short whence = 0,
+ off_t start = 0,
+ off_t len = 0);
+
+ int flock_wrlock (ace_flock_t *lock,
+ short whence = 0,
+ off_t start = 0,
+ off_t len = 0);
+
+ //@}
+
+ FILE *fopen (const ACE_TCHAR *filename, const ACE_TCHAR *mode);
+
+# if defined (ACE_WIN32)
+
+ /// Translate fopen's mode char to open's mode. This helper function
+ /// is here to avoid maintaining several pieces of identical code.
+ void fopen_mode_to_open_mode_converter (ACE_TCHAR x, int &hmode);
+
+ OSVERSIONINFO win32_versioninfo_;
+
+ HINSTANCE win32_resource_module_;
+
+# endif /* ACE_WIN32 */
+
+ int fprintf (FILE *fp, const char *format, ...);
+
+# if defined (ACE_HAS_WCHAR)
+ int fprintf (FILE *fp, const wchar_t *format, ...);
+# endif /* ACE_HAS_WCHAR */
+
+ int fputs (const ACE_TCHAR *s,
+ FILE *stream);
+
+ size_t fread (void *ptr,
+ size_t size,
+ size_t nelems,
+ FILE *fp);
+
+ FILE *freopen (const ACE_TCHAR *filename,
+ const ACE_TCHAR *mode,
+ FILE* stream);
+
+ int fseek (FILE *fp,
+ long offset,
+ int ptrname);
+
+ int fsetpos (FILE* fp, fpos_t* pos);
+
+ long ftell (FILE* fp);
+
+ size_t fwrite (const void *ptr,
+ size_t size,
+ size_t nitems,
+ FILE *fp);
+
+ // 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
+ char *gets (char *str, int n = 0);
+
+ void perror (const ACE_TCHAR *s);
+
+ int printf (const char *format, ...);
+
+ int puts (const ACE_TCHAR *s);
+
+ int rename (const ACE_TCHAR *old_name,
+ const ACE_TCHAR *new_name,
+ int flags = -1);
+
+ void rewind (FILE *fp);
+
+ int snprintf (char *buf, size_t maxlen, const char *format, ...);
+
+# if defined (ACE_HAS_WCHAR)
+ int snprintf (wchar_t *buf, size_t maxlen, const wchar_t *format,...);
+# endif /* ACE_HAS_WCHAR */
+
+ int sprintf (char *buf, const char *format, ...);
+
+# if defined (ACE_HAS_WCHAR)
+ int sprintf (wchar_t *buf, const wchar_t *format, ...);
+# endif /* ACE_HAS_WCHAR */
+
+ ACE_TCHAR *tempnam (const ACE_TCHAR *dir = 0,
+ const ACE_TCHAR *pfx = 0);
+
+ int vsprintf (char *buffer, const char *format, va_list argptr);
+
+# if defined (ACE_HAS_WCHAR)
+ int vsprintf (wchar_t *buffer, const wchar_t *format, va_list argptr);
+# endif /* ACE_HAS_WCHAR */
+
+} /* namespace ACE_OS */
+
+# if defined (ACE_HAS_INLINED_OSCALLS)
+# if defined (ACE_INLINE)
+# undef ACE_INLINE
+# endif /* ACE_INLINE */
+# define ACE_INLINE inline
+# include "ace/OS_NS_stdio.inl"
+# endif /* ACE_HAS_INLINED_OSCALLS */
+
+# include /**/ "ace/post.h"
+#endif /* ACE_OS_NS_STDIO_H */
diff --git a/ace/OS_NS_stdio.inl b/ace/OS_NS_stdio.inl
index fc532b41367..233c1f8778b 100644
--- a/ace/OS_NS_stdio.inl
+++ b/ace/OS_NS_stdio.inl
@@ -1,4 +1,929 @@
// -*- C++ -*-
// $Id$
-// This is a placeholder.
+#include "ace/OS_NS_unistd.h"
+#include "ace/OS_NS_stdlib.h"
+#include "ace/OS_NS_fcntl.h"
+#include "ace/OS_NS_errno.h"
+#include "ace/OS_NS_string.h"
+#include "ace/OS_NS_pwd.h"
+
+#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) */
+
+/*****************************************************************************/
+
+#if defined (ACE_WIN32)
+ACE_INLINE void
+ACE_OS::flock_adjust_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_, 0);
+ break;
+ }
+ lock->overlapped_.Offset = start;
+ if (len == 0)
+ len = ::GetFileSize (lock->handle_,
+ 0) - start;
+}
+#endif /* ACE_WIN32 */
+
+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 = 0;
+#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 */
+}
+
+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::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::flock_adjust_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_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::flock_adjust_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_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::flock_adjust_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_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::flock_adjust_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_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::flock_adjust_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 */
+}
+
+#if defined (ACE_WIN32)
+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 */
+
+#if !defined (ACE_LACKS_CLEARERR)
+ACE_INLINE void
+ACE_OS::clearerr (FILE* fp)
+{
+#if defined (__ace_clearerr_hack)
+ __ace_clearerr(fp);
+#else
+ ::clearerr(fp);
+#endif /* __ace_clearerr_hack */
+}
+#endif /* !ACE_LACKS_CLEARERR */
+
+#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::strlen (pw->pw_name) <= max_length)
+ {
+ return ACE_OS::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::fclose (FILE *fp)
+{
+ ACE_OS_TRACE ("ACE_OS::fclose");
+ ACE_OSCALL_RETURN (::fclose (fp), int, -1);
+}
+
+ACE_INLINE FILE *
+ACE_OS::fdopen (ACE_HANDLE handle, const ACE_TCHAR *mode)
+{
+ ACE_OS_TRACE ("ACE_OS::fdopen");
+# if defined (ACE_HAS_WINCE)
+ ACE_OSCALL_RETURN (::_wfdopen (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;
+
+# if defined (ACE_WIN64)
+ int crt_handle = ::_open_osfhandle (intptr_t (handle), 0);
+# else
+ int crt_handle = ::_open_osfhandle (long (handle), 0);
+# endif /* ACE_WIN64 */
+
+ 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_WINCE */
+}
+
+ACE_INLINE int
+ACE_OS::fflush (FILE *fp)
+{
+ ACE_OS_TRACE ("ACE_OS::fflush");
+#if defined (VXWORKS)
+ if (fp == 0)
+ {
+ // Do not allow fflush(0) on VxWorks
+ return 0;
+ }
+#endif /* VXWORKS */
+
+ ACE_OSCALL_RETURN (::fflush (fp), int, -1);
+}
+
+ACE_INLINE int
+ACE_OS::fgetc (FILE* fp)
+{
+ ACE_OSCALL_RETURN (::fgetc (fp), int, -1);
+}
+
+ACE_INLINE int
+ACE_OS::fgetpos (FILE* fp, fpos_t* pos)
+{
+ ACE_OSCALL_RETURN (::fgetpos (fp, pos), int, -1);
+}
+
+ACE_INLINE ACE_TCHAR *
+ACE_OS::fgets (ACE_TCHAR *buf, int size, FILE *fp)
+{
+ ACE_OS_TRACE ("ACE_OS::fgets");
+#if 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_WIN32 && ACE_USES_WCHAR */
+}
+
+#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)
+{
+ ACE_OS_TRACE ("ACE_OS::fopen");
+ ACE_OSCALL_RETURN (::fopen (filename, mode), FILE *, 0);
+}
+#endif /* ACE_WIN32 */
+
+ACE_INLINE int
+ACE_OS::fputs (const ACE_TCHAR *s, FILE *stream)
+{
+ ACE_OS_TRACE ("ACE_OS::fputs");
+#if 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_WIN32 && ACE_USES_WCHAR */
+}
+
+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_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_LACKS_POSIX_PROTOTYPES */
+}
+
+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_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 /* ACE_WIN32 && ACE_USES_WCHAR */
+}
+
+ACE_INLINE int
+ACE_OS::fseek (FILE *fp, long offset, int whence)
+{
+# 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);
+}
+
+ACE_INLINE int
+ACE_OS::fsetpos (FILE* fp, fpos_t* pos)
+{
+ ACE_OSCALL_RETURN (::fsetpos (fp, pos), int, -1);
+}
+
+ACE_INLINE long
+ACE_OS::ftell (FILE* fp)
+{
+ ACE_OSCALL_RETURN (::ftell (fp), long, -1);
+}
+
+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_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_LACKS_POSIX_PROTOTYPES */
+}
+
+#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 void
+ACE_OS::perror (const ACE_TCHAR *s)
+{
+ ACE_OS_TRACE ("ACE_OS::perror");
+#if 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_WINCE */
+}
+
+ACE_INLINE int
+ACE_OS::puts (const ACE_TCHAR *s)
+{
+ ACE_OS_TRACE ("ACE_OS::puts");
+#if 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_WIN32 && ACE_USES_WCHAR */
+}
+
+ACE_INLINE int
+ACE_OS::rename (const ACE_TCHAR *old_name,
+ const ACE_TCHAR *new_name,
+ int flags)
+{
+# if defined (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_LACKS_RENAME */
+}
+
+ACE_INLINE void
+ACE_OS::rewind (FILE *fp)
+{
+#if !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_WINCE */
+}
+
+ACE_INLINE ACE_TCHAR *
+ACE_OS::tempnam (const ACE_TCHAR *dir, const ACE_TCHAR *pfx)
+{
+ ACE_OS_TRACE ("ACE_OS::tempnam");
+#if 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 (ACE_WIN32) && ((defined (__BORLANDC__) && !defined(ACE_USES_WCHAR)) || defined (__IBMCPP__)))
+ ACE_OSCALL_RETURN (::_tempnam ((char *) dir, (char *) pfx), char *, 0);
+#elif defined(ACE_WIN32) && 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 /* ACE_HAS_WINCE || ACE_LACKS_TEMPNAM */
+ ACE_OSCALL_RETURN (::tempnam (dir, pfx), char *, 0);
+#endif /* VXWORKS */
+}
+
+ACE_INLINE int
+ACE_OS::vsprintf (char *buffer, const char *format, va_list argptr)
+{
+ return ACE_SPRINTF_ADAPTER (::vsprintf (buffer, format, argptr));
+}
+
+#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 */
diff --git a/ace/OS_NS_stdlib.cpp b/ace/OS_NS_stdlib.cpp
index fc532b41367..09aafb817f2 100644
--- a/ace/OS_NS_stdlib.cpp
+++ b/ace/OS_NS_stdlib.cpp
@@ -1,4 +1,400 @@
// -*- C++ -*-
// $Id$
-// This is a placeholder.
+#include "ace/OS_NS_stdlib.h"
+
+ACE_RCSID(ace, OS_NS_stdlib, "$Id$")
+
+#if !defined (ACE_HAS_INLINED_OSCALLS)
+# include "ace/OS_NS_stdlib.inl"
+#endif /* ACE_HAS_INLINED_OS_CALLS */
+
+ACE_EXIT_HOOK ACE_OS::exit_hook_ = 0;
+
+void *
+ACE_OS::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 */
+}
+
+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 */
+}
+
+void
+ACE_OS::free (void *ptr)
+{
+ ACE_FREE_FUNC (ACE_MALLOC_T (ptr));
+}
+
+// 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_ITOA)
+char *
+ACE_OS::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;
+ ++e; // Don't overwrite the negative sign.
+ value = -value; // Drop negative sign so character selection is correct.
+ }
+
+ // 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::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 */
+
+void *
+ACE_OS::malloc (size_t nbytes)
+{
+ return ACE_MALLOC_FUNC (nbytes);
+}
+
+#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 */
+
+void *
+ACE_OS::realloc (void *ptr, size_t nbytes)
+{
+ return ACE_REALLOC_FUNC (ACE_MALLOC_T (ptr), nbytes);
+}
+
+#if defined (ACE_LACKS_STRTOL)
+long
+ACE_OS::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::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 */
+
diff --git a/ace/OS_NS_stdlib.h b/ace/OS_NS_stdlib.h
index fc532b41367..6ebc1d75c99 100644
--- a/ace/OS_NS_stdlib.h
+++ b/ace/OS_NS_stdlib.h
@@ -1,4 +1,193 @@
// -*- C++ -*-
-// $Id$
-// This is a placeholder.
+//=============================================================================
+/**
+ * @file OS_NS_stdlib.h
+ *
+ * $Id$
+ *
+ * @author Douglas C. Schmidt <schmidt@cs.wustl.edu>
+ * @author Jesper S. M|ller<stophph@diku.dk>
+ * @author and a cast of thousands...
+ *
+ * Originally in OS.h.
+ */
+//=============================================================================
+
+#ifndef ACE_OS_NS_STDLIB_H
+# define ACE_OS_NS_STDLIB_H
+
+# include /**/ "ace/pre.h"
+
+# include "ace/config-all.h"
+
+# if !defined (ACE_LACKS_PRAGMA_ONCE)
+# pragma once
+# endif /* ACE_LACKS_PRAGMA_ONCE */
+
+#include "ace/os_include/os_stdlib.h"
+
+# if defined (ACE_HAS_BROKEN_R_ROUTINES)
+# undef rand_r
+# endif /* ACE_HAS_BROKEN_R_ROUTINES */
+
+// We need this for MVS... as well as Linux, etc...
+extern "C" {
+ typedef int (*ACE_COMPARE_FUNC)(const void *, const void *);
+}
+
+namespace ACE_OS {
+
+ /** @name Non-standard functions
+ *
+ * These functions aren't in the standard.
+ *
+ */
+ //@{
+
+
+ void _exit (int status = 0);
+
+ void abort (void);
+
+ int atexit (ACE_EXIT_HOOK func);
+
+ int atoi (const char *s);
+
+# if defined (ACE_HAS_WCHAR)
+ int atoi (const wchar_t *s);
+# endif /* ACE_HAS_WCHAR */
+
+ // atop not in spec
+# if defined (atop)
+# undef atop
+# endif /* atop */
+
+ void *atop (const char *s);
+
+# if defined (ACE_HAS_WCHAR)
+ void *atop (const wchar_t *s);
+# endif /* ACE_HAS_WCHAR */
+
+ void *bsearch (const void *key,
+ const void *base,
+ size_t nel,
+ size_t size,
+ ACE_COMPARE_FUNC);
+
+ void *calloc (size_t elements, size_t sizeof_elements);
+
+ void exit (int status = 0);
+
+ void free (void *);
+
+ char *getenv (const char *symbol);
+
+# if defined (ACE_HAS_WCHAR) && defined (ACE_WIN32)
+ wchar_t *getenv (const wchar_t *symbol);
+# endif /* ACE_HAS_WCHAR && ACE_WIN32 */
+
+ // not in spec
+ ACE_TCHAR *getenvstrings (void);
+
+ // itoa not in spec
+ /// Converts an integer to a string.
+ char *itoa (int value, char *string, int radix);
+
+#if defined (ACE_HAS_WCHAR)
+ /// Converts an integer to a string.
+ wchar_t *itoa (int value, wchar_t *string, int radix);
+#endif /* ACE_HAS_WCHAR */
+
+#if !defined (ACE_HAS_ITOA)
+ /// Emulated itoa - Converts an integer to a string.
+ 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.
+ wchar_t *itow_emulation (int value, wchar_t *string, int radix);
+#endif /* ACE_HAS_WCHAR && ACE_LACKS_ITOW */
+
+ void *malloc (size_t);
+
+ ACE_HANDLE mkstemp (ACE_TCHAR *t);
+
+ ACE_TCHAR *mktemp (ACE_TCHAR *t);
+
+ int putenv (const ACE_TCHAR *string);
+
+ void qsort (void *base,
+ size_t nel,
+ size_t width,
+ ACE_COMPARE_FUNC);
+
+ int rand (void);
+
+ int rand_r (ACE_RANDR_TYPE &seed);
+
+ void *realloc (void *, size_t);
+
+ // exit_hook and set_exit_hook not in spec
+ /// Function that is called by <ACE_OS::exit>, if non-null.
+ extern ACE_EXIT_HOOK exit_hook_;
+
+ /// For use by ACE_Object_Manager only, to register its exit hook..
+ ACE_EXIT_HOOK set_exit_hook (ACE_EXIT_HOOK hook);
+
+ void srand (u_int seed);
+
+ // not in spec
+ ACE_TCHAR *strenvdup (const ACE_TCHAR *str);
+
+#if !defined (ACE_LACKS_STRTOD)
+ /// Converts a string to a double value (char version).
+ 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).
+ 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).
+ 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).
+ long strtol (const wchar_t *s, wchar_t **ptr, int base);
+#endif /* ACE_HAS_WCHAR && !ACE_LACKS_WCSTOL */
+
+#if defined (ACE_LACKS_STRTOL)
+ long strtol_emulation (const char *nptr, char **endptr, int base);
+#endif /* ACE_LACKS_STRTOL */
+
+ /// Converts a string to an unsigned long value (char version).
+ 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).
+ unsigned long strtoul (const wchar_t *s, wchar_t **ptr, int base);
+#endif /* ACE_HAS_WCHAR && !ACE_LACKS_WCSTOUL */
+
+#if defined (ACE_LACKS_STRTOUL)
+ unsigned long strtoul_emulation (const char *nptr,
+ char **endptr,
+ int base);
+#endif /* ACE_LACKS_STRTOUL */
+
+ int system (const ACE_TCHAR *s);
+
+
+} /* namespace ACE_OS */
+
+# if defined (ACE_HAS_INLINED_OSCALLS)
+# if defined (ACE_INLINE)
+# undef ACE_INLINE
+# endif /* ACE_INLINE */
+# define ACE_INLINE inline
+# include "ace/OS_NS_stdlib.inl"
+# endif /* ACE_HAS_INLINED_OSCALLS */
+
+# include /**/ "ace/post.h"
+#endif /* ACE_OS_NS_STDLIB_H */
diff --git a/ace/OS_NS_stdlib.inl b/ace/OS_NS_stdlib.inl
index fc532b41367..c22b3723fc1 100644
--- a/ace/OS_NS_stdlib.inl
+++ b/ace/OS_NS_stdlib.inl
@@ -1,4 +1,391 @@
// -*- C++ -*-
// $Id$
-// This is a placeholder.
+#include "ace/Object_Manager.h"
+
+// 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 (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 /* VXWORKS */
+}
+
+ACE_INLINE void
+ACE_OS::abort (void)
+{
+#if !defined (ACE_HAS_WINCE)
+ ::abort ();
+#else
+ // @@ CE doesn't support abort?
+ exit (1);
+#endif /* !ACE_HAS_WINCE */
+}
+
+ACE_INLINE int
+ACE_OS::atexit (ACE_EXIT_HOOK func)
+{
+ return ACE_OS_Object_Manager::instance ()->at_exit (func);
+}
+
+ACE_INLINE int
+ACE_OS::atoi (const char *s)
+{
+ ACE_OSCALL_RETURN (::atoi (s), int, -1);
+}
+
+#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 void *
+ACE_OS::atop (const char *s)
+{
+ ACE_TRACE ("ACE_OS::atop");
+ // It would be nice to make use of Basic_Types.h here, but that
+ // file relies on OS.h. Fortunately, most platforms have int
+ // the same as pointer size (IA32, IA64), with Win64 being the
+ // exception.
+#if defined (ACE_WIN64)
+ __int64 ip = ::_atoi64 (s);
+#else
+ int ip = ::atoi (s);
+#endif /* ACE_WIN64 */
+ void *p = ACE_reinterpret_cast (void *, ip);
+ return p;
+}
+
+#if defined (ACE_HAS_WCHAR)
+ACE_INLINE void *
+ACE_OS::atop (const wchar_t *s)
+{
+# if defined (ACE_WIN64)
+ __int64 ip = ::_wtoi64 (s);
+# else
+ int ip = ACE_OS::atoi (s);
+# endif /* ACE_WIN64 */
+ void *p = ACE_reinterpret_cast (void *, ip);
+ return p;
+}
+#endif /* ACE_HAS_WCHAR */
+
+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_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 (0);
+#endif /* ACE_LACKS_BSEARCH */
+}
+
+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_PSOS)
+ ACE_UNUSED_ARG (symbol);
+ ACE_NOTSUP_RETURN (0);
+#else /* ACE_PSOS */
+ ACE_OSCALL_RETURN (::getenv (symbol), char *, 0);
+#endif /* ACE_LACKS_ENV */
+}
+
+#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 char *
+ACE_OS::itoa (int value, char *string, int radix)
+{
+#if !defined (ACE_HAS_ITOA)
+ return ACE_OS::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::itoa (int value, wchar_t *string, int radix)
+{
+#if defined (ACE_LACKS_ITOW)
+ return ACE_OS::itow_emulation (value, string, radix);
+#else /* ACE_LACKS_ITOW */
+ return ::_itow (value, string, radix);
+#endif /* ACE_LACKS_ITOW */
+}
+#endif /* ACE_HAS_WCHAR */
+
+#if !defined (ACE_LACKS_MKSTEMP)
+ACE_INLINE ACE_HANDLE
+ACE_OS::mkstemp (ACE_TCHAR *s)
+{
+ return ::mkstemp (s);
+}
+#endif /* !ACE_LACKS_MKSTEMP */
+
+#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(INTEGRITY)
+extern "C" {
+ int putenv(char *string);
+}
+#endif
+
+ACE_INLINE int
+ACE_OS::putenv (const ACE_TCHAR *string)
+{
+ ACE_OS_TRACE ("ACE_OS::putenv");
+#if 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_LACKS_ENV)
+ ACE_UNUSED_ARG (string);
+ ACE_NOTSUP_RETURN (0);
+#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 void
+ACE_OS::qsort (void *base,
+ size_t nel,
+ size_t width,
+ ACE_COMPARE_FUNC compar)
+{
+#if !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_LACKS_QSORT */
+}
+
+ACE_INLINE int
+ACE_OS::rand (void)
+{
+ ACE_OS_TRACE ("ACE_OS::rand");
+ ACE_OSCALL_RETURN (::rand (), int, -1);
+}
+
+#if !defined (ACE_WIN32)
+
+ACE_INLINE int
+ACE_OS::rand_r (ACE_RANDR_TYPE &seed)
+{
+ ACE_OS_TRACE ("ACE_OS::rand_r");
+# if 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_REENTRANT_FUNCTIONS */
+}
+
+#else /* ACE_WIN32 */
+
+ACE_INLINE int
+ACE_OS::rand_r (ACE_RANDR_TYPE& seed)
+{
+ ACE_OS_TRACE ("ACE_OS::rand_r");
+
+ long new_seed = (long)(seed);
+ if (new_seed == 0)
+ new_seed = 0x12345987;
+ long temp = new_seed / 127773;
+ new_seed = 16807 * (new_seed - temp * 127773) - 2836 * temp;
+ if (new_seed < 0)
+ new_seed += 2147483647;
+ (seed) = (unsigned int)new_seed;
+ return (int)(new_seed & RAND_MAX);
+}
+
+#endif /* !ACE_WIN32 */
+
+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 void
+ACE_OS::srand (u_int seed)
+{
+ ACE_OS_TRACE ("ACE_OS::srand");
+ ::srand (seed);
+}
+
+// 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_HAS_WINCE)
+ // WinCE doesn't have environment variables so we just skip it.
+ return ACE_OS::strdup (str);
+#elif defined (ACE_LACKS_ENV)
+ ACE_UNUSED_ARG (str);
+ ACE_NOTSUP_RETURN (0);
+#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 */
+}
+
+#if !defined (ACE_LACKS_STRTOD)
+ACE_INLINE double
+ACE_OS::strtod (const char *s, char **endptr)
+{
+ return ::strtod (s, endptr);
+}
+#endif /* !ACE_LACKS_STRTOD */
+
+#if defined (ACE_HAS_WCHAR) && !defined (ACE_LACKS_WCSTOD)
+ACE_INLINE double
+ACE_OS::strtod (const wchar_t *s, wchar_t **endptr)
+{
+ return ::wcstod (s, endptr);
+}
+#endif /* ACE_HAS_WCHAR && !ACE_LACKS_WCSTOD */
+
+ACE_INLINE long
+ACE_OS::strtol (const char *s, char **ptr, int base)
+{
+#if defined (ACE_LACKS_STRTOL)
+ return ACE_OS::strtol_emulation (s, ptr, base);
+#else /* ACE_LACKS_STRTOL */
+ return ::strtol (s, ptr, base);
+#endif /* ACE_LACKS_STRTOL */
+}
+
+#if defined (ACE_HAS_WCHAR) && !defined (ACE_LACKS_WCSTOL)
+ACE_INLINE long
+ACE_OS::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::strtoul (const char *s, char **ptr, int base)
+{
+#if defined (ACE_LACKS_STRTOUL)
+ return ACE_OS::strtoul_emulation (s, ptr, base);
+#else /* ACE_LACKS_STRTOUL */
+ return ::strtoul (s, ptr, base);
+#endif /* ACE_LACKS_STRTOUL */
+}
+
+#if defined (ACE_HAS_WCHAR) && !defined (ACE_LACKS_WCSTOUL)
+ACE_INLINE unsigned long
+ACE_OS::strtoul (const wchar_t *s, wchar_t **ptr, int base)
+{
+ return ::wcstoul (s, ptr, base);
+}
+#endif /* ACE_HAS_WCHAR && !ACE_LACKS_WCSTOUL */
+
+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 */
+}
+
diff --git a/ace/OS_NS_string.cpp b/ace/OS_NS_string.cpp
index fc532b41367..f3317fc69b4 100644
--- a/ace/OS_NS_string.cpp
+++ b/ace/OS_NS_string.cpp
@@ -1,4 +1,389 @@
// -*- C++ -*-
// $Id$
-// This is a placeholder.
+#include "ace/OS_NS_string.h"
+
+ACE_RCSID(ace, OS_NS_string, "$Id$")
+
+#if !defined (ACE_HAS_INLINED_OSCALLS)
+# include "ace/OS_NS_string.inl"
+#endif /* ACE_HAS_INLINED_OS_CALLS */
+
+#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 (ACE_HAS_MEMCHR)
+const void *
+ACE_OS::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_LACKS_STRCHR)
+char *
+ACE_OS::strchr_emulation (char *s, int c)
+{
+ for (;;++s)
+ {
+ if (*s == c)
+ return s;
+ if (*s == 0)
+ return 0;
+ }
+}
+
+const char *
+ACE_OS::strchr_emulation (const char *s, int c)
+{
+ for (;;++s)
+ {
+ if (*s == c)
+ return s;
+ if (*s == 0)
+ return 0;
+ }
+}
+#endif /* ACE_LACKS_STRCHR */
+
+#if defined (ACE_LACKS_STRCSPN)
+size_t
+ACE_OS::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 */
+
+char *
+ACE_OS::strdup (const char *s)
+{
+#if defined (ACE_HAS_STRDUP_EMULATION)
+ char *t = (char *) ACE_OS::malloc (ACE_OS::strlen (s) + 1);
+ if (t == 0)
+ return 0;
+
+ return ACE_OS::strcpy (t, s);
+#else
+ return ::strdup (s);
+#endif /* ACE_HAS_STRDUP_EMULATION */
+}
+
+#if defined (ACE_HAS_WCHAR)
+wchar_t *
+ACE_OS::strdup (const wchar_t *s)
+{
+# if defined (ACE_LACKS_WCSDUP)
+ wchar_t *buffer =
+ (wchar_t *) ACE_OS::malloc ((ACE_OS::strlen (s) + 1)
+ * sizeof (wchar_t));
+ if (buffer == 0)
+ return 0;
+
+ return ACE_OS::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 */
+
+char *
+ACE_OS::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::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_STRERROR)
+/**
+ * Just returns "Unknown Error" all the time.
+ */
+char *
+ACE_OS::strerror_emulation (int errnum)
+{
+ return "Unknown Error";
+}
+#endif /* ACE_LACKS_STRERROR */
+
+const char *
+ACE_OS::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::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;
+}
+
+const char *
+ACE_OS::strnstr (const char *s1, const char *s2, size_t len2)
+{
+ // Substring length
+ size_t len1 = ACE_OS::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::memcmp (s1 + i, s2, len2) == 0)
+ // Found a match! Return the index.
+ return s1 + i;
+ }
+
+ return 0;
+}
+
+const ACE_WCHAR_T *
+ACE_OS::strnstr (const ACE_WCHAR_T *s1, const ACE_WCHAR_T *s2, size_t len2)
+{
+ // Substring length
+ size_t len1 = ACE_OS::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::memcmp (s1 + i, s2, len2 * sizeof (ACE_WCHAR_T)) == 0)
+ // Found a match! Return the index.
+ return s1 + i;
+ }
+
+ return 0;
+}
+
+#if defined (ACE_LACKS_STRPBRK)
+char *
+ACE_OS::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 0;
+}
+#endif /* ACE_LACKS_STRPBRK */
+
+#if defined (ACE_LACKS_STRRCHR)
+char *
+ACE_OS::strrchr_emulation (char *s, int c)
+{
+ char *p = s + ACE_OS::strlen (s);
+
+ while (*p != c)
+ if (p == s)
+ return 0;
+ else
+ p--;
+
+ return p;
+}
+
+const char *
+ACE_OS::strrchr_emulation (const char *s, int c)
+{
+ const char *p = s + ACE_OS::strlen (s);
+
+ while (*p != c)
+ if (p == s)
+ return 0;
+ else
+ p--;
+
+ return p;
+}
+#endif /* ACE_LACKS_STRRCHR */
+
+char *
+ACE_OS::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)
+ {
+ if (rdst!=rsrc)
+ {
+ *rdst = '\0';
+ if (rsrc != 0)
+ strncat (rdst, rsrc, --rmaxlen);
+ }
+ else
+ {
+ rdst += (rmaxlen - 1);
+ *rdst = '\0';
+ }
+ }
+ return dst;
+}
+
+ACE_WCHAR_T *
+ACE_OS::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)
+ {
+ if (rdst!=rsrc)
+ {
+ *rdst = ACE_TEXT_WIDE ('\0');
+ if (rsrc != 0)
+ strncat (rdst, rsrc, --rmaxlen);
+ }
+ else
+ {
+ rdst += (rmaxlen - 1);
+ *rdst = ACE_TEXT_WIDE ('\0');
+ }
+ }
+ return dst;
+}
+
+#if defined (ACE_LACKS_STRSPN)
+size_t
+ACE_OS::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_REENTRANT_FUNCTIONS)
+char *
+ACE_OS::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;
+ size_t l_org = ACE_OS::strlen (s);
+ s = ::strtok (s, tokens);
+ if (s == 0)
+ return 0;
+ size_t l_sub = ACE_OS::strlen (s);
+ if (s + l_sub < *lasts + l_org)
+ *lasts = s + l_sub + 1;
+ else
+ *lasts = s + l_sub;
+ return s ;
+}
+#endif /* !ACE_HAS_REENTRANT_FUNCTIONS */
+
+# if defined (ACE_HAS_WCHAR) && defined (ACE_LACKS_WCSTOK)
+wchar_t*
+ACE_OS::strtok_r_emulation (ACE_WCHAR_T *s,
+ const ACE_WCHAR_T *tokens,
+ ACE_WCHAR_T **lasts)
+{
+ if (s == 0)
+ s = *lasts;
+ else
+ *lasts = s;
+ if (*s == 0) // We have reached the end
+ return 0;
+ int l_org = ACE_OS::strlen (s);
+ s = ACE_OS::strtok (s, tokens);
+ if (s == 0)
+ return 0;
+ int l_sub = ACE_OS::strlen (s);
+ if (s + l_sub < *lasts + l_org)
+ *lasts = s + l_sub + 1;
+ else
+ *lasts = s + l_sub;
+ return s ;
+}
+# endif /* ACE_HAS_WCHAR && ACE_LACKS_WCSTOK */
+
diff --git a/ace/OS_NS_string.h b/ace/OS_NS_string.h
index fc532b41367..0de70d023fe 100644
--- a/ace/OS_NS_string.h
+++ b/ace/OS_NS_string.h
@@ -1,4 +1,402 @@
// -*- C++ -*-
-// $Id$
-// This is a placeholder.
+//=============================================================================
+/**
+ * @file OS_NS_string.h
+ *
+ * $Id$
+ *
+ * @author Douglas C. Schmidt <schmidt@cs.wustl.edu>
+ * @author Jesper S. M|ller<stophph@diku.dk>
+ * @author and a cast of thousands...
+ *
+ * Originally in OS.h.
+ */
+//=============================================================================
+
+#ifndef ACE_OS_NS_STRING_H
+# define ACE_OS_NS_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 "ace/os_include/os_string.h"
+#include "ace/Basic_Types.h" // to get ACE_WCHAR_T,
+ // should be in os_stddef.h or not used like this.
+
+class ACE_Time_Value;
+
+# if defined (ACE_LACKS_SYS_NERR)
+extern ACE_OS_Export int sys_nerr;
+# endif /* ACE_LACKS_SYS_NERR */
+
+namespace ACE_OS {
+
+ /** @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).
+ const void *memchr (const void *s, int c, size_t len);
+
+ /// Finds characters in a buffer (void version).
+ void *memchr (void *s, int c, size_t len);
+
+#if !defined (ACE_HAS_MEMCHR)
+ /// Emulated memchr - Finds a character in a buffer.
+ const void *memchr_emulation (const void *s, int c, size_t len);
+#endif /* ACE_HAS_MEMCHR */
+
+ /// Compares two buffers.
+ int memcmp (const void *t, const void *s, size_t len);
+
+ /// Copies one buffer to another.
+ void *memcpy (void *t, const void *s, size_t len);
+
+ /// Moves one buffer to another.
+ void *memmove (void *t, const void *s, size_t len);
+
+ /// Fills a buffer with a character value.
+ void *memset (void *s, int c, size_t len);
+
+ /// Appends a string to another string (char version).
+ char *strcat (char *s, const char *t);
+
+#if defined (ACE_HAS_WCHAR)
+ /// Appends a string to another string (wchar_t version).
+ 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).
+ 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).
+ 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).
+ char *strchr (char *s, int c);
+
+#if defined (ACE_HAS_WCHAR)
+ /// Finds the first occurance of a character in a string (wchar_t version).
+ wchar_t *strchr (wchar_t *s, wint_t c);
+#endif /* ACE_HAS_WCHAR */
+
+#if defined (ACE_LACKS_STRCHR)
+ /// Emulated strchr (char version) - Finds the first occurance of a
+ /// character in a string.
+ char *strchr_emulation (char *s, int c);
+
+ /// Emulated strchr (const char version) - Finds the first occurance of a
+ /// character in a string.
+ const char *strchr_emulation (const char *s, int c);
+#endif /* ACE_LACKS_STRCHR */
+
+ /// Compares two strings (char version).
+ int strcmp (const char *s, const char *t);
+
+ /// Compares two strings (wchar_t version).
+ int strcmp (const ACE_WCHAR_T *s, const ACE_WCHAR_T *t);
+
+ /// Copies a string (char version).
+ char *strcpy (char *s, const char *t);
+
+#if defined (ACE_HAS_WCHAR)
+ /// Copies a string (wchar_t version).
+ 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).
+ 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).
+ size_t strcspn (const wchar_t *s, const wchar_t *reject);
+#endif /* ACE_HAS_WCHAR */
+
+#if defined (ACE_LACKS_STRCSPN)
+ /// Emulated strcspn - Finds a substring in a string.
+ size_t strcspn_emulation (const char *s, const char *reject);
+#endif /* ACE_LACKS_STRCSPN */
+
+ /// Returns a malloced duplicated string (char version).
+ char *strdup (const char *s);
+
+#if defined (ACE_HAS_WCHAR)
+ /// Returns a malloced duplicated string (wchar_t version).
+ wchar_t *strdup (const wchar_t *s);
+#endif /* ACE_HAS_WCHAR */
+
+ /// Copies a string, but returns a pointer to the end of the
+ /// copied region (char version).
+ 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).
+ wchar_t *strecpy (wchar_t *s, const wchar_t *t);
+#endif /* ACE_HAS_WCHAR */
+
+ /// Returns a system error message.
+ char *strerror (int errnum);
+
+#if defined (ACE_LACKS_STRERROR)
+ /// Emulated strerror - Returns a system error message.
+ char *strerror_emulation (int errnum);
+#endif /* ACE_LACKS_STRERROR */
+
+ /// Finds the length of a string (char version).
+ size_t strlen (const char *s);
+
+ /// Finds the length of a string (ACE_WCHAR_T version).
+ size_t strlen (const ACE_WCHAR_T *s);
+
+ /// Appends part of a string to another string (char version).
+ char *strncat (char *s, const char *t, size_t len);
+
+ /// Appends part of a string to another string (wchar_t version).
+ ACE_WCHAR_T *strncat (ACE_WCHAR_T *s, const ACE_WCHAR_T *t, size_t len);
+
+ /// Finds the first occurance of a character in an array (const char
+ /// version).
+ 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).
+ 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).
+ char *strnchr (char *s, int c, size_t len);
+
+ /// Finds the first occurance of a character in an array (ACE_WCHAR_T version).
+ ACE_WCHAR_T *strnchr (ACE_WCHAR_T *s, ACE_WINT_T c, size_t len);
+
+ /// Compares two arrays (char version).
+ int strncmp (const char *s, const char *t, size_t len);
+
+ /// Compares two arrays (wchar_t version).
+ int strncmp (const ACE_WCHAR_T *s, const ACE_WCHAR_T *t, size_t len);
+
+ /// Copies an array (char version)
+ char *strncpy (char *s, const char *t, size_t len);
+
+ /// Copies an array (ACE_WCHAR_T version)
+ ACE_WCHAR_T *strncpy (ACE_WCHAR_T *s, const ACE_WCHAR_T *t, size_t len);
+
+ /// Finds the length of a limited-length string (char version).
+ /**
+ * @param s The character string to find the length of.
+ * @param maxlen The maximum number of characters that will be
+ * scanned for the terminating nul character.
+ *
+ * @return The length of @arg s, if the terminating nul character
+ * is located, else @arg maxlen.
+ */
+ size_t strnlen (const char *s, size_t maxlen);
+
+ /// Finds the length of a limited-length string (ACE_WCHAR_T version).
+ /**
+ * @param s The character string to find the length of.
+ * @param maxlen The maximum number of characters that will be
+ * scanned for the terminating nul character.
+ *
+ * @return The length of @arg s, if the terminating nul character
+ * is located, else @arg maxlen.
+ */
+ size_t strnlen (const ACE_WCHAR_T *s, size_t maxlen);
+
+ /// Finds the first occurance of a substring in an array (const char
+ /// version).
+ 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).
+ 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).
+ char *strnstr (char *s, const char *t, size_t len);
+
+ /// Finds the first occurance of a substring in an array (wchar_t version).
+ ACE_WCHAR_T *strnstr (ACE_WCHAR_T *s, const ACE_WCHAR_T *t, size_t len);
+
+ /// Searches for characters in a string (const char version).
+ const char *strpbrk (const char *s1, const char *s2);
+
+#if defined (ACE_HAS_WCHAR)
+ /// Searches for characters in a string (const wchar_t version).
+ const wchar_t *strpbrk (const wchar_t *s1, const wchar_t *s2);
+#endif /* ACE_HAS_WCHAR */
+
+ /// Searches for characters in a string (char version).
+ char *strpbrk (char *s1, const char *s2);
+
+#if defined (ACE_HAS_WCHAR)
+ /// Searches for characters in a string (wchar_t version).
+ wchar_t *strpbrk (wchar_t *s1, const wchar_t *s2);
+#endif /* ACE_HAS_WCHAR */
+
+#if defined (ACE_LACKS_STRPBRK)
+ /// Emulated strpbrk - Searches for characters in a string.
+ char *strpbrk_emulation (const char *string,
+ const char *charset);
+#endif /* ACE_LACKS_STRPBRK */
+
+ /// Finds the last occurance of a character in a string (const char
+ /// version).
+ 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).
+ 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).
+ char *strrchr (char *s, int c);
+
+#if defined (ACE_HAS_WCHAR)
+ /// Finds the last occurance of a character in a string (wchar_t version).
+ wchar_t *strrchr (wchar_t *s, wint_t c);
+#endif /* ACE_HAS_WCHAR */
+
+#if defined (ACE_LACKS_STRRCHR)
+ /// Emulated strrchr (char version) - Finds the last occurance of a
+ /// character in a string.
+ char *strrchr_emulation (char *s, int c);
+
+ /// Emulated strrchr (const char version) - Finds the last occurance of a
+ /// character in a string.
+ const char *strrchr_emulation (const char *s, int c);
+#endif /* ACE_LACKS_STRRCHR */
+
+ /// 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.
+ */
+ 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.
+ */
+ ACE_WCHAR_T *strsncpy (ACE_WCHAR_T *dst,
+ const ACE_WCHAR_T *src,
+ size_t maxlen);
+
+ /// Searches for the first substring containing only the specified
+ /// characters and returns the size of the substring (char version).
+ 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).
+ size_t strspn (const wchar_t *s1, const wchar_t *s2);
+#endif /* ACE_HAS_WCHAR */
+
+#if defined (ACE_LACKS_STRSPN)
+ /// Emulated wcsspn.
+ size_t strspn_emulation (const char *string,
+ const char *charset);
+#endif /* ACE_LACKS_STRSPN */
+
+ /// Finds the first occurance of a substring in a string (const char
+ /// version).
+ 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).
+ 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).
+ 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).
+ wchar_t *strstr (wchar_t *s, const wchar_t *t);
+#endif /* ACE_HAS_WCHAR */
+
+ /// Finds the next token in a string (char version).
+ 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).
+ wchar_t *strtok (wchar_t *s, const wchar_t *tokens);
+#endif /* ACE_HAS_WCHAR && !ACE_LACKS_WCSTOK */
+
+ //@}
+
+ /// Finds the next token in a string (safe char version).
+ char *strtok_r (char *s, const char *tokens, char **lasts);
+
+#if defined (ACE_HAS_WCHAR)
+ /// Finds the next token in a string (wchar_t version).
+ wchar_t *strtok_r (ACE_WCHAR_T *s, const ACE_WCHAR_T *tokens, ACE_WCHAR_T **lasts);
+#endif // ACE_HAS_WCHAR
+
+#if !defined (ACE_HAS_REENTRANT_FUNCTIONS)
+ /// Emulated strtok_r.
+ char *strtok_r_emulation (char *s, const char *tokens, char **lasts);
+
+# if defined (ACE_HAS_WCHAR)
+ /// Emulated strtok_r (wchar_t version).
+ wchar_t *strtok_r_emulation (ACE_WCHAR_T *s, const ACE_WCHAR_T *tokens, ACE_WCHAR_T **lasts);
+# endif // ACE_HAS_WCHAR
+#endif /* !ACE_HAS_REENTRANT_FUNCTIONS */
+
+} /* namespace ACE_OS */
+
+# if defined (ACE_HAS_INLINED_OSCALLS)
+# if defined (ACE_INLINE)
+# undef ACE_INLINE
+# endif /* ACE_INLINE */
+# define ACE_INLINE inline
+# include "ace/OS_NS_string.inl"
+# endif /* ACE_HAS_INLINED_OSCALLS */
+
+# include /**/ "ace/post.h"
+#endif /* ACE_OS_NS_STRING_H */
diff --git a/ace/OS_NS_string.inl b/ace/OS_NS_string.inl
index fc532b41367..8604cb2153f 100644
--- a/ace/OS_NS_string.inl
+++ b/ace/OS_NS_string.inl
@@ -1,4 +1,493 @@
// -*- C++ -*-
// $Id$
-// This is a placeholder.
+// don't like this... dhinton
+#include "ace/OS_NS_wchar.h"
+
+ACE_INLINE const void *
+ACE_OS::memchr (const void *s, int c, size_t len)
+{
+#if defined (ACE_HAS_MEMCHR)
+ return ::memchr (s, c, len);
+#else /* ACE_HAS_MEMCHR */
+ return ACE_OS::memchr_emulation (s, c, len);
+#endif /* ACE_HAS_MEMCHR */
+}
+
+ACE_INLINE void *
+ACE_OS::memchr (void *s, int c, size_t len)
+{
+ return ACE_const_cast (void *,
+ ACE_OS::memchr (ACE_static_cast (const void *, s), c, len));
+}
+
+ACE_INLINE int
+ACE_OS::memcmp (const void *t, const void *s, size_t len)
+{
+ return ::memcmp (t, s, len);
+}
+
+
+ACE_INLINE void *
+ACE_OS::memcpy (void *t, const void *s, size_t len)
+{
+ return ::memcpy (t, s, len);
+}
+
+ACE_INLINE void *
+ACE_OS::memmove (void *t, const void *s, size_t len)
+{
+ return ::memmove (t, s, len);
+}
+
+ACE_INLINE void *
+ACE_OS::memset (void *s, int c, size_t len)
+{
+ return ::memset (s, c, len);
+}
+
+ACE_INLINE char *
+ACE_OS::strcat (char *s, const char *t)
+{
+ return ::strcat (s, t);
+}
+
+#if defined (ACE_HAS_WCHAR)
+ACE_INLINE wchar_t *
+ACE_OS::strcat (wchar_t *s, const wchar_t *t)
+{
+# if defined (ACE_LACKS_WCSCAT)
+ return ACE_OS::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::strchr (const char *s, int c)
+{
+#if defined (ACE_LACKS_STRCHR)
+ return ACE_OS::strchr_emulation (s, c);
+#else /* ! ACE_LACKS_STRCHR */
+ return (const char *) ::strchr (s, c);
+#endif /* ACE_LACKS_STRCHR */
+}
+
+#if defined (ACE_HAS_WCHAR)
+ACE_INLINE const wchar_t *
+ACE_OS::strchr (const wchar_t *s, wint_t c)
+{
+# if defined (ACE_LACKS_WCSCHR)
+ return ACE_OS::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::strchr (char *s, int c)
+{
+#if defined (ACE_LACKS_STRCHR)
+ return ACE_OS::strchr_emulation (s, c);
+#else /* ! ACE_LACKS_STRCHR */
+ return ::strchr (s, c);
+#endif /* ACE_LACKS_STRCHR */
+}
+
+#if defined (ACE_HAS_WCHAR)
+ACE_INLINE wchar_t *
+ACE_OS::strchr (wchar_t *s, wint_t c)
+{
+ return ACE_const_cast (wchar_t *,
+ ACE_OS::strchr (ACE_static_cast (const wchar_t *, s), c));
+}
+#endif /* ACE_HAS_WCHAR */
+
+ACE_INLINE int
+ACE_OS::strcmp (const char *s, const char *t)
+{
+ return ::strcmp (s, t);
+}
+
+ACE_INLINE int
+ACE_OS::strcmp (const ACE_WCHAR_T *s, const ACE_WCHAR_T *t)
+{
+# if !defined (ACE_HAS_WCHAR) || defined (ACE_LACKS_WCSCMP)
+ return ACE_OS::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::strcpy (char *s, const char *t)
+{
+ return ::strcpy (s, t);
+}
+
+#if defined (ACE_HAS_WCHAR)
+ACE_INLINE wchar_t *
+ACE_OS::strcpy (wchar_t *s, const wchar_t *t)
+{
+# if defined (ACE_LACKS_WCSCPY)
+ return ACE_OS::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::strcspn (const char *s, const char *reject)
+{
+#if defined (ACE_LACKS_STRCSPN)
+ return ACE_OS::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::strcspn (const wchar_t *s, const wchar_t *reject)
+{
+# if defined (ACE_LACKS_WCSCSPN)
+ return ACE_OS::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::strerror (int errnum)
+{
+#if defined (ACE_LACKS_STRERROR)
+ return ACE_OS::strerror_emulation (errnum);
+#else /* ACE_LACKS_STRERROR */
+ return ::strerror (errnum);
+#endif /* ACE_LACKS_STRERROR */
+}
+
+ACE_INLINE size_t
+ACE_OS::strlen (const char *s)
+{
+ return ::strlen (s);
+}
+
+ACE_INLINE size_t
+ACE_OS::strlen (const ACE_WCHAR_T *s)
+{
+# if !defined (ACE_HAS_WCHAR) || defined (ACE_LACKS_WCSLEN)
+ return ACE_OS::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::strncat (char *s, const char *t, size_t len)
+{
+ return ::strncat (s, t, len);
+}
+
+ACE_INLINE ACE_WCHAR_T *
+ACE_OS::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::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 char *
+ACE_OS::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::strnchr (const_char_s, c, len));
+#else
+ return ACE_const_cast (char *,
+ ACE_OS::strnchr (ACE_static_cast (const char *, s), c, len));
+#endif
+}
+
+ACE_INLINE ACE_WCHAR_T *
+ACE_OS::strnchr (ACE_WCHAR_T *s, ACE_WINT_T c, size_t len)
+{
+ return ACE_const_cast (ACE_WCHAR_T *,
+ ACE_OS::strnchr (ACE_static_cast (const ACE_WCHAR_T *, s), c, len));
+}
+
+ACE_INLINE int
+ACE_OS::strncmp (const char *s, const char *t, size_t len)
+{
+ return ::strncmp (s, t, len);
+}
+
+ACE_INLINE int
+ACE_OS::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::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::strncpy (char *s, const char *t, size_t len)
+{
+ return ::strncpy (s, t, len);
+}
+
+ACE_INLINE ACE_WCHAR_T *
+ACE_OS::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::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 size_t
+ACE_OS::strnlen (const char *s, size_t maxlen)
+{
+#if defined (ACE_HAS_STRNLEN)
+ return ::strnlen (s, maxlen);
+#else /* ACE_HAS_STRNLEN */
+ size_t i;
+ for (i = 0; i < maxlen; ++i)
+ if (s[i] == '\0')
+ break;
+ return i;
+#endif /* ACE_HAS_STRNLEN */
+}
+
+ACE_INLINE size_t
+ACE_OS::strnlen (const ACE_WCHAR_T *s, size_t maxlen)
+{
+#if defined (ACE_HAS_WCHAR) && defined (ACE_HAS_WCSNLEN)
+ return wcsnlen (s, maxlen);
+#else /* ACE_HAS_WCSNLEN */
+ size_t i;
+ for (i = 0; i < maxlen; ++i)
+ if (s[i] == '\0')
+ break;
+ return i;
+#endif /* ACE_HAS_WCSNLEN */
+}
+
+ACE_INLINE char *
+ACE_OS::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::strnstr (const_char_s, t, len);
+#else
+ return (char *) ACE_OS::strnstr ((const char *) s, t, len);
+#endif
+}
+
+ACE_INLINE ACE_WCHAR_T *
+ACE_OS::strnstr (ACE_WCHAR_T *s, const ACE_WCHAR_T *t, size_t len)
+{
+ return ACE_const_cast (ACE_WCHAR_T *,
+ ACE_OS::strnstr (ACE_static_cast (const ACE_WCHAR_T *, s), t, len));
+}
+
+ACE_INLINE const char *
+ACE_OS::strpbrk (const char *s1, const char *s2)
+{
+#if defined (ACE_LACKS_STRPBRK)
+ return ACE_OS::strpbrk_emulation (s1, s2);
+#else /* ACE_LACKS_STRPBRK */
+ return (const char *) ::strpbrk (s1, s2);
+#endif /* ACE_LACKS_STRPBRK */
+}
+
+#if defined (ACE_HAS_WCHAR)
+ACE_INLINE const wchar_t *
+ACE_OS::strpbrk (const wchar_t *s, const wchar_t *t)
+{
+# if defined (ACE_LACKS_WCSPBRK)
+ return ACE_OS::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::strpbrk (char *s1, const char *s2)
+{
+#if defined (ACE_LACKS_STRPBRK)
+ return ACE_OS::strpbrk_emulation (s1, s2);
+#else /* ACE_LACKS_STRPBRK */
+ return ::strpbrk (s1, s2);
+#endif /* ACE_LACKS_STRPBRK */
+}
+
+#if defined (ACE_HAS_WCHAR)
+ACE_INLINE wchar_t *
+ACE_OS::strpbrk (wchar_t *s, const wchar_t *t)
+{
+ return ACE_const_cast (wchar_t *,
+ ACE_OS::strpbrk (ACE_static_cast (const wchar_t *, s), t));
+}
+#endif /* ACE_HAS_WCHAR */
+
+ACE_INLINE const char *
+ACE_OS::strrchr (const char *s, int c)
+{
+#if defined (ACE_LACKS_STRRCHR)
+ return ACE_OS::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::strrchr (const wchar_t *s, wint_t c)
+{
+#if defined (ACE_LACKS_WCSRCHR)
+ return ACE_OS::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::strrchr (char *s, int c)
+{
+#if defined (ACE_LACKS_STRRCHR)
+ return ACE_OS::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::strrchr (wchar_t *s, wint_t c)
+{
+ return ACE_const_cast (wchar_t *,
+ ACE_OS::strrchr (ACE_static_cast (const wchar_t *, s), c));
+}
+#endif /* ACE_HAS_WCHAR */
+
+ACE_INLINE size_t
+ACE_OS::strspn (const char *s, const char *t)
+{
+#if defined (ACE_LACKS_STRSPN)
+ return ACE_OS::strspn_emulation (s, t);
+#else /* ACE_LACKS_STRSPN */
+ return ::strspn (s, t);
+#endif /* ACE_LACKS_STRSPN */
+}
+
+#if defined (ACE_HAS_WCHAR)
+ACE_INLINE size_t
+ACE_OS::strspn (const wchar_t *s, const wchar_t *t)
+{
+# if defined (ACE_LACKS_WCSSPN)
+ return ACE_OS::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::strstr (const char *s, const char *t)
+{
+ return (const char *) ::strstr (s, t);
+}
+
+#if defined (ACE_HAS_WCHAR)
+ACE_INLINE const wchar_t *
+ACE_OS::strstr (const wchar_t *s, const wchar_t *t)
+{
+# if defined (ACE_LACKS_WCSSTR)
+ return ACE_OS::wcsstr_emulation (s, t);
+# elif defined (HPUX)
+ return (const wchar_t *) ::wcswcs (s, t);
+# else /* ACE_LACKS_WCSSTR */
+ return (const wchar_t *) ::wcsstr (s, t);
+# endif /* ACE_LACKS_WCSSTR */
+}
+#endif /* ACE_HAS_WCHAR */
+
+ACE_INLINE char *
+ACE_OS::strstr (char *s, const char *t)
+{
+ return ::strstr (s, t);
+}
+
+#if defined (ACE_HAS_WCHAR)
+ACE_INLINE wchar_t *
+ACE_OS::strstr (wchar_t *s, const wchar_t *t)
+{
+# if defined (ACE_LACKS_WCSSTR)
+ return ACE_OS::wcsstr_emulation (s, t);
+# elif defined (HPUX)
+ return ::wcswcs (s, t);
+# else /* ACE_LACKS_WCSSTR */
+ return ::wcsstr (s, t);
+# endif /* ACE_LACKS_WCSSTR */
+}
+#endif /* ACE_HAS_WCHAR */
+
+ACE_INLINE char *
+ACE_OS::strtok (char *s, const char *tokens)
+{
+ return ::strtok (s, tokens);
+}
+
+#if defined (ACE_HAS_WCHAR) && !defined (ACE_LACKS_WCSTOK)
+ACE_INLINE wchar_t *
+ACE_OS::strtok (wchar_t *s, const wchar_t *tokens)
+{
+#if defined (ACE_HAS_3_PARAM_WCSTOK)
+ static wchar_t *lasts;
+ return ::wcstok (s, tokens, &lasts);
+#else
+ return ::wcstok (s, tokens);
+#endif /* ACE_HAS_3_PARAM_WCSTOK */
+}
+#endif /* ACE_HAS_WCHAR && !ACE_LACKS_WCSTOK */
+
+ACE_INLINE char *
+ACE_OS::strtok_r (char *s, const char *tokens, char **lasts)
+{
+#if defined (ACE_HAS_REENTRANT_FUNCTIONS)
+ return ::strtok_r (s, tokens, lasts);
+#else
+ return ACE_OS::strtok_r_emulation (s, tokens, lasts);
+#endif /* (ACE_HAS_REENTRANT_FUNCTIONS) */
+}
+
+#if defined (ACE_HAS_WCHAR)
+ACE_INLINE wchar_t*
+ACE_OS::strtok_r (ACE_WCHAR_T *s, const ACE_WCHAR_T *tokens, ACE_WCHAR_T **lasts)
+{
+#if defined (ACE_LACKS_WCSTOK)
+ return ACE_OS::strtok_r_emulation (s, tokens, lasts);
+#else
+# if defined (ACE_HAS_3_PARAM_WCSTOK)
+ return ::wcstok (s, tokens, lasts);
+# else /* ACE_HAS_3_PARAM_WCSTOK */
+ *lasts = ::wcstok (s, tokens);
+ return *lasts;
+# endif /* ACE_HAS_3_PARAM_WCSTOK */
+#endif /* ACE_LACKS_WCSTOK */
+}
+#endif // ACE_HAS_WCHAR
+
diff --git a/ace/OS_NS_strings.cpp b/ace/OS_NS_strings.cpp
index fc532b41367..ec2ab0ee4a0 100644
--- a/ace/OS_NS_strings.cpp
+++ b/ace/OS_NS_strings.cpp
@@ -1,4 +1,77 @@
// -*- C++ -*-
// $Id$
-// This is a placeholder.
+#include "ace/OS_NS_strings.h"
+
+ACE_RCSID(ace, OS_NS_strings, "$Id$")
+
+#if !defined (ACE_HAS_INLINED_OSCALLS)
+# include "ace/OS_NS_strings.inl"
+#endif /* ACE_HAS_INLINED_OS_CALLS */
+
+#if defined (ACE_LACKS_STRCASECMP)
+int
+ACE_OS::strcasecmp_emulation (const char *s, const char *t)
+{
+ const char *scan1 = s;
+ const char *scan2 = t;
+
+ while (*scan1 != 0
+ && ACE_OS::to_lower (*scan1)
+ == ACE_OS::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::to_lower (*scan1) - ACE_OS::to_lower (*scan2);
+}
+#endif /* ACE_LACKS_STRCASECMP */
+
+#if defined (ACE_LACKS_STRCASECMP)
+int
+ACE_OS::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::to_lower (*scan1)
+ == ACE_OS::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::to_lower (*scan1) - ACE_OS::to_lower (*scan2);
+}
+#endif /* ACE_LACKS_STRCASECMP */
diff --git a/ace/OS_NS_strings.h b/ace/OS_NS_strings.h
index fc532b41367..e465ff94f64 100644
--- a/ace/OS_NS_strings.h
+++ b/ace/OS_NS_strings.h
@@ -1,4 +1,69 @@
// -*- C++ -*-
-// $Id$
-// This is a placeholder.
+//=============================================================================
+/**
+ * @file OS_NS_strings.h
+ *
+ * $Id$
+ *
+ * @author Douglas C. Schmidt <schmidt@cs.wustl.edu>
+ * @author Jesper S. M|ller<stophph@diku.dk>
+ * @author and a cast of thousands...
+ *
+ * Originally in OS.h.
+ */
+//=============================================================================
+
+#ifndef ACE_OS_NS_STRINGS_H
+# define ACE_OS_NS_STRINGS_H
+
+# include /**/ "ace/pre.h"
+
+# include "ace/config-all.h"
+
+# if !defined (ACE_LACKS_PRAGMA_ONCE)
+# pragma once
+# endif /* ACE_LACKS_PRAGMA_ONCE */
+
+#include "ace/os_include/os_strings.h"
+
+class ACE_Time_Value;
+
+namespace ACE_OS {
+
+ /// Compares two strings (case insensitive const char version).
+ int strcasecmp (const char *s, const char *t);
+
+#if defined (ACE_HAS_WCHAR)
+ /// Compares two strings (case insensitive const wchar_t version).
+ int strcasecmp (const wchar_t *s, const wchar_t *t);
+#endif /* ACE_HAS_WCHAR */
+
+ /// Compares two arrays (case insensitive const char version).
+ 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).
+ int strncasecmp (const wchar_t *s, const wchar_t *t, size_t len);
+#endif /* ACE_HAS_WCHAR */
+
+#if defined (ACE_LACKS_STRCASECMP)
+ /// Emulated strcasecmp - Performs a case insensitive comparison of strings.
+ int strcasecmp_emulation (const char *s, const char *t);
+
+ /// Emulated strncasecmp - Performs a case insensitvie comparison of arrays.
+ int strncasecmp_emulation (const char *s, const char *t, size_t len);
+#endif /* ACE_LACKS_STRCASECMP */
+
+} /* namespace ACE_OS */
+
+# if defined (ACE_HAS_INLINED_OSCALLS)
+# if defined (ACE_INLINE)
+# undef ACE_INLINE
+# endif /* ACE_INLINE */
+# define ACE_INLINE inline
+# include "ace/OS_NS_strings.inl"
+# endif /* ACE_HAS_INLINED_OSCALLS */
+
+# include /**/ "ace/post.h"
+#endif /* ACE_OS_NS_STRINGS_H */
diff --git a/ace/OS_NS_strings.inl b/ace/OS_NS_strings.inl
index fc532b41367..52960598711 100644
--- a/ace/OS_NS_strings.inl
+++ b/ace/OS_NS_strings.inl
@@ -1,4 +1,51 @@
// -*- C++ -*-
// $Id$
-// This is a placeholder.
+ACE_INLINE int
+ACE_OS::strcasecmp (const char *s, const char *t)
+{
+#if defined (ACE_LACKS_STRCASECMP)
+ return ACE_OS::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::strcasecmp (const wchar_t *s, const wchar_t *t)
+{
+# if defined (ACE_LACKS_WCSICMP)
+ return ACE_OS::wcsicmp_emulation (s, t);
+# else /* ACE_LACKS_WCSICMP */
+ return ::_wcsicmp (s, t);
+# endif /* ACE_LACKS_WCSICMP */
+}
+#endif /* ACE_HAS_WCHAR */
+
+ACE_INLINE int
+ACE_OS::strncasecmp (const char *s, const char *t, size_t len)
+{
+#if defined (ACE_LACKS_STRCASECMP)
+ return ACE_OS::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::strncasecmp (const wchar_t *s, const wchar_t *t, size_t len)
+{
+#if defined (ACE_LACKS_WCSNICMP)
+ return ACE_OS::wcsnicmp_emulation (s, t, len);
+#else /* ACE_LACKS_WCSNICMP */
+ return ::_wcsnicmp (s, t, len);
+#endif /* ACE_LACKS_WCSNICMP */
+}
+#endif /* ACE_HAS_WCHAR */
+
diff --git a/ace/OS_NS_stropts.cpp b/ace/OS_NS_stropts.cpp
index fc532b41367..91682f7ebec 100644
--- a/ace/OS_NS_stropts.cpp
+++ b/ace/OS_NS_stropts.cpp
@@ -1,4 +1,193 @@
// -*- C++ -*-
// $Id$
-// This is a placeholder.
+#include "ace/OS_NS_stropts.h"
+
+ACE_RCSID(ace, OS_NS_stropts, "$Id$")
+
+#if !defined (ACE_HAS_INLINED_OSCALLS)
+# include "ace/OS_NS_stropts.inl"
+#endif /* ACE_HAS_INLINED_OS_CALLS */
+
+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 */
+}
+
diff --git a/ace/OS_NS_stropts.h b/ace/OS_NS_stropts.h
index fc532b41367..c37dd25d13c 100644
--- a/ace/OS_NS_stropts.h
+++ b/ace/OS_NS_stropts.h
@@ -1,4 +1,146 @@
// -*- C++ -*-
-// $Id$
-// This is a placeholder.
+//=============================================================================
+/**
+ * @file OS_NS_stropts.h
+ *
+ * $Id$
+ *
+ * @author Douglas C. Schmidt <schmidt@cs.wustl.edu>
+ * @author Jesper S. M|ller<stophph@diku.dk>
+ * @author and a cast of thousands...
+ *
+ * Originally in OS.h.
+ */
+//=============================================================================
+
+#ifndef ACE_OS_NS_STROPTS_H
+# define ACE_OS_NS_STROPTS_H
+
+# include /**/ "ace/pre.h"
+
+# include "ace/config-all.h"
+
+# if !defined (ACE_LACKS_PRAGMA_ONCE)
+# pragma once
+# endif /* ACE_LACKS_PRAGMA_ONCE */
+
+#include "ace/OS_Export.h"
+#include "ace/os_include/os_stropts.h"
+#include "ace/os_include/os_stdio.h"
+
+#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) */
+
+// @todo: move this to it's own file... dhinton
+/**
+ * @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 &);
+};
+
+class ACE_QoS;
+
+namespace ACE_OS {
+
+ int getmsg (ACE_HANDLE handle,
+ struct strbuf *ctl,
+ struct strbuf
+ *data, int *flags);
+ int getpmsg (ACE_HANDLE handle,
+ struct strbuf *ctl,
+ struct strbuf
+ *data,
+ int *band,
+ int *flags);
+
+ int fattach (int handle,
+ const char *path);
+ int fdetach (const char *file);
+
+ /// UNIX-style <ioctl>.
+ int ioctl (ACE_HANDLE handle,
+ int cmd,
+ void * = 0);
+
+#if !defined (ACE_HAS_WINCE)
+ /// QoS-enabled <ioctl>.
+ 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.
+ 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);
+#endif // ACE_HAS_WINCE
+
+ int isastream (ACE_HANDLE handle);
+
+ int putmsg (ACE_HANDLE handle,
+ const struct strbuf *ctl,
+ const struct strbuf *data,
+ int flags);
+ int putpmsg (ACE_HANDLE handle,
+ const struct strbuf *ctl,
+ const struct strbuf *data,
+ int band,
+ int flags);
+
+} /* namespace ACE_OS */
+
+# if defined (ACE_HAS_INLINED_OSCALLS)
+# if defined (ACE_INLINE)
+# undef ACE_INLINE
+# endif /* ACE_INLINE */
+# define ACE_INLINE inline
+# include "ace/OS_NS_stropts.inl"
+# endif /* ACE_HAS_INLINED_OSCALLS */
+
+# include /**/ "ace/post.h"
+#endif /* ACE_OS_NS_STROPTS_H */
diff --git a/ace/OS_NS_stropts.inl b/ace/OS_NS_stropts.inl
index fc532b41367..ef8558f67de 100644
--- a/ace/OS_NS_stropts.inl
+++ b/ace/OS_NS_stropts.inl
@@ -1,4 +1,189 @@
// -*- C++ -*-
// $Id$
-// This is a placeholder.
+#include "ace/os_include/os_errno.h"
+#include "ace/OS_NS_unistd.h"
+#include "ace/OS_NS_string.h"
+#include "ace/OS_Memory.h"
+
+#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 */
+
+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 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::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 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::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);
+#else
+ ACE_OSCALL_RETURN (::ioctl (handle, cmd, val), int, -1);
+#endif /* ACE_WIN32 */
+}
+
+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 */
+}
+
+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 */
+}
diff --git a/ace/OS_NS_sys_mman.cpp b/ace/OS_NS_sys_mman.cpp
index fc532b41367..5a9c10ce148 100644
--- a/ace/OS_NS_sys_mman.cpp
+++ b/ace/OS_NS_sys_mman.cpp
@@ -1,4 +1,11 @@
// -*- C++ -*-
// $Id$
-// This is a placeholder.
+#include "ace/OS_NS_sys_mman.h"
+
+ACE_RCSID(ace, OS_NS_sys_mman, "$Id$")
+
+#if !defined (ACE_HAS_INLINED_OSCALLS)
+# include "ace/OS_NS_sys_mman.inl"
+#endif /* ACE_HAS_INLINED_OS_CALLS */
+
diff --git a/ace/OS_NS_sys_mman.h b/ace/OS_NS_sys_mman.h
index fc532b41367..9f883789a0c 100644
--- a/ace/OS_NS_sys_mman.h
+++ b/ace/OS_NS_sys_mman.h
@@ -1,4 +1,73 @@
// -*- C++ -*-
-// $Id$
-// This is a placeholder.
+//=============================================================================
+/**
+ * @file OS_NS_sys_mman.h
+ *
+ * $Id$
+ *
+ * @author Douglas C. Schmidt <schmidt@cs.wustl.edu>
+ * @author Jesper S. M|ller<stophph@diku.dk>
+ * @author and a cast of thousands...
+ *
+ * Originally in OS.h.
+ */
+//=============================================================================
+
+#ifndef ACE_OS_NS_SYS_MMAN_H
+# define ACE_OS_NS_SYS_MMAN_H
+
+# include /**/ "ace/pre.h"
+
+# include "ace/config-all.h"
+
+# if !defined (ACE_LACKS_PRAGMA_ONCE)
+# pragma once
+# endif /* ACE_LACKS_PRAGMA_ONCE */
+
+#include "ace/os_include/sys/os_mman.h"
+#include "ace/Global_Macros.h"
+
+namespace ACE_OS {
+
+ //@{ @name A set of wrappers for memory mapped files.
+ int madvise (caddr_t addr,
+ size_t len,
+ int map_advice);
+ 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);
+ int mprotect (void *addr,
+ size_t len,
+ int prot);
+ int msync (void *addr,
+ size_t len,
+ int sync);
+ int munmap (void *addr,
+ size_t len);
+ //@}
+
+ ACE_HANDLE shm_open (const ACE_TCHAR *filename,
+ int mode,
+ int perms = 0,
+ LPSECURITY_ATTRIBUTES sa = 0);
+ int shm_unlink (const ACE_TCHAR *path);
+
+} /* namespace ACE_OS */
+
+# if defined (ACE_HAS_INLINED_OSCALLS)
+# if defined (ACE_INLINE)
+# undef ACE_INLINE
+# endif /* ACE_INLINE */
+# define ACE_INLINE inline
+# include "ace/OS_NS_sys_mman.inl"
+# endif /* ACE_HAS_INLINED_OSCALLS */
+
+# include /**/ "ace/post.h"
+#endif /* ACE_OS_NS_SYS_MMAN_H */
diff --git a/ace/OS_NS_sys_mman.inl b/ace/OS_NS_sys_mman.inl
index fc532b41367..612bac0162d 100644
--- a/ace/OS_NS_sys_mman.inl
+++ b/ace/OS_NS_sys_mman.inl
@@ -1,4 +1,318 @@
// -*- C++ -*-
// $Id$
-// This is a placeholder.
+#include "ace/OS_NS_fcntl.h"
+#include "ace/OS_NS_unistd.h"
+
+#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 */
+
+ACE_INLINE int
+ACE_OS::madvise (caddr_t addr, size_t len, int map_advice)
+{
+ ACE_OS_TRACE ("ACE_OS::madvise");
+#if defined (ACE_WIN32)
+ ACE_UNUSED_ARG (addr);
+ ACE_UNUSED_ARG (len);
+ ACE_UNUSED_ARG (map_advice);
+
+ ACE_NOTSUP_RETURN (-1);
+#elif !defined (ACE_LACKS_MADVISE)
+ ACE_OSCALL_RETURN (::madvise (addr, len, map_advice), int, -1);
+#else
+ ACE_UNUSED_ARG (addr);
+ ACE_UNUSED_ARG (len);
+ ACE_UNUSED_ARG (map_advice);
+ ACE_NOTSUP_RETURN (-1);
+#endif /* ACE_WIN32 */
+}
+
+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_WIN32) && !defined (ACE_HAS_PHARLAP)
+
+# if defined(ACE_HAS_WINCE)
+ ACE_UNUSED_ARG (addr);
+ if (ACE_BIT_ENABLED (flags, MAP_FIXED)) // not supported
+ {
+ errno = EINVAL;
+ return MAP_FAILED;
+ }
+# else
+ if (!ACE_BIT_ENABLED (flags, MAP_FIXED))
+ addr = 0;
+ else if (addr == 0) // can not map to address 0
+ {
+ errno = EINVAL;
+ return MAP_FAILED;
+ }
+# endif
+
+ 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))
+ {
+# if !defined(ACE_HAS_WINCE)
+ prot = PAGE_WRITECOPY;
+# endif // ACE_HAS_WINCE
+ 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, and the desired name is valid, do we try
+ // CreateFileMapping.
+
+ *file_mapping = ACE_TEXT_OpenFileMapping (nt_flags,
+ 0,
+ file_mapping_name);
+ if (*file_mapping != 0
+ || (::GetLastError () == ERROR_INVALID_NAME
+ && ::GetLastError () == ERROR_FILE_NOT_FOUND))
+ 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
+ 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
+ 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_WIN32 && !ACE_HAS_PHARLAP */
+}
+
+// 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_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_WIN32 && !ACE_HAS_PHARLAP */
+}
+
+ACE_INLINE int
+ACE_OS::msync (void *addr, size_t len, int sync)
+{
+ ACE_OS_TRACE ("ACE_OS::msync");
+#if 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_WIN32 && !ACE_HAS_PHARLAP */
+}
+
+ACE_INLINE int
+ACE_OS::munmap (void *addr, size_t len)
+{
+ ACE_OS_TRACE ("ACE_OS::munmap");
+#if 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_WIN32 */
+}
+
+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_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_SHM_OPEN */
+}
+
+ACE_INLINE int
+ACE_OS::shm_unlink (const ACE_TCHAR *path)
+{
+ ACE_OS_TRACE ("ACE_OS::shm_unlink");
+# if 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_SHM_OPEN */
+}
+
diff --git a/ace/OS_NS_sys_msg.cpp b/ace/OS_NS_sys_msg.cpp
index fc532b41367..917121a8680 100644
--- a/ace/OS_NS_sys_msg.cpp
+++ b/ace/OS_NS_sys_msg.cpp
@@ -1,4 +1,11 @@
// -*- C++ -*-
// $Id$
-// This is a placeholder.
+#include "ace/OS_NS_sys_msg.h"
+
+ACE_RCSID(ace, OS_NS_sys_msg, "$Id$")
+
+#if !defined (ACE_HAS_INLINED_OSCALLS)
+# include "ace/OS_NS_sys_msg.inl"
+#endif /* ACE_HAS_INLINED_OS_CALLS */
+
diff --git a/ace/OS_NS_sys_msg.h b/ace/OS_NS_sys_msg.h
index fc532b41367..2a20bc77cf2 100644
--- a/ace/OS_NS_sys_msg.h
+++ b/ace/OS_NS_sys_msg.h
@@ -1,4 +1,60 @@
// -*- C++ -*-
-// $Id$
-// This is a placeholder.
+//=============================================================================
+/**
+ * @file OS_NS_sys_msg.h
+ *
+ * $Id$
+ *
+ * @author Douglas C. Schmidt <schmidt@cs.wustl.edu>
+ * @author Jesper S. M|ller<stophph@diku.dk>
+ * @author and a cast of thousands...
+ *
+ * Originally in OS.h.
+ */
+//=============================================================================
+
+#ifndef ACE_OS_NS_SYS_MSG_H
+# define ACE_OS_NS_SYS_MSG_H
+
+# include /**/ "ace/pre.h"
+
+# include "ace/config-all.h"
+
+# if !defined (ACE_LACKS_PRAGMA_ONCE)
+# pragma once
+# endif /* ACE_LACKS_PRAGMA_ONCE */
+
+#include "ace/os_include/sys/os_msg.h"
+
+namespace ACE_OS {
+
+ //@{ @name A set of wrappers for System V message queues.
+ int msgctl (int msqid,
+ int cmd,
+ struct msqid_ds *);
+ int msgget (key_t key,
+ int msgflg);
+ int msgrcv (int int_id,
+ void *buf,
+ size_t len,
+ long type,
+ int flags);
+ int msgsnd (int int_id,
+ const void *buf,
+ size_t len,
+ int flags);
+ //@}
+
+} /* namespace ACE_OS */
+
+# if defined (ACE_HAS_INLINED_OSCALLS)
+# if defined (ACE_INLINE)
+# undef ACE_INLINE
+# endif /* ACE_INLINE */
+# define ACE_INLINE inline
+# include "ace/OS_NS_sys_msg.inl"
+# endif /* ACE_HAS_INLINED_OSCALLS */
+
+# include /**/ "ace/post.h"
+#endif /* ACE_OS_NS_SYS_MSG_H */
diff --git a/ace/OS_NS_sys_msg.inl b/ace/OS_NS_sys_msg.inl
index fc532b41367..f09e2b4895a 100644
--- a/ace/OS_NS_sys_msg.inl
+++ b/ace/OS_NS_sys_msg.inl
@@ -1,4 +1,78 @@
// -*- C++ -*-
// $Id$
-// This is a placeholder.
+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 */
+}
+
diff --git a/ace/OS_NS_sys_resource.cpp b/ace/OS_NS_sys_resource.cpp
index fc532b41367..3499e4bfc5c 100644
--- a/ace/OS_NS_sys_resource.cpp
+++ b/ace/OS_NS_sys_resource.cpp
@@ -1,4 +1,11 @@
// -*- C++ -*-
// $Id$
-// This is a placeholder.
+#include "ace/OS_NS_sys_resource.h"
+
+ACE_RCSID(ace, OS_NS_sys_resource, "$Id$")
+
+#if !defined (ACE_HAS_INLINED_OSCALLS)
+# include "ace/OS_NS_sys_resource.inl"
+#endif /* ACE_HAS_INLINED_OS_CALLS */
+
diff --git a/ace/OS_NS_sys_resource.h b/ace/OS_NS_sys_resource.h
index fc532b41367..54dcf186ef9 100644
--- a/ace/OS_NS_sys_resource.h
+++ b/ace/OS_NS_sys_resource.h
@@ -1,4 +1,53 @@
// -*- C++ -*-
-// $Id$
-// This is a placeholder.
+//=============================================================================
+/**
+ * @file OS_NS_sys_resource.h
+ *
+ * $Id$
+ *
+ * @author Douglas C. Schmidt <schmidt@cs.wustl.edu>
+ * @author Jesper S. M|ller<stophph@diku.dk>
+ * @author and a cast of thousands...
+ *
+ * Originally in OS.h.
+ */
+//=============================================================================
+
+#ifndef ACE_OS_NS_SYS_RESOURCE_H
+# define ACE_OS_NS_SYS_RESOURCE_H
+
+# include /**/ "ace/pre.h"
+
+# include "ace/config-all.h"
+
+# if !defined (ACE_LACKS_PRAGMA_ONCE)
+# pragma once
+# endif /* ACE_LACKS_PRAGMA_ONCE */
+
+#include "ace/os_include/sys/os_resource.h"
+
+namespace ACE_OS {
+
+ int getrlimit (int resource,
+ struct rlimit *rl);
+
+ int getrusage (int who,
+ struct rusage *rusage);
+
+
+ int setrlimit (int resource,
+ ACE_SETRLIMIT_TYPE *rl);
+
+} /* namespace ACE_OS */
+
+# if defined (ACE_HAS_INLINED_OSCALLS)
+# if defined (ACE_INLINE)
+# undef ACE_INLINE
+# endif /* ACE_INLINE */
+# define ACE_INLINE inline
+# include "ace/OS_NS_sys_resource.inl"
+# endif /* ACE_HAS_INLINED_OSCALLS */
+
+# include /**/ "ace/post.h"
+#endif /* ACE_OS_NS_SYS_RESOURCE_H */
diff --git a/ace/OS_NS_sys_resource.inl b/ace/OS_NS_sys_resource.inl
index fc532b41367..f01b3994c87 100644
--- a/ace/OS_NS_sys_resource.inl
+++ b/ace/OS_NS_sys_resource.inl
@@ -1,4 +1,76 @@
// -*- C++ -*-
// $Id$
-// This is a placeholder.
+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::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::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 */
+}
+
diff --git a/ace/OS_NS_sys_select.cpp b/ace/OS_NS_sys_select.cpp
index fc532b41367..fb2bc11b1b2 100644
--- a/ace/OS_NS_sys_select.cpp
+++ b/ace/OS_NS_sys_select.cpp
@@ -1,4 +1,11 @@
// -*- C++ -*-
// $Id$
-// This is a placeholder.
+#include "ace/OS_NS_sys_select.h"
+
+ACE_RCSID(ace, OS_NS_sys_select, "$Id$")
+
+#if !defined (ACE_HAS_INLINED_OSCALLS)
+# include "ace/OS_NS_sys_select.inl"
+#endif /* ACE_HAS_INLINED_OS_CALLS */
+
diff --git a/ace/OS_NS_sys_select.h b/ace/OS_NS_sys_select.h
index fc532b41367..256f5fad57a 100644
--- a/ace/OS_NS_sys_select.h
+++ b/ace/OS_NS_sys_select.h
@@ -1,4 +1,57 @@
// -*- C++ -*-
-// $Id$
-// This is a placeholder.
+//=============================================================================
+/**
+ * @file OS_NS_sys_select.h
+ *
+ * $Id$
+ *
+ * @author Douglas C. Schmidt <schmidt@cs.wustl.edu>
+ * @author Jesper S. M|ller<stophph@diku.dk>
+ * @author and a cast of thousands...
+ *
+ * Originally in OS.h.
+ */
+//=============================================================================
+
+#ifndef ACE_OS_NS_SYS_SELECT_H
+# define ACE_OS_NS_SYS_SELECT_H
+
+# include /**/ "ace/pre.h"
+
+# include "ace/config-all.h"
+
+# if !defined (ACE_LACKS_PRAGMA_ONCE)
+# pragma once
+# endif /* ACE_LACKS_PRAGMA_ONCE */
+
+#include "ace/os_include/sys/os_select.h"
+
+class ACE_Time_Value;
+
+namespace ACE_OS {
+
+ // Should be moved to cpp or inl.
+ int select (int width,
+ fd_set *rfds,
+ fd_set *wfds = 0,
+ fd_set *efds = 0,
+ const ACE_Time_Value *tv = 0);
+ int select (int width,
+ fd_set *rfds,
+ fd_set *wfds,
+ fd_set *efds,
+ const ACE_Time_Value &tv);
+
+} /* namespace ACE_OS */
+
+# if defined (ACE_HAS_INLINED_OSCALLS)
+# if defined (ACE_INLINE)
+# undef ACE_INLINE
+# endif /* ACE_INLINE */
+# define ACE_INLINE inline
+# include "ace/OS_NS_sys_select.inl"
+# endif /* ACE_HAS_INLINED_OSCALLS */
+
+# include /**/ "ace/post.h"
+#endif /* ACE_OS_NS_SYS_SELECT_H */
diff --git a/ace/OS_NS_sys_select.inl b/ace/OS_NS_sys_select.inl
index fc532b41367..26d52eac344 100644
--- a/ace/OS_NS_sys_select.inl
+++ b/ace/OS_NS_sys_select.inl
@@ -1,4 +1,59 @@
// -*- C++ -*-
// $Id$
-// This is a placeholder.
+#include "ace/Time_Value.h"
+#include "ace/OS_NS_macros.h"
+
+// 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
+}
+
diff --git a/ace/OS_NS_sys_shm.cpp b/ace/OS_NS_sys_shm.cpp
index fc532b41367..33474349f7f 100644
--- a/ace/OS_NS_sys_shm.cpp
+++ b/ace/OS_NS_sys_shm.cpp
@@ -1,4 +1,17 @@
// -*- C++ -*-
// $Id$
-// This is a placeholder.
+#include "ace/OS_NS_sys_shm.h"
+
+ACE_RCSID(ace, OS_NS_sys_shm, "$Id$")
+
+#if !defined (ACE_HAS_INLINED_OSCALLS)
+# include "ace/OS_NS_sys_shm.inl"
+#endif /* ACE_HAS_INLINED_OS_CALLS */
+
+// these don't appear to be used anywhere. dhinton
+#if defined(INTEGRITY) && defined(ACE_HAS_SHM_OPEN)
+char* shm_area_name = "ACE_Area";
+char* shm_area_password = "******";
+#endif
+
diff --git a/ace/OS_NS_sys_shm.h b/ace/OS_NS_sys_shm.h
index fc532b41367..1f45bf90a7a 100644
--- a/ace/OS_NS_sys_shm.h
+++ b/ace/OS_NS_sys_shm.h
@@ -1,4 +1,56 @@
// -*- C++ -*-
-// $Id$
-// This is a placeholder.
+//=============================================================================
+/**
+ * @file OS_NS_sys_shm.h
+ *
+ * $Id$
+ *
+ * @author Douglas C. Schmidt <schmidt@cs.wustl.edu>
+ * @author Jesper S. M|ller<stophph@diku.dk>
+ * @author and a cast of thousands...
+ *
+ * Originally in OS.h.
+ */
+//=============================================================================
+
+#ifndef ACE_OS_NS_SYS_SHM_H
+# define ACE_OS_NS_SYS_SHM_H
+
+# include /**/ "ace/pre.h"
+
+# include "ace/config-all.h"
+
+# if !defined (ACE_LACKS_PRAGMA_ONCE)
+# pragma once
+# endif /* ACE_LACKS_PRAGMA_ONCE */
+
+#include "ace/os_include/sys/os_shm.h"
+
+namespace ACE_OS {
+
+ //@{ @name A set of wrappers for System V shared memory.
+ void *shmat (int int_id,
+ void *shmaddr,
+ int shmflg);
+ int shmctl (int int_id,
+ int cmd,
+ struct shmid_ds *buf);
+ int shmdt (void *shmaddr);
+ int shmget (key_t key,
+ int size,
+ int flags);
+ ///@}
+
+} /* namespace ACE_OS */
+
+# if defined (ACE_HAS_INLINED_OSCALLS)
+# if defined (ACE_INLINE)
+# undef ACE_INLINE
+# endif /* ACE_INLINE */
+# define ACE_INLINE inline
+# include "ace/OS_NS_sys_shm.inl"
+# endif /* ACE_HAS_INLINED_OSCALLS */
+
+# include /**/ "ace/post.h"
+#endif /* ACE_OS_NS_SYS_SHM_H */
diff --git a/ace/OS_NS_sys_shm.inl b/ace/OS_NS_sys_shm.inl
index fc532b41367..0e7cf34c070 100644
--- a/ace/OS_NS_sys_shm.inl
+++ b/ace/OS_NS_sys_shm.inl
@@ -1,4 +1,65 @@
// -*- C++ -*-
// $Id$
-// This is a placeholder.
+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 */
+}
+
diff --git a/ace/OS_NS_sys_socket.cpp b/ace/OS_NS_sys_socket.cpp
index fc532b41367..f5907f91c76 100644
--- a/ace/OS_NS_sys_socket.cpp
+++ b/ace/OS_NS_sys_socket.cpp
@@ -1,4 +1,155 @@
// -*- C++ -*-
// $Id$
-// This is a placeholder.
+#include "ace/OS_NS_sys_socket.h"
+
+ACE_RCSID(ace, OS_NS_sys_socket, "$Id$")
+
+#if !defined (ACE_HAS_INLINED_OSCALLS)
+# include "ace/OS_NS_sys_socket.inl"
+#endif /* ACE_HAS_INLINED_OS_CALLS */
+
+#if !defined (ACE_HAS_WINCE)
+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 */
+}
+
+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 */
+}
+#endif // ACE_HAS_WINCE
+
+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::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 (0, 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 (0, 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;
+}
+
diff --git a/ace/OS_NS_sys_socket.h b/ace/OS_NS_sys_socket.h
index fc532b41367..e09f65d76df 100644
--- a/ace/OS_NS_sys_socket.h
+++ b/ace/OS_NS_sys_socket.h
@@ -1,4 +1,223 @@
// -*- C++ -*-
-// $Id$
-// This is a placeholder.
+//=============================================================================
+/**
+ * @file OS_NS_sys_socket.h
+ *
+ * $Id$
+ *
+ * @author Douglas C. Schmidt <schmidt@cs.wustl.edu>
+ * @author Jesper S. M|ller<stophph@diku.dk>
+ * @author and a cast of thousands...
+ *
+ * Originally in OS.h.
+ */
+//=============================================================================
+
+#ifndef ACE_OS_NS_SYS_SOCKET_H
+# define ACE_OS_NS_SYS_SOCKET_H
+
+# include /**/ "ace/pre.h"
+
+# include "ace/config-all.h"
+
+# if !defined (ACE_LACKS_PRAGMA_ONCE)
+# pragma once
+# endif /* ACE_LACKS_PRAGMA_ONCE */
+
+#include "ace/os_include/sys/os_socket.h"
+#include "ace/OS_NS_stropts.h"
+
+class ACE_Accept_QoS_Params;
+class ACE_QoS_Params;
+class ACE_Protocol_Info;
+
+namespace ACE_OS {
+
+# if defined (ACE_WIN32)
+ /// Keeps track of whether we've already initialized WinSock...
+ int socket_initialized_;
+# endif /* ACE_WIN32 */
+
+ //@{ @name A set of wrappers for sockets.
+ /// BSD-style <accept> (no QoS).
+ ACE_HANDLE accept (ACE_HANDLE handle,
+ struct sockaddr *addr,
+ int *addrlen);
+
+#if !defined (ACE_HAS_WINCE)
+ /**
+ * 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.
+ */
+ ACE_HANDLE accept (ACE_HANDLE handle,
+ struct sockaddr *addr,
+ int *addrlen,
+ const ACE_Accept_QoS_Params &qos_params);
+#endif // ACE_HAS_WINCE
+
+ int bind (ACE_HANDLE s,
+ struct sockaddr *name,
+ int namelen);
+
+ // takes care of windows specific requirement to call closesocket
+ int closesocket (ACE_HANDLE s);
+
+ /// BSD-style <connect> (no QoS).
+ int connect (ACE_HANDLE handle,
+ struct sockaddr *addr,
+ int addrlen);
+
+#if !defined (ACE_HAS_WINCE)
+ /**
+ * 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.
+ */
+ int connect (ACE_HANDLE handle,
+ const sockaddr *addr,
+ int addrlen,
+ const ACE_QoS_Params &qos_params);
+#endif // ACE_HAS_WINCE
+
+ /// Retrieve information about available transport protocols
+ /// installed on the local machine. Windows specific...
+ int enum_protocols (int *protocols,
+ ACE_Protocol_Info *protocol_buffer,
+ u_long *buffer_length);
+
+ int getpeername (ACE_HANDLE handle,
+ struct sockaddr *addr,
+ int *addrlen);
+
+ int getsockname (ACE_HANDLE handle,
+ struct sockaddr *addr,
+ int *addrlen);
+ int getsockopt (ACE_HANDLE handle,
+ int level,
+ int optname,
+ char *optval,
+ int *optlen);
+
+#if !defined (ACE_HAS_WINCE)
+ /// Joins a leaf node into a QoS-enabled multi-point session.
+ ACE_HANDLE join_leaf (ACE_HANDLE socket,
+ const sockaddr *name,
+ int namelen,
+ const ACE_QoS_Params &qos_params);
+#endif // ACE_HAS_WINCE
+
+ int listen (ACE_HANDLE handle,
+ int backlog);
+
+ int recv (ACE_HANDLE handle,
+ char *buf,
+ size_t len,
+ int flags = 0);
+
+ int recvfrom (ACE_HANDLE handle,
+ char *buf,
+ size_t len,
+ int flags,
+ struct sockaddr *addr,
+ int *addrlen);
+
+ 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);
+
+ int recvmsg (ACE_HANDLE handle,
+ struct msghdr *msg,
+ int flags);
+
+ ssize_t recvv (ACE_HANDLE handle,
+ iovec *iov,
+ int iovlen);
+
+ int send (ACE_HANDLE handle,
+ const char *buf,
+ size_t len,
+ int flags = 0);
+
+ int sendmsg (ACE_HANDLE handle,
+ const struct msghdr *msg,
+ int flags);
+
+ int sendto (ACE_HANDLE handle,
+ const char *buf,
+ size_t len,
+ int flags,
+ const struct sockaddr *addr,
+ int addrlen);
+
+ 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);
+
+ ssize_t sendv (ACE_HANDLE handle,
+ const iovec *iov,
+ int iovcnt);
+
+
+ /// Manipulate the options associated with a socket.
+ int setsockopt (ACE_HANDLE handle,
+ int level,
+ int optname,
+ const char *optval,
+ int optlen);
+
+ int shutdown (ACE_HANDLE handle,
+ int how);
+
+ /// Initialize WinSock before first use (e.g., when a DLL is first
+ /// loaded or the first use of a socket() call.
+ int socket_init (int version_high = 1,
+ int version_low = 1);
+
+ /// Finalize WinSock after last use (e.g., when a DLL is unloaded).
+ int socket_fini (void);
+
+ /// Create a BSD-style socket (no QoS).
+ 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.
+ ACE_HANDLE socket (int protocol_family,
+ int type,
+ int proto,
+ ACE_Protocol_Info *protocolinfo,
+ ACE_SOCK_GROUP g,
+ u_long flags);
+
+ int socketpair (int domain,
+ int type,
+ int protocol,
+ ACE_HANDLE sv[2]);
+
+} /* namespace ACE_OS */
+
+# if defined (ACE_HAS_INLINED_OSCALLS)
+# if defined (ACE_INLINE)
+# undef ACE_INLINE
+# endif /* ACE_INLINE */
+# define ACE_INLINE inline
+# include "ace/OS_NS_sys_socket.inl"
+# endif /* ACE_HAS_INLINED_OSCALLS */
+
+# include /**/ "ace/post.h"
+#endif /* ACE_OS_NS_SYS_SOCKET_H */
diff --git a/ace/OS_NS_sys_socket.inl b/ace/OS_NS_sys_socket.inl
index fc532b41367..631fc3fb85a 100644
--- a/ace/OS_NS_sys_socket.inl
+++ b/ace/OS_NS_sys_socket.inl
@@ -1,4 +1,736 @@
// -*- C++ -*-
// $Id$
-// This is a placeholder.
+#include "ace/OS_NS_errno.h"
+#include "ace/OS_NS_macros.h"
+#include "ace/OS_NS_sys_uio.h"
+
+#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 */
+
+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::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::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::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) */
+}
+
+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::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 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::recv (ACE_HANDLE handle, char *buf, size_t 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,
+ ACE_static_cast (int, 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,
+ size_t 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, len, flags,
+ (struct sockaddr_in *) addr, (ACE_SOCKET_LEN *) addrlen),
+ int, -1);
+# else
+ ACE_SOCKCALL_RETURN (::recvfrom ((ACE_SOCKET) handle, buf, len, flags,
+ (struct sockaddr *) addr, (ACE_SOCKET_LEN *) addrlen),
+ int, -1);
+# endif /* defined ACE_PSOS_DIAB_PPC */
+#elif defined (ACE_WIN32)
+ int shortened_len = ACE_static_cast (int, len);
+ int result = ::recvfrom ((ACE_SOCKET) handle,
+ buf,
+ shortened_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 shortened_len;
+ else
+ return -1;
+ }
+ else
+ return result;
+#else /* non Win32 and non PSOS */
+ ACE_SOCKCALL_RETURN (::recvfrom ((ACE_SOCKET) handle, buf, len, flags,
+ addr, (ACE_SOCKET_LEN *) addrlen),
+ int, -1);
+#endif /* defined (ACE_PSOS) */
+}
+
+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);
+ if (result != 0) {
+ ACE_OS::set_errno_to_last_error ();
+ }
+ 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::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 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 int
+ACE_OS::send (ACE_HANDLE handle, const char *buf, size_t 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,
+ ACE_static_cast (int, 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::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::sendto (ACE_HANDLE handle,
+ const char *buf,
+ size_t 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
+# if defined (ACE_WIN32)
+ ACE_SOCKCALL_RETURN (::sendto ((ACE_SOCKET) handle, buf,
+ ACE_static_cast (int, len), flags,
+ ACE_const_cast (struct sockaddr *, addr), addrlen),
+ int, -1);
+# else
+ ACE_SOCKCALL_RETURN (::sendto ((ACE_SOCKET) handle, buf, len, flags,
+ ACE_const_cast (struct sockaddr *, addr), addrlen),
+ int, -1);
+# endif /* ACE_WIN32 */
+#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);
+ if (result != 0) {
+ ACE_OS::set_errno_to_last_error ();
+ }
+ 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 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);
+ // Gets ignored on error anyway
+ bytes_sent += buffers[i].iov_len;
+
+ // If the transfer isnt complete just drop out of the loop.
+ if (result < (int)buffers[i].iov_len)
+ break;
+ }
+# 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::setsockopt (ACE_HANDLE handle,
+ int level,
+ int optname,
+ const char *optval,
+ int optlen)
+{
+ ACE_OS_TRACE ("ACE_OS::setsockopt");
+
+ #if defined (ACE_HAS_WINSOCK2) && (ACE_HAS_WINSOCK2 != 0) && defined(SO_REUSEPORT)
+ // To work around an inconsistency with Microsofts implementation of
+ // sockets, we will check for SO_REUSEADDR, and ignore it. Winsock
+ // always behaves as if SO_REUSEADDR=1. Some implementations have the
+ // same behaviour as Winsock, but use a new name for it. SO_REUSEPORT.
+ // If you want the normal behaviour for SO_REUSEADDR=0, then NT 4 sp4 and later
+ // supports SO_EXCLUSIVEADDRUSE. This also requires using an updated Platform SDK
+ // so it was decided to ignore the option for now. (Especially since ACE always
+ // sets SO_REUSEADDR=1, which we can mimic by doing nothing.)
+ if (level == SOL_SOCKET) {
+ if (optname == SO_REUSEADDR) {
+ return 0; // Not supported by Winsock
+ }
+ if (optname == SO_REUSEPORT) {
+ optname = SO_REUSEADDR;
+ }
+ }
+ #endif /*ACE_HAS_WINSOCK2*/
+
+ 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::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 */
+}
+
diff --git a/ace/OS_NS_sys_stat.cpp b/ace/OS_NS_sys_stat.cpp
index fc532b41367..fa50a6b040d 100644
--- a/ace/OS_NS_sys_stat.cpp
+++ b/ace/OS_NS_sys_stat.cpp
@@ -1,4 +1,11 @@
// -*- C++ -*-
// $Id$
-// This is a placeholder.
+#include "ace/OS_NS_sys_stat.h"
+
+ACE_RCSID(ace, OS_NS_sys_stat, "$Id$")
+
+#if !defined (ACE_HAS_INLINED_OSCALLS)
+# include "ace/OS_NS_sys_stat.inl"
+#endif /* ACE_HAS_INLINED_OS_CALLS */
+
diff --git a/ace/OS_NS_sys_stat.h b/ace/OS_NS_sys_stat.h
index fc532b41367..b9df56eee1d 100644
--- a/ace/OS_NS_sys_stat.h
+++ b/ace/OS_NS_sys_stat.h
@@ -1,4 +1,79 @@
// -*- C++ -*-
-// $Id$
-// This is a placeholder.
+//=============================================================================
+/**
+ * @file OS_NS_sys_stat.h
+ *
+ * $Id$
+ *
+ * @author Douglas C. Schmidt <schmidt@cs.wustl.edu>
+ * @author Jesper S. M|ller<stophph@diku.dk>
+ * @author and a cast of thousands...
+ *
+ * Originally in OS.h.
+ */
+//=============================================================================
+
+#ifndef ACE_OS_NS_SYS_STAT_H
+# define ACE_OS_NS_SYS_STAT_H
+
+# include /**/ "ace/pre.h"
+
+# include "ace/config-all.h"
+
+# if !defined (ACE_LACKS_PRAGMA_ONCE)
+# pragma once
+# endif /* ACE_LACKS_PRAGMA_ONCE */
+
+#include "ace/os_include/sys/os_stat.h"
+#include "ace/Default_Constants.h" // for ACE_DEFAULT_DIR_PERMS
+
+# if defined (ACE_WIN32) && !defined (ACE_HAS_WINCE) && !defined (__BORLANDC__)
+ typedef struct _stat ACE_stat;
+# else
+ typedef struct stat ACE_stat;
+# endif /* ACE_WIN32 */
+
+namespace ACE_OS {
+
+ ACE_HANDLE creat (const ACE_TCHAR *filename,
+ mode_t mode);
+
+ //@{ @name A set of wrappers for low-level file operations.
+
+ // non-standard
+ long filesize (ACE_HANDLE handle);
+
+ long filesize (const ACE_TCHAR *handle);
+
+
+ //@}
+
+ int fstat (ACE_HANDLE,
+ ACE_stat *);
+
+ int lstat (const char *,
+ ACE_stat *);
+
+ int mkdir (const ACE_TCHAR *path,
+ mode_t mode = ACE_DEFAULT_DIR_PERMS);
+
+ int mkfifo (const ACE_TCHAR *file,
+ mode_t mode = ACE_DEFAULT_FILE_PERMS);
+
+ int stat (const ACE_TCHAR *file, ACE_stat *);
+
+ mode_t umask (mode_t cmask);
+
+} /* namespace ACE_OS */
+
+# if defined (ACE_HAS_INLINED_OSCALLS)
+# if defined (ACE_INLINE)
+# undef ACE_INLINE
+# endif /* ACE_INLINE */
+# define ACE_INLINE inline
+# include "ace/OS_NS_sys_stat.inl"
+# endif /* ACE_HAS_INLINED_OSCALLS */
+
+# include /**/ "ace/post.h"
+#endif /* ACE_OS_NS_SYS_STAT_H */
diff --git a/ace/OS_NS_sys_stat.inl b/ace/OS_NS_sys_stat.inl
index fc532b41367..d6fefa014b2 100644
--- a/ace/OS_NS_sys_stat.inl
+++ b/ace/OS_NS_sys_stat.inl
@@ -1,4 +1,313 @@
// -*- C++ -*-
// $Id$
-// This is a placeholder.
+#include "ace/OS_NS_unistd.h"
+#include "ace/OS_NS_fcntl.h"
+
+ACE_INLINE ACE_HANDLE
+ACE_OS::creat (const ACE_TCHAR *filename, mode_t mode)
+{
+ ACE_OS_TRACE ("ACE_OS::creat");
+#if defined (ACE_WIN32)
+ return ACE_OS::open (filename, O_CREAT|O_TRUNC|O_WRONLY, 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_WIN32 */
+}
+
+// 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, 0), 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 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;
+}
+
+#if !defined (ACE_WIN32)
+
+ACE_INLINE int
+ACE_OS::fstat (ACE_HANDLE handle, ACE_stat *stp)
+{
+ ACE_OS_TRACE ("ACE_OS::fstat");
+#if 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 /* ACE_PSOS_LACKS_PHILE */
+}
+
+#else /* ACE_WIN32 */
+
+ACE_INLINE int
+ACE_OS::fstat (ACE_HANDLE handle, ACE_stat *stp)
+{
+ ACE_OS_TRACE ("ACE_OS::fstat");
+# if 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 ();
+ 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) |
+ (fdata.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY ? S_IFDIR : S_IFREG);
+ }
+ 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 /* 1 */
+}
+
+#endif /* WIN32 */
+
+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 /* ACE_LACKS_LSTAT */
+}
+
+ACE_INLINE int
+ACE_OS::mkdir (const ACE_TCHAR *path, mode_t mode)
+{
+#if 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, 0),
+ 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_PSOS_LACKS_PHILE */
+}
+
+ACE_INLINE int
+ACE_OS::mkfifo (const ACE_TCHAR *file, mode_t mode)
+{
+ ACE_OS_TRACE ("ACE_OS::mkfifo");
+#if 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_LACKS_MKFIFO */
+}
+
+ACE_INLINE int
+ACE_OS::stat (const ACE_TCHAR *file, ACE_stat *stp)
+{
+ ACE_OS_TRACE ("ACE_OS::stat");
+#if 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 /* VXWORKS */
+}
+
+#if !defined (ACE_WIN32)
+
+ACE_INLINE mode_t
+ACE_OS::umask (mode_t cmask)
+{
+ ACE_OS_TRACE ("ACE_OS::umask");
+# if defined (VXWORKS) || defined (ACE_PSOS) || defined (INTEGRITY)
+ ACE_UNUSED_ARG (cmask);
+ ACE_NOTSUP_RETURN ((mode_t)-1);
+# else
+ return ::umask (cmask); // This call shouldn't fail...
+# endif /* VXWORKS || ACE_PSOS */
+}
+
+#else /* ACE_WIN32 */
+
+ACE_INLINE mode_t
+ACE_OS::umask (mode_t cmask)
+{
+#if !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_WINCE */
+}
+
+#endif /* WIN32 */
diff --git a/ace/OS_NS_sys_time.cpp b/ace/OS_NS_sys_time.cpp
index fc532b41367..2109fa005e0 100644
--- a/ace/OS_NS_sys_time.cpp
+++ b/ace/OS_NS_sys_time.cpp
@@ -1,4 +1,11 @@
// -*- C++ -*-
// $Id$
-// This is a placeholder.
+#include "ace/OS_NS_sys_time.h"
+
+ACE_RCSID(ace, OS_NS_sys_time, "$Id$")
+
+#if !defined (ACE_HAS_INLINED_OSCALLS)
+# include "ace/OS_NS_sys_time.inl"
+#endif /* ACE_HAS_INLINED_OS_CALLS */
+
diff --git a/ace/OS_NS_sys_time.h b/ace/OS_NS_sys_time.h
index fc532b41367..bb2ffd29882 100644
--- a/ace/OS_NS_sys_time.h
+++ b/ace/OS_NS_sys_time.h
@@ -1,4 +1,45 @@
// -*- C++ -*-
-// $Id$
-// This is a placeholder.
+//=============================================================================
+/**
+ * @file OS_NS_sys_time.h
+ *
+ * $Id$
+ *
+ * @author Douglas C. Schmidt <schmidt@cs.wustl.edu>
+ * @author Jesper S. M|ller<stophph@diku.dk>
+ * @author and a cast of thousands...
+ *
+ * Originally in OS.h.
+ */
+//=============================================================================
+
+#ifndef ACE_OS_NS_SYS_TIME_H
+# define ACE_OS_NS_SYS_TIME_H
+
+# include /**/ "ace/pre.h"
+
+# include "ace/config-all.h"
+
+# if !defined (ACE_LACKS_PRAGMA_ONCE)
+# pragma once
+# endif /* ACE_LACKS_PRAGMA_ONCE */
+
+#include "ace/Time_Value.h"
+
+namespace ACE_OS {
+
+ ACE_Time_Value gettimeofday (void);
+
+} /* namespace ACE_OS */
+
+# if defined (ACE_HAS_INLINED_OSCALLS)
+# if defined (ACE_INLINE)
+# undef ACE_INLINE
+# endif /* ACE_INLINE */
+# define ACE_INLINE inline
+# include "ace/OS_NS_sys_time.inl"
+# endif /* ACE_HAS_INLINED_OSCALLS */
+
+# include /**/ "ace/post.h"
+#endif /* ACE_OS_NS_SYS_TIME_H */
diff --git a/ace/OS_NS_sys_time.inl b/ace/OS_NS_sys_time.inl
index fc532b41367..1db85317bb4 100644
--- a/ace/OS_NS_sys_time.inl
+++ b/ace/OS_NS_sys_time.inl
@@ -1,4 +1,72 @@
// -*- C++ -*-
// $Id$
-// This is a placeholder.
+#include "ace/os_include/sys/os_time.h"
+
+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)
+}
+
diff --git a/ace/OS_NS_sys_uio.cpp b/ace/OS_NS_sys_uio.cpp
index fc532b41367..f51dd4bc3fb 100644
--- a/ace/OS_NS_sys_uio.cpp
+++ b/ace/OS_NS_sys_uio.cpp
@@ -1,4 +1,114 @@
// -*- C++ -*-
// $Id$
-// This is a placeholder.
+#include "ace/OS_NS_sys_uio.h"
+
+ACE_RCSID(ace, OS_NS_sys_uio, "$Id$")
+
+#if !defined (ACE_HAS_INLINED_OSCALLS)
+# include "ace/OS_NS_sys_uio.inl"
+#endif /* ACE_HAS_INLINED_OS_CALLS */
+
+# 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;
+ ssize_t 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_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 */
diff --git a/ace/OS_NS_sys_uio.h b/ace/OS_NS_sys_uio.h
index fc532b41367..2910dbdde29 100644
--- a/ace/OS_NS_sys_uio.h
+++ b/ace/OS_NS_sys_uio.h
@@ -1,4 +1,65 @@
// -*- C++ -*-
-// $Id$
-// This is a placeholder.
+//=============================================================================
+/**
+ * @file OS_NS_sys_uio.h
+ *
+ * $Id$
+ *
+ * @author Douglas C. Schmidt <schmidt@cs.wustl.edu>
+ * @author Jesper S. M|ller<stophph@diku.dk>
+ * @author and a cast of thousands...
+ *
+ * Originally in OS.h.
+ */
+//=============================================================================
+
+#ifndef ACE_OS_NS_SYS_UIO_H
+# define ACE_OS_NS_SYS_UIO_H
+
+# include /**/ "ace/pre.h"
+
+# include "ace/config-all.h"
+
+# if !defined (ACE_LACKS_PRAGMA_ONCE)
+# pragma once
+# endif /* ACE_LACKS_PRAGMA_ONCE */
+
+#include "ace/os_include/sys/os_uio.h"
+
+namespace ACE_OS {
+
+ ssize_t readv (ACE_HANDLE handle,
+ iovec *iov,
+ int iovlen);
+
+#if defined (ACE_LACKS_READV)
+ ssize_t readv_emulation (ACE_HANDLE handle,
+ ACE_READV_TYPE *iov,
+ int iovcnt);
+#endif /* ACE_LACKS_READV */
+
+ ssize_t writev (ACE_HANDLE handle,
+ const iovec *iov,
+ int iovcnt);
+
+ // these don't need to be in the header, better to put them in the cpp
+ // or inl.
+#if defined (ACE_LACKS_WRITEV)
+ int writev_emulation (ACE_HANDLE handle,
+ ACE_WRITEV_TYPE *iov,
+ int iovcnt);
+#endif /* ACE_LACKS_WRITEV */
+
+} /* namespace ACE_OS */
+
+# if defined (ACE_HAS_INLINED_OSCALLS)
+# if defined (ACE_INLINE)
+# undef ACE_INLINE
+# endif /* ACE_INLINE */
+# define ACE_INLINE inline
+# include "ace/OS_NS_sys_uio.inl"
+# endif /* ACE_HAS_INLINED_OSCALLS */
+
+# include /**/ "ace/post.h"
+#endif /* ACE_OS_NS_SYS_UIO_H */
diff --git a/ace/OS_NS_sys_uio.inl b/ace/OS_NS_sys_uio.inl
index fc532b41367..2ffef0dc152 100644
--- a/ace/OS_NS_sys_uio.inl
+++ b/ace/OS_NS_sys_uio.inl
@@ -1,4 +1,35 @@
// -*- C++ -*-
// $Id$
-// This is a placeholder.
+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 */
+}
+
diff --git a/ace/OS_NS_sys_utsname.cpp b/ace/OS_NS_sys_utsname.cpp
index fc532b41367..a7ff514d951 100644
--- a/ace/OS_NS_sys_utsname.cpp
+++ b/ace/OS_NS_sys_utsname.cpp
@@ -1,4 +1,227 @@
// -*- C++ -*-
// $Id$
-// This is a placeholder.
+#include "ace/OS_NS_sys_utsname.h"
+
+ACE_RCSID(ace, OS_NS_sys_utsname, "$Id$")
+
+#if !defined (ACE_HAS_INLINED_OSCALLS)
+# include "ace/OS_NS_sys_utsname.inl"
+#endif /* ACE_HAS_INLINED_OS_CALLS */
+
+#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
+# if defined (VER_PLATFORM_WIN32_CE)
+ || vinfo.dwPlatformId == VER_PLATFORM_WIN32_CE
+# endif
+ )
+ {
+ // Get information from the two structures
+ const ACE_TCHAR *os;
+ if (vinfo.dwPlatformId == VER_PLATFORM_WIN32_NT)
+ os = ACE_LIB_TEXT ("Windows NT %d.%d");
+ else
+ os = ACE_LIB_TEXT ("Windows CE %d.%d");
+ ACE_OS::sprintf (name->release,
+ os,
+ (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;
+# if defined PROCESSOR_ARCHITECTURE_IA64
+ case PROCESSOR_ARCHITECTURE_IA64:
+ ACE_OS_String::strcpy (processor, ACE_LIB_TEXT ("Itanium"));
+ ACE_OS::sprintf (subtype, ACE_LIB_TEXT ("%d"),
+ sinfo.wProcessorLevel);
+ break;
+# endif
+# if defined PROCESSOR_ARCHITECTURE_ARM
+ case PROCESSOR_ARCHITECTURE_ARM:
+ ACE_OS_String::strcpy (processor, ACE_LIB_TEXT ("ARM"));
+ ACE_OS::sprintf (subtype, ACE_LIB_TEXT ("%d"),
+ sinfo.wProcessorLevel);
+ break;
+# endif
+ 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 */
diff --git a/ace/OS_NS_sys_utsname.h b/ace/OS_NS_sys_utsname.h
index fc532b41367..fd780b14afd 100644
--- a/ace/OS_NS_sys_utsname.h
+++ b/ace/OS_NS_sys_utsname.h
@@ -1,4 +1,63 @@
// -*- C++ -*-
-// $Id$
-// This is a placeholder.
+//=============================================================================
+/**
+ * @file OS_NS_sys_utsname.h
+ *
+ * $Id$
+ *
+ * @author Douglas C. Schmidt <schmidt@cs.wustl.edu>
+ * @author Jesper S. M|ller<stophph@diku.dk>
+ * @author and a cast of thousands...
+ *
+ * Originally in OS.h.
+ */
+//=============================================================================
+
+#ifndef ACE_OS_NS_SYS_UTSNAME_H
+# define ACE_OS_NS_SYS_UTSNAME_H
+
+# include /**/ "ace/pre.h"
+
+# include "ace/config-all.h"
+
+# if !defined (ACE_LACKS_PRAGMA_ONCE)
+# pragma once
+# endif /* ACE_LACKS_PRAGMA_ONCE */
+
+#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 "ace/os_include/sys/os_utsname.h"
+typedef struct utsname ACE_utsname;
+# endif /* ACE_LACKS_UTSNAME_T */
+
+namespace ACE_OS {
+
+ int uname (ACE_utsname *name);
+
+} /* namespace ACE_OS */
+
+# if defined (ACE_HAS_INLINED_OSCALLS)
+# if defined (ACE_INLINE)
+# undef ACE_INLINE
+# endif /* ACE_INLINE */
+# define ACE_INLINE inline
+# include "ace/OS_NS_sys_utsname.inl"
+# endif /* ACE_HAS_INLINED_OSCALLS */
+
+# include /**/ "ace/post.h"
+#endif /* ACE_OS_NS_SYS_UTSNAME_H */
diff --git a/ace/OS_NS_sys_utsname.inl b/ace/OS_NS_sys_utsname.inl
index fc532b41367..d2ca08ee515 100644
--- a/ace/OS_NS_sys_utsname.inl
+++ b/ace/OS_NS_sys_utsname.inl
@@ -1,4 +1,28 @@
// -*- C++ -*-
// $Id$
-// This is a placeholder.
+#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)
+{
+#if defined (INTEGRITY)
+ if(!name) {
+ errno = EFAULT;
+ return -1;
+ }
+ strcpy(name->sysname,"INTEGRITY");
+ int status = gethostname(name->nodename,_SYS_NMLN);
+ strcpy(name->release,"4.0");
+ strcpy(name->version,"4.0.9");
+ strcpy(name->machine,"a standard name");
+ return status;
+#else
+ ACE_OS_TRACE ("ACE_OS::uname");
+ ACE_OSCALL_RETURN (::uname (name), int, -1);
+#endif
+}
+#endif /* ! ACE_WIN32 && ! VXWORKS && ! CHORUS */
+
diff --git a/ace/OS_NS_sys_wait.cpp b/ace/OS_NS_sys_wait.cpp
index fc532b41367..0a1b8ee4d50 100644
--- a/ace/OS_NS_sys_wait.cpp
+++ b/ace/OS_NS_sys_wait.cpp
@@ -1,4 +1,10 @@
// -*- C++ -*-
// $Id$
-// This is a placeholder.
+#include "ace/OS_NS_sys_wait.h"
+
+ACE_RCSID(ace, OS_NS_sys_wait, "$Id$")
+
+#if !defined (ACE_HAS_INLINED_OSCALLS)
+# include "ace/OS_NS_sys_wait.inl"
+#endif /* ACE_HAS_INLINED_OS_CALLS */
diff --git a/ace/OS_NS_sys_wait.h b/ace/OS_NS_sys_wait.h
index fc532b41367..6551a42fd2f 100644
--- a/ace/OS_NS_sys_wait.h
+++ b/ace/OS_NS_sys_wait.h
@@ -1,4 +1,74 @@
// -*- C++ -*-
-// $Id$
-// This is a placeholder.
+//=============================================================================
+/**
+ * @file OS_NS_sys_wait.h
+ *
+ * $Id$
+ *
+ * @author Douglas C. Schmidt <schmidt@cs.wustl.edu>
+ * @author Jesper S. M|ller<stophph@diku.dk>
+ * @author and a cast of thousands...
+ *
+ * Originally in OS.h.
+ */
+//=============================================================================
+
+#ifndef ACE_OS_NS_SYS_WAIT_H
+# define ACE_OS_NS_SYS_WAIT_H
+
+# include /**/ "ace/pre.h"
+
+# include "ace/config-all.h"
+
+# if !defined (ACE_LACKS_PRAGMA_ONCE)
+# pragma once
+# endif /* ACE_LACKS_PRAGMA_ONCE */
+
+#include "ace/os_include/sys/os_wait.h"
+
+namespace ACE_OS {
+
+ /// Calls OS <::wait> function, so it's only portable to UNIX/POSIX
+ /// platforms.
+ pid_t wait (int * = 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.
+ */
+ pid_t wait (pid_t pid,
+ ACE_exitcode *status,
+ int wait_options = 0,
+ ACE_HANDLE handle = 0);
+
+ /**
+ * 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.
+ */
+ pid_t waitpid (pid_t pid,
+ ACE_exitcode *status = 0,
+ int wait_options = 0,
+ ACE_HANDLE handle = 0);
+
+} /* namespace ACE_OS */
+
+# if defined (ACE_HAS_INLINED_OSCALLS)
+# if defined (ACE_INLINE)
+# undef ACE_INLINE
+# endif /* ACE_INLINE */
+# define ACE_INLINE inline
+# include "ace/OS_NS_sys_wait.inl"
+# endif /* ACE_HAS_INLINED_OSCALLS */
+
+# include /**/ "ace/post.h"
+#endif /* ACE_OS_NS_SYS_WAIT_H */
diff --git a/ace/OS_NS_sys_wait.inl b/ace/OS_NS_sys_wait.inl
index fc532b41367..9c018294a2b 100644
--- a/ace/OS_NS_sys_wait.inl
+++ b/ace/OS_NS_sys_wait.inl
@@ -1,4 +1,105 @@
// -*- C++ -*-
// $Id$
-// This is a placeholder.
+ACE_INLINE pid_t
+ACE_OS::wait (int *status)
+{
+ ACE_OS_TRACE ("ACE_OS::wait");
+#if defined (ACE_WIN32) || defined (VXWORKS) || defined(CHORUS) || defined (ACE_PSOS) || defined (INTEGRITY)
+ 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_WIN32 || VXWORKS || CHORUS || ACE_PSOS */
+}
+
+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::waitpid (pid_t pid,
+ ACE_exitcode *status,
+ int wait_options,
+ ACE_HANDLE handle)
+{
+ ACE_OS_TRACE ("ACE_OS::waitpid");
+#if defined (VXWORKS) || defined (ACE_PSOS) || defined (INTEGRITY)
+ 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 /* VXWORKS || ACE_PSOS */
+}
+
diff --git a/ace/OS_NS_time.cpp b/ace/OS_NS_time.cpp
index fc532b41367..50d8d686759 100644
--- a/ace/OS_NS_time.cpp
+++ b/ace/OS_NS_time.cpp
@@ -1,4 +1,810 @@
// -*- C++ -*-
// $Id$
-// This is a placeholder.
+#include "ace/OS_NS_time.h"
+
+ACE_RCSID(ace, OS_NS_time, "$Id$")
+
+#if !defined (ACE_HAS_INLINED_OSCALLS)
+# include "ace/OS_NS_time.inl"
+#endif /* ACE_HAS_INLINED_OS_CALLS */
+
+#include "ace/OS_NS_Thread.h"
+#include "ace/Object_Manager_Base.h"
+
+// hmmm, should this be only for ACE_MT_SAFE? dhinton
+#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 */
+#endif /* ACE_MT_SAFE && ACE_MT_SAFE != 0 */
+
+# 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 (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.
+ {
+ errno = ERANGE;
+ 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_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 */
+
+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;
+ }
+#elif defined (ACE_HAS_WINCE)
+ // This is really stupid, converting FILETIME to timeval back and
+ // forth. It assumes FILETIME and DWORDLONG are the same structure
+ // internally.
+
+ TIME_ZONE_INFORMATION pTz;
+
+ const unsigned short int __mon_yday[2][13] =
+ {
+ /* Normal years. */
+ { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365 },
+ /* Leap years. */
+ { 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366 }
+ };
+
+ ULARGE_INTEGER _100ns;
+ ::GetTimeZoneInformation (&pTz);
+
+ _100ns.QuadPart = (DWORDLONG) *t * 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);
+
+ res->tm_hour = systime.wHour;
+
+ if(pTz.DaylightBias!=0)
+ res->tm_isdst = 1;
+ else
+ res->tm_isdst = 1;
+
+ int iLeap;
+ iLeap = (res->tm_year % 4 == 0 && (res->tm_year% 100 != 0 || res->tm_year % 400 == 0));
+ // based on leap select which group to use
+
+ res->tm_mday = systime.wDay;
+ res->tm_min = systime.wMinute;
+ res->tm_mon = systime.wMonth;
+ res->tm_sec = systime.wSecond;
+ res->tm_wday = systime.wDayOfWeek;
+ res->tm_yday = __mon_yday[iLeap][systime.wMonth] + systime.wDay;
+ res->tm_year = systime.wYear;// this the correct year but bias the value to start at the 1900
+ res->tm_year = res->tm_year - 1900;
+
+ 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 */
+}
+
+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);
+# elif defined (ACE_HAS_WINCE)
+ SYSTEMTIME t_sys;
+ FILETIME t_file;
+ t_sys.wSecond = t->tm_sec;
+ t_sys.wMinute = t->tm_min;
+ t_sys.wHour = t->tm_hour;
+ t_sys.wDay = t->tm_mday;
+ t_sys.wMonth = t->tm_mon + 1; // SYSTEMTIME is 1-indexed, tm is 0-indexed
+ t_sys.wYear = t->tm_year + 1900; // SYSTEMTIME is real; tm is since 1900
+ t_sys.wDayOfWeek = t->tm_wday; // Ignored in below function call.
+ if (SystemTimeToFileTime (&t_sys, &t_file) == 0)
+ return -1;
+ ACE_Time_Value tv (t_file);
+ return tv.sec ();
+# 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 */
+}
+
+#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_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 */
diff --git a/ace/OS_NS_time.h b/ace/OS_NS_time.h
index fc532b41367..635e0a0e522 100644
--- a/ace/OS_NS_time.h
+++ b/ace/OS_NS_time.h
@@ -1,4 +1,317 @@
// -*- C++ -*-
-// $Id$
-// This is a placeholder.
+//=============================================================================
+/**
+ * @file OS_NS_time.h
+ *
+ * $Id$
+ *
+ * @author Douglas C. Schmidt <schmidt@cs.wustl.edu>
+ * @author Jesper S. M|ller<stophph@diku.dk>
+ * @author and a cast of thousands...
+ *
+ * Originally in OS.h.
+ */
+//=============================================================================
+
+#ifndef ACE_OS_NS_TIME_H
+# define ACE_OS_NS_TIME_H
+
+# include /**/ "ace/pre.h"
+
+# include "ace/config-all.h"
+
+# if !defined (ACE_LACKS_PRAGMA_ONCE)
+# pragma once
+# endif /* ACE_LACKS_PRAGMA_ONCE */
+
+#include "ace/os_include/os_time.h"
+
+# if defined (ACE_HAS_BROKEN_R_ROUTINES)
+# undef ctime_r
+# undef asctime_r
+# endif /* ACE_HAS_BROKEN_R_ROUTINES */
+
+#include "ace/Basic_Types.h"
+
+// 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_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 */
+
+#if defined (ACE_HAS_WINCE)
+ /// Supporting data for ctime and ctime_r functions on WinCE.
+ const wchar_t *day_of_week_name[7];
+ const wchar_t *month_name[12];
+
+// WinCE doesn't have most of the standard C library time functions. It
+// also doesn't define struct tm. SYSTEMTIME has pretty much the same
+// info though, so we can map it when needed. Define struct tm here and
+// use it when needed. This is taken from the standard C library.
+struct tm {
+ int tm_sec;
+ int tm_min;
+ int tm_hour;
+ int tm_mday; // Day of the month
+ int tm_mon;
+ int tm_year;
+ int tm_wday; // Day of the week
+ int tm_yday; // Day in the year
+ int tm_isdst; // >0 if dst in effet; 0 if not; <0 if unknown
+};
+#endif /* ACE_HAS_WINCE */
+
+/// 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 (VXWORKS) && !defined (ACE_PSOS) && !defined (CHORUS)
+# if defined (ACE_HAS_WINCE)
+ TIME_ZONE_INFORMATION tz;
+ GetTimeZoneInformation (&tz);
+ return tz.Bias * 60;
+# elif defined (ACE_WIN32)
+ return _timezone; // For Win32.
+# elif ( defined (__Lynx__) || defined (__FreeBSD__) || defined (ACE_HAS_SUNOS4_GETTIMEOFDAY) ) && ( !defined (__linux__) )
+ 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__ ... */
+# if defined (__linux__)
+ // Under Linux, gettimeofday() does not correctly set the timezone
+ // struct, so we should use the global variable <timezone>.
+ // However, it is initialized by tzset(). I assume other systems
+ // are the same (i.e., tzset() needs to be called to set
+ // <timezone>), but since no one is complaining, I will only make
+ // the change for Linux.
+ ::tzset();
+# endif
+ 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_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_PSOS !ACE_PSOS_HAS_TIME */
+}
+#endif /* !ACE_LACKS_DIFFTIME */
+
+# if defined (ACE_WIN32)
+# 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
+# elif defined (ACE_PSOS)
+typedef ACE_UINT64 ACE_hrtime_t;
+# else /* !ACE_WIN32 && !ACE_PSOS */
+# 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 /* ACE_WIN32 */
+
+
+
+namespace ACE_OS {
+
+# 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 */
+
+ //@{ @name A set of wrappers for operations on time.
+
+ char *asctime (const struct tm *tm);
+
+ char *asctime_r (const struct tm *tm,
+ char *buf, int buflen);
+
+ int clock_gettime (clockid_t,
+ struct timespec *);
+
+ ACE_TCHAR *ctime (const time_t *t);
+
+ ACE_TCHAR *ctime_r (const time_t *clock, ACE_TCHAR *buf, int buflen);
+
+# if defined (difftime)
+# undef difftime
+# endif /* difftime */
+
+ double difftime (time_t t1,
+ time_t t0);
+
+ ACE_hrtime_t gethrtime (const ACE_HRTimer_Op = ACE_HRTIMER_GETTIME);
+
+ struct tm *gmtime (const time_t *clock);
+
+ struct tm *gmtime_r (const time_t *clock,
+ struct tm *res);
+
+ struct tm *localtime (const time_t *clock);
+
+ struct tm *localtime_r (const time_t *clock,
+ struct tm *res);
+
+ // Get the current time.
+ time_t mktime (struct tm *timeptr);
+
+ int nanosleep (const struct timespec *requested,
+ struct timespec *remaining = 0);
+
+# if defined (ACE_HAS_POWERPC_TIMER) && (defined (ghs) || defined (__GNUG__))
+ void readPPCTimeBase (u_long &most,
+ u_long &least);
+# endif /* ACE_HAS_POWERPC_TIMER && (ghs or __GNUG__) */
+
+ size_t strftime (char *s,
+ size_t maxsize,
+ const char *format,
+ const struct tm *timeptr);
+
+#if defined (ACE_HAS_STRPTIME)
+ char *strptime (char *buf,
+ const char *format,
+ struct tm *tm);
+
+# if defined (ACE_LACKS_NATIVE_STRPTIME)
+ int strptime_getnum (char *buf, int *num, int *bi,
+ int *fi, int min, int max);
+# endif /* ACE_LACKS_NATIVE_STRPTIME */
+#endif /* ACE_HAS_STRPTIME */
+
+ time_t time (time_t *tloc = 0);
+
+# if defined (timezone)
+# undef timezone
+# endif /* timezone */
+
+ long timezone (void);
+
+ // wrapper for time zone information.
+ void tzset (void);
+
+ //@}
+} /* namespace ACE_OS */
+
+# if defined (ACE_HAS_INLINED_OSCALLS)
+# if defined (ACE_INLINE)
+# undef ACE_INLINE
+# endif /* ACE_INLINE */
+# define ACE_INLINE inline
+# include "ace/OS_NS_time.inl"
+# endif /* ACE_HAS_INLINED_OSCALLS */
+
+# include /**/ "ace/post.h"
+#endif /* ACE_OS_NS_TIME_H */
diff --git a/ace/OS_NS_time.inl b/ace/OS_NS_time.inl
index fc532b41367..e67c033cf36 100644
--- a/ace/OS_NS_time.inl
+++ b/ace/OS_NS_time.inl
@@ -1,4 +1,488 @@
// -*- C++ -*-
// $Id$
-// This is a placeholder.
+#include "ace/OS_NS_string.h"
+#include "ace/OS_NS_errno.h"
+#include "ace/Time_Value.h"
+#include "ace/OS_NS_unistd.h"
+
+ACE_INLINE char *
+ACE_OS::asctime (const struct tm *t)
+{
+#if !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_WINCE && !ACE_PSOS || ACE_PSOS_HAS_TIME */
+}
+
+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_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_REENTRANT_FUNCTIONS */
+}
+
+ACE_INLINE int
+ACE_OS::clock_gettime (clockid_t clockid, struct timespec *ts)
+{
+ ACE_OS_TRACE ("ACE_OS::clock_gettime");
+#if 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_CLOCK_GETTIME */
+}
+
+// Magic number declaration and definition for ctime and ctime_r ()
+static const int ctime_buf_size = 26;
+
+ACE_INLINE ACE_TCHAR *
+ACE_OS::ctime (const time_t *t)
+{
+ ACE_OS_TRACE ("ACE_OS::ctime");
+#if 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)
+ static ACE_TCHAR buf [ctime_buf_size];
+ return ACE_OS::ctime_r (t,
+ buf,
+ ctime_buf_size);
+#elif defined (ACE_USES_WCHAR)
+ ACE_OSCALL_RETURN (::_wctime (t), wchar_t *, 0);
+#else
+ ACE_OSCALL_RETURN (::ctime (t), char *, 0);
+# endif /* ACE_HAS_BROKEN_CTIME */
+}
+
+#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_REENTRANT_FUNCTIONS)
+# if defined (ACE_HAS_2_PARAM_ASCTIME_R_AND_CTIME_R)
+ if (buflen < ctime_buf_size)
+ {
+ errno = ERANGE;
+ return 0;
+ }
+# if defined (DIGITAL_UNIX)
+ ACE_OSCALL_RETURN (::_Pctime_r (t, buf), ACE_TCHAR *, 0);
+# else /* DIGITAL_UNIX */
+ ACE_OSCALL_RETURN (::ctime_r (t, buf), ACE_TCHAR *, 0);
+# endif /* DIGITAL_UNIX */
+ 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 */
+ if (buflen < ctime_buf_size)
+ {
+ errno = ERANGE;
+ return 0;
+ }
+
+ ACE_TCHAR *result;
+# if defined (ACE_USES_WCHAR)
+ ACE_OSCALL (::_wctime (t), wchar_t *, 0, result);
+# else /* ACE_USES_WCHAR */
+ ACE_OSCALL (::ctime (t), char *, 0, result);
+# endif /* ACE_USES_WCHAR */
+ if (result != 0)
+ ACE_OS::strsncpy (buf, result, buflen);
+ return buf;
+# endif /* ACE_PSOS && !ACE_PSOS_HAS_TIME */
+#endif /* ACE_HAS_REENTRANT_FUNCTIONS */
+}
+#endif /* !ACE_HAS_WINCE */
+
+#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 */
+
+#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 struct tm *
+ACE_OS::gmtime (const time_t *t)
+{
+#if !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_WINCE && !ACE_PSOS || ACE_PSOS_HAS_TIME */
+}
+
+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_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_REENTRANT_FUNCTIONS */
+}
+
+ACE_INLINE struct tm *
+ACE_OS::localtime (const time_t *t)
+{
+#if !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_WINCE && !ACE_PSOS || ACE_PSOS_HAS_TIME */
+}
+
+ACE_INLINE int
+ACE_OS::nanosleep (const struct timespec *requested,
+ struct timespec *remaining)
+{
+ ACE_OS_TRACE ("ACE_OS::nanosleep");
+#if 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 size_t
+ACE_OS::strftime (char *s, size_t maxsize, const char *format,
+ const struct tm *timeptr)
+{
+#if !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_WINCE && !ACE_PSOS || ACE_PSOS_HAS_TIME */
+}
+
+ACE_INLINE time_t
+ACE_OS::time (time_t *tloc)
+{
+#if !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_WINCE */
+}
+
+// Linux won't compile unless we explicitly use a namespace here.
+#if defined (linux)
+namespace ACE_OS {
+ ACE_INLINE long
+ timezone (void)
+ {
+ return ::ace_timezone ();
+ }
+} /* namespace ACE_OS */
+#else
+ACE_INLINE long
+ACE_OS::timezone (void)
+{
+ return ::ace_timezone ();
+}
+#endif /* linux */
+
+ACE_INLINE void
+ACE_OS::tzset (void)
+{
+#if !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_WINCE && !VXWORKS && !ACE_PSOS && !__rtems__ */
+}
diff --git a/ace/OS_NS_unistd.cpp b/ace/OS_NS_unistd.cpp
index fc532b41367..4b17f4667df 100644
--- a/ace/OS_NS_unistd.cpp
+++ b/ace/OS_NS_unistd.cpp
@@ -1,4 +1,712 @@
// -*- C++ -*-
// $Id$
-// This is a placeholder.
+#include "ace/OS_NS_unistd.h"
+
+ACE_RCSID(ace, OS_NS_unistd, "$Id$")
+
+#if !defined (ACE_HAS_INLINED_OSCALLS)
+# include "ace/OS_NS_unistd.inl"
+#endif /* ACE_HAS_INLINED_OS_CALLS */
+
+#include "ace/Base_Thread_Adapter.h"
+#include "ace/OS_NS_stdlib.h"
+#include "ace/OS_NS_ctype.h"
+#include "ace/Default_Constants.h"
+#include "ace/OS_Memory.h"
+
+#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 */
+
+/*****************************************************************************/
+
+int
+ACE_OS::argv_to_string (ACE_TCHAR **argv,
+ ACE_TCHAR *&buf,
+ int substitute_env_args)
+{
+ if (argv == 0 || argv[0] == 0)
+ return 0;
+
+ size_t 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::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 */
+}
+
+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 */
+}
+
+// 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 */
+}
+
+long
+ACE_OS::num_processors (void)
+{
+ ACE_OS_TRACE ("ACE_OS::num_processors");
+
+#if defined (ACE_HAS_PHARLAP)
+ return 1;
+#elif defined (ACE_WIN32) || defined (ACE_WIN64)
+ SYSTEM_INFO sys_info;
+ ::GetSystemInfo (&sys_info);
+ return sys_info.dwNumberOfProcessors;
+#elif defined (linux) || defined (sun)
+ return ::sysconf (_SC_NPROCESSORS_CONF);
+#else
+ ACE_NOTSUP_RETURN (-1);
+#endif
+}
+
+long
+ACE_OS::num_processors_online (void)
+{
+ ACE_OS_TRACE ("ACE_OS::num_processors_online");
+
+#if defined (ACE_HAS_PHARLAP)
+ return 1;
+#elif defined (ACE_WIN32) || defined (ACE_WIN64)
+ SYSTEM_INFO sys_info;
+ ::GetSystemInfo (&sys_info);
+ return sys_info.dwNumberOfProcessors;
+#elif defined (linux) || defined (sun)
+ return ::sysconf (_SC_NPROCESSORS_ONLN);
+#elif defined (__hpux)
+ struct pst_dynamic psd;
+ if (::pstat_getdynamic (&psd, sizeof (psd), (size_t) 1, 0) != -1)
+ return psd.psd_proc_cnt;
+ else
+ return -1;
+#else
+ ACE_NOTSUP_RETURN (-1);
+#endif
+}
+
+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;
+}
+
+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,
+ 0,
+ FILE_CURRENT);
+
+ if (original_position == 0xFFFFFFFF)
+ return -1;
+
+ // Go to the correct position
+ DWORD altered_position = ::SetFilePointer (handle,
+ offset,
+ 0,
+ 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,
+ ACE_static_cast (DWORD, 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,
+ 0);
+ if (result == FALSE)
+ return -1;
+
+# endif /* ACE_HAS_WINNT4 && (ACE_HAS_WINNT4 != 0) */
+
+ // Reset the original file pointer position
+ if (::SetFilePointer (handle,
+ original_position,
+ 0,
+ 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,
+ 0,
+ FILE_CURRENT);
+
+ if (original_position == 0xFFFFFFFF)
+ return -1;
+
+ // Go to the correct position
+ DWORD altered_position = ::SetFilePointer (handle,
+ offset,
+ 0,
+ 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,
+ ACE_static_cast (DWORD, 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,
+ 0);
+ if (result == FALSE)
+ return -1;
+
+# endif /* ACE_HAS_WINNT4 && (ACE_HAS_WINNT4 != 0) */
+
+ // Reset the original file pointer position
+ if (::SetFilePointer (handle,
+ original_position,
+ 0,
+ 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 */
+}
+
+int
+ACE_OS::string_to_argv (ACE_TCHAR *buf,
+ int &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 != ACE_LIB_TEXT ('\0') && *cp != ACE_LIB_TEXT ('#'))
+ {
+ // Skip whitespace..
+ while (ACE_OS::ace_isspace (*cp))
+ cp++;
+
+ // Increment count and move to next whitespace..
+ if (*cp != ACE_LIB_TEXT ('\0'))
+ argc++;
+
+ while (*cp != ACE_LIB_TEXT ('\0') && !ACE_OS::ace_isspace (*cp))
+ {
+ // Grok quotes....
+ if (*cp == ACE_LIB_TEXT ('\'') || *cp == ACE_LIB_TEXT ('"'))
+ {
+ ACE_TCHAR quote = *cp;
+
+ // Scan past the string..
+ for (cp++; *cp != ACE_LIB_TEXT ('\0') && *cp != quote; cp++)
+ continue;
+
+ // '\0' implies unmatched quote..
+ if (*cp == ACE_LIB_TEXT ('\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 (int 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 != ACE_LIB_TEXT ('\0') && !ACE_OS::ace_isspace (*ptr))
+ if (*ptr == ACE_LIB_TEXT ('\'') || *ptr == ACE_LIB_TEXT ('"'))
+ {
+ ACE_TCHAR quote = *ptr++;
+
+ while (*ptr != ACE_LIB_TEXT ('\0') && *ptr != quote)
+ *cp++ = *ptr++;
+
+ if (*ptr == quote)
+ ptr++;
+ }
+ else
+ *cp++ = *ptr++;
+
+ *cp = ACE_LIB_TEXT ('\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;
+}
+
+// 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;
+}
+
diff --git a/ace/OS_NS_unistd.h b/ace/OS_NS_unistd.h
index fc532b41367..51f67f62f74 100644
--- a/ace/OS_NS_unistd.h
+++ b/ace/OS_NS_unistd.h
@@ -1,4 +1,264 @@
// -*- C++ -*-
-// $Id$
-// This is a placeholder.
+//=============================================================================
+/**
+ * @file OS_NS_unistd.h
+ *
+ * $Id$
+ *
+ * @author Douglas C. Schmidt <schmidt@cs.wustl.edu>
+ * @author Jesper S. M|ller<stophph@diku.dk>
+ * @author and a cast of thousands...
+ *
+ * Originally in OS.h.
+ */
+//=============================================================================
+
+#ifndef ACE_OS_NS_UNISTD_H
+# define ACE_OS_NS_UNISTD_H
+
+# include /**/ "ace/pre.h"
+
+# include "ace/config-all.h"
+
+# if !defined (ACE_LACKS_PRAGMA_ONCE)
+# pragma once
+# endif /* ACE_LACKS_PRAGMA_ONCE */
+
+#include "ace/os_include/os_unistd.h"
+#include "ace/Time_Value.h"
+#include "ace/os_include/os_stdio.h"
+
+// This should go in os_unistd.h, but since we don't yet implement any code
+// at that level, we put it here. It used to be in OS.i.
+#if defined (ACE_NEEDS_FTRUNCATE)
+extern "C" ACE_Export int ftruncate (ACE_HANDLE handle, long len);
+#endif /* ACE_NEEDS_FTRUNCATE */
+
+namespace ACE_OS {
+
+ int access (const char *path, int amode);
+
+#if defined (ACE_HAS_WCHAR)
+ int access (const wchar_t *path, int amode);
+#endif /* ACE_HAS_WCHAR */
+
+ unsigned int alarm (u_int secs);
+
+ int allocation_granularity (void);
+
+ // used by ARGV::argv_to_string() and ACE_OS::fork_exec()
+ int argv_to_string (ACE_TCHAR **argv,
+ ACE_TCHAR *&buf,
+ int substitute_env_args = 1);
+
+#if !defined (ACE_LACKS_CHDIR)
+ int chdir (const char *path);
+
+#if defined (ACE_HAS_WCHAR)
+ int chdir (const wchar_t *path);
+#endif /* ACE_HAS_WCHAR */
+#endif /* ACE_LACKS_CHDIR */
+
+ int close (ACE_HANDLE handle);
+
+ ACE_HANDLE dup (ACE_HANDLE handle);
+
+ int dup2 (ACE_HANDLE oldfd,
+ ACE_HANDLE newfd);
+
+ int execl (const char *path,
+ const char *arg0, ...);
+
+ int execle (const char *path,
+ const char *arg0, ...);
+
+ int execlp (const char *file,
+ const char *arg0, ...);
+
+ int execv (const char *path,
+ char *const argv[]);
+
+ int execve (const char *path,
+ char *const argv[],
+ char *const envp[]);
+
+ int execvp (const char *file,
+ char *const argv[]);
+
+ //@{
+ /// 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.
+ pid_t fork (void);
+
+ // not in susv3
+ pid_t fork (const ACE_TCHAR *program_name);
+
+ pid_t fork_exec (ACE_TCHAR *argv[]);
+
+ //@}
+
+ int fsync (ACE_HANDLE handle);
+
+ int ftruncate (ACE_HANDLE,
+ off_t);
+
+ ACE_TCHAR *getcwd (ACE_TCHAR *, size_t);
+
+ gid_t getgid (void);
+
+ int getopt (int argc,
+ char *const *argv,
+ const char *optstring);
+
+ int getpagesize (void);
+
+ pid_t getpgid (pid_t pid);
+
+ pid_t getpid (void);
+
+ pid_t getppid (void);
+
+ uid_t getuid (void);
+
+ // should call gethostname()
+ int hostname (char *name,
+ size_t maxnamelen);
+
+#if defined (ACE_HAS_WCHAR)
+ int hostname (wchar_t *name,
+ size_t maxnamelen);
+#endif /* ACE_HAS_WCHAR */
+
+ int isatty (int handle);
+
+#if defined (ACE_WIN32)
+ int isatty (ACE_HANDLE handle);
+#endif /* ACE_WIN32 */
+
+ off_t lseek (ACE_HANDLE handle,
+ off_t offset,
+ int whence);
+
+#if defined (ACE_HAS_LLSEEK) || defined (ACE_HAS_LSEEK64)
+ ACE_LOFF_T llseek (ACE_HANDLE handle, ACE_LOFF_T offset, int whence);
+#endif /* ACE_HAS_LLSEEK */
+
+ /// Get the number of CPUs configured in the machine.
+ long num_processors (void);
+
+ /// Get the number of CPUs currently online.
+ long num_processors_online (void);
+
+ int pipe (ACE_HANDLE handles[]);
+
+ ssize_t pread (ACE_HANDLE handle,
+ void *buf,
+ size_t nbyte,
+ off_t offset);
+
+ ssize_t pwrite (ACE_HANDLE handle,
+ const void *buf,
+ size_t nbyte,
+ off_t offset);
+
+ ssize_t read (ACE_HANDLE handle,
+ void *buf,
+ size_t len);
+
+ 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
+ * read will be returned to the caller through<bytes_transferred>.
+ *
+ */
+ ssize_t read_n (ACE_HANDLE handle,
+ void *buf,
+ size_t len,
+ size_t *bytes_transferred = 0);
+
+ int readlink (const char *path,
+ char *buf,
+ size_t bufsiz);
+
+ void *sbrk (int brk);
+
+ int setgid (gid_t);
+
+ int setpgid (pid_t pid, pid_t pgid);
+
+ int setregid (gid_t rgid, gid_t egid);
+
+ int setreuid (uid_t ruid, uid_t euid);
+
+ pid_t setsid (void);
+
+ int setuid (uid_t);
+
+ int sleep (u_int seconds);
+
+ int sleep (const ACE_Time_Value &tv);
+
+ // used by ARGV::string_to_argv
+ int string_to_argv (ACE_TCHAR *buf,
+ int &argc,
+ ACE_TCHAR **&argv,
+ int substitute_env_args = 1);
+
+ long sysconf (int);
+
+ // not in susv3
+ long sysinfo (int cmd,
+ char *buf,
+ long count);
+
+ int truncate (const ACE_TCHAR *filename, off_t length);
+
+ u_int ualarm (u_int usecs,
+ u_int interval = 0);
+
+ u_int ualarm (const ACE_Time_Value &tv,
+ const ACE_Time_Value &tv_interval = ACE_Time_Value::zero);
+
+ int unlink (const ACE_TCHAR *path);
+
+ ssize_t write (ACE_HANDLE handle,
+ const void *buf,
+ size_t nbyte);
+
+ 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>.
+ */
+ ssize_t write_n (ACE_HANDLE handle,
+ const void *buf,
+ size_t len,
+ size_t *bytes_transferred = 0);
+
+} /* namespace ACE_OS */
+
+# if defined (ACE_HAS_INLINED_OSCALLS)
+# if defined (ACE_INLINE)
+# undef ACE_INLINE
+# endif /* ACE_INLINE */
+# define ACE_INLINE inline
+# include "ace/OS_NS_unistd.inl"
+# endif /* ACE_HAS_INLINED_OSCALLS */
+
+# include /**/ "ace/post.h"
+#endif /* ACE_OS_NS_UNISTD_H */
diff --git a/ace/OS_NS_unistd.inl b/ace/OS_NS_unistd.inl
index fc532b41367..43c2348c9ff 100644
--- a/ace/OS_NS_unistd.inl
+++ b/ace/OS_NS_unistd.inl
@@ -1,4 +1,1222 @@
// -*- C++ -*-
// $Id$
-// This is a placeholder.
+#include "ace/OS_NS_sys_utsname.h"
+#include "ace/OS_NS_string.h"
+#include "ace/OS_NS_errno.h"
+
+ACE_INLINE int
+ACE_OS::access (const char *path, int amode)
+{
+ ACE_OS_TRACE ("ACE_OS::access");
+#if defined (ACE_LACKS_ACCESS)
+# if 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 (ACE_TEXT_CHAR_TO_TCHAR(path), ACE_LIB_TEXT ("r"));
+ ACE_UNUSED_ARG (amode);
+
+ ACE_OS::fclose (handle);
+ return (handle == ACE_INVALID_HANDLE ? -1 : 0);
+# elif defined (VXWORKS)
+ FILE* handle = ACE_OS::fopen (ACE_TEXT_CHAR_TO_TCHAR(path), ACE_LIB_TEXT ("r"));
+ ACE_UNUSED_ARG (amode);
+ if (handle != 0)
+ {
+ ACE_OS::fclose (handle);
+ return 0;
+ }
+ return (-1);
+# else
+ ACE_UNUSED_ARG (path);
+ ACE_UNUSED_ARG (amode);
+ ACE_NOTSUP_RETURN (-1);
+# endif // ACE_HAS_WINCE
+#else
+ ACE_OSCALL_RETURN (::access (path, amode), int, -1);
+#endif /* ACE_LACKS_ACCESS */
+}
+
+
+#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 u_int
+ACE_OS::alarm (u_int secs)
+{
+ ACE_OS_TRACE ("ACE_OS::alarm");
+#if defined (ACE_WIN32) || defined (VXWORKS) || defined (CHORUS) || defined (ACE_PSOS)
+ ACE_UNUSED_ARG (secs);
+
+ ACE_NOTSUP_RETURN (0);
+#else
+ return ::alarm (secs);
+#endif /* ACE_WIN32 || VXWORKS || CHORUS || ACE_PSOS */
+}
+
+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 */
+}
+
+#if !defined (ACE_LACKS_CHDIR)
+ACE_INLINE int
+ACE_OS::chdir (const char *path)
+{
+ ACE_OS_TRACE ("ACE_OS::chdir");
+#if 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 /* VXWORKS */
+}
+
+#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 */
+
+// @todo: which 4 and why??? dhinton
+// 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_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_WIN32 */
+}
+
+ACE_INLINE ACE_HANDLE
+ACE_OS::dup (ACE_HANDLE handle)
+{
+ ACE_OS_TRACE ("ACE_OS::dup");
+#if 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_WIN32 && !ACE_HAS_WINCE */
+}
+
+ACE_INLINE int
+ACE_OS::dup2 (ACE_HANDLE oldhandle, ACE_HANDLE newhandle)
+{
+ ACE_OS_TRACE ("ACE_OS::dup2");
+#if 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_WIN32 || VXWORKS || ACE_PSOS */
+}
+
+ACE_INLINE int
+ACE_OS::execv (const char *path,
+ char *const argv[])
+{
+ ACE_OS_TRACE ("ACE_OS::execv");
+#if 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_LACKS_EXEC */
+}
+
+ACE_INLINE int
+ACE_OS::execve (const char *path,
+ char *const argv[],
+ char *const envp[])
+{
+ ACE_OS_TRACE ("ACE_OS::execve");
+#if 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_LACKS_EXEC */
+}
+
+ACE_INLINE int
+ACE_OS::execvp (const char *file,
+ char *const argv[])
+{
+ ACE_OS_TRACE ("ACE_OS::execvp");
+#if 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_LACKS_EXEC */
+}
+
+ACE_INLINE pid_t
+ACE_OS::fork (void)
+{
+ ACE_OS_TRACE ("ACE_OS::fork");
+#if defined (ACE_LACKS_FORK)
+ ACE_NOTSUP_RETURN (pid_t (-1));
+#else
+ ACE_OSCALL_RETURN (::fork (), pid_t, -1);
+#endif /* ACE_LACKS_FORK */
+}
+
+ACE_INLINE int
+ACE_OS::fsync (ACE_HANDLE handle)
+{
+ ACE_OS_TRACE ("ACE_OS::fsync");
+# if defined (ACE_LACKS_FSYNC)
+ ACE_UNUSED_ARG (handle);
+ ACE_NOTSUP_RETURN (-1);
+# else
+ ACE_OSCALL_RETURN (::fsync (handle), int, -1);
+# endif /* ACE_LACKS_FSYNC */
+}
+
+ACE_INLINE int
+ACE_OS::ftruncate (ACE_HANDLE handle, off_t offset)
+{
+ ACE_OS_TRACE ("ACE_OS::ftruncate");
+#if defined (ACE_WIN32)
+ if (::SetFilePointer (handle, offset, 0, 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_WIN32 */
+}
+
+ACE_INLINE ACE_TCHAR *
+ACE_OS::getcwd (ACE_TCHAR *buf, size_t size)
+{
+ ACE_OS_TRACE ("ACE_OS::getcwd");
+#if 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)
+# if defined (ACE_USES_WCHAR)
+ return ::_wgetcwd (buf, ACE_static_cast (int, size));
+# else
+ return ::getcwd (buf, ACE_static_cast (int, size));
+# endif /* ACE_USES_WCHAR */
+#else
+ ACE_OSCALL_RETURN (::getcwd (buf, size), char *, 0);
+#endif /* ACE_PSOS_LACKS_PHILE */
+}
+
+ACE_INLINE gid_t
+ACE_OS::getgid (void)
+{
+ ACE_OS_TRACE ("ACE_OS::getgid");
+#if defined (VXWORKS) || defined (ACE_PSOS) || defined (INTEGRITY)
+ // 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 /* VXWORKS || ACE_PSOS */
+}
+
+#if !defined (ACE_WIN32)
+
+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) || defined (INTEGRITY)
+ 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 */
+}
+
+#else /* ACE_WIN32 */
+
+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);
+}
+
+#endif /* !ACE_WIN32 */
+
+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 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::getpid (void)
+{
+ // ACE_OS_TRACE ("ACE_OS::getpid");
+#if 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_WIN32 */
+}
+
+ACE_INLINE pid_t
+ACE_OS::getppid (void)
+{
+ ACE_OS_TRACE ("ACE_OS::getppid");
+#if 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_LACKS_GETPPID */
+}
+
+ACE_INLINE uid_t
+ACE_OS::getuid (void)
+{
+ ACE_OS_TRACE ("ACE_OS::getuid");
+#if defined (VXWORKS) || defined (ACE_PSOS) || defined (INTEGRITY)
+ // 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 /* VXWORKS || ACE_PSOS */
+}
+
+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::isatty (int handle)
+{
+#if 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
+# if defined (ACE_WIN64)
+ int fd = ::_open_osfhandle (intptr_t (handle), 0);
+# else
+ int fd = ::_open_osfhandle (long (handle), 0);
+# endif /* ACE_WIN64 */
+
+ int status = ::_isatty (fd);
+ ::_close (fd);
+ return status;
+#endif /* ACE_LACKS_ISATTY */
+}
+
+#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_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, 0, 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_WIN32 */
+}
+
+#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 ssize_t
+ACE_OS::read (ACE_HANDLE handle, void *buf, size_t len)
+{
+ ACE_OS_TRACE ("ACE_OS::read");
+#if defined (ACE_WIN32)
+ DWORD ok_len;
+ if (::ReadFile (handle, buf, ACE_static_cast (DWORD, 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_WIN32 */
+}
+
+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;
+ DWORD short_len = ACE_static_cast (DWORD, len);
+ if (::ReadFile (handle, buf, short_len, &ok_len, overlapped))
+ return (ssize_t) ok_len;
+ else
+ ACE_FAIL_RETURN (-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 */
+}
+
+#if !defined (ACE_WIN32)
+
+ACE_INLINE int
+ACE_OS::pipe (ACE_HANDLE fds[])
+{
+ ACE_OS_TRACE ("ACE_OS::pipe");
+# if defined (VXWORKS) || defined (ACE_PSOS) || defined (INTEGRITY)
+ ACE_UNUSED_ARG (fds);
+ ACE_NOTSUP_RETURN (-1);
+# else
+ ACE_OSCALL_RETURN (::pipe (fds), int, -1);
+# endif /* VXWORKS || ACE_PSOS */
+}
+
+#else /* ACE_WIN32 */
+
+ACE_INLINE int
+ACE_OS::pipe (ACE_HANDLE fds[])
+{
+# if !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_WINCE && !__IBMCPP__ */
+}
+
+#endif /* !ACE_WIN32 */
+
+ACE_INLINE void *
+ACE_OS::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 int
+ACE_OS::setgid (gid_t gid)
+{
+ ACE_OS_TRACE ("ACE_OS::setgid");
+#if defined (VXWORKS) || defined (ACE_PSOS) || defined (INTEGRITY)
+ // 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 /* VXWORKS || ACE_PSOS */
+}
+
+ACE_INLINE int
+ACE_OS::setpgid (pid_t pid, pid_t pgid)
+{
+ ACE_OS_TRACE ("ACE_OS::setpgid");
+#if 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_LACKS_SETPGID */
+}
+
+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 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 */
+}
+
+#if !defined (ACE_WIN32)
+
+ACE_INLINE pid_t
+ACE_OS::setsid (void)
+{
+ ACE_OS_TRACE ("ACE_OS::setsid");
+# if defined (VXWORKS) || defined (CHORUS) || defined (ACE_PSOS) || defined (INTEGRITY)
+ ACE_NOTSUP_RETURN (-1);
+# else
+ ACE_OSCALL_RETURN (::setsid (), int, -1);
+# endif /* VXWORKS || CHORUS || ACE_PSOS */
+}
+
+#else /* ACE_WIN32 */
+
+ACE_INLINE pid_t
+ACE_OS::setsid (void)
+{
+ ACE_OS_TRACE ("ACE_OS::setsid");
+ ACE_NOTSUP_RETURN (-1);
+}
+
+#endif /* WIN32 */
+
+ACE_INLINE int
+ACE_OS::setuid (uid_t uid)
+{
+ ACE_OS_TRACE ("ACE_OS::setuid");
+#if defined (VXWORKS) || defined (ACE_PSOS) || defined (INTEGRITY)
+ // 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 /* VXWORKS || ACE_PSOS */
+}
+
+ACE_INLINE int
+ACE_OS::sleep (u_int seconds)
+{
+ ACE_OS_TRACE ("ACE_OS::sleep");
+#if 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 long
+ACE_OS::sysconf (int name)
+{
+ ACE_OS_TRACE ("ACE_OS::sysconf");
+#if defined (ACE_WIN32) || defined (VXWORKS) || defined (ACE_PSOS) || defined (INTEGRITY)
+ ACE_UNUSED_ARG (name);
+ ACE_NOTSUP_RETURN (-1);
+#else
+ ACE_OSCALL_RETURN (::sysconf (name), long, -1);
+#endif /* ACE_WIN32 || VXWORKS || ACE_PSOS */
+}
+
+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 int
+ACE_OS::truncate (const ACE_TCHAR *filename,
+ off_t offset)
+{
+ ACE_OS_TRACE ("ACE_OS::truncate");
+#if 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,
+ 0,
+ 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_WIN32 */
+}
+
+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::unlink (const ACE_TCHAR *path)
+{
+ ACE_OS_TRACE ("ACE_OS::unlink");
+# if 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 /* VXWORKS */
+}
+
+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_WIN32)
+ DWORD bytes_written; // This is set to 0 byte WriteFile.
+
+ // Strictly correctly, we should loop writing all the data if more
+ // than a DWORD length can hold.
+ DWORD short_nbyte = ACE_static_cast (DWORD, nbyte);
+ if (::WriteFile (handle, buf, short_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_WIN32 */
+}
+
+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.
+
+ DWORD short_nbyte = ACE_static_cast (DWORD, nbyte);
+ if (::WriteFile (handle, buf, short_nbyte, &bytes_written, overlapped))
+ return (ssize_t) bytes_written;
+ else
+ return -1;
+#else
+ return ACE_OS::write (handle, buf, nbyte);
+#endif /* ACE_WIN32 */
+}
+
diff --git a/ace/OS_NS_wchar.cpp b/ace/OS_NS_wchar.cpp
index fc532b41367..e934c9378ca 100644
--- a/ace/OS_NS_wchar.cpp
+++ b/ace/OS_NS_wchar.cpp
@@ -1,4 +1,370 @@
// -*- C++ -*-
// $Id$
-// This is a placeholder.
+#include "ace/OS_NS_wchar.h"
+
+ACE_RCSID(ace, OS_NS_wchar, "$Id$")
+
+#if !defined (ACE_HAS_INLINED_OSCALLS)
+# include "ace/OS_NS_wchar.inl"
+#endif /* ACE_HAS_INLINED_OS_CALLS */
+
+// 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::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_HAS_WCHAR) && defined (ACE_LACKS_WCSCHR)
+wchar_t *
+ACE_OS::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 0;
+}
+#endif /* ACE_HAS_WCHAR && ACE_LACKS_WCSCHR */
+
+#if !defined (ACE_HAS_WCHAR) || defined (ACE_LACKS_WCSCMP)
+int
+ACE_OS::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::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_HAS_WCHAR) && defined (ACE_LACKS_WCSCSPN)
+size_t
+ACE_OS::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 */
+
+#if defined (ACE_HAS_WCHAR) && defined (ACE_LACKS_WCSICMP)
+int
+ACE_OS::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::to_lower (*scan1)
+ == ACE_OS::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::to_lower (*scan1) - ACE_OS::to_lower (*scan2);
+}
+#endif /* ACE_HAS_WCHAR && ACE_LACKS_WCSICMP */
+
+#if !defined (ACE_HAS_WCHAR) || defined (ACE_LACKS_WCSLEN)
+size_t
+ACE_OS::wcslen_emulation (const ACE_WCHAR_T *string)
+{
+ const ACE_WCHAR_T *s;
+
+ for (s = string; *s; ++s)
+ continue;
+
+ return s - string;
+}
+#endif /* !ACE_HAS_WCHAR || ACE_LACKS_WCSLEN */
+
+#if !defined (ACE_HAS_WCHAR) || defined (ACE_LACKS_WCSNCAT)
+ACE_WCHAR_T *
+ACE_OS::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_WCSNCMP)
+int
+ACE_OS::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_HAS_WCHAR) || defined (ACE_LACKS_WCSNCPY)
+ACE_WCHAR_T *
+ACE_OS::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_WCSNICMP)
+int
+ACE_OS::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::to_lower (*scan1)
+ == ACE_OS::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::to_lower (*scan1) - ACE_OS::to_lower (*scan2);
+}
+#endif /* ACE_HAS_WCHAR && ACE_LACKS_WCSNICMP */
+
+#if defined (ACE_HAS_WCHAR) && defined (ACE_LACKS_WCSPBRK)
+wchar_t *
+ACE_OS::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 0;
+}
+#endif /* ACE_HAS_WCHAR && ACE_LACKS_WCSPBRK */
+
+#if defined (ACE_HAS_WCHAR) && defined (ACE_LACKS_WCSRCHR)
+const wchar_t *
+ACE_OS::wcsrchr_emulation (const wchar_t *s, wint_t c)
+{
+ const wchar_t *p = s + ACE_OS::strlen (s);
+
+ while (*p != ACE_static_cast (wchar_t, c))
+ if (p == s)
+ return 0;
+ else
+ p--;
+
+ return p;
+}
+
+wchar_t *
+ACE_OS::wcsrchr_emulation (wchar_t *s, wint_t c)
+{
+ wchar_t *p = s + ACE_OS::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 */
+
+#if defined (ACE_HAS_WCHAR) && defined (ACE_LACKS_WCSSPN)
+size_t
+ACE_OS::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::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 0;
+ } while (sc != c);
+ } while (strncmp(string, charset, len) != 0);
+ string--;
+ }
+
+ return ACE_const_cast (wchar_t *, string);
+}
+#endif /* ACE_HAS_WCHAR && ACE_LACKS_WCSSTR */
+
diff --git a/ace/OS_NS_wchar.h b/ace/OS_NS_wchar.h
index fc532b41367..9d113747232 100644
--- a/ace/OS_NS_wchar.h
+++ b/ace/OS_NS_wchar.h
@@ -1,4 +1,162 @@
// -*- C++ -*-
-// $Id$
-// This is a placeholder.
+//=============================================================================
+/**
+ * @file OS_NS_wchar.h
+ *
+ * $Id$
+ *
+ * @author Douglas C. Schmidt <schmidt@cs.wustl.edu>
+ * @author Jesper S. M|ller<stophph@diku.dk>
+ * @author and a cast of thousands...
+ *
+ * Originally in OS.h.
+ */
+//=============================================================================
+
+#ifndef ACE_OS_NS_WCHAR_H
+# define ACE_OS_NS_WCHAR_H
+
+# include /**/ "ace/pre.h"
+
+# include "ace/config-all.h"
+
+# if !defined (ACE_LACKS_PRAGMA_ONCE)
+# pragma once
+# endif /* ACE_LACKS_PRAGMA_ONCE */
+
+#include "ace/os_include/os_wchar.h"
+#include "ace/Basic_Types.h"
+
+namespace ACE_OS {
+
+//#if defined (ACE_HAS_WCHAR)
+ typedef ACE_WCHAR_T WChar;
+
+ wint_t fgetwc (FILE* fp);
+
+#if defined (ACE_HAS_WCHAR) && defined (ACE_LACKS_WCSCAT)
+ /// Emulated wcscat - Appends a string.
+ 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.
+ 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.
+ 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.
+ 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_WCSCSPN)
+ /// Emulated wcscspn.
+ 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_WCSICMP)
+ /// Emulated wcsicmp - Performs a case insensitive comparison of strings.
+ 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.
+ 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.
+ 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.
+ 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.
+ 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
+ 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.
+ 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.
+ 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.
+ 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_WCSSPN)
+ /// Emulated wcsspn.
+ 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.
+ wchar_t *wcsstr_emulation (const wchar_t *string,
+ const wchar_t *charset);
+#endif /* ACE_HAS_WCHAR && ACE_LACKS_WCSSTR */
+
+ // these are named wrong. should be wcslen, etc... dhinton
+ u_int wslen (const WChar *);
+
+ WChar *wscpy (WChar *,
+ const WChar *);
+
+ int wscmp (const WChar *,
+ const WChar *);
+
+ int wsncmp (const WChar *,
+ const WChar *,
+ size_t len);
+
+ wint_t ungetwc (wint_t c, FILE* fp);
+
+} /* namespace ACE_OS */
+
+//#endif /* ACE_HAS_WCHAR */
+
+# if defined (ACE_HAS_INLINED_OSCALLS)
+# if defined (ACE_INLINE)
+# undef ACE_INLINE
+# endif /* ACE_INLINE */
+# define ACE_INLINE inline
+# include "ace/OS_NS_wchar.inl"
+# endif /* ACE_HAS_INLINED_OSCALLS */
+
+# include /**/ "ace/post.h"
+#endif /* ACE_OS_NS_STDIO_H */
diff --git a/ace/OS_NS_wchar.inl b/ace/OS_NS_wchar.inl
index fc532b41367..26caa1a43d0 100644
--- a/ace/OS_NS_wchar.inl
+++ b/ace/OS_NS_wchar.inl
@@ -1,4 +1,83 @@
// -*- C++ -*-
// $Id$
-// This is a placeholder.
+#if defined (ACE_HAS_WCHAR)
+ACE_INLINE wint_t
+ACE_OS::fgetwc (FILE* fp)
+{
+#if defined (ACE_LACKS_FGETWC)
+ ACE_UNUSED_ARG (fp);
+ ACE_NOTSUP_RETURN (0);
+#else
+ ACE_OSCALL_RETURN (::fgetwc (fp), wint_t, WEOF);
+#endif /* ACE_LACKS_FGETWC */
+}
+#endif /* ACE_HAS_WCHAR */
+
+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_HAS_WCHAR)
+ACE_INLINE wint_t
+ACE_OS::ungetwc (wint_t c, FILE* fp)
+{
+#if defined (ACE_LACKS_FGETWC)
+ ACE_UNUSED_ARG (c);
+ ACE_UNUSED_ARG (fp);
+ ACE_NOTSUP_RETURN (0);
+#else
+ ACE_OSCALL_RETURN (::ungetwc (c, fp), wint_t, WEOF);
+#endif /* ACE_LACKS_FGETWC */
+}
+#endif /* ACE_HAS_WCHAR */
+
diff --git a/ace/OS_String.cpp b/ace/OS_String.cpp
index a7388fffd86..d8db2e3c296 100644
--- a/ace/OS_String.cpp
+++ b/ace/OS_String.cpp
@@ -21,1053 +21,3 @@ ACE_RCSID (ace, OS_String, "$Id$")
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;
- size_t l_org = ACE_OS_String::strlen (s);
- s = ::strtok (s, tokens);
- if (s == 0)
- return 0;
- size_t l_sub = ACE_OS_String::strlen (s);
- if (s + l_sub < *lasts + l_org)
- *lasts = s + l_sub + 1;
- else
- *lasts = s + l_sub;
- return s ;
-}
-#endif /* !ACE_HAS_REENTRANT_FUNCTIONS */
-
-# if defined (ACE_HAS_WCHAR) && defined (ACE_LACKS_WCSTOK)
-wchar_t*
-ACE_OS_String::strtok_r_emulation (ACE_WCHAR_T *s, const ACE_WCHAR_T *tokens, ACE_WCHAR_T **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 = ACE_OS_String::strtok (s, tokens);
- if (s == 0)
- return 0;
- int l_sub = ACE_OS_String::strlen (s);
- if (s + l_sub < *lasts + l_org)
- *lasts = s + l_sub + 1;
- else
- *lasts = s + l_sub;
- return s ;
-}
-# endif /* ACE_HAS_WCHAR && ACE_LACKS_WCSTOK */
-
-#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;
- ++e; // Don't overwrite the negative sign.
- value = -value; // Drop negative sign so character selection is correct.
- }
-
- // 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 0;
- } 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)
- continue;
-
- 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 0;
-}
-#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 0;
-}
-#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 0;
-}
-#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)
- {
- if (rdst!=rsrc)
- {
- *rdst = '\0';
- if (rsrc != 0)
- strncat (rdst, rsrc, --rmaxlen);
- }
- else
- {
- rdst += (rmaxlen - 1);
- *rdst = '\0';
- }
- }
- 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)
- {
- if (rdst!=rsrc)
- {
- *rdst = ACE_TEXT_WIDE ('\0');
- if (rsrc != 0)
- strncat (rdst, rsrc, --rmaxlen);
- }
- else
- {
- rdst += (rmaxlen - 1);
- *rdst = ACE_TEXT_WIDE ('\0');
- }
- }
- return dst;
-}
diff --git a/ace/OS_String.h b/ace/OS_String.h
index 3d011ef3479..759d4b078b6 100644
--- a/ace/OS_String.h
+++ b/ace/OS_String.h
@@ -23,598 +23,30 @@
# pragma once
#endif /* ACE_LACKS_PRAGMA_ONCE */
-#include "ace/Basic_Types.h"
-#include "ace/os_include/os_stddef.h"
-
+//#include "ace/Basic_Types.h"
+//#include "ace/os_include/os_stddef.h"
+#include "ace/OS_NS_string.h"
+#include "ace/OS_NS_strings.h"
+#include "ace/OS_NS_wchar.h"
+#include "ace/OS_NS_ctype.h"
+
+#if 0
#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 */
+#endif
/**
- * @class ACE_OS_String
+ * @namespace ACE_OS_String
*
* @brief This class includes functions available in string.h and ctype.h.
*/
-class ACE_OS_Export ACE_OS_String
+#define ACE_OS_String ACE_OS
+namespace ACE_OS
{
-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);
-
- /// Finds the length of a limited-length string (char version).
- /**
- * @param s The character string to find the length of.
- * @param maxlen The maximum number of characters that will be
- * scanned for the terminating nul character.
- *
- * @return The length of @arg s, if the terminating nul character
- * is located, else @arg maxlen.
- */
- static size_t strnlen (const char *s, size_t maxlen);
-
- /// Finds the length of a limited-length string (ACE_WCHAR_T version).
- /**
- * @param s The character string to find the length of.
- * @param maxlen The maximum number of characters that will be
- * scanned for the terminating nul character.
- *
- * @return The length of @arg s, if the terminating nul character
- * is located, else @arg maxlen.
- */
- static size_t strnlen (const ACE_WCHAR_T *s, size_t maxlen);
-
- /// 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_HAS_WCHAR)
- /// Finds the next token in a string (wchar_t version).
- static wchar_t *strtok_r (ACE_WCHAR_T *s, const ACE_WCHAR_T *tokens, ACE_WCHAR_T **lasts);
-#endif // ACE_HAS_WCHAR
-
-#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);
-
-# if defined (ACE_HAS_WCHAR)
- /// Emulated strtok_r (wchar_t version).
- static wchar_t *strtok_r_emulation (ACE_WCHAR_T *s, const ACE_WCHAR_T *tokens, ACE_WCHAR_T **lasts);
-# endif // ACE_HAS_WCHAR
-#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 */
-
- //@}
-};
+}; /* namespace ACE_OS */
# if defined (ACE_HAS_INLINED_OSCALLS)
# if defined (ACE_INLINE)
diff --git a/ace/OS_String.inl b/ace/OS_String.inl
index aa86825114c..64b6ef0150d 100644
--- a/ace/OS_String.inl
+++ b/ace/OS_String.inl
@@ -9,663 +9,10 @@
*/
//=============================================================================
-// 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 */
-
#include "ace/os_include/os_stdlib.h"
#include "ace/os_include/os_string.h"
#include "ace/os_include/os_strings.h"
#include "ace/os_include/os_ctype.h"
-ACE_INLINE const void *
-ACE_OS_String::memchr (const void *s, int c, size_t len)
-{
-#if 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)
-{
- return ::memcmp (t, s, len);
-}
-
-
-ACE_INLINE void *
-ACE_OS_String::memcpy (void *t, const void *s, size_t len)
-{
- return ::memcpy (t, s, len);
-}
-
-ACE_INLINE void *
-ACE_OS_String::memmove (void *t, const void *s, size_t len)
-{
- return ::memmove (t, s, len);
-}
-
-ACE_INLINE void *
-ACE_OS_String::memset (void *s, int c, size_t len)
-{
- return ::memset (s, c, len);
-}
-
-ACE_INLINE char *
-ACE_OS_String::strcat (char *s, const char *t)
-{
- return ::strcat (s, t);
-}
-
-#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_LACKS_STRCHR)
- return ACE_OS_String::strchr_emulation (s, c);
-#else /* ! ACE_LACKS_STRCHR */
- return (const char *) ::strchr (s, c);
-#endif /* ACE_LACKS_STRCHR */
-}
-
-#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_LACKS_STRCHR)
- return ACE_OS_String::strchr_emulation (s, c);
-#else /* ! ACE_LACKS_STRCHR */
- return ::strchr (s, c);
-#endif /* ACE_LACKS_STRCHR */
-}
-
-#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)
-{
- return ::strcmp (s, t);
-}
-
-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)
-{
- return ::strcpy (s, t);
-}
-
-#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_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)
-{
- return ::strlen (s);
-}
-
-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 size_t
-ACE_OS_String::strnlen (const char *s, size_t maxlen)
-{
-#if defined (ACE_HAS_STRNLEN)
- return ::strnlen (s, maxlen);
-#else /* ACE_HAS_STRNLEN */
- size_t i;
- for (i = 0; i < maxlen; ++i)
- if (s[i] == '\0')
- break;
- return i;
-#endif /* ACE_HAS_STRNLEN */
-}
-
-ACE_INLINE size_t
-ACE_OS_String::strnlen (const ACE_WCHAR_T *s, size_t maxlen)
-{
-#if defined (ACE_HAS_WCHAR) && defined (ACE_HAS_WCSNLEN)
- return wcsnlen (s, maxlen);
-#else /* ACE_HAS_WCSNLEN */
- size_t i;
- for (i = 0; i < maxlen; ++i)
- if (s[i] == '\0')
- break;
- return i;
-#endif /* ACE_HAS_WCSNLEN */
-}
-
-ACE_INLINE char *
-ACE_OS_String::strncat (char *s, const char *t, size_t len)
-{
- return ::strncat (s, t, len);
-}
-
-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)
-{
- return ::strncmp (s, t, len);
-}
-
-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)
-{
- return ::strncpy (s, t, len);
-}
-
-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_LACKS_STRPBRK)
- return ACE_OS_String::strpbrk_emulation (s1, s2);
-#else /* ACE_LACKS_STRPBRK */
- return (const char *) ::strpbrk (s1, s2);
-#endif /* ACE_LACKS_STRPBRK */
-}
-
-#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_LACKS_STRPBRK)
- return ACE_OS_String::strpbrk_emulation (s1, s2);
-#else /* ACE_LACKS_STRPBRK */
- return ::strpbrk (s1, s2);
-#endif /* ACE_LACKS_STRPBRK */
-}
-
-#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_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_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_LACKS_STRSPN)
- return ACE_OS_String::strspn_emulation (s, t);
-#else /* ACE_LACKS_STRSPN */
- return ::strspn (s, t);
-#endif /* ACE_LACKS_STRSPN */
-}
-
-#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)
-{
- return (const char *) ::strstr (s, t);
-}
-
-#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);
-# elif defined (HPUX)
- return (const wchar_t *) ::wcswcs (s, t);
-# else /* ACE_LACKS_WCSSTR */
- return (const wchar_t *) ::wcsstr (s, t);
-# endif /* ACE_LACKS_WCSSTR */
-}
-#endif /* ACE_HAS_WCHAR */
-
-ACE_INLINE char *
-ACE_OS_String::strstr (char *s, const char *t)
-{
- return ::strstr (s, t);
-}
-
-#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);
-# elif defined (HPUX)
- return ::wcswcs (s, t);
-# else /* ACE_LACKS_WCSSTR */
- return ::wcsstr (s, t);
-# endif /* ACE_LACKS_WCSSTR */
-}
-#endif /* ACE_HAS_WCHAR */
-
-ACE_INLINE char *
-ACE_OS_String::strtok (char *s, const char *tokens)
-{
- return ::strtok (s, tokens);
-}
-
-#if defined (ACE_HAS_WCHAR) && !defined (ACE_LACKS_WCSTOK)
-ACE_INLINE wchar_t *
-ACE_OS_String::strtok (wchar_t *s, const wchar_t *tokens)
-{
-#if defined (ACE_HAS_3_PARAM_WCSTOK)
- static wchar_t *lasts;
- return ::wcstok (s, tokens, &lasts);
-#else
- return ::wcstok (s, tokens);
-#endif /* ACE_HAS_3_PARAM_WCSTOK */
-}
-#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);
-#else /* ACE_USES_WCHAR */
- return isprint ((unsigned char) 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);
-#else /* ACE_USES_WCHAR */
- return isspace ((unsigned char) c);
-#endif /* ACE_USES_WCHAR */
-}
-
-ACE_INLINE int
-ACE_OS_String::to_lower (int c)
-{
- return tolower (c);
-}
-
-#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_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_HAS_WCHAR)
-ACE_INLINE wchar_t*
-ACE_OS_String::strtok_r (ACE_WCHAR_T *s, const ACE_WCHAR_T *tokens, ACE_WCHAR_T **lasts)
-{
-#if defined (ACE_LACKS_WCSTOK)
- return ACE_OS_String::strtok_r_emulation (s, tokens, lasts);
-#else
-# if defined (ACE_HAS_3_PARAM_WCSTOK)
- return ::wcstok (s, tokens, lasts);
-# else /* ACE_HAS_3_PARAM_WCSTOK */
- *lasts = ::wcstok (s, tokens);
- return *lasts;
-# endif /* ACE_HAS_3_PARAM_WCSTOK */
-#endif /* ACE_LACKS_WCSTOK */
-}
-#endif // ACE_HAS_WCHAR
-
-#if !defined (ACE_LACKS_STRTOD)
-ACE_INLINE double
-ACE_OS_String::strtod (const char *s, char **endptr)
-{
- return ::strtod (s, endptr);
-}
-#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_LACKS_STRTOL)
- return ACE_OS_String::strtol_emulation (s, ptr, base);
-#else /* ACE_LACKS_STRTOL */
- return ::strtol (s, ptr, base);
-#endif /* ACE_LACKS_STRTOL */
-}
-
-#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_LACKS_STRTOUL)
- return ACE_OS_String::strtoul_emulation (s, ptr, base);
-#else /* ACE_LACKS_STRTOUL */
- return ::strtoul (s, ptr, base);
-#endif /* ACE_LACKS_STRTOUL */
-}
-#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_TLI.h b/ace/OS_TLI.h
index 1a83e22f93f..3615805a1bd 100644
--- a/ace/OS_TLI.h
+++ b/ace/OS_TLI.h
@@ -119,71 +119,71 @@ extern "C" int _xti_error(char *);
# endif /* ACE_REDEFINES_XTI_FUNCTIONS */
/**
- * @class ACE_OS_TLI
+ * @namespace ACE_OS_TLI
*
* @brief This class is a wrapper for the TLI operations
*
*/
-class ACE_OS_Export ACE_OS_TLI
+#define ACE_OS_TLI ACE_OS
+namespace ACE_OS
{
-public:
// = A set of wrappers for TLI.
- static int t_accept (ACE_HANDLE fildes,
+ int t_accept (ACE_HANDLE fildes,
ACE_HANDLE resfd,
struct t_call
*call);
- static char *t_alloc (ACE_HANDLE fildes,
+ char *t_alloc (ACE_HANDLE fildes,
int struct_type,
int
fields);
- static int t_bind (ACE_HANDLE fildes,
+ 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,
+ int t_close (ACE_HANDLE fildes);
+ 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,
+ void t_error (const char *errmsg);
+ int t_free (char *ptr,
int struct_type);
- static int t_getinfo (ACE_HANDLE fildes,
+ int t_getinfo (ACE_HANDLE fildes,
struct t_info *info);
- static int t_getname (ACE_HANDLE fildes,
+ 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 t_getstate (ACE_HANDLE fildes);
+ int t_listen (ACE_HANDLE fildes,
+ struct t_call *call);
+ int t_look (ACE_HANDLE fildes);
+ ACE_HANDLE t_open (char *path,
int oflag,
struct t_info *info);
- static int t_optmgmt (ACE_HANDLE fildes,
+ int t_optmgmt (ACE_HANDLE fildes,
struct t_optmgmt *req,
struct t_optmgmt *ret);
- static int t_rcv (ACE_HANDLE fildes,
+ int t_rcv (ACE_HANDLE fildes,
char *buf,
unsigned int nbytes,
int *flags);
- static int t_rcvdis (ACE_HANDLE fildes,
+ int t_rcvdis (ACE_HANDLE fildes,
struct t_discon *discon);
- static int t_rcvrel (ACE_HANDLE fildes);
- static int t_rcvudata (ACE_HANDLE fildes,
+ int t_rcvrel (ACE_HANDLE fildes);
+ int t_rcvudata (ACE_HANDLE fildes,
struct t_unitdata *unitdata,
int *flags);
- static int t_rcvuderr (ACE_HANDLE fildes,
+ int t_rcvuderr (ACE_HANDLE fildes,
struct t_uderr *uderr);
- static int t_snd (ACE_HANDLE fildes,
+ int t_snd (ACE_HANDLE fildes,
const char *buf,
unsigned int nbytes,
int flags);
- static int t_snddis (ACE_HANDLE fildes,
+ 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);
-};
+ int t_sndrel (ACE_HANDLE fildes);
+ int t_sync (ACE_HANDLE fildes);
+ int t_unbind (ACE_HANDLE fildes);
+}; /* namespace ACE_OS */
# if defined (ACE_HAS_INLINED_OSCALLS)
# if defined (ACE_INLINE)
diff --git a/ace/OS_TLI.inl b/ace/OS_TLI.inl
index c4dc02d5346..4b8ff91bbde 100644
--- a/ace/OS_TLI.inl
+++ b/ace/OS_TLI.inl
@@ -2,9 +2,9 @@
// $Id$
ACE_INLINE int
-ACE_OS_TLI::t_accept (ACE_HANDLE handle,
- ACE_HANDLE reshandle,
- struct t_call *call)
+ACE_OS::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);
@@ -18,8 +18,8 @@ ACE_OS_TLI::t_accept (ACE_HANDLE handle,
}
ACE_INLINE char *
-ACE_OS_TLI::t_alloc (ACE_HANDLE handle, int struct_type,
- int fields)
+ACE_OS::t_alloc (ACE_HANDLE handle, int struct_type,
+ int fields)
{
#if defined (ACE_HAS_TLI)
ACE_OSCALL_RETURN (::t_alloc (handle, struct_type, fields),
@@ -34,8 +34,8 @@ ACE_OS_TLI::t_alloc (ACE_HANDLE handle, int struct_type,
}
ACE_INLINE int
-ACE_OS_TLI::t_bind (ACE_HANDLE handle, struct t_bind *req,
- struct t_bind *ret)
+ACE_OS::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);
@@ -49,7 +49,7 @@ ACE_OS_TLI::t_bind (ACE_HANDLE handle, struct t_bind *req,
}
ACE_INLINE int
-ACE_OS_TLI::t_close (ACE_HANDLE handle)
+ACE_OS::t_close (ACE_HANDLE handle)
{
#if defined (ACE_HAS_TLI)
ACE_OSCALL_RETURN (::t_close (handle), int, -1);
@@ -61,9 +61,9 @@ ACE_OS_TLI::t_close (ACE_HANDLE handle)
}
ACE_INLINE int
-ACE_OS_TLI::t_connect(ACE_HANDLE fildes,
- struct t_call *sndcall,
- struct t_call *rcvcall)
+ACE_OS::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);
@@ -77,7 +77,7 @@ ACE_OS_TLI::t_connect(ACE_HANDLE fildes,
}
ACE_INLINE void
-ACE_OS_TLI::t_error (const char *errmsg)
+ACE_OS::t_error (const char *errmsg)
{
#if defined (ACE_HAS_TLI)
#if defined (ACE_HAS_BROKEN_T_ERROR)
@@ -91,7 +91,7 @@ ACE_OS_TLI::t_error (const char *errmsg)
}
ACE_INLINE int
-ACE_OS_TLI::t_free (char *ptr, int struct_type)
+ACE_OS::t_free (char *ptr, int struct_type)
{
#if defined (ACE_HAS_TLI)
if (ptr == 0)
@@ -106,7 +106,7 @@ ACE_OS_TLI::t_free (char *ptr, int struct_type)
}
ACE_INLINE int
-ACE_OS_TLI::t_getinfo (ACE_HANDLE handle, struct t_info *info)
+ACE_OS::t_getinfo (ACE_HANDLE handle, struct t_info *info)
{
#if defined (ACE_HAS_TLI)
ACE_OSCALL_RETURN (::t_getinfo (handle, info), int, -1);
@@ -119,9 +119,9 @@ ACE_OS_TLI::t_getinfo (ACE_HANDLE handle, struct t_info *info)
}
ACE_INLINE int
-ACE_OS_TLI::t_getname (ACE_HANDLE handle,
- struct netbuf *namep,
- int type)
+ACE_OS::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);
@@ -135,7 +135,7 @@ ACE_OS_TLI::t_getname (ACE_HANDLE handle,
}
ACE_INLINE int
-ACE_OS_TLI::t_getstate (ACE_HANDLE handle)
+ACE_OS::t_getstate (ACE_HANDLE handle)
{
#if defined (ACE_HAS_TLI)
ACE_OSCALL_RETURN (::t_getstate (handle), int, -1);
@@ -147,7 +147,7 @@ ACE_OS_TLI::t_getstate (ACE_HANDLE handle)
}
ACE_INLINE int
-ACE_OS_TLI::t_listen (ACE_HANDLE handle, struct t_call *call)
+ACE_OS::t_listen (ACE_HANDLE handle, struct t_call *call)
{
#if defined (ACE_HAS_TLI)
ACE_OSCALL_RETURN (::t_listen (handle, call), int, -1);
@@ -160,7 +160,7 @@ ACE_OS_TLI::t_listen (ACE_HANDLE handle, struct t_call *call)
}
ACE_INLINE int
-ACE_OS_TLI::t_look (ACE_HANDLE handle)
+ACE_OS::t_look (ACE_HANDLE handle)
{
#if defined (ACE_HAS_TLI)
ACE_OSCALL_RETURN (::t_look (handle), int, -1);
@@ -172,7 +172,7 @@ ACE_OS_TLI::t_look (ACE_HANDLE handle)
}
ACE_INLINE ACE_HANDLE
-ACE_OS_TLI::t_open (char *path, int oflag, struct t_info *info)
+ACE_OS::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);
@@ -186,9 +186,9 @@ ACE_OS_TLI::t_open (char *path, int oflag, struct t_info *info)
}
ACE_INLINE int
-ACE_OS_TLI::t_optmgmt (ACE_HANDLE handle,
- struct t_optmgmt *req,
- struct t_optmgmt *ret)
+ACE_OS::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);
@@ -202,10 +202,10 @@ ACE_OS_TLI::t_optmgmt (ACE_HANDLE handle,
}
ACE_INLINE int
-ACE_OS_TLI::t_rcv (ACE_HANDLE handle,
- char *buf,
- unsigned int nbytes,
- int *flags)
+ACE_OS::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),
@@ -221,7 +221,7 @@ ACE_OS_TLI::t_rcv (ACE_HANDLE handle,
}
ACE_INLINE int
-ACE_OS_TLI::t_rcvdis (ACE_HANDLE handle, struct t_discon *discon)
+ACE_OS::t_rcvdis (ACE_HANDLE handle, struct t_discon *discon)
{
#if defined (ACE_HAS_TLI)
ACE_OSCALL_RETURN (::t_rcvdis (handle, discon), int, -1);
@@ -234,7 +234,7 @@ ACE_OS_TLI::t_rcvdis (ACE_HANDLE handle, struct t_discon *discon)
}
ACE_INLINE int
-ACE_OS_TLI::t_rcvrel (ACE_HANDLE handle)
+ACE_OS::t_rcvrel (ACE_HANDLE handle)
{
#if defined (ACE_HAS_TLI)
ACE_OSCALL_RETURN (::t_rcvrel (handle), int, -1);
@@ -246,9 +246,9 @@ ACE_OS_TLI::t_rcvrel (ACE_HANDLE handle)
}
ACE_INLINE int
-ACE_OS_TLI::t_rcvudata (ACE_HANDLE handle,
- struct t_unitdata *unitdata,
- int *flags)
+ACE_OS::t_rcvudata (ACE_HANDLE handle,
+ struct t_unitdata *unitdata,
+ int *flags)
{
#if defined (ACE_HAS_TLI)
ACE_OSCALL_RETURN (::t_rcvudata (handle, unitdata, flags),
@@ -263,7 +263,7 @@ ACE_OS_TLI::t_rcvudata (ACE_HANDLE handle,
}
ACE_INLINE int
-ACE_OS_TLI::t_rcvuderr (ACE_HANDLE handle, struct t_uderr *uderr)
+ACE_OS::t_rcvuderr (ACE_HANDLE handle, struct t_uderr *uderr)
{
#if defined (ACE_HAS_TLI)
ACE_OSCALL_RETURN (::t_rcvuderr (handle, uderr), int, -1);
@@ -276,10 +276,10 @@ ACE_OS_TLI::t_rcvuderr (ACE_HANDLE handle, struct t_uderr *uderr)
}
ACE_INLINE int
-ACE_OS_TLI::t_snd (ACE_HANDLE handle,
- const char *buf,
- unsigned int nbytes,
- int flags)
+ACE_OS::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);
@@ -294,7 +294,7 @@ ACE_OS_TLI::t_snd (ACE_HANDLE handle,
}
ACE_INLINE int
-ACE_OS_TLI::t_snddis (ACE_HANDLE handle, struct t_call *call)
+ACE_OS::t_snddis (ACE_HANDLE handle, struct t_call *call)
{
#if defined (ACE_HAS_TLI)
ACE_OSCALL_RETURN (::t_snddis (handle, call), int, -1);
@@ -307,7 +307,7 @@ ACE_OS_TLI::t_snddis (ACE_HANDLE handle, struct t_call *call)
}
ACE_INLINE int
-ACE_OS_TLI::t_sndrel (ACE_HANDLE handle)
+ACE_OS::t_sndrel (ACE_HANDLE handle)
{
#if defined (ACE_HAS_TLI)
ACE_OSCALL_RETURN (::t_sndrel (handle), int, -1);
@@ -319,7 +319,7 @@ ACE_OS_TLI::t_sndrel (ACE_HANDLE handle)
}
ACE_INLINE int
-ACE_OS_TLI::t_sync (ACE_HANDLE handle)
+ACE_OS::t_sync (ACE_HANDLE handle)
{
#if defined (ACE_HAS_TLI)
ACE_OSCALL_RETURN (::t_sync (handle), int, -1);
@@ -331,7 +331,7 @@ ACE_OS_TLI::t_sync (ACE_HANDLE handle)
}
ACE_INLINE int
-ACE_OS_TLI::t_unbind (ACE_HANDLE handle)
+ACE_OS::t_unbind (ACE_HANDLE handle)
{
#if defined (ACE_HAS_TLI)
ACE_OSCALL_RETURN (::t_unbind (handle), int, -1);
diff --git a/ace/OS_main.h b/ace/OS_main.h
index fc532b41367..175378dcba8 100644
--- a/ace/OS_main.h
+++ b/ace/OS_main.h
@@ -1,4 +1,203 @@
// -*- C++ -*-
-// $Id$
-// This is a placeholder.
+//=============================================================================
+/**
+ * @file OS_NS_main.h
+ *
+ * $Id$
+ *
+ * @author Douglas C. Schmidt <schmidt@cs.wustl.edu>
+ * @author Jesper S. M|ller<stophph@diku.dk>
+ * @author and a cast of thousands...
+ *
+ * Originally in OS.h.
+ */
+//=============================================================================
+
+#ifndef ACE_OS_MAIN_H
+# define ACE_OS_MAIN_H
+
+# include /**/ "ace/pre.h"
+
+# include "ace/config-all.h"
+
+# if !defined (ACE_LACKS_PRAGMA_ONCE)
+# pragma once
+# endif /* ACE_LACKS_PRAGMA_ONCE */
+
+# if !defined (ACE_MAIN)
+# define ACE_MAIN main
+# endif /* ! ACE_MAIN */
+
+# if !defined (ACE_WMAIN)
+# define ACE_WMAIN wmain
+# endif /* ! ACE_WMAIN */
+
+# if defined (ACE_WIN32) && defined (ACE_USES_WCHAR)
+# define ACE_TMAIN wmain
+# else
+# define ACE_TMAIN main
+# endif
+
+# 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
+
+# elif defined (ACE_HAS_WINCE)
+
+# if defined (ACE_TMAIN) // Use WinMain on CE; others give warning/error.
+# undef ACE_TMAIN
+# endif // ACE_TMAIN
+
+// CE only gets a command line string; no argv. So we need to convert it
+// when the main entrypoint expects argc/argv. ACE_ARGV supports this.
+# include "ace/ARGV.h"
+
+// Support for ACE_TMAIN, which is a recommended way. It would be nice if
+// CE had CommandLineToArgvW()... but it's only on NT3.5 and up.
+
+# define ACE_TMAIN \
+ace_main_i (int, ACE_TCHAR *[]); /* forward declaration */ \
+int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int nCmdShow) \
+{ \
+ ACE_TCHAR cmdline[1024]; \
+ ACE_OS::strcpy (cmdline, ACE_LIB_TEXT ("program ")); \
+ ACE_OS::strcat (cmdline, lpCmdLine); \
+ ACE_ARGV ce_argv (cmdline); \
+ ACE::init (); \
+ ACE_MAIN_OBJECT_MANAGER \
+ int i = ace_main_i (ce_argv.argc (), ce_argv.argv ()); \
+ ACE::fini (); \
+ return i; \
+} \
+int ace_main_i
+
+// Support for wchar_t but still can't fit to CE because of the command
+// line parameters.
+# define wmain \
+ace_main_i (int, ACE_TCHAR *[]); /* forward declaration */ \
+int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int nCmdShow) \
+{ \
+ ACE_TCHAR cmdline[1024]; \
+ ACE_OS::strcpy (cmdline, ACE_LIB_TEXT ("program ")); \
+ ACE_OS::strcat (cmdline, lpCmdLine); \
+ ACE_ARGV ce_argv (cmdline); \
+ ACE::init (); \
+ ACE_MAIN_OBJECT_MANAGER \
+ int i = ace_main_i (ce_argv.argc (), ce_argv.argv ()); \
+ ACE::fini (); \
+ return i; \
+} \
+int ace_main_i
+
+// Supporting legacy 'main' is A LOT easier for users than changing existing
+// code on WinCE. Unfortunately, evc 3 can't grok a #include within the macro
+// expansion, so it needs to go out here.
+# include "ace/Argv_Type_Converter.h"
+# define main \
+ace_main_i (int, char *[]); /* forward declaration */ \
+int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int nCmdShow) \
+{ \
+ ACE_TCHAR cmdline[1024]; \
+ ACE_OS::strcpy (cmdline, ACE_LIB_TEXT ("program ")); \
+ ACE_OS::strcat (cmdline, lpCmdLine); \
+ ACE_ARGV ce_argv (cmdline); \
+ ACE::init (); \
+ ACE_MAIN_OBJECT_MANAGER \
+ ACE_Argv_Type_Converter command_line (ce_argv.argc (), ce_argv.argv ()); \
+ int i = ace_main_i (command_line.get_argc(), command_line.get_ASCII_argv());\
+ ACE::fini (); \
+ return i; \
+} \
+int ace_main_i
+
+# else
+# define main \
+ace_main_i (int, char *[]); /* forward declaration */ \
+int \
+ACE_MAIN (int argc, char *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)
+# define wmain \
+ace_main_i (int, ACE_TCHAR *[]); /* forward declaration */ \
+int \
+ACE_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 */
+
+#endif /* ACE_OS_MAIN_H */
diff --git a/ace/Object_Manager.h b/ace/Object_Manager.h
index 2101ca83c83..e7f36753159 100644
--- a/ace/Object_Manager.h
+++ b/ace/Object_Manager.h
@@ -16,6 +16,7 @@
#define ACE_OBJECT_MANAGER_H
#include /**/ "ace/pre.h"
+#include "ace/config-all.h"
#include "ace/OS.h"
#if !defined (ACE_LACKS_PRAGMA_ONCE)
@@ -41,10 +42,16 @@ class ACE_Sig_Set;
#include "ace/Recursive_Thread_Mutex.h"
#endif /* ACE_MT_SAFE */
+// only used by ACE_OS_Object_Manager::ctor
+# 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_Info_Node;
template <class T> class ACE_Cleanup_Adapter;
-
// Configuration parameters.
#if !defined (ACE_MAX_MANAGED_OBJECTS)
# define ACE_MAX_MANAGED_OBJECTS 128
@@ -58,7 +65,6 @@ template <class T> class ACE_Cleanup_Adapter;
# define ACE_APPLICATION_PREALLOCATED_ARRAY_DECLARATIONS
#endif /* ! ACE_APPLICATION_PREALLOCATED_ARRAY_DECLARATIONS */
-
/**
* @class ACE_Object_Manager
*
diff --git a/ace/Object_Manager_Base.cpp b/ace/Object_Manager_Base.cpp
index fc532b41367..c0209773c1f 100644
--- a/ace/Object_Manager_Base.cpp
+++ b/ace/Object_Manager_Base.cpp
@@ -1,4 +1,506 @@
// -*- C++ -*-
// $Id$
-// This is a placeholder.
+#include "ace/Object_Manager_Base.h"
+
+ACE_RCSID(ace, OS_NS_sys_time, "$Id$")
+
+#if !defined (ACE_HAS_INLINED_OSCALLS)
+# include "ace/Object_Manager_Base.inl"
+#endif /* ACE_HAS_INLINED_OS_CALLS */
+
+#include "ace/OS_Memory.h"
+#include "ace/OS_NS_Thread.h"
+#include "ace/OS_NS_sys_socket.h"
+#include "ace/OS_NS_signal.h"
+
+#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 */
+ // this is only windows and only used here,
+ // defined in ace/config-win32-common.h.
+ return (DWORD) ACE_SEH_DEFAULT_EXCEPTION_HANDLING_ACTION;
+}
+
+int ACE_SEH_Default_Exception_Handler (void *)
+{
+ return 0;
+}
+#endif /* ACE_HAS_WIN32_STRUCTURAL_EXCEPTIONS */
+
+# 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,
+ 0,
+ ::GetLastError (),
+ MAKELANGID (LANG_NEUTRAL,
+ SUBLANG_DEFAULT),
+ // Default language
+ (ACE_TCHAR *) &lpMsgBuf,
+ 0,
+ 0);
+ ::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
+ *
+ * @brief Ensure that the <ACE_OS_Object_Manager> gets initialized at
+ * program startup, and destroyed at program termination.
+ *
+ * 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.
+ */
+class ACE_OS_Object_Manager_Manager
+{
+public:
+ /// Constructor.
+ ACE_OS_Object_Manager_Manager (void);
+
+ /// Destructor.
+ ~ACE_OS_Object_Manager_Manager (void);
+
+private:
+ /// Save the main thread ID, so that destruction can be suppressed.
+ ACE_thread_t saved_main_thread_id_;
+};
+
+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 */
diff --git a/ace/Object_Manager_Base.h b/ace/Object_Manager_Base.h
index fc532b41367..0ebf39628d3 100644
--- a/ace/Object_Manager_Base.h
+++ b/ace/Object_Manager_Base.h
@@ -1,4 +1,265 @@
-// -*- C++ -*-
-// $Id$
+/* -*- C++ -*- */
-// This is a placeholder.
+//=============================================================================
+/**
+ * @file Object_Manager_Base.h
+ *
+ * $Id$
+ *
+ * @author Douglas C. Schmidt <schmidt@cs.wustl.edu>
+ * @author Jesper S. M|ller<stophph@diku.dk>
+ * @author and a cast of thousands...
+ *
+ * Originally in OS.h.
+ */
+//=============================================================================
+
+#ifndef ACE_OBJECT_MANAGER_BASE_H
+#define ACE_OBJECT_MANAGER_BASE_H
+#include /**/ "ace/pre.h"
+
+#include "ace/config-all.h"
+
+#if !defined (ACE_LACKS_PRAGMA_ONCE)
+# pragma once
+#endif /* ACE_LACKS_PRAGMA_ONCE */
+
+#include "ace/OS_Export.h"
+#include "ace/Cleanup.h"
+#include "ace/OS_NS_netdb.h"
+#include "ace/OS_NS_unistd.h"
+#include "ace/OS_NS_time.h"
+#include "ace/OS_NS_stdlib.h"
+
+class ACE_Thread_Hook;
+
+/**
+ * @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.
+# if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0) && defined (ACE_LACKS_NETDB_REENTRANT_FUNCTIONS)
+ friend int ACE_OS::netdb_acquire (void);
+ friend int ACE_OS::netdb_release (void);
+# endif /* defined (ACE_MT_SAFE) && ACE_LACKS_NETDB_REENTRANT_FUNCTIONS */
+ friend ssize_t ACE_OS::pread(ACE_HANDLE, void*, size_t, off_t);
+ friend ssize_t ACE_OS::pwrite(ACE_HANDLE, const void*, size_t, off_t);
+ friend time_t ACE_OS::mktime(tm*);
+ friend int ACE_OS::atexit(void (*)());
+ 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_HAS_INLINED_OSCALLS)
+# if defined (ACE_INLINE)
+# undef ACE_INLINE
+# endif /* ACE_INLINE */
+# define ACE_INLINE inline
+# include "ace/Object_Manager_Base.inl"
+# endif /* ACE_HAS_INLINED_OSCALLS */
+
+#include /**/ "ace/post.h"
+#endif /* ACE_OBJECT_MANAGER_BASE_H */
diff --git a/ace/Object_Manager_Base.inl b/ace/Object_Manager_Base.inl
index fc532b41367..c130d6682b1 100644
--- a/ace/Object_Manager_Base.inl
+++ b/ace/Object_Manager_Base.inl
@@ -1,4 +1,2 @@
// -*- C++ -*-
// $Id$
-
-// This is a placeholder.
diff --git a/ace/SOCK.h b/ace/SOCK.h
index c616ce8c0ef..53ac2a2e529 100644
--- a/ace/SOCK.h
+++ b/ace/SOCK.h
@@ -24,6 +24,30 @@
#include "ace/IPC_SAP.h"
#include "ace/OS.h"
+#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 */
+
/**
* @class ACE_SOCK
*
diff --git a/ace/Signal.h b/ace/Signal.h
index 63e4ad05c9c..368b913cf9c 100644
--- a/ace/Signal.h
+++ b/ace/Signal.h
@@ -26,6 +26,9 @@
#include "ace/Event_Handler.h"
+// Type of the extended signal handler.
+typedef void (*ACE_Sig_Handler_Ex) (int, siginfo_t *siginfo, ucontext_t *ucontext);
+
// This worksaround a horrible bug with HP/UX C++...
typedef struct sigaction ACE_SIGACTION;
diff --git a/ace/TTY_IO.h b/ace/TTY_IO.h
index b0c7028fa54..8c26cc6e6af 100644
--- a/ace/TTY_IO.h
+++ b/ace/TTY_IO.h
@@ -21,6 +21,18 @@
#include "ace/DEV_IO.h"
+#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 */
+
/**
* @class ACE_TTY_IO
*
diff --git a/ace/Time_Value.cpp b/ace/Time_Value.cpp
index a9153981576..c8d81a1c5e9 100644
--- a/ace/Time_Value.cpp
+++ b/ace/Time_Value.cpp
@@ -199,3 +199,17 @@ ACE_Time_Value::normalize (void)
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 ();
+}
diff --git a/ace/Time_Value.h b/ace/Time_Value.h
index f6792d5a1d5..dff278f063d 100644
--- a/ace/Time_Value.h
+++ b/ace/Time_Value.h
@@ -321,6 +321,50 @@ private:
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);
+
+ /// Returns 1 if we've already been stopped, else 0.
+ int stopped (void) const;
+
+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_INLINE__)
#include "ace/Time_Value.inl"
#endif /* __ACE_INLINE__ */
diff --git a/ace/Time_Value.inl b/ace/Time_Value.inl
index 95fba6c98d1..d714308f88d 100644
--- a/ace/Time_Value.inl
+++ b/ace/Time_Value.inl
@@ -2,6 +2,7 @@
//
// $Id$
+#include "ace/OS_NS_sys_time.h"
// Returns the value of the object as a timeval.
@@ -327,3 +328,49 @@ operator - (const ACE_Time_Value &tv1,
delta.normalize ();
return delta;
}
+
+/*****************************************************************************/
+
+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::stopped (void) const
+{
+ return stopped_;
+}
+
+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 ();
+}
diff --git a/ace/Timeprobe.h b/ace/Timeprobe.h
index e12636a78de..916b7dc55e8 100644
--- a/ace/Timeprobe.h
+++ b/ace/Timeprobe.h
@@ -47,6 +47,13 @@
# pragma once
#endif /* ACE_LACKS_PRAGMA_ONCE */
+/* Enable ACE Timeprobes */
+#if defined (ACE_ENABLE_TIMEPROBES)
+ #if !defined (ACE_COMPILE_TIMEPROBES)
+ #define ACE_COMPILE_TIMEPROBES
+ #endif /* ACE_COMPILE_TIMEPROBES */
+#endif /* ACE_ENABLE_TIMEPROBES */
+
#if defined (ACE_COMPILE_TIMEPROBES)
/**
diff --git a/ace/ace.mpc b/ace/ace.mpc
index d01e04067cd..d03508545cd 100644
--- a/ace/ace.mpc
+++ b/ace/ace.mpc
@@ -11,11 +11,45 @@ project(ACE) : acedefaults, aceversion, core, qt_moc, qt_reactor {
OS {
Basic_Types.cpp
Time_Value.cpp
- OS.cpp
- OS_Dirent.cpp
- OS_Memory.cpp
+ Cleanup.cpp
+ Object_Manager_Base.cpp
+ //OS.cpp
+ //OS_Dirent.cpp
+ //OS_Memory.cpp
OS_QoS.cpp
- OS_String.cpp
+ //OS_String.cpp
+ OS_NS_arpa_inet.cpp
+ OS_NS_fcntl.cpp
+ OS_NS_regex.cpp
+ OS_NS_strings.cpp
+ OS_NS_sys_select.cpp
+ OS_NS_sys_uio.cpp
+ OS_NS_unistd.cpp
+ OS_NS_ctype.cpp
+ OS_NS_math.cpp
+ OS_NS_signal.cpp
+ OS_NS_stropts.cpp
+ OS_NS_sys_shm.cpp
+ OS_NS_sys_utsname.cpp
+ OS_NS_wchar.cpp
+ OS_NS_dirent.cpp
+ OS_NS_netdb.cpp
+ OS_NS_stdio.cpp
+ OS_NS_sys_mman.cpp
+ OS_NS_sys_socket.cpp
+ OS_NS_sys_wait.cpp
+ OS_NS_dlfcn.cpp
+ OS_NS_poll.cpp
+ OS_NS_stdlib.cpp
+ OS_NS_sys_msg.cpp
+ OS_NS_sys_stat.cpp
+ OS_NS_Thread.cpp
+ OS_NS_errno.cpp
+ OS_NS_pwd.cpp
+ OS_NS_string.cpp
+ OS_NS_sys_resource.cpp
+ OS_NS_sys_time.cpp
+ OS_NS_time.cpp
OS_TLI.cpp
OS_Errno.cpp
ARGV.cpp
diff --git a/ace/config-all.h b/ace/config-all.h
index 0c5f03c2cd6..e76ecf68ff6 100644
--- a/ace/config-all.h
+++ b/ace/config-all.h
@@ -23,6 +23,13 @@
# pragma once
#endif /* ACE_LACKS_PRAGMA_ONCE */
+// 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 */
+
#define ACE_BITS_PER_ULONG (8 * sizeof (u_long))
#if !defined (ACE_OSTREAM_TYPE)
diff --git a/ace/config-vxworks5.x.h b/ace/config-vxworks5.x.h
index 85bc5c4040a..20cb1b723e6 100644
--- a/ace/config-vxworks5.x.h
+++ b/ace/config-vxworks5.x.h
@@ -83,6 +83,10 @@
# error unsupported compiler on VxWorks
#endif /* ! __GNUG__ && ! ghs */
+#if defined (ACE_VXWORKS) && ACE_VXWORKS <= 0x540
+# define ACE_LACKS_ARPA_INET_H
+#endif /* ! (ACE_VXWORKS) && ACE_VXWORKS <= 0x540 */
+
// OS-specific configuration
#define ACE_LACKS_UNIX_SYSLOG
diff --git a/ace/os_include/arpa/os_inet.h b/ace/os_include/arpa/os_inet.h
index b425a5d3b3f..af37b96530c 100644
--- a/ace/os_include/arpa/os_inet.h
+++ b/ace/os_include/arpa/os_inet.h
@@ -36,13 +36,113 @@
# include /**/ <inetLib.h>
#endif /* VXWORKS */
+/**
+ * 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
+
// Place all additions (especially function declarations) within extern "C" {}
#ifdef __cplusplus
extern "C"
{
#endif /* __cplusplus */
+#if defined (ACE_VXWORKS) && ACE_VXWORKS <= 0x540
+ // 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 *);
+#endif /* ! (ACE_VXWORKS) && ACE_VXWORKS <= 0x540 */
+
// @todo move the ACE_HTONL, etc macros here
+// 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 */
+# 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__) ||\
+ defined (ARM) || defined (_M_IA64)
+ // 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 */
+
+// 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 */
#ifdef __cplusplus
}
diff --git a/ace/os_include/netinet/os_in.h b/ace/os_include/netinet/os_in.h
index d831515bad3..88e25e3f507 100644
--- a/ace/os_include/netinet/os_in.h
+++ b/ace/os_include/netinet/os_in.h
@@ -49,6 +49,25 @@ extern "C"
{
#endif /* __cplusplus */
+# 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_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
+ {
+ /// IP multicast address of group
+ struct in_addr imr_multiaddr;
+ /// Local IP address of interface
+ struct in_addr imr_interface;
+ };
+# endif /* ! ACE_HAS_IP_MULTICAST && ACE_LACKS_IP_ADD_MEMBERSHIP */
+
#if !defined (IPPORT_RESERVED)
# define IPPORT_RESERVED 1024
#endif /* !IPPORT_RESERVED */
@@ -80,6 +99,35 @@ extern "C"
# define INET6_ADDRSTRLEN 46
#endif /* INET6_ADDRSTRLEN */
+# 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 */
+
#ifdef __cplusplus
}
#endif /* __cplusplus */
diff --git a/ace/os_include/netinet/os_tcp.h b/ace/os_include/netinet/os_tcp.h
index bf9886ef632..85facbfd4a6 100644
--- a/ace/os_include/netinet/os_tcp.h
+++ b/ace/os_include/netinet/os_tcp.h
@@ -24,10 +24,24 @@
# pragma once
#endif /* ACE_LACKS_PRAGMA_ONCE */
+// @todo: remove this, and fix references when you get a chance... dhinton
+#if defined (ACE_LACKS_TCP_H)
+# define ACE_LACKS_NETINET_TCP_H
+#endif /* ACE_LACKS_TCP_H */
+
#if !defined (ACE_LACKS_NETINET_TCP_H)
# include /**/ <netinet/tcp.h>
#endif /* !ACE_LACKS_NETIINET_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 /* ACE_HAS_CONFLICTING_XTI_MACROS */
+
// Place all additions (especially function declarations) within extern "C" {}
#ifdef __cplusplus
extern "C"
diff --git a/ace/os_include/os_dirent.h b/ace/os_include/os_dirent.h
index 32c92249e0b..d76f0f4010b 100644
--- a/ace/os_include/os_dirent.h
+++ b/ace/os_include/os_dirent.h
@@ -45,6 +45,13 @@ extern "C"
# define MAXNAMLEN NAME_MAX
#endif /* !MAXNAMLEN */
+# if defined (ACE_PSOS)
+// pHILE+ calls the DIR struct XDIR instead
+# if !defined (ACE_PSOS_DIAB_PPC)
+typedef XDIR ACE_DIR;
+# endif /* !defined (ACE_PSOS_DIAB_PPC) */
+# endif /* ACE_PSOS */
+
// At least compile on some of the platforms without <ACE_DIR> info yet.
#if !defined (ACE_HAS_DIRENT)
typedef int ACE_DIR;
diff --git a/ace/os_include/os_dlfcn.h b/ace/os_include/os_dlfcn.h
index a0b5934c2cd..91864eae5e0 100644
--- a/ace/os_include/os_dlfcn.h
+++ b/ace/os_include/os_dlfcn.h
@@ -55,6 +55,13 @@ extern "C"
{
#endif /* __cplusplus */
+#if defined (_M_UNIX)
+ int _dlclose (void *);
+ char *_dlerror (void);
+ void *_dlopen (const char *, int);
+ void * _dlsym (void *, const char *);
+#endif /* _M_UNIX */
+
/* 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 */
diff --git a/ace/os_include/os_fcntl.h b/ace/os_include/os_fcntl.h
index 13b47486786..4f7e3ec02fd 100644
--- a/ace/os_include/os_fcntl.h
+++ b/ace/os_include/os_fcntl.h
@@ -80,12 +80,20 @@ extern "C"
# define O_NDELAY 1
#endif /* ACE_WIN32 */
+# if !defined (O_NONBLOCK)
+# define O_NONBLOCK 1
+# endif /* O_NONBLOCK */
+
#if defined (ACE_HAS_POSIX_NONBLOCK)
# define ACE_NONBLOCK O_NONBLOCK
#else
# define ACE_NONBLOCK O_NDELAY
#endif /* ACE_HAS_POSIX_NONBLOCK */
+# if !defined (F_GETFL)
+# define F_GETFL 0
+# endif /* F_GETFL */
+
#ifdef __cplusplus
}
#endif /* __cplusplus */
diff --git a/ace/os_include/os_limits.h b/ace/os_include/os_limits.h
index 0501064ea08..d03eedef7ec 100644
--- a/ace/os_include/os_limits.h
+++ b/ace/os_include/os_limits.h
@@ -101,6 +101,24 @@ extern "C"
# define PIPE_BUF 5120
#endif /* PIPE_BUF */
+#if defined (ACE_HAS_POSIX_REALTIME_SIGNALS)
+ // = 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_POSIX_REALTIME_SIGNALS */
+
#ifdef __cplusplus
}
#endif /* __cplusplus */
diff --git a/ace/os_include/os_pthread.h b/ace/os_include/os_pthread.h
index 030730a8a6b..77e1282bd67 100644
--- a/ace/os_include/os_pthread.h
+++ b/ace/os_include/os_pthread.h
@@ -362,8 +362,7 @@ extern "C" pthread_t pthread_self (void);
*/
class ACE_OS_Export ACE_sema_t
{
-friend class ACE_OS;
-protected:
+public:
/// Serialize access to internal state.
ACE_mutex_t lock_;
diff --git a/ace/os_include/os_signal.h b/ace/os_include/os_signal.h
index 4668e1f8b33..06112a60a46 100644
--- a/ace/os_include/os_signal.h
+++ b/ace/os_include/os_signal.h
@@ -51,9 +51,15 @@
#if defined (VXWORKS)
# include /**/ <sigLib.h>
-# define NSIG (_NSIGS + 1)
#endif /* VXWORKS */
+// should this be extern "C" {}?
+#if defined (CHORUS)
+# if !defined(CHORUS_4)
+typedef void (*__sighandler_t)(int); // keep Signal compilation happy
+# endif
+#endif /* CHORUS */
+
// Place all additions (especially function declarations) within extern "C" {}
#ifdef __cplusplus
extern "C"
@@ -90,6 +96,14 @@ extern "C"
typedef int sig_atomic_t;
#endif /* !ACE_HAS_SIG_ATOMIC_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 (SIGHUP)
# define SIGHUP 0
#endif /* SIGHUP */
@@ -180,6 +194,21 @@ extern "C"
# endif /* NSIG */
#endif /* ACE_PSOS && !ACE_PSOSIM */
+#if defined (VXWORKS)
+# define NSIG (_NSIGS + 1)
+#elif defined (__Lynx__)
+ // LynxOS Neutrino sets NSIG to the highest-numbered signal.
+# define ACE_NSIG (NSIG + 1)
+#elif defined (__rtems__)
+# define ACE_NSIG (SIGRTMAX)
+#elif defined(__BORLANDC__) && (__BORLANDC__ >= 0x600)
+# define ACE_NSIG _NSIG
+#else
+ // All other platforms set NSIG to one greater than the
+ // highest-numbered signal.
+# define ACE_NSIG NSIG
+#endif /* __Lynx__ */
+
#if defined (ACE_HAS_CONSISTENT_SIGNAL_PROTOTYPES)
// Prototypes for both signal() and struct sigaction are consistent..
//# if defined (ACE_HAS_SIG_C_FUNC)
@@ -259,6 +288,32 @@ extern "C"
#endif /* ACE_HAS_POSIX_REALTIME_SIGNALS */
+#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.
+ 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__)
+ int sigwait (const sigset_t *set, int *sig);
+# else
+ int sigwait (sigset_t *set);
+# endif /* __rtems__ */
+#endif /* ! DIGITAL_UNIX && ! ACE_HAS_SIGWAIT */
+
+ typedef void (*ACE_SIGNAL_C_FUNC)(int,siginfo_t*,void*);
+
#ifdef __cplusplus
}
#endif /* __cplusplus */
diff --git a/ace/os_include/os_stdio.h b/ace/os_include/os_stdio.h
index 673802faba0..4036b631e3e 100644
--- a/ace/os_include/os_stdio.h
+++ b/ace/os_include/os_stdio.h
@@ -45,9 +45,13 @@ extern "C"
{
#endif /* __cplusplus */
-#if !defined (ACE_WIN32) && !defined (INTEGRITY)
+# if defined (INTEGRITY)
+# define ACE_MAX_USERID 32
+# elif defined (ACE_WIN32)
+# define ACE_MAX_USERID 32
+# else
# define ACE_MAX_USERID L_cuserid
-#endif /*!ACE_WIN32*/
+#endif /* INTEGRITY */
// this is a nasty hack to get around problems with the
// pSOS definition of BUFSIZ as the config table entry
diff --git a/ace/os_include/os_stdlib.h b/ace/os_include/os_stdlib.h
index e1bc4c9a042..95d56f67c54 100644
--- a/ace/os_include/os_stdlib.h
+++ b/ace/os_include/os_stdlib.h
@@ -67,6 +67,12 @@ extern "C"
int putenv (char *); // stdlib.h
#endif /* ACE_PSOS_SNARFS_HEADER_INFO */
+// These prototypes are chronically lacking from many versions of
+// UNIX.
+#if !defined (ACE_WIN32) && defined (ACE_LACKS_MKTEMP)
+ char *mktemp (char *);
+#endif /* !ACE_WIN32 && ACE_LACKS_MKTEMP */
+
#ifdef __cplusplus
}
#endif /* __cplusplus */
diff --git a/ace/os_include/os_string.h b/ace/os_include/os_string.h
index d56a1117ca4..3f4fff3814d 100644
--- a/ace/os_include/os_string.h
+++ b/ace/os_include/os_string.h
@@ -26,9 +26,18 @@
#include "ace/os_include/os_stddef.h"
-#if !defined (ACE_LACKS_STRING_H)
-# include /**/ <string.h>
-#endif /* !ACE_LACKS_STRING_H */
+// 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 */
+# if !defined (ACE_LACKS_STRING_H)
+# include /**/ <string.h>
+# endif /* !ACE_LACKS_STRING_H */
+#endif /* ACE_HAS_GNU_CSTRING_H */
// Place all additions (especially function declarations) within extern "C" {}
#ifdef __cplusplus
@@ -36,6 +45,16 @@ extern "C"
{
#endif /* __cplusplus */
+ // this looks fishy... dhinton
+#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_LACKS_STRTOK_R_PROTOTYPE) && !defined (_POSIX_SOURCE)
char *strtok_r (char *s, const char *delim, char **save_ptr);
#endif /* ACE_LACKS_STRTOK_R_PROTOTYPE */
diff --git a/ace/os_include/os_strings.h b/ace/os_include/os_strings.h
index 789b6b3fbbe..cacafa7c866 100644
--- a/ace/os_include/os_strings.h
+++ b/ace/os_include/os_strings.h
@@ -26,10 +26,12 @@
#include "ace/os_include/os_stddef.h"
-// The is for backward compatibility and needs to be fixed in the config files.
-#if !defined (ACE_HAS_STRINGS)
-# define ACE_LACKS_STRINGS_H
-#endif /* !ACE_HAS_STRINGS */
+// The is for backward compatibility and needs to be fixed in the
+// config files. This is wrong, so I've commented it out and will fix in the
+// config files as needed.
+//#if !defined (ACE_HAS_STRINGS)
+//# define ACE_LACKS_STRINGS_H
+//#endif /* !ACE_HAS_STRINGS */
#if !defined (ACE_LACKS_STRINGS_H)
# include /**/ <strings.h>
diff --git a/ace/os_include/os_stropts.h b/ace/os_include/os_stropts.h
index 65fff659b2f..d4113e49983 100644
--- a/ace/os_include/os_stropts.h
+++ b/ace/os_include/os_stropts.h
@@ -50,10 +50,28 @@
# include /**/ <sys/sockio.h>
#endif /* ACE_HAS_SOCKIO_ */
+// This is sorta counter intuitive, but this is how it was done in OS.h
+// @todo: fix this... dhinton
+#if defined (ACE_HAS_STREAMS)
+# if defined (AIX)
+# if !defined (_XOPEN_EXTENDED_SOURCE)
+# define _XOPEN_EXTENDED_SOURCE
+# endif /* !_XOPEN_EXTENDED_SOURCE */
+# endif /* AIX */
+#endif /* ACE_HAS_STREAMS */
+
#if !defined (ACE_LACKS_STROPTS_H)
# include /**/ <stropts.h>
#endif /* !ACE_LACKS_STROPTS_H */
+// This is sorta counter intuitive, but this is how it was done in OS.h
+// @todo: fix this... dhinton
+#if defined (ACE_HAS_STREAMS)
+# if defined (AIX)
+# undef _XOPEN_EXTENDED_SOURCE
+# endif /* AIX */
+#endif /* ACE_HAS_STREAMS */
+
#if defined (VXWORKS)
// for ioctl()
# include /**/ <ioLib.h>
@@ -69,6 +87,32 @@ extern "C"
struct strrecvfd {};
#endif /* ACE_LACKS_STRRECVFD */
+# if !defined (SIOCGIFBRDADDR)
+# define SIOCGIFBRDADDR 0
+# endif /* SIOCGIFBRDADDR */
+
+# if !defined (SIOCGIFADDR)
+# define SIOCGIFADDR 0
+# endif /* SIOCGIFADDR */
+
+# if !defined (ACE_HAS_STRBUF_T)
+struct strbuf
+{
+ /// No. of bytes in buffer.
+ int maxlen;
+ /// No. of bytes returned.
+ int len;
+ /// Pointer to data.
+ void *buf;
+};
+# endif /* ACE_HAS_STRBUF_T */
+
+// These prototypes are chronically lacking from many versions of
+// UNIX.
+#if !defined (ACE_WIN32) && !defined (ACE_HAS_ISASTREAM_PROTO)
+ int isastream (int);
+#endif /* !ACE_WIN32 && ACE_HAS_ISASTREAM_PROTO */
+
#ifdef __cplusplus
}
#endif /* __cplusplus */
diff --git a/ace/os_include/os_time.h b/ace/os_include/os_time.h
index 14e843ab03f..5083070f29b 100644
--- a/ace/os_include/os_time.h
+++ b/ace/os_include/os_time.h
@@ -31,6 +31,17 @@
# include /**/ <time.h>
#endif /* !ACE_LACKS_TIME_H */
+# if defined (ACE_USES_STD_NAMESPACE_FOR_STDC_LIB) && \
+ (ACE_USES_STD_NAMESPACE_FOR_STDC_LIB != 0)
+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 */
+
// Place all additions (especially function declarations) within extern "C" {}
#ifdef __cplusplus
extern "C"
diff --git a/ace/os_include/os_ucontext.h b/ace/os_include/os_ucontext.h
index e04c7228374..67ce5ba9b10 100644
--- a/ace/os_include/os_ucontext.h
+++ b/ace/os_include/os_ucontext.h
@@ -36,6 +36,10 @@ extern "C"
{
#endif /* __cplusplus */
+# if !defined (ACE_HAS_UCONTEXT_T)
+typedef int ucontext_t;
+# endif /* ACE_HAS_UCONTEXT_T */
+
#ifdef __cplusplus
}
#endif /* __cplusplus */
diff --git a/ace/os_include/os_unistd.h b/ace/os_include/os_unistd.h
index a9ca19f0ec2..74df3005d1e 100644
--- a/ace/os_include/os_unistd.h
+++ b/ace/os_include/os_unistd.h
@@ -52,6 +52,55 @@ extern "C"
{
#endif /* __cplusplus */
+#if (!defined (_BSD_SOURCE) && \
+ !defined (_XOPEN_SOURCE) && !defined (_XOPEN_SOURCE_EXTENDED)) \
+ || (defined (_XOPEN_SOURCE) && defined (__GNUC__))
+
+# if defined (ACE_LACKS_SETREUID_PROTOTYPE)
+ extern int setreuid (uid_t ruid, uid_t euid);
+# endif /* ACE_LACKS_SETREUID_PROTOTYPE */
+
+# if defined (ACE_LACKS_SETREGID_PROTOTYPE)
+ extern int setregid (gid_t rgid, gid_t egid);
+# endif /* ACE_LACKS_SETREGID_PROTOTYPE */
+#endif /* !_BSD_SOURCE && !_XOPEN_SOURCE && !_XOPEN_SOURCE_EXTENDED
+ || _XOPEN_SOURCE && __GNUC__ */
+
+# 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 */
+
+ // for use by access()
+# 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 (CHORUS)
+ int getgid __((void));
+ int getuid __((void));
+ char* getcwd __((char* buf, size_t size));
+ int pipe __((int* fildes));
+ int gethostname __((char*, size_t));
+#endif /* CHORUS */
+
#if defined (ACE_LACKS_UALARM_PROTOTYPE)
u_int ualarm (u_int usecs, u_int interval);
#endif /* ACE_LACKS_UALARM_PROTOTYPE */
@@ -111,6 +160,20 @@ extern "C"
int isatty (int h);
#endif /* ACE_PSOS_SNARFS_HEADER_INFO */
+# if defined (ACE_LACKS_TIMEDWAIT_PROTOTYPES)
+
+ ssize_t read_timedwait (ACE_HANDLE handle,
+ char *buf,
+ size_t n,
+ struct timespec *timeout);
+
+ ssize_t write_timedwait (ACE_HANDLE handle,
+ const void *buf,
+ size_t n,
+ struct timespec *timeout);
+
+# endif /* ACE_LACKS_TIMEDWAIT_PROTOTYPES */
+
#ifdef __cplusplus
}
#endif /* __cplusplus */
diff --git a/ace/os_include/sys/os_mman.h b/ace/os_include/sys/os_mman.h
index 7014343bda6..d481cafaad8 100644
--- a/ace/os_include/sys/os_mman.h
+++ b/ace/os_include/sys/os_mman.h
@@ -76,10 +76,36 @@ PAGE_NOACCESS
PAGE_NOCACHE */
#endif /* !ACE_LACKS_SYS_MMAN_H && !ACE_WIN32*/
+# 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 (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 (PROT_RDWR)
# define PROT_RDWR (PROT_READ|PROT_WRITE)
#endif /* PROT_RDWR */
+# if defined (ACE_WIN32)
+ // Needed to map calls to NT transparently.
+# define MS_ASYNC 0
+# define MS_INVALIDATE 0
+# endif /* ACE_WIN32 */
+
# if !defined (MS_SYNC)
# define MS_SYNC 0x0
# endif /* !MS_SYNC */
diff --git a/ace/os_include/sys/os_resource.h b/ace/os_include/sys/os_resource.h
index 1aa55705ffe..b4091960abe 100644
--- a/ace/os_include/sys/os_resource.h
+++ b/ace/os_include/sys/os_resource.h
@@ -37,6 +37,25 @@ extern "C"
{
#endif /* __cplusplus */
+#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 */
+
+// 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_HAS_BROKEN_SETRLIMIT)
typedef struct rlimit ACE_SETRLIMIT_TYPE;
#else
@@ -52,8 +71,29 @@ extern "C"
FILETIME ru_utime;
FILETIME ru_stime;
};
+#else /* !ACE_WIN32 */
+# if defined (m88k)
+# define RUSAGE_SELF 1
+# endif /* m88k */
#endif /* ACE_WIN32 */
+#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_WIN32)
+// These prototypes are chronically lacking from many versions of
+// UNIX.
+# if !defined (ACE_HAS_GETRUSAGE_PROTO)
+ int getrusage (int who, struct rusage *rusage);
+# endif /* ! ACE_HAS_GETRUSAGE_PROTO */
+
+# if defined (ACE_LACKS_SYSCALL)
+ int syscall (int, ACE_HANDLE, struct rusage *);
+# endif /* ACE_LACKS_SYSCALL */
+#endif /* !ACE_WIN32 */
+
#ifdef __cplusplus
}
#endif /* __cplusplus */
diff --git a/ace/os_include/sys/os_select.h b/ace/os_include/sys/os_select.h
index 21b8d4a4ae5..ae5f371abdf 100644
--- a/ace/os_include/sys/os_select.h
+++ b/ace/os_include/sys/os_select.h
@@ -44,6 +44,10 @@ extern "C"
#if defined (ACE_WIN32)
// This will help until we figure out everything:
# define NFDBITS 32 /* only used in unused functions... */
+#elif defined (__QNX__)
+# if !defined (NFDBITS)
+# define NFDBITS (sizeof(fd_mask) * NBBY) /* bits per mask */
+# endif /* ! NFDBITS */
#endif /* ACE_WIN32 */
#if defined (ACE_SELECT_USES_INT)
@@ -52,6 +56,11 @@ extern "C"
typedef fd_set ACE_FD_SET_TYPE;
#endif /* ACE_SELECT_USES_INT */
+#if defined (__rtems__)
+ int select (int n, fd_set *readfds, fd_set *writefds,
+ fd_set *exceptfds, const struct timeval *timeout);
+#endif /* __rtems__ */
+
#ifdef __cplusplus
}
#endif /* __cplusplus */
diff --git a/ace/os_include/sys/os_sem.h b/ace/os_include/sys/os_sem.h
index ef35feb3397..b0f3544dd26 100644
--- a/ace/os_include/sys/os_sem.h
+++ b/ace/os_include/sys/os_sem.h
@@ -36,6 +36,26 @@ extern "C"
{
#endif /* __cplusplus */
+# if !defined (GETVAL)
+# define GETVAL 0
+# endif /* GETVAL */
+
+# 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 (ACE_LACKS_SEMBUF_T)
struct sembuf
{
diff --git a/ace/os_include/sys/os_socket.h b/ace/os_include/sys/os_socket.h
index 5c9ac3796a9..d0b69c0aef2 100644
--- a/ace/os_include/sys/os_socket.h
+++ b/ace/os_include/sys/os_socket.h
@@ -141,6 +141,14 @@ extern "C"
# define ACE_PROTOCOL_FAMILY_INET PF_INET
#endif /* ACE_HAS_IPV6 */
+#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_HAS_LKSCTP)
extern "C"
{
@@ -148,6 +156,48 @@ extern "C"
}
#endif /* ACE_HAS_LKSCTP */
+# if defined (ACE_LACKS_TIMEDWAIT_PROTOTYPES)
+
+ ssize_t recv_timedwait (ACE_HANDLE handle,
+ char *buf,
+ int len,
+ int flags,
+ struct timespec *timeout);
+
+ ssize_t recvmsg_timedwait (ACE_HANDLE handle,
+ struct msghdr *msg,
+ int flags,
+ struct timespec *timeout);
+
+ ssize_t recvfrom_timedwait (ACE_HANDLE handle,
+ char *buf,
+ int len,
+ int flags,
+ struct sockaddr *addr,
+ int *addrlen,
+ struct timespec *timeout);
+
+ ssize_t send_timedwait (ACE_HANDLE handle,
+ const char *buf,
+ int len,
+ int flags,
+ struct timespec *timeout);
+
+ ssize_t sendmsg_timedwait (ACE_HANDLE handle,
+ ACE_SENDMSG_TYPE *msg,
+ int flags,
+ struct timespec *timeout);
+
+ ssize_t sendto_timedwait (ACE_HANDLE handle,
+ const char *buf,
+ int len,
+ int flags,
+ const struct sockaddr *addr,
+ int addrlen,
+ struct timespec *timeout);
+
+# endif /* ACE_LACKS_TIMEDWAIT_PROTOTYPES */
+
#ifdef __cplusplus
}
#endif /* __cplusplus */
diff --git a/ace/os_include/sys/os_stat.h b/ace/os_include/sys/os_stat.h
index e43c68ca282..7224eee9160 100644
--- a/ace/os_include/sys/os_stat.h
+++ b/ace/os_include/sys/os_stat.h
@@ -27,7 +27,7 @@
#include "ace/os_include/sys/os_types.h"
#if defined (ACE_WIN32) && !defined (ACE_HAS_WINCE)
-# include <direct.h>
+# include /**/ <direct.h>
#endif /* ACE_WIN32 && !ACE_HAS_WINCE */
// This collides with phile.h on PSOS
diff --git a/ace/os_include/sys/os_time.h b/ace/os_include/sys/os_time.h
index 297a4ce084f..16336d47034 100644
--- a/ace/os_include/sys/os_time.h
+++ b/ace/os_include/sys/os_time.h
@@ -37,6 +37,18 @@ extern "C"
{
#endif /* __cplusplus */
+#if defined (ACE_HAS_SVR4_GETTIMEOFDAY)
+# if !defined (m88k) && !defined (SCO)
+ int gettimeofday (struct timeval *tp, void * = 0);
+# else
+ int gettimeofday (struct timeval *tp);
+# endif /* !m88k && !SCO */
+#elif defined (ACE_HAS_OSF1_GETTIMEOFDAY)
+ int gettimeofday (struct timeval *tp, struct timezone * = 0);
+#elif defined (ACE_HAS_SUNOS4_GETTIMEOFDAY)
+# define ACE_HAS_SVR4_GETTIMEOFDAY
+#endif /* ACE_HAS_SVR4_GETTIMEOFDAY */
+
#ifdef __cplusplus
}
#endif /* __cplusplus */
diff --git a/ace/os_include/sys/os_times.h b/ace/os_include/sys/os_times.h
index 13d75f8678f..62e69921e7d 100644
--- a/ace/os_include/sys/os_times.h
+++ b/ace/os_include/sys/os_times.h
@@ -24,7 +24,7 @@
# pragma once
#endif /* ACE_LACKS_PRAGMA_ONCE */
-#include "ace/os_include/sys/types.h"
+#include "ace/os_include/sys/os_types.h"
#if !defined (ACE_LACKS_SYS_TIMES_H)
# include /**/ <sys/times.h>
diff --git a/ace/os_include/sys/os_types.h b/ace/os_include/sys/os_types.h
index 800d35dbf3f..5ba552dde08 100644
--- a/ace/os_include/sys/os_types.h
+++ b/ace/os_include/sys/os_types.h
@@ -34,12 +34,23 @@
# include /**/ <types.h>
#endif /* ACE_HAS_WINCE */
+# if defined (ACE_USES_STD_NAMESPACE_FOR_STDC_LIB) && \
+ (ACE_USES_STD_NAMESPACE_FOR_STDC_LIB != 0)
+using std::time_t;
+# endif /* ACE_USES_STD_NAMESPACE_FOR_STDC_LIB */
+
// Place all additions (especially function declarations) within extern "C" {}
#ifdef __cplusplus
extern "C"
{
#endif /* __cplusplus */
+# if defined (ACE_LACKS_FLOATING_POINT)
+typedef ACE_UINT32 ACE_timer_t;
+# else
+typedef double ACE_timer_t;
+# endif /* ACE_LACKS_FLOATING_POINT */
+
// todo: don't forget to clean this up! ;-)
#if !defined (ACE_HAS_CLOCK_GETTIME) && !(defined (_CLOCKID_T_) || defined (_CLOCKID_T))
typedef int clockid_t;
diff --git a/ace/os_include/sys/os_uio.h b/ace/os_include/sys/os_uio.h
index 1cb7a6d2e71..6c39c1e15b8 100644
--- a/ace/os_include/sys/os_uio.h
+++ b/ace/os_include/sys/os_uio.h
@@ -75,6 +75,20 @@ extern "C"
typedef struct iovec ACE_READV_TYPE;
#endif /* ACE_HAS_BROKEN_READV */
+# if defined (ACE_LACKS_TIMEDWAIT_PROTOTYPES)
+
+ ssize_t readv_timedwait (ACE_HANDLE handle,
+ iovec *iov,
+ int iovcnt,
+ struct timespec* timeout);
+
+ ssize_t writev_timedwait (ACE_HANDLE handle,
+ ACE_WRITEV_TYPE *iov,
+ int iovcnt,
+ struct timespec *timeout);
+
+# endif /* ACE_LACKS_TIMEDWAIT_PROTOTYPES */
+
#ifdef __cplusplus
}
#endif /* __cplusplus */
diff --git a/ace/os_include/sys/os_wait.h b/ace/os_include/sys/os_wait.h
index 8b36fedfe1d..8e6ec6e1624 100644
--- a/ace/os_include/sys/os_wait.h
+++ b/ace/os_include/sys/os_wait.h
@@ -37,9 +37,57 @@ extern "C"
{
#endif /* __cplusplus */
-#if !defined (WNOHANG)
-# define WNOHANG 0100
-#endif /* !WNOHANG */
+ // Wrapping around wait status <wstat> macros for platforms that
+ // lack them.
+
+# if !defined (WCOREDUMP)
+# define WCOREDUMP(stat) 0
+# endif /* WCOREDUMP */
+
+# if !defined (WNOHANG)
+# define WNOHANG 0100
+# endif /* !WNOHANG */
+
+ // 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 */
+
+# if !defined (WIFCONTINUED)
+# define WIFCONTINUED(stat) 0
+# endif /* WIFCONTINUED */
+
+ // 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 */
+
+ // 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 !defined (WIFSTOPPED)
+# define WIFSTOPPED(stat) 0
+# endif /* WIFSTOPPED */
+
+# if !defined (WSTOPSIG)
+# define WSTOPSIG(stat) 0
+# endif /* WSTOPSIG */
+
+ // 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 */
#ifdef __cplusplus
}