Changes to attempt to silence bcc64x
[ACE_TAO.git] / ACE / ace / Acceptor.cpp
blobfd3fc9795cdd1167b414970c2eb81dff9edfa29d
1 #ifndef ACE_ACCEPTOR_CPP
2 #define ACE_ACCEPTOR_CPP
4 #include "ace/ACE.h"
6 #if !defined (ACE_LACKS_PRAGMA_ONCE)
7 # pragma once
8 #endif /* ACE_LACKS_PRAGMA_ONCE */
10 #include "ace/Acceptor.h"
11 #include "ace/Svc_Handler.h"
12 #include "ace/WFMO_Reactor.h"
13 #include "ace/OS_NS_stdio.h"
14 #include "ace/OS_NS_string.h"
16 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
18 ACE_ALLOC_HOOK_DEFINE_Tca(ACE_Acceptor)
20 template <typename SVC_HANDLER, typename PEER_ACCEPTOR> void
21 ACE_Acceptor<SVC_HANDLER, PEER_ACCEPTOR>::dump () const
23 #if defined (ACE_HAS_DUMP)
24 ACE_TRACE ("ACE_Acceptor<SVC_HANDLER, PEER_ACCEPTOR>::dump");
26 ACELIB_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this));
27 this->peer_acceptor_.dump ();
28 ACELIB_DEBUG ((LM_DEBUG, ACE_END_DUMP));
29 #endif /* ACE_HAS_DUMP */
32 template <typename SVC_HANDLER, typename PEER_ACCEPTOR>
33 ACE_Acceptor<SVC_HANDLER, PEER_ACCEPTOR>::operator PEER_ACCEPTOR & () const
35 ACE_TRACE ("ACE_Acceptor<SVC_HANDLER, PEER_ACCEPTOR>::operator PEER_ACCEPTOR &");
36 return (PEER_ACCEPTOR &) this->peer_acceptor_;
39 template <typename SVC_HANDLER, typename PEER_ACCEPTOR> PEER_ACCEPTOR &
40 ACE_Acceptor<SVC_HANDLER, PEER_ACCEPTOR>::acceptor () const
42 ACE_TRACE ("ACE_Acceptor<SVC_HANDLER, PEER_ACCEPTOR>::acceptor");
43 return const_cast<PEER_ACCEPTOR &> (this->peer_acceptor_);
46 // Returns ACE_HANDLE of the underlying Acceptor_Strategy.
48 template <typename SVC_HANDLER, typename PEER_ACCEPTOR> ACE_HANDLE
49 ACE_Acceptor<SVC_HANDLER, PEER_ACCEPTOR>::get_handle () const
51 ACE_TRACE ("ACE_Acceptor<SVC_HANDLER, PEER_ACCEPTOR>::get_handle");
52 return this->peer_acceptor_.get_handle ();
55 // Initialize the appropriate strategies for creation, passive
56 // connection acceptance, and concurrency, and then register <this>
57 // with the Reactor and listen for connection requests at the
58 // designated <local_addr>.
60 template <typename SVC_HANDLER, typename PEER_ACCEPTOR> int
61 ACE_Acceptor<SVC_HANDLER, PEER_ACCEPTOR>::open
62 (const typename PEER_ACCEPTOR::PEER_ADDR &local_addr,
63 ACE_Reactor *reactor,
64 int flags,
65 int use_select,
66 int reuse_addr)
68 ACE_TRACE ("ACE_Acceptor<SVC_HANDLER, PEER_ACCEPTOR>::open");
69 this->flags_ = flags;
70 this->use_select_ = use_select;
71 this->reuse_addr_ = reuse_addr;
72 this->peer_acceptor_addr_ = local_addr;
74 // Must supply a valid Reactor to Acceptor::open()...
76 if (reactor == 0)
78 errno = EINVAL;
79 return -1;
82 // Open the underlying PEER_ACCEPTOR.
83 if (this->peer_acceptor_.open (local_addr, reuse_addr) == -1)
84 return -1;
86 // Set the peer acceptor's handle into non-blocking mode. This is a
87 // safe-guard against the race condition that can otherwise occur
88 // between the time when <select> indicates that a passive-mode
89 // socket handle is "ready" and when we call <accept>. During this
90 // interval, the client can shutdown the connection, in which case,
91 // the <accept> call can hang!
92 (void) this->peer_acceptor_.enable (ACE_NONBLOCK);
94 int const result = reactor->register_handler (this,
95 ACE_Event_Handler::ACCEPT_MASK);
96 if (result != -1)
97 this->reactor (reactor);
98 else
99 this->peer_acceptor_.close ();
101 return result;
104 // Simple constructor.
106 template <typename SVC_HANDLER, typename PEER_ACCEPTOR>
107 ACE_Acceptor<SVC_HANDLER, PEER_ACCEPTOR>::ACE_Acceptor (ACE_Reactor *reactor,
108 int use_select)
109 :flags_ (0),
110 use_select_ (use_select),
111 reuse_addr_ (1)
113 ACE_TRACE ("ACE_Acceptor<SVC_HANDLER, PEER_ACCEPTOR>::ACE_Acceptor");
115 this->reactor (reactor);
118 template <typename SVC_HANDLER, typename PEER_ACCEPTOR>
119 ACE_Acceptor<SVC_HANDLER, PEER_ACCEPTOR>::ACE_Acceptor
120 (const typename PEER_ACCEPTOR::PEER_ADDR &addr,
121 ACE_Reactor *reactor,
122 int flags,
123 int use_select,
124 int reuse_addr)
126 ACE_TRACE ("ACE_Acceptor<SVC_HANDLER, PEER_ACCEPTOR>::ACE_Acceptor");
128 if (this->open (addr,
129 reactor,
130 flags,
131 use_select,
132 reuse_addr) == -1)
133 ACELIB_ERROR ((LM_ERROR,
134 ACE_TEXT ("%p\n"),
135 ACE_TEXT ("ACE_Acceptor::ACE_Acceptor")));
138 template <typename SVC_HANDLER, typename PEER_ACCEPTOR>
139 ACE_Acceptor<SVC_HANDLER, PEER_ACCEPTOR>::~ACE_Acceptor ()
141 ACE_TRACE ("ACE_Acceptor<SVC_HANDLER, PEER_ACCEPTOR>::~ACE_Acceptor");
142 this->handle_close ();
145 template <typename SVC_HANDLER, typename PEER_ACCEPTOR> int
146 ACE_Acceptor<SVC_HANDLER, PEER_ACCEPTOR>::fini ()
148 ACE_TRACE ("ACE_Acceptor<SVC_HANDLER, PEER_ACCEPTOR>::fini");
149 return ACE_Acceptor<SVC_HANDLER, PEER_ACCEPTOR>::handle_close ();
152 // Hook called by the explicit dynamic linking facility.
154 template <typename SVC_HANDLER, typename PEER_ACCEPTOR> int
155 ACE_Acceptor<SVC_HANDLER, PEER_ACCEPTOR>::init (int, ACE_TCHAR *[])
157 ACE_TRACE ("ACE_Acceptor<SVC_HANDLER, PEER_ACCEPTOR>::init");
158 return -1;
161 template <typename SVC_HANDLER, typename PEER_ACCEPTOR> int
162 ACE_Acceptor<SVC_HANDLER, PEER_ACCEPTOR>::info (ACE_TCHAR **strp,
163 size_t length) const
165 ACE_TRACE ("ACE_Acceptor<SVC_HANDLER, PEER_ACCEPTOR>::info");
166 ACE_TCHAR addr_str[BUFSIZ];
167 typename PEER_ACCEPTOR::PEER_ADDR addr;
169 if (this->acceptor ().get_local_addr (addr) == -1)
170 return -1;
171 else if (addr.addr_to_string (addr_str, sizeof addr_str) == -1)
172 return -1;
175 // gcc10 complains that it is possible that buf could be truncated by up to
176 // 35 bytes in this call to snprintf. Technically, this is possible
177 // (however unlikely that may be). Since addr_str is defined to be of size
178 // BUFSIZ, gcc assumes that the string could actually be BUFSIZ in length.
179 // That makes the possible total length of the combined string (given the
180 // size of the literal string constants) 3 + 12 + BUFSIZE + 19 + 1.
182 const size_t additional = 35;
183 ACE_TCHAR buf[BUFSIZ + additional];
184 ACE_OS::snprintf (buf, sizeof buf,
185 ACE_TEXT ("%s\t %s %s"),
186 ACE_TEXT ("ACE_Acceptor"),
187 addr_str,
188 ACE_TEXT ("# acceptor factory\n"));
190 if (*strp == 0 && (*strp = ACE_OS::strdup (buf)) == 0)
191 return -1;
192 else
193 ACE_OS::strsncpy (*strp, buf, length);
194 return static_cast<int> (ACE_OS::strlen (buf));
197 template <typename SVC_HANDLER, typename PEER_ACCEPTOR> int
198 ACE_Acceptor<SVC_HANDLER, PEER_ACCEPTOR>::suspend ()
200 ACE_TRACE ("ACE_Acceptor<SVC_HANDLER, PEER_ACCEPTOR>::suspend");
201 return this->reactor ()->suspend_handler (this);
204 template <typename SVC_HANDLER, typename PEER_ACCEPTOR> int
205 ACE_Acceptor<SVC_HANDLER, PEER_ACCEPTOR>::resume ()
207 ACE_TRACE ("ACE_Acceptor<SVC_HANDLER, PEER_ACCEPTOR>::resume");
208 return this->reactor ()->resume_handler (this);
211 // Perform termination activities when <this> is removed from the
212 // <reactor>.
214 template <typename SVC_HANDLER, typename PEER_ACCEPTOR> int
215 ACE_Acceptor<SVC_HANDLER, PEER_ACCEPTOR>::close ()
217 ACE_TRACE ("ACE_Acceptor<SVC_HANDLER, PEER_ACCEPTOR>::close");
218 return this->handle_close ();
221 template <typename SVC_HANDLER, typename PEER_ACCEPTOR> int
222 ACE_Acceptor<SVC_HANDLER, PEER_ACCEPTOR>::handle_accept_error ()
224 ACE_TRACE ("ACE_Acceptor<SVC_HANDLER, PEER_ACCEPTOR>::handle_accept_error");
225 return 0;
228 template <typename SVC_HANDLER, typename PEER_ACCEPTOR> int
229 ACE_Acceptor<SVC_HANDLER, PEER_ACCEPTOR>::handle_close (ACE_HANDLE,
230 ACE_Reactor_Mask)
232 ACE_TRACE ("ACE_Acceptor<SVC_HANDLER, PEER_ACCEPTOR>::handle_close");
233 // Guard against multiple closes.
234 if (this->reactor () != 0)
236 ACE_HANDLE handle = this->get_handle ();
238 this->reactor ()->remove_handler
239 (handle,
240 // We must pass the DONT_CALL flag here to avoid infinite
241 // recursion.
242 ACE_Event_Handler::ACCEPT_MASK | ACE_Event_Handler::DONT_CALL);
244 // Shut down the listen socket to recycle the handles.
245 if (this->peer_acceptor_.close () == -1)
246 ACELIB_ERROR ((LM_ERROR,
247 ACE_TEXT ("close\n")));
248 // Set the Reactor to 0 so that we don't try to close down
249 // again.
250 this->reactor (0);
252 return 0;
255 // Bridge method for creating a SVC_HANDLER. The strategy for
256 // creating a SVC_HANDLER are configured into the Acceptor via it's
257 // <creation_strategy_>. The default is to create a new SVC_HANDLER.
258 // However, subclasses can override this strategy to perform
259 // SVC_HANDLER creation in any way that they like (such as creating
260 // subclass instances of SVC_HANDLER, using a singleton, dynamically
261 // linking the handler, etc.).
263 template <typename SVC_HANDLER, typename PEER_ACCEPTOR> int
264 ACE_Acceptor<SVC_HANDLER, PEER_ACCEPTOR>::make_svc_handler (SVC_HANDLER *&sh)
266 ACE_TRACE ("ACE_Acceptor<SVC_HANDLER, PEER_ACCEPTOR>::make_svc_handler");
268 if (sh == 0)
269 ACE_NEW_RETURN (sh,
270 SVC_HANDLER,
271 -1);
273 // Set the reactor of the newly created <SVC_HANDLER> to the same
274 // reactor that this <ACE_Acceptor> is using.
275 sh->reactor (this->reactor ());
276 return 0;
279 // Bridge method for accepting the new connection into the
280 // <svc_handler>. The default behavior delegates to the
281 // <PEER_ACCEPTOR::accept> in the Acceptor_Strategy.
283 template <typename SVC_HANDLER, typename PEER_ACCEPTOR> int
284 ACE_Acceptor<SVC_HANDLER, PEER_ACCEPTOR>::accept_svc_handler
285 (SVC_HANDLER *svc_handler)
287 ACE_TRACE ("ACE_Acceptor<SVC_HANDLER, PEER_ACCEPTOR>::accept_svc_handler");
289 // Try to find out if the implementation of the reactor that we are
290 // using requires us to reset the event association for the newly
291 // created handle. This is because the newly created handle will
292 // inherit the properties of the listen handle, including its event
293 // associations.
295 ACE_Reactor *reactor = this->reactor ();
296 bool reset_new_handle;
298 if (reactor)
300 reset_new_handle = reactor->uses_event_associations ();
302 else
304 // Acceptor is closed, so reject this call
305 errno = EINVAL;
306 return -1;
309 if (this->acceptor ().accept (svc_handler->peer (), // stream
310 0, // remote address
311 0, // timeout
312 true, // restart
313 reset_new_handle // reset new handler
314 ) == -1)
316 // Ensure that errno is preserved in case the svc_handler
317 // close() method resets it
318 ACE_Errno_Guard error(errno);
320 // Close down handler to avoid memory leaks.
321 svc_handler->close (CLOSE_DURING_NEW_CONNECTION);
323 return -1;
325 else
326 return 0;
329 // Bridge method for activating a <svc_handler> with the appropriate
330 // concurrency strategy. The default behavior of this method is to
331 // activate the SVC_HANDLER by calling its open() method (which allows
332 // the SVC_HANDLER to define its own concurrency strategy). However,
333 // subclasses can override this strategy to do more sophisticated
334 // concurrency activations (such as creating the SVC_HANDLER as an
335 // "active object" via multi-threading or multi-processing).
337 template <typename SVC_HANDLER, typename PEER_ACCEPTOR> int
338 ACE_Acceptor<SVC_HANDLER, PEER_ACCEPTOR>::activate_svc_handler
339 (SVC_HANDLER *svc_handler)
341 ACE_TRACE ("ACE_Acceptor<SVC_HANDLER, PEER_ACCEPTOR>::activate_svc_handler");
343 int result = 0;
345 // See if we should enable non-blocking I/O on the <svc_handler>'s
346 // peer.
347 if (ACE_BIT_ENABLED (this->flags_,
348 ACE_NONBLOCK))
350 if (svc_handler->peer ().enable (ACE_NONBLOCK) == -1)
351 result = -1;
353 // Otherwise, make sure it's disabled by default.
354 else if (svc_handler->peer ().disable (ACE_NONBLOCK) == -1)
355 result = -1;
357 if (result == 0 && svc_handler->open ((void *) this) == -1)
358 result = -1;
360 if (result == -1)
361 // The connection was already made; so this close is a "normal" close
362 // operation.
363 svc_handler->close (NORMAL_CLOSE_OPERATION);
365 return result;
368 // Template Method that makes a SVC_HANDLER (using the appropriate
369 // creation strategy), accept the connection into the SVC_HANDLER, and
370 // then activate the SVC_HANDLER.
372 template <typename SVC_HANDLER, typename PEER_ACCEPTOR> int
373 ACE_Acceptor<SVC_HANDLER, PEER_ACCEPTOR>::handle_input (ACE_HANDLE listener)
375 ACE_TRACE ("ACE_Acceptor<SVC_HANDLER, PEER_ACCEPTOR>::handle_input");
377 // Default is "timeout (0, 0)," which means "poll."
378 ACE_Time_Value timeout;
380 // Accept connections from clients. Note that a loop is used for two
381 // reasons:
383 // 1. It allows us to accept all pending connections without an
384 // extra trip through the ACE_Reactor and without having to use
385 // non-blocking I/O...
387 // 2. It allows the TLI_SAP::ACE_Acceptor class to work correctly (don't
388 // ask -- TLI is *horrible*...).
390 // Ensure that errno is preserved in case the ACE::handle_read_ready()
391 // method resets it in the loop bellow. We are actually supposed to
392 // ignore any errors from this loop, hence the return 0 following it.
393 ACE_Errno_Guard error (errno);
395 // @@ What should we do if any of the substrategies fail? Right
396 // now, we just print out a diagnostic message if <ACE::debug>
397 // returns > 0 and return 0 (which means that the Acceptor remains
398 // registered with the Reactor)...
401 // Create a service handler, using the appropriate creation
402 // strategy.
404 SVC_HANDLER *svc_handler = 0;
406 if (this->make_svc_handler (svc_handler) == -1)
408 if (ACE::debug ())
410 ACELIB_DEBUG ((LM_DEBUG,
411 ACE_TEXT ("%p\n"),
412 ACE_TEXT ("make_svc_handler")));
414 return 0;
416 // Accept connection into the Svc_Handler.
417 else if (this->accept_svc_handler (svc_handler) == -1)
419 // Note that <accept_svc_handler> closes the <svc_handler>
420 // on failure.
421 if (ACE::debug ())
423 ACELIB_DEBUG ((LM_DEBUG,
424 ACE_TEXT ("%p\n"),
425 ACE_TEXT ("accept_svc_handler")));
427 const int ret = this->handle_accept_error ();
428 if (ret == -1)
430 // Ensure that the errno from the above call propegates.
431 error = errno;
433 return ret;
435 // Activate the <svc_handler> using the designated concurrency
436 // strategy (note that this method becomes responsible for
437 // handling errors and freeing up the memory if things go
438 // awry...).
439 else if (this->activate_svc_handler (svc_handler) == -1)
441 // Note that <activate_svc_handler> closes the <svc_handler>
442 // on failure.
444 if (ACE::debug ())
446 ACELIB_DEBUG ((LM_DEBUG,
447 ACE_TEXT ("%p\n"),
448 ACE_TEXT ("activate_svc_handler")));
450 return 0;
452 // Now, check to see if there is another connection pending and
453 // break out of the loop if there is none.
454 } while (this->use_select_ &&
455 ACE::handle_read_ready (listener, &timeout) == 1);
456 return 0;
459 ACE_ALLOC_HOOK_DEFINE_Tca(ACE_Strategy_Acceptor)
461 template <typename SVC_HANDLER, typename PEER_ACCEPTOR> int
462 ACE_Strategy_Acceptor<SVC_HANDLER, PEER_ACCEPTOR>::suspend ()
464 ACE_TRACE ("ACE_Strategy_Acceptor<SVC_HANDLER, PEER_ACCEPTOR>::suspend");
466 // First suspend the SVC_HANDLER's we've created.
467 if (this->scheduling_strategy_->suspend () == -1)
468 return -1;
469 else // Then suspend ourselves.
470 return ACE_Acceptor<SVC_HANDLER, PEER_ACCEPTOR>::suspend ();
473 template <typename SVC_HANDLER, typename PEER_ACCEPTOR> int
474 ACE_Strategy_Acceptor<SVC_HANDLER, PEER_ACCEPTOR>::resume ()
476 ACE_TRACE ("ACE_Strategy_Acceptor<SVC_HANDLER, PEER_ACCEPTOR>::resume");
478 // First resume ourselves.
479 if (ACE_Acceptor<SVC_HANDLER, PEER_ACCEPTOR>::resume () == -1)
480 return -1;
481 else // Then resume the SVC_HANDLER's we've created.
482 return this->scheduling_strategy_->resume ();
485 template <typename SVC_HANDLER, typename PEER_ACCEPTOR> void
486 ACE_Strategy_Acceptor<SVC_HANDLER, PEER_ACCEPTOR>::dump () const
488 #if defined (ACE_HAS_DUMP)
489 ACE_TRACE ("ACE_Strategy_Acceptor<SVC_HANDLER, PEER_ACCEPTOR>::dump");
491 ACELIB_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this));
492 ACE_Acceptor<SVC_HANDLER, PEER_ACCEPTOR>::dump ();
493 this->creation_strategy_->dump ();
494 ACELIB_DEBUG ((LM_DEBUG, ACE_TEXT ("delete_creation_strategy_ = %d"), delete_creation_strategy_));
495 this->accept_strategy_->dump ();
496 ACELIB_DEBUG ((LM_DEBUG, ACE_TEXT ("delete_accept_strategy_ = %d"), delete_accept_strategy_));
497 this->concurrency_strategy_->dump ();
498 ACELIB_DEBUG ((LM_DEBUG, ACE_TEXT ("delete_concurrency_strategy_ = %d"), delete_concurrency_strategy_));
499 this->scheduling_strategy_->dump ();
500 ACELIB_DEBUG ((LM_DEBUG, ACE_TEXT ("delete_scheduling_strategy_ = %d"), delete_scheduling_strategy_));
501 ACELIB_DEBUG ((LM_DEBUG, ACE_TEXT ("\nservice_name_ = %s"),
502 this->service_name_ == 0 ? ACE_TEXT ("<unknown>") : this->service_name_));
503 ACELIB_DEBUG ((LM_DEBUG, ACE_TEXT ("\nservice_description_ = %s"),
504 this->service_description_ == 0 ? ACE_TEXT ("<unknown>") : this->service_description_));
505 this->service_addr_.dump ();
506 ACELIB_DEBUG ((LM_DEBUG, ACE_END_DUMP));
507 #endif /* ACE_HAS_DUMP */
510 template <typename SVC_HANDLER, typename PEER_ACCEPTOR> PEER_ACCEPTOR &
511 ACE_Strategy_Acceptor<SVC_HANDLER, PEER_ACCEPTOR>::acceptor () const
513 ACE_TRACE ("ACE_Strategy_Acceptor<SVC_HANDLER, PEER_ACCEPTOR>::acceptor");
514 return this->accept_strategy_->acceptor ();
517 template <typename SVC_HANDLER, typename PEER_ACCEPTOR>
518 ACE_Strategy_Acceptor<SVC_HANDLER, PEER_ACCEPTOR>::operator PEER_ACCEPTOR & () const
520 ACE_TRACE ("ACE_Strategy_Acceptor<SVC_HANDLER, PEER_ACCEPTOR>::operator PEER_ACCEPTOR &");
521 return this->accept_strategy_->acceptor ();
524 // Returns ACE_HANDLE of the underlying Acceptor_Strategy.
526 template <typename SVC_HANDLER, typename PEER_ACCEPTOR> ACE_HANDLE
527 ACE_Strategy_Acceptor<SVC_HANDLER, PEER_ACCEPTOR>::get_handle () const
529 ACE_TRACE ("ACE_Strategy_Acceptor<SVC_HANDLER, PEER_ACCEPTOR>::get_handle");
530 return this->accept_strategy_->get_handle ();
533 // Initialize the appropriate strategies for creation, passive
534 // connection acceptance, and concurrency, and then register <this>
535 // with the Reactor and listen for connection requests at the
536 // designated <local_addr>.
537 template <typename SVC_HANDLER, typename PEER_ACCEPTOR> int
538 ACE_Strategy_Acceptor<SVC_HANDLER, PEER_ACCEPTOR>::open
539 (const typename PEER_ACCEPTOR::PEER_ADDR &local_addr,
540 ACE_Reactor *reactor,
541 int /* flags unused */,
542 int use_select,
543 int reuse_addr)
545 ACE_TRACE ("ACE_Strategy_Acceptor<SVC_HANDLER, PEER_ACCEPTOR>::open");
546 return this->open
547 (local_addr, reactor, 0, 0, 0, 0, 0, 0, use_select, reuse_addr);
551 template <typename SVC_HANDLER, typename PEER_ACCEPTOR> int
552 ACE_Strategy_Acceptor<SVC_HANDLER, PEER_ACCEPTOR>::open
553 (const typename PEER_ACCEPTOR::PEER_ADDR &local_addr,
554 ACE_Reactor *reactor,
555 ACE_Creation_Strategy<SVC_HANDLER> *cre_s,
556 ACE_Accept_Strategy<SVC_HANDLER, PEER_ACCEPTOR> *acc_s,
557 ACE_Concurrency_Strategy<SVC_HANDLER> *con_s,
558 ACE_Scheduling_Strategy<SVC_HANDLER> *sch_s,
559 const ACE_TCHAR *service_name,
560 const ACE_TCHAR *service_description,
561 int use_select,
562 int reuse_addr)
564 ACE_TRACE ("ACE_Strategy_Acceptor<SVC_HANDLER, PEER_ACCEPTOR>::open");
566 if (this->service_name_ == 0 && service_name != 0)
567 ACE_ALLOCATOR_RETURN (this->service_name_,
568 ACE_OS::strdup (service_name),
569 -1);
570 if (this->service_description_ == 0 && service_description != 0)
571 ACE_ALLOCATOR_RETURN (this->service_description_,
572 ACE_OS::strdup (service_description),
573 -1);
574 this->reactor (reactor);
576 // Must supply a valid Reactor to Acceptor::open()...
577 if (reactor == 0)
579 errno = EINVAL;
580 return -1;
583 // Initialize the creation strategy.
585 if (cre_s == 0)
587 ACE_NEW_RETURN (cre_s,
588 CREATION_STRATEGY,
589 -1);
590 this->delete_creation_strategy_ = true;
592 this->creation_strategy_ = cre_s;
594 // Initialize the accept strategy.
596 if (acc_s == 0)
598 ACE_NEW_RETURN (acc_s,
599 ACCEPT_STRATEGY (this->reactor ()),
600 -1);
601 this->delete_accept_strategy_ = true;
603 this->accept_strategy_ = acc_s;
605 if (this->accept_strategy_->open (local_addr, reuse_addr) == -1)
606 return -1;
608 // Set the peer acceptor's handle into non-blocking mode. This is a
609 // safe-guard against the race condition that can otherwise occur
610 // between the time when <select> indicates that a passive-mode
611 // socket handle is "ready" and when we call <accept>. During this
612 // interval, the client can shutdown the connection, in which case,
613 // the <accept> call can hang!
614 if (this->accept_strategy_->acceptor ().enable (ACE_NONBLOCK) != 0)
615 return -1;
617 // Initialize the concurrency strategy.
619 if (con_s == 0)
621 ACE_NEW_RETURN (con_s,
622 CONCURRENCY_STRATEGY,
623 -1);
624 this->delete_concurrency_strategy_ = true;
626 this->concurrency_strategy_ = con_s;
628 // Initialize the scheduling strategy.
630 if (sch_s == 0)
632 ACE_NEW_RETURN (sch_s,
633 SCHEDULING_STRATEGY,
634 -1);
635 this->delete_scheduling_strategy_ = true;
637 this->scheduling_strategy_ = sch_s;
639 this->use_select_ = use_select;
641 return this->reactor ()->register_handler
642 (this,
643 ACE_Event_Handler::ACCEPT_MASK);
646 // Simple constructor.
648 template <typename SVC_HANDLER, typename PEER_ACCEPTOR>
649 ACE_Strategy_Acceptor<SVC_HANDLER, PEER_ACCEPTOR>::ACE_Strategy_Acceptor
650 (const ACE_TCHAR service_name[],
651 const ACE_TCHAR service_description[],
652 int use_select,
653 int reuse_addr)
654 : creation_strategy_ (0),
655 delete_creation_strategy_ (false),
656 accept_strategy_ (0),
657 delete_accept_strategy_ (false),
658 concurrency_strategy_ (0),
659 delete_concurrency_strategy_ (false),
660 scheduling_strategy_ (0),
661 delete_scheduling_strategy_ (false),
662 service_name_ (0),
663 service_description_ (0)
665 ACE_TRACE ("ACE_Strategy_Acceptor<SVC_HANDLER, PEER_ACCEPTOR>::ACE_Strategy_Acceptor");
667 if (service_name != 0)
668 ACE_ALLOCATOR (this->service_name_,
669 ACE_OS::strdup (service_name));
670 if (service_description != 0)
671 ACE_ALLOCATOR (this->service_description_,
672 ACE_OS::strdup (service_description));
673 this->use_select_ = use_select;
674 this->reuse_addr_ = reuse_addr;
677 template <typename SVC_HANDLER, typename PEER_ACCEPTOR>
678 ACE_Strategy_Acceptor<SVC_HANDLER, PEER_ACCEPTOR>::ACE_Strategy_Acceptor
679 (const typename PEER_ACCEPTOR::PEER_ADDR &addr,
680 ACE_Reactor *reactor,
681 ACE_Creation_Strategy<SVC_HANDLER> *cre_s,
682 ACE_Accept_Strategy<SVC_HANDLER, PEER_ACCEPTOR> *acc_s,
683 ACE_Concurrency_Strategy<SVC_HANDLER> *con_s,
684 ACE_Scheduling_Strategy<SVC_HANDLER> *sch_s,
685 const ACE_TCHAR service_name[],
686 const ACE_TCHAR service_description[],
687 int use_select,
688 int reuse_addr)
689 : creation_strategy_ (0),
690 delete_creation_strategy_ (false),
691 accept_strategy_ (0),
692 delete_accept_strategy_ (false),
693 concurrency_strategy_ (0),
694 delete_concurrency_strategy_ (false),
695 scheduling_strategy_ (0),
696 delete_scheduling_strategy_ (false),
697 service_name_ (0),
698 service_description_ (0)
700 ACE_TRACE ("ACE_Strategy_Acceptor<SVC_HANDLER, PEER_ACCEPTOR>::ACE_Strategy_Acceptor");
702 if (this->open (addr,
703 reactor,
704 cre_s,
705 acc_s,
706 con_s,
707 sch_s,
708 service_name,
709 service_description,
710 use_select,
711 reuse_addr) == -1)
712 ACELIB_ERROR ((LM_ERROR,
713 ACE_TEXT ("%p\n"),
714 ACE_TEXT ("ACE_Strategy_Acceptor::ACE_Strategy_Acceptor")));
717 // Perform termination activities when <this> is removed from the
718 // <ACE_Reactor>.
720 template <typename SVC_HANDLER, typename PEER_ACCEPTOR> int
721 ACE_Strategy_Acceptor<SVC_HANDLER, PEER_ACCEPTOR>::handle_close (ACE_HANDLE,
722 ACE_Reactor_Mask)
724 ACE_TRACE ("ACE_Strategy_Acceptor<SVC_HANDLER, PEER_ACCEPTOR>::handle_close");
725 // Guard against multiple closes.
726 if (this->reactor () != 0)
728 ACE_HANDLE handle = this->get_handle ();
730 if (this->delete_creation_strategy_)
731 delete this->creation_strategy_;
732 this->delete_creation_strategy_ = false;
733 this->creation_strategy_ = 0;
735 if (this->delete_accept_strategy_)
736 delete this->accept_strategy_;
737 this->delete_accept_strategy_ = false;
738 this->accept_strategy_ = 0;
740 if (this->delete_concurrency_strategy_)
741 delete this->concurrency_strategy_;
742 this->delete_concurrency_strategy_ = false;
743 this->concurrency_strategy_ = 0;
745 if (this->delete_scheduling_strategy_)
746 delete this->scheduling_strategy_;
747 this->delete_scheduling_strategy_ = false;
748 this->scheduling_strategy_ = 0;
750 // We must use the <handle> obtained *before* we deleted the
751 // accept_strategy_...
753 this->reactor ()->remove_handler
754 (handle,
755 ACE_Event_Handler::ACCEPT_MASK | ACE_Event_Handler::DONT_CALL);
757 // Set the Reactor to 0 so that we don't try to close down
758 // again.
759 this->reactor (0);
761 return 0;
764 // Bridge method for creating a <SVC_HANDLER>. The strategy for
765 // creating a <SVC_HANDLER> are configured into the Acceptor via it's
766 // <creation_strategy_>. The default is to create a new
767 // <SVC_HANDLER>. However, subclasses can override this strategy to
768 // perform <SVC_HANDLER> creation in any way that they like (such as
769 // creating subclass instances of <SVC_HANDLER>, using a singleton,
770 // dynamically linking the handler, etc.).
772 template <typename SVC_HANDLER, typename PEER_ACCEPTOR> int
773 ACE_Strategy_Acceptor<SVC_HANDLER, PEER_ACCEPTOR>::make_svc_handler (SVC_HANDLER *&sh)
775 ACE_TRACE ("ACE_Strategy_Acceptor<SVC_HANDLER, PEER_ACCEPTOR>::make_svc_handler");
776 return this->creation_strategy_->make_svc_handler (sh);
779 // Bridge method for accepting the new connection into the
780 // <svc_handler>. The default behavior delegates to the
781 // <Strategy_Acceptor::accept> in the Acceptor_Strategy.
783 template <typename SVC_HANDLER, typename PEER_ACCEPTOR> int
784 ACE_Strategy_Acceptor<SVC_HANDLER, PEER_ACCEPTOR>::accept_svc_handler
785 (SVC_HANDLER *svc_handler)
787 ACE_TRACE ("ACE_Strategy_Acceptor<SVC_HANDLER, PEER_ACCEPTOR>::accept_svc_handler");
788 return this->accept_strategy_->accept_svc_handler (svc_handler);
791 // Bridge method for activating a <svc_handler> with the appropriate
792 // concurrency strategy. The default behavior of this method is to
793 // activate the SVC_HANDLER by calling its open() method (which allows
794 // the SVC_HANDLER to define its own concurrency strategy). However,
795 // subclasses can override this strategy to do more sophisticated
796 // concurrency activations (such as creating the SVC_HANDLER as an
797 // "active object" via multi-threading or multi-processing).
799 template <typename SVC_HANDLER, typename PEER_ACCEPTOR> int
800 ACE_Strategy_Acceptor<SVC_HANDLER, PEER_ACCEPTOR>::activate_svc_handler
801 (SVC_HANDLER *svc_handler)
803 ACE_TRACE ("ACE_Strategy_Acceptor<SVC_HANDLER, PEER_ACCEPTOR>::activate_svc_handler");
804 return this->concurrency_strategy_->activate_svc_handler
805 (svc_handler,
806 (void *) this);
809 template <typename SVC_HANDLER, typename PEER_ACCEPTOR>
810 ACE_Strategy_Acceptor<SVC_HANDLER, PEER_ACCEPTOR>::~ACE_Strategy_Acceptor ()
812 ACE_TRACE ("ACE_Strategy_Acceptor<SVC_HANDLER, PEER_ACCEPTOR>::~ACE_Strategy_Acceptor");
813 ACE_OS::free ((void *) this->service_name_);
814 ACE_OS::free ((void *) this->service_description_);
815 this->handle_close ();
818 // Signal the server to shutdown gracefully.
820 template <typename SVC_HANDLER, typename PEER_ACCEPTOR> int
821 ACE_Strategy_Acceptor<SVC_HANDLER, PEER_ACCEPTOR>::handle_signal (int, siginfo_t *, ucontext_t *)
823 ACE_Reactor::instance()->end_reactor_event_loop ();
824 return 0;
827 template <typename SVC_HANDLER, typename PEER_ACCEPTOR> int
828 ACE_Strategy_Acceptor<SVC_HANDLER, PEER_ACCEPTOR>::info (ACE_TCHAR **strp,
829 size_t length) const
831 ACE_TRACE ("ACE_Strategy_Acceptor::info");
833 ACE_TCHAR service_addr_str[BUFSIZ];
834 typename PEER_ACCEPTOR::PEER_ADDR addr;
836 if (this->acceptor ().get_local_addr (addr) == -1)
837 return -1;
838 else if (addr.addr_to_string (service_addr_str,
839 sizeof service_addr_str) == -1)
840 return -1;
843 // gcc10 complains that it is possible that buf could be truncated by up to
844 // 6 bytes in this call to snprintf. Technically, this is possible
845 // (however unlikely that may be). Since service_addr_str is defined to be
846 // of size BUFSIZ, gcc assumes that the string could actually be BUFSIZ in
847 // length. That makes the possible total length of the combined string
848 // (given the size of the literal string constants) 5 + BUFSIZE + 1.
850 const size_t additional = 6;
851 ACE_TCHAR buf[BUFSIZ + additional];
852 ACE_OS::snprintf (buf, sizeof buf,
853 ACE_TEXT ("%s\t %s #%s\n"),
854 this->service_name_ == 0
855 ? ACE_TEXT ("<unknown>")
856 : this->service_name_,
857 service_addr_str,
858 this->service_description_ == 0
859 ? ACE_TEXT ("<unknown>")
860 : this->service_description_);
862 if (*strp == 0 && (*strp = ACE_OS::strdup (buf)) == 0)
863 return -1;
864 else
865 ACE_OS::strsncpy (*strp, buf, length);
866 return static_cast<int> (ACE_OS::strlen (buf));
869 template <typename SVC_HANDLER, typename PEER_ACCEPTOR> int
870 ACE_Strategy_Acceptor<SVC_HANDLER, PEER_ACCEPTOR>::fini ()
872 ACE_TRACE ("ACE_Strategy_Acceptor<SVC_HANDLER, PEER_ACCEPTOR>::fini");
873 return this->ACE_Strategy_Acceptor<SVC_HANDLER, PEER_ACCEPTOR>::handle_close ();
876 ACE_ALLOC_HOOK_DEFINE_Tca(ACE_Oneshot_Acceptor)
878 template <typename SVC_HANDLER, typename PEER_ACCEPTOR> void
879 ACE_Oneshot_Acceptor<SVC_HANDLER, PEER_ACCEPTOR>::dump () const
881 #if defined (ACE_HAS_DUMP)
882 ACE_TRACE ("ACE_Oneshot_Acceptor<SVC_HANDLER, PEER_ACCEPTOR>::dump");
884 ACELIB_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this));
885 ACELIB_DEBUG ((LM_DEBUG, ACE_TEXT ("\nsvc_handler_ = %x"), this->svc_handler_));
886 ACELIB_DEBUG ((LM_DEBUG, ACE_TEXT ("\nrestart_ = %d"), this->restart_));
887 this->peer_acceptor_.dump ();
888 ACELIB_DEBUG ((LM_DEBUG, ACE_TEXT ("delete_concurrency_strategy_ = %d"),
889 delete_concurrency_strategy_));
890 this->concurrency_strategy_->dump ();
891 ACELIB_DEBUG ((LM_DEBUG, ACE_END_DUMP));
892 #endif /* ACE_HAS_DUMP */
895 template <typename SVC_HANDLER, typename PEER_ACCEPTOR> int
896 ACE_Oneshot_Acceptor<SVC_HANDLER, PEER_ACCEPTOR>::open
897 (const typename PEER_ACCEPTOR::PEER_ADDR &local_addr,
898 ACE_Reactor *reactor,
899 ACE_Concurrency_Strategy<SVC_HANDLER> *con_s)
901 ACE_TRACE ("ACE_Oneshot_Acceptor<SVC_HANDLER, PEER_ACCEPTOR>::open");
902 this->reactor (reactor);
904 // Initialize the concurrency strategy.
906 if (con_s == 0)
908 ACE_NEW_RETURN (con_s,
909 ACE_Concurrency_Strategy<SVC_HANDLER>,
910 -1);
911 this->delete_concurrency_strategy_ = true;
913 this->concurrency_strategy_ = con_s;
915 // Reuse the addr, even if it is already in use...!
916 return this->peer_acceptor_.open (local_addr, 1);
919 template <typename SVC_HANDLER, typename PEER_ACCEPTOR>
920 ACE_Oneshot_Acceptor<SVC_HANDLER, PEER_ACCEPTOR>::ACE_Oneshot_Acceptor ()
921 : svc_handler_ (0),
922 restart_ (false),
923 concurrency_strategy_ (0),
924 delete_concurrency_strategy_ (false)
926 ACE_TRACE ("ACE_Oneshot_Acceptor<SVC_HANDLER, PEER_ACCEPTOR>::ACE_Oneshot_Acceptor");
927 this->reactor (0);
930 template <typename SVC_HANDLER, typename PEER_ACCEPTOR>
931 ACE_Oneshot_Acceptor<SVC_HANDLER, PEER_ACCEPTOR>::ACE_Oneshot_Acceptor
932 (const typename PEER_ACCEPTOR::PEER_ADDR &local_addr,
933 ACE_Reactor *reactor,
934 ACE_Concurrency_Strategy<SVC_HANDLER> *cs)
935 : svc_handler_ (0),
936 restart_ (false),
937 concurrency_strategy_ (0),
938 delete_concurrency_strategy_ (false)
940 ACE_TRACE ("ACE_Oneshot_Acceptor<SVC_HANDLER, PEER_ACCEPTOR>::ACE_Oneshot_Acceptor");
941 if (this->open (local_addr, reactor, cs) == -1)
942 ACELIB_ERROR ((LM_ERROR,
943 ACE_TEXT ("%p\n"),
944 ACE_TEXT ("ACE_Oneshot_Acceptor::ACE_Oneshot_Acceptor")));
947 template <typename SVC_HANDLER, typename PEER_ACCEPTOR>
948 ACE_Oneshot_Acceptor<SVC_HANDLER, PEER_ACCEPTOR>::~ACE_Oneshot_Acceptor ()
950 ACE_TRACE ("ACE_Oneshot_Acceptor<SVC_HANDLER, PEER_ACCEPTOR>::~ACE_Oneshot_Acceptor");
951 this->handle_close ();
954 template <typename SVC_HANDLER, typename PEER_ACCEPTOR> int
955 ACE_Oneshot_Acceptor<SVC_HANDLER, PEER_ACCEPTOR>::close ()
957 ACE_TRACE ("ACE_Oneshot_Acceptor<SVC_HANDLER, PEER_ACCEPTOR>::close");
958 return this->handle_close ();
961 template <typename SVC_HANDLER, typename PEER_ACCEPTOR> int
962 ACE_Oneshot_Acceptor<SVC_HANDLER, PEER_ACCEPTOR>::handle_close (ACE_HANDLE,
963 ACE_Reactor_Mask)
965 ACE_TRACE ("ACE_Oneshot_Acceptor<SVC_HANDLER, PEER_ACCEPTOR>::handle_close");
967 // Guard against multiple closes.
968 if (this->delete_concurrency_strategy_)
970 delete this->concurrency_strategy_;
971 this->delete_concurrency_strategy_ = false;
972 this->concurrency_strategy_ = 0;
974 // Note that if we aren't actually registered with the
975 // ACE_Reactor then it's ok for this call to fail...
977 if (this->reactor ())
978 this->reactor ()->remove_handler
979 (this,
980 ACE_Event_Handler::ACCEPT_MASK | ACE_Event_Handler::DONT_CALL);
982 if (this->peer_acceptor_.close () == -1)
983 ACELIB_ERROR ((LM_ERROR,
984 ACE_TEXT ("close\n")));
985 return 0;
988 template <typename SVC_HANDLER, typename PEER_ACCEPTOR> int
989 ACE_Oneshot_Acceptor<SVC_HANDLER, PEER_ACCEPTOR>::handle_timeout
990 (const ACE_Time_Value &tv,
991 const void *arg)
993 ACE_TRACE ("ACE_Oneshot_Acceptor<SVC_HANDLER, PEER_ACCEPTOR>::handle_timeout");
994 errno = ETIME;
996 if (this->svc_handler_->handle_timeout (tv, arg) == -1)
997 this->svc_handler_->handle_close (this->svc_handler_->get_handle (),
998 ACE_Event_Handler::TIMER_MASK);
1000 // Since we aren't necessarily registered with the Reactor, don't
1001 // bother to check the return value here...
1002 if (this->reactor ())
1003 this->reactor ()->remove_handler (this,
1004 ACE_Event_Handler::ACCEPT_MASK);
1005 return 0;
1008 template <typename SVC_HANDLER, typename PEER_ACCEPTOR> int
1009 ACE_Oneshot_Acceptor<SVC_HANDLER, PEER_ACCEPTOR>::cancel ()
1011 ACE_TRACE ("ACE_Oneshot_Acceptor<SVC_HANDLER, PEER_ACCEPTOR>::cancel");
1012 return this->reactor () && this->reactor ()->cancel_timer (this);
1015 template <typename SVC_HANDLER, typename PEER_ACCEPTOR> int
1016 ACE_Oneshot_Acceptor<SVC_HANDLER, PEER_ACCEPTOR>::register_handler
1017 (SVC_HANDLER *svc_handler,
1018 const ACE_Synch_Options &synch_options,
1019 bool restart)
1021 ACE_TRACE ("ACE_Oneshot_Acceptor<SVC_HANDLER, PEER_ACCEPTOR>::register_handler");
1022 // Can't do this if we don't have a Reactor.
1023 if (this->reactor () == 0)
1025 errno = EINVAL;
1026 return -1;
1028 else
1030 this->svc_handler_ = svc_handler;
1031 this->restart_ = restart;
1032 ACE_Time_Value *tv = (ACE_Time_Value *) synch_options.time_value ();
1034 if (tv != 0
1035 && this->reactor ()->schedule_timer (this,
1036 synch_options.arg (),
1037 *tv) == -1)
1038 return -1;
1039 else
1040 return this->reactor ()->register_handler
1041 (this,
1042 ACE_Event_Handler::ACCEPT_MASK);
1046 // Bridge method for activating a <svc_handler> with the appropriate
1047 // concurrency strategy. The default behavior of this method is to
1048 // activate the SVC_HANDLER by calling its open() method (which allows
1049 // the SVC_HANDLER to define its own concurrency strategy). However,
1050 // subclasses can override this strategy to do more sophisticated
1051 // concurrency activations (such as creating the SVC_HANDLER as an
1052 // "active object" via multi-threading or multi-processing).
1054 template <typename SVC_HANDLER, typename PEER_ACCEPTOR> int
1055 ACE_Oneshot_Acceptor<SVC_HANDLER, PEER_ACCEPTOR>::activate_svc_handler
1056 (SVC_HANDLER *svc_handler)
1058 ACE_TRACE ("ACE_Oneshot_Acceptor<SVC_HANDLER, PEER_ACCEPTOR>::activate_svc_handler");
1059 return this->concurrency_strategy_->activate_svc_handler
1060 (svc_handler,
1061 (void *) this);
1064 // Factors out the code shared between the <accept> and <handle_input>
1065 // methods.
1067 template <typename SVC_HANDLER, typename PEER_ACCEPTOR> int
1068 ACE_Oneshot_Acceptor<SVC_HANDLER, PEER_ACCEPTOR>::shared_accept
1069 (SVC_HANDLER *svc_handler,
1070 typename PEER_ACCEPTOR::PEER_ADDR *remote_addr,
1071 ACE_Time_Value *timeout,
1072 bool restart,
1073 bool reset_new_handle)
1075 ACE_TRACE ("ACE_Oneshot_Acceptor<SVC_HANDLER, PEER_ACCEPTOR>::shared_accept");
1076 if (svc_handler == 0)
1077 return -1;
1079 // Accept connection into the Svc_Handler.
1080 else if (this->peer_acceptor_.accept (svc_handler->peer (), // stream
1081 remote_addr, // remote address
1082 timeout, // timeout
1083 restart, // restart
1084 reset_new_handle // reset new handle
1085 ) == -1)
1087 // Check whether we just timed out or whether we failed...
1088 if (!(errno == EWOULDBLOCK || errno == ETIME))
1089 // Close down handler to avoid memory leaks.
1090 svc_handler->close (CLOSE_DURING_NEW_CONNECTION);
1091 return -1;
1093 // Activate the <svc_handler> using the designated concurrency
1094 // strategy (note that this method becomes responsible for handling
1095 // errors and freeing up the memory if things go awry...)
1096 else
1097 return this->activate_svc_handler (svc_handler);
1100 // Make a SVC_HANDLER, accept the connection into the SVC_HANDLER, and
1101 // then activate the SVC_HANDLER. Note that SVC_HANDLER::open()
1102 // decides what type of concurrency strategy to use.
1104 template <typename SVC_HANDLER, typename PEER_ACCEPTOR> int
1105 ACE_Oneshot_Acceptor<SVC_HANDLER, PEER_ACCEPTOR>::accept
1106 (SVC_HANDLER *svc_handler,
1107 typename PEER_ACCEPTOR::PEER_ADDR *remote_addr,
1108 const ACE_Synch_Options &synch_options,
1109 bool restart,
1110 bool reset_new_handle)
1112 ACE_TRACE ("ACE_Oneshot_Acceptor<SVC_HANDLER, PEER_ACCEPTOR>::accept");
1113 // Note that if timeout == ACE_Time_Value (x, y) where (x > 0 || y >
1114 // 0) then this->connector_.connect() will block synchronously. If
1115 // <use_reactor> is set then we don't want this to happen (since we
1116 // want the ACE_Reactor to do the timeout asynchronously).
1117 // Therefore, we'll force this->connector_ to use ACE_Time_Value (0,
1118 // 0) in this case...
1120 ACE_Time_Value *timeout;
1121 int const use_reactor = synch_options[ACE_Synch_Options::USE_REACTOR];
1123 if (use_reactor)
1124 timeout = (ACE_Time_Value *) &ACE_Time_Value::zero;
1125 else
1126 timeout = (ACE_Time_Value *) synch_options.time_value ();
1128 if (this->shared_accept (svc_handler, // stream
1129 remote_addr, // remote address
1130 timeout, // timeout
1131 restart, // restart
1132 reset_new_handle // reset new handler
1133 ) == -1)
1135 if (use_reactor && errno == EWOULDBLOCK)
1136 // We couldn't accept right away, so let's wait in the
1137 // <ACE_Reactor>.
1138 this->register_handler (svc_handler,
1139 synch_options,
1140 restart);
1141 return -1;
1143 return 0;
1146 // Accepts one pending connection from a client (since we're the
1147 // "oneshot" Acceptor).
1149 template <typename SVC_HANDLER, typename PEER_ACCEPTOR> int
1150 ACE_Oneshot_Acceptor<SVC_HANDLER, PEER_ACCEPTOR>::handle_input (ACE_HANDLE)
1152 ACE_TRACE ("ACE_Oneshot_Acceptor<SVC_HANDLER, PEER_ACCEPTOR>::handle_input");
1153 int result = 0;
1155 // Cancel any timer that might be pending.
1156 this->cancel ();
1158 // Try to find out if the implementation of the reactor that we are
1159 // using requires us to reset the event association for the newly
1160 // created handle. This is because the newly created handle will
1161 // inherit the properties of the listen handle, including its event
1162 // associations.
1163 ACE_Reactor *reactor = this->reactor ();
1164 bool reset_new_handle = false;
1166 // There is a use-case whereby this object will be gone upon return
1167 // from shared_accept - if the Svc_Handler deletes this Oneshot_Acceptor
1168 // during the shared_accept/activation steps. So, do whatever we need
1169 // to do with this object before calling shared_accept.
1170 if (reactor)
1172 reset_new_handle = reactor->uses_event_associations ();
1173 reactor->remove_handler
1174 (this,
1175 ACE_Event_Handler::ACCEPT_MASK | ACE_Event_Handler::DONT_CALL);
1178 if (this->shared_accept (this->svc_handler_, // stream
1179 0, // remote address
1180 0, // timeout
1181 this->restart_, // restart
1182 reset_new_handle // reset new handle
1183 ) == -1)
1184 result = -1;
1186 return result;
1189 // Hook called by the explicit dynamic linking facility.
1191 template <typename SVC_HANDLER, typename PEER_ACCEPTOR> int
1192 ACE_Oneshot_Acceptor<SVC_HANDLER, PEER_ACCEPTOR>::init (int, ACE_TCHAR *[])
1194 ACE_TRACE ("ACE_Oneshot_Acceptor<SVC_HANDLER, PEER_ACCEPTOR>::init");
1195 return -1;
1198 template <typename SVC_HANDLER, typename PEER_ACCEPTOR> int
1199 ACE_Oneshot_Acceptor<SVC_HANDLER, PEER_ACCEPTOR>::fini ()
1201 ACE_TRACE ("ACE_Oneshot_Acceptor<SVC_HANDLER, PEER_ACCEPTOR>::fini");
1202 return this->handle_close ();
1205 template <typename SVC_HANDLER, typename PEER_ACCEPTOR> int
1206 ACE_Oneshot_Acceptor<SVC_HANDLER, PEER_ACCEPTOR>::info (ACE_TCHAR **strp,
1207 size_t length) const
1209 ACE_TRACE ("ACE_Oneshot_Acceptor<SVC_HANDLER, PEER_ACCEPTOR>::info");
1210 ACE_TCHAR buf[BUFSIZ];
1211 ACE_TCHAR addr_str[BUFSIZ];
1212 typename PEER_ACCEPTOR::PEER_ADDR addr;
1214 if (this->peer_acceptor_.get_local_addr (addr) == -1)
1215 return -1;
1216 else if (addr.addr_to_string (addr_str, sizeof addr_str) == -1)
1217 return -1;
1219 ACE_OS::snprintf (buf, BUFSIZ,
1220 ACE_TEXT ("%s\t %s %s"),
1221 ACE_TEXT ("ACE_Oneshot_Acceptor"),
1222 addr_str,
1223 ACE_TEXT ("#oneshot acceptor factory\n"));
1225 if (*strp == 0 && (*strp = ACE_OS::strdup (buf)) == 0)
1226 return -1;
1227 else
1228 ACE_OS::strsncpy (*strp, buf, length);
1229 return static_cast<int> (ACE_OS::strlen (buf));
1232 template <typename SVC_HANDLER, typename PEER_ACCEPTOR> int
1233 ACE_Oneshot_Acceptor<SVC_HANDLER, PEER_ACCEPTOR>::suspend ()
1235 ACE_TRACE ("ACE_Oneshot_Acceptor<SVC_HANDLER, PEER_ACCEPTOR>::suspend");
1236 return this->reactor () && this->reactor ()->suspend_handler (this);
1239 template <typename SVC_HANDLER, typename PEER_ACCEPTOR> int
1240 ACE_Oneshot_Acceptor<SVC_HANDLER, PEER_ACCEPTOR>::resume ()
1242 ACE_TRACE ("ACE_Oneshot_Acceptor<SVC_HANDLER, PEER_ACCEPTOR>::resume");
1243 return this->reactor () && this->reactor ()->resume_handler (this);
1246 // Returns ACE_HANDLE of the underlying peer_acceptor.
1248 template <typename SVC_HANDLER, typename PEER_ACCEPTOR> ACE_HANDLE
1249 ACE_Oneshot_Acceptor<SVC_HANDLER, PEER_ACCEPTOR>::get_handle () const
1251 ACE_TRACE ("ACE_Oneshot_Acceptor<SVC_HANDLER, PEER_ACCEPTOR>::get_handle");
1252 return this->peer_acceptor_.get_handle ();
1255 template <typename SVC_HANDLER, typename PEER_ACCEPTOR> PEER_ACCEPTOR &
1256 ACE_Oneshot_Acceptor<SVC_HANDLER, PEER_ACCEPTOR>::acceptor () const
1258 ACE_TRACE ("ACE_Oneshot_Acceptor<SVC_HANDLER, PEER_ACCEPTOR>::acceptor");
1259 return (PEER_ACCEPTOR &) this->peer_acceptor_;
1262 template <typename SVC_HANDLER, typename PEER_ACCEPTOR>
1263 ACE_Oneshot_Acceptor<SVC_HANDLER, PEER_ACCEPTOR>::operator PEER_ACCEPTOR & () const
1265 ACE_TRACE ("ACE_Oneshot_Acceptor<SVC_HANDLER, PEER_ACCEPTOR>::operator PEER_ACCEPTOR &");
1266 return (PEER_ACCEPTOR &) this->peer_acceptor_;
1269 ACE_END_VERSIONED_NAMESPACE_DECL
1271 #endif /* ACE_ACCEPTOR_CPP */