summaryrefslogtreecommitdiff
path: root/ACE/examples/Connection/misc/Connection_Handler.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'ACE/examples/Connection/misc/Connection_Handler.cpp')
-rw-r--r--ACE/examples/Connection/misc/Connection_Handler.cpp230
1 files changed, 230 insertions, 0 deletions
diff --git a/ACE/examples/Connection/misc/Connection_Handler.cpp b/ACE/examples/Connection/misc/Connection_Handler.cpp
new file mode 100644
index 00000000000..f05c38ce59b
--- /dev/null
+++ b/ACE/examples/Connection/misc/Connection_Handler.cpp
@@ -0,0 +1,230 @@
+// $Id$
+
+// ============================================================================
+//
+// = FILENAME
+// Connection_Handler.cpp
+//
+// = DESCRIPTION
+// This test illustrates how to use the Acceptor pattern to
+// create multiple threads, each running its own Reactor. You
+// can connect to this via telnet and keep typing until you enter
+// '^D'.
+//
+// = AUTHOR
+// Doug Schmidt
+//
+// ============================================================================
+
+#include "ace/Acceptor.h"
+#include "ace/SOCK_Acceptor.h"
+#include "ace/Service_Config.h"
+#include "ace/Thread.h"
+#include "ace/Sig_Adapter.h"
+
+#include "Connection_Handler.h"
+
+ACE_RCSID(misc, Connection_Handler, "$Id$")
+
+int
+Connection_Handler::open (void *)
+{
+ //FUZZ: disable check_for_lack_ACE_OS
+ ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("(%P|%t) in open()\n")));
+ //FUZZ: enable check_for_lack_ACE_OS
+
+ // Make ourselves an Active Object.
+ return this->activate (THR_NEW_LWP | THR_DETACHED);
+}
+
+int
+Connection_Handler::close (u_long)
+{
+ //FUZZ: disable check_for_lack_ACE_OS
+ ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("(%P|%t) in close()\n")));
+ //FUZZ: enable check_for_lack_ACE_OS
+
+ // Shut ourself down. Note that this doesn't destroy the thread,
+ // just the state of the object.
+ this->destroy ();
+ return 0;
+}
+
+int
+Connection_Handler::svc (void)
+{
+ ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("(%P|%t) in svc()\n")));
+
+ this->finished_ = 0;
+
+ // Create our own personal Reactor just for this thread. Note that
+ // we create this on the stack of the thread since it's only used
+ // for the duration of this connection!
+
+ ACE_Reactor reactor;
+
+ // Each <ACE_Svc_Handler> has its own <ACE_Reactor *>. By default,
+ // this points to the <Acceptor's> Reactor. However, we can point
+ // it to our local Reactor, which is what we do in this case.
+ this->reactor (&reactor);
+
+ // Register ourselves to handle input in this thread without
+ // blocking.
+ if (this->reactor ()->register_handler
+ (this, ACE_Event_Handler::READ_MASK) == -1)
+ ACE_ERROR_RETURN ((LM_ERROR,
+ ACE_TEXT ("can' (%P|%t) t register with reactor\n")),
+ -1);
+ // Schedule a timer.
+ else if (this->reactor ()->schedule_timer (this,
+ (const void *) this,
+ ACE_Time_Value (2),
+ ACE_Time_Value (2)) == -1)
+ ACE_ERROR_RETURN ((LM_ERROR,
+ ACE_TEXT ("(%P|%t) can't register with reactor\n")),
+ -1);
+ else
+ ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("(%P|%t) connected with client\n")));
+
+ // Keep looping until we receive SIGQUIT or the client shutsdown.
+
+ while (this->finished_ == 0)
+ {
+ ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("(%P|%t) handling events\n")));
+ this->reactor ()->handle_events ();
+ }
+
+ // Cancel all pending timeouts.
+ this->reactor ()->cancel_timer (this);
+
+ // Remove ourselves from the Reactor.
+ this->reactor ()->remove_handler
+ (this, ACE_Event_Handler::READ_MASK | ACE_Event_Handler::DONT_CALL);
+
+ // Zero-out the Reactor field so it isn't accessed later on.
+ this->reactor (0);
+
+ ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("(%P|%t) exiting svc\n")));
+ return 0;
+}
+
+int
+Connection_Handler::handle_close (ACE_HANDLE,
+ ACE_Reactor_Mask)
+{
+ ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("(%P|%t) in handle_close \n")));
+
+ // Signal the svc() event loop to shut down.
+ this->finished_ = 1;
+ return 0;
+}
+
+int
+Connection_Handler::handle_input (ACE_HANDLE)
+{
+ char buf[BUFSIZ];
+
+ ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("(%P|%t) handle_input\n")));
+
+ switch (this->peer ().recv (buf, sizeof buf))
+ {
+ case -1:
+ ACE_ERROR_RETURN ((LM_ERROR,
+ ACE_TEXT ("(%P|%t) %p bad read\n"),
+ ACE_TEXT ("client logger")),
+ -1);
+ case 0:
+ ACE_ERROR_RETURN ((LM_ERROR,
+ ACE_TEXT ("(%P|%t) closing log daemon (fd = %d)\n"),
+ this->get_handle ()),
+ -1);
+ default:
+ if (buf[0] == (char) EOF)
+ ACE_ERROR_RETURN ((LM_ERROR,
+ ACE_TEXT ("(%P|%t) closing log daemon (fd = %d)\n"),
+ this->get_handle ()),
+ -1);
+ else
+ ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("(%P|%t) from client: %s"), buf));
+ }
+
+ return 0;
+}
+
+int
+Connection_Handler::handle_signal (int signum,
+ siginfo_t *,
+ ucontext_t *)
+{
+ // @@ Note that this code is not portable to all OS platforms since
+ // it uses print statements within signal handler context.
+
+ ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("received signal %S\n"), signum));
+
+ this->finished_ = 1;
+ return 0;
+}
+
+int
+Connection_Handler::handle_timeout (const ACE_Time_Value &,
+ const void *arg)
+{
+#if defined (ACE_NDEBUG)
+ ACE_UNUSED_ARG (arg);
+#endif /* ACE_NDEBUG */
+
+ ACE_ASSERT (arg == this);
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("(%P|%t) handling timeout from this = %@\n"),
+ this));
+ return 0;
+}
+
+// Define an Acceptor for the <Connection_Handler>.
+
+typedef ACE_Acceptor <Connection_Handler, ACE_SOCK_ACCEPTOR>
+ Connection_Acceptor;
+
+int
+ACE_TMAIN (int argc, ACE_TCHAR *argv[])
+{
+ ACE_Service_Config daemon (argv[0]);
+
+ u_short port = argc > 1 ? ACE_OS::atoi (argv[1]) : ACE_DEFAULT_SERVER_PORT;
+
+ ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("(%P|%t) in main\n")));
+
+ // Acceptor factory.
+ Connection_Acceptor peer_acceptor;
+
+ // Create an adapter to end the event loop.
+ ACE_Sig_Adapter sa ((ACE_Sig_Handler_Ex) ACE_Reactor::end_event_loop);
+
+ // Register the signal handler adapter.
+ if (ACE_Reactor::instance ()->register_handler (SIGINT, &sa) == -1)
+ ACE_ERROR_RETURN ((LM_ERROR,
+ ACE_TEXT ("%p\n"),
+ ACE_TEXT ("register_handler")),
+ -1);
+
+ // Open the Acceptor.
+ else if (peer_acceptor.open (ACE_INET_Addr (port),
+ ACE_Reactor::instance ()) == -1)
+ ACE_ERROR_RETURN ((LM_ERROR,
+ ACE_TEXT ("%p\n"),
+ ACE_TEXT ("open")),
+ -1);
+
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("(%P|%t) starting up connection server\n")));
+
+ // Perform connection service until we receive SIGINT.
+
+ while (ACE_Reactor::event_loop_done() == 0)
+ ACE_Reactor::run_event_loop ();
+
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("(%P|%t) shutting down connection server\n")));
+ return 0;
+}
+