summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ace/Task.cpp6
-rw-r--r--ace/Task.h8
-rw-r--r--ace/Thread_Manager.cpp15
-rw-r--r--ace/Thread_Manager.h3
-rw-r--r--tests/TSS_Test.cpp37
-rw-r--r--tests/Task_Test.cpp38
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 */