diff options
author | levine <levine@ae88bc3d-4319-0410-8dbf-d08b4c9d3795> | 1996-10-21 21:41:34 +0000 |
---|---|---|
committer | levine <levine@ae88bc3d-4319-0410-8dbf-d08b4c9d3795> | 1996-10-21 21:41:34 +0000 |
commit | a5fdebc5f6375078ec1763850a4ca23ec7fe6458 (patch) | |
tree | bcf0a25c3d45a209a6e3ac37b233a4812f29c732 /apps/Orbix-Examples/Logger | |
download | ATCD-a5fdebc5f6375078ec1763850a4ca23ec7fe6458.tar.gz |
Initial revision
Diffstat (limited to 'apps/Orbix-Examples/Logger')
-rw-r--r-- | apps/Orbix-Examples/Logger/Logger.cpp | 131 | ||||
-rw-r--r-- | apps/Orbix-Examples/Logger/Logger.h | 56 | ||||
-rw-r--r-- | apps/Orbix-Examples/Logger/Makefile | 63 | ||||
-rw-r--r-- | apps/Orbix-Examples/Logger/Orbix.hostgroups | 1 | ||||
-rw-r--r-- | apps/Orbix-Examples/Logger/Orbix.hosts | 3 | ||||
-rw-r--r-- | apps/Orbix-Examples/Logger/README | 35 | ||||
-rw-r--r-- | apps/Orbix-Examples/Logger/a1.tex | 232 | ||||
-rw-r--r-- | apps/Orbix-Examples/Logger/client.cpp | 142 | ||||
-rw-r--r-- | apps/Orbix-Examples/Logger/logger.hh | 434 | ||||
-rw-r--r-- | apps/Orbix-Examples/Logger/logger.idl | 56 | ||||
-rw-r--r-- | apps/Orbix-Examples/Logger/loggerS.cpp | 141 | ||||
-rw-r--r-- | apps/Orbix-Examples/Logger/logger_i.cpp | 120 | ||||
-rw-r--r-- | apps/Orbix-Examples/Logger/logger_i.h | 75 | ||||
-rw-r--r-- | apps/Orbix-Examples/Logger/server.cpp | 40 |
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; +} |