00001
00002
00003 #include "ace/Task.h"
00004 #include "ace/Module.h"
00005
00006 #if !defined (__ACE_INLINE__)
00007 #include "ace/Task.inl"
00008 #endif
00009
00010
00011 ACE_RCSID (ace,
00012 Task,
00013 "Task.cpp,v 4.87 2006/06/20 19:27:06 shuston Exp")
00014
00015
00016 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
00017
00018 ACE_Task_Base::ACE_Task_Base (ACE_Thread_Manager *thr_man)
00019 : thr_count_ (0),
00020 thr_mgr_ (thr_man),
00021 flags_ (0),
00022 grp_id_ (-1),
00023 last_thread_id_ (0)
00024 {
00025 }
00026
00027 ACE_Task_Base::~ACE_Task_Base (void)
00028 {
00029 }
00030
00031
00032
00033 int
00034 ACE_Task_Base::svc (void)
00035 {
00036 ACE_TRACE ("ACE_Task_Base::svc");
00037 return 0;
00038 }
00039
00040
00041
00042 int
00043 ACE_Task_Base::open (void *)
00044 {
00045 ACE_TRACE ("ACE_Task_Base::open");
00046 return 0;
00047 }
00048
00049
00050
00051 int
00052 ACE_Task_Base::close (u_long)
00053 {
00054 ACE_TRACE ("ACE_Task_Base::close");
00055 return 0;
00056 }
00057
00058
00059
00060
00061 int
00062 ACE_Task_Base::module_closed (void)
00063 {
00064 return this->close (1);
00065 }
00066
00067
00068
00069 int
00070 ACE_Task_Base::put (ACE_Message_Block *, ACE_Time_Value *)
00071 {
00072 ACE_TRACE ("ACE_Task_Base::put");
00073 return 0;
00074 }
00075
00076
00077
00078 int
00079 ACE_Task_Base::wait (void)
00080 {
00081 ACE_TRACE ("ACE_Task_Base::wait");
00082
00083
00084
00085 if (this->thr_mgr () != 0)
00086 return this->thr_mgr ()->wait_task (this);
00087 else
00088 return 0;
00089 }
00090
00091
00092 int
00093 ACE_Task_Base::suspend (void)
00094 {
00095 ACE_TRACE ("ACE_Task_Base::suspend");
00096 ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1));
00097 if (this->thr_count_ > 0)
00098 return this->thr_mgr_->suspend_task (this);
00099
00100 return 0;
00101 }
00102
00103
00104 int
00105 ACE_Task_Base::resume (void)
00106 {
00107 ACE_TRACE ("ACE_Task_Base::resume");
00108 ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1));
00109 if (this->thr_count_ > 0)
00110 return this->thr_mgr_->resume_task (this);
00111
00112 return 0;
00113 }
00114
00115 int
00116 ACE_Task_Base::activate (long flags,
00117 int n_threads,
00118 int force_active,
00119 long priority,
00120 int grp_id,
00121 ACE_Task_Base *task,
00122 ACE_hthread_t thread_handles[],
00123 void *stack[],
00124 size_t stack_size[],
00125 ACE_thread_t thread_ids[])
00126 {
00127 ACE_TRACE ("ACE_Task_Base::activate");
00128
00129 #if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0)
00130 ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1);
00131
00132
00133 if (task == 0)
00134 task = this;
00135
00136 if (this->thr_count_ > 0 && force_active == 0)
00137 return 1;
00138 else
00139 {
00140 if (this->thr_count_ > 0 && this->grp_id_ != -1)
00141
00142
00143 grp_id = this->grp_id_;
00144 this->thr_count_ += n_threads;
00145 }
00146
00147
00148
00149
00150 if (this->thr_mgr_ == 0)
00151 # if defined (ACE_THREAD_MANAGER_LACKS_STATICS)
00152 this->thr_mgr_ = ACE_THREAD_MANAGER_SINGLETON::instance ();
00153 # else
00154 this->thr_mgr_ = ACE_Thread_Manager::instance ();
00155 # endif
00156
00157 int grp_spawned = -1;
00158 if (thread_ids == 0)
00159
00160 grp_spawned =
00161 this->thr_mgr_->spawn_n (n_threads,
00162 &ACE_Task_Base::svc_run,
00163 (void *) this,
00164 flags,
00165 priority,
00166 grp_id,
00167 task,
00168 thread_handles,
00169 stack,
00170 stack_size);
00171 else
00172
00173 grp_spawned =
00174 this->thr_mgr_->spawn_n (thread_ids,
00175 n_threads,
00176 &ACE_Task_Base::svc_run,
00177 (void *) this,
00178 flags,
00179 priority,
00180 grp_id,
00181 stack,
00182 stack_size,
00183 thread_handles,
00184 task);
00185 if (grp_spawned == -1)
00186 {
00187
00188 this->thr_count_ -= n_threads;
00189 return -1;
00190 }
00191
00192 if (this->grp_id_ == -1)
00193 this->grp_id_ = grp_spawned;
00194
00195 this->last_thread_id_ = 0;
00196
00197 return 0;
00198
00199 #else
00200 {
00201
00202 ACE_UNUSED_ARG (flags);
00203 ACE_UNUSED_ARG (n_threads);
00204 ACE_UNUSED_ARG (force_active);
00205 ACE_UNUSED_ARG (priority);
00206 ACE_UNUSED_ARG (grp_id);
00207 ACE_UNUSED_ARG (task);
00208 ACE_UNUSED_ARG (thread_handles);
00209 ACE_UNUSED_ARG (stack);
00210 ACE_UNUSED_ARG (stack_size);
00211 ACE_UNUSED_ARG (thread_ids);
00212 ACE_NOTSUP_RETURN (-1);
00213 }
00214 #endif
00215 }
00216
00217 void
00218 ACE_Task_Base::cleanup (void *object, void *)
00219 {
00220 ACE_Task_Base *t = (ACE_Task_Base *) object;
00221
00222
00223
00224 {
00225 ACE_MT (ACE_GUARD (ACE_Thread_Mutex, ace_mon, t->lock_));
00226 t->thr_count_--;
00227 if (0 == t->thr_count_)
00228 t->last_thread_id_ = ACE_Thread::self ();
00229 }
00230
00231
00232 t->close ();
00233
00234 }
00235
00236
00237 #if defined (ACE_HAS_SIG_C_FUNC)
00238 extern "C" void
00239 ACE_Task_Base_cleanup (void *object, void *)
00240 {
00241 ACE_Task_Base::cleanup (object, 0);
00242 }
00243 #endif
00244
00245 ACE_THR_FUNC_RETURN
00246 ACE_Task_Base::svc_run (void *args)
00247 {
00248 ACE_TRACE ("ACE_Task_Base::svc_run");
00249
00250 ACE_Task_Base *t = (ACE_Task_Base *) args;
00251
00252
00253
00254
00255
00256 #if defined ACE_HAS_SIG_C_FUNC
00257 t->thr_mgr ()->at_exit (t, ACE_Task_Base_cleanup, 0);
00258 #else
00259 t->thr_mgr ()->at_exit (t, ACE_Task_Base::cleanup, 0);
00260 #endif
00261
00262
00263 int svc_status = t->svc ();
00264 ACE_THR_FUNC_RETURN status;
00265 #if (defined (__BORLANDC__) && (__BORLANDC__ < 0x600)) || defined (__MINGW32__) || (defined (_MSC_VER) && (_MSC_VER <= 1400)) || (defined (ACE_WIN32) && defined(__IBMCPP__) || defined (__DCC__))
00266
00267 status = static_cast<ACE_THR_FUNC_RETURN> (svc_status);
00268 #else
00269 status = reinterpret_cast<ACE_THR_FUNC_RETURN> (svc_status);
00270 #endif
00271
00272
00273 #if 1
00274
00275 ACE_Thread_Manager *thr_mgr_ptr = t->thr_mgr ();
00276
00277
00278 t->cleanup (t, 0);
00279
00280
00281
00282 thr_mgr_ptr->at_exit (t, 0, 0);
00283 #endif
00284 return status;
00285 }
00286
00287 ACE_END_VERSIONED_NAMESPACE_DECL