[6916] Fixed typos in spell checking code.
[getmangos.git] / dep / ACE_wrappers / ace / Acceptor.cpp
blob1ba51af5e5aab87f7cf5b80807186f7e063d4b74
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/Handle_Set.h"
12 #include "ace/Svc_Handler.h"
13 #include "ace/WFMO_Reactor.h"
14 #include "ace/OS_NS_stdio.h"
15 #include "ace/OS_NS_string.h"
16 #include "ace/OS_NS_sys_select.h"
18 ACE_RCSID (ace,
19 Acceptor,
20 "$Id: Acceptor.cpp 81991 2008-06-16 19:05:40Z elliott_c $")
22 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
24 ACE_ALLOC_HOOK_DEFINE(ACE_Acceptor)
26 template <class SVC_HANDLER, ACE_PEER_ACCEPTOR_1> void
27 ACE_Acceptor<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::dump (void) const
29 #if defined (ACE_HAS_DUMP)
30 ACE_TRACE ("ACE_Acceptor<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::dump");
32 ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this));
33 this->peer_acceptor_.dump ();
34 ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP));
35 #endif /* ACE_HAS_DUMP */
38 template <class SVC_HANDLER, ACE_PEER_ACCEPTOR_1>
39 ACE_Acceptor<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::operator ACE_PEER_ACCEPTOR & () const
41 ACE_TRACE ("ACE_Acceptor<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::operator ACE_PEER_ACCEPTOR &");
42 return (ACE_PEER_ACCEPTOR &) this->peer_acceptor_;
45 template <class SVC_HANDLER, ACE_PEER_ACCEPTOR_1> ACE_PEER_ACCEPTOR &
46 ACE_Acceptor<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::acceptor (void) const
48 ACE_TRACE ("ACE_Acceptor<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::acceptor");
49 return const_cast<ACE_PEER_ACCEPTOR &> (this->peer_acceptor_);
52 // Returns ACE_HANDLE of the underlying Acceptor_Strategy.
54 template <class SVC_HANDLER, ACE_PEER_ACCEPTOR_1> ACE_HANDLE
55 ACE_Acceptor<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::get_handle (void) const
57 ACE_TRACE ("ACE_Acceptor<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::get_handle");
58 return this->peer_acceptor_.get_handle ();
61 // Initialize the appropriate strategies for creation, passive
62 // connection acceptance, and concurrency, and then register <this>
63 // with the Reactor and listen for connection requests at the
64 // designated <local_addr>.
66 template <class SVC_HANDLER, ACE_PEER_ACCEPTOR_1> int
67 ACE_Acceptor<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::open
68 (const ACE_PEER_ACCEPTOR_ADDR &local_addr,
69 ACE_Reactor *reactor,
70 int flags,
71 int use_select,
72 int reuse_addr)
74 ACE_TRACE ("ACE_Acceptor<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::open");
75 this->flags_ = flags;
76 this->use_select_ = use_select;
77 this->reuse_addr_ = reuse_addr;
78 this->peer_acceptor_addr_ = local_addr;
80 // Must supply a valid Reactor to Acceptor::open()...
82 if (reactor == 0)
84 errno = EINVAL;
85 return -1;
88 if (this->peer_acceptor_.open (local_addr, reuse_addr) == -1)
89 return -1;
91 // Set the peer acceptor's handle into non-blocking mode. This is a
92 // safe-guard against the race condition that can otherwise occur
93 // between the time when <select> indicates that a passive-mode
94 // socket handle is "ready" and when we call <accept>. During this
95 // interval, the client can shutdown the connection, in which case,
96 // the <accept> call can hang!
97 (void) this->peer_acceptor_.enable (ACE_NONBLOCK);
99 int const result = reactor->register_handler (this,
100 ACE_Event_Handler::ACCEPT_MASK);
101 if (result != -1)
102 this->reactor (reactor);
103 else
104 this->peer_acceptor_.close ();
106 return result;
109 // Simple constructor.
111 template <class SVC_HANDLER, ACE_PEER_ACCEPTOR_1>
112 ACE_Acceptor<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::ACE_Acceptor (ACE_Reactor *reactor,
113 int use_select)
114 :flags_ (0),
115 use_select_ (use_select),
116 reuse_addr_ (1)
118 ACE_TRACE ("ACE_Acceptor<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::ACE_Acceptor");
120 this->reactor (reactor);
123 template <class SVC_HANDLER, ACE_PEER_ACCEPTOR_1>
124 ACE_Acceptor<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::ACE_Acceptor
125 (const ACE_PEER_ACCEPTOR_ADDR &addr,
126 ACE_Reactor *reactor,
127 int flags,
128 int use_select,
129 int reuse_addr)
131 ACE_TRACE ("ACE_Acceptor<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::ACE_Acceptor");
133 if (this->open (addr,
134 reactor,
135 flags,
136 use_select,
137 reuse_addr) == -1)
138 ACE_ERROR ((LM_ERROR,
139 ACE_TEXT ("%p\n"),
140 ACE_TEXT ("ACE_Acceptor::ACE_Acceptor")));
143 template <class SVC_HANDLER, ACE_PEER_ACCEPTOR_1>
144 ACE_Acceptor<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::~ACE_Acceptor (void)
146 ACE_TRACE ("ACE_Acceptor<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::~ACE_Acceptor");
147 this->handle_close ();
150 template <class SVC_HANDLER, ACE_PEER_ACCEPTOR_1> int
151 ACE_Acceptor<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::fini (void)
153 ACE_TRACE ("ACE_Acceptor<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::fini");
154 return ACE_Acceptor<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::handle_close ();
157 // Hook called by the explicit dynamic linking facility.
159 template <class SVC_HANDLER, ACE_PEER_ACCEPTOR_1> int
160 ACE_Acceptor<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::init (int, ACE_TCHAR *[])
162 ACE_TRACE ("ACE_Acceptor<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::init");
163 return -1;
166 template <class SVC_HANDLER, ACE_PEER_ACCEPTOR_1> int
167 ACE_Acceptor<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::info (ACE_TCHAR **strp,
168 size_t length) const
170 ACE_TRACE ("ACE_Acceptor<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::info");
171 ACE_TCHAR buf[BUFSIZ];
172 ACE_TCHAR addr_str[BUFSIZ];
173 ACE_PEER_ACCEPTOR_ADDR addr;
175 if (this->acceptor ().get_local_addr (addr) == -1)
176 return -1;
177 else if (addr.addr_to_string (addr_str, sizeof addr_str) == -1)
178 return -1;
180 ACE_OS::sprintf (buf,
181 ACE_TEXT ("%s\t %s %s"),
182 ACE_TEXT ("ACE_Acceptor"),
183 addr_str,
184 ACE_TEXT ("# acceptor factory\n"));
186 if (*strp == 0 && (*strp = ACE_OS::strdup (buf)) == 0)
187 return -1;
188 else
189 ACE_OS::strsncpy (*strp, buf, length);
190 return static_cast<int> (ACE_OS::strlen (buf));
193 template <class SVC_HANDLER, ACE_PEER_ACCEPTOR_1> int
194 ACE_Acceptor<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::suspend (void)
196 ACE_TRACE ("ACE_Acceptor<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::suspend");
197 return this->reactor ()->suspend_handler (this);
200 template <class SVC_HANDLER, ACE_PEER_ACCEPTOR_1> int
201 ACE_Acceptor<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::resume (void)
203 ACE_TRACE ("ACE_Acceptor<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::resume");
204 return this->reactor ()->resume_handler (this);
207 // Perform termination activities when <this> is removed from the
208 // <reactor>.
210 template <class SVC_HANDLER, ACE_PEER_ACCEPTOR_1> int
211 ACE_Acceptor<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::close (void)
213 ACE_TRACE ("ACE_Acceptor<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::close");
214 return this->handle_close ();
217 template <class SVC_HANDLER, ACE_PEER_ACCEPTOR_1> int
218 ACE_Acceptor<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::handle_accept_error (void)
220 ACE_TRACE ("ACE_Acceptor<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::handle_accept_error");
221 return 0;
224 template <class SVC_HANDLER, ACE_PEER_ACCEPTOR_1> int
225 ACE_Acceptor<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::handle_close (ACE_HANDLE,
226 ACE_Reactor_Mask)
228 ACE_TRACE ("ACE_Acceptor<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::handle_close");
229 // Guard against multiple closes.
230 if (this->reactor () != 0)
232 ACE_HANDLE handle = this->get_handle ();
234 this->reactor ()->remove_handler
235 (handle,
236 // We must pass the DONT_CALL flag here to avoid infinite
237 // recursion.
238 ACE_Event_Handler::ACCEPT_MASK | ACE_Event_Handler::DONT_CALL);
240 // Shut down the listen socket to recycle the handles.
241 if (this->peer_acceptor_.close () == -1)
242 ACE_ERROR ((LM_ERROR,
243 ACE_TEXT ("close\n")));
244 // Set the Reactor to 0 so that we don't try to close down
245 // again.
246 this->reactor (0);
248 return 0;
251 // Bridge method for creating a SVC_HANDLER. The strategy for
252 // creating a SVC_HANDLER are configured into the Acceptor via it's
253 // <creation_strategy_>. The default is to create a new SVC_HANDLER.
254 // However, subclasses can override this strategy to perform
255 // SVC_HANDLER creation in any way that they like (such as creating
256 // subclass instances of SVC_HANDLER, using a singleton, dynamically
257 // linking the handler, etc.).
259 template <class SVC_HANDLER, ACE_PEER_ACCEPTOR_1> int
260 ACE_Acceptor<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::make_svc_handler (SVC_HANDLER *&sh)
262 ACE_TRACE ("ACE_Acceptor<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::make_svc_handler");
264 if (sh == 0)
265 ACE_NEW_RETURN (sh,
266 SVC_HANDLER,
267 -1);
269 // Set the reactor of the newly created <SVC_HANDLER> to the same
270 // reactor that this <ACE_Acceptor> is using.
271 sh->reactor (this->reactor ());
272 return 0;
275 // Bridge method for accepting the new connection into the
276 // <svc_handler>. The default behavior delegates to the
277 // <PEER_ACCEPTOR::accept> in the Acceptor_Strategy.
279 template <class SVC_HANDLER, ACE_PEER_ACCEPTOR_1> int
280 ACE_Acceptor<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::accept_svc_handler
281 (SVC_HANDLER *svc_handler)
283 ACE_TRACE ("ACE_Acceptor<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::accept_svc_handler");
285 // Try to find out if the implementation of the reactor that we are
286 // using requires us to reset the event association for the newly
287 // created handle. This is because the newly created handle will
288 // inherit the properties of the listen handle, including its event
289 // associations.
290 int reset_new_handle = this->reactor ()->uses_event_associations ();
292 if (this->acceptor ().accept (svc_handler->peer (), // stream
293 0, // remote address
294 0, // timeout
295 1, // restart
296 reset_new_handle // reset new handler
297 ) == -1)
299 // Ensure that errno is preserved in case the svc_handler
300 // close() method resets it
301 ACE_Errno_Guard error(errno);
303 // Close down handler to avoid memory leaks.
304 svc_handler->close (CLOSE_DURING_NEW_CONNECTION);
306 return -1;
308 else
309 return 0;
312 // Bridge method for activating a <svc_handler> with the appropriate
313 // concurrency strategy. The default behavior of this method is to
314 // activate the SVC_HANDLER by calling its open() method (which allows
315 // the SVC_HANDLER to define its own concurrency strategy). However,
316 // subclasses can override this strategy to do more sophisticated
317 // concurrency activations (such as creating the SVC_HANDLER as an
318 // "active object" via multi-threading or multi-processing).
320 template <class SVC_HANDLER, ACE_PEER_ACCEPTOR_1> int
321 ACE_Acceptor<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::activate_svc_handler
322 (SVC_HANDLER *svc_handler)
324 ACE_TRACE ("ACE_Acceptor<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::activate_svc_handler");
326 int result = 0;
328 // See if we should enable non-blocking I/O on the <svc_handler>'s
329 // peer.
330 if (ACE_BIT_ENABLED (this->flags_,
331 ACE_NONBLOCK))
333 if (svc_handler->peer ().enable (ACE_NONBLOCK) == -1)
334 result = -1;
336 // Otherwise, make sure it's disabled by default.
337 else if (svc_handler->peer ().disable (ACE_NONBLOCK) == -1)
338 result = -1;
340 if (result == 0 && svc_handler->open ((void *) this) == -1)
341 result = -1;
343 if (result == -1)
344 // The connection was already made; so this close is a "normal" close
345 // operation.
346 svc_handler->close (NORMAL_CLOSE_OPERATION);
348 return result;
351 // Template Method that makes a SVC_HANDLER (using the appropriate
352 // creation strategy), accept the connection into the SVC_HANDLER, and
353 // then activate the SVC_HANDLER.
355 template <class SVC_HANDLER, ACE_PEER_ACCEPTOR_1> int
356 ACE_Acceptor<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::handle_input (ACE_HANDLE listener)
358 ACE_TRACE ("ACE_Acceptor<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::handle_input");
359 ACE_Handle_Set conn_handle;
361 // Default is "timeout (0, 0)," which means "poll."
362 ACE_Time_Value timeout;
363 # if defined (ACE_WIN32)
364 // This arg is ignored on Windows and causes pointer truncation
365 // warnings on 64-bit compiles
366 int select_width = 0;
367 # else
368 int select_width = int (listener) + 1;
369 # endif /* ACE_WIN32 */
371 // Accept connections from clients. Note that a loop is used for two
372 // reasons:
374 // 1. It allows us to accept all pending connections without an
375 // extra trip through the ACE_Reactor and without having to use
376 // non-blocking I/O...
378 // 2. It allows the TLI_SAP::ACE_Acceptor class to work correctly (don't
379 // ask -- TLI is *horrible*...).
381 // @@ What should we do if any of the substrategies fail? Right
382 // now, we just print out a diagnostic message if <ACE::debug>
383 // returns > 0 and return 0 (which means that the Acceptor remains
384 // registered with the Reactor)...
387 // Create a service handler, using the appropriate creation
388 // strategy.
390 SVC_HANDLER *svc_handler = 0;
392 if (this->make_svc_handler (svc_handler) == -1)
394 if (ACE::debug ())
395 ACE_DEBUG ((LM_DEBUG,
396 ACE_TEXT ("%p\n"),
397 ACE_TEXT ("make_svc_handler")));
398 return 0;
400 // Accept connection into the Svc_Handler.
401 else if (this->accept_svc_handler (svc_handler) == -1)
403 // Note that <accept_svc_handler> closes the <svc_handler>
404 // on failure.
405 if (ACE::debug ())
406 ACE_DEBUG ((LM_DEBUG,
407 ACE_TEXT ("%p\n"),
408 ACE_TEXT ("accept_svc_handler")));
409 return this->handle_accept_error ();
411 // Activate the <svc_handler> using the designated concurrency
412 // strategy (note that this method becomes responsible for
413 // handling errors and freeing up the memory if things go
414 // awry...).
415 else if (this->activate_svc_handler (svc_handler) == -1)
417 // Note that <activate_svc_handler> closes the <svc_handler>
418 // on failure.
420 if (ACE::debug ())
421 ACE_DEBUG ((LM_DEBUG,
422 ACE_TEXT ("%p\n"),
423 ACE_TEXT ("activate_svc_handler")));
424 return 0;
427 conn_handle.set_bit (listener);
430 // Now, check to see if there is another connection pending and
431 // break out of the loop if there is none.
432 while (this->use_select_
433 && ACE_OS::select (select_width,
434 conn_handle,
437 &timeout) == 1);
438 return 0;
441 ACE_ALLOC_HOOK_DEFINE(ACE_Strategy_Acceptor)
443 template <class SVC_HANDLER, ACE_PEER_ACCEPTOR_1> int
444 ACE_Strategy_Acceptor<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::suspend (void)
446 ACE_TRACE ("ACE_Strategy_Acceptor<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::suspend");
448 // First suspend the SVC_HANDLER's we've created.
449 if (this->scheduling_strategy_->suspend () == -1)
450 return -1;
451 else // Then suspend ourselves.
452 return ACE_Acceptor<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::suspend ();
455 template <class SVC_HANDLER, ACE_PEER_ACCEPTOR_1> int
456 ACE_Strategy_Acceptor<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::resume (void)
458 ACE_TRACE ("ACE_Strategy_Acceptor<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::resume");
460 // First resume ourselves.
461 if (ACE_Acceptor<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::resume () == -1)
462 return -1;
463 else // Then resume the SVC_HANDLER's we've created.
464 return this->scheduling_strategy_->resume ();
467 template <class SVC_HANDLER, ACE_PEER_ACCEPTOR_1> void
468 ACE_Strategy_Acceptor<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::dump (void) const
470 #if defined (ACE_HAS_DUMP)
471 ACE_TRACE ("ACE_Strategy_Acceptor<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::dump");
473 ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this));
474 ACE_Acceptor<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::dump ();
475 this->creation_strategy_->dump ();
476 ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("delete_creation_strategy_ = %d"), delete_creation_strategy_));
477 this->accept_strategy_->dump ();
478 ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("delete_accept_strategy_ = %d"), delete_accept_strategy_));
479 this->concurrency_strategy_->dump ();
480 ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("delete_concurrency_strategy_ = %d"), delete_concurrency_strategy_));
481 this->scheduling_strategy_->dump ();
482 ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("delete_scheduling_strategy_ = %d"), delete_scheduling_strategy_));
483 ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\nservice_name_ = %s"),
484 this->service_name_ == 0 ? ACE_TEXT ("<unknown>") : this->service_name_));
485 ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\nservice_description_ = %s"),
486 this->service_description_ == 0 ? ACE_TEXT ("<unknown>") : this->service_description_));
487 this->service_addr_.dump ();
488 ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP));
489 #endif /* ACE_HAS_DUMP */
492 template <class SVC_HANDLER, ACE_PEER_ACCEPTOR_1> ACE_PEER_ACCEPTOR &
493 ACE_Strategy_Acceptor<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::acceptor (void) const
495 ACE_TRACE ("ACE_Strategy_Acceptor<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::acceptor");
496 return this->accept_strategy_->acceptor ();
499 template <class SVC_HANDLER, ACE_PEER_ACCEPTOR_1>
500 ACE_Strategy_Acceptor<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::operator ACE_PEER_ACCEPTOR & () const
502 ACE_TRACE ("ACE_Strategy_Acceptor<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::operator ACE_PEER_ACCEPTOR &");
503 return this->accept_strategy_->acceptor ();
506 // Returns ACE_HANDLE of the underlying Acceptor_Strategy.
508 template <class SVC_HANDLER, ACE_PEER_ACCEPTOR_1> ACE_HANDLE
509 ACE_Strategy_Acceptor<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::get_handle (void) const
511 ACE_TRACE ("ACE_Strategy_Acceptor<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::get_handle");
512 return this->accept_strategy_->get_handle ();
515 // Initialize the appropriate strategies for creation, passive
516 // connection acceptance, and concurrency, and then register <this>
517 // with the Reactor and listen for connection requests at the
518 // designated <local_addr>.
519 template <class SVC_HANDLER, ACE_PEER_ACCEPTOR_1> int
520 ACE_Strategy_Acceptor<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::open
521 (const ACE_PEER_ACCEPTOR_ADDR &local_addr,
522 ACE_Reactor *reactor,
523 int /* flags unused */,
524 int use_select,
525 int reuse_addr)
527 ACE_TRACE ("ACE_Strategy_Acceptor<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::open");
528 return this->open
529 (local_addr, reactor, 0, 0, 0, 0, 0, 0, use_select, reuse_addr);
533 template <class SVC_HANDLER, ACE_PEER_ACCEPTOR_1> int
534 ACE_Strategy_Acceptor<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::open
535 (const ACE_PEER_ACCEPTOR_ADDR &local_addr,
536 ACE_Reactor *reactor,
537 ACE_Creation_Strategy<SVC_HANDLER> *cre_s,
538 ACE_Accept_Strategy<SVC_HANDLER, ACE_PEER_ACCEPTOR_2> *acc_s,
539 ACE_Concurrency_Strategy<SVC_HANDLER> *con_s,
540 ACE_Scheduling_Strategy<SVC_HANDLER> *sch_s,
541 const ACE_TCHAR *service_name,
542 const ACE_TCHAR *service_description,
543 int use_select,
544 int reuse_addr)
546 ACE_TRACE ("ACE_Strategy_Acceptor<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::open");
548 if (this->service_name_ == 0 && service_name != 0)
549 ACE_ALLOCATOR_RETURN (this->service_name_,
550 ACE_OS::strdup (service_name),
551 -1);
552 if (this->service_description_ == 0 && service_description != 0)
553 ACE_ALLOCATOR_RETURN (this->service_description_,
554 ACE_OS::strdup (service_description),
555 -1);
556 this->reactor (reactor);
558 // Must supply a valid Reactor to Acceptor::open()...
559 if (reactor == 0)
561 errno = EINVAL;
562 return -1;
565 // Initialize the creation strategy.
567 if (cre_s == 0)
569 ACE_NEW_RETURN (cre_s,
570 CREATION_STRATEGY,
571 -1);
572 this->delete_creation_strategy_ = true;
574 this->creation_strategy_ = cre_s;
576 // Initialize the accept strategy.
578 if (acc_s == 0)
580 ACE_NEW_RETURN (acc_s,
581 ACCEPT_STRATEGY (this->reactor ()),
582 -1);
583 this->delete_accept_strategy_ = true;
585 this->accept_strategy_ = acc_s;
587 if (this->accept_strategy_->open (local_addr, reuse_addr) == -1)
588 return -1;
590 // Set the peer acceptor's handle into non-blocking mode. This is a
591 // safe-guard against the race condition that can otherwise occur
592 // between the time when <select> indicates that a passive-mode
593 // socket handle is "ready" and when we call <accept>. During this
594 // interval, the client can shutdown the connection, in which case,
595 // the <accept> call can hang!
596 if (this->accept_strategy_->acceptor ().enable (ACE_NONBLOCK) != 0)
597 return -1;
599 // Initialize the concurrency strategy.
601 if (con_s == 0)
603 ACE_NEW_RETURN (con_s,
604 CONCURRENCY_STRATEGY,
605 -1);
606 this->delete_concurrency_strategy_ = true;
608 this->concurrency_strategy_ = con_s;
610 // Initialize the scheduling strategy.
612 if (sch_s == 0)
614 ACE_NEW_RETURN (sch_s,
615 SCHEDULING_STRATEGY,
616 -1);
617 this->delete_scheduling_strategy_ = true;
619 this->scheduling_strategy_ = sch_s;
621 this->use_select_ = use_select;
623 return this->reactor ()->register_handler
624 (this,
625 ACE_Event_Handler::ACCEPT_MASK);
628 // Simple constructor.
630 template <class SVC_HANDLER, ACE_PEER_ACCEPTOR_1>
631 ACE_Strategy_Acceptor<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::ACE_Strategy_Acceptor
632 (const ACE_TCHAR service_name[],
633 const ACE_TCHAR service_description[],
634 int use_select,
635 int reuse_addr)
636 : creation_strategy_ (0),
637 delete_creation_strategy_ (false),
638 accept_strategy_ (0),
639 delete_accept_strategy_ (false),
640 concurrency_strategy_ (0),
641 delete_concurrency_strategy_ (false),
642 scheduling_strategy_ (0),
643 delete_scheduling_strategy_ (false),
644 service_name_ (0),
645 service_description_ (0)
647 ACE_TRACE ("ACE_Strategy_Acceptor<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::ACE_Strategy_Acceptor");
649 if (service_name != 0)
650 ACE_ALLOCATOR (this->service_name_,
651 ACE_OS::strdup (service_name));
652 if (service_description != 0)
653 ACE_ALLOCATOR (this->service_description_,
654 ACE_OS::strdup (service_description));
655 this->use_select_ = use_select;
656 this->reuse_addr_ = reuse_addr;
659 template <class SVC_HANDLER, ACE_PEER_ACCEPTOR_1>
660 ACE_Strategy_Acceptor<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::ACE_Strategy_Acceptor
661 (const ACE_PEER_ACCEPTOR_ADDR &addr,
662 ACE_Reactor *reactor,
663 ACE_Creation_Strategy<SVC_HANDLER> *cre_s,
664 ACE_Accept_Strategy<SVC_HANDLER, ACE_PEER_ACCEPTOR_2> *acc_s,
665 ACE_Concurrency_Strategy<SVC_HANDLER> *con_s,
666 ACE_Scheduling_Strategy<SVC_HANDLER> *sch_s,
667 const ACE_TCHAR service_name[],
668 const ACE_TCHAR service_description[],
669 int use_select,
670 int reuse_addr)
671 : creation_strategy_ (0),
672 delete_creation_strategy_ (false),
673 accept_strategy_ (0),
674 delete_accept_strategy_ (false),
675 concurrency_strategy_ (0),
676 delete_concurrency_strategy_ (false),
677 scheduling_strategy_ (0),
678 delete_scheduling_strategy_ (false),
679 service_name_ (0),
680 service_description_ (0)
682 ACE_TRACE ("ACE_Strategy_Acceptor<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::ACE_Strategy_Acceptor");
684 if (this->open (addr,
685 reactor,
686 cre_s,
687 acc_s,
688 con_s,
689 sch_s,
690 service_name,
691 service_description,
692 use_select,
693 reuse_addr) == -1)
694 ACE_ERROR ((LM_ERROR,
695 ACE_TEXT ("%p\n"),
696 ACE_TEXT ("ACE_Strategy_Acceptor::ACE_Strategy_Acceptor")));
699 // Perform termination activities when <this> is removed from the
700 // <ACE_Reactor>.
702 template <class SVC_HANDLER, ACE_PEER_ACCEPTOR_1> int
703 ACE_Strategy_Acceptor<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::handle_close (ACE_HANDLE,
704 ACE_Reactor_Mask)
706 ACE_TRACE ("ACE_Strategy_Acceptor<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::handle_close");
707 // Guard against multiple closes.
708 if (this->reactor () != 0)
710 ACE_HANDLE handle = this->get_handle ();
712 if (this->delete_creation_strategy_)
713 delete this->creation_strategy_;
714 this->delete_creation_strategy_ = false;
715 this->creation_strategy_ = 0;
717 if (this->delete_accept_strategy_)
718 delete this->accept_strategy_;
719 this->delete_accept_strategy_ = false;
720 this->accept_strategy_ = 0;
722 if (this->delete_concurrency_strategy_)
723 delete this->concurrency_strategy_;
724 this->delete_concurrency_strategy_ = false;
725 this->concurrency_strategy_ = 0;
727 if (this->delete_scheduling_strategy_)
728 delete this->scheduling_strategy_;
729 this->delete_scheduling_strategy_ = false;
730 this->scheduling_strategy_ = 0;
732 // We must use the <handle> obtained *before* we deleted the
733 // accept_strategy_...
735 this->reactor ()->remove_handler
736 (handle,
737 ACE_Event_Handler::ACCEPT_MASK | ACE_Event_Handler::DONT_CALL);
739 // Set the Reactor to 0 so that we don't try to close down
740 // again.
741 this->reactor (0);
743 return 0;
746 // Bridge method for creating a <SVC_HANDLER>. The strategy for
747 // creating a <SVC_HANDLER> are configured into the Acceptor via it's
748 // <creation_strategy_>. The default is to create a new
749 // <SVC_HANDLER>. However, subclasses can override this strategy to
750 // perform <SVC_HANDLER> creation in any way that they like (such as
751 // creating subclass instances of <SVC_HANDLER>, using a singleton,
752 // dynamically linking the handler, etc.).
754 template <class SVC_HANDLER, ACE_PEER_ACCEPTOR_1> int
755 ACE_Strategy_Acceptor<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::make_svc_handler (SVC_HANDLER *&sh)
757 ACE_TRACE ("ACE_Strategy_Acceptor<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::make_svc_handler");
758 return this->creation_strategy_->make_svc_handler (sh);
761 // Bridge method for accepting the new connection into the
762 // <svc_handler>. The default behavior delegates to the
763 // <Strategy_Acceptor::accept> in the Acceptor_Strategy.
765 template <class SVC_HANDLER, ACE_PEER_ACCEPTOR_1> int
766 ACE_Strategy_Acceptor<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::accept_svc_handler
767 (SVC_HANDLER *svc_handler)
769 ACE_TRACE ("ACE_Strategy_Acceptor<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::accept_svc_handler");
770 return this->accept_strategy_->accept_svc_handler (svc_handler);
773 // Bridge method for activating a <svc_handler> with the appropriate
774 // concurrency strategy. The default behavior of this method is to
775 // activate the SVC_HANDLER by calling its open() method (which allows
776 // the SVC_HANDLER to define its own concurrency strategy). However,
777 // subclasses can override this strategy to do more sophisticated
778 // concurrency activations (such as creating the SVC_HANDLER as an
779 // "active object" via multi-threading or multi-processing).
781 template <class SVC_HANDLER, ACE_PEER_ACCEPTOR_1> int
782 ACE_Strategy_Acceptor<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::activate_svc_handler
783 (SVC_HANDLER *svc_handler)
785 ACE_TRACE ("ACE_Strategy_Acceptor<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::activate_svc_handler");
786 return this->concurrency_strategy_->activate_svc_handler
787 (svc_handler,
788 (void *) this);
791 template <class SVC_HANDLER, ACE_PEER_ACCEPTOR_1>
792 ACE_Strategy_Acceptor<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::~ACE_Strategy_Acceptor (void)
794 ACE_TRACE ("ACE_Strategy_Acceptor<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::~ACE_Strategy_Acceptor");
795 ACE_OS::free ((void *) this->service_name_);
796 ACE_OS::free ((void *) this->service_description_);
797 this->handle_close ();
800 // Signal the server to shutdown gracefully.
802 template <class SVC_HANDLER, ACE_PEER_ACCEPTOR_1> int
803 ACE_Strategy_Acceptor<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::handle_signal (int, siginfo_t *, ucontext_t *)
805 ACE_Reactor::instance()->end_reactor_event_loop ();
806 return 0;
809 template <class SVC_HANDLER, ACE_PEER_ACCEPTOR_1> int
810 ACE_Strategy_Acceptor<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::info (ACE_TCHAR **strp,
811 size_t length) const
813 ACE_TRACE ("ACE_Strategy_Acceptor::info");
815 ACE_TCHAR buf[BUFSIZ];
816 ACE_TCHAR service_addr_str[BUFSIZ];
817 ACE_PEER_ACCEPTOR_ADDR addr;
819 if (this->acceptor ().get_local_addr (addr) == -1)
820 return -1;
821 else if (addr.addr_to_string (service_addr_str,
822 sizeof service_addr_str) == -1)
823 return -1;
825 // @@ Should add the protocol in...
826 ACE_OS::sprintf (buf,
827 ACE_TEXT ("%s\t %s #%s\n"),
828 this->service_name_ == 0
829 ? ACE_TEXT ("<unknown>")
830 : this->service_name_,
831 service_addr_str,
832 this->service_description_ == 0
833 ? ACE_TEXT ("<unknown>")
834 : this->service_description_);
836 if (*strp == 0 && (*strp = ACE_OS::strdup (buf)) == 0)
837 return -1;
838 else
839 ACE_OS::strsncpy (*strp, buf, length);
840 return static_cast<int> (ACE_OS::strlen (buf));
843 template <class SVC_HANDLER, ACE_PEER_ACCEPTOR_1> int
844 ACE_Strategy_Acceptor<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::fini (void)
846 ACE_TRACE ("ACE_Strategy_Acceptor<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::fini");
847 return this->ACE_Strategy_Acceptor<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::handle_close ();
850 ACE_ALLOC_HOOK_DEFINE(ACE_Oneshot_Acceptor)
852 template <class SVC_HANDLER, ACE_PEER_ACCEPTOR_1> void
853 ACE_Oneshot_Acceptor<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::dump (void) const
855 #if defined (ACE_HAS_DUMP)
856 ACE_TRACE ("ACE_Oneshot_Acceptor<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::dump");
858 ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this));
859 ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\nsvc_handler_ = %x"), this->svc_handler_));
860 ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\nrestart_ = %d"), this->restart_));
861 this->peer_acceptor_.dump ();
862 ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("delete_concurrency_strategy_ = %d"),
863 delete_concurrency_strategy_));
864 this->concurrency_strategy_->dump ();
865 ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP));
866 #endif /* ACE_HAS_DUMP */
869 template <class SVC_HANDLER, ACE_PEER_ACCEPTOR_1> int
870 ACE_Oneshot_Acceptor<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::open
871 (const ACE_PEER_ACCEPTOR_ADDR &local_addr,
872 ACE_Reactor *reactor,
873 ACE_Concurrency_Strategy<SVC_HANDLER> *con_s)
875 ACE_TRACE ("ACE_Oneshot_Acceptor<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::open");
876 this->reactor (reactor);
878 // Initialize the concurrency strategy.
880 if (con_s == 0)
882 ACE_NEW_RETURN (con_s,
883 ACE_Concurrency_Strategy<SVC_HANDLER>,
884 -1);
885 this->delete_concurrency_strategy_ = true;
887 this->concurrency_strategy_ = con_s;
889 // Reuse the addr, even if it is already in use...!
890 return this->peer_acceptor_.open (local_addr, 1);
893 template <class SVC_HANDLER, ACE_PEER_ACCEPTOR_1>
894 ACE_Oneshot_Acceptor<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::ACE_Oneshot_Acceptor (void)
895 : delete_concurrency_strategy_ (false)
897 ACE_TRACE ("ACE_Oneshot_Acceptor<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::ACE_Oneshot_Acceptor");
898 this->reactor (0);
901 template <class SVC_HANDLER, ACE_PEER_ACCEPTOR_1>
902 ACE_Oneshot_Acceptor<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::ACE_Oneshot_Acceptor
903 (const ACE_PEER_ACCEPTOR_ADDR &local_addr,
904 ACE_Reactor *reactor,
905 ACE_Concurrency_Strategy<SVC_HANDLER> *cs)
906 : delete_concurrency_strategy_ (false)
908 ACE_TRACE ("ACE_Oneshot_Acceptor<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::ACE_Oneshot_Acceptor");
909 if (this->open (local_addr, reactor, cs) == -1)
910 ACE_ERROR ((LM_ERROR,
911 ACE_TEXT ("%p\n"),
912 ACE_TEXT ("ACE_Oneshot_Acceptor::ACE_Oneshot_Acceptor")));
915 template <class SVC_HANDLER, ACE_PEER_ACCEPTOR_1>
916 ACE_Oneshot_Acceptor<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::~ACE_Oneshot_Acceptor (void)
918 ACE_TRACE ("ACE_Oneshot_Acceptor<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::~ACE_Oneshot_Acceptor");
919 this->handle_close ();
922 template <class SVC_HANDLER, ACE_PEER_ACCEPTOR_1> int
923 ACE_Oneshot_Acceptor<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::close (void)
925 ACE_TRACE ("ACE_Oneshot_Acceptor<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::close");
926 return this->handle_close ();
929 template <class SVC_HANDLER, ACE_PEER_ACCEPTOR_1> int
930 ACE_Oneshot_Acceptor<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::handle_close (ACE_HANDLE,
931 ACE_Reactor_Mask)
933 ACE_TRACE ("ACE_Oneshot_Acceptor<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::handle_close");
935 // Guard against multiple closes.
936 if (this->delete_concurrency_strategy_)
938 delete this->concurrency_strategy_;
939 this->delete_concurrency_strategy_ = false;
940 this->concurrency_strategy_ = 0;
942 // Note that if we aren't actually registered with the
943 // ACE_Reactor then it's ok for this call to fail...
945 if (this->reactor ())
946 this->reactor ()->remove_handler
947 (this,
948 ACE_Event_Handler::ACCEPT_MASK | ACE_Event_Handler::DONT_CALL);
950 if (this->peer_acceptor_.close () == -1)
951 ACE_ERROR ((LM_ERROR,
952 ACE_TEXT ("close\n")));
953 return 0;
956 template <class SVC_HANDLER, ACE_PEER_ACCEPTOR_1> int
957 ACE_Oneshot_Acceptor<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::handle_timeout
958 (const ACE_Time_Value &tv,
959 const void *arg)
961 ACE_TRACE ("ACE_Oneshot_Acceptor<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::handle_timeout");
962 errno = ETIME;
964 if (this->svc_handler_->handle_timeout (tv, arg) == -1)
965 this->svc_handler_->handle_close (this->svc_handler_->get_handle (),
966 ACE_Event_Handler::TIMER_MASK);
968 // Since we aren't necessarily registered with the Reactor, don't
969 // bother to check the return value here...
970 if (this->reactor ())
971 this->reactor ()->remove_handler (this,
972 ACE_Event_Handler::ACCEPT_MASK);
973 return 0;
976 template <class SVC_HANDLER, ACE_PEER_ACCEPTOR_1> int
977 ACE_Oneshot_Acceptor<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::cancel (void)
979 ACE_TRACE ("ACE_Oneshot_Acceptor<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::cancel");
980 return this->reactor () && this->reactor ()->cancel_timer (this);
983 template <class SVC_HANDLER, ACE_PEER_ACCEPTOR_1> int
984 ACE_Oneshot_Acceptor<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::register_handler
985 (SVC_HANDLER *svc_handler,
986 const ACE_Synch_Options &synch_options,
987 int restart)
989 ACE_TRACE ("ACE_Oneshot_Acceptor<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::register_handler");
990 // Can't do this if we don't have a Reactor.
991 if (this->reactor () == 0)
993 errno = EINVAL;
994 return -1;
996 else
998 this->svc_handler_ = svc_handler;
999 this->restart_ = restart;
1000 ACE_Time_Value *tv = (ACE_Time_Value *) synch_options.time_value ();
1002 if (tv != 0
1003 && this->reactor ()->schedule_timer (this,
1004 synch_options.arg (),
1005 *tv) == 0)
1006 return -1;
1007 else
1008 return this->reactor ()->register_handler
1009 (this,
1010 ACE_Event_Handler::ACCEPT_MASK);
1014 // Bridge method for activating a <svc_handler> with the appropriate
1015 // concurrency strategy. The default behavior of this method is to
1016 // activate the SVC_HANDLER by calling its open() method (which allows
1017 // the SVC_HANDLER to define its own concurrency strategy). However,
1018 // subclasses can override this strategy to do more sophisticated
1019 // concurrency activations (such as creating the SVC_HANDLER as an
1020 // "active object" via multi-threading or multi-processing).
1022 template <class SVC_HANDLER, ACE_PEER_ACCEPTOR_1> int
1023 ACE_Oneshot_Acceptor<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::activate_svc_handler
1024 (SVC_HANDLER *svc_handler)
1026 ACE_TRACE ("ACE_Oneshot_Acceptor<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::activate_svc_handler");
1027 return this->concurrency_strategy_->activate_svc_handler
1028 (svc_handler,
1029 (void *) this);
1032 // Factors out the code shared between the <accept> and <handle_input>
1033 // methods.
1035 template <class SVC_HANDLER, ACE_PEER_ACCEPTOR_1> int
1036 ACE_Oneshot_Acceptor<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::shared_accept
1037 (SVC_HANDLER *svc_handler,
1038 ACE_PEER_ACCEPTOR_ADDR *remote_addr,
1039 ACE_Time_Value *timeout,
1040 int restart,
1041 int reset_new_handle)
1043 ACE_TRACE ("ACE_Oneshot_Acceptor<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::shared_accept");
1044 if (svc_handler == 0)
1045 return -1;
1047 // Accept connection into the Svc_Handler.
1048 else if (this->peer_acceptor_.accept (svc_handler->peer (), // stream
1049 remote_addr, // remote address
1050 timeout, // timeout
1051 restart, // restart
1052 reset_new_handle // reset new handle
1053 ) == -1)
1055 // Check whether we just timed out or whether we failed...
1056 if (!(errno == EWOULDBLOCK || errno == ETIME))
1057 // Close down handler to avoid memory leaks.
1058 svc_handler->close (CLOSE_DURING_NEW_CONNECTION);
1059 return -1;
1061 // Activate the <svc_handler> using the designated concurrency
1062 // strategy (note that this method becomes responsible for handling
1063 // errors and freeing up the memory if things go awry...)
1064 else
1065 return this->activate_svc_handler (svc_handler);
1068 // Make a SVC_HANDLER, accept the connection into the SVC_HANDLER, and
1069 // then activate the SVC_HANDLER. Note that SVC_HANDLER::open()
1070 // decides what type of concurrency strategy to use.
1072 template <class SVC_HANDLER, ACE_PEER_ACCEPTOR_1> int
1073 ACE_Oneshot_Acceptor<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::accept
1074 (SVC_HANDLER *svc_handler,
1075 ACE_PEER_ACCEPTOR_ADDR *remote_addr,
1076 const ACE_Synch_Options &synch_options,
1077 int restart,
1078 int reset_new_handle)
1080 ACE_TRACE ("ACE_Oneshot_Acceptor<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::accept");
1081 // Note that if timeout == ACE_Time_Value (x, y) where (x > 0 || y >
1082 // 0) then this->connector_.connect() will block synchronously. If
1083 // <use_reactor> is set then we don't want this to happen (since we
1084 // want the ACE_Reactor to do the timeout asynchronously).
1085 // Therefore, we'll force this->connector_ to use ACE_Time_Value (0,
1086 // 0) in this case...
1088 ACE_Time_Value *timeout;
1089 int use_reactor = synch_options[ACE_Synch_Options::USE_REACTOR];
1091 if (use_reactor)
1092 timeout = (ACE_Time_Value *) &ACE_Time_Value::zero;
1093 else
1094 timeout = (ACE_Time_Value *) synch_options.time_value ();
1096 if (this->shared_accept (svc_handler, // stream
1097 remote_addr, // remote address
1098 timeout, // timeout
1099 restart, // restart
1100 reset_new_handle // reset new handler
1101 ) == -1)
1103 if (use_reactor && errno == EWOULDBLOCK)
1104 // We couldn't accept right away, so let's wait in the
1105 // <ACE_Reactor>.
1106 this->register_handler (svc_handler,
1107 synch_options,
1108 restart);
1109 return -1;
1111 return 0;
1114 // Accepts one pending connection from a client (since we're the
1115 // "oneshot" Acceptor).
1117 template <class SVC_HANDLER, ACE_PEER_ACCEPTOR_1> int
1118 ACE_Oneshot_Acceptor<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::handle_input (ACE_HANDLE)
1120 ACE_TRACE ("ACE_Oneshot_Acceptor<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::handle_input");
1121 int result = 0;
1123 // Cancel any timer that might be pending.
1124 this->cancel ();
1126 // Try to find out if the implementation of the reactor that we are
1127 // using requires us to reset the event association for the newly
1128 // created handle. This is because the newly created handle will
1129 // inherit the properties of the listen handle, including its event
1130 // associations.
1131 int reset_new_handle = this->reactor ()->uses_event_associations ();
1133 // There is a use-case whereby this object will be gone upon return
1134 // from shared_accept - if the Svc_Handler deletes this Oneshot_Acceptor
1135 // during the shared_accept/activation steps. So, do whatever we need
1136 // to do with this object before calling shared_accept.
1137 if (this->reactor ())
1138 this->reactor ()->remove_handler
1139 (this,
1140 ACE_Event_Handler::ACCEPT_MASK | ACE_Event_Handler::DONT_CALL);
1142 if (this->shared_accept (this->svc_handler_, // stream
1143 0, // remote address
1144 0, // timeout
1145 this->restart_, // restart
1146 reset_new_handle // reset new handle
1147 ) == -1)
1148 result = -1;
1150 return result;
1153 // Hook called by the explicit dynamic linking facility.
1155 template <class SVC_HANDLER, ACE_PEER_ACCEPTOR_1> int
1156 ACE_Oneshot_Acceptor<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::init (int, ACE_TCHAR *[])
1158 ACE_TRACE ("ACE_Oneshot_Acceptor<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::init");
1159 return -1;
1162 template <class SVC_HANDLER, ACE_PEER_ACCEPTOR_1> int
1163 ACE_Oneshot_Acceptor<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::fini (void)
1165 ACE_TRACE ("ACE_Oneshot_Acceptor<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::fini");
1166 return this->handle_close ();
1169 template <class SVC_HANDLER, ACE_PEER_ACCEPTOR_1> int
1170 ACE_Oneshot_Acceptor<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::info (ACE_TCHAR **strp,
1171 size_t length) const
1173 ACE_TRACE ("ACE_Oneshot_Acceptor<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::info");
1174 ACE_TCHAR buf[BUFSIZ];
1175 ACE_TCHAR addr_str[BUFSIZ];
1176 ACE_PEER_ACCEPTOR_ADDR addr;
1178 if (this->peer_acceptor_.get_local_addr (addr) == -1)
1179 return -1;
1180 else if (addr.addr_to_string (addr_str, sizeof addr_str) == -1)
1181 return -1;
1183 ACE_OS::sprintf (buf,
1184 ACE_TEXT ("%s\t %s %s"),
1185 ACE_TEXT ("ACE_Oneshot_Acceptor"),
1186 addr_str,
1187 ACE_TEXT ("#oneshot acceptor factory\n"));
1189 if (*strp == 0 && (*strp = ACE_OS::strdup (buf)) == 0)
1190 return -1;
1191 else
1192 ACE_OS::strsncpy (*strp, buf, length);
1193 return static_cast<int> (ACE_OS::strlen (buf));
1196 template <class SVC_HANDLER, ACE_PEER_ACCEPTOR_1> int
1197 ACE_Oneshot_Acceptor<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::suspend (void)
1199 ACE_TRACE ("ACE_Oneshot_Acceptor<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::suspend");
1200 return this->reactor () && this->reactor ()->suspend_handler (this);
1203 template <class SVC_HANDLER, ACE_PEER_ACCEPTOR_1> int
1204 ACE_Oneshot_Acceptor<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::resume (void)
1206 ACE_TRACE ("ACE_Oneshot_Acceptor<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::resume");
1207 return this->reactor () && this->reactor ()->resume_handler (this);
1210 // Returns ACE_HANDLE of the underlying peer_acceptor.
1212 template <class SVC_HANDLER, ACE_PEER_ACCEPTOR_1> ACE_HANDLE
1213 ACE_Oneshot_Acceptor<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::get_handle (void) const
1215 ACE_TRACE ("ACE_Oneshot_Acceptor<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::get_handle");
1216 return this->peer_acceptor_.get_handle ();
1219 template <class SVC_HANDLER, ACE_PEER_ACCEPTOR_1> ACE_PEER_ACCEPTOR &
1220 ACE_Oneshot_Acceptor<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::acceptor (void) const
1222 ACE_TRACE ("ACE_Oneshot_Acceptor<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::acceptor");
1223 return (ACE_PEER_ACCEPTOR &) this->peer_acceptor_;
1226 template <class SVC_HANDLER, ACE_PEER_ACCEPTOR_1>
1227 ACE_Oneshot_Acceptor<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::operator ACE_PEER_ACCEPTOR & () const
1229 ACE_TRACE ("ACE_Oneshot_Acceptor<SVC_HANDLER, ACE_PEER_ACCEPTOR_2>::operator ACE_PEER_ACCEPTOR &");
1230 return (ACE_PEER_ACCEPTOR &) this->peer_acceptor_;
1233 ACE_END_VERSIONED_NAMESPACE_DECL
1235 #endif /* ACE_ACCEPTOR_CPP */