diff options
-rw-r--r-- | ace/Task.cpp | 6 | ||||
-rw-r--r-- | ace/Task.h | 8 | ||||
-rw-r--r-- | ace/Thread_Manager.cpp | 15 | ||||
-rw-r--r-- | ace/Thread_Manager.h | 3 | ||||
-rw-r--r-- | tests/TSS_Test.cpp | 37 | ||||
-rw-r--r-- | tests/Task_Test.cpp | 38 |
6 files changed, 88 insertions, 19 deletions
diff --git a/ace/Task.cpp b/ace/Task.cpp index 009ad53d6b4..e9c3180ecbe 100644 --- a/ace/Task.cpp +++ b/ace/Task.cpp @@ -168,7 +168,8 @@ ACE_Task_Base::activate (long flags, int force_active, long priority, int grp_id, - ACE_Task_Base *task) + ACE_Task_Base *task, + ACE_hthread_t thread_handles[]) { ACE_TRACE ("ACE_Task_Base::activate"); @@ -196,7 +197,8 @@ ACE_Task_Base::activate (long flags, flags, priority, grp_id, - task); + task, + thread_handles); if (this->grp_id_ == -1) return -1; else diff --git a/ace/Task.h b/ace/Task.h index 2b800aa934f..5ae87e26596 100644 --- a/ace/Task.h +++ b/ace/Task.h @@ -92,7 +92,8 @@ public: int force_active = 0, long priority = ACE_DEFAULT_THREAD_PRIORITY, int grp_id = -1, - ACE_Task_Base *task = 0); + ACE_Task_Base *task = 0, + ACE_hthread_t thread_handles[] = 0); // Turn the task into an active object, i.e., having <n_threads> of // control, all running at the <priority> level (see below) with the same // <grp_id>, all of which invoke <Task::svc>. Returns -1 if failure @@ -119,6 +120,11 @@ public: // explicit value is given, it is used. Note that actual priority // values are EXTREMEMLY implementation-dependent, and are probably // best avoided. + // + // If <thread_handles> != 0 it is assumed to be an array of <n> + // thread_handles that will be assigned the values of the thread + // handles being spawned. Returns -1 on failure (<errno> will + // explain...), otherwise returns the group id of the threads. virtual int wait (void); // Wait for all threads running in this task to exit. diff --git a/ace/Thread_Manager.cpp b/ace/Thread_Manager.cpp index ee86fe81903..1690b70a89b 100644 --- a/ace/Thread_Manager.cpp +++ b/ace/Thread_Manager.cpp @@ -316,7 +316,8 @@ ACE_Thread_Manager::spawn_n (size_t n, long flags, long priority, int grp_id, - ACE_Task_Base *task) + ACE_Task_Base *task, + ACE_hthread_t thread_handles[]) { ACE_TRACE ("ACE_Thread_Manager::spawn_n"); ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1)); @@ -328,8 +329,16 @@ ACE_Thread_Manager::spawn_n (size_t n, { // @@ What should happen if this fails?! e.g., should we try to // cancel the other threads that we've already spawned or what? - if (this->spawn_i (func, args, flags, 0, 0, priority, grp_id, - 0, 0, task) == -1) + if (this->spawn_i (func, + args, + flags, + 0, + thread_handles == 0 ? 0 : &thread_handles[i], + priority, + grp_id, + 0, + 0, + task) == -1) return -1; } diff --git a/ace/Thread_Manager.h b/ace/Thread_Manager.h index 37d8f01ef98..ae7670c91b5 100644 --- a/ace/Thread_Manager.h +++ b/ace/Thread_Manager.h @@ -124,7 +124,8 @@ public: long flags = THR_NEW_LWP, long priority = ACE_DEFAULT_THREAD_PRIORITY, int grp_id = -1, - ACE_Task_Base *task = 0); + ACE_Task_Base *task = 0, + ACE_hthread_t thread_handles[] = 0); // Create N new threads, all of which execute <func>. // Returns: on success a unique group id that can be used to control // all of the threads in the same group. On failure, returns -1. diff --git a/tests/TSS_Test.cpp b/tests/TSS_Test.cpp index 43ef001913d..2fb12ca9a33 100644 --- a/tests/TSS_Test.cpp +++ b/tests/TSS_Test.cpp @@ -172,14 +172,39 @@ main (int, char *[]) // Register a signal handler. ACE_Sig_Action sa ((ACE_SignalHandler) handler, SIGINT); ACE_UNUSED_ARG (sa); + ACE_hthread_t *thread_handles; + + ACE_NEW_RETURN (thread_handles, ACE_hthread_t[ACE_MAX_THREADS], -1); + + if (ACE_Thread_Manager::instance ()->spawn_n + ((ACE_thread_t *) 0, + ACE_MAX_THREADS, + ACE_THR_FUNC (worker), + (void *) ITERATIONS, + THR_BOUND, + ACE_DEFAULT_THREAD_PRIORITY, + -1, + 0, + 0, + thread_handles) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "spawn_n"), 1); + +#if !defined (VXWORKS) + // VxWorks doesn't support thr_join() semantics... Someday + // we'll fix this. + ACE_Thread_Manager::instance ()->wait (); +#else + // Wait for all the threads to reach their exit point and then join + // with all the exiting threads. + for (int i = 0; + i < ACE_MAX_THREADS; + i++) + if (ACE_Thread::join (thread_handles[i]) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "join"), -1); +#endif /* VXWORKS */ - if (ACE_Thread_Manager::instance ()->spawn_n (ACE_MAX_THREADS, - ACE_THR_FUNC (&worker), - (void *) ITERATIONS, - THR_BOUND | THR_DETACHED) == -1) - ACE_OS::perror ("ACE_Thread_Manager::spawn_n"); + delete [] thread_handles; - ACE_Thread_Manager::instance ()->wait (); #else ACE_ERROR ((LM_ERROR, "threads are not supported on this platform\n")); diff --git a/tests/Task_Test.cpp b/tests/Task_Test.cpp index 19cf2b40038..65aeb0b14d6 100644 --- a/tests/Task_Test.cpp +++ b/tests/Task_Test.cpp @@ -30,7 +30,8 @@ class Barrier_Task : public ACE_Task<ACE_MT_SYNCH> public: Barrier_Task (ACE_Thread_Manager *thr_mgr, int n_threads, - int n_iterations); + int n_iterations, + ACE_hthread_t thread_handles[]); virtual int svc (void); // Iterate <n_iterations> time printing off a message and "waiting" @@ -47,13 +48,20 @@ private: Barrier_Task::Barrier_Task (ACE_Thread_Manager *thr_mgr, int n_threads, - int n_iterations) + int n_iterations, + ACE_hthread_t thread_handles[]) : ACE_Task<ACE_MT_SYNCH> (thr_mgr), barrier_ (n_threads), n_iterations_ (n_iterations) { // Create worker threads. - if (this->activate (THR_NEW_LWP, n_threads) == -1) + if (this->activate (THR_NEW_LWP, + n_threads, + 0, + ACE_DEFAULT_THREAD_PRIORITY, + -1, + 0, + thread_handles) == -1) ACE_ERROR ((LM_ERROR, "%p\n", "activate failed")); } @@ -93,13 +101,31 @@ main (int, char *[]) #if defined (ACE_HAS_THREADS) int n_threads = ACE_MAX_THREADS; int n_iterations = ACE_MAX_ITERATIONS; + ACE_hthread_t *thread_handles; + + ACE_NEW_RETURN (thread_handles, ACE_hthread_t[n_threads], -1); Barrier_Task barrier_task (ACE_Thread_Manager::instance (), n_threads, - n_iterations); + n_iterations, + thread_handles); + +#if !defined (VXWORKS) + // VxWorks doesn't support thr_join() semantics... Someday + // we'll fix this. + ACE_Thread_Manager::instance ()->wait (); +#else + // Wait for all the threads to reach their exit point and then join + // with all the exiting threads. + for (int i = 0; + i < n_threads; + i++) + if (ACE_Thread::join (thread_handles[i]) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "join"), -1); +#endif /* VXWORKS */ + + delete [] thread_handles; - // Wait for all the threads to reach their exit point. - ACE_Thread_Manager::instance ()->wait (); #else ACE_ERROR ((LM_ERROR, "threads not supported on this platform\n")); #endif /* ACE_HAS_THREADS */ |