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