Changes to attempt to silence bcc64x
[ACE_TAO.git] / ACE / ace / Task.cpp
blob4596d91088ebc4edd03a690f87dc206e32e5e6f6
1 #include "ace/Task.h"
2 #include "ace/Module.h"
4 #if !defined (__ACE_INLINE__)
5 #include "ace/Task.inl"
6 #endif /* __ACE_INLINE__ */
8 #include "ace/OS_NS_string.h"
10 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
12 ACE_Task_Base::ACE_Task_Base (ACE_Thread_Manager *thr_man)
13 : thr_count_ (0),
14 thr_mgr_ (thr_man),
15 flags_ (0),
16 grp_id_ (-1)
17 #if !defined (ACE_THREAD_T_IS_A_STRUCT)
18 ,last_thread_id_ (0)
19 #endif /* !ACE_THREAD_T_IS_A_STRUCT */
21 #if defined (ACE_THREAD_T_IS_A_STRUCT)
22 ACE_OS::memset( &this->last_thread_id_, '\0', sizeof( this->last_thread_id_ ));
23 #endif /* ACE_THREAD_T_IS_A_STRUCT */
26 ACE_Task_Base::~ACE_Task_Base ()
30 /// Default ACE_Task service routine
31 int
32 ACE_Task_Base::svc ()
34 ACE_TRACE ("ACE_Task_Base::svc");
35 return 0;
38 /// Default ACE_Task open routine
39 int
40 ACE_Task_Base::open (void *)
42 ACE_TRACE ("ACE_Task_Base::open");
43 return 0;
46 /// Default ACE_Task close routine
47 int
48 ACE_Task_Base::close (u_long)
50 ACE_TRACE ("ACE_Task_Base::close");
51 return 0;
54 /// Forward the call to close() so that existing applications don't
55 /// break.
56 int
57 ACE_Task_Base::module_closed ()
59 return this->close (1);
62 /// Default ACE_Task put routine.
63 int
64 ACE_Task_Base::put (ACE_Message_Block *, ACE_Time_Value *)
66 ACE_TRACE ("ACE_Task_Base::put");
67 return 0;
70 /// Wait for all threads running in a task to exit.
71 int
72 ACE_Task_Base::wait ()
74 ACE_TRACE ("ACE_Task_Base::wait");
76 // If we don't have a thread manager, we probably were never
77 // activated.
78 if (this->thr_mgr () != 0)
79 return this->thr_mgr ()->wait_task (this);
80 else
81 return 0;
84 /// Suspend a task.
85 int
86 ACE_Task_Base::suspend ()
88 ACE_TRACE ("ACE_Task_Base::suspend");
89 ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1));
90 if (this->thr_count_ > 0)
91 return this->thr_mgr_->suspend_task (this);
93 return 0;
96 /// Resume a suspended task.
97 int
98 ACE_Task_Base::resume ()
100 ACE_TRACE ("ACE_Task_Base::resume");
101 ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1));
102 if (this->thr_count_ > 0)
103 return this->thr_mgr_->resume_task (this);
105 return 0;
109 ACE_Task_Base::activate (long flags,
110 int n_threads,
111 int force_active,
112 long priority,
113 int grp_id,
114 ACE_Task_Base *task,
115 ACE_hthread_t thread_handles[],
116 void *stack[],
117 size_t stack_size[],
118 ACE_thread_t thread_ids[],
119 const char* thr_name[])
121 ACE_TRACE ("ACE_Task_Base::activate");
123 #if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0)
124 ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1);
126 // If the task passed in is zero, we will use <this>
127 if (task == 0)
128 task = this;
130 if (this->thr_count_ > 0 && force_active == 0)
131 return 1; // Already active.
132 else
134 if ((this->thr_count_ > 0 || grp_id == -1) &&
135 this->grp_id_ != -1)
136 // If we're joining an existing group of threads then make
137 // sure to (re)use its group id.
138 grp_id = this->grp_id_;
139 else if (grp_id != -1)
140 // make sure to reset the cached grp_id
141 this->grp_id_ = -1;
142 this->thr_count_ += n_threads;
145 // Use the ACE_Thread_Manager singleton if we're running as an
146 // active object and the caller didn't supply us with a
147 // Thread_Manager.
148 if (this->thr_mgr_ == 0)
149 # if defined (ACE_THREAD_MANAGER_LACKS_STATICS)
150 this->thr_mgr_ = ACE_THREAD_MANAGER_SINGLETON::instance ();
151 # else /* ! ACE_THREAD_MANAGER_LACKS_STATICS */
152 this->thr_mgr_ = ACE_Thread_Manager::instance ();
153 # endif /* ACE_THREAD_MANAGER_LACKS_STATICS */
155 int grp_spawned = -1;
156 if (thread_ids == 0)
157 // Thread Ids were not specified
158 grp_spawned =
159 this->thr_mgr_->spawn_n (n_threads,
160 &ACE_Task_Base::svc_run,
161 (void *) this,
162 flags,
163 priority,
164 grp_id,
165 task,
166 thread_handles,
167 stack,
168 stack_size,
169 thr_name);
170 else
171 // thread names were specified
172 grp_spawned =
173 this->thr_mgr_->spawn_n (thread_ids,
174 n_threads,
175 &ACE_Task_Base::svc_run,
176 (void *) this,
177 flags,
178 priority,
179 grp_id,
180 stack,
181 stack_size,
182 thread_handles,
183 task,
184 thr_name);
185 if (grp_spawned == -1)
187 // If spawn_n fails, restore original thread count.
188 this->thr_count_ -= n_threads;
189 return -1;
192 if (this->grp_id_ == -1)
193 this->grp_id_ = grp_spawned;
195 #if defined (ACE_THREAD_T_IS_A_STRUCT)
196 ACE_OS::memcpy( &this->last_thread_id_, '\0', sizeof(this->last_thread_id_));
197 #else
198 this->last_thread_id_ = 0; // Reset to prevent inadvertant match on ID
199 #endif /* ACE_THREAD_T_IS_A_STRUCT */
201 return 0;
203 #else
205 // Keep the compiler from complaining.
206 ACE_UNUSED_ARG (flags);
207 ACE_UNUSED_ARG (n_threads);
208 ACE_UNUSED_ARG (force_active);
209 ACE_UNUSED_ARG (priority);
210 ACE_UNUSED_ARG (grp_id);
211 ACE_UNUSED_ARG (task);
212 ACE_UNUSED_ARG (thread_handles);
213 ACE_UNUSED_ARG (stack);
214 ACE_UNUSED_ARG (stack_size);
215 ACE_UNUSED_ARG (thread_ids);
216 ACE_UNUSED_ARG (thr_name);
217 ACE_NOTSUP_RETURN (-1);
219 #endif /* ACE_MT_SAFE */
222 void
223 ACE_Task_Base::cleanup (void *object, void *)
225 ACE_Task_Base *t = (ACE_Task_Base *) object;
227 // The thread count must be decremented first in case the <close>
228 // hook does something crazy like "delete this".
230 ACE_MT (ACE_GUARD (ACE_Thread_Mutex, ace_mon, t->lock_));
231 t->thr_count_--;
232 if (0 == t->thr_count_)
233 t->last_thread_id_ = ACE_Thread::self ();
236 // @@ Is it possible to pass in the exit status somehow?
237 t->close ();
238 // t is undefined here. close() could have deleted it.
242 #if defined (ACE_HAS_SIG_C_FUNC)
243 extern "C" void
244 ACE_Task_Base_cleanup (void *object, void *)
246 ACE_Task_Base::cleanup (object, 0);
248 #endif /* ACE_HAS_SIG_C_FUNC */
250 ACE_THR_FUNC_RETURN
251 ACE_Task_Base::svc_run (void *args)
253 ACE_TRACE ("ACE_Task_Base::svc_run");
255 ACE_Task_Base *t = (ACE_Task_Base *) args;
257 // Register ourself with our <Thread_Manager>'s thread exit hook
258 // mechanism so that our close() hook will be sure to get invoked
259 // when this thread exits.
261 #if defined ACE_HAS_SIG_C_FUNC
262 t->thr_mgr ()->at_exit (t, ACE_Task_Base_cleanup, 0);
263 #else
264 t->thr_mgr ()->at_exit (t, ACE_Task_Base::cleanup, 0);
265 #endif /* ACE_HAS_SIG_C_FUNC */
267 ACE_THR_FUNC_RETURN status;
268 // Call the Task's svc() hook method.
269 int const svc_status = t->svc ();
271 #if defined (ACE_HAS_INTEGRAL_TYPE_THR_FUNC_RETURN)
272 // Reinterpret case between integral types is not mentioned in the C++ spec
273 status = static_cast<ACE_THR_FUNC_RETURN> (svc_status);
274 #else
275 status = reinterpret_cast<ACE_THR_FUNC_RETURN> (svc_status);
276 #endif /* ACE_HAS_INTEGRAL_TYPE_THR_FUNC_RETURN */
278 // If we changed this zero change the other if in OS.cpp Thread_Adapter::invoke
279 #if 1
280 // Call the <Task->close> hook.
281 ACE_Thread_Manager *thr_mgr_ptr = t->thr_mgr ();
283 // This calls the Task->close () hook.
284 t->cleanup (t, 0);
286 // This prevents a second invocation of the cleanup code
287 // (called later by <ACE_Thread_Manager::exit>.
288 thr_mgr_ptr->at_exit (t, 0, 0);
289 #endif
290 return status;
293 ACE_END_VERSIONED_NAMESPACE_DECL