summaryrefslogtreecommitdiff
path: root/ACE/examples/Logger/simple-server
diff options
context:
space:
mode:
Diffstat (limited to 'ACE/examples/Logger/simple-server')
-rw-r--r--ACE/examples/Logger/simple-server/Logger_Simple_Server.mpc6
-rw-r--r--ACE/examples/Logger/simple-server/Logging_Acceptor.cpp85
-rw-r--r--ACE/examples/Logger/simple-server/Logging_Acceptor.h59
-rw-r--r--ACE/examples/Logger/simple-server/Logging_Handler.cpp202
-rw-r--r--ACE/examples/Logger/simple-server/Logging_Handler.h71
-rw-r--r--ACE/examples/Logger/simple-server/Makefile.am39
-rw-r--r--ACE/examples/Logger/simple-server/Reactor_Singleton.h33
-rw-r--r--ACE/examples/Logger/simple-server/server_loggerd.cpp85
8 files changed, 580 insertions, 0 deletions
diff --git a/ACE/examples/Logger/simple-server/Logger_Simple_Server.mpc b/ACE/examples/Logger/simple-server/Logger_Simple_Server.mpc
new file mode 100644
index 00000000000..1e4d8240e38
--- /dev/null
+++ b/ACE/examples/Logger/simple-server/Logger_Simple_Server.mpc
@@ -0,0 +1,6 @@
+// -*- MPC -*-
+// $Id$
+
+project : aceexe {
+ exename = server_loggerd
+} \ No newline at end of file
diff --git a/ACE/examples/Logger/simple-server/Logging_Acceptor.cpp b/ACE/examples/Logger/simple-server/Logging_Acceptor.cpp
new file mode 100644
index 00000000000..7e5e0d0075c
--- /dev/null
+++ b/ACE/examples/Logger/simple-server/Logging_Acceptor.cpp
@@ -0,0 +1,85 @@
+// $Id$
+
+#include "ace/WFMO_Reactor.h"
+#include "ace/Log_Msg.h"
+
+#include "Logging_Acceptor.h"
+#include "Logging_Handler.h"
+#include "Reactor_Singleton.h"
+
+ACE_RCSID(simple_server, Logging_Acceptor, "$Id$")
+
+// Initialize peer_acceptor object.
+
+int
+Logging_Acceptor::open (const ACE_INET_Addr &addr)
+{
+ // Reuse addr if already in use.
+ if (this->peer_acceptor_.open (addr, 1) == -1)
+ return -1;
+ else
+ return 0;
+}
+
+// Default constructor.
+
+Logging_Acceptor::Logging_Acceptor (void)
+{
+}
+
+// Performs termination activities.
+
+int
+Logging_Acceptor::handle_close (ACE_HANDLE, ACE_Reactor_Mask)
+{
+ this->peer_acceptor_.close ();
+ // Note, this object MUST be allocated dynamically!
+ delete this;
+ return 0;
+}
+
+Logging_Acceptor::~Logging_Acceptor (void)
+{
+}
+
+// Returns underlying device descriptor.
+
+ACE_HANDLE
+Logging_Acceptor::get_handle (void) const
+{
+ return this->peer_acceptor_.get_handle ();
+}
+
+// Accepts connections from client and registers new object with the
+// ACE_Reactor.
+
+int
+Logging_Acceptor::handle_input (ACE_HANDLE)
+{
+ Logging_Handler *svc_handler;
+
+ ACE_NEW_RETURN (svc_handler, Logging_Handler, -1);
+
+ // Accept the connection from a client client daemon.
+
+ // Try to find out if the implementation of the reactor that we are
+ // using requires us to reset the event association for the newly
+ // created handle. This is because the newly created handle will
+ // inherit the properties of the listen handle, including its event
+ // associations.
+ int reset_new_handle = this->reactor ()->uses_event_associations ();
+
+ if (this->peer_acceptor_.accept (svc_handler->peer (), // stream
+ 0, // remote address
+ 0, // timeout
+ 1, // restart
+ reset_new_handle // reset new handler
+ ) == -1
+ || svc_handler->open () == -1)
+ {
+ svc_handler->close ();
+ ACE_ERROR_RETURN ((LM_ERROR, "%p", "accept/open failed"), -1);
+ }
+
+ return 0;
+}
diff --git a/ACE/examples/Logger/simple-server/Logging_Acceptor.h b/ACE/examples/Logger/simple-server/Logging_Acceptor.h
new file mode 100644
index 00000000000..0424a7c3889
--- /dev/null
+++ b/ACE/examples/Logger/simple-server/Logging_Acceptor.h
@@ -0,0 +1,59 @@
+/* -*- C++ -*- */
+// $Id$
+
+// ============================================================================
+//
+// = LIBRARY
+// examples
+//
+// = FILENAME
+// Logging_Acceptor.h
+//
+// = AUTHOR
+// Doug Schmidt
+//
+// ============================================================================
+
+#ifndef _CLIENT_ACCEPTOR_H
+#define _CLIENT_ACCEPTOR_H
+
+#include "ace/SOCK_Acceptor.h"
+
+#if !defined (ACE_LACKS_PRAGMA_ONCE)
+# pragma once
+#endif /* ACE_LACKS_PRAGMA_ONCE */
+
+#include "ace/Event_Handler.h"
+
+class Logging_Acceptor : public ACE_Event_Handler
+ // = TITLE
+ // Handle connection requests from remote client clients.
+ //
+ // = DESCRIPTION
+ // Accepts client connection requests, creates Logging_Handler's
+ // to process them, and registers these Handlers with the
+ // ACE_Reactor Singleton.
+{
+friend class Logging_Handler;
+public:
+ Logging_Acceptor (void);
+ // Constructor.
+
+ int open (const ACE_INET_Addr &a);
+ // Initialization.
+
+private:
+ // = Demuxing hooks.
+ virtual int handle_input (ACE_HANDLE);
+ virtual int handle_close (ACE_HANDLE, ACE_Reactor_Mask);
+ virtual ACE_HANDLE get_handle (void) const;
+
+ ~Logging_Acceptor (void);
+ // By making this private we ensure that the <Logging_Acceptor> is
+ // allocated dynamically.
+
+ ACE_SOCK_Acceptor peer_acceptor_;
+ // Passive connection acceptor factory.
+};
+
+#endif /* _CLIENT_ACCEPTOR_H */
diff --git a/ACE/examples/Logger/simple-server/Logging_Handler.cpp b/ACE/examples/Logger/simple-server/Logging_Handler.cpp
new file mode 100644
index 00000000000..aacad00c3f1
--- /dev/null
+++ b/ACE/examples/Logger/simple-server/Logging_Handler.cpp
@@ -0,0 +1,202 @@
+// $Id$
+
+#include "ace/Log_Msg.h"
+#include "ace/Message_Block.h"
+#include "ace/Log_Record.h"
+#include "ace/OS_NS_string.h"
+#include "ace/CDR_Stream.h"
+#include "ace/Auto_Ptr.h"
+
+#include "Logging_Handler.h"
+#include "Reactor_Singleton.h"
+
+ACE_RCSID(simple_server, Logging_Handler, "$Id$")
+
+// Default constructor.
+
+Logging_Handler::Logging_Handler (void)
+{
+}
+
+Logging_Handler::~Logging_Handler (void)
+{
+ // Make sure there are no timers.
+ REACTOR::instance ()->cancel_timer (this);
+
+ this->cli_stream_.close ();
+}
+
+// Extract the underlying ACE_SOCK_Stream (e.g., for purposes of
+// accept()).
+
+ACE_SOCK_Stream &
+Logging_Handler::peer (void)
+{
+ return this->cli_stream_;
+}
+
+int
+Logging_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;
+}
+
+// Perform the logging record receive.
+
+int
+Logging_Handler::handle_input (ACE_HANDLE)
+{
+ ACE_Log_Record log_record;
+
+ // We need to use the old two-read trick here since TCP sockets
+ // don't support framing natively. Allocate a message block for the
+ // payload; initially at least large enough to hold the header, but
+ // needs some room for alignment.
+ ACE_Message_Block *payload_p = 0;
+ ACE_Message_Block *header_p = 0;
+ ACE_NEW_RETURN (header_p,
+ ACE_Message_Block (ACE_DEFAULT_CDR_BUFSIZE),
+ -1);
+
+ auto_ptr <ACE_Message_Block> header (header_p);
+
+ // Align the Message Block for a CDR stream
+ ACE_CDR::mb_align (header.get ());
+
+ ACE_CDR::Boolean byte_order;
+ ACE_CDR::ULong length;
+
+ ssize_t count = ACE::recv_n (this->peer ().get_handle (),
+ header->wr_ptr (),
+ 8);
+ switch (count)
+ {
+ // Handle shutdown and error cases.
+ default:
+ case -1:
+ case 0:
+
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("server logging daemon closing down\n")));
+
+ return -1;
+ /* NOTREACHED */
+
+ case 8:
+ // Just fall through in this case..
+ break;
+ }
+
+ header->wr_ptr (8); // Reflect addition of 8 bytes.
+
+ // Create a CDR stream to parse the 8-byte header.
+ ACE_InputCDR header_cdr (header.get ());
+
+ // Extract the byte-order and use helper methods to disambiguate
+ // octet, booleans, and chars.
+ header_cdr >> ACE_InputCDR::to_boolean (byte_order);
+
+ // Set the byte-order on the stream...
+ header_cdr.reset_byte_order (byte_order);
+
+ // Extract the length
+ header_cdr >> length;
+
+ ACE_NEW_RETURN (payload_p,
+ ACE_Message_Block (length),
+ -1);
+ auto_ptr <ACE_Message_Block> payload (payload_p);
+
+ // Ensure there's sufficient room for log record payload.
+ ACE_CDR::grow (payload.get (), 8 + ACE_CDR::MAX_ALIGNMENT + length);
+
+ // Use <recv_n> to obtain the contents.
+ if (ACE::recv_n (this->peer ().get_handle (),
+ payload->wr_ptr (),
+ length) <= 0)
+ {
+ ACE_ERROR ((LM_ERROR,
+ ACE_TEXT ("%p\n"),
+ ACE_TEXT ("recv_n()")));
+ return -1;
+ }
+
+ payload->wr_ptr (length); // Reflect additional bytes
+
+ ACE_InputCDR payload_cdr (payload.get ());
+ payload_cdr.reset_byte_order (byte_order);
+ payload_cdr >> log_record; // Finally extract the <ACE_log_record>.
+
+ log_record.length (length);
+
+ log_record.print (ACE_TEXT_CHAR_TO_TCHAR (this->host_name_), 1, stderr);
+
+ return 0;
+}
+
+// Extract underlying device descriptor.
+
+ACE_HANDLE
+Logging_Handler::get_handle (void) const
+{
+ return this->cli_stream_.get_handle ();
+}
+
+int
+Logging_Handler::open (void)
+{
+ ACE_INET_Addr addr;
+
+ if (this->cli_stream_.get_remote_addr (addr) == -1)
+ return -1;
+ else
+ {
+ ACE_OS::strncpy (this->host_name_,
+ addr.get_host_name (),
+ MAXHOSTNAMELEN + 1);
+
+ if (REACTOR::instance ()->register_handler (this, READ_MASK) == -1)
+ ACE_ERROR_RETURN ((LM_ERROR,
+ ACE_TEXT ("(%P|%t) can't register with reactor\n")),
+ -1);
+ else if (REACTOR::instance ()->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 %C\n"),
+ this->host_name_));
+ return 0;
+ }
+}
+
+// Perform termination activities when deregistered from the
+// ACE_Reactor.
+
+int
+Logging_Handler::handle_close (ACE_HANDLE, ACE_Reactor_Mask)
+{
+ // Must have been allocated dynamically
+ delete this;
+ return 0;
+}
+
+// Perform termination activities when close fails.
+
+int
+Logging_Handler::close (void)
+{
+ return this->handle_close ();
+}
diff --git a/ACE/examples/Logger/simple-server/Logging_Handler.h b/ACE/examples/Logger/simple-server/Logging_Handler.h
new file mode 100644
index 00000000000..633e04a167c
--- /dev/null
+++ b/ACE/examples/Logger/simple-server/Logging_Handler.h
@@ -0,0 +1,71 @@
+/* -*- C++ -*- */
+// $Id$
+
+
+// ============================================================================
+//
+// = LIBRARY
+// examples
+//
+// = FILENAME
+// Logging_Handler.h
+//
+// = AUTHOR
+// Doug Schmidt
+//
+// ============================================================================
+
+#ifndef _CLIENT_HANDLER_H
+#define _CLIENT_HANDLER_H
+
+#include "ace/Event_Handler.h"
+
+#if !defined (ACE_LACKS_PRAGMA_ONCE)
+# pragma once
+#endif /* ACE_LACKS_PRAGMA_ONCE */
+
+#include "ace/INET_Addr.h"
+#include "ace/SOCK_Stream.h"
+#include "ace/os_include/os_netdb.h"
+
+class Logging_Handler : public ACE_Event_Handler
+ // = TITLE
+ // Receive client message from the remote clients.
+ //
+ // = DESCRIPTION
+ // This class demonstrates how to receive messages from remote
+ // clients using the notification mechanisms in the
+ // <ACE_Reactor>. In addition, it also illustrates how to
+ // utilize the <ACE_Reactor> timer mechanisms, as well.
+{
+public:
+ Logging_Handler (void);
+
+ // = Hooks for opening and closing handlers.
+ virtual int open (void);
+ virtual int close (void);
+
+ ACE_SOCK_Stream &peer (void);
+ // Conversion operators.
+
+protected:
+ // = Demultiplexing hooks.
+ virtual ACE_HANDLE get_handle (void) const;
+ virtual int handle_input (ACE_HANDLE);
+ virtual int handle_close (ACE_HANDLE = ACE_INVALID_HANDLE,
+ ACE_Reactor_Mask = ACE_Event_Handler::ALL_EVENTS_MASK);
+ virtual int handle_timeout (const ACE_Time_Value &tv, const void *arg);
+
+ // = Really should be private...
+ virtual ~Logging_Handler (void);
+ // Ensure dynamic allocation.
+
+private:
+ char host_name_[MAXHOSTNAMELEN + 1];
+ // Host we are connected to.
+
+ ACE_SOCK_Stream cli_stream_;
+ // Connection with client
+};
+
+#endif /* _CLIENT_HANDLER_H */
diff --git a/ACE/examples/Logger/simple-server/Makefile.am b/ACE/examples/Logger/simple-server/Makefile.am
new file mode 100644
index 00000000000..d9a43e17ee6
--- /dev/null
+++ b/ACE/examples/Logger/simple-server/Makefile.am
@@ -0,0 +1,39 @@
+## Process this file with automake to create Makefile.in
+##
+## $Id$
+##
+## This file was generated by MPC. Any changes made directly to
+## this file will be lost the next time it is generated.
+##
+## MPC Command:
+## ./bin/mwc.pl -type automake -noreldefs ACE.mwc
+
+ACE_BUILDDIR = $(top_builddir)
+ACE_ROOT = $(top_srcdir)
+
+## Makefile.Logger_Simple_Server.am
+
+noinst_PROGRAMS = server_loggerd
+
+server_loggerd_CPPFLAGS = \
+ -I$(ACE_ROOT) \
+ -I$(ACE_BUILDDIR)
+
+server_loggerd_SOURCES = \
+ Logging_Acceptor.cpp \
+ Logging_Handler.cpp \
+ server_loggerd.cpp \
+ Logging_Acceptor.h \
+ Logging_Handler.h \
+ Reactor_Singleton.h
+
+server_loggerd_LDADD = \
+ $(ACE_BUILDDIR)/ace/libACE.la
+
+## Clean up template repositories, etc.
+clean-local:
+ -rm -f *~ *.bak *.rpo *.sym lib*.*_pure_* core core.*
+ -rm -f gcctemp.c gcctemp so_locations *.ics
+ -rm -rf cxx_repository ptrepository ti_files
+ -rm -rf templateregistry ir.out
+ -rm -rf ptrepository SunWS_cache Templates.DB
diff --git a/ACE/examples/Logger/simple-server/Reactor_Singleton.h b/ACE/examples/Logger/simple-server/Reactor_Singleton.h
new file mode 100644
index 00000000000..ec0653125a9
--- /dev/null
+++ b/ACE/examples/Logger/simple-server/Reactor_Singleton.h
@@ -0,0 +1,33 @@
+/* -*- C++ -*- */
+// $Id$
+
+
+// ============================================================================
+//
+// = LIBRARY
+// examples
+//
+// = FILENAME
+// Reactor_Singleton.h
+//
+// = AUTHOR
+// Doug Schmidt
+//
+// ============================================================================
+
+#ifndef _REACTOR_SINGLETON_H
+#define _REACTOR_SINGLETON_H
+
+#include "ace/Singleton.h"
+#include "ace/Null_Mutex.h"
+
+#if !defined (ACE_LACKS_PRAGMA_ONCE)
+# pragma once
+#endif /* ACE_LACKS_PRAGMA_ONCE */
+
+#include "ace/Reactor.h"
+
+// Our global Reactor Singleton.
+typedef ACE_Singleton<ACE_Reactor, ACE_Null_Mutex> REACTOR;
+
+#endif /* _REACTOR_SINGLETON_H */
diff --git a/ACE/examples/Logger/simple-server/server_loggerd.cpp b/ACE/examples/Logger/simple-server/server_loggerd.cpp
new file mode 100644
index 00000000000..f323a2f3826
--- /dev/null
+++ b/ACE/examples/Logger/simple-server/server_loggerd.cpp
@@ -0,0 +1,85 @@
+// $Id$
+
+// This server daemon collects, formats, and displays logging
+// information forwarded from client daemons running on other hosts in
+// the network.
+//
+// In addition, it also illustrates how the ACE_Reactor framework is
+// used.
+
+#include "ace/Get_Opt.h"
+#include "ace/Log_Msg.h"
+#include "ace/Signal.h"
+
+#include "Logging_Acceptor.h"
+#include "Reactor_Singleton.h"
+
+ACE_RCSID(simple_server, server_loggerd, "$Id$")
+
+static sig_atomic_t finished = 0;
+
+extern "C" void
+handler (int)
+{
+ finished = 1;
+}
+
+// It doesn't get anymore const than this....
+static const u_short PORT = ACE_DEFAULT_SERVER_PORT;
+
+int
+ACE_TMAIN (int argc, ACE_TCHAR *argv[])
+{
+ // Register a signal handler.
+ ACE_Sig_Action sa ((ACE_SignalHandler) handler, SIGINT);
+ ACE_UNUSED_ARG (sa);
+
+ Logging_Acceptor *peer_acceptor;
+ ACE_NEW_RETURN (peer_acceptor,
+ Logging_Acceptor,
+ 1);
+
+ ACE_INET_Addr addr (PORT);
+
+ ACE_Get_Opt get_opt (argc, argv, ACE_TEXT ("p:"));
+
+ for (int c; (c = get_opt ()) != -1; )
+ switch (c)
+ {
+ case 'p':
+ addr.set (ACE_OS::atoi (get_opt.opt_arg ()));
+ break;
+ default:
+ break;
+ }
+
+ if (peer_acceptor->open (addr) == -1)
+ ACE_ERROR_RETURN ((LM_ERROR,
+ ACE_TEXT ("%p\n"),
+ ACE_TEXT ("open")),
+ -1);
+ else if (REACTOR::instance ()->register_handler
+ (peer_acceptor,
+ ACE_Event_Handler::ACCEPT_MASK) == -1)
+ ACE_ERROR_RETURN ((LM_ERROR,
+ ACE_TEXT ("registering service with ACE_Reactor\n")),
+ -1);
+
+ // Run forever, performing the logging service.
+
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("(%P|%t) starting up server logging daemon\n")));
+
+ while (!finished)
+ REACTOR::instance ()->handle_events ();
+
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("(%P|%t) shutting down server logging daemon\n")));
+ return 0;
+}
+
+
+#if defined (ACE_HAS_EXPLICIT_STATIC_TEMPLATE_MEMBER_INSTANTIATION)
+template ACE_Singleton<ACE_Reactor, ACE_Null_Mutex> *
+ ACE_Singleton<ACE_Reactor, ACE_Null_Mutex>::singleton_;
+#endif /* ACE_HAS_EXPLICIT_STATIC_TEMPLATE_MEMBER_INSTANTIATION */