Main Page   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   File Members   Related Pages  

Task.cpp

Go to the documentation of this file.
00001 #include "ace_pch.h"
00002 // $Id: Task.cpp,v 1.1.1.4.2.1 2003/03/13 19:44:22 chad Exp $
00003 
00004 #include "ace/Task.h"
00005 #include "ace/Module.h"
00006 
00007 #if !defined (__ACE_INLINE__)
00008 #include "ace/Task.i"
00009 #endif /* __ACE_INLINE__ */
00010 
00011 ACE_RCSID(ace, Task, "$Id: Task.cpp,v 1.1.1.4.2.1 2003/03/13 19:44:22 chad Exp $")
00012 
00013 ACE_Task_Base::~ACE_Task_Base (void)
00014 {
00015 }
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 {
00023 }
00024 
00025 // Wait for all threads running in a task to exit.
00026 
00027 int
00028 ACE_Task_Base::wait (void)
00029 {
00030   ACE_TRACE ("ACE_Task_Base::wait");
00031 
00032   // If we don't have a thread manager, we probably were never
00033   // activated.
00034   if (this->thr_mgr () != 0)
00035     return this->thr_mgr ()->wait_task (this);
00036   else
00037     return 0;
00038 }
00039 
00040 // Suspend a task.
00041 int
00042 ACE_Task_Base::suspend (void)
00043 {
00044   ACE_TRACE ("ACE_Task_Base::suspend");
00045   ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1));
00046   if (this->thr_count_ > 0)
00047     return this->thr_mgr_->suspend_task (this);
00048 
00049   return 0;
00050 }
00051 
00052 // Resume a suspended task.
00053 int
00054 ACE_Task_Base::resume (void)
00055 {
00056   ACE_TRACE ("ACE_Task_Base::resume");
00057   ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1));
00058   if (this->thr_count_ > 0)
00059     return this->thr_mgr_->resume_task (this);
00060 
00061   return 0;
00062 }
00063 
00064 int
00065 ACE_Task_Base::activate (long flags,
00066                          int n_threads,
00067                          int force_active,
00068                          long priority,
00069                          int grp_id,
00070                          ACE_Task_Base *task,
00071                          ACE_hthread_t thread_handles[],
00072                          void *stack[],
00073                          size_t stack_size[],
00074                          ACE_thread_t thread_ids[])
00075 {
00076   ACE_TRACE ("ACE_Task_Base::activate");
00077 
00078 #if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0)
00079   ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1);
00080 
00081   // If the task passed in is zero, we will use <this>
00082   if (task == 0)
00083     task = this;
00084 
00085   if (this->thr_count_ > 0 && force_active == 0)
00086     return 1; // Already active.
00087   else
00088     {
00089       if (this->thr_count_ > 0 && grp_id != -1)
00090         // If we're joining an existing group of threads then make
00091         // sure to use its group id.
00092         grp_id = this->grp_id_;
00093       this->thr_count_ += n_threads;
00094     }
00095 
00096   // Use the ACE_Thread_Manager singleton if we're running as an
00097   // active object and the caller didn't supply us with a
00098   // Thread_Manager.
00099   if (this->thr_mgr_ == 0)
00100 # if defined (ACE_THREAD_MANAGER_LACKS_STATICS)
00101     this->thr_mgr_ = ACE_THREAD_MANAGER_SINGLETON::instance ();
00102 # else /* ! ACE_THREAD_MANAGER_LACKS_STATICS */
00103     this->thr_mgr_ = ACE_Thread_Manager::instance ();
00104 # endif /* ACE_THREAD_MANAGER_LACKS_STATICS */
00105 
00106   int grp_spawned = -1;
00107   if (thread_ids == 0)
00108     // Thread Ids were not specified
00109     grp_spawned =
00110       this->thr_mgr_->spawn_n (n_threads,
00111                                &ACE_Task_Base::svc_run,
00112                                (void *) this,
00113                                flags,
00114                                priority,
00115                                grp_id,
00116                                task,
00117                                thread_handles,
00118                                stack,
00119                                stack_size);
00120   else
00121     // thread names were specified
00122     grp_spawned =
00123       this->thr_mgr_->spawn_n (thread_ids,
00124                                n_threads,
00125                                &ACE_Task_Base::svc_run,
00126                                (void *) this,
00127                                flags,
00128                                priority,
00129                                grp_id,
00130                                stack,
00131                                stack_size,
00132                                thread_handles,
00133                                task);
00134   if (grp_spawned == -1)
00135     {
00136       // If spawn_n fails, restore original thread count.
00137       this->thr_count_ -= n_threads;
00138       return -1;
00139     }
00140 
00141   if (this->grp_id_ == -1)
00142     this->grp_id_ = grp_spawned;
00143 
00144   return 0;
00145 
00146 #else
00147   {
00148     // Keep the compiler from complaining.
00149     ACE_UNUSED_ARG (flags);
00150     ACE_UNUSED_ARG (n_threads);
00151     ACE_UNUSED_ARG (force_active);
00152     ACE_UNUSED_ARG (priority);
00153     ACE_UNUSED_ARG (grp_id);
00154     ACE_UNUSED_ARG (task);
00155     ACE_UNUSED_ARG (thread_handles);
00156     ACE_UNUSED_ARG (stack);
00157     ACE_UNUSED_ARG (stack_size);
00158     ACE_UNUSED_ARG (thread_ids);
00159     ACE_NOTSUP_RETURN (-1);
00160   }
00161 #endif /* ACE_MT_SAFE */
00162 }
00163 
00164 void
00165 ACE_Task_Base::cleanup (void *object, void *)
00166 {
00167   ACE_Task_Base *t = (ACE_Task_Base *) object;
00168 
00169   // The thread count must be decremented first in case the <close>
00170   // hook does something crazy like "delete this".
00171   t->thr_count_dec ();
00172 
00173   // @@ Is it possible to pass in the exit status somehow?
00174   t->close ();
00175 }
00176 
00177 
00178 #if defined (ACE_HAS_SIG_C_FUNC)
00179 extern "C" void
00180 ACE_Task_Base_cleanup (void *object, void *)
00181 {
00182   ACE_Task_Base::cleanup (object, 0);
00183 }
00184 #endif /* ACE_HAS_SIG_C_FUNC */
00185 
00186 ACE_THR_FUNC_RETURN
00187 ACE_Task_Base::svc_run (void *args)
00188 {
00189   ACE_TRACE ("ACE_Task_Base::svc_run");
00190 
00191   ACE_Task_Base *t = (ACE_Task_Base *) args;
00192 
00193   // Register ourself with our <Thread_Manager>'s thread exit hook
00194   // mechanism so that our close() hook will be sure to get invoked
00195   // when this thread exits.
00196 
00197 #if defined ACE_HAS_SIG_C_FUNC
00198   t->thr_mgr ()->at_exit (t, ACE_Task_Base_cleanup, 0);
00199 #else
00200   t->thr_mgr ()->at_exit (t, ACE_Task_Base::cleanup, 0);
00201 #endif /* ACE_HAS_SIG_C_FUNC */
00202 
00203   // Call the Task's svc() hook method.
00204   int svc_status = t->svc ();
00205   ACE_THR_FUNC_RETURN status;
00206 #if (defined (__BORLANDC__) && (__BORLANDC__ < 0x570)) || defined (__MINGW32__) || (defined (_MSC_VER) && (_MSC_VER <= 1200))
00207   // Some compilers complain about reinterpret_cast from int to unsigned long...
00208   status = ACE_static_cast (ACE_THR_FUNC_RETURN, svc_status);
00209 #else
00210   status = ACE_reinterpret_cast (ACE_THR_FUNC_RETURN, svc_status);
00211 #endif /* (__BORLANDC__ < 0x570) || __MINGW32__ || _MSC_VER <= 1200 */
00212 
00213 // If we changed this zero change the other if in OS.cpp Thread_Adapter::invoke
00214 #if 1
00215   // Call the <Task->close> hook.
00216   ACE_Thread_Manager *thr_mgr_ptr = t->thr_mgr ();
00217 
00218   // This calls the Task->close () hook.
00219   t->cleanup (t, 0);
00220 
00221   // This prevents a second invocation of the cleanup code
00222   // (called later by <ACE_Thread_Manager::exit>.
00223   thr_mgr_ptr->at_exit (t, 0, 0);
00224 #endif
00225   return status;
00226 }
00227 
00228 // Forward the call to close() so that existing applications don't
00229 // break.
00230 
00231 int
00232 ACE_Task_Base::module_closed (void)
00233 {
00234   return this->close (1);
00235 }

Generated on Mon Jun 16 11:21:44 2003 for ACE by doxygen1.2.14 written by Dimitri van Heesch, © 1997-2002