diff options
Diffstat (limited to 'ace/OS.cpp')
-rw-r--r-- | ace/OS.cpp | 1241 |
1 files changed, 0 insertions, 1241 deletions
diff --git a/ace/OS.cpp b/ace/OS.cpp deleted file mode 100644 index ceb87dcd53f..00000000000 --- a/ace/OS.cpp +++ /dev/null @@ -1,1241 +0,0 @@ -// $Id$ - -// OS.cpp -#define ACE_BUILD_DLL -#include "ace/OS.h" - -#include "ace/Log_Msg.h" -#include "ace/ARGV.h" - -// Perhaps we should *always* include ace/OS.i in order to make sure -// we can always link against the OS symbols? -#if !defined (ACE_HAS_INLINED_OSCALLS) -#include "ace/OS.i" -#endif /* ACE_HAS_INLINED_OS_CALLS */ - -void -ACE_OS::flock_t::dump (void) const -{ -// ACE_TRACE ("ACE_OS::flock_t::dump"); - - ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this)); - ACE_DEBUG ((LM_DEBUG, "handle_ = %u", this->handle_)); -#if defined (ACE_WIN32) - ACE_DEBUG ((LM_DEBUG, "\nInternal = %d", this->overlapped_.Internal)); - ACE_DEBUG ((LM_DEBUG, "\nInternalHigh = %d", this->overlapped_.InternalHigh)); - ACE_DEBUG ((LM_DEBUG, "\nOffsetHigh = %d", this->overlapped_.OffsetHigh)); - ACE_DEBUG ((LM_DEBUG, "\nhEvent = %d", this->overlapped_.hEvent)); -#else - ACE_DEBUG ((LM_DEBUG, "\nl_whence = %d", this->lock_.l_whence)); - ACE_DEBUG ((LM_DEBUG, "\nl_start = %d", this->lock_.l_start)); - ACE_DEBUG ((LM_DEBUG, "\nl_len = %d", this->lock_.l_len)); - ACE_DEBUG ((LM_DEBUG, "\nl_type = %d", this->lock_.l_type)); -#endif /* ACE_WIN32 */ - ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); -} - -void -ACE_OS::mutex_lock_cleanup (void *mutex) -{ -// ACE_TRACE ("ACE_OS::mutex_lock_cleanup"); -#if defined (ACE_HAS_THREADS) -#if defined (ACE_HAS_DCETHREADS) || defined (ACE_HAS_PTHREADS) - ACE_mutex_t *p_lock = (ACE_mutex_t *) mutex; - ACE_OS::mutex_unlock (p_lock); -#endif /* ACE_HAS_DCETHREADS */ -#endif /* ACE_HAS_THREADS */ -} - -// = Static initialization. - -// This is necessary to deal with POSIX pthreads insanity. This -// guarantees that we've got a "zero'd" thread id even when ACE_thread_t -// is implemented as a structure... -ACE_thread_t ACE_OS::NULL_thread; - -ACE_OS::ACE_OS (void) -{ -// ACE_TRACE ("ACE_OS::ACE_OS"); -} - -#if defined (ACE_WIN32) - -// = Static initialization. - -// Keeps track of whether we've initialized the WinSock DLL. -int ACE_OS::socket_initialized_; - -// We need this to initialize the WinSock DLL. - -BOOL WINAPI -DllMain (HINSTANCE, // DLL module handle - DWORD fdwReason, // Reason called - LPVOID) // Reserved -{ - switch (fdwReason) - { - case DLL_PROCESS_ATTACH: - if (ACE_OS::socket_init (ACE_WSOCK_VERSION) != 0) - return FALSE; - break; - - case DLL_PROCESS_DETACH: - if (ACE_OS::socket_fini () != 0) - return FALSE; - break; - - case DLL_THREAD_ATTACH: - case DLL_THREAD_DETACH: - break; - - default: - ACE_ERROR_RETURN ((LM_ERROR, - "Sock.DLL DllMain called with unknown fdwReason = %u\n.", - fdwReason), FALSE); - /* NOTREACHED */ - } - - return TRUE; -} - -#include "ace/Synch.h" -#include "ace/Set.h" - -class ACE_TSS_Ref - // = TITLE - // "Reference count" for thread-specific storage keys. - // - // = DESCRIPTION - // Since the ACE_Unbounded_Set doesn't allow duplicates, the - // "reference count" is the identify of the thread_id. -{ -public: - ACE_TSS_Ref (ACE_thread_t id); - // Constructor - - ACE_TSS_Ref (void); - // Default constructor - - int operator== (const ACE_TSS_Ref &); - // Check for equality. - -// private: - - ACE_thread_t tid_; - // ID of thread using a specific key. -}; - -ACE_TSS_Ref::ACE_TSS_Ref (ACE_thread_t id) - : tid_(id) -{ -// ACE_TRACE ("ACE_TSS_Ref::ACE_TSS_Ref"); -} - -ACE_TSS_Ref::ACE_TSS_Ref (void) -{ -// ACE_TRACE ("ACE_TSS_Ref::ACE_TSS_Ref"); -} - -// Check for equality. -int -ACE_TSS_Ref::operator== (const ACE_TSS_Ref &info) -{ -// ACE_TRACE ("ACE_TSS_Ref::operator=="); - - return this->tid_ == info.tid_; -} - -typedef ACE_Unbounded_Set<ACE_TSS_Ref> ACE_TSS_REF_TABLE; -typedef ACE_Unbounded_Set_Iterator<ACE_TSS_Ref> ACE_TSS_REF_TABLE_ITERATOR; - -class ACE_TSS_Info - // = TITLE - // Thread Specific Key management. - // - // = DESCRIPTION - // This class maps a key to a "destructor." -{ -public: - ACE_TSS_Info (ACE_thread_key_t key, - void (*dest)(void *) = 0, - void *tss_inst = 0); - // Constructor - - ACE_TSS_Info (void); - // Default constructor - - int operator== (const ACE_TSS_Info &); - // Check for equality. - - void dump (void); - // Dump the state. - -// private: - ACE_thread_key_t key_; - // Key to the thread-specific storage item. - - void (*destructor_)(void *); - // "Destructor" that gets called when the item is finally released. - - void *tss_obj_; - // Pointer to ACE_TSS<xxx> instance that has/will allocate the key. - - ACE_TSS_REF_TABLE ref_table_; - // Table of thread IDs that are using this key. -}; - -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) -{ -// ACE_TRACE ("ACE_TSS_Info::ACE_TSS_Info"); -} - -ACE_TSS_Info::ACE_TSS_Info (void) -{ -// ACE_TRACE ("ACE_TSS_Info::ACE_TSS_Info"); -} - -// Check for equality. -int -ACE_TSS_Info::operator== (const ACE_TSS_Info &info) -{ -// ACE_TRACE ("ACE_TSS_Info::operator=="); - - return this->key_ == info.key_; -} - -void -ACE_TSS_Info::dump (void) -{ -// ACE_TRACE ("ACE_TSS_Info::dump"); - - ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this)); - ACE_DEBUG ((LM_DEBUG, "key_ = %u", this->key_)); - ACE_DEBUG ((LM_DEBUG, "\ndestructor_ = %u", this->destructor_)); - ACE_DEBUG ((LM_DEBUG, "\ntss_obj_ = %u", this->tss_obj_)); - ACE_DEBUG ((LM_DEBUG, "\nref_table_.size_ = %u", this->ref_table_.size ())); - - ACE_TSS_Ref *tid_info = 0; - - ACE_DEBUG ((LM_DEBUG, "\nThread_usage_list\n[\n")); - - for (ACE_TSS_REF_TABLE_ITERATOR iter (this->ref_table_); - iter.next (tid_info) != 0; - iter.advance ()) - ACE_DEBUG ((LM_DEBUG, "\ntid_ = %d", tid_info->tid_)); - - ACE_DEBUG ((LM_DEBUG, "\n]\n")); - ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); -} - -// Create a set of <ACE_TSS_Info> objects that will reside -// within thread-specific storage. -typedef ACE_Unbounded_Set<ACE_TSS_Info> ACE_TSS_TABLE; -typedef ACE_Unbounded_Set_Iterator<ACE_TSS_Info> ACE_TSS_TABLE_ITERATOR; - -class ACE_TSS_Cleanup - // = TITLE - // Singleton that knows how to clean up all the thread-specific - // resources for Win32. - // - // = DESCRIPTION - // All this nonsense is required since Win32 doesn't - // automatically cleanup thread-specific storage on thread exit, - // unlike real operating systems... ;-) -{ -public: - static ACE_TSS_Cleanup *instance (void); - - void exit (void *status); - // Cleanup the thread-specific objects and exit with <status>. - - int insert (ACE_thread_key_t key, void (*destructor)(void *), void *inst); - // Insert a <key, destructor> tuple into the table. - - int remove (ACE_thread_key_t key); - // Remove a <key, destructor> tuple from the table. - - int detach (void *inst); - // Detaches a tss_instance from its key. - - int detach (ACE_thread_key_t key, ACE_thread_t tid); - // Detaches a thread from the key. - - int key_used (ACE_thread_key_t key); - // Mark a key as being used by this thread. - -protected: - void dump (void); - - ACE_TSS_Cleanup (void); - // Ensure singleton. - -private: - ACE_TSS_TABLE table_; - // Table of <ACE_TSS_Info>'s. - - // = Static data. - static ACE_TSS_Cleanup *instance_; - // Pointer to the singleton instance. - -public: - static ACE_Recursive_Thread_Mutex lock_; - // Serialize initialization of <key_>. -}; - -// = Static object initialization. - -// Pointer to the singleton instance. -ACE_TSS_Cleanup *ACE_TSS_Cleanup::instance_ = 0; - -// Serialize initialization of <key_>. -ACE_Recursive_Thread_Mutex ACE_TSS_Cleanup::lock_; - -void -ACE_TSS_Cleanup::exit (void *status) -{ -// ACE_TRACE ("ACE_TSS_Cleanup::exit"); - - { - ACE_GUARD (ACE_Recursive_Thread_Mutex, ace_mon, ACE_TSS_Cleanup::lock_); - - // Prevent recursive deletions (note that when a recursive mutex - // is first acquired it has a nesting level of 1...). - if (ACE_TSS_Cleanup::lock_.get_nesting_level () > 1) - return; - - ACE_thread_key_t key_arr[TLS_MINIMUM_AVAILABLE]; - int index = 0; - - ACE_TSS_Info *key_info = 0; - - // Iterate through all the thread-specific items and free them all - // up. - - for (ACE_TSS_TABLE_ITERATOR iter (this->table_); - iter.next (key_info) != 0; - iter.advance ()) - { - void *tss_info = 0; - - int val = key_info->ref_table_.remove (ACE_TSS_Ref (ACE_OS::thr_self ())); - - if ((ACE_OS::thr_getspecific (key_info->key_, &tss_info) == 0) - && (key_info->destructor_) - && tss_info) - // Probably need to have an exception handler here... - (*key_info->destructor_) (tss_info); - - if (key_info->ref_table_.size () == 0 - && key_info->tss_obj_ == 0) - key_arr[index++] = key_info->key_; - } - - for (int i = 0; i < index; i++) - { - ::TlsFree (key_arr[i]); - this->table_.remove (ACE_TSS_Info (key_arr[i])); - } - } - -#if 0 - ::ExitThread ((DWORD) status); -#endif - ::_endthreadex ((DWORD) status); - - /* NOTREACHED */ -} - -ACE_TSS_Cleanup::ACE_TSS_Cleanup (void) -{ -// ACE_TRACE ("ACE_TSS_Cleanup::ACE_TSS_Cleanup"); -} - -ACE_TSS_Cleanup * -ACE_TSS_Cleanup::instance (void) -{ -// ACE_TRACE ("ACE_TSS_Cleanup::instance"); - - // Create and initialize thread-specific key. - if (ACE_TSS_Cleanup::instance_ == 0) - { - // Insure that we are serialized! - ACE_GUARD_RETURN (ACE_Recursive_Thread_Mutex, ace_mon, ACE_TSS_Cleanup::lock_, 0); - - // Now, use the Double-Checked Locking pattern to make sure we - // only create the key once. - if (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_TRACE ("ACE_TSS_Cleanup::insert"); - ACE_GUARD_RETURN (ACE_Recursive_Thread_Mutex, ace_mon, ACE_TSS_Cleanup::lock_, -1); - - return this->table_.insert (ACE_TSS_Info (key, destructor, inst)); -} - -int -ACE_TSS_Cleanup::remove (ACE_thread_key_t key) -{ -// ACE_TRACE ("ACE_TSS_Cleanup::remove"); - ACE_GUARD_RETURN (ACE_Recursive_Thread_Mutex, ace_mon, ACE_TSS_Cleanup::lock_, -1); - - return this->table_.remove (ACE_TSS_Info (key)); -} - -int -ACE_TSS_Cleanup::detach (void *inst) -{ - ACE_GUARD_RETURN (ACE_Recursive_Thread_Mutex, ace_mon, ACE_TSS_Cleanup::lock_, -1); - - ACE_TSS_Info *key_info = 0; - int success = 0; - int ref_cnt = 0; - - for (ACE_TSS_TABLE_ITERATOR iter (this->table_); - iter.next (key_info) != 0; - iter.advance ()) - { - if (key_info->tss_obj_ == inst) - { - key_info->tss_obj_ = 0; - ref_cnt = key_info->ref_table_.size (); - success = 1; - break; - } - } - - if (success == 0) - return -1; - else if (ACE_TSS_Cleanup::lock_.get_nesting_level () > 1) - ACE_ERROR_RETURN ((LM_DEBUG, "Detach() invoked from ACE_TSS_Cleanup::exit()\n"), 0); - else if (ref_cnt == 0) - { - ::TlsFree (key_info->key_); - return this->table_.remove (ACE_TSS_Info (key_info->key_)); - } - - return 0; -} - -int -ACE_TSS_Cleanup::detach (ACE_thread_key_t key, ACE_thread_t tid) -{ - return -1; -} - -int -ACE_TSS_Cleanup::key_used (ACE_thread_key_t key) -{ - ACE_GUARD_RETURN (ACE_Recursive_Thread_Mutex, ace_mon, ACE_TSS_Cleanup::lock_, -1); - - ACE_TSS_Info *key_info = 0; - - for (ACE_TSS_TABLE_ITERATOR iter (this->table_); - iter.next (key_info) != 0; - iter.advance ()) - if (key_info->key_ == key) - return key_info->ref_table_.insert (ACE_TSS_Ref (ACE_OS::thr_self ())); - - return -1; -} - -void -ACE_TSS_Cleanup::dump (void) -{ - ACE_TSS_Info *key_info = 0; - - // Iterate through all the thread-specific items and dump them all. - - for (ACE_TSS_TABLE_ITERATOR iter (this->table_); - iter.next (key_info) != 0; - iter.advance ()) - key_info->dump (); -} - -// Special thread startup argument (used below in <thr_create>). - -class ACE_Win32_Thread_Adapter -{ -public: - ACE_Win32_Thread_Adapter (ACE_THR_FUNC f, void *a); - // Constructor - - static void *svc_run (ACE_Win32_Thread_Adapter *); - // Run the thread exit point. - -private: - // = Arguments to thread startup. - ACE_THR_FUNC func_; - // Thread startup function. - - void *arg_; - // Argument to thread startup function. -}; - -ACE_Win32_Thread_Adapter::ACE_Win32_Thread_Adapter (ACE_THR_FUNC f, void *a) - : func_(f), - arg_(a) -{ -// ACE_TRACE ("ACE_Win32_Thread_Adapter::ACE_Win32_Thread_Adapter"); -} - -void * -ACE_Win32_Thread_Adapter::svc_run (ACE_Win32_Thread_Adapter *thread_args) -{ -// ACE_TRACE ("ACE_Win32_Thread_Adapter::svc_run"); - ACE_THR_FUNC func = thread_args->func_; - void *arg = thread_args->arg_; - delete thread_args; - void *status; - - ACE_SEH_TRY { - status = (*func) (arg); // Call thread entry point. - } - ACE_SEH_EXCEPT (EXCEPTION_EXECUTE_HANDLER) { - // Here's where we might want to provide a hook to report this... - // As it stands now, we just catch all Win32 structured exceptions - // so that we can make sure to clean up correctly when the thread - // exits. - } - - // If dropped off end, call destructors for thread-specific storage - // and exit. - ACE_TSS_Cleanup::instance ()->exit (status); - - /* NOTREACHED */ - return status; -} - -#endif // WIN32 - -int -ACE_OS::thr_create (ACE_THR_FUNC func, - void *args, - long flags, - ACE_thread_t *thr_id, - ACE_hthread_t *thr_handle, - u_int priority, - void *stack, - size_t stacksize) -{ -// ACE_TRACE ("ACE_OS::thr_create"); - -#if defined (ACE_HAS_THREADS) -#if defined (ACE_HAS_DCETHREADS) || defined (ACE_HAS_PTHREADS) - int result; - pthread_attr_t attr; - ACE_thread_t tmp_thr; - ACE_thread_t *p_thr; - -#if defined (ACE_HAS_SETKIND_NP) - if (::pthread_attr_create (&attr) != 0) -#else /* ACE_HAS_SETKIND_NP */ - if (::pthread_attr_init (&attr) != 0) -#endif /* ACE_HAS_SETKIND_NP */ - return -1; - else if (priority != 0) - { - struct sched_param sparam; - - ACE_OS::memset ((void *) &sparam, 0, sizeof sparam); - -#if defined (ACE_HAS_DCETHREADS) && !defined (ACE_HAS_SETKIND_NP) - sparam.sched_priority = priority > PRIORITY_MAX ? PRIORITY_MAX : priority; -#elif defined(ACE_HAS_IRIX62_THREADS) - sparam.sched_priority = priority > PTHREAD_MAX_PRIORITY ? PTHREAD_MAX_PRIORITY : priority; -#elif defined (PTHREAD_MAX_PRIORITY) // For MIT pthreads... - sparam.prio = priority > PTHREAD_MAX_PRIORITY ? PTHREAD_MAX_PRIORITY : priority; -#endif /* ACE_HAS_DCETHREADS */ - -#if !defined (ACE_HAS_FSU_PTHREADS) -#if defined (ACE_HAS_SETKIND_NP) - if (::pthread_attr_setsched (&attr, SCHED_OTHER) != 0) -#else /* ACE_HAS_SETKIND_NP */ - if (::pthread_attr_setschedparam (&attr, &sparam) != 0) -#endif /* ACE_HAS_SETKIND_NP */ - { -#if defined (ACE_HAS_SETKIND_NP) - ::pthread_attr_delete (&attr); -#else /* ACE_HAS_SETKIND_NP */ - ::pthread_attr_destroy (&attr); -#endif /* ACE_HAS_SETKIND_NP */ - return -1; - } -#else - if ((sparam.sched_priority >= PTHREAD_MIN_PRIORITY) - && (sparam.sched_priority <= PTHREAD_MAX_PRIORITY)) - attr.prio = sparam.sched_priority; - else - { - pthread_attr_destroy (&attr); - return -1; - } -#endif // ACE_HAS_FSU_PTHREADS - } - - if (stacksize != 0) - { - size_t size = stacksize; - -#if defined (PTHREAD_STACK_MIN) - if (size < PTHREAD_STACK_MIN) - stacksize = PTHREAD_STACK_MIN; -#endif /* PTHREAD_STACK_MIN */ - - if (::pthread_attr_setstacksize (&attr, size) != 0) - { -#if defined (ACE_HAS_SETKIND_NP) - ::pthread_attr_delete (&attr); -#else /* ACE_HAS_SETKIND_NP */ - ::pthread_attr_destroy (&attr); -#endif /* ACE_HAS_SETKIND_NP */ - return -1; - } - } - -#if !defined (ACE_LACKS_THREAD_STACK_ADDR) - if (stack != 0) - { - if (::pthread_attr_setstackaddr (&attr, stack) != 0) - { -#if defined (ACE_HAS_SETKIND_NP) - ::pthread_attr_delete (&attr); -#else /* ACE_HAS_SETKIND_NP */ - ::pthread_attr_destroy (&attr); -#endif /* ACE_HAS_SETKIND_NP */ - return -1; - } - } -#endif /* !ACE_LACKS_THREAD_STACK_ADDR */ - if (flags != 0) - { -#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_SETKIND_NP) - if (::pthread_attr_setdetach_np (&attr, dstate) != 0) -#else /* ACE_HAS_SETKIND_NP */ - if (::pthread_attr_setdetachstate (&attr, dstate) != 0) -#endif /* ACE_HAS_SETKIND_NP */ - { -#if defined (ACE_HAS_SETKIND_NP) - ::pthread_attr_delete (&attr); -#else /* ACE_HAS_SETKIND_NP */ - ::pthread_attr_destroy (&attr); -#endif /* ACE_HAS_SETKIND_NP */ - return -1; - } - } -#endif /* ACE_LACKS_SETDETACH */ - 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 (ACE_BIT_ENABLED (flags, THR_SCHED_DEFAULT)) - spolicy = SCHED_OTHER; - else if (ACE_BIT_ENABLED (flags, THR_SCHED_FIFO)) - spolicy = SCHED_FIFO; - else - spolicy = SCHED_RR; - -#if !defined (ACE_HAS_FSU_PTHREADS) -#if defined (ACE_HAS_SETKIND_NP) - if (::pthread_attr_setsched (&attr, spolicy) != 0) -#else /* ACE_HAS_SETKIND_NP */ - if (::pthread_attr_setschedpolicy (&attr, spolicy) != 0) -#endif /* ACE_HAS_SETKIND_NP */ - { -#if defined (ACE_HAS_SETKIND_NP) - ::pthread_attr_delete (&attr); -#else /* ACE_HAS_SETKIND_NP */ - ::pthread_attr_destroy (&attr); -#endif /* ACE_HAS_SETKIND_NP */ - return -1; - } -#else - int ret; - switch (spolicy) - { - case SCHED_FIFO: - case SCHED_RR: - ret = 0; - break; - default: - ret = 22; - break; - } - if (ret != 0) - { -#if defined (ACE_HAS_SETKIND_NP) - ::pthread_attr_delete (&attr); -#else /* ACE_HAS_SETKIND_NP */ - ::pthread_attr_destroy (&attr); -#endif /* ACE_HAS_SETKIND_NP */ - return -1; - } -#endif // ACE_HAS_FSU_PTHREADS - } - - if (ACE_BIT_ENABLED (flags, THR_INHERIT_SCHED) - || ACE_BIT_ENABLED (flags, THR_EXPLICIT_SCHED)) - { -#if defined (ACE_HAS_SETKIND_NP) - int sched = PTHREAD_DEFAULT_SCHED; -#else /* ACE_HAS_SETKIND_NP */ - int sched = PTHREAD_EXPLICIT_SCHED; -#endif /* ACE_HAS_SETKIND_NP */ - if (ACE_BIT_ENABLED (flags, THR_INHERIT_SCHED)) - sched = PTHREAD_INHERIT_SCHED; - if (::pthread_attr_setinheritsched (&attr, sched) != 0) - { -#if defined (ACE_HAS_SETKIND_NP) - ::pthread_attr_delete (&attr); -#else /* ACE_HAS_SETKIND_NP */ - ::pthread_attr_destroy (&attr); -#endif /* ACE_HAS_SETKIND_NP */ - return -1; - } - } -#if !defined (ACE_LACKS_THREAD_PROCESS_SCOPING) - if (ACE_BIT_ENABLED (flags, THR_SCOPE_SYSTEM) - || ACE_BIT_ENABLED (flags, THR_SCOPE_PROCESS)) - { - int scope = PTHREAD_SCOPE_PROCESS; - if (ACE_BIT_ENABLED (flags, THR_SCOPE_SYSTEM)) - scope = PTHREAD_SCOPE_SYSTEM; - - if (::pthread_attr_setscope (&attr, scope) != 0) - { -#if defined (ACE_HAS_SETKIND_NP) - ::pthread_attr_delete (&attr); -#else /* ACE_HAS_SETKIND_NP */ - ::pthread_attr_destroy (&attr); -#endif /* ACE_HAS_SETKIND_NP */ - 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 - // Solaris semantics. - int lwps = ACE_OS::thr_getconcurrency (); - ACE_OS::thr_setconcurrency (lwps + 1); - } - } - - p_thr = (thr_id == 0 ? &tmp_thr : thr_id); - -#if defined (ACE_HAS_SETKIND_NP) - ACE_OSCALL (ACE_ADAPT_RETVAL (::pthread_create (p_thr, attr, func, args), - result), - int, -1, result); - ::pthread_attr_delete (&attr); - if (thr_handle != 0) - *thr_handle = (ACE_hthread_t) 0; -#else /* !ACE_HAS_SETKIND_NP */ - ACE_OSCALL (ACE_ADAPT_RETVAL (::pthread_create (p_thr, &attr, func, args), - result), - int, -1, result); - ::pthread_attr_destroy (&attr); - -#if defined (ACE_HAS_STHREADS) - // This is the Solaris implementation of pthreads, where - // ACE_thread_t and ACE_hthread_t are the same. - if (result == 0 && thr_handle != 0) - *thr_handle = *thr_id; -#else - if (thr_handle != 0) - thr_handle = (ACE_hthread_t *) 0; -#endif /* ACE_HAS_STHREADS */ -#endif /* ACE_HAS_SETKIND_NP */ - return result; -#elif defined (ACE_HAS_STHREADS) - int result; - ACE_OSCALL (ACE_ADAPT_RETVAL (::thr_create (stack, stacksize, func, args, - flags, thr_id), result), - int, -1, result); - if (result == 0 && thr_handle != 0) - *thr_handle = *thr_id; - return result; -#elif defined (ACE_HAS_WTHREADS) - ACE_thread_t t; - ACE_hthread_t handle; - - if (thr_id == 0) - thr_id = &t; - if (thr_handle == 0) - thr_handle = &handle; - - ACE_Win32_Thread_Adapter *thread_args; - - ACE_NEW_RETURN (thread_args, ACE_Win32_Thread_Adapter (func, args), -1); - - typedef unsigned (__stdcall *ThreadFunc) (void*); - -#if defined (ACE_HAS_MFC) - if (ACE_BIT_ENABLED (flags, THR_USE_AFX)) - { - CWinThread *cwin_thread = - // These aren't the right arguments (yet). - ::AfxBeginThread ((ThreadFunc) (ACE_Win32_Thread_Adapter::svc_run), - thread_args, 0, 0, flags); - *thr_handle = cwin_thread->m_hThread; - *thr_id = cwin_thread->m_nThreadID; - // Can we delete the memory of cwin_thread here? - } - else -#endif /* ACE_HAS_MFC */ - *thr_handle = (void *) ::_beginthreadex - (NULL, - stacksize, - (ThreadFunc) (ACE_Win32_Thread_Adapter::svc_run), - thread_args, - flags, - (unsigned int *) thr_id); - -#if 0 - *thr_handle = ::CreateThread - (NULL, stacksize, - LPTHREAD_START_ROUTINE (ACE_Win32_Thread_Adapter::svc_run), - thread_args, flags, thr_id); -#endif /* 0 */ - - // Close down the handle if no one wants to use it. - if (thr_handle == &handle) - ::CloseHandle (handle); - - if (*thr_handle != 0) - return 0; - else - ACE_FAIL_RETURN (-1); - /* NOTREACHED */ -#elif defined (VXWORKS) - // If thr_id points to NULL (or is 0), the call below causes VxWorks - // to assign a unique task name of the form: "t" + an integer. - - // args must be an array of _exactly_ 10 ints. - - // stack arg is ignored: if there's a need for it, we'd have to use - // taskInit ()/taskActivate () instead of taskSpawn () - - // The hard-coded arguments are what ::sp() would use. ::taskInit() - // is used instead of ::sp() so that we can set the priority, flags, - // and stacksize. (::sp() also hardcodes priority to 100, flags - // to VX_FP_TASK, and stacksize to 20,000.) stacksize should be - // an even integer. - - // if called with thr_create() defaults, use same default values as ::sp() - if (stacksize == 0) stacksize = 20000; - if (priority == 0) priority = 100; - - ACE_hthread_t tid = ::taskSpawn (thr_id == 0 ? NULL : *thr_id, priority, - (int) flags, (int) stacksize, func, - ((int *) args)[0], ((int *) args)[1], - ((int *) args)[2], ((int *) args)[3], - ((int *) args)[4], ((int *) args)[5], - ((int *) args)[6], ((int *) args)[7], - ((int *) args)[8], ((int *) args)[9]); - - if (tid == ERROR) - return -1; - else - { - // return the thr_id and thr_handle, if addresses were provided for them - if (thr_id != 0) - // 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 - // would be a bit quicker than this extraction of the tcb . . . - *thr_id = taskTcb (tid)->name; - if (thr_handle != 0) - *thr_handle = tid; - return 0; - } - -#endif /* ACE_HAS_STHREADS */ -#else - ACE_NOTSUP_RETURN (-1); -#endif /* ACE_HAS_THREADS */ -} - -void -ACE_OS::thr_exit (void *status) -{ -// ACE_TRACE ("ACE_OS::thr_exit"); -#if defined (ACE_HAS_THREADS) -#if defined (ACE_HAS_DCETHREADS) || defined (ACE_HAS_PTHREADS) - ::pthread_exit (status); -#elif defined (ACE_HAS_STHREADS) - ::thr_exit (status); -#elif defined (ACE_HAS_WTHREADS) - // Cleanup the thread-specific resources and exit. - ACE_TSS_Cleanup::instance ()->exit (status); -#elif defined (VXWORKS) - ACE_hthread_t tid; - ACE_OS::thr_self (tid); - - *((int *) status) = ::taskDelete (tid); -#endif /* ACE_HAS_STHREADS */ -#else - ; -#endif /* ACE_HAS_THREADS */ -} - -int -ACE_OS::thr_setspecific (ACE_thread_key_t key, void *data) -{ -// ACE_TRACE ("ACE_OS::thr_setspecific"); -#if defined (ACE_HAS_THREADS) -#if defined (ACE_HAS_DCETHREADS) || 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); - ACE_TSS_Cleanup::instance ()->key_used (key); - return 0; -#elif defined (VXWORKS) - ACE_NOTSUP_RETURN (-1); -#endif /* ACE_HAS_STHREADS */ -#else - ACE_NOTSUP_RETURN (-1); -#endif /* ACE_HAS_THREADS */ -} - -int -ACE_OS::thr_keyfree (ACE_thread_key_t key) -{ -// ACE_TRACE ("ACE_OS::thr_keyfree"); -#if defined (ACE_HAS_THREADS) -#if defined (ACE_LACKS_KEYDELETE) - ACE_NOTSUP_RETURN (-1); -#elif defined (ACE_HAS_PTHREADS) && !defined (ACE_HAS_FSU_PTHREADS) - return ::pthread_key_delete (key); -#elif defined (ACE_HAS_DCETHREADS) - ACE_NOTSUP_RETURN (-1); -#elif defined (ACE_HAS_STHREADS) - ACE_NOTSUP_RETURN (-1); -#elif defined (ACE_HAS_WTHREADS) - // Extract out the thread-specific table instance and and free up - // the key and destructor. - ACE_TSS_Cleanup::instance ()->remove (key); - ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::TlsFree (key), ace_result_), int, -1); -#elif defined (VXWORKS) - ACE_NOTSUP_RETURN (-1); -#endif /* ACE_HAS_STHREADS */ -#else - ACE_NOTSUP_RETURN (-1); -#endif /* ACE_HAS_THREADS */ -} - -int -ACE_OS::thr_keycreate (ACE_thread_key_t *key, - void (*dest) (void *), - void *inst) -{ -// ACE_TRACE ("ACE_OS::thr_keycreate"); - inst = inst; -#if defined (ACE_HAS_THREADS) -#if defined (ACE_HAS_DCETHREADS) || defined (ACE_HAS_PTHREADS) -#if defined (ACE_HAS_SETKIND_NP) - ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::pthread_keycreate (key, dest), - ace_result_), - int, -1); -#else /* ACE_HAS_SETKIND_NP */ - ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::pthread_key_create (key, dest), - ace_result_), - int, -1); -#endif /* ACE_HAS_SETKIND_NP */ -#elif defined (ACE_HAS_STHREADS) - 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 */ - -#elif defined (VXWORKS) - ACE_NOTSUP_RETURN (-1); -#endif /* ACE_HAS_STHREADS */ -#else - ACE_NOTSUP_RETURN (-1); -#endif /* ACE_HAS_THREADS */ -} - -int -ACE_OS::thr_key_used (ACE_thread_key_t key) -{ -#if defined (ACE_WIN32) - return ACE_TSS_Cleanup::instance ()->key_used (key); -#else - key = key; - ACE_NOTSUP_RETURN (-1); -#endif /* ACE_WIN32 */ -} - -int -ACE_OS::thr_key_detach (void *inst) -{ -#if defined (ACE_WIN32) - return ACE_TSS_Cleanup::instance()->detach (inst); -#else - inst = inst; - ACE_NOTSUP_RETURN (-1); -#endif /* ACE_WIN32 */ -} - -// Create a contiguous command-line argument buffer with each arg -// separated by spaces. - -pid_t -ACE_OS::fork_exec (char *argv[]) -{ -#if defined (ACE_WIN32) - ACE_ARGV argv_buf (argv); - - char *buf = argv_buf.buf (); - - if (buf != 0) - { - PROCESS_INFORMATION process_info; - STARTUPINFO startup_info; - ACE_OS::memset ((void *) &startup_info, 0, sizeof startup_info); - startup_info.cb = sizeof startup_info; - - if (::CreateProcess (NULL, - buf, - NULL, // No process attributes. - NULL, // No thread attributes. - TRUE, // Allow handle inheritance. - CREATE_NEW_CONSOLE, // Create a new console window. - NULL, // No environment. - NULL, // No current directory. - &startup_info, - &process_info)) - { - // Free resources allocated in kernel. - ACE_OS::close (process_info.hThread); - ACE_OS::close (process_info.hProcess); - // Return new process id. - return process_info.dwProcessId; - } - } - - // CreateProcess failed. - return -1; -#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) - { - 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 */ - } - -#if defined (ACE_NEEDS_WRITEV) - -// "Fake" writev for sites without it. Note that this is totally -// broken for multi-threaded applications since the <send_n> calls are -// not atomic... - -extern "C" int -writev (ACE_HANDLE handle, ACE_WRITEV_TYPE *vp, int vpcount) -{ -// ACE_TRACE ("::writev"); - - int count; - - for (count = 0; --vpcount >= 0; count += vp->iov_len, vp++) - if (ACE::send_n (handle, vp->iov_base, vp->iov_len) < 0) - return -1; - - return count; -} -#endif /* ACE_NEEDS_WRITEV */ - -#if defined (ACE_NEEDS_READV) - -// "Fake" readv for sites without it. Note that this is totally -// broken for multi-threaded applications since the <send_n> calls are -// not atomic... - -extern "C" int -readv (ACE_HANDLE handle, struct iovec *vp, int vpcount) -{ -// ACE_TRACE ("::readv"); - - int count; - - for (count = 0; --vpcount >= 0; count += vp->iov_len, vp++) - if (ACE::recv_n (handle, vp->iov_base, vp->iov_len) < 0) - return -1; - - return count; -} -#endif /* ACE_NEEDS_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 ::fcntl (handle, F_FREESP, &fl); -} -#endif /* ACE_NEEDS_FTRUNCATE */ - -char * -ACE_OS::mktemp (char *s) -{ - // ACE_TRACE ("ACE_OS::mktemp"); -#if defined (ACE_LACKS_MKTEMP) - if (s == 0) - // check for null template string failed! - return 0; - else - { - char *xxxxxx = ACE_OS::strstr (s, "XXXXXX"); - - if (xxxxxx == 0) - // the template string doesn't contain "XXXXXX"! - return s; - else - { - char unique_letter = 'a'; - struct 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 - // Solaris 2.5 mktemp(). - ::sprintf (xxxxxx, "%05d%c", getpid (), unique_letter); - while (::stat (s, &sb) >= 0) - { - if (++unique_letter <= 'z') - ::sprintf (xxxxxx, "%05d%c", getpid (), unique_letter); - else - { - // maximum of 26 unique files per template, per process - ::sprintf (xxxxxx, "%s", ""); - return s; - } - } - } - return s; - } - -#else - return ::mktemp (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) - ACE_ERROR_RETURN ((LM_ERROR, - "WSAStartup failed, WSAGetLastError returned %u.\n", - error), -1); - - ACE_OS::socket_initialized_ = 1; - } -#else - version_high = version_high; - version_low = 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 (); - ACE_ERROR_RETURN ((LM_ERROR, - "WSACleanup failed, WSAGetLastError returned %u.\n", - error), -1); - } - ACE_OS::socket_initialized_ = 0; - } -#endif /* ACE_WIN32 */ - return 0; -} - -#if defined (VXWORKS) -int sys_nerr = ERRMAX + 1; - -#endif /* VXWORKS */ |