PageRenderTime 44ms CodeModel.GetById 12ms RepoModel.GetById 0ms app.codeStats 0ms

/dep/acelite/ace/Svc_Handler.cpp

https://github.com/chucho/FaceCore
C++ | 529 lines | 389 code | 88 blank | 52 comment | 47 complexity | 122d62b4bec412a472f7a5392b9ac05c MD5 | raw file
  1. // $Id: Svc_Handler.cpp 89432 2010-03-10 10:34:51Z vzykov $
  2. #ifndef ACE_SVC_HANDLER_CPP
  3. #define ACE_SVC_HANDLER_CPP
  4. #include "ace/Svc_Handler.h"
  5. #if !defined (ACE_LACKS_PRAGMA_ONCE)
  6. # pragma once
  7. #endif /* ACE_LACKS_PRAGMA_ONCE */
  8. #include "ace/OS_NS_sys_time.h"
  9. #include "ace/Object_Manager.h"
  10. #include "ace/Connection_Recycling_Strategy.h"
  11. #include "ace/Dynamic.h"
  12. #define PR_ST_1 ACE_PEER_STREAM_1
  13. #define PR_ST_2 ACE_PEER_STREAM_2
  14. ACE_BEGIN_VERSIONED_NAMESPACE_DECL
  15. template <PR_ST_1, ACE_SYNCH_DECL> void *
  16. ACE_Svc_Handler<PR_ST_2, ACE_SYNCH_USE>::operator new (size_t, void *p)
  17. {
  18. ACE_TRACE ("ACE_Svc_Handler<PR_ST_2, ACE_SYNCH_USE>::operator new (NOOP, 2 parameters)");
  19. return p;
  20. }
  21. #if !defined (ACE_LACKS_PLACEMENT_OPERATOR_DELETE)
  22. template <PR_ST_1, ACE_SYNCH_DECL> void
  23. ACE_Svc_Handler<PR_ST_2, ACE_SYNCH_USE>::operator delete (void *, void *)
  24. {
  25. ACE_TRACE ("ACE_Svc_Handler<PR_ST_2, ACE_SYNCH_USE>::operator delete (NOOP, 2 parameters)");
  26. return;
  27. }
  28. #endif /* ACE_LACKS_PLACEMENT_OPERATOR_DELETE */
  29. template <PR_ST_1, ACE_SYNCH_DECL> void *
  30. ACE_Svc_Handler<PR_ST_2, ACE_SYNCH_USE>::operator new (size_t n)
  31. {
  32. ACE_TRACE ("ACE_Svc_Handler<PR_ST_2, ACE_SYNCH_USE>::operator new");
  33. ACE_Dynamic *const dynamic_instance = ACE_Dynamic::instance ();
  34. if (dynamic_instance == 0)
  35. {
  36. // If this ACE_ASSERT fails, it may be due to running of out TSS
  37. // keys. Try using ACE_HAS_TSS_EMULATION, or increasing
  38. // ACE_DEFAULT_THREAD_KEYS if already using TSS emulation.
  39. ACE_ASSERT (dynamic_instance != 0);
  40. ACE_throw_bad_alloc;
  41. }
  42. else
  43. {
  44. // Allocate the memory and store it (usually in thread-specific
  45. // storage, depending on config flags).
  46. dynamic_instance->set ();
  47. return ::new char[n];
  48. }
  49. }
  50. #if defined (ACE_HAS_NEW_NOTHROW)
  51. template <PR_ST_1, ACE_SYNCH_DECL> void *
  52. ACE_Svc_Handler<PR_ST_2, ACE_SYNCH_USE>::operator new (size_t n,
  53. const ACE_nothrow_t&) throw()
  54. {
  55. ACE_TRACE ("ACE_Svc_Handler<PR_ST_2, ACE_SYNCH_USE>::operator new(nothrow)");
  56. ACE_Dynamic *const dynamic_instance = ACE_Dynamic::instance ();
  57. if (dynamic_instance == 0)
  58. {
  59. // If this ACE_ASSERT fails, it may be due to running of out TSS
  60. // keys. Try using ACE_HAS_TSS_EMULATION, or increasing
  61. // ACE_DEFAULT_THREAD_KEYS if already using TSS emulation.
  62. ACE_ASSERT (dynamic_instance != 0);
  63. return 0;
  64. }
  65. else
  66. {
  67. // Allocate the memory and store it (usually in thread-specific
  68. // storage, depending on config flags).
  69. dynamic_instance->set ();
  70. return ::new(ACE_nothrow) char[n];
  71. }
  72. }
  73. #if !defined (ACE_LACKS_PLACEMENT_OPERATOR_DELETE)
  74. template <PR_ST_1, ACE_SYNCH_DECL> void
  75. ACE_Svc_Handler<PR_ST_2, ACE_SYNCH_USE>::operator delete (void *p,
  76. const ACE_nothrow_t&) throw()
  77. {
  78. ACE_TRACE
  79. ("ACE_Svc_Handler<PR_ST_2, ACE_SYNCH_USE>::operator delete(nothrow)");
  80. ::delete [] static_cast <char *> (p);
  81. }
  82. #endif /* ACE_LACKS_PLACEMENT_OPERATOR_DELETE */
  83. #endif /* ACE_HAS_NEW_NOTHROW */
  84. template <PR_ST_1, ACE_SYNCH_DECL> void
  85. ACE_Svc_Handler<PR_ST_2, ACE_SYNCH_USE>::destroy (void)
  86. {
  87. ACE_TRACE ("ACE_Svc_Handler<PR_ST_2, ACE_SYNCH_USE>::destroy");
  88. // Only delete ourselves if we're not owned by a module and have
  89. // been allocated dynamically.
  90. if (this->mod_ == 0 && this->dynamic_ && this->closing_ == false)
  91. // Will call the destructor, which automatically calls <shutdown>.
  92. // Note that if we are *not* allocated dynamically then the
  93. // destructor will call <shutdown> automatically when it gets run
  94. // during cleanup.
  95. delete this;
  96. }
  97. template <PR_ST_1, ACE_SYNCH_DECL> void
  98. ACE_Svc_Handler<PR_ST_2, ACE_SYNCH_USE>::operator delete (void *obj)
  99. {
  100. ACE_TRACE ("ACE_Svc_Handler<PR_ST_2, ACE_SYNCH_USE>::operator delete");
  101. // You cannot delete a 'void*' (X3J16/95-0087 5.3.5.3), but we know
  102. // the pointer was created using new char[] (see operator new code),
  103. // so we use a cast:
  104. ::delete [] static_cast <char *> (obj);
  105. }
  106. // Default constructor.
  107. template <PR_ST_1, ACE_SYNCH_DECL>
  108. ACE_Svc_Handler<PR_ST_2, ACE_SYNCH_USE>::ACE_Svc_Handler (ACE_Thread_Manager *tm,
  109. ACE_Message_Queue<ACE_SYNCH_USE> *mq,
  110. ACE_Reactor *reactor)
  111. : ACE_Task<ACE_SYNCH_USE> (tm, mq),
  112. closing_ (false),
  113. recycler_ (0),
  114. recycling_act_ (0)
  115. {
  116. ACE_TRACE ("ACE_Svc_Handler<PR_ST_2, ACE_SYNCH_USE>::ACE_Svc_Handler");
  117. this->reactor (reactor);
  118. // This clever idiom transparently checks if we were allocated
  119. // dynamically. This information is used by the <destroy> method to
  120. // decide if we need to delete <this>... The idiom is based on a
  121. // paper by Michael van Rooyen (mrooyen@cellnet.co.uk) that appeared
  122. // in the April '96 issue of the C++ Report. We've spruced it up to
  123. // work correctly in multi-threaded programs by using our ACE_TSS
  124. // class.
  125. this->dynamic_ = ACE_Dynamic::instance ()->is_dynamic ();
  126. if (this->dynamic_)
  127. // Make sure to reset the flag.
  128. ACE_Dynamic::instance ()->reset ();
  129. }
  130. // Default behavior for a ACE_Svc_Handler object is to be registered
  131. // with the ACE_Reactor (thereby ensuring single threading).
  132. template <PR_ST_1, ACE_SYNCH_DECL> int
  133. ACE_Svc_Handler<PR_ST_2, ACE_SYNCH_USE>::open (void *)
  134. {
  135. ACE_TRACE ("ACE_Svc_Handler<PR_ST_2, ACE_SYNCH_USE>::open");
  136. #if defined (ACE_DEBUGGING)
  137. ACE_TCHAR buf[BUFSIZ];
  138. ACE_PEER_STREAM_ADDR client_addr;
  139. if (this->peer_.get_remote_addr (client_addr) == -1)
  140. ACE_ERROR_RETURN ((LM_ERROR,
  141. ACE_TEXT ("%p\n"),
  142. ACE_TEXT ("get_remote_addr")),
  143. -1);
  144. else if (client_addr.addr_to_string (buf, sizeof buf) == -1)
  145. ACE_ERROR_RETURN ((LM_ERROR,
  146. ACE_TEXT ("%p\n"),
  147. ACE_TEXT ("can't obtain peer's address")),
  148. -1);
  149. ACE_DEBUG ((LM_DEBUG,
  150. ACE_TEXT ("connected to %s on fd %d\n"),
  151. buf,
  152. this->peer_.get_handle ()));
  153. #endif /* ACE_DEBUGGING */
  154. if (this->reactor ()
  155. && this->reactor ()->register_handler
  156. (this,
  157. ACE_Event_Handler::READ_MASK) == -1)
  158. ACE_ERROR_RETURN ((LM_ERROR,
  159. ACE_TEXT ("%p\n"),
  160. ACE_TEXT ("unable to register client handler")),
  161. -1);
  162. return 0;
  163. }
  164. // Perform termination activities.
  165. template <PR_ST_1, ACE_SYNCH_DECL> void
  166. ACE_Svc_Handler<PR_ST_2, ACE_SYNCH_USE>::shutdown (void)
  167. {
  168. ACE_TRACE ("ACE_Svc_Handler<PR_ST_2, ACE_SYNCH_USE>::shutdown");
  169. // Deregister this handler with the ACE_Reactor.
  170. if (this->reactor ())
  171. {
  172. ACE_Reactor_Mask mask = ACE_Event_Handler::ALL_EVENTS_MASK |
  173. ACE_Event_Handler::DONT_CALL;
  174. // Make sure there are no timers.
  175. this->reactor ()->cancel_timer (this);
  176. if (this->peer ().get_handle () != ACE_INVALID_HANDLE)
  177. // Remove self from reactor.
  178. this->reactor ()->remove_handler (this, mask);
  179. }
  180. // Remove self from the recycler.
  181. if (this->recycler ())
  182. this->recycler ()->purge (this->recycling_act_);
  183. this->peer ().close ();
  184. }
  185. template <PR_ST_1, ACE_SYNCH_DECL> void
  186. ACE_Svc_Handler<PR_ST_2, ACE_SYNCH_USE>::cleanup_hint (void **act_holder)
  187. {
  188. ACE_TRACE ("ACE_Svc_Handler<PR_ST_2, ACE_SYNCH_USE>::cleanup_hint");
  189. // Remove as hint.
  190. if (this->recycler ())
  191. this->recycler ()->cleanup_hint (this->recycling_act_,
  192. act_holder);
  193. }
  194. template <PR_ST_1, ACE_SYNCH_DECL> void
  195. ACE_Svc_Handler<PR_ST_2, ACE_SYNCH_USE>::dump (void) const
  196. {
  197. #if defined (ACE_HAS_DUMP)
  198. ACE_TRACE ("ACE_Svc_Handler<PR_ST_2, ACE_SYNCH_USE>::dump");
  199. this->peer_.dump ();
  200. ACE_DEBUG ((LM_DEBUG,
  201. "dynamic_ = %d\n",
  202. this->dynamic_));
  203. ACE_DEBUG ((LM_DEBUG,
  204. "closing_ = %d\n",
  205. this->closing_));
  206. ACE_DEBUG ((LM_DEBUG,
  207. "recycler_ = %d\n",
  208. this->recycler_));
  209. ACE_DEBUG ((LM_DEBUG,
  210. "recycling_act_ = %d\n",
  211. this->recycling_act_));
  212. #endif /* ACE_HAS_DUMP */
  213. }
  214. template <PR_ST_1, ACE_SYNCH_DECL> ACE_PEER_STREAM &
  215. ACE_Svc_Handler<PR_ST_2, ACE_SYNCH_USE>::peer (void) const
  216. {
  217. ACE_TRACE ("ACE_Svc_Handler<PR_ST_2, ACE_SYNCH_USE>::peer");
  218. return (ACE_PEER_STREAM &) this->peer_;
  219. }
  220. // Extract the underlying I/O descriptor.
  221. template <PR_ST_1, ACE_SYNCH_DECL> ACE_HANDLE
  222. ACE_Svc_Handler<PR_ST_2, ACE_SYNCH_USE>::get_handle (void) const
  223. {
  224. ACE_TRACE ("ACE_Svc_Handler<PR_ST_2, ACE_SYNCH_USE>::get_handle");
  225. return this->peer_.get_handle ();
  226. }
  227. // Set the underlying I/O descriptor.
  228. template <PR_ST_1, ACE_SYNCH_DECL> void
  229. ACE_Svc_Handler<PR_ST_2, ACE_SYNCH_USE>::set_handle (ACE_HANDLE h)
  230. {
  231. ACE_TRACE ("ACE_Svc_Handler<PR_ST_2, ACE_SYNCH_USE>::set_handle");
  232. this->peer_.set_handle (h);
  233. }
  234. template <PR_ST_1, ACE_SYNCH_DECL>
  235. ACE_Svc_Handler<PR_ST_2, ACE_SYNCH_USE>::~ACE_Svc_Handler (void)
  236. {
  237. ACE_TRACE ("ACE_Svc_Handler<PR_ST_2, ACE_SYNCH_USE>::~ACE_Svc_Handler");
  238. if (this->closing_ == false)
  239. {
  240. // We're closing down now, so make sure not to call ourselves
  241. // recursively via other calls to handle_close() (e.g., from the
  242. // Timer_Queue).
  243. this->closing_ = true;
  244. this->shutdown ();
  245. }
  246. }
  247. template <PR_ST_1, ACE_SYNCH_DECL> int
  248. ACE_Svc_Handler<PR_ST_2, ACE_SYNCH_USE>::handle_close (ACE_HANDLE,
  249. ACE_Reactor_Mask)
  250. {
  251. ACE_TRACE ("ACE_Svc_Handler<PR_ST_2, ACE_SYNCH_USE>::handle_close");
  252. if (this->reference_counting_policy ().value () ==
  253. ACE_Event_Handler::Reference_Counting_Policy::DISABLED)
  254. {
  255. this->destroy ();
  256. }
  257. return 0;
  258. }
  259. template <PR_ST_1, ACE_SYNCH_DECL> int
  260. ACE_Svc_Handler<PR_ST_2, ACE_SYNCH_USE>::handle_timeout (const ACE_Time_Value &,
  261. const void *)
  262. {
  263. ACE_TRACE ("ACE_Svc_Handler<PR_ST_2, ACE_SYNCH_USE>::handle_timeout");
  264. return this->handle_close ();
  265. }
  266. template <PR_ST_1, ACE_SYNCH_DECL> int
  267. ACE_Svc_Handler<PR_ST_2, ACE_SYNCH_USE>::close (u_long)
  268. {
  269. ACE_TRACE ("ACE_Svc_Handler<PR_ST_2, ACE_SYNCH_USE>::close");
  270. return this->handle_close ();
  271. }
  272. template <PR_ST_1, ACE_SYNCH_DECL> int
  273. ACE_Svc_Handler<PR_ST_2, ACE_SYNCH_USE>::init (int /* argc */,
  274. ACE_TCHAR * /* argv */[])
  275. {
  276. ACE_TRACE ("ACE_Svc_Handler<PR_ST_2, ACE_SYNCH_USE>::init");
  277. return -1;
  278. }
  279. template <PR_ST_1, ACE_SYNCH_DECL> int
  280. ACE_Svc_Handler<PR_ST_2, ACE_SYNCH_USE>::fini (void)
  281. {
  282. ACE_TRACE ("ACE_Svc_Handler<PR_ST_2, ACE_SYNCH_USE>::fini");
  283. return -1;
  284. }
  285. template <PR_ST_1, ACE_SYNCH_DECL> int
  286. ACE_Svc_Handler<PR_ST_2, ACE_SYNCH_USE>::info (ACE_TCHAR **, size_t) const
  287. {
  288. ACE_TRACE ("ACE_Svc_Handler<PR_ST_2, ACE_SYNCH_USE>::info");
  289. return -1;
  290. }
  291. template <PR_ST_1, ACE_SYNCH_DECL> int
  292. ACE_Svc_Handler<PR_ST_2, ACE_SYNCH_USE>::idle (u_long flags)
  293. {
  294. if (this->recycler ())
  295. return this->recycler ()->cache (this->recycling_act_);
  296. else
  297. return this->close (flags);
  298. }
  299. template <PR_ST_1, ACE_SYNCH_DECL> int
  300. ACE_Svc_Handler<PR_ST_2, ACE_SYNCH_USE>::recycle_state (ACE_Recyclable_State new_state)
  301. {
  302. if (this->recycler ())
  303. return this->recycler ()->recycle_state (this->recycling_act_,
  304. new_state);
  305. return 0;
  306. }
  307. template <PR_ST_1, ACE_SYNCH_DECL> ACE_Recyclable_State
  308. ACE_Svc_Handler<PR_ST_2, ACE_SYNCH_USE>::recycle_state (void) const
  309. {
  310. if (this->recycler ())
  311. return this->recycler ()->recycle_state (this->recycling_act_);
  312. return ACE_RECYCLABLE_UNKNOWN;
  313. }
  314. template <PR_ST_1, ACE_SYNCH_DECL> void
  315. ACE_Svc_Handler<PR_ST_2, ACE_SYNCH_USE>::recycler (ACE_Connection_Recycling_Strategy *recycler,
  316. const void *recycling_act)
  317. {
  318. ACE_TRACE ("ACE_Svc_Handler<PR_ST_2, ACE_SYNCH_USE>::recycler");
  319. this->recycler_ = recycler;
  320. this->recycling_act_ = recycling_act;
  321. }
  322. template <PR_ST_1, ACE_SYNCH_DECL> ACE_Connection_Recycling_Strategy *
  323. ACE_Svc_Handler<PR_ST_2, ACE_SYNCH_USE>::recycler (void) const
  324. {
  325. ACE_TRACE ("ACE_Svc_Handler<PR_ST_2, ACE_SYNCH_USE>::recycler");
  326. return this->recycler_;
  327. }
  328. template <PR_ST_1, ACE_SYNCH_DECL> const void *
  329. ACE_Svc_Handler<PR_ST_2, ACE_SYNCH_USE>::recycling_act (void) const
  330. {
  331. ACE_TRACE ("ACE_Svc_Handler<PR_ST_2, ACE_SYNCH_USE>::recycling_act");
  332. return this->recycling_act_;
  333. }
  334. template <PR_ST_1, ACE_SYNCH_DECL> int
  335. ACE_Svc_Handler<PR_ST_2, ACE_SYNCH_USE>::recycle (void *)
  336. {
  337. ACE_TRACE ("ACE_Svc_Handler<PR_ST_2, ACE_SYNCH_USE>::recycle");
  338. // By default, the object is ready and willing to be recycled.
  339. return 0;
  340. }
  341. template <PR_ST_1, ACE_SYNCH_DECL>
  342. ACE_Buffered_Svc_Handler<PR_ST_2, ACE_SYNCH_USE>::~ACE_Buffered_Svc_Handler (void)
  343. {
  344. this->flush ();
  345. }
  346. template <PR_ST_1, ACE_SYNCH_DECL>
  347. ACE_Buffered_Svc_Handler<PR_ST_2, ACE_SYNCH_USE>::ACE_Buffered_Svc_Handler (ACE_Thread_Manager *tm,
  348. ACE_Message_Queue<ACE_SYNCH_USE> *mq,
  349. ACE_Reactor *reactor,
  350. size_t maximum_buffer_size,
  351. ACE_Time_Value *timeout)
  352. : ACE_Svc_Handler<PR_ST_2, ACE_SYNCH_USE> (tm, mq, reactor),
  353. maximum_buffer_size_ (maximum_buffer_size),
  354. current_buffer_size_ (0),
  355. timeoutp_ (timeout)
  356. {
  357. ACE_TRACE ("ACE_Buffered_Svc_Handler<PR_ST_2, ACE_SYNCH_USE>::ACE_Buffered_Svc_Handler");
  358. if (this->timeoutp_ != 0)
  359. {
  360. this->interval_ = *timeout;
  361. this->next_timeout_ = ACE_OS::gettimeofday () + this->interval_;
  362. }
  363. }
  364. template <PR_ST_1, ACE_SYNCH_DECL> int
  365. ACE_Buffered_Svc_Handler<PR_ST_2, ACE_SYNCH_USE>::put (ACE_Message_Block *mb,
  366. ACE_Time_Value *tv)
  367. {
  368. ACE_GUARD_RETURN (ACE_SYNCH_MUTEX_T, m, this->msg_queue ()->lock (), -1);
  369. // Enqueue <mb> onto the message queue.
  370. if (this->putq (mb, tv) == -1)
  371. return -1;
  372. else
  373. {
  374. // Update the current number of bytes on the queue.
  375. this->current_buffer_size_ += mb->total_size ();
  376. // Flush the buffer when the number of bytes exceeds the maximum
  377. // buffer size or when the timeout period has elapsed.
  378. if (this->current_buffer_size_ >= this->maximum_buffer_size_
  379. || (this->timeoutp_ != 0
  380. && this->next_timeout_ <= ACE_OS::gettimeofday ()))
  381. return this->flush_i ();
  382. else
  383. return 0;
  384. }
  385. }
  386. // Flush the buffer.
  387. template <PR_ST_1, ACE_SYNCH_DECL> int
  388. ACE_Buffered_Svc_Handler<PR_ST_2, ACE_SYNCH_USE>::flush (void)
  389. {
  390. ACE_GUARD_RETURN (ACE_SYNCH_MUTEX_T, m, this->msg_queue ()->lock (), -1);
  391. return this->flush_i ();
  392. }
  393. template <PR_ST_1, ACE_SYNCH_DECL> int
  394. ACE_Buffered_Svc_Handler<PR_ST_2, ACE_SYNCH_USE>::flush_i (void)
  395. {
  396. ACE_Message_Queue_Iterator<ACE_SYNCH_USE> iterator (*this->msg_queue ());
  397. ACE_Message_Block *mblk = 0;
  398. ssize_t result = 0;
  399. // Get the first <ACE_Message_Block> so that we can write everything
  400. // out via the <send_n>.
  401. if (iterator.next (mblk) != 0)
  402. result = this->peer ().send_n (mblk);
  403. // This method assumes the caller holds the queue's lock!
  404. if (result != -1)
  405. this->msg_queue ()->flush_i ();
  406. if (this->timeoutp_ != 0)
  407. // Update the next timeout period by adding the interval.
  408. this->next_timeout_ += this->interval_;
  409. this->current_buffer_size_ = 0;
  410. return result;
  411. }
  412. template <PR_ST_1, ACE_SYNCH_DECL> void
  413. ACE_Buffered_Svc_Handler<PR_ST_2, ACE_SYNCH_USE>::dump (void) const
  414. {
  415. #if defined (ACE_HAS_DUMP)
  416. ACE_TRACE ("ACE_Buffered_Svc_Handler<PR_ST_2, ACE_SYNCH_USE>::dump");
  417. ACE_Buffered_Svc_Handler<PR_ST_2, ACE_SYNCH_USE>::dump ();
  418. ACE_DEBUG ((LM_DEBUG,
  419. "maximum_buffer_size_ = %d\n",
  420. this->maximum_buffer_size_));
  421. ACE_DEBUG ((LM_DEBUG,
  422. "current_buffer_size_ = %d\n",
  423. this->current_buffer_size_));
  424. if (this->timeoutp_ != 0)
  425. ACE_DEBUG ((LM_DEBUG,
  426. "next_timeout_.sec = %d, next_timeout_.usec = %d\n",
  427. this->next_timeout_.sec (),
  428. this->next_timeout_.usec ()));
  429. #endif /* ACE_HAS_DUMP */
  430. }
  431. template <PR_ST_1, ACE_SYNCH_DECL> int
  432. ACE_Buffered_Svc_Handler<PR_ST_2, ACE_SYNCH_USE>::handle_timeout (const ACE_Time_Value &,
  433. const void *)
  434. {
  435. ACE_TRACE ("ACE_Buffered_Svc_Handler<PR_ST_2, ACE_SYNCH_USE>::handle_timeout");
  436. return 0;
  437. }
  438. ACE_END_VERSIONED_NAMESPACE_DECL
  439. #undef PR_ST_1
  440. #undef PR_ST_2
  441. #endif /* ACE_SVC_HANDLER_CPP */