summaryrefslogtreecommitdiff
path: root/apps/Orbix-Examples/Logger
diff options
context:
space:
mode:
Diffstat (limited to 'apps/Orbix-Examples/Logger')
-rw-r--r--apps/Orbix-Examples/Logger/Logger.cpp131
-rw-r--r--apps/Orbix-Examples/Logger/Logger.h56
-rw-r--r--apps/Orbix-Examples/Logger/Makefile63
-rw-r--r--apps/Orbix-Examples/Logger/Orbix.hostgroups1
-rw-r--r--apps/Orbix-Examples/Logger/Orbix.hosts3
-rw-r--r--apps/Orbix-Examples/Logger/README35
-rw-r--r--apps/Orbix-Examples/Logger/a1.tex232
-rw-r--r--apps/Orbix-Examples/Logger/client.cpp142
-rw-r--r--apps/Orbix-Examples/Logger/logger.hh434
-rw-r--r--apps/Orbix-Examples/Logger/logger.idl56
-rw-r--r--apps/Orbix-Examples/Logger/loggerS.cpp141
-rw-r--r--apps/Orbix-Examples/Logger/logger_i.cpp120
-rw-r--r--apps/Orbix-Examples/Logger/logger_i.h75
-rw-r--r--apps/Orbix-Examples/Logger/server.cpp40
14 files changed, 1529 insertions, 0 deletions
diff --git a/apps/Orbix-Examples/Logger/Logger.cpp b/apps/Orbix-Examples/Logger/Logger.cpp
new file mode 100644
index 00000000000..de05360f606
--- /dev/null
+++ b/apps/Orbix-Examples/Logger/Logger.cpp
@@ -0,0 +1,131 @@
+#include <iostream.h>
+// @(#)Logger.cpp 1.1 10/18/96
+
+#include "Logger.h"
+
+Logger::~Logger (void)
+{
+ // Release and free up the object reference.
+ this->logref_->_release ();
+
+ // Must use free since we used strdup(3C).
+ ACE_OS::free (ACE_MALLOC_T (this->server_));
+}
+
+// Constructor takes the name of the host where the server
+// is located. If server == 0, then use the locator service.
+
+Logger::Logger (char *server, size_t max_message_size)
+ : server_ (server == 0 ? 0 : ACE_OS::strdup (server)),
+ ip_ (0),
+ pid_ (ACE_OS::getpid ())
+{
+ struct utsname name;
+
+#if 0
+ // Could also use sysinfo(2)...
+
+ ACE_OS::sysinfo (SI_HOSTNAME, clienthost, MAXHOSTNAMELEN);
+#endif
+
+ ACE_OS::uname (&name);
+ hostent *hp = ACE_OS::gethostbyname (name.nodename);
+
+ if (hp != 0)
+ memcpy ((void *) &this->ip_, (void *) hp->h_addr, hp->h_length);
+
+ TRY {
+ // First bind to the logger object.
+ // argv[1] has the hostname (if any) of the target logger object;
+ // The default is the local host:
+ this->logref_ = profile_logger::_bind ("", this->server_, IT_X);
+ } CATCHANY {
+ // an error occurred while trying to bind to the logger object.
+ cerr << "Bind to object failed" << endl;
+ cerr << "Unexpected exception " << IT_X << endl;
+ } ENDTRY;
+ // Pre-assign certain values that don't change.
+ this->log_msg_.app_id = this->pid_;
+ this->log_msg_.host_addr = this->ip_;
+ this->log_msg_.msg_data._maximum = max_message_size;
+}
+
+// Transmit the message to the logging server.
+
+int
+Logger::log (logger::Log_Priority priority, char message[], int length)
+{
+ // The following values change with every logging operation.
+ this->log_msg_.type = priority;
+ this->log_msg_.time = ACE_OS::time (0);
+ this->log_msg_.msg_data._length = length;
+ this->log_msg_.msg_data._buffer = message;
+
+ TRY {
+ // Try to log a message.
+ this->logref_->log (this->log_msg_, IT_X);
+ } CATCHANY {
+ // an error occurred while trying to read the height and width:
+ cerr << "call to log failed" << endl;
+ cerr << "Unexpected exception " << IT_X << endl;
+ return -1;
+ } ENDTRY;
+ // success.
+ return 0;
+}
+
+// Get the value of verbose.
+
+int
+Logger::verbose (void)
+{
+ int verbosity = 0;
+
+ TRY {
+ verbosity = this->logref_->verbose ();
+ } CATCHANY {
+ return -1;
+ } ENDTRY;
+ return verbosity;
+}
+
+// Set the value of verbose.
+
+int
+Logger::verbose (int value)
+{
+ int verbosity = 0;
+
+ TRY {
+ this->logref_->verbose (value);
+ } CATCHANY {
+ return -1;
+ } ENDTRY;
+ return 0;
+}
+
+// Activate the timer.
+
+int
+Logger::start_timer (void)
+{
+ TRY {
+ this->logref_->start_timer ();
+ } CATCHANY {
+ return -1;
+ } ENDTRY;
+ return 0;
+}
+
+// Deactivate the timer and return the elapsed time.
+
+int
+Logger::stop_timer (profile_logger::Elapsed_Time &et)
+{
+ TRY {
+ this->logref_->stop_timer (et);
+ } CATCHANY {
+ return -1;
+ } ENDTRY;
+ return 0;
+}
diff --git a/apps/Orbix-Examples/Logger/Logger.h b/apps/Orbix-Examples/Logger/Logger.h
new file mode 100644
index 00000000000..fecae83cbf6
--- /dev/null
+++ b/apps/Orbix-Examples/Logger/Logger.h
@@ -0,0 +1,56 @@
+/* -*- C++ -*- */
+// @(#)Logger.h 1.1 10/18/96
+
+
+#if !defined (_LOGGER_H)
+#define _LOGGER_H
+
+#include "ace/OS.h"
+#include "logger.hh"
+
+class Logger
+ // = TITLE
+ // Wrapper class that uses CORBA object reference
+ // as the transport mechanism to simplify implementation.
+{
+public:
+ Logger (char *server, size_t max_message_size);
+ // Constructor takes the name of the host where the server
+ // is located. If server == 0, then use the locator service.
+
+ ~Logger (void);
+ // Destructor releases the object reference.
+
+ int log (logger::Log_Priority prio, char msg[], int len);
+ // Log a <msg> of length <len> with priority <prio>.
+
+ int verbose (void);
+ // Report current level of verbosity.
+
+ int verbose (int verbosity);
+ // Set the level of verbosity (0 == no verbose, > 0 == verbose).
+
+ int start_timer (void);
+ // Activate the timer.
+
+ int stop_timer (profile_logger::Elapsed_Time &et);
+ // Deactivate the timer and return the elapsed time.
+
+private:
+ profile_logger *logref_;
+ // CORBA object reference proxy.
+
+ int pid_;
+ // Process ID.
+
+ u_long ip_;
+ // IP address of self.
+
+ logger::Log_Record log_msg_;
+ // Cache certain non-changing values to avoid recomputing them.
+
+ char *server_;
+ // Name of server that we are bound to.
+};
+
+#endif /* _LOGGER_H */
diff --git a/apps/Orbix-Examples/Logger/Makefile b/apps/Orbix-Examples/Logger/Makefile
new file mode 100644
index 00000000000..7193cee9945
--- /dev/null
+++ b/apps/Orbix-Examples/Logger/Makefile
@@ -0,0 +1,63 @@
+#----------------------------------------------------------------------------
+# @(#)Makefile 1.1 10/18/96
+#
+# Makefile for the Logger.
+#----------------------------------------------------------------------------
+
+#----------------------------------------------------------------------------
+# Local macros
+#----------------------------------------------------------------------------
+
+SVR_OBJS = loggerS.o logger_i.o server.o
+CLT_OBJS = loggerC.o client.o Logger.o
+
+LDLIBS =
+
+VLDLIBS = $(LDLIBS:%=%$(VAR))
+
+#----------------------------------------------------------------------------
+# Include macros and targets
+#----------------------------------------------------------------------------
+
+include $(WRAPPER_ROOT)/include/makeinclude/wrapper_macros.GNU
+include $(WRAPPER_ROOT)/include/makeinclude/macros.GNU
+include $(WRAPPER_ROOT)/include/makeinclude/rules.common.GNU
+include $(WRAPPER_ROOT)/include/makeinclude/rules.nonested.GNU
+include $(WRAPPER_ROOT)/include/makeinclude/rules.lib.GNU
+include $(WRAPPER_ROOT)/include/makeinclude/rules.bin.GNU
+include $(WRAPPER_ROOT)/include/makeinclude/rules.local.GNU
+
+#----------------------------------------------------------------------------
+# Orbix related macros and target settings.
+#----------------------------------------------------------------------------
+
+ORBIX_BINDIR = $(ORBIX_ROOT)/bin
+ORBIX_LIBDIR = $(ORBIX_ROOT)/lib
+ORBIX_INCDIR = $(ORBIX_ROOT)/include
+
+CPPFLAGS += -DEXCEPTIONS -I$(ORBIX_INCDIR) -DWANT_ORBIX_FDS
+LDFLAGS += -L$(ORBIX_LIBDIR) -R $(ORBIX_LIBDIR)
+
+IDLFLAGS = -s S.cpp -c C.cpp -B
+
+#----------------------------------------------------------------------------
+# Local targets
+#----------------------------------------------------------------------------
+
+all: client server
+
+client: $(addprefix $(VDIR),$(CLT_OBJS))
+ $(LINK.cc) -o client $(addprefix $(VDIR),$(CLT_OBJS)) $(LDFLAGS) -lITsrvmt $(VLDLIBS)
+
+server: $(addprefix $(VDIR),$(SVR_OBJS))
+ $(LINK.cc) -o server $(addprefix $(VDIR),$(SVR_OBJS)) $(LDFLAGS) -lITsrvmt $(VLDLIBS)
+
+#----------------------------------------------------------------------------
+# Dependencies
+#----------------------------------------------------------------------------
+# DO NOT DELETE THIS LINE -- g++dep uses it.
+# DO NOT PUT ANYTHING AFTER THIS LINE, IT WILL GO AWAY.
+
+
+
+# IF YOU PUT ANYTHING HERE IT WILL GO AWAY
diff --git a/apps/Orbix-Examples/Logger/Orbix.hostgroups b/apps/Orbix-Examples/Logger/Orbix.hostgroups
new file mode 100644
index 00000000000..013636e79c4
--- /dev/null
+++ b/apps/Orbix-Examples/Logger/Orbix.hostgroups
@@ -0,0 +1 @@
+all:tango
diff --git a/apps/Orbix-Examples/Logger/Orbix.hosts b/apps/Orbix-Examples/Logger/Orbix.hosts
new file mode 100644
index 00000000000..2e11d889bed
--- /dev/null
+++ b/apps/Orbix-Examples/Logger/Orbix.hosts
@@ -0,0 +1,3 @@
+profile_logger:tango:
+logger:tango:
+IT_daemon:tango:
diff --git a/apps/Orbix-Examples/Logger/README b/apps/Orbix-Examples/Logger/README
new file mode 100644
index 00000000000..19b1db681f2
--- /dev/null
+++ b/apps/Orbix-Examples/Logger/README
@@ -0,0 +1,35 @@
+The directory contains the source code that implements an Orbix
+version of the distributed Logger. Other ACE versions of this code
+appear in the ./apps/Logger directory. It is interesting to compare
+and contrast the alternative implementations.
+
+RUNNING:
+
+The client is run as follows:
+
+client -h host -m max_message_size
+
+The -h host is optional if the locator service is properly configured.
+The -m specifies the maximum number of kilobytes to be sent per log. This
+is useful when redirecting messages to stdin.
+
+TIMING:
+
+I recommend timing the log's by specifying a max_message_size and
+redirecting /usr/dict/words. This will give you several trials from
+which to take an average.
+
+CLIENT:
+
+While using the client and typing in messages manually, capital Q and V
+must be used to quit and toggle verbose respectively. This allows you
+to redirect /usr/dict/words without quiting at the q's!!
+
+SERVER:
+
+To turn off message reporting on the server side, do a
+
+setenv NO_MESSAGES
+
+in the enviroment where the server will be run. If this is done, the server
+will only report that a message was received, but not display the messages.
diff --git a/apps/Orbix-Examples/Logger/a1.tex b/apps/Orbix-Examples/Logger/a1.tex
new file mode 100644
index 00000000000..5d10042e26e
--- /dev/null
+++ b/apps/Orbix-Examples/Logger/a1.tex
@@ -0,0 +1,232 @@
+\documentstyle[times,11pt,moretext] {article}
+\input macros
+\input widen
+\input psfig
+
+\begin{document}
+\centerline{\Large Washington University}
+\centerline{\Large Department of Computer Science}
+\bigskip
+\centerline{\large CS523: Distributed Operating Systems}
+%\smallskip
+%\centerline{\large Spring 1995}
+\bigskip
+\centerline{\large Programming Project}
+% \centerline{\large Due Tuesday, January $31^{st}$, 1995}
+
+\section{Overview}
+
+In this assignment, you will implement a distributed logging service
+shown in Figure~\ref{logenv}. Applications use this service to log
+information (such as error notifications, debugging traces, and status
+updates) in a distributed environment. In this service, CORBA remote
+operations are used to send logging records to a central logging
+server. The logging server outputs the logging records to a console,
+a printer, a file, or a network management database, etc.
+
+\section{Design and Implementation Issues}
+
+The distributed logging service will be designed as a client/server
+pair, containing the objects shown in Figure~\ref{simplog}.
+
+\subsection{CORBA IDL Specification}
+The following CORBA IDL specification defines the logging interface:
+
+{
+\small
+\ls{0.9}
+\begin{verbatim}
+// IDL schema definition
+interface Logger
+{
+ // Types of logging messages.
+ enum Log_Priority {
+ LM_DEBUG, // Debugging messages
+ LM_WARNING, // Warning messages
+ LM_ERROR, // Errors
+ LM_EMERG // A panic condition
+ };
+
+ // Format of the logging record.
+ struct Log_Record {
+ Log_Priority type; // Type of logging message.
+ long time; // Time stamp at sender.
+ long app_id; // Process ID of sender.
+ long host_addr; // IP address of the sender.
+ sequence<char> msg_data; // Sender-specific logging message.
+ };
+
+ // Transmit a Log_Record to the logging server.
+ oneway void log (in Log_Record log_rec);
+
+ // Toggle verbose formatting
+ attribute char verbose;
+};
+\end{verbatim}}
+
+\begin{figure}
+\center{\ \psfig{figure=graphics/logsimp.eps,width=13cm}\ }
+\vspace{-0.12in}
+\caption{Distributed Logging Service}
+\label{logenv}
+\end{figure}
+
+You will use a CORBA IDL compiler to translate this specification into
+client-side {\em stubs} and server-side {\em skeletons}. The client
+application (which you must write) will use the stubs as a {\em proxy}
+to access the logging services provided by the server. You must also
+write the implementation of the server, which provides the logging
+service.
+
+\subsection{Client and Server Functionality}
+For the purposes of the assignment, you can make the client driver
+program very simple. The client can read a line from its standard
+input and send it to the logging server. The server can then format
+and print the line on its standard output. For example, if you type
+this line to the client:
+
+\begin{verbatim}
+To boldly go where no one has gone before
+\end{verbatim}
+
+\noindent Then the server should output something like this:
+
+\begin{verbatim}
+Jan 24 14:50:28 1995@tango.cs.wustl.edu@18352@LM_DEBUG
+::To boldly go where no one has gone before
+\end{verbatim}
+
+\noindent Note that the server has printed out the logging message
+timestamp, sender's hostname and process id, and the message priority,
+followed by the logging message data.
+
+\begin{figure}
+\center{\ \psfig{figure=graphics/simplog.eps,width=13cm}\ }
+\vspace{-0.12in}
+\caption{CORBA-based Logger Design}
+\label{simplog}
+\end{figure}
+
+Note that in order to pass the client's IP address (which is
+represented as a 4-byte {\tt long}) in the logging message, you'll
+need to learn about several other UNIX routines. On the client-side
+you'll need to use {\tt uname(2)} and {\tt gethostbyname(2)} to
+determine the IP address of the client host. On the server-side,
+you'll need to use the {\tt gethostbyaddr(2)} function to convert the
+4-byte IP host address into an ASCII version of the host name. I
+recommend that you check the manual pages and read Richard Steven's
+book ``UNIX Network Programming'' for more details on using these
+functions.
+
+\subsection{Invoking the Client and Server}
+Once the client and server components are written, compiled, and
+linked together you will use the {\tt putit} command to register the
+server with the Orbix daemon. You'll then need to start up a copy of
+{\tt orbixd} (if there isn't already one running). {\tt orbixd}
+serves as the Object Request Broker for the local endpoint.
+
+A client will bind to the {\tt Logger} interface via the generated
+{\tt Logger::\_bind} method. There are two general ways to use this
+method. The first is to explicitly pass in the name of the server
+where {\tt orbixd} is running (your client should accept a
+command-line argument that is the name of the server, {\em e.g.,}
+``tango.cs.wustl.edu'').
+
+The second method is to use the CORBA locator service to get an object
+reference for the logging service. You'll need to read the Orbix
+documentation to learn how to set up a location file. This file will
+enable you to omit the name of the server in the call to {\tt
+Logger::\_bind}. By using the locator server, your clients can bind
+to object's implicitly. Make sure that your solution will work for
+either implicit or explicit service location.
+
+Once the client application has bound (either explicitly or
+implicitly) to an object reference for the {\tt Logger}, it can log
+messages by calling the {\tt log} method via the object reference
+proxy.
+
+\subsection{Performance Measurement}
+
+An important part of developing distributed systems is understanding
+the performance implications of different design approaches. In order
+to measure the performance overhead of using CORBA to build the
+Logger, you will write a simple extension to the original {\tt Logger}
+interface, as follows:
+
+{
+\small
+\ls{0.9}
+\begin{verbatim}
+// IDL schema definition
+interface Profile_Logger
+ : Logger // Profile_Logger IS-A Logger
+{
+ // Stores the amount of time that has elapsed.
+ struct Elapsed_Time
+ {
+ double real_time;
+ double user_time;
+ double system_time;
+ };
+
+ // Activate the timer.
+ void start_timer (void);
+
+ // Deactivate the timer and return the elapsed time.
+ void stop_timer (out Elapsed_Time et);
+};
+\end{verbatim}}
+
+\noindent You will need to modify your client program so that it can
+time a series of {\tt Logger::log} operations for various sizes of
+logging messages. This will help us understand the performance
+overhead of CORBA.
+
+The main benchmarking should take place within a loop in your client
+program. Basically, your client call {\tt
+Profile\_Logger::start\_timer} just before sending the first of the
+logging messages. After a suitable number of iterations (defined on
+the command-line), you client will call {\tt
+Profile\_Logger::stop\_timer} to determine and report the elapsed time
+to the user. You should print out the ``real'' time, as well as the
+``system $+$ user'' times. Make sure that you print out the
+throughput in terms of megabits/sec (rather than bytes/sec or
+kbytes/sec). Be sure to include the fixed-sized {\tt Log\_Record}
+object, as well as the variable-sized {\tt msg\_data} portion in your
+computations.
+
+The number of iterations and the size of the messages sent by the
+client should be parameterizable on the command-line. Make sure that
+your timing tests are run between processes on two different machines
+(rather than processes on the same machine). If possible, try to run
+the client and server processes on two machines on the same subnet.
+
+When you are finished with your timing test, you should explain the
+timing results and indicate trends that you observed.
+
+\section{Learning and Using CORBA}
+
+To help you learn how CORBA works, I will be making copies of the
+Orbix programmer's manual available for a small reproduction fee.
+This manual explains how to program in CORBA. I will announce in
+class where this will be available.
+
+We will be using IONA's Orbix CORBA Object Request Broker (ORB)
+implementation. The libraries, executables, CORBA IDL compiler, and
+example demo applications are located in {\tt
+/project/adaptive/Orbix}. Please note that this is an automounted
+directory, so you will need to {\tt cd} directly to it in order to see
+the contents. To configure Orbix for your environment, copy the {\tt
+/project/adaptive/Orbix/Orbix.cfg} file to your account. You'll need
+to set the environment variable {\tt IT\_CONFIG\_PATH} to the complete
+path where this file is located.
+
+\section{Concluding Remarks}
+In office hours and in class, we will discuss how to use C++ and CORBA
+in order to develop your solutions. Note that this assignment will
+teach you many skills required to become adept at network programming.
+However, it also will require a great deal of thought and planning.
+Please make sure you start early, come to office hours, and ask lots
+of questions.
+
+\end{document}
diff --git a/apps/Orbix-Examples/Logger/client.cpp b/apps/Orbix-Examples/Logger/client.cpp
new file mode 100644
index 00000000000..aea23379488
--- /dev/null
+++ b/apps/Orbix-Examples/Logger/client.cpp
@@ -0,0 +1,142 @@
+// A client for the distributed logger example. This program reads
+// @(#)client.cpp 1.1 10/18/96
+
+// from either stdin or from a redirected file and sends all the
+// contents to the logging server. It also computes how long it takes
+// to send this stuff.
+
+#include "ace/Log_Msg.h"
+#include "Logger.h"
+
+// maximum message size
+static size_t max_message_size = BUFSIZ;
+
+// Default behavior is to use the locator service.
+static char *hostname = 0;
+
+// Should we prompt the user?
+static int user_prompt;
+
+static void
+parse_args (int argc, char *argv[])
+{
+ extern char *optarg;
+ extern int optind;
+ int c;
+
+ ACE_LOG_MSG->open (argv[0]);
+
+ // If a file has been redirected, don't activate user prompts
+ if (ACE_OS::isatty (0))
+ user_prompt = 1;
+ else
+ user_prompt = 0;
+
+ while ((c = ACE_OS::getopt (argc, argv, "m:h:")) != -1)
+ switch (c)
+ {
+ case 'm':
+ max_message_size = ACE_OS::atoi (optarg) * BUFSIZ;
+ break;
+ case 'h':
+ hostname = optarg;
+ break;
+ default:
+ ACE_ERROR ((LM_ERROR, "%n: -h host -m max_message_size (in kbytes)\n%a", 1));
+ /* NOTREACHED */
+ }
+}
+
+// Enable/disable verbose logging.
+
+static int
+toggle_verbose (Logger &logger)
+{
+ int verbose_value;
+
+ verbose_value = logger.verbose ();
+ logger.verbose (!verbose_value);
+ return 0;
+}
+
+// Transmit messages to the server.
+
+int
+transmit (Logger &logger, char buf[], ACE_HANDLE handle = 0)
+{
+ if (user_prompt)
+ cout << "\nEnter message ('Q':quit,'V':toggle verbose):\n" << flush;
+
+ ssize_t nbytes = ACE_OS::read (handle, buf, max_message_size);
+
+ if (nbytes <= 0)
+ return nbytes; // End of file or error.
+ buf[nbytes] = '\0';
+
+ if (user_prompt)
+ {
+ if (buf[0] == 'Q' || buf[0] == 'q')
+ return 0;
+ // toggle verbose?
+ else if (buf[0] == 'V' || buf[0] == 'v')
+ toggle_verbose (logger);
+ }
+
+ // send the message to the logger
+ if (logger.log (logger::LM_DEBUG, buf, nbytes) == -1)
+ return -1;
+ else
+ return nbytes;
+}
+
+// Print the results of the tests.
+
+void
+report_results (profile_logger::Elapsed_Time &et, size_t total_bytes)
+{
+ ACE_DEBUG ((LM_DEBUG,
+ "real time = %8.2f\n"
+ "user time = %8.2f\n"
+ "sys time = %8.2f\n"
+ "mbits sec = %8.2f\n",
+ et.real_time, et.user_time, et.system_time,
+ (total_bytes / et.real_time) * 8.0 / 1024.0 / 1024.0));
+}
+
+int
+main (int argc, char **argv)
+{
+ parse_args (argc,argv);
+
+ // Pointer to the logger object that will be used.
+ Logger logger (hostname, max_message_size);
+ char *buf = new char [max_message_size];
+ size_t total_bytes = 0;
+ size_t nbytes = 0;
+
+ logger.start_timer ();
+
+ // Transmit logging records until user quits.
+
+ for (int done = 0; done == 0;)
+ switch (nbytes = transmit (logger, buf))
+ {
+ case -1:
+ ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "transmit"), -1);
+ /* NOTREACHED */
+ case 0:
+ done = 1;
+ break;
+ default:
+ total_bytes += nbytes;
+ break;
+ }
+
+ profile_logger::Elapsed_Time et;
+
+ if (logger.stop_timer (et) == -1)
+ ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "stop timer"), -1);
+
+ report_results (et, total_bytes);
+ return 0;
+}
diff --git a/apps/Orbix-Examples/Logger/logger.hh b/apps/Orbix-Examples/Logger/logger.hh
new file mode 100644
index 00000000000..0d0eeeca2f0
--- /dev/null
+++ b/apps/Orbix-Examples/Logger/logger.hh
@@ -0,0 +1,434 @@
+
+#ifndef logger_hh
+#define logger_hh
+
+#include <CORBA.h>
+
+#include <string.h>
+
+
+#ifndef _IDL_SEQUENCE_char_defined
+#define _IDL_SEQUENCE_char_defined
+
+struct IONANC__IDL_SEQUENCE_char;
+struct _IDL_SEQUENCE_char {
+ unsigned long _maximum;
+ unsigned long _length;
+ char *_buffer;
+
+ operator IONANC__IDL_SEQUENCE_char();
+ operator const IONANC__IDL_SEQUENCE_char() const;
+ _IDL_SEQUENCE_char& operator= (const IONANC__IDL_SEQUENCE_char&);
+
+ _IDL_SEQUENCE_char& operator= (const _IDL_SEQUENCE_char&);
+ _IDL_SEQUENCE_char (const _IDL_SEQUENCE_char&);
+
+ _IDL_SEQUENCE_char (unsigned long IT_size = 0);
+
+ ~_IDL_SEQUENCE_char () { if (_buffer) delete [] _buffer; }
+
+ char& operator [] (unsigned long IT_i) const {return _buffer[IT_i]; }
+
+ void encodeOp (CORBA::Request &IT_r) const;
+ void decodeOp (CORBA::Request &IT_r);
+ void decodeInOutOp (CORBA::Request &IT_r);
+};
+
+struct IONANC__IDL_SEQUENCE_char {
+ unsigned long _maximum;
+ unsigned long _length;
+ char *_buffer;
+
+ char& operator [] (unsigned long IT_i) const;
+
+ operator _IDL_SEQUENCE_char ();
+
+ operator const _IDL_SEQUENCE_char () const;
+
+};
+
+
+
+#endif
+
+
+#ifndef _logger_defined
+#define _logger_defined
+class logger_dispatch : public virtual CORBA::PPTR {
+public:
+
+ logger_dispatch (void *IT_p, CORBA::Object* IT_o, const char *IT_m,
+ CORBA::LoaderClass *IT_l, char *IT_i, void* IT_im)
+ : CORBA::PPTR (IT_p,IT_o,IT_m,IT_l,IT_i,IT_im) {}
+
+
+ logger_dispatch (char *IT_OR, void *IT_p, CORBA::Object *IT_o)
+ : CORBA::PPTR (IT_OR,IT_p,IT_o) {}
+
+
+ logger_dispatch () {}
+
+ logger_dispatch (void *IT_p, CORBA::Object *IT_o, const char *IT_m,
+ char *IT_i, CORBA::Object* IT_ob, void* IT_im)
+ : CORBA::PPTR (IT_p,IT_o,IT_m,IT_i,IT_ob,IT_im) {}
+
+
+ virtual unsigned char dispatch (CORBA::Request &IT_r,
+ unsigned char IT_isTarget, void* IT_pp=NULL);
+
+
+};
+
+class logger;
+
+
+#ifndef loggerForwH
+#define loggerForwH
+CORBA::ObjectRef logger_getBase (void *);
+void logger_release (void *, CORBA::Environment &IT_env=CORBA::default_environment);
+logger* logger_duplicate (void *, CORBA::Environment &IT_env=CORBA::default_environment);
+#endif
+#define logger_IMPL "logger"
+
+
+class logger;
+#define logger_IR "logger"
+#define logger_IMPL "logger"
+
+typedef logger* loggerRef;
+typedef logger* logger_ptr;
+class logger: public virtual CORBA::Object {
+public:
+ logger (char *IT_OR);
+ logger () : CORBA::Object (1) {}
+ logger* _duplicate(
+ CORBA::Environment &IT_env=CORBA::default_environment) {
+ CORBA::Object::_duplicate (IT_env); return this; }
+ static logger* _bind (const char* IT_markerServer, const char* host,
+ const CORBA::Context &IT_c,
+ CORBA::Environment &IT_env=CORBA::default_environment);
+ static logger* _bind (CORBA::Environment &IT_env);
+ static logger* _bind (const char* IT_markerServer=NULL, const char* host=NULL,
+ CORBA::Environment &IT_env=CORBA::default_environment);
+ static logger* _narrow (CORBA::Object* , CORBA::Environment &IT_env=CORBA::default_environment);
+enum Log_Priority {LM_MESSAGE,LM_DEBUG,LM_WARNING,LM_ERROR,LM_EMERG};
+
+#ifndef logger_Log_Record_defined
+#define logger_Log_Record_defined
+
+struct IONANC_Log_Record;
+struct Log_Record {
+ logger::Log_Priority type;
+ long time;
+ long app_id;
+ long host_addr;
+ _IDL_SEQUENCE_char msg_data;
+
+ void encodeOp (CORBA::Request &IT_r) const;
+ void decodeOp (CORBA::Request &IT_r);
+ void decodeInOutOp (CORBA::Request &IT_r);
+ Log_Record(const Log_Record &);
+ Log_Record();
+ operator logger::IONANC_Log_Record();
+ operator const logger::IONANC_Log_Record() const;
+ Log_Record& operator= (const IONANC_Log_Record&);
+ ~Log_Record();
+ Log_Record& operator= (const Log_Record&);
+};
+
+struct IONANC_Log_Record {
+ logger::Log_Priority type;
+ long time;
+ long app_id;
+ long host_addr;
+ IONANC__IDL_SEQUENCE_char msg_data;
+ operator logger::Log_Record ();
+ operator const logger::Log_Record () const;
+ };
+
+
+#endif
+
+ virtual void log (const logger::Log_Record& log_rec, CORBA::Environment &IT_env=CORBA::default_environment);
+ virtual void verbose (char verbose, CORBA::Environment &IT_env=CORBA::default_environment);
+ virtual char verbose (CORBA::Environment &IT_env=CORBA::default_environment);
+};
+
+
+#define TIE_logger(X) logger##X
+
+#define DEF_TIE_logger(X) \
+ class logger##X : public virtual logger { \
+ X* m_obj; \
+ public: \
+ \
+ logger##X (X *objp, const char* m="", CORBA::LoaderClass *l=nil)\
+ : logger(), CORBA::Object (), m_obj(objp) { \
+ m_pptr = new logger_dispatch \
+ (( logger*)this,(CORBA::Object*)this,m,l,logger_IR,m_obj); \
+ } \
+ logger##X (CORBA::Object *IT_p, const char* IT_m="", void *IT_q=nil)\
+ : logger(), CORBA::Object () { \
+ m_pptr = new logger_dispatch \
+ (( logger*)this,(CORBA::Object*)this,IT_m,logger_IR,IT_p,IT_q); \
+ m_obj = (X*)(m_pptr->getImplObj ()); \
+ } \
+ \
+ virtual ~logger##X () { \
+ if (_okToDeleteImpl ()) delete m_obj; } \
+ \
+ virtual void* _deref () { \
+ return m_obj; } \
+ \
+ virtual void log (const logger::Log_Record& log_rec, CORBA::Environment &IT_env) {\
+m_obj->log ( log_rec,IT_env);\
+}\
+ \
+virtual void verbose (char verbose, CORBA::Environment &IT_env) {\
+ m_obj->verbose(verbose,IT_env); }\
+ \
+virtual char verbose (CORBA::Environment &IT_env) {\
+return m_obj->verbose(IT_env); }\
+ \
+ };
+
+
+#define QUALS_logger \
+ virtual void log (const logger::Log_Record& log_rec, CORBA::Environment &IT_env) {\
+m_obj->log ( log_rec,IT_env);\
+}\
+ \
+virtual void verbose (char verbose, CORBA::Environment &IT_env) {\
+ m_obj->verbose(verbose,IT_env); }\
+ \
+virtual char verbose (CORBA::Environment &IT_env) {\
+return m_obj->verbose(IT_env); }\
+
+
+
+
+class loggerProxyFactoryClass : public virtual CORBA::ObjectFactoryClass {
+public:
+ loggerProxyFactoryClass (unsigned char IT_p=0)
+ : CORBA::ProxyFactory (logger_IR, IT_p) {}
+
+ virtual void* New (char *IT_OR, CORBA::Environment&);
+
+ virtual void* New2 ();
+
+ virtual void* IT_castUp (void *IT_p, char* IT_s);
+
+ virtual CORBA::PPTR* pptr (void *IT_p);
+
+ virtual void baseInterfaces (_IDL_SEQUENCE_string&);
+
+
+};
+
+extern loggerProxyFactoryClass loggerProxyFactory;
+
+
+
+class loggerBOAImpl : public virtual logger {
+public:
+ loggerBOAImpl (const char *m="", CORBA::LoaderClass *l=NULL) {
+ if (CORBA::PPTR::isOK (m_pptr, logger_IR))
+ m_pptr = new logger_dispatch ( (logger*)this,
+ (CORBA::Object*)this, m, l, logger_IR, this);
+}
+
+ virtual void log (const logger::Log_Record& log_rec, CORBA::Environment &IT_env=CORBA::default_environment) =0;
+ virtual void verbose (char verbose, CORBA::Environment &IT_env=CORBA::default_environment)=0;
+ virtual char verbose (CORBA::Environment &IT_env=CORBA::default_environment)=0;
+};
+
+
+#endif
+
+
+#ifndef _profile_logger_defined
+#define _profile_logger_defined
+class profile_logger_dispatch : public virtual logger_dispatch {
+public:
+
+ profile_logger_dispatch (void *IT_p, CORBA::Object* IT_o, const char *IT_m,
+ CORBA::LoaderClass *IT_l, char *IT_i, void* IT_im)
+ : CORBA::PPTR (IT_p,IT_o,IT_m,IT_l,IT_i,IT_im) {}
+
+
+ profile_logger_dispatch (char *IT_OR, void *IT_p, CORBA::Object *IT_o)
+ : CORBA::PPTR (IT_OR,IT_p,IT_o) {}
+
+
+ profile_logger_dispatch () {}
+
+ profile_logger_dispatch (void *IT_p, CORBA::Object *IT_o, const char *IT_m,
+ char *IT_i, CORBA::Object* IT_ob, void* IT_im)
+ : CORBA::PPTR (IT_p,IT_o,IT_m,IT_i,IT_ob,IT_im) {}
+
+
+ virtual unsigned char dispatch (CORBA::Request &IT_r,
+ unsigned char IT_isTarget, void* IT_pp=NULL);
+
+
+};
+
+class profile_logger;
+
+
+#ifndef profile_loggerForwH
+#define profile_loggerForwH
+CORBA::ObjectRef profile_logger_getBase (void *);
+void profile_logger_release (void *, CORBA::Environment &IT_env=CORBA::default_environment);
+profile_logger* profile_logger_duplicate (void *, CORBA::Environment &IT_env=CORBA::default_environment);
+#endif
+#define profile_logger_IMPL "profile_logger"
+
+
+class profile_logger;
+#define profile_logger_IR "profile_logger"
+#define profile_logger_IMPL "profile_logger"
+
+typedef profile_logger* profile_loggerRef;
+typedef profile_logger* profile_logger_ptr;
+class profile_logger: public virtual logger {
+public:
+ profile_logger (char *IT_OR);
+ profile_logger () : CORBA::Object (1) {}
+ profile_logger* _duplicate(
+ CORBA::Environment &IT_env=CORBA::default_environment) {
+ CORBA::Object::_duplicate (IT_env); return this; }
+ static profile_logger* _bind (const char* IT_markerServer, const char* host,
+ const CORBA::Context &IT_c,
+ CORBA::Environment &IT_env=CORBA::default_environment);
+ static profile_logger* _bind (CORBA::Environment &IT_env);
+ static profile_logger* _bind (const char* IT_markerServer=NULL, const char* host=NULL,
+ CORBA::Environment &IT_env=CORBA::default_environment);
+ static profile_logger* _narrow (CORBA::Object* , CORBA::Environment &IT_env=CORBA::default_environment);
+
+#ifndef profile_logger_Elapsed_Time_defined
+#define profile_logger_Elapsed_Time_defined
+
+struct Elapsed_Time {
+ double real_time;
+ double user_time;
+ double system_time;
+
+ void encodeOp (CORBA::Request &IT_r) const;
+ void decodeOp (CORBA::Request &IT_r);
+ void decodeInOutOp (CORBA::Request &IT_r);
+};
+
+
+#endif
+
+ virtual void start_timer (CORBA::Environment &IT_env=CORBA::default_environment);
+ virtual void stop_timer (profile_logger::Elapsed_Time& et, CORBA::Environment &IT_env=CORBA::default_environment);
+};
+
+
+#define TIE_profile_logger(X) profile_logger##X
+
+#define DEF_TIE_profile_logger(X) \
+ class profile_logger##X : public virtual profile_logger { \
+ X* m_obj; \
+ public: \
+ \
+ profile_logger##X (X *objp, const char* m="", CORBA::LoaderClass *l=nil)\
+ : profile_logger(), CORBA::Object (), m_obj(objp) { \
+ m_pptr = new profile_logger_dispatch \
+ (( profile_logger*)this,(CORBA::Object*)this,m,l,profile_logger_IR,m_obj); \
+ } \
+ profile_logger##X (CORBA::Object *IT_p, const char* IT_m="", void *IT_q=nil)\
+ : profile_logger(), CORBA::Object () { \
+ m_pptr = new profile_logger_dispatch \
+ (( profile_logger*)this,(CORBA::Object*)this,IT_m,profile_logger_IR,IT_p,IT_q); \
+ m_obj = (X*)(m_pptr->getImplObj ()); \
+ } \
+ \
+ virtual ~profile_logger##X () { \
+ if (_okToDeleteImpl ()) delete m_obj; } \
+ \
+ virtual void* _deref () { \
+ return m_obj; } \
+ \
+ virtual void log (const logger::Log_Record& log_rec, CORBA::Environment &IT_env) {\
+m_obj->log ( log_rec,IT_env);\
+}\
+ \
+virtual void verbose (char verbose, CORBA::Environment &IT_env) {\
+ m_obj->verbose(verbose,IT_env); }\
+ \
+virtual char verbose (CORBA::Environment &IT_env) {\
+return m_obj->verbose(IT_env); }\
+ virtual void start_timer (CORBA::Environment &IT_env) {\
+m_obj->start_timer (IT_env);\
+}\
+ \
+ virtual void stop_timer (profile_logger::Elapsed_Time& et, CORBA::Environment &IT_env) {\
+m_obj->stop_timer ( et,IT_env);\
+}\
+ \
+ };
+
+
+#define QUALS_profile_logger \
+ virtual void log (const logger::Log_Record& log_rec, CORBA::Environment &IT_env) {\
+m_obj->log ( log_rec,IT_env);\
+}\
+ \
+virtual void verbose (char verbose, CORBA::Environment &IT_env) {\
+ m_obj->verbose(verbose,IT_env); }\
+ \
+virtual char verbose (CORBA::Environment &IT_env) {\
+return m_obj->verbose(IT_env); }\
+ virtual void start_timer (CORBA::Environment &IT_env) {\
+m_obj->start_timer (IT_env);\
+}\
+ \
+ virtual void stop_timer (profile_logger::Elapsed_Time& et, CORBA::Environment &IT_env) {\
+m_obj->stop_timer ( et,IT_env);\
+}\
+
+
+
+
+class profile_loggerProxyFactoryClass : public virtual loggerProxyFactoryClass {
+public:
+ profile_loggerProxyFactoryClass (unsigned char IT_p=0)
+ : CORBA::ProxyFactory (profile_logger_IR, IT_p) {}
+
+ virtual void* New (char *IT_OR, CORBA::Environment&);
+
+ virtual void* New2 ();
+
+ virtual void* IT_castUp (void *IT_p, char* IT_s);
+
+ virtual CORBA::PPTR* pptr (void *IT_p);
+
+ virtual void baseInterfaces (_IDL_SEQUENCE_string&);
+
+
+};
+
+extern profile_loggerProxyFactoryClass profile_loggerProxyFactory;
+
+
+
+class profile_loggerBOAImpl : public virtual profile_logger {
+public:
+ profile_loggerBOAImpl (const char *m="", CORBA::LoaderClass *l=NULL) {
+ if (CORBA::PPTR::isOK (m_pptr, profile_logger_IR))
+ m_pptr = new profile_logger_dispatch ( (profile_logger*)this,
+ (CORBA::Object*)this, m, l, profile_logger_IR, this);
+}
+
+ virtual void start_timer (CORBA::Environment &IT_env=CORBA::default_environment) =0;
+ virtual void stop_timer (profile_logger::Elapsed_Time& et, CORBA::Environment &IT_env=CORBA::default_environment) =0;
+};
+
+
+#endif
+
+
+#endif
diff --git a/apps/Orbix-Examples/Logger/logger.idl b/apps/Orbix-Examples/Logger/logger.idl
new file mode 100644
index 00000000000..0fe673a84b9
--- /dev/null
+++ b/apps/Orbix-Examples/Logger/logger.idl
@@ -0,0 +1,56 @@
+/* -*- C++ -*- */
+// @(#)logger.idl 1.1 10/18/96
+
+// logger.idl
+
+interface logger
+// = TITLE
+// This is the CORBA interface for the logger class.
+{
+ // = Types of logging messages.
+ enum Log_Priority
+ {
+ LM_MESSAGE,
+ LM_DEBUG,
+ LM_WARNING,
+ LM_ERROR,
+ LM_EMERG
+ };
+
+ // = Format of the logging record.
+ struct Log_Record
+ {
+ Log_Priority type; // Type of logging message.
+ long time; // Time stamp at sender.
+ long app_id; // Process ID of sender.
+ long host_addr; // IP address of the sender.
+ sequence<char> msg_data; // Sender-specific logging message.
+ };
+
+ oneway void log (in Log_Record log_rec);
+ // Transmit a Log_Record to the logging server.
+
+ attribute char verbose;
+ // Toggle verbose formatting
+};
+
+interface profile_logger
+ : logger // Profile_Logger IS-A Logger
+// = TITLE
+// IDL Profile Logger definition that is used
+// to compute statistics about the logging.
+{
+ // = Stores the amount of time that has elapsed.
+ struct Elapsed_Time
+ {
+ double real_time;
+ double user_time;
+ double system_time;
+ };
+
+ void start_timer ();
+ // Activate the timer.
+
+ void stop_timer (out Elapsed_Time et);
+ // Deactivate the timer and return the elapsed time.
+};
diff --git a/apps/Orbix-Examples/Logger/loggerS.cpp b/apps/Orbix-Examples/Logger/loggerS.cpp
new file mode 100644
index 00000000000..b1210683886
--- /dev/null
+++ b/apps/Orbix-Examples/Logger/loggerS.cpp
@@ -0,0 +1,141 @@
+
+// @(#)loggerS.cpp 1.1 10/18/96
+
+#include "logger.hh"
+
+
+#define logger_dispatch_impl
+
+unsigned char logger_dispatch::dispatch (CORBA::Request &IT_r,
+ unsigned char IT_isTarget, void *IT_pp) {
+ if (!IT_pp)
+ IT_pp = m_obj;
+ const char *IT_s = IT_r.getOperation ();
+ if (!strcmp(IT_s,"log")) {
+ CORBA::Environment IT_env (IT_r);
+ CORBA::Filter* IT_f = CORBA::Orbix.getFilter ();
+ if (!IT_r.tcAssert ("\
+Ro~log~+log_rec{R~logger::Log_Record~type{E~logger::Log_Priority~LM_MESSAGE,LM_DEBUG,LM_WARNING,LM_ERROR,LM_EMERG},time{l},app_id{l},host_addr{l},msg_data{S{c},0}},>{v},O{}\
+"))
+ return 1;
+ logger::Log_Record log_rec;
+ log_rec.decodeOp (IT_r);
+
+ if (IT_f && !IT_r.isException (IT_env))
+ IT_f->inRequestPostM (IT_r, IT_env);
+ if (!IT_r.isException (IT_env))
+ ((logger*)IT_pp)->log ( log_rec, IT_env);
+
+ IT_r.replyNoResults (CORBA::Flags(CORBA::INV_NO_RESPONSE),IT_env);
+ return 1;
+ }
+
+ else if (!strcmp (IT_s,"_get_verbose")) {
+ char verbose;
+ CORBA::Environment IT_env (IT_r);
+ CORBA::Filter* IT_f = CORBA::Orbix.getFilter ();
+ if (!IT_r.tcAssert ("\
+Ro~_get_verbose~>{c},N{}\
+"))
+ return 1;
+ if (IT_f)
+ IT_f->inRequestPostM (IT_r, IT_env);
+ if (!IT_r.isException (IT_env))
+ verbose = ((logger*)IT_pp)->verbose(IT_env);
+
+ if (!IT_r.isException (IT_env)) {
+ if (!IT_r.convertToReply ("\
+c\
+", IT_env)) return 1;
+ IT_r << verbose;
+ }
+ else IT_r.makeSystemException (IT_env);
+
+ return 1;
+ }
+ else if (!strcmp (IT_s,"_set_verbose")) {
+ CORBA::Environment IT_env (IT_r);
+ CORBA::Filter* IT_f = CORBA::Orbix.getFilter ();
+ if (IT_r.tcAssert ("\
+Ro~_set_verbose~+{c},>{v},N{}\
+")) {
+ char verbose;
+ IT_r >> verbose;
+ if (IT_f && !IT_r.isException (IT_env))
+ IT_f->inRequestPostM (IT_r, IT_env);
+ if (!IT_r.isException (IT_env))
+ ((logger*)IT_pp)->verbose(verbose, IT_env);
+ }
+ IT_r.replyNoResults (IT_env);
+ return 1;
+ }
+
+ else if (IT_isTarget)
+ IT_r.makeRuntimeException2 ();
+
+ return 0;
+}
+
+#define profile_logger_dispatch_impl
+
+unsigned char profile_logger_dispatch::dispatch (CORBA::Request &IT_r,
+ unsigned char IT_isTarget, void *IT_pp) {
+ if (!IT_pp)
+ IT_pp = m_obj;
+ const char *IT_s = IT_r.getOperation ();
+ if (!strcmp(IT_s,"start_timer")) {
+ CORBA::Environment IT_env (IT_r);
+ CORBA::Filter* IT_f = CORBA::Orbix.getFilter ();
+ if (!IT_r.tcAssert ("\
+Ro~start_timer~>{v},N{}\
+"))
+ return 1;
+
+ if (IT_f && !IT_r.isException (IT_env))
+ IT_f->inRequestPostM (IT_r, IT_env);
+ if (!IT_r.isException (IT_env))
+ ((profile_logger*)IT_pp)->start_timer (IT_env);
+
+ IT_r.replyNoResults (IT_env);
+ return 1;
+ }
+
+ else if (!strcmp(IT_s,"stop_timer")) {
+ CORBA::Environment IT_env (IT_r);
+ CORBA::Filter* IT_f = CORBA::Orbix.getFilter ();
+ if (!IT_r.tcAssert ("\
+Ro~stop_timer~-et{R~profile_logger::Elapsed_Time~real_time{d},user_time{d},system_time{d}},>{v},N{}\
+"))
+ return 1;
+ profile_logger::Elapsed_Time et;
+
+ if (IT_f && !IT_r.isException (IT_env))
+ IT_f->inRequestPostM (IT_r, IT_env);
+ if (!IT_r.isException (IT_env))
+ ((profile_logger*)IT_pp)->stop_timer ( et, IT_env);
+
+
+ if (!IT_r.isException (IT_env)) {
+ if (!IT_r.convertToReply ("\
+v\
+", IT_env)) return 1;
+ et.encodeOp (IT_r);
+ }
+
+ else IT_r.makeSystemException (IT_env);
+ return 1;
+ }
+
+ else if (logger_dispatch::dispatch (IT_r, 0,
+ (logger*)((profile_logger*)IT_pp))) {
+ return 1;
+ }
+
+ else if (IT_isTarget)
+ IT_r.makeRuntimeException2 ();
+
+ return 0;
+}
+
+#include "loggerC.cpp"
+
diff --git a/apps/Orbix-Examples/Logger/logger_i.cpp b/apps/Orbix-Examples/Logger/logger_i.cpp
new file mode 100644
index 00000000000..cfd5a5b0d8b
--- /dev/null
+++ b/apps/Orbix-Examples/Logger/logger_i.cpp
@@ -0,0 +1,120 @@
+// Implementation of the logger object.
+// @(#)logger_i.cpp 1.1 10/18/96
+
+
+#include "ace/OS.h"
+#include <iostream.h>
+#include "logger_i.h"
+
+// Select non-verbose logging by default.
+
+logger_i::logger_i (int verbose)
+ : verbose_value_ (verbose)
+{
+ if (ACE_OS::getenv ("NO_MESSAGES") == 0)
+ this->verbose_message_ = 1;
+ else
+ this->verbose_message_ = 0;
+}
+
+// Implement the log method.
+
+void
+logger_i::log (const logger::Log_Record &log_rec, CORBA::Environment &IT_env)
+{
+ if (this->verbose_value_) // If verbose mode is on
+ {
+ char *tm;
+
+ // Convert time
+ if ((tm = ACE_OS::ctime (&log_rec.time)) == 0)
+ cerr << "ctime failed" << endl;
+ else
+ {
+ hostent *hp;
+
+ /* 01234567890123456789012345 */
+ /* Wed Oct 18 14:25:36 1989n0 */
+ tm[24] = '@';
+ cout << tm;
+
+ // Get host name of client
+
+ if ((hp = gethostbyaddr((char *) &log_rec.host_addr,
+ sizeof log_rec.host_addr, AF_INET)) == NULL)
+ {
+ cerr << "server: error in calling gethostbyaddr" << endl;
+ cerr << "h_errno = " << h_errno << endl;
+ return;
+ }
+ else // Output client hostname.
+ cout << hp->h_name << "@";
+
+ // Output PID of client
+ cout << log_rec.app_id << "@";
+
+ // Output priority
+
+ switch (log_rec.type)
+ {
+ case logger::LM_DEBUG:
+ cout << "LM_DEBUG";
+ break;
+ case logger::LM_WARNING:
+ cout << "LM_WARNING";
+ break;
+ case logger::LM_ERROR:
+ cout << "LM_ERROR";
+ break;
+ case logger::LM_EMERG:
+ cout << "LM_EMERG";
+ break;
+ }
+ }
+ }
+ if (this->verbose_message_)
+ {
+ cout << "::";
+ // Output message
+ cout.write (log_rec.msg_data._buffer, log_rec.msg_data._length) << flush;
+ }
+}
+
+// Enable/disable verbosity.
+
+void
+logger_i::verbose (char verbose, CORBA::Environment &IT_env)
+{
+ this->verbose_value_ = verbose;
+}
+
+// Report current verbosity level.
+
+char
+logger_i::verbose (CORBA::Environment &IT_env)
+{
+ return this->verbose_value_;
+}
+
+// Profile_Logger_i
+
+void
+profile_logger_i::start_timer (CORBA::Environment &IT_env)
+{
+ this->pt_.start ();
+}
+
+void
+profile_logger_i::stop_timer (profile_logger::Elapsed_Time& et,
+ CORBA::Environment &IT_env)
+{
+ this->pt_.stop ();
+
+ ACE_Profile_Timer::ACE_Elapsed_Time e;
+
+ this->pt_.elapsed_time (e);
+
+ et.real_time = e.real_time;
+ et.user_time = e.user_time;
+ et.system_time = e.system_time;
+}
diff --git a/apps/Orbix-Examples/Logger/logger_i.h b/apps/Orbix-Examples/Logger/logger_i.h
new file mode 100644
index 00000000000..65253527370
--- /dev/null
+++ b/apps/Orbix-Examples/Logger/logger_i.h
@@ -0,0 +1,75 @@
+/* -*- C++ -*- */
+// @(#)logger_i.h 1.1 10/18/96
+
+
+#include "ace/Profile_Timer.h"
+#define EXCEPTIONS
+#include "logger.hh"
+
+class logger_i
+#if defined (USE_BOA_IMPL)
+ : virtual public loggerBOAImpl
+#endif /* USE_BOA_IMPL */
+ // = TITLE
+ // Implementation of the logger interface.
+ //
+ // = DESCRIPTION
+ // Uses either the BOAImpl or the DEF_TIE approach,
+ // depending on the #ifdef
+{
+public:
+ logger_i (int verbose = 0);
+ // Select non-verbose logging by default.
+
+ virtual void log (const logger::Log_Record &log_rec, CORBA::Environment &IT_env);
+ // Implement the log method.
+
+ virtual void verbose (char verbose, CORBA::Environment &IT_env);
+ // Enable/disable verbosity.
+
+ virtual char verbose (CORBA::Environment &IT_env);
+ // Report current verbosity level.
+
+private:
+ unsigned char verbose_value_;
+ // Indicate if we are using verbose logging or not.
+
+ unsigned char verbose_message_;
+ // Indicate if we outputting the messages (turn off if you
+ // want to conduct timing tests that just measure throughput).
+};
+
+class profile_logger_i :
+#if defined (USE_BOA_IMPL)
+ public virtual profile_loggerBOAImpl,
+ public virtual Logger_i
+#else /* USE_TIE */
+ public logger_i
+#endif /* USE_BOA_IMPL */
+ // = TITLE
+ // Implementation of the profiler logger interface.
+ //
+ // = DESCRIPTION
+ // Uses the BOAImpl approach.
+{
+public:
+ virtual void start_timer (CORBA::Environment &env);
+ // Activate the timer.
+
+ virtual void stop_timer (profile_logger::Elapsed_Time &et,
+ CORBA::Environment &env);
+ // Deactivate the timer and return the elapsed time.
+
+private:
+ ACE_Profile_Timer pt_;
+ // Object that keeps track of the user and system execution time.
+};
+
+#if !defined (USE_BOA_IMPL)
+// Indicate that the C++ classes logger_i and profile_logger_i implement
+// the IDL interface logger and profile_logger, respectively:
+
+DEF_TIE_logger (logger_i)
+DEF_TIE_profile_logger (profile_logger_i)
+
+#endif /* USE_BOA_IMPL */
diff --git a/apps/Orbix-Examples/Logger/server.cpp b/apps/Orbix-Examples/Logger/server.cpp
new file mode 100644
index 00000000000..c41aa474dcf
--- /dev/null
+++ b/apps/Orbix-Examples/Logger/server.cpp
@@ -0,0 +1,40 @@
+// server.C
+// @(#)server.cpp 1.1 10/18/96
+
+
+// The server for the logger example.
+// This uses the TRY,CATCHANY,ENDTRY macros for error testing.
+
+// The executable file generated from this code should be registered
+// (under the name 'logger') using the 'putit' command.
+
+#include <iostream.h>
+#include "logger_i.h"
+
+int
+main (int, char *[])
+{
+ // Tell the server not to hang up while clients are connected.
+ CORBA::Orbix.setNoHangup (1);
+
+ // create a logger object - using the implementation class logger_i
+#if defined (USE_BOA_IMPL)
+ profile_logger_i profile_logger;
+#else
+ TIE_profile_logger (profile_logger_i) profile_logger (new profile_logger_i);
+#endif /* USE_BOA_IMPL */
+
+ TRY {
+ // tell Orbix that we have completed the server's initialisation:
+ CORBA::Orbix.impl_is_ready (profile_logger_IMPL, IT_X);
+ } CATCHANY {
+ // an error occured calling impl_is_ready () - output the error.
+ cout << IT_X << endl;
+ } ENDTRY;
+
+ // impl_is_ready() returns only when Orbix times-out an idle server
+ // (or an error occurs).
+ cerr << "server exiting" << endl;
+
+ return 0;
+}