PageRenderTime 28ms CodeModel.GetById 28ms RepoModel.GetById 3ms app.codeStats 1ms

/dep/acelite/ace/Thread_Manager.cpp

https://github.com/chucho/FaceCore
C++ | 1716 lines | 1235 code | 261 blank | 220 comment | 197 complexity | 298f914aad71b7bd28d3163e32b292aa MD5 | raw file
  1. // $Id: Thread_Manager.cpp 91368 2010-08-16 13:03:34Z mhengstmengel $
  2. #include "ace/TSS_T.h"
  3. #include "ace/Thread_Manager.h"
  4. #include "ace/Dynamic.h"
  5. #include "ace/Object_Manager.h"
  6. #include "ace/Singleton.h"
  7. #include "ace/Auto_Ptr.h"
  8. #include "ace/Guard_T.h"
  9. #include "ace/Time_Value.h"
  10. #include "ace/OS_NS_sys_time.h"
  11. #include "ace/Truncate.h"
  12. #if !defined (__ACE_INLINE__)
  13. #include "ace/Thread_Manager.inl"
  14. #endif /* __ACE_INLINE__ */
  15. ACE_BEGIN_VERSIONED_NAMESPACE_DECL
  16. ACE_At_Thread_Exit::~ACE_At_Thread_Exit (void)
  17. {
  18. this->do_apply ();
  19. }
  20. ACE_At_Thread_Exit_Func::~ACE_At_Thread_Exit_Func (void)
  21. {
  22. this->do_apply ();
  23. }
  24. void
  25. ACE_At_Thread_Exit_Func::apply (void)
  26. {
  27. this->func_ (this->object_, this->param_);
  28. }
  29. ACE_ALLOC_HOOK_DEFINE(ACE_Thread_Control)
  30. ACE_ALLOC_HOOK_DEFINE(ACE_Thread_Manager)
  31. #if ! defined (ACE_THREAD_MANAGER_LACKS_STATICS)
  32. // Process-wide Thread Manager.
  33. ACE_Thread_Manager *ACE_Thread_Manager::thr_mgr_ = 0;
  34. // Controls whether the Thread_Manager is deleted when we shut down
  35. // (we can only delete it safely if we created it!)
  36. bool ACE_Thread_Manager::delete_thr_mgr_ = false;
  37. #endif /* ! defined (ACE_THREAD_MANAGER_LACKS_STATICS) */
  38. ACE_TSS_TYPE (ACE_Thread_Exit) *ACE_Thread_Manager::thr_exit_ = 0;
  39. int
  40. ACE_Thread_Manager::set_thr_exit (ACE_TSS_TYPE (ACE_Thread_Exit) *ptr)
  41. {
  42. if (ACE_Thread_Manager::thr_exit_ == 0)
  43. ACE_Thread_Manager::thr_exit_ = ptr;
  44. else
  45. return -1;
  46. return 0;
  47. }
  48. void
  49. ACE_Thread_Manager::dump (void)
  50. {
  51. #if defined (ACE_HAS_DUMP)
  52. ACE_TRACE ("ACE_Thread_Manager::dump");
  53. // Cast away const-ness of this in order to use its non-const lock_.
  54. ACE_MT (ACE_GUARD (ACE_Thread_Mutex, ace_mon,
  55. ((ACE_Thread_Manager *) this)->lock_));
  56. ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this));
  57. ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\ngrp_id_ = %d"), this->grp_id_));
  58. ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\ncurrent_count_ = %d"), this->thr_list_.size ()));
  59. for (ACE_Double_Linked_List_Iterator<ACE_Thread_Descriptor> iter (this->thr_list_);
  60. !iter.done ();
  61. iter.advance ())
  62. {
  63. iter.next ()->dump ();
  64. }
  65. ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP));
  66. #endif /* ACE_HAS_DUMP */
  67. }
  68. ACE_Thread_Descriptor::~ACE_Thread_Descriptor (void)
  69. {
  70. delete this->sync_;
  71. }
  72. void
  73. ACE_Thread_Descriptor::at_pop (int apply)
  74. {
  75. ACE_TRACE ("ACE_Thread_Descriptor::at_pop");
  76. // Get first at from at_exit_list
  77. ACE_At_Thread_Exit* at = this->at_exit_list_;
  78. // Remove at from at_exit list
  79. this->at_exit_list_ = at->next_;
  80. // Apply if required
  81. if (apply)
  82. {
  83. at->apply ();
  84. // Do the apply method
  85. at->was_applied (true);
  86. // Mark at has been applied to avoid double apply from
  87. // at destructor
  88. }
  89. // If at is not owner delete at.
  90. if (!at->is_owner ())
  91. delete at;
  92. }
  93. void
  94. ACE_Thread_Descriptor::at_push (ACE_At_Thread_Exit* cleanup, bool is_owner)
  95. {
  96. ACE_TRACE ("ACE_Thread_Descriptor::at_push");
  97. cleanup->is_owner (is_owner);
  98. cleanup->td_ = this;
  99. cleanup->next_ = at_exit_list_;
  100. at_exit_list_ = cleanup;
  101. }
  102. int
  103. ACE_Thread_Descriptor::at_exit (ACE_At_Thread_Exit& cleanup)
  104. {
  105. ACE_TRACE ("ACE_Thread_Descriptor::at_exit");
  106. at_push (&cleanup, 1);
  107. return 0;
  108. }
  109. int
  110. ACE_Thread_Descriptor::at_exit (ACE_At_Thread_Exit* cleanup)
  111. {
  112. ACE_TRACE ("ACE_Thread_Descriptor::at_exit");
  113. if (cleanup==0)
  114. return -1;
  115. else
  116. {
  117. this->at_push (cleanup);
  118. return 0;
  119. }
  120. }
  121. void
  122. ACE_Thread_Descriptor::do_at_exit ()
  123. {
  124. ACE_TRACE ("ACE_Thread_Descriptor::do_at_exit");
  125. while (at_exit_list_!=0)
  126. this->at_pop ();
  127. }
  128. void
  129. ACE_Thread_Descriptor::terminate ()
  130. {
  131. ACE_TRACE ("ACE_Thread_Descriptor::terminate");
  132. if (!terminated_)
  133. {
  134. ACE_Log_Msg* log_msg = this->log_msg_;
  135. terminated_ = true;
  136. // Run at_exit hooks
  137. this->do_at_exit ();
  138. // We must remove Thread_Descriptor from Thread_Manager list
  139. if (this->tm_ != 0)
  140. {
  141. int close_handle = 0;
  142. #if !defined (ACE_HAS_VXTHREADS)
  143. // Threads created with THR_DAEMON shouldn't exist here, but
  144. // just to be safe, let's put it here.
  145. if (ACE_BIT_DISABLED (this->thr_state_, ACE_Thread_Manager::ACE_THR_JOINING))
  146. {
  147. if (ACE_BIT_DISABLED (this->flags_, THR_DETACHED | THR_DAEMON)
  148. || ACE_BIT_ENABLED (this->flags_, THR_JOINABLE))
  149. {
  150. // Mark thread as terminated.
  151. ACE_SET_BITS (this->thr_state_, ACE_Thread_Manager::ACE_THR_TERMINATED);
  152. tm_->register_as_terminated (this);
  153. // Must copy the information here because td will be
  154. // "freed" below.
  155. }
  156. #if defined (ACE_WIN32)
  157. else
  158. {
  159. close_handle = 1;
  160. }
  161. #endif /* ACE_WIN32 */
  162. }
  163. #endif /* !ACE_HAS_VXTHREADS */
  164. // Remove thread descriptor from the table.
  165. if (this->tm_ != 0)
  166. tm_->remove_thr (this, close_handle);
  167. }
  168. // Check if we need delete ACE_Log_Msg instance
  169. // If ACE_TSS_cleanup was not executed first log_msg == 0
  170. if (log_msg == 0)
  171. {
  172. // Only inform to ACE_TSS_cleanup that it must delete the log instance
  173. // setting ACE_LOG_MSG thr_desc to 0.
  174. ACE_LOG_MSG->thr_desc (0);
  175. }
  176. else
  177. {
  178. // Thread_Descriptor is the owner of the Log_Msg instance!!
  179. // deleted.
  180. this->log_msg_ = 0;
  181. delete log_msg;
  182. }
  183. }
  184. }
  185. int
  186. ACE_Thread_Descriptor::at_exit (void *object,
  187. ACE_CLEANUP_FUNC cleanup_hook,
  188. void *param)
  189. {
  190. ACE_TRACE ("ACE_Thread_Descriptor::at_exit");
  191. // To keep compatibility, when cleanup_hook is null really is a at_pop
  192. // without apply.
  193. if (cleanup_hook == 0)
  194. {
  195. if (this->at_exit_list_!= 0)
  196. this->at_pop(0);
  197. }
  198. else
  199. {
  200. ACE_At_Thread_Exit* cleanup = 0;
  201. ACE_NEW_RETURN (cleanup,
  202. ACE_At_Thread_Exit_Func (object,
  203. cleanup_hook,
  204. param),
  205. -1);
  206. this->at_push (cleanup);
  207. }
  208. return 0;
  209. }
  210. void
  211. ACE_Thread_Descriptor::dump (void) const
  212. {
  213. #if defined (ACE_HAS_DUMP)
  214. ACE_TRACE ("ACE_Thread_Descriptor::dump");
  215. ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this));
  216. ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\nthr_id_ = %d"), this->thr_id_));
  217. ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\nthr_handle_ = %d"), this->thr_handle_));
  218. ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\ngrp_id_ = %d"), this->grp_id_));
  219. ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\nthr_state_ = %d"), this->thr_state_));
  220. ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\nflags_ = %x\n"), this->flags_));
  221. ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP));
  222. #endif /* ACE_HAS_DUMP */
  223. }
  224. ACE_Thread_Descriptor::ACE_Thread_Descriptor (void)
  225. : log_msg_ (0),
  226. at_exit_list_ (0),
  227. terminated_ (false)
  228. {
  229. ACE_TRACE ("ACE_Thread_Descriptor::ACE_Thread_Descriptor");
  230. ACE_NEW (this->sync_,
  231. ACE_DEFAULT_THREAD_MANAGER_LOCK);
  232. }
  233. void
  234. ACE_Thread_Descriptor::acquire_release (void)
  235. {
  236. // Just try to acquire the lock then release it.
  237. #if defined (ACE_THREAD_MANAGER_USES_SAFE_SPAWN)
  238. if (ACE_BIT_DISABLED (this->thr_state_, ACE_Thread_Manager::ACE_THR_SPAWNED))
  239. #endif /* ACE_THREAD_MANAGER_USES_SAFE_SPAWN */
  240. {
  241. this->sync_->acquire ();
  242. // Acquire the lock before removing <td> from the thread table. If
  243. // this thread is in the table already, it should simply acquire the
  244. // lock easily.
  245. // Once we get the lock, we must have registered.
  246. ACE_ASSERT (ACE_BIT_ENABLED (this->thr_state_, ACE_Thread_Manager::ACE_THR_SPAWNED));
  247. this->sync_->release ();
  248. // Release the lock before putting it back to freelist.
  249. }
  250. }
  251. void
  252. ACE_Thread_Descriptor::acquire (void)
  253. {
  254. // Just try to acquire the lock then release it.
  255. #if defined (ACE_THREAD_MANAGER_USES_SAFE_SPAWN)
  256. if (ACE_BIT_DISABLED (this->thr_state_, ACE_Thread_Manager::ACE_THR_SPAWNED))
  257. #endif /* ACE_THREAD_MANAGER_USES_SAFE_SPAWN */
  258. {
  259. this->sync_->acquire ();
  260. }
  261. }
  262. void
  263. ACE_Thread_Descriptor::release (void)
  264. {
  265. // Just try to acquire the lock then release it.
  266. #if defined (ACE_THREAD_MANAGER_USES_SAFE_SPAWN)
  267. if (ACE_BIT_DISABLED (this->thr_state_, ACE_Thread_Manager::ACE_THR_SPAWNED))
  268. #endif /* ACE_THREAD_MANAGER_USES_SAFE_SPAWN */
  269. {
  270. this->sync_->release ();
  271. // Release the lock before putting it back to freelist.
  272. }
  273. }
  274. // The following macro simplifies subsequence code.
  275. #define ACE_FIND(OP,INDEX) \
  276. ACE_Thread_Descriptor *INDEX = OP; \
  277. ACE_Thread_Descriptor *
  278. ACE_Thread_Manager::thread_descriptor (ACE_thread_t thr_id)
  279. {
  280. ACE_TRACE ("ACE_Thread_Manager::thread_descriptor");
  281. ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, 0));
  282. ACE_FIND (this->find_thread (thr_id), ptr);
  283. return ptr;
  284. }
  285. ACE_Thread_Descriptor *
  286. ACE_Thread_Manager::hthread_descriptor (ACE_hthread_t thr_handle)
  287. {
  288. ACE_TRACE ("ACE_Thread_Manager::hthread_descriptor");
  289. ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, 0));
  290. ACE_FIND (this->find_hthread (thr_handle), ptr);
  291. return ptr;
  292. }
  293. // Return the thread descriptor (indexed by ACE_hthread_t).
  294. int
  295. ACE_Thread_Manager::thr_self (ACE_hthread_t &self)
  296. {
  297. ACE_TRACE ("ACE_Thread_Manager::thr_self");
  298. ACE_Thread_Descriptor *desc =
  299. this->thread_desc_self ();
  300. if (desc == 0)
  301. return -1;
  302. else
  303. desc->self (self);
  304. return 0;
  305. }
  306. // Initialize the synchronization variables.
  307. ACE_Thread_Manager::ACE_Thread_Manager (size_t prealloc,
  308. size_t lwm,
  309. size_t inc,
  310. size_t hwm)
  311. : grp_id_ (1),
  312. automatic_wait_ (1)
  313. #if defined (ACE_HAS_THREADS)
  314. , zero_cond_ (lock_)
  315. #endif /* ACE_HAS_THREADS */
  316. , thread_desc_freelist_ (ACE_FREE_LIST_WITH_POOL,
  317. prealloc, lwm, hwm, inc)
  318. {
  319. ACE_TRACE ("ACE_Thread_Manager::ACE_Thread_Manager");
  320. }
  321. #if ! defined (ACE_THREAD_MANAGER_LACKS_STATICS)
  322. ACE_Thread_Manager *
  323. ACE_Thread_Manager::instance (void)
  324. {
  325. ACE_TRACE ("ACE_Thread_Manager::instance");
  326. if (ACE_Thread_Manager::thr_mgr_ == 0)
  327. {
  328. // Perform Double-Checked Locking Optimization.
  329. ACE_MT (ACE_GUARD_RETURN (ACE_Recursive_Thread_Mutex, ace_mon,
  330. *ACE_Static_Object_Lock::instance (), 0));
  331. if (ACE_Thread_Manager::thr_mgr_ == 0)
  332. {
  333. ACE_NEW_RETURN (ACE_Thread_Manager::thr_mgr_,
  334. ACE_Thread_Manager,
  335. 0);
  336. ACE_Thread_Manager::delete_thr_mgr_ = true;
  337. }
  338. }
  339. return ACE_Thread_Manager::thr_mgr_;
  340. }
  341. ACE_Thread_Manager *
  342. ACE_Thread_Manager::instance (ACE_Thread_Manager *tm)
  343. {
  344. ACE_TRACE ("ACE_Thread_Manager::instance");
  345. ACE_MT (ACE_GUARD_RETURN (ACE_Recursive_Thread_Mutex, ace_mon,
  346. *ACE_Static_Object_Lock::instance (), 0));
  347. ACE_Thread_Manager *t = ACE_Thread_Manager::thr_mgr_;
  348. // We can't safely delete it since we don't know who created it!
  349. ACE_Thread_Manager::delete_thr_mgr_ = false;
  350. ACE_Thread_Manager::thr_mgr_ = tm;
  351. return t;
  352. }
  353. void
  354. ACE_Thread_Manager::close_singleton (void)
  355. {
  356. ACE_TRACE ("ACE_Thread_Manager::close_singleton");
  357. ACE_MT (ACE_GUARD (ACE_Recursive_Thread_Mutex, ace_mon,
  358. *ACE_Static_Object_Lock::instance ()));
  359. if (ACE_Thread_Manager::delete_thr_mgr_)
  360. {
  361. // First, we clean up the thread descriptor list.
  362. ACE_Thread_Manager::thr_mgr_->close ();
  363. delete ACE_Thread_Manager::thr_mgr_;
  364. ACE_Thread_Manager::thr_mgr_ = 0;
  365. ACE_Thread_Manager::delete_thr_mgr_ = false;
  366. }
  367. ACE_Thread_Exit::cleanup (ACE_Thread_Manager::thr_exit_);
  368. }
  369. #endif /* ! defined (ACE_THREAD_MANAGER_LACKS_STATICS) */
  370. // Close up and release all resources.
  371. int
  372. ACE_Thread_Manager::close ()
  373. {
  374. ACE_TRACE ("ACE_Thread_Manager::close");
  375. // Clean up the thread descriptor list.
  376. if (this->automatic_wait_)
  377. this->wait (0, 1);
  378. else
  379. {
  380. ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1));
  381. this->remove_thr_all ();
  382. }
  383. return 0;
  384. }
  385. ACE_Thread_Manager::~ACE_Thread_Manager (void)
  386. {
  387. ACE_TRACE ("ACE_Thread_Manager::~ACE_Thread_Manager");
  388. this->close ();
  389. }
  390. // Run the entry point for thread spawned under the control of the
  391. // <ACE_Thread_Manager>. This must be an extern "C" to make certain
  392. // compilers happy...
  393. //
  394. // The interaction with <ACE_Thread_Exit> and
  395. // <ace_thread_manager_adapter> works like this, with
  396. // ACE_HAS_THREAD_SPECIFIC_STORAGE or ACE_HAS_TSS_EMULATION:
  397. //
  398. // o Every thread in the <ACE_Thread_Manager> is run with
  399. // <ace_thread_manager_adapter>.
  400. //
  401. // o <ace_thread_manager_adapter> retrieves the singleton
  402. // <ACE_Thread_Exit> instance from <ACE_Thread_Exit::instance>.
  403. // The singleton gets created in thread-specific storage
  404. // in the first call to that function. The key point is that the
  405. // instance is in thread-specific storage.
  406. //
  407. // o A thread can exit by various means, such as <ACE_Thread::exit>, C++
  408. // or Win32 exception, "falling off the end" of the thread entry
  409. // point function, etc.
  410. //
  411. // o If you follow this so far, now it gets really fun . . .
  412. // When the thread-specific storage (for the thread that
  413. // is being destroyed) is cleaned up, the OS threads package (or
  414. // the ACE emulation of thread-specific storage) will destroy any
  415. // objects that are in thread-specific storage. It has a list of
  416. // them, and just walks down the list and destroys each one.
  417. //
  418. // o That's where the ACE_Thread_Exit destructor gets called.
  419. #if defined(ACE_USE_THREAD_MANAGER_ADAPTER)
  420. extern "C" void *
  421. ace_thread_manager_adapter (void *args)
  422. {
  423. #if defined (ACE_HAS_TSS_EMULATION)
  424. // As early as we can in the execution of the new thread, allocate
  425. // its local TS storage. Allocate it on the stack, to save dynamic
  426. // allocation/dealloction.
  427. void *ts_storage[ACE_TSS_Emulation::ACE_TSS_THREAD_KEYS_MAX];
  428. ACE_TSS_Emulation::tss_open (ts_storage);
  429. #endif /* ACE_HAS_TSS_EMULATION */
  430. ACE_Thread_Adapter *thread_args = reinterpret_cast<ACE_Thread_Adapter *> (args);
  431. // NOTE: this preprocessor directive should match the one in above
  432. // ACE_Thread_Exit::instance (). With the Xavier Pthreads package,
  433. // the exit_hook in TSS causes a seg fault. So, this works around
  434. // that by creating exit_hook on the stack.
  435. #if defined (ACE_HAS_THREAD_SPECIFIC_STORAGE) || defined (ACE_HAS_TSS_EMULATION)
  436. // Obtain our thread-specific exit hook and make sure that it knows
  437. // how to clean us up! Note that we never use this pointer directly
  438. // (it's stored in thread-specific storage), so it's ok to
  439. // dereference it here and only store it as a reference.
  440. ACE_Thread_Exit &exit_hook = *ACE_Thread_Exit::instance ();
  441. #else
  442. // Without TSS, create an <ACE_Thread_Exit> instance. When this
  443. // function returns, its destructor will be called because the
  444. // object goes out of scope. The drawback with this appraoch is
  445. // that the destructor _won't_ get called if <thr_exit> is called.
  446. // So, threads shouldn't exit that way. Instead, they should return
  447. // from <svc>.
  448. ACE_Thread_Exit exit_hook;
  449. #endif /* ACE_HAS_THREAD_SPECIFIC_STORAGE || ACE_HAS_TSS_EMULATION */
  450. // Keep track of the <Thread_Manager> that's associated with this
  451. // <exit_hook>.
  452. exit_hook.thr_mgr (thread_args->thr_mgr ());
  453. // Invoke the user-supplied function with the args.
  454. void *status = thread_args->invoke ();
  455. delete static_cast<ACE_Base_Thread_Adapter *> (thread_args);
  456. return status;
  457. }
  458. #endif
  459. // Call the appropriate OS routine to spawn a thread. Should *not* be
  460. // called with the lock_ held...
  461. int
  462. ACE_Thread_Manager::spawn_i (ACE_THR_FUNC func,
  463. void *args,
  464. long flags,
  465. ACE_thread_t *t_id,
  466. ACE_hthread_t *t_handle,
  467. long priority,
  468. int grp_id,
  469. void *stack,
  470. size_t stack_size,
  471. ACE_Task_Base *task,
  472. const char** thr_name)
  473. {
  474. // First, threads created by Thread Manager should not be daemon threads.
  475. // Using assertion is probably a bit too strong. However, it helps
  476. // finding this kind of error as early as possible. Perhaps we can replace
  477. // assertion by returning error.
  478. ACE_ASSERT (ACE_BIT_DISABLED (flags, THR_DAEMON));
  479. // Create a new thread running <func>. *Must* be called with the
  480. // <lock_> held...
  481. // Get a "new" Thread Descriptor from the freelist.
  482. auto_ptr<ACE_Thread_Descriptor> new_thr_desc (this->thread_desc_freelist_.remove ());
  483. // Reset thread descriptor status
  484. new_thr_desc->reset (this);
  485. ACE_Thread_Adapter *thread_args = 0;
  486. # if defined (ACE_HAS_WIN32_STRUCTURAL_EXCEPTIONS)
  487. ACE_NEW_RETURN (thread_args,
  488. ACE_Thread_Adapter (func,
  489. args,
  490. (ACE_THR_C_FUNC) ACE_THREAD_ADAPTER_NAME,
  491. this,
  492. new_thr_desc.get (),
  493. ACE_OS_Object_Manager::seh_except_selector(),
  494. ACE_OS_Object_Manager::seh_except_handler()),
  495. -1);
  496. # else
  497. ACE_NEW_RETURN (thread_args,
  498. ACE_Thread_Adapter (func,
  499. args,
  500. (ACE_THR_C_FUNC) ACE_THREAD_ADAPTER_NAME,
  501. this,
  502. new_thr_desc.get ()),
  503. -1);
  504. # endif /* ACE_HAS_WIN32_STRUCTURAL_EXCEPTIONS */
  505. auto_ptr <ACE_Base_Thread_Adapter> auto_thread_args (static_cast<ACE_Base_Thread_Adapter *> (thread_args));
  506. ACE_TRACE ("ACE_Thread_Manager::spawn_i");
  507. ACE_hthread_t thr_handle;
  508. ACE_thread_t thr_id;
  509. if (t_id == 0)
  510. t_id = &thr_id;
  511. // Acquire the <sync_> lock to block the spawned thread from
  512. // removing this Thread Descriptor before it gets put into our
  513. // thread table.
  514. new_thr_desc->sync_->acquire ();
  515. int const result = ACE_Thread::spawn (func,
  516. args,
  517. flags,
  518. t_id,
  519. &thr_handle,
  520. priority,
  521. stack,
  522. stack_size,
  523. thread_args,
  524. thr_name);
  525. if (result != 0)
  526. {
  527. // _Don't_ clobber errno here! result is either 0 or -1, and
  528. // ACE_OS::thr_create () already set errno! D. Levine 28 Mar 1997
  529. // errno = result;
  530. ACE_Errno_Guard guard (errno); // Lock release may smash errno
  531. new_thr_desc->sync_->release ();
  532. return -1;
  533. }
  534. auto_thread_args.release ();
  535. #if defined (ACE_HAS_WTHREADS)
  536. // Have to duplicate handle if client asks for it.
  537. // @@ How are thread handles implemented on AIX? Do they
  538. // also need to be duplicated?
  539. if (t_handle != 0)
  540. # if defined (ACE_LACKS_DUPLICATEHANDLE)
  541. *t_handle = thr_handle;
  542. # else /* ! ACE_LACKS_DUP */
  543. (void) ::DuplicateHandle (::GetCurrentProcess (),
  544. thr_handle,
  545. ::GetCurrentProcess (),
  546. t_handle,
  547. 0,
  548. TRUE,
  549. DUPLICATE_SAME_ACCESS);
  550. # endif /* ! ACE_LACKS_DUP */
  551. #else /* ! ACE_HAS_WTHREADS */
  552. if (t_handle != 0)
  553. *t_handle = thr_handle;
  554. #endif /* ! ACE_HAS_WTHREADS */
  555. // append_thr also put the <new_thr_desc> into Thread_Manager's
  556. // double-linked list. Only after this point, can we manipulate
  557. // double-linked list from a spawned thread's context.
  558. return this->append_thr (*t_id,
  559. thr_handle,
  560. ACE_THR_SPAWNED,
  561. grp_id,
  562. task,
  563. flags,
  564. new_thr_desc.release ());
  565. }
  566. int
  567. ACE_Thread_Manager::spawn (ACE_THR_FUNC func,
  568. void *args,
  569. long flags,
  570. ACE_thread_t *t_id,
  571. ACE_hthread_t *t_handle,
  572. long priority,
  573. int grp_id,
  574. void *stack,
  575. size_t stack_size,
  576. const char** thr_name)
  577. {
  578. ACE_TRACE ("ACE_Thread_Manager::spawn");
  579. ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1));
  580. if (grp_id == -1)
  581. grp_id = this->grp_id_++; // Increment the group id.
  582. if (priority != ACE_DEFAULT_THREAD_PRIORITY)
  583. ACE_CLR_BITS (flags, THR_INHERIT_SCHED);
  584. if (this->spawn_i (func,
  585. args,
  586. flags,
  587. t_id,
  588. t_handle,
  589. priority,
  590. grp_id,
  591. stack,
  592. stack_size,
  593. 0,
  594. thr_name) == -1)
  595. return -1;
  596. return grp_id;
  597. }
  598. // Create N new threads running FUNC.
  599. int
  600. ACE_Thread_Manager::spawn_n (size_t n,
  601. ACE_THR_FUNC func,
  602. void *args,
  603. long flags,
  604. long priority,
  605. int grp_id,
  606. ACE_Task_Base *task,
  607. ACE_hthread_t thread_handles[],
  608. void *stack[],
  609. size_t stack_size[],
  610. const char* thr_name[])
  611. {
  612. ACE_TRACE ("ACE_Thread_Manager::spawn_n");
  613. ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1));
  614. if (grp_id == -1)
  615. grp_id = this->grp_id_++; // Increment the group id.
  616. for (size_t i = 0; i < n; i++)
  617. {
  618. // @@ What should happen if this fails?! e.g., should we try to
  619. // cancel the other threads that we've already spawned or what?
  620. if (this->spawn_i (func,
  621. args,
  622. flags,
  623. 0,
  624. thread_handles == 0 ? 0 : &thread_handles[i],
  625. priority,
  626. grp_id,
  627. stack == 0 ? 0 : stack[i],
  628. stack_size == 0 ? ACE_DEFAULT_THREAD_STACKSIZE : stack_size[i],
  629. task,
  630. thr_name == 0 ? 0 : &thr_name [i]) == -1)
  631. return -1;
  632. }
  633. return grp_id;
  634. }
  635. // Create N new threads running FUNC.
  636. int
  637. ACE_Thread_Manager::spawn_n (ACE_thread_t thread_ids[],
  638. size_t n,
  639. ACE_THR_FUNC func,
  640. void *args,
  641. long flags,
  642. long priority,
  643. int grp_id,
  644. void *stack[],
  645. size_t stack_size[],
  646. ACE_hthread_t thread_handles[],
  647. ACE_Task_Base *task,
  648. const char* thr_name[])
  649. {
  650. ACE_TRACE ("ACE_Thread_Manager::spawn_n");
  651. ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1));
  652. if (grp_id == -1)
  653. grp_id = this->grp_id_++; // Increment the group id.
  654. for (size_t i = 0; i < n; i++)
  655. {
  656. // @@ What should happen if this fails?! e.g., should we try to
  657. // cancel the other threads that we've already spawned or what?
  658. if (this->spawn_i (func,
  659. args,
  660. flags,
  661. thread_ids == 0 ? 0 : &thread_ids[i],
  662. thread_handles == 0 ? 0 : &thread_handles[i],
  663. priority,
  664. grp_id,
  665. stack == 0 ? 0 : stack[i],
  666. stack_size == 0 ? ACE_DEFAULT_THREAD_STACKSIZE : stack_size[i],
  667. task,
  668. thr_name == 0 ? 0 : &thr_name [i]) == -1)
  669. return -1;
  670. }
  671. return grp_id;
  672. }
  673. // Append a thread into the pool (does not check for duplicates).
  674. // Must be called with locks held.
  675. int
  676. ACE_Thread_Manager::append_thr (ACE_thread_t t_id,
  677. ACE_hthread_t t_handle,
  678. ACE_UINT32 thr_state,
  679. int grp_id,
  680. ACE_Task_Base *task,
  681. long flags,
  682. ACE_Thread_Descriptor *td)
  683. {
  684. ACE_TRACE ("ACE_Thread_Manager::append_thr");
  685. ACE_Thread_Descriptor *thr_desc = 0;
  686. if (td == 0)
  687. {
  688. ACE_NEW_RETURN (thr_desc,
  689. ACE_Thread_Descriptor,
  690. -1);
  691. thr_desc->tm_ = this;
  692. // Setup the Thread_Manager.
  693. }
  694. else
  695. thr_desc = td;
  696. thr_desc->thr_id_ = t_id;
  697. thr_desc->thr_handle_ = t_handle;
  698. thr_desc->grp_id_ = grp_id;
  699. thr_desc->task_ = task;
  700. thr_desc->flags_ = flags;
  701. this->thr_list_.insert_head (thr_desc);
  702. ACE_SET_BITS (thr_desc->thr_state_, thr_state);
  703. thr_desc->sync_->release ();
  704. return 0;
  705. }
  706. // Return the thread descriptor (indexed by ACE_hthread_t).
  707. ACE_Thread_Descriptor *
  708. ACE_Thread_Manager::find_hthread (ACE_hthread_t h_id)
  709. {
  710. for (ACE_Double_Linked_List_Iterator<ACE_Thread_Descriptor> iter (this->thr_list_);
  711. !iter.done ();
  712. iter.advance ())
  713. {
  714. if (ACE_OS::thr_cmp (iter.next ()->thr_handle_, h_id))
  715. {
  716. return iter.next ();
  717. }
  718. }
  719. return 0;
  720. }
  721. // Locate the index in the table associated with <t_id>. Must be
  722. // called with the lock held.
  723. ACE_Thread_Descriptor *
  724. ACE_Thread_Manager::find_thread (ACE_thread_t t_id)
  725. {
  726. ACE_TRACE ("ACE_Thread_Manager::find_thread");
  727. for (ACE_Double_Linked_List_Iterator<ACE_Thread_Descriptor> iter (this->thr_list_);
  728. !iter.done ();
  729. iter.advance ())
  730. {
  731. if (ACE_OS::thr_equal (iter.next ()->thr_id_, t_id))
  732. {
  733. return iter.next ();
  734. }
  735. }
  736. return 0;
  737. }
  738. // Insert a thread into the pool (checks for duplicates and doesn't
  739. // allow them to be inserted twice).
  740. int
  741. ACE_Thread_Manager::insert_thr (ACE_thread_t t_id,
  742. ACE_hthread_t t_handle,
  743. int grp_id,
  744. long flags)
  745. {
  746. ACE_TRACE ("ACE_Thread_Manager::insert_thr");
  747. ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1));
  748. // Check for duplicates and bail out if we're already registered...
  749. if (this->find_thread (t_id) != 0 )
  750. return -1;
  751. if (grp_id == -1)
  752. grp_id = this->grp_id_++;
  753. if (this->append_thr (t_id,
  754. t_handle,
  755. ACE_THR_SPAWNED,
  756. grp_id,
  757. 0,
  758. flags) == -1)
  759. return -1;
  760. return grp_id;
  761. }
  762. // Run the registered hooks when the thread exits.
  763. void
  764. ACE_Thread_Manager::run_thread_exit_hooks (int i)
  765. {
  766. #if 0 // currently unused!
  767. ACE_TRACE ("ACE_Thread_Manager::run_thread_exit_hooks");
  768. // @@ Currently, we have just one hook. This should clearly be
  769. // generalized to support an arbitrary number of hooks.
  770. ACE_Thread_Descriptor *td = this->thread_desc_self ();
  771. for (ACE_Cleanup_Info_Node *iter = td->cleanup_info_->pop_front ();
  772. iter != 0;
  773. iter = cleanup_info_->pop_front ())
  774. {
  775. if (iter->cleanup_hook () != 0)
  776. {
  777. (*iter->cleanup_hook ()) (iter->object (), iter->param ());
  778. }
  779. delete iter;
  780. }
  781. ACE_UNUSED_ARG (i);
  782. #else
  783. ACE_UNUSED_ARG (i);
  784. #endif /* 0 */
  785. }
  786. // Remove a thread from the pool. Must be called with locks held.
  787. void
  788. ACE_Thread_Manager::remove_thr (ACE_Thread_Descriptor *td,
  789. int close_handler)
  790. {
  791. ACE_TRACE ("ACE_Thread_Manager::remove_thr");
  792. td->tm_ = 0;
  793. this->thr_list_.remove (td);
  794. #if defined (ACE_WIN32)
  795. if (close_handler != 0)
  796. ::CloseHandle (td->thr_handle_);
  797. #else
  798. ACE_UNUSED_ARG (close_handler);
  799. #endif /* ACE_WIN32 */
  800. this->thread_desc_freelist_.add (td);
  801. #if defined (ACE_HAS_THREADS)
  802. // Tell all waiters when there are no more threads left in the pool.
  803. if (this->thr_list_.size () == 0)
  804. this->zero_cond_.broadcast ();
  805. #endif /* ACE_HAS_THREADS */
  806. }
  807. // Repeatedly call remove_thr on all table entries until there
  808. // is no thread left. Must be called with lock held.
  809. void
  810. ACE_Thread_Manager::remove_thr_all (void)
  811. {
  812. ACE_Thread_Descriptor *td = 0;
  813. while ((td = this->thr_list_.delete_head ()) != 0)
  814. {
  815. this->remove_thr (td, 1);
  816. }
  817. }
  818. // ------------------------------------------------------------------
  819. // Factor out some common behavior to simplify the following methods.
  820. #define ACE_THR_OP(OP,STATE) \
  821. int result = OP (td->thr_handle_); \
  822. if (result == -1) { \
  823. if (errno != ENOTSUP) \
  824. this->thr_to_be_removed_.enqueue_tail (td); \
  825. return -1; \
  826. } \
  827. else { \
  828. ACE_SET_BITS (td->thr_state_, STATE); \
  829. return 0; \
  830. }
  831. int
  832. ACE_Thread_Manager::join_thr (ACE_Thread_Descriptor *td, int)
  833. {
  834. ACE_TRACE ("ACE_Thread_Manager::join_thr");
  835. int const result = ACE_Thread::join (td->thr_handle_);
  836. if (result != 0)
  837. {
  838. // Since the thread are being joined, we should
  839. // let it remove itself from the list.
  840. // this->remove_thr (td);
  841. errno = result;
  842. return -1;
  843. }
  844. return 0;
  845. }
  846. int
  847. ACE_Thread_Manager::suspend_thr (ACE_Thread_Descriptor *td, int)
  848. {
  849. ACE_TRACE ("ACE_Thread_Manager::suspend_thr");
  850. int const result = ACE_Thread::suspend (td->thr_handle_);
  851. if (result == -1) {
  852. if (errno != ENOTSUP)
  853. this->thr_to_be_removed_.enqueue_tail (td);
  854. return -1;
  855. }
  856. else {
  857. ACE_SET_BITS (td->thr_state_, ACE_THR_SUSPENDED);
  858. return 0;
  859. }
  860. }
  861. int
  862. ACE_Thread_Manager::resume_thr (ACE_Thread_Descriptor *td, int)
  863. {
  864. ACE_TRACE ("ACE_Thread_Manager::resume_thr");
  865. int const result = ACE_Thread::resume (td->thr_handle_);
  866. if (result == -1) {
  867. if (errno != ENOTSUP)
  868. this->thr_to_be_removed_.enqueue_tail (td);
  869. return -1;
  870. }
  871. else {
  872. ACE_CLR_BITS (td->thr_state_, ACE_THR_SUSPENDED);
  873. return 0;
  874. }
  875. }
  876. int
  877. ACE_Thread_Manager::cancel_thr (ACE_Thread_Descriptor *td, int async_cancel)
  878. {
  879. ACE_TRACE ("ACE_Thread_Manager::cancel_thr");
  880. // Must set the state first and then try to cancel the thread.
  881. ACE_SET_BITS (td->thr_state_, ACE_THR_CANCELLED);
  882. if (async_cancel != 0)
  883. // Note that this call only does something relevant if the OS
  884. // platform supports asynchronous thread cancellation. Otherwise,
  885. // it's a no-op.
  886. return ACE_Thread::cancel (td->thr_id_);
  887. return 0;
  888. }
  889. int
  890. ACE_Thread_Manager::kill_thr (ACE_Thread_Descriptor *td, int signum)
  891. {
  892. ACE_TRACE ("ACE_Thread_Manager::kill_thr");
  893. ACE_thread_t tid = td->thr_id_;
  894. int const result = ACE_Thread::kill (tid, signum);
  895. if (result != 0)
  896. {
  897. // Only remove a thread from us when there is a "real" error.
  898. if (errno != ENOTSUP)
  899. this->thr_to_be_removed_.enqueue_tail (td);
  900. return -1;
  901. }
  902. return 0;
  903. }
  904. // ------------------------------------------------------------------
  905. // Factor out some common behavior to simplify the following methods.
  906. #define ACE_EXECUTE_OP(OP, ARG) \
  907. ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1)); \
  908. ACE_ASSERT (this->thr_to_be_removed_.is_empty ()); \
  909. ACE_FIND (this->find_thread (t_id), ptr); \
  910. if (ptr == 0) \
  911. { \
  912. errno = ENOENT; \
  913. return -1; \
  914. } \
  915. int const result = OP (ptr, ARG); \
  916. ACE_Errno_Guard error (errno); \
  917. while (! this->thr_to_be_removed_.is_empty ()) { \
  918. ACE_Thread_Descriptor * td = 0; \
  919. this->thr_to_be_removed_.dequeue_head (td); \
  920. this->remove_thr (td, 1); \
  921. } \
  922. return result
  923. // Suspend a single thread.
  924. int
  925. ACE_Thread_Manager::suspend (ACE_thread_t t_id)
  926. {
  927. ACE_TRACE ("ACE_Thread_Manager::suspend");
  928. ACE_EXECUTE_OP (this->suspend_thr, 0);
  929. }
  930. // Resume a single thread.
  931. int
  932. ACE_Thread_Manager::resume (ACE_thread_t t_id)
  933. {
  934. ACE_TRACE ("ACE_Thread_Manager::resume");
  935. ACE_EXECUTE_OP (this->resume_thr, 0);
  936. }
  937. // Cancel a single thread.
  938. int
  939. ACE_Thread_Manager::cancel (ACE_thread_t t_id, int async_cancel)
  940. {
  941. ACE_TRACE ("ACE_Thread_Manager::cancel");
  942. ACE_EXECUTE_OP (this->cancel_thr, async_cancel);
  943. }
  944. // Send a signal to a single thread.
  945. int
  946. ACE_Thread_Manager::kill (ACE_thread_t t_id, int signum)
  947. {
  948. ACE_TRACE ("ACE_Thread_Manager::kill");
  949. ACE_EXECUTE_OP (this->kill_thr, signum);
  950. }
  951. int
  952. ACE_Thread_Manager::check_state (ACE_UINT32 state,
  953. ACE_thread_t id,
  954. int enable)
  955. {
  956. ACE_TRACE ("ACE_Thread_Manager::check_state");
  957. ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1));
  958. ACE_UINT32 thr_state;
  959. int self_check = ACE_OS::thr_equal (id, ACE_OS::thr_self ());
  960. // If we're checking the state of our thread, try to get the cached
  961. // value out of TSS to avoid lookup.
  962. if (self_check)
  963. {
  964. ACE_Thread_Descriptor *desc = ACE_LOG_MSG->thr_desc ();
  965. if (desc == 0)
  966. return 0; // Always return false.
  967. thr_state = desc->thr_state_;
  968. }
  969. else
  970. {
  971. // Not calling from self, have to look it up from the list.
  972. ACE_FIND (this->find_thread (id), ptr);
  973. if (ptr == 0)
  974. return 0;
  975. thr_state = ptr->thr_state_;
  976. }
  977. if (enable)
  978. return ACE_BIT_ENABLED (thr_state, state);
  979. return ACE_BIT_DISABLED (thr_state, state);
  980. }
  981. // Test if a single thread has terminated.
  982. int
  983. ACE_Thread_Manager::testterminate (ACE_thread_t t_id)
  984. {
  985. ACE_TRACE ("ACE_Thread_Manager::testterminate");
  986. return this->check_state (ACE_THR_TERMINATED, t_id);
  987. }
  988. // Test if a single thread is suspended.
  989. int
  990. ACE_Thread_Manager::testsuspend (ACE_thread_t t_id)
  991. {
  992. ACE_TRACE ("ACE_Thread_Manager::testsuspend");
  993. return this->check_state (ACE_THR_SUSPENDED, t_id);
  994. }
  995. // Test if a single thread is active (i.e., resumed).
  996. int
  997. ACE_Thread_Manager::testresume (ACE_thread_t t_id)
  998. {
  999. ACE_TRACE ("ACE_Thread_Manager::testresume");
  1000. return this->check_state (ACE_THR_SUSPENDED, t_id, 0);
  1001. }
  1002. // Test if a single thread is cancelled.
  1003. int
  1004. ACE_Thread_Manager::testcancel (ACE_thread_t t_id)
  1005. {
  1006. ACE_TRACE ("ACE_Thread_Manager::testcancel");
  1007. return this->check_state (ACE_THR_CANCELLED, t_id);
  1008. }
  1009. // Thread information query functions.
  1010. int
  1011. ACE_Thread_Manager::hthread_within (ACE_hthread_t handle)
  1012. {
  1013. ACE_TRACE ("ACE_Thread_Manager::hthread_within");
  1014. ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_monx, this->lock_, -1));
  1015. for (ACE_Double_Linked_List_Iterator<ACE_Thread_Descriptor> iter (this->thr_list_);
  1016. !iter.done ();
  1017. iter.advance ())
  1018. {
  1019. if (ACE_OS::thr_cmp(iter.next ()->thr_handle_, handle))
  1020. {
  1021. return 1;
  1022. }
  1023. }
  1024. return 0;
  1025. }
  1026. int
  1027. ACE_Thread_Manager::thread_within (ACE_thread_t tid)
  1028. {
  1029. ACE_TRACE ("ACE_Thread_Manager::thread_within");
  1030. ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_monx, this->lock_, -1));
  1031. for (ACE_Double_Linked_List_Iterator<ACE_Thread_Descriptor> iter (this->thr_list_);
  1032. !iter.done ();
  1033. iter.advance ())
  1034. {
  1035. if (ACE_OS::thr_equal (iter.next ()->thr_id_, tid))
  1036. {
  1037. return 1;
  1038. }
  1039. }
  1040. return 0;
  1041. }
  1042. // Get group ids for a particular thread id.
  1043. int
  1044. ACE_Thread_Manager::get_grp (ACE_thread_t t_id, int &grp_id)
  1045. {
  1046. ACE_TRACE ("ACE_Thread_Manager::get_grp");
  1047. ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1));
  1048. ACE_FIND (this->find_thread (t_id), ptr);
  1049. if (ptr)
  1050. grp_id = ptr->grp_id_;
  1051. else
  1052. return -1;
  1053. return 0;
  1054. }
  1055. // Set group ids for a particular thread id.
  1056. int
  1057. ACE_Thread_Manager::set_grp (ACE_thread_t t_id, int grp_id)
  1058. {
  1059. ACE_TRACE ("ACE_Thread_Manager::set_grp");
  1060. ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1));
  1061. ACE_FIND (this->find_thread (t_id), ptr);
  1062. if (ptr)
  1063. ptr->grp_id_ = grp_id;
  1064. else
  1065. return -1;
  1066. return 0;
  1067. }
  1068. // Suspend a group of threads.
  1069. int
  1070. ACE_Thread_Manager::apply_grp (int grp_id,
  1071. ACE_THR_MEMBER_FUNC func,
  1072. int arg)
  1073. {
  1074. ACE_TRACE ("ACE_Thread_Manager::apply_grp");
  1075. ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_monx, this->lock_, -1));
  1076. ACE_ASSERT (this->thr_to_be_removed_.is_empty ());
  1077. int result = 0;
  1078. for (ACE_Double_Linked_List_Iterator<ACE_Thread_Descriptor> iter (this->thr_list_);
  1079. !iter.done ();
  1080. iter.advance ())
  1081. {
  1082. if (iter.next ()->grp_id_ == grp_id)
  1083. {
  1084. if ((this->*func) (iter.next (), arg) == -1)
  1085. {
  1086. result = -1;
  1087. }
  1088. }
  1089. }
  1090. // Must remove threads after we have traversed the thr_list_ to
  1091. // prevent clobber thr_list_'s integrity.
  1092. if (! this->thr_to_be_removed_.is_empty ())
  1093. {
  1094. // Save/restore errno.
  1095. ACE_Errno_Guard error (errno);
  1096. for (ACE_Thread_Descriptor *td;
  1097. this->thr_to_be_removed_.dequeue_head (td) != -1;
  1098. )
  1099. this->remove_thr (td, 1);
  1100. }
  1101. return result;
  1102. }
  1103. int
  1104. ACE_Thread_Manager::suspend_grp (int grp_id)
  1105. {
  1106. ACE_TRACE ("ACE_Thread_Manager::suspend_grp");
  1107. return this->apply_grp (grp_id,
  1108. ACE_THR_MEMBER_FUNC (&ACE_Thread_Manager::suspend_thr));
  1109. }
  1110. // Resume a group of threads.
  1111. int
  1112. ACE_Thread_Manager::resume_grp (int grp_id)
  1113. {
  1114. ACE_TRACE ("ACE_Thread_Manager::resume_grp");
  1115. return this->apply_grp (grp_id,
  1116. ACE_THR_MEMBER_FUNC (&ACE_Thread_Manager::resume_thr));
  1117. }
  1118. // Kill a group of threads.
  1119. int
  1120. ACE_Thread_Manager::kill_grp (int grp_id, int signum)
  1121. {
  1122. ACE_TRACE ("ACE_Thread_Manager::kill_grp");
  1123. return this->apply_grp (grp_id,
  1124. ACE_THR_MEMBER_FUNC (&ACE_Thread_Manager::kill_thr), signum);
  1125. }
  1126. // Cancel a group of threads.
  1127. int
  1128. ACE_Thread_Manager::cancel_grp (int grp_id, int async_cancel)
  1129. {
  1130. ACE_TRACE ("ACE_Thread_Manager::cancel_grp");
  1131. return this->apply_grp (grp_id,
  1132. ACE_THR_MEMBER_FUNC (&ACE_Thread_Manager::cancel_thr),
  1133. async_cancel);
  1134. }
  1135. int
  1136. ACE_Thread_Manager::apply_all (ACE_THR_MEMBER_FUNC func, int arg)
  1137. {
  1138. ACE_TRACE ("ACE_Thread_Manager::apply_all");
  1139. ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1));
  1140. ACE_ASSERT (this->thr_to_be_removed_.is_empty ());
  1141. int result = 0;
  1142. for (ACE_Double_Linked_List_Iterator<ACE_Thread_Descriptor> iter (this->thr_list_);
  1143. !iter.done ();
  1144. iter.advance ())
  1145. {
  1146. if ((this->*func)(iter.next (), arg) == -1)
  1147. {
  1148. result = -1;
  1149. }
  1150. }
  1151. // Must remove threads after we have traversed the thr_list_ to
  1152. // prevent clobber thr_list_'s integrity.
  1153. if (! this->thr_to_be_removed_.is_empty ())
  1154. {
  1155. // Save/restore errno.
  1156. ACE_Errno_Guard error (errno);
  1157. for (ACE_Thread_Descriptor *td;
  1158. this->thr_to_be_removed_.dequeue_head (td) != -1;
  1159. )
  1160. this->remove_thr (td, 1);
  1161. }
  1162. return result;
  1163. }
  1164. // Resume all threads that are suspended.
  1165. int
  1166. ACE_Thread_Manager::resume_all (void)
  1167. {
  1168. ACE_TRACE ("ACE_Thread_Manager::resume_all");
  1169. return this->apply_all (ACE_THR_MEMBER_FUNC (&ACE_Thread_Manager::resume_thr));
  1170. }
  1171. int
  1172. ACE_Thread_Manager::suspend_all (void)
  1173. {
  1174. ACE_TRACE ("ACE_Thread_Manager::suspend_all");
  1175. return this->apply_all (ACE_THR_MEMBER_FUNC (&ACE_Thread_Manager::suspend_thr));
  1176. }
  1177. int
  1178. ACE_Thread_Manager::kill_all (int sig)
  1179. {
  1180. ACE_TRACE ("ACE_Thread_Manager::kill_all");
  1181. return this->apply_all (&ACE_Thread_Manager::kill_thr, sig);
  1182. }
  1183. int
  1184. ACE_Thread_Manager::cancel_all (int async_cancel)
  1185. {
  1186. ACE_TRACE ("ACE_Thread_Manager::cancel_all");
  1187. return this->apply_all (ACE_THR_MEMBER_FUNC (&ACE_Thread_Manager::cancel_thr),
  1188. async_cancel);
  1189. }
  1190. int
  1191. ACE_Thread_Manager::join (ACE_thread_t tid, ACE_THR_FUNC_RETURN *status)
  1192. {
  1193. ACE_TRACE ("ACE_Thread_Manager::join");
  1194. bool found = false;
  1195. ACE_Thread_Descriptor_Base tdb;
  1196. {
  1197. ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1));
  1198. #if !defined (ACE_HAS_VXTHREADS)
  1199. for (ACE_Double_Linked_List_Iterator<ACE_Thread_Descriptor_Base> biter (this->terminated_thr_list_);
  1200. !biter.done ();
  1201. biter.advance ())
  1202. {
  1203. if (ACE_OS::thr_equal (biter.next ()->thr_id_, tid))
  1204. {
  1205. ACE_Thread_Descriptor_Base *tdb = biter.advance_and_remove (false);
  1206. if (ACE_Thread::join (tdb->thr_handle_, status) == -1)
  1207. {
  1208. return -1;
  1209. }
  1210. delete tdb;
  1211. // return immediately if we've found the thread we want to join.
  1212. return 0;
  1213. }
  1214. }
  1215. #endif /* !ACE_HAS_VXTHREADS */
  1216. for (ACE_Double_Linked_List_Iterator<ACE_Thread_Descriptor> iter (this->thr_list_);
  1217. !iter.done ();
  1218. iter.advance ())
  1219. {
  1220. // If threads are created as THR_DETACHED or THR_DAEMON, we
  1221. // can't help much.
  1222. if (ACE_OS::thr_equal (iter.next ()->thr_id_,tid) &&
  1223. (ACE_BIT_DISABLED (iter.next ()->flags_, THR_DETACHED | THR_DAEMON)
  1224. || ACE_BIT_ENABLED (iter.next ()->flags_, THR_JOINABLE)))
  1225. {
  1226. tdb = *iter.next ();
  1227. ACE_SET_BITS (iter.next ()->thr_state_, ACE_THR_JOINING);
  1228. found = 1;
  1229. break;
  1230. }
  1231. }
  1232. if (!found)
  1233. return -1;
  1234. // Didn't find the thread we want or the thread is not joinable.
  1235. }
  1236. if (ACE_Thread::join (tdb.thr_handle_, status) == -1)
  1237. return -1;
  1238. return 0;
  1239. }
  1240. // Wait for group of threads
  1241. int
  1242. ACE_Thread_Manager::wait_grp (int grp_id)
  1243. {
  1244. ACE_TRACE ("ACE_Thread_Manager::wait_grp");
  1245. int copy_count = 0;
  1246. ACE_Thread_Descriptor_Base *copy_table = 0;
  1247. // We have to make sure that while we wait for these threads to
  1248. // exit, we do not have the lock. Therefore we make a copy of all
  1249. // interesting entries and let go of the lock.
  1250. {
  1251. ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1));
  1252. #if !defined (ACE_HAS_VXTHREADS)
  1253. ACE_NEW_RETURN (copy_table,
  1254. ACE_Thread_Descriptor_Base [this->thr_list_.size ()
  1255. + this->terminated_thr_list_.size ()],
  1256. -1);
  1257. #else
  1258. ACE_NEW_RETURN (copy_table,
  1259. ACE_Thread_Descriptor_Base [this->thr_list_.size ()],
  1260. -1);
  1261. #endif /* !ACE_HAS_VXTHREADS */
  1262. for (ACE_Double_Linked_List_Iterator<ACE_Thread_Descriptor> iter (this->thr_list_);
  1263. !iter.done ();
  1264. iter.advance ())
  1265. {
  1266. // If threads are created as THR_DETACHED or THR_DAEMON, we
  1267. // can't help much.
  1268. if (iter.next ()->grp_id_ == grp_id &&
  1269. (ACE_BIT_DISABLED (iter.next ()->flags_, THR_DETACHED | THR_DAEMON)
  1270. || ACE_BIT_ENABLED (iter.next ()->flags_, THR_JOINABLE)))
  1271. {
  1272. ACE_SET_BITS (iter.next ()->thr_state_, ACE_THR_JOINING);
  1273. copy_table[copy_count++] = *iter.next ();
  1274. }
  1275. }
  1276. #if !defined (ACE_HAS_VXTHREADS)
  1277. for (ACE_Double_Linked_List_Iterator<ACE_Thread_Descriptor_Base> biter (this->terminated_thr_list_);
  1278. !biter.done ();
  1279. biter.advance ())
  1280. {
  1281. // If threads are created as THR_DETACHED or THR_DAEMON, we
  1282. // can't help much.
  1283. if (biter.next ()->grp_id_ == grp_id)
  1284. {
  1285. ACE_Thread_Descriptor_Base *tdb = biter.advance_and_remove (false);
  1286. copy_table[copy_count++] = *tdb;
  1287. delete tdb;
  1288. }
  1289. }
  1290. #endif /* !ACE_HAS_VXTHREADS */
  1291. }
  1292. // Now actually join() with all the threads in this group.
  1293. int result = 0;
  1294. for (int i = 0;
  1295. i < copy_count && result != -1;
  1296. i++)
  1297. {
  1298. if (ACE_Thread::join (copy_table[i].thr_handle_) == -1)
  1299. result = -1;
  1300. }
  1301. delete [] copy_table;
  1302. return result;
  1303. }
  1304. // Must be called when thread goes out of scope to clean up its table
  1305. // slot.
  1306. ACE_THR_FUNC_RETURN
  1307. ACE_Thread_Manager::exit (ACE_THR_FUNC_RETURN status, bool do_thread_exit)
  1308. {
  1309. ACE_TRACE ("ACE_Thread_Manager::exit");
  1310. #if defined (ACE_WIN32)
  1311. // Remove detached thread handle.
  1312. if (do_thread_exit)
  1313. {
  1314. #if 0
  1315. // @@ This callback is now taken care of by TSS_Cleanup. Do we
  1316. // need it anymore?
  1317. // On Win32, if we really wants to exit from a thread, we must
  1318. // first clean up the thread specific storage. By doing so,
  1319. // ACE_Thread_Manager::exit will be called again with
  1320. // do_thr_exit = 0 and cleaning up the ACE_Cleanup_Info (but not
  1321. // exiting the thread.) After the following call returns, we
  1322. // are safe to exit this thread.
  1323. delete ACE_Thread_Exit::instance ();
  1324. #endif /* 0 */
  1325. ACE_Thread::exit (status);
  1326. }
  1327. #endif /* ACE_WIN32 */
  1328. // Just hold onto the guard while finding this thread's id and
  1329. {
  1330. ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, 0));
  1331. // Find the thread id, but don't use the cache. It might have been
  1332. // deleted already.
  1333. ACE_thread_t const id = ACE_OS::thr_self ();
  1334. ACE_Thread_Descriptor* td = this->find_thread (id);
  1335. if (td != 0)
  1336. {
  1337. // @@ We call Thread_Descriptor terminate this realize the cleanup
  1338. // process itself.
  1339. td->terminate();
  1340. }
  1341. }
  1342. if (do_thread_exit)
  1343. {
  1344. ACE_Thread::exit (status);
  1345. // On reasonable systems <ACE_Thread::exit> should not return.
  1346. // However, due to horrible semantics with Win32 thread-specific
  1347. // storage this call can return (don't ask...).
  1348. }
  1349. return 0;
  1350. }
  1351. // Wait for all the threads to exit.
  1352. int
  1353. ACE_Thread_Manager::wait (const ACE_Time_Value *timeout,
  1354. bool abandon_detached_threads,
  1355. bool use_absolute_time)
  1356. {
  1357. ACE_TRACE ("ACE_Thread_Manager::wait");
  1358. ACE_Time_Value local_timeout;
  1359. // Check to see if we're using absolute time or not.
  1360. if (use_absolute_time == false && timeout != 0)
  1361. {
  1362. local_timeout = *timeout;
  1363. local_timeout += ACE_OS::gettimeofday ();
  1364. timeout = &local_timeout;
  1365. }
  1366. #if !defined (ACE_HAS_VXTHREADS)
  1367. ACE_Double_Linked_List<ACE_Thread_Descriptor_Base> term_thr_list_copy;
  1368. #endif /* ACE_HAS_VXTHREADS */
  1369. #if defined (ACE_HAS_THREADS)
  1370. {
  1371. // Just hold onto the guard while waiting.
  1372. ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1));
  1373. if (ACE_Object_Manager::shutting_down () != 1)
  1374. {
  1375. // Program is not shutting down. Perform a normal wait on threads.
  1376. if (abandon_detached_threads != 0)
  1377. {
  1378. ACE_ASSERT (this->thr_to_be_removed_.is_empty ());
  1379. for (ACE_Double_Linked_List_Iterator<ACE_Thread_Descriptor>
  1380. iter (this->thr_list_);
  1381. !iter.done ();
  1382. iter.advance ())
  1383. {
  1384. if (ACE_BIT_ENABLED (iter.next ()->flags_,
  1385. THR_DETACHED | THR_DAEMON)
  1386. && ACE_BIT_DISABLED (iter.next ()->flags_, THR_JOINABLE))
  1387. {
  1388. this->thr_to_be_removed_.enqueue_tail (iter.next ());
  1389. ACE_SET_BITS (iter.next ()->thr_state_, ACE_THR_JOINING);
  1390. }
  1391. }
  1392. if (! this->thr_to_be_removed_.is_empty ())
  1393. {
  1394. ACE_Thread_Descriptor *td = 0;
  1395. while (this->thr_to_be_removed_.dequeue_head (td) != -1)
  1396. this->remove_thr (td, 1);
  1397. }
  1398. }
  1399. while (this->thr_list_.size () > 0)
  1400. if (this->zero_cond_.wait (timeout) == -1)
  1401. return -1;
  1402. }
  1403. else
  1404. // Program is shutting down, no chance to wait on threads.
  1405. // Therefore, we'll just remove threads from the list.
  1406. this->remove_thr_all ();
  1407. #if !defined (ACE_HAS_VXTHREADS)
  1408. ACE_Thread_Descriptor_Base* item = 0;
  1409. while ((item = this->terminated_thr_list_.delete_head ()) != 0)
  1410. {
  1411. term_thr_list_copy.insert_tail (item);
  1412. }
  1413. #endif /* ACE_HAS_VXTHREADS */
  1414. // Release the guard, giving other threads a chance to run.
  1415. }
  1416. #if !defined (ACE_HAS_VXTHREADS)
  1417. // @@ VxWorks doesn't support thr_join (yet.) We are working
  1418. // on our implementation. Chorus'es thr_join seems broken.
  1419. ACE_Thread_Descriptor_Base *item = 0;
  1420. while ((item = term_thr_list_copy.delete_head ()) != 0)
  1421. {
  1422. if (ACE_BIT_DISABLED (item->flags_, THR_DETACHED | THR_DAEMON)
  1423. || ACE_BIT_ENABLED (item->flags_, THR_JOINABLE))
  1424. // Detached handles shouldn't reached here.
  1425. (void) ACE_Thread::join (item->thr_handle_);
  1426. delete item;
  1427. }
  1428. #endif /* !ACE_HAS_VXTHREADS */
  1429. #else
  1430. ACE_UNUSED_ARG (timeout);
  1431. ACE_UNUSED_ARG (abandon_detached_threads);
  1432. #endif /* ACE_HAS_THREADS */
  1433. return 0;
  1434. }
  1435. int
  1436. ACE_Thread_Manager::apply_task (ACE_Task_Base *task,
  1437. ACE_THR_MEMBER_FUNC func,
  1438. int arg)
  1439. {
  1440. ACE_TRACE ("ACE_Thread_Manager::apply_task");
  1441. ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1));
  1442. ACE_ASSERT (this->thr_to_be_removed_.is_empty ());
  1443. int result = 0;
  1444. for (ACE_Double_Linked_List_Iterator<ACE_Thread_Descriptor> iter (this->thr_list_);
  1445. !iter.done ();
  1446. iter.advance ())
  1447. if (iter.next ()->task_ == task
  1448. && (this->*func) (iter.next (), arg) == -1)
  1449. result = -1;
  1450. // Must remove threads after we have traversed the thr_list_ to
  1451. // prevent clobber thr_list_'s integrity.
  1452. if (! this->thr_to_be_removed_.is_empty ())
  1453. {
  1454. // Save/restore errno.
  1455. ACE_Errn