Overview of Logging Strategy Service
The Logging Strategy Service can be used to control the output of all the
network services. It can be invoked with certain flags that determine
where the output of all the services should go. The Logging Strategy
Service sets the flags in ACE_Log_Msg, which controls all the streams
through macros such as ACE_DEBUG, ACE_ERROR, and ACE_ERROR_RETURN. If
default behavior is required, the Logging Strategy Service need not be
invoked or it can be invoked with no parameters.
The following describes how to configure the Logging Strategy
Service:
- Startup configuration
Here are the command line arguments that can be given to the Logging
Strategy Service:
-f <flag1>|<flag2>|<flag3> (etc...)
where a flag can be any of the following:
Flags
|
Description
|
STDERR
|
Write messages to stderr.
|
LOGGER
|
Write messages to the local client logger deamon.
|
OSTREAM
|
Write messages to the ostream that gets created by specifying a
filename (see below)
|
VERBOSE
|
Display messages in a verbose manner
|
SILENT
|
Do not print messages at all
|
Note: If more than one flag is specified, the flags need to be 'OR'ed
as above syntax shows. Make sure there is no space in between the flag
and '|'.
-s filename
If the OSTREAM flag is set, this can be used to specify the filename
where the output should be directed. Note that if the OSTREAM flag is
set and no filename is specified, ACE_DEFAULT_LOGFILE will be used to
write the output to.
- Examples:
Here is an example svc.conf entry that dynamically loads the
Logging Strategy Service specifying that the output be sent
to STDERR:
dynamic Logging_Strategy_Service Service_Object *
../lib/netsvcs:_make_ACE_Logging_Strategy()
"-f STDERR"
- To direct output only to STDERR, specify command line arguments as:
"-f STDERR"
- To direct output to both STDERR and a file called "mylog", specify
command line arguments as:
"-f STDERR|OSTREAM -s mylog"
Note:
- These files would vary if the services are run on NT. For
example, instead of using *.so, we would have to use *.dll.
- Values for parameters can also be passed in using environment
variables. For example, instead of specifying absolute hostname or
port numbers in the config file, we can use $HOST and $PORT,
respectively, in the file (assuming that these environment variables
have been set).
- If the environment variable LD_LIBRARY_PATH (in the case of UNIX)
or PATH (in the case of Win32) contains the path to the shared object
files or dll, then the config file can be further simplified. Instead
of specifying a path to the shared object or dll, only the
name of the shared object or dll would suffice. That is, the Service
Configurator makes use of LD_LIBRARY_PATH (on UNIX) or PATH (on Win32)
to look for the shared object files or dlls.
Back to the
ACE home page.
ace-8.0.1+dfsg.orig/netsvcs/lib/ 0000755 0001750 0001750 00000000000 14653244051 015417 5 ustar sudip sudip ace-8.0.1+dfsg.orig/netsvcs/lib/Base_Optimizer.h 0000644 0001750 0001750 00000001463 14653111173 020506 0 ustar sudip sudip /* -*- C++ -*- */
//=============================================================================
/**
* @file Base_Optimizer.h
*
* @author Per Andersson.
*/
//=============================================================================
#ifndef BASE_OPTIMIZER_H
#define BASE_OPTIMIZER_H
#include "ace/config-all.h"
#if !defined (ACE_LACKS_PRAGMA_ONCE)
# pragma once
#endif /* ACE_LACKS_PRAGMA_ONCE */
/**
* @class Base_Optimizer
*
* Thanks to Nathan Myers and Fergus Henderson for this little
* beauty.
*/
template
class Base_Optimizer : public Base
{
public:
Base_Optimizer ();
Base_Optimizer (const Base &base);
Base_Optimizer (const Base &base,
const Member &member);
Member m_;
};
#include "Base_Optimizer.cpp"
#endif /* BASE_OPTIMIZER_H */
ace-8.0.1+dfsg.orig/netsvcs/lib/Server_Logging_Handler_T.h 0000644 0001750 0001750 00000014726 14653111173 022434 0 ustar sudip sudip /* -*- C++ -*- */
//=============================================================================
/**
* @file Server_Logging_Handler_T.h
*
* @author Doug Schmidt and Per Andersson
*/
//=============================================================================
#ifndef ACE_SERVER_LOGGING_HANDLER_T_H
#define ACE_SERVER_LOGGING_HANDLER_T_H
#include "ace/config-all.h"
#if !defined (ACE_LACKS_PRAGMA_ONCE)
# pragma once
#endif /* ACE_LACKS_PRAGMA_ONCE */
#include "ace/TLI_Acceptor.h"
#include "ace/SOCK_Acceptor.h"
#include "ace/Svc_Handler.h"
#include "ace/Acceptor.h"
#include "ace/SString.h"
#include "ace/Atomic_Op.h"
#if !defined (__GNUG__)
#include "Base_Optimizer.h"
#endif /* ! __GNUG__ */
/**
* @class ACE_Server_Logging_Handler_T
*
* @brief Product object created by an . An
* receives, and frames logging
* records. The logging record is then processed by the
*
*
* Defines the classes that perform server logging daemon
* functionality.
*/
template
class ACE_Server_Logging_Handler_T : public ACE_Svc_Handler
{
public:
/// Constructor.
ACE_Server_Logging_Handler_T (ACE_Thread_Manager *,
const LOG_MESSAGE_RECEIVER &receiver );
/// Process remote logging records.
virtual int handle_input (ACE_HANDLE = ACE_INVALID_HANDLE);
protected:
/// Receive the logging record from a client.
int handle_logging_record ();
/// Common parts of open function, sets hostname and diables NONBLOCK in peer
/// called from derived classes open method.
int open_common ();
/// Count the number of logging records that arrive.
static COUNTER request_count_;
#if !defined (__GNUG__)
/**
* Packs a LOG_MESSAGE_RECEIVER and ACE_CString attribute together
* in a optimized fashion. The LOG_MESSAGE_RECEIVER class is often
* a class with no instance data.
*/
Base_Optimizer receiver_;
#else
LOG_MESSAGE_RECEIVER receiver_;
ACE_TString host_name_;
#endif /* ! __GNUG__ */
/// Name of the host we are connected to.
const ACE_TCHAR *host_name ();
/// The receiver of log records
LOG_MESSAGE_RECEIVER &receiver () { return receiver_; }
};
#if 1 //!defined (ACE_HAS_TLI)
#define LOGGING_PEER_ACCEPTOR ACE_SOCK_ACCEPTOR
#define LOGGING_PEER_STREAM ACE_SOCK_STREAM
#else /* use sockets */
#define LOGGING_PEER_ACCEPTOR ACE_TLI_ACCEPTOR
#define LOGGING_PEER_STREAM ACE_TLI_STREAM
#endif /* ACE_HAS_TLI */
/**
* @class ACE_Server_Logging_Acceptor_T
*
* @brief Factory that creates s scheduled with
* and logging records proccessed by a
*
*
* This class contains the service-specific methods that can't
* easily be factored into the .
*/
template
class ACE_Server_Logging_Acceptor_T : public ACE_Strategy_Acceptor
{
public:
/// Dynamic linking hook.
ACE_Server_Logging_Acceptor_T ();
virtual int init (int argc, ACE_TCHAR *argv[]);
protected:
/// Parse svc.conf arguments.
int parse_args (int argc, ACE_TCHAR *argv[]);
/**
* Factory that creates a new . We need to
* specialize this since the held by this Acceptor must be
* passed into the .
*/
virtual int make_svc_handler (SERVER_LOGGING_HANDLER *&);
private:
// At the moment each ACE_Server_Logging_Acceptor_T contains
// a attribute that is passed to the
// at construction. A better idea might
// be to have accessor class as template argument. The accessor
// should be a factory/strategy that hands the
// ACE_Server_Logging_Acceptor_T instance references
// to a . This makes it possible
// to change how are created without chaning the
// ACE_Server_Logging_Acceptor_T code.
#if !defined (__GNUG__)
/**
* Packs a LOG_MESSAGE_RECEIVER and ACE_CString attribute together
* in a optimized fashion. The LOG_MESSAGE_RECEIVER class is often a
* class with no instance data.
*/
Base_Optimizer receiver_;
#else
LOG_MESSAGE_RECEIVER receiver_;
SCHEDULE_STRATEGY schedule_strategy_;
#endif /* ! __GNUG__ */
/// The scheduling strategy for the service.
SCHEDULE_STRATEGY &scheduling_strategy ();
/// The receiver of log records
LOG_MESSAGE_RECEIVER &receiver ();
};
/**
* @class ACE_Server_Logging_Handler
*
* @brief Product object created by a
* >. An
* ACE_Server_Logging_Handler receives, frames. The logging record
* is then processed by the
*
* All clients are handled in the same thread.
*/
template
class ACE_Server_Logging_Handler : public ACE_Server_Logging_Handler_T
{
public:
ACE_Server_Logging_Handler (ACE_Thread_Manager * = 0);
ACE_Server_Logging_Handler (ACE_Thread_Manager *,
const LOG_MESSAGE_RECEIVER &receiver);
virtual int open (void* = 0);
};
#if defined (ACE_HAS_THREADS)
typedef ACE_Atomic_Op ACE_LOGGER_COUNTER;
#define ACE_LOGGER_SYNCH ACE_MT_SYNCH
#else
typedef u_long ACE_LOGGER_COUNTER;
#define ACE_LOGGER_SYNCH ACE_NULL_SYNCH
#endif /* ACE_HAS_THREADS */
/**
* @class ACE_Thr_Server_Logging_Handler
*
* @brief Product object created by a
*
* >. An ACE_Thr_Server_Logging_Handler receives, frames. The
* logging record is then processed by the
*
* Each client is handled in its own separate thread.
*/
template
class ACE_Thr_Server_Logging_Handler : public ACE_Server_Logging_Handler_T
{
public:
ACE_Thr_Server_Logging_Handler (ACE_Thread_Manager * = 0);
ACE_Thr_Server_Logging_Handler (ACE_Thread_Manager *,
const LOG_MESSAGE_RECEIVER &receiver);
virtual int open (void * = 0);
virtual int svc ();
};
#include "Server_Logging_Handler_T.cpp"
#endif /* ACE_SERVER_LOGGING_HANDLER_T_H */
ace-8.0.1+dfsg.orig/netsvcs/lib/TS_Clerk_Handler.h 0000644 0001750 0001750 00000016552 14653111173 020702 0 ustar sudip sudip /* -*- C++ -*- */
//=============================================================================
/**
* @file TS_Clerk_Handler.h
*
* @author Prashant Jain
*/
//=============================================================================
#ifndef ACE_TS_CLERK_HANDLER_H
#define ACE_TS_CLERK_HANDLER_H
#if !defined (ACE_LACKS_PRAGMA_ONCE)
# pragma once
#endif /* ACE_LACKS_PRAGMA_ONCE */
#include "ace/SOCK_Connector.h"
#include "ace/Svc_Handler.h"
#include "ace/Connector.h"
#include "ace/MMAP_Memory_Pool.h"
#include "ace/Malloc_T.h"
#include "ace/Null_Mutex.h"
#include "ace/svc_export.h"
#include "ace/os_include/os_dirent.h"
#include "Time_Request_Reply.h"
/**
* @class ACE_Time_Info
*
* @brief A simple struct containing delta time and a sequence number.
*/
class ACE_Time_Info
{
public:
time_t delta_time_;
ACE_UINT32 sequence_num_;
};
class ACE_TS_Clerk_Processor; // forward declaration
#if defined ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION_EXPORT
template class ACE_Svc_Export ACE_Svc_Handler;
#endif /* ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION_EXPORT */
/**
* @class ACE_TS_Clerk_Handler
*
* @brief The Clerk Handler provides the interface that is used by the
* Clerk Processor to send time update requests to all the
* servers. It obtains these updates from the servers and passes
* the updates to the Clerk Processor
*
* The Clerk Processor uses send_request() to send a request for
* time update to a server. The Clerk Handler internally computes
* the round trip delay for the reply to come back. Once it gets
* the reply back from the server (handle_input), it adjusts the
* system time using the round trip delay estimate and then
* passes the delta time by reference back to the Clerk
* Processor.
*/
class ACE_Svc_Export ACE_TS_Clerk_Handler : public ACE_Svc_Handler
{
public:
/// Default constructor.
ACE_TS_Clerk_Handler (ACE_TS_Clerk_Processor *processor = 0,
ACE_INET_Addr &addr = (ACE_INET_Addr &) ACE_Addr::sap_any);
// = Set/get the current state
enum State
{
IDLE = 1, // Prior to initialization.
CONNECTING, // During connection establishment.
ESTABLISHED, // Connection is established and active.
DISCONNECTING, // In the process of disconnecting.
FAILED // Connection has failed.
};
// = Set/get the current state.
State state ();
void state (State);
// = Set/get the current retry timeout delay.
long timeout ();
void timeout (long);
// = Set/get the maximum retry timeout delay.
long max_timeout ();
void max_timeout (long);
/// Activate this instance of the
/// (called by the ).
virtual int open (void * = 0);
/// Return the handle of the message_fifo_;
virtual ACE_HANDLE get_handle () const;
/// Called when object is removed from the ACE_Reactor
virtual int handle_close (ACE_HANDLE = ACE_INVALID_HANDLE,
ACE_Reactor_Mask = ACE_Event_Handler::ALL_EVENTS_MASK);
/// Receive time update from a server.
virtual int handle_input (ACE_HANDLE);
/// Restart connection asynchronously when timeout occurs.
virtual int handle_timeout (const ACE_Time_Value &tv,
const void *arg);
/// Get/Set remote addr
void remote_addr (ACE_INET_Addr &addr);
ACE_INET_Addr &remote_addr ();
/// Send request for time update to the server as well as return the
/// current time info by reference.
int send_request (ACE_UINT32 sequence_num,
ACE_Time_Info &time_info);
protected:
/// Handle SIGPIPE.
virtual int handle_signal (int signum, siginfo_t *, ucontext_t *);
static void stderr_output (int = 0);
enum
{
MAX_RETRY_TIMEOUT = 300
// 5 minutes is the maximum timeout.
};
private:
/// Receive a reply from a server containing time update
int recv_reply (ACE_Time_Request &reply);
/// Reinitiate connection with the server
int reinitiate_connection ();
/// The current state of the connection
State state_;
/// Amount of time to wait between reconnection attempts
long timeout_;
/// Maximum amount of time to wait between reconnection attempts
long max_timeout_;
/// Remote Addr used for connecting to the server
ACE_INET_Addr remote_addr_;
/// Instance of Clerk Processor used for re-establishing connections
ACE_TS_Clerk_Processor *processor_;
/// Time at which request was sent (used to compute round trip delay)
time_t start_time_;
/// Next sequence number of time request (waiting for this update from
/// the server).
ACE_UINT32 cur_sequence_num_;
/// Record of current delta time and current sequence number
ACE_Time_Info time_info_;
};
/**
* @class ACE_TS_Clerk_Processor
*
* @brief This class manages all the connections to the servers along
* with querying them periodically for time updates.
*
* The Clerk Processor creates connections to all the servers and
* creates an ACE_TS_Clerk_Handler for each connection to handle
* the requests and replies. It periodically sends a request for
* time update through each of the handlers and uses the replies
* for computing a synchronized system time.
*/
class ACE_TS_Clerk_Processor : public ACE_Connector
{
public:
/// Default constructor
ACE_TS_Clerk_Processor ();
/// Query servers for time periodically (timeout value)
virtual int handle_timeout (const ACE_Time_Value &tv,
const void *arg);
/// Set up connections to all servers
int initiate_connection (ACE_TS_Clerk_Handler *,
ACE_Synch_Options &);
protected:
// = Dynamic linking hooks.
/// Called when service is linked.
virtual int init (int argc, ACE_TCHAR *argv[]);
/// Called when service is unlinked.
virtual int fini ();
/// Called to determine info about the service.
virtual int info (ACE_TCHAR **strp, size_t length) const;
// = Scheduling hooks.
virtual int suspend ();
virtual int resume ();
private:
/// Parse svc.conf arguments.
int parse_args (int argc, ACE_TCHAR *argv[]);
/// Allocate entry in shared memory for system time
void alloc ();
/// Update delta_time using times obtained from all servers
int update_time ();
/// Allocator (used for reading/writing system time from/to shared memory)
typedef ACE_Malloc MALLOC;
typedef ACE_Allocator_Adapter ALLOCATOR;
ALLOCATOR *shmem_;
/// Set of TS_Clerk_Handlers and iterator over the set.
typedef ACE_Unbounded_Set HANDLER_SET;
typedef ACE_Unbounded_Set_Iterator HANDLER_SET_ITERATOR;
HANDLER_SET handler_set_;
struct System_Time
{
time_t *delta_time_; // Diff between system time and local time
time_t *last_local_time_; // Last local time
};
/// Clerk system time containing pointers to entries in shared memory
System_Time system_time_;
/// Timer id returned by Reactor
long timer_id_;
/// Time period for updating system time
long timeout_;
/// Pool name for backing store
ACE_TCHAR poolname_[MAXNAMLEN + 1];
/// Do a blocking/non-blocking connect
int blocking_semantics_;
/// Sequence number of next expected update from servers
ACE_UINT32 cur_sequence_num_;
};
ACE_SVC_FACTORY_DECLARE (ACE_TS_Clerk_Processor)
#endif /* ACE_TS_CLERK_HANDLER_H */
ace-8.0.1+dfsg.orig/netsvcs/lib/lib.mpc 0000644 0001750 0001750 00000000714 14653111173 016666 0 ustar sudip sudip // -*- MPC -*-
project(netsvcs): ace_output, acelib {
avoids += ace_for_tao
sharedname = netsvcs
dynamicflags += ACE_BUILD_SVC_DLL
Source_Files {
Time_Request_Reply.cpp
TS_Server_Handler.cpp
TS_Clerk_Handler.cpp
Client_Logging_Handler.cpp
Name_Handler.cpp
Log_Message_Receiver.cpp
Server_Logging_Handler.cpp
Token_Handler.cpp
}
Template_Files {
Base_Optimizer.cpp
Server_Logging_Handler_T.cpp
}
}
ace-8.0.1+dfsg.orig/netsvcs/lib/Log_Message_Receiver.h 0000644 0001750 0001750 00000016213 14653111173 021602 0 ustar sudip sudip /* -*- C++ -*- */
//=============================================================================
/**
* @file Log_Message_Receiver.h
*
* @author Per Andersson
*/
//=============================================================================
#ifndef LOG_MESSAGE_RECEIVER_H
#define LOG_MESSAGE_RECEIVER_H
#include "ace/Log_Record.h"
#if !defined (ACE_LACKS_PRAGMA_ONCE)
# pragma once
#endif /* ACE_LACKS_PRAGMA_ONCE */
#include "ace/Synch_Traits.h"
#include "ace/Guard_T.h"
#if defined (ACE_HAS_THREADS)
# include "ace/Thread_Mutex.h"
#else
# include "ace/Null_Mutex.h"
#endif /* ACE_HAS_THREADS */
// ==========================================================================//
//------------- General Requirements on a Log Message Receiver --------------//
// ==========================================================================//
// The requirements on a log manager receiver, T, are quite simple.
// 1: There must exist one "log_record" member function with the following
// prototype:
// void log_record(const ACE_TCHAR *hostname,
// ACE_Log_Record &record);
//
// 2: There must exist a public destructor.
// 3: There must exist a public copy constructor.
// 4: There must exist a default constructor. (for now)
//
// The semantics are also simple. A log message receiver should
// behave as an accessor object (smart pointer or envelope class).
// It should be very cheap to copy and the should be no noticeable
// difference when using either the new copy or the old log message
// receiver.
//
// Methods:
// void log_record(const ACE_TCHAR* hostname,
// ACE_Log_Record& record)
// Description:
// Processes the log record "record" from the host "hostname"
// Precondition:
// hostname != 0;
// Requirements:
// Record must be a valid ACE_Log_Record.
//
// ==========================================================================//
// ==========================================================================//
// ------------ General Description of a Log Message Receiver -------------- //
// ==========================================================================//
// Log Message Receivers, LRMs, are processing log records. It is the
// LRM that writes a log message to stderr, stdout, a log file and maybee
// converts some of the log messages to notifications, warnings, alarms
// and forwards them to some operation and maintenance system (PATROL).
//
// The client logging handler and server logging handler are responsible
// for forwarding, receiving, framing, processing log records.
// That is a very usable service, but it should also be possible to change
// how log records are processed without having to rewrite code in
// the server log handler. This code should instead be written as a
// separate entity, a Log Message Receiver.
//
// A simple LMR should be very easy to write but it should also
// be possible to write more complex LMRs, like one that creates
// a new log file each day or keeps a fixed size, round robin,
// log file. It should also be possible to have separate LMRs
// of the same type that uses different log files.
//
// ==========================================================================//
// Type based log message receiver
/**
* @class Static_Log_Message_Receiver
*
* @brief Static_Log_Message_Receiver is a simple log message receiver. It
* has no instance data and only static member
* functions. Static/typed based receivers are best when all LMR
* should do exactly the same thing.
*
* This class contains a static log_record member function that
* prints the content of log_records on stderr.
*/
template
class Static_Log_Message_Receiver
{
public:
/// Prints the log_record to stderr using record.print (hostname, 0, stderr).
/// Serializes the output by using a ACE_SYNCH_MUTEX.
static void log_record(const ACE_TCHAR *hostname,
ACE_Log_Record &record);
/// Prints the log_record to a user specified ostream.
static void log_output(const ACE_TCHAR *hostname,
ACE_Log_Record &record,
ostream *output);
};
// Instance based log message receiver
// ------------------------ Log_Message_Receiver --------------------------- //
// Log_Message_Receiver is little more complicated log message receiver.
// It is instance based and have a reference counted implementation.
// Log_Message_Receiver is the envelope class for Log_Message_Receiver_Impl.
//
// ------------------------------------------------------------------------- //
//Forward declaration
template class Log_Message_Receiver_Impl;
/**
* @class Log_Message_Receiver
*
* @brief Log_Message_Receiver is a little more complicated log message
* receiver. It is instance based and have a reference counted
* implementation. Log_Message_Receiver is the envelope class for
* Log_Message_Receiver_Impl. The difference between
* Static_Log_Message_Receiver and Log_Message_Receiver is that is
* possible to have instance data in Log_Message_Receiver.
* Comment:
* The practical usage of this is limited with the current
* ACE_Server_Logging_Acceptor_T design. Since
* ACE_Server_Logging_Acceptor_T will create the
* Log_Message_Receiver using the default constructor. The main
* reason for inclusion right now is to ensure that the code in
* ACE_Server_Logging_Handler_T works both with type and instance
* based LMRs.
*
* This class contains a log_record member function that prints the
* content of log_records on stderr.
*/
template
class Log_Message_Receiver
{
public:
/// Creates a new Log_Message_Receiver
Log_Message_Receiver ();
Log_Message_Receiver(Log_Message_Receiver const &rhs);
~Log_Message_Receiver ();
void log_record (const ACE_TCHAR *hostname,
ACE_Log_Record &record);
void log_output(const ACE_TCHAR *hostname,
ACE_Log_Record &record,
ostream *output);
private:
void operator= (const Log_Message_Receiver &rhs) = delete;
/// Attributes
Log_Message_Receiver_Impl *receiver_impl_;
};
/**
* @class Log_Message_Receiver_Impl
*
* @brief Implementation with reference count.
*/
template
class Log_Message_Receiver_Impl
{
public:
// Methods for handling reference count and instance lifetime
static Log_Message_Receiver_Impl *create ();
static Log_Message_Receiver_Impl *attach (Log_Message_Receiver_Impl *body);
static void detach (Log_Message_Receiver_Impl *body);
void log_record (const ACE_TCHAR *hostname, ACE_Log_Record &record);
void log_output(const ACE_TCHAR *hostname,
ACE_Log_Record &record,
ostream *output);
protected:
Log_Message_Receiver_Impl ();
~Log_Message_Receiver_Impl ();
/// Attributes
int count_;
ACE_SYNCH_MUTEX_T print_lock_;
private:
static ACE_SYNCH_MUTEX_T copy_lock_;
void operator= (const Log_Message_Receiver_Impl &) = delete;
Log_Message_Receiver_Impl (const Log_Message_Receiver_Impl &) = delete;
};
#include "Log_Message_Receiver.cpp"
#endif /* LOG_MESSAGE_RECEIVER_H */
ace-8.0.1+dfsg.orig/netsvcs/lib/TS_Server_Handler.cpp 0000644 0001750 0001750 00000016466 14653111173 021447 0 ustar sudip sudip #include "ace/SString.h"
#include "ace/Containers.h"
#include "ace/Get_Opt.h"
#include "TS_Server_Handler.h"
#include "ace/OS_NS_time.h"
#include "ace/Signal.h"
int
ACE_TS_Server_Acceptor::parse_args (int argc, ACE_TCHAR *argv[])
{
ACE_TRACE ("ACE_TS_Server_Acceptor::parse_args");
int service_port = ACE_DEFAULT_SERVER_PORT;
ACE_LOG_MSG->open (ACE_TEXT ("Time Service"));
ACE_Get_Opt get_opt (argc, argv, ACE_TEXT ("p:"), 0);
for (int c; (c = get_opt ()) != -1; )
{
switch (c)
{
case 'p':
service_port = ACE_OS::atoi (get_opt.opt_arg ());
break;
default:
ACE_ERROR_RETURN ((LM_ERROR,
ACE_TEXT ("%n:\n[-p server-port]\n"), 1),
-1);
}
}
this->service_addr_.set (service_port);
return 0;
}
int
ACE_TS_Server_Acceptor::init (int argc, ACE_TCHAR *argv[])
{
ACE_TRACE ("ACE_TS_Server_Acceptor::init");
// Use the options hook to parse the command line arguments and set
// options.
this->parse_args (argc, argv);
// Set the acceptor endpoint into listen mode (use the Singleton
// global Reactor...).
if (this->open (this->service_addr_, ACE_Reactor::instance (),
0, 0, 0,
&this->scheduling_strategy_,
ACE_TEXT ("Time Server"),
ACE_TEXT ("ACE time service")) == -1)
ACE_ERROR_RETURN ((LM_ERROR,
ACE_TEXT ("%n: %p on port %d\n"),
ACE_TEXT ("acceptor::open failed"),
this->service_addr_.get_port_number ()),
-1);
// Ignore SIGPIPE so that each can handle this on its
// own.
ACE_Sig_Action sig ((ACE_SignalHandler) SIG_IGN, SIGPIPE);
ACE_UNUSED_ARG (sig);
ACE_INET_Addr server_addr;
// Figure out what port we're really bound to.
if (this->acceptor ().get_local_addr (server_addr) == -1)
ACE_ERROR_RETURN ((LM_ERROR,
ACE_TEXT ("%p\n"),
ACE_TEXT ("get_local_addr")),
-1);
ACE_DEBUG ((LM_DEBUG,
ACE_TEXT ("starting up Time Server at port %d on handle %d\n"),
server_addr.get_port_number (),
this->acceptor ().get_handle ()));
return 0;
}
// The following is a "Factory" used by the ACE_Service_Config and
// svc.conf file to dynamically initialize the state of the Time Server
ACE_SVC_FACTORY_DEFINE (ACE_TS_Server_Acceptor)
// Default constructor.
ACE_TS_Server_Handler::ACE_TS_Server_Handler (ACE_Thread_Manager *tm)
: ACE_Svc_Handler (tm)
{
ACE_TRACE ("ACE_TS_Server_Handler::ACE_TS_Server_Handler");
}
// Activate this instance of the ACE_TS_Server_Handler (called by the
// ACE_TS_Server_Acceptor).
/* VIRTUAL */ int
ACE_TS_Server_Handler::open (void *)
{
ACE_TRACE ("ACE_TS_Server_Handler::open");
ACE_INET_Addr client_addr;
// Determine the address of the client and display it.
if (this->peer ().get_remote_addr (client_addr) == -1)
ACE_ERROR_RETURN ((LM_ERROR,
ACE_TEXT ("%p\n"),
ACE_TEXT ("get_remote_addr")),
-1);
ACE_DEBUG ((LM_DEBUG,
ACE_TEXT ("(%t) accepted connection from host %C on fd %d\n"),
client_addr.get_host_name (),
this->peer ().get_handle ()));
// Call down to our parent to register ourselves with the Reactor.
if (ACE_Svc_Handler::open (0) == -1)
ACE_ERROR_RETURN ((LM_ERROR,
ACE_TEXT ("%p\n"),
ACE_TEXT ("open")),
-1);
return 0;
}
/* VIRTUAL */ int
ACE_TS_Server_Handler::send_request (ACE_Time_Request &request)
{
ACE_TRACE ("ACE_TS_Server_Handler::send_request");
void *buffer;
ssize_t length = request.encode (buffer);
if (length == -1)
ACE_ERROR_RETURN ((LM_ERROR,
ACE_TEXT ("%p\n"),
ACE_TEXT ("encode failed")),
-1);
// Transmit request via a blocking send.
if (this->peer ().send_n (buffer, length) != length)
ACE_ERROR_RETURN ((LM_ERROR,
ACE_TEXT ("%p\n"),
ACE_TEXT ("send_n failed")),
-1);
return 0;
}
// Give up waiting (e.g., when a timeout occurs or a client shuts down
// unexpectedly).
/* VIRTUAL */ int
ACE_TS_Server_Handler::abandon ()
{
ACE_TRACE ("ACE_TS_Server_Handler::abandon");
// Note we are using the time field to report the errno in case of
// failure.
ACE_Time_Request rq (-1, errno);
return this->send_request (rq);
}
// Enable clients to limit the amount of time they'll wait
/* VIRTUAL */ int
ACE_TS_Server_Handler::handle_timeout (const ACE_Time_Value &, const void *)
{
ACE_TRACE ("ACE_TS_Server_Handler::handle_timeout");
return this->abandon ();
}
// Return the underlying ACE_HANDLE.
/* VIRTUAL */ ACE_HANDLE
ACE_TS_Server_Handler::get_handle () const
{
ACE_TRACE ("ACE_TS_Server_Handler::get_handle");
return this->peer ().get_handle ();
}
// Dispatch the appropriate operation to handle the client request.
/* VIRTUAL */ int
ACE_TS_Server_Handler::dispatch ()
{
ACE_TRACE ("ACE_TS_Server_Handler::dispatch");
// Get the system time and then create an ACE_Time_Request
time_t t = ACE_OS::time (0);
ACE_Time_Request rq (ACE_Time_Request::TIME_UPDATE, t);
return this->send_request (rq);
}
// Receive, frame, and decode the client's request. Note, this method
// should use non-blocking I/O.
/* VIRTUAL */ int
ACE_TS_Server_Handler::recv_request ()
{
ACE_TRACE ("ACE_TS_Server_Handler::recv_request");
ssize_t const bytes_expected = this->time_request_.size ();
// Since Time_Request messages are fixed size, read the entire
// message in one go.
ssize_t const n = this->peer ().recv ((void *) &this->time_request_, bytes_expected);
if (n != bytes_expected)
{
switch (n)
{
case -1:
ACE_DEBUG ((LM_DEBUG,
ACE_TEXT ("****************** recv_request returned -1\n")));
ACE_FALLTHROUGH;
default:
ACE_ERROR ((LM_ERROR,
ACE_TEXT ("%p got %d bytes, expected %d bytes\n"),
ACE_TEXT ("recv failed"),
n,
bytes_expected));
ACE_FALLTHROUGH;
case 0:
// We've shutdown unexpectedly, let's abandon the
// connection.
this->abandon ();
return -1;
/* NOTREACHED */
}
}
else
{
// Decode the request into host byte order.
if (this->time_request_.decode () == -1)
{
ACE_ERROR ((LM_ERROR,
ACE_TEXT ("%p\n"),
ACE_TEXT ("decode failed")));
return this->abandon ();
}
}
return 0;
}
// Callback method invoked by the ACE_Reactor when events arrive from
// the client.
/* VIRTUAL */ int
ACE_TS_Server_Handler::handle_input (ACE_HANDLE)
{
ACE_TRACE ("ACE_TS_Server_Handler::handle_input");
if (this->recv_request () == -1)
return -1;
else
return this->dispatch ();
}
ACE_TS_Server_Handler::~ACE_TS_Server_Handler ()
{
ACE_TRACE ("ACE_TS_Server_Handler::~ACE_TS_Server_Handler");
ACE_DEBUG ((LM_DEBUG,
ACE_TEXT ("closing down Handle %d\n"),
this->get_handle ()));
}
ace-8.0.1+dfsg.orig/netsvcs/lib/Server_Logging_Handler.h 0000644 0001750 0001750 00000007146 14653111173 022147 0 ustar sudip sudip /* -*- C++ -*- */
//=============================================================================
/**
* @file Server_Logging_Handler.h
*
* @author Doug Schmidt and Per Andersson
*/
//=============================================================================
#ifndef ACE_SERVER_LOGGING_HANDLER_H
#define ACE_SERVER_LOGGING_HANDLER_H
#include "Log_Message_Receiver.h"
#include "Server_Logging_Handler_T.h"
#include "ace/svc_export.h"
// Typedefs for Logging Handlers & acceptors using a static type based
// log message receivers.
// Synched and NULL synched message receivers
typedef Static_Log_Message_Receiver
Null_Synch_Static_Receiver;
typedef Static_Log_Message_Receiver
Synch_Static_Receiver;
// NULL synched logging handler
typedef ACE_Server_Logging_Handler
Null_Synch_Logging_Handler_Static_Receiver;
// synched logging handlers
typedef ACE_Server_Logging_Handler
Synch_Logging_Handler_Static_Receiver;
typedef ACE_Thr_Server_Logging_Handler
Synch_Thr_Logging_Handler_Static_Receiver;
// NULL synched logging acceptor
typedef ACE_Server_Logging_Acceptor_T >
Null_Synch_Logging_Handler_Static_Receiver_Acceptor;
// NULL synched logging acceptors
typedef ACE_Server_Logging_Acceptor_T >
Synch_Logging_Handler_Static_Receiver_Acceptor;
typedef ACE_Server_Logging_Acceptor_T >
Synch_Thr_Logging_Handler_Static_Receiver_Acceptor;
// typedefs for Logging Handlers & acceptors using a instance based
// log message receivers.
// Synched message receivers
typedef Log_Message_Receiver
Synch_Receiver;
// synched logging handlers
typedef ACE_Server_Logging_Handler
Synch_Logging_Handler_Receiver;
typedef ACE_Thr_Server_Logging_Handler
Synch_Thr_Logging_Handler_Receiver;
// synched logging acceptors
typedef ACE_Server_Logging_Acceptor_T >
Synch_Logging_Handler_Receiver_Acceptor;
typedef ACE_Server_Logging_Acceptor_T >
Synch_Thr_Logging_Handler_Receiver_Acceptor;
// Define external acceptors
// Acceptors that use static/type based log message receiver.
typedef Null_Synch_Logging_Handler_Static_Receiver_Acceptor
ACE_Server_Logging_Acceptor;
typedef Synch_Thr_Logging_Handler_Static_Receiver_Acceptor
ACE_Thr_Server_Logging_Acceptor;
ACE_SVC_FACTORY_DECLARE (ACE_Server_Logging_Acceptor)
ACE_SVC_FACTORY_DECLARE (ACE_Thr_Server_Logging_Acceptor)
#endif /* ACE_SERVER_LOGGING_HANDLER_H */
ace-8.0.1+dfsg.orig/netsvcs/lib/Client_Logging_Handler.cpp 0000644 0001750 0001750 00000053003 14653111173 022443 0 ustar sudip sudip #include "ace/Get_Opt.h"
#include "ace/Acceptor.h"
#include "ace/SOCK_Connector.h"
#include "ace/SOCK_Acceptor.h"
#include "ace/SPIPE_Acceptor.h"
#include "ace/Log_Record.h"
#include "ace/OS_NS_stdio.h"
#include "ace/OS_NS_string.h"
#include "ace/OS_NS_sys_socket.h"
#include "ace/OS_NS_unistd.h"
#include "ace/CDR_Stream.h"
#include
#include "ace/SString.h"
#include "ace/INET_Addr.h"
#include "Client_Logging_Handler.h"
ACE_Client_Logging_Handler::ACE_Client_Logging_Handler (ACE_HANDLE output_handle)
: logging_output_ (output_handle)
{
// Register ourselves to receive SIGPIPE so we can attempt
// reconnections.
#if !defined (ACE_LACKS_UNIX_SIGNALS)
if (ACE_Reactor::instance ()->register_handler (SIGPIPE,
this) == -1)
ACE_ERROR ((LM_ERROR,
ACE_TEXT ("%n: %p\n"),
ACE_TEXT ("register_handler (SIGPIPE)")));
#endif /* !ACE_LACKS_UNIX_SIGNALS */
}
// This is called when a to the logging server fails...
int
ACE_Client_Logging_Handler::handle_signal (int signum,
siginfo_t *,
ucontext_t *)
{
if (signum == SIGPIPE)
return 0;
else
return -1;
}
// This function is called every time a client connects to us.
int
ACE_Client_Logging_Handler::open (void *)
{
LOGGING_ADDR server_addr;
// Register ourselves to receive callbacks when
// clients send us logging records. Note that since we're really a
// Singleton, this->peer() will change after each connect, so we
// need to grab the value now.
if (ACE_Reactor::instance ()->register_handler
(this->peer ().get_handle (),
this,
ACE_Event_Handler::READ_MASK
| ACE_Event_Handler::EXCEPT_MASK) == -1)
ACE_ERROR_RETURN ((LM_ERROR,
ACE_TEXT ("%n: %p\n"),
ACE_TEXT ("register_handler")),
-1);
// Figure out what remote port we're really bound to.
if (this->peer ().get_remote_addr (server_addr) == -1)
ACE_ERROR_RETURN ((LM_ERROR,
ACE_TEXT ("%p\n"),
ACE_TEXT ("get_remote_addr")),
-1);
ACE_DEBUG ((LM_DEBUG,
ACE_TEXT ("Connected to client on handle %u\n"),
this->peer ().get_handle ()));
return 0;
}
/* VIRTUAL */ ACE_HANDLE
ACE_Client_Logging_Handler::get_handle () const
{
ACE_TRACE ("ACE_Client_Logging_Handler::get_handle");
ACE_ERROR ((LM_ERROR,
ACE_TEXT ("get_handle() shouldn't be called\n")));
return ACE_INVALID_HANDLE;
}
// Receive a logging record from an application.
int
ACE_Client_Logging_Handler::handle_input (ACE_HANDLE handle)
{
#if 0
ACE_DEBUG ((LM_DEBUG,
ACE_TEXT ("in ACE_Client_Logging_Handler::handle_input, handle = %u\n"),
handle));
#endif /* 0 */
if (handle == this->logging_output_)
// We're getting a message from the logging server!
ACE_ERROR_RETURN ((LM_ERROR,
ACE_TEXT ("Received data from server!\n")),
-1);
ACE_Log_Record log_record;
// We need to use the old two-read trick here since TCP sockets
// don't support framing natively. Allocate a message block for the
// payload; initially at least large enough to hold the header, but
// needs some room for alignment.
ACE_Message_Block *payload_p = 0;
ACE_Message_Block *header_p = 0;
ACE_NEW_RETURN (header_p,
ACE_Message_Block (ACE_DEFAULT_CDR_BUFSIZE),
-1);
std::unique_ptr header (header_p);
// Align the Message Block for a CDR stream
ACE_CDR::mb_align (header.get ());
#if (ACE_HAS_STREAM_LOG_MSG_IPC == 1)
// We're getting a logging message from a local application using
// STREAM pipes, which are nicely prioritized for us.
ACE_Str_Buf header_msg (header->wr_ptr (),
0,
8);
ACE_SPIPE_Stream spipe;
spipe.set_handle (handle);
int flags = 0;
// We've got a framed IPC mechanism, so we can just to a .
ssize_t result = spipe.recv (&header_msg,
(ACE_Str_Buf *) 0,
&flags);
if (result < 0 || header_msg.len == 0)
{
ACE_DEBUG ((LM_DEBUG,
ACE_TEXT ("client closing down unexpectedly\n")));
if (ACE_Reactor::instance ()->remove_handler
(handle,
ACE_Event_Handler::READ_MASK
| ACE_Event_Handler::EXCEPT_MASK
| ACE_Event_Handler::DONT_CALL) == -1)
ACE_ERROR_RETURN ((LM_ERROR,
ACE_TEXT ("%n: %p\n"),
ACE_TEXT ("remove_handler")),
-1);
spipe.close ();
return 0;
}
#else
// We're getting a logging message from a local application using
// sockets pipes, which are NOT prioritized for us.
ssize_t const count = ACE::recv_n (handle,
header->wr_ptr (),
8);
switch (count)
{
// Handle shutdown and error cases.
default:
case -1:
case 0:
ACE_DEBUG ((LM_DEBUG,
ACE_TEXT ("client closing down\n")));
if (ACE_Reactor::instance ()->remove_handler
(handle,
ACE_Event_Handler::READ_MASK
| ACE_Event_Handler::EXCEPT_MASK
| ACE_Event_Handler::DONT_CALL) == -1)
ACE_ERROR_RETURN ((LM_ERROR,
ACE_TEXT ("%n: %p\n"),
ACE_TEXT ("remove_handler")),
0);
if (handle == this->peer ().get_handle ())
this->peer ().close ();
else
ACE_OS::closesocket (handle);
// Release the memory to prevent a leak.
return 0;
/* NOTREACHED */
case 8:
// Just fall through in this case..
break;
}
#endif /* ACE_HAS_STREAM_LOG_MSG_IPC == 1 */
// Reflect addition of 8 bytes for the header.
header->wr_ptr (8);
// Create a CDR stream to parse the 8-byte header.
ACE_InputCDR header_cdr (header.get ());
// Extract the byte-order and use helper methods to disambiguate
// octet, booleans, and chars.
ACE_CDR::Boolean byte_order;
if (!(header_cdr >> ACE_InputCDR::to_boolean (byte_order)))
{
ACE_ERROR ((LM_ERROR,
ACE_TEXT ("Can't extract byte_order\n")));
return 0;
}
// Set the byte-order on the stream...
header_cdr.reset_byte_order (byte_order);
// Extract the length
ACE_CDR::ULong length;
if (!(header_cdr >> length))
{
ACE_ERROR ((LM_ERROR,
ACE_TEXT ("Can't extract length\n")));
return 0;
}
ACE_NEW_RETURN (payload_p,
ACE_Message_Block (length),
-1);
std::unique_ptr payload (payload_p);
// Ensure there's sufficient room for log record payload.
ACE_CDR::grow (payload.get (), 8 + ACE_CDR::MAX_ALIGNMENT + length);
#if (ACE_HAS_STREAM_LOG_MSG_IPC == 1)
ACE_Str_Buf payload_msg (payload->wr_ptr (),
0,
length);
// We've got a framed IPC mechanism, so we can just do a .
result = spipe.recv ((ACE_Str_Buf *) 0,
&payload_msg,
&flags);
if (result < 0 || payload_msg.len != (int)length)
{
ACE_DEBUG ((LM_DEBUG,
ACE_TEXT ("%p\n"),
ACE_TEXT ("client closing down due to error\n")));
if (ACE_Reactor::instance ()->remove_handler
(handle,
ACE_Event_Handler::READ_MASK
| ACE_Event_Handler::EXCEPT_MASK
| ACE_Event_Handler::DONT_CALL) == -1)
ACE_ERROR_RETURN ((LM_ERROR,
ACE_TEXT ("%n: result %d, length %d %p\n"),
result,
payload_msg.len,
ACE_TEXT ("remove_handler")),
-1);
spipe.close ();
return 0;
}
#else
// Use to obtain the contents.
if (ACE::recv_n (handle, payload->wr_ptr (), length) <= 0)
{
ACE_ERROR ((LM_ERROR,
ACE_TEXT ("%p\n"),
ACE_TEXT ("recv_n()")));
if (ACE_Reactor::instance ()->remove_handler
(handle,
ACE_Event_Handler::READ_MASK
| ACE_Event_Handler::EXCEPT_MASK
| ACE_Event_Handler::DONT_CALL) == -1)
ACE_ERROR ((LM_ERROR,
ACE_TEXT ("%n: %p\n"),
ACE_TEXT ("remove_handler")));
ACE_OS::closesocket (handle);
return 0;
}
#endif /* ACE_HAS_STREAM_LOG_MSG_IPC == 1 */
// Reflect additional bytes for the message.
payload->wr_ptr (length);
ACE_InputCDR payload_cdr (payload.get ());
payload_cdr.reset_byte_order (byte_order);
if (!(payload_cdr >> log_record)) // Finally extract the ACE_log_record.
{
ACE_ERROR ((LM_ERROR,
ACE_TEXT ("Can't extract log_record\n")));
return 0;
}
log_record.length (length);
// Forward the logging record to the server.
if (this->send (log_record) == -1)
ACE_ERROR ((LM_ERROR,
ACE_TEXT ("%p\n"),
ACE_TEXT ("send")));
return 0;
}
// Receive a logging record from an application send via a non-0
// MSG_BAND... This just calls handle_input().
int
ACE_Client_Logging_Handler::handle_exception (ACE_HANDLE handle)
{
return this->handle_input (handle);
}
// Called when object is removed from the ACE_Reactor
int
ACE_Client_Logging_Handler::close (u_long)
{
if (this->logging_output_ != ACE_STDERR)
ACE_OS::closesocket (this->logging_output_);
this->destroy ();
return 0;
}
int
ACE_Client_Logging_Handler::handle_output (ACE_HANDLE)
{
return 0;
}
// Encodes the contents of log_record object using network byte-order
// and sends it to the logging server.
int
ACE_Client_Logging_Handler::send (ACE_Log_Record &log_record)
{
ostream *orig_ostream = ACE_Log_Msg::instance ()->msg_ostream ();
// This logic must occur before we do the encode() on
// since otherwise the values of the fields will be in
// network byte order.
if (orig_ostream)
log_record.print (ACE_TEXT (""),
ACE_Log_Msg::instance ()->flags (),
*orig_ostream);
if (this->logging_output_ == ACE_STDERR)
{
log_record.print (ACE_TEXT (""),
ACE_Log_Msg::instance ()->flags (),
stderr);
}
else
{
// Serialize the log record using a CDR stream, allocate enough
// space for the complete .
size_t const max_payload_size =
4 // type()
+ 8 // timestamp
+ 4 // process id
+ 4 // data length
+ ACE_Log_Record::MAXLOGMSGLEN // data
+ ACE_CDR::MAX_ALIGNMENT; // padding;
// Insert contents of into payload stream.
ACE_OutputCDR payload (max_payload_size);
if (!(payload << log_record))
{
ACE_ERROR ((LM_ERROR,
ACE_TEXT ("Can't insert log_record\n")));
return -1;
}
// Get the number of bytes used by the CDR stream.
ACE_CDR::ULong const length = payload.total_length ();
// Send a header so the receiver can determine the byte order and
// size of the incoming CDR stream.
ACE_OutputCDR header (ACE_CDR::MAX_ALIGNMENT + 8);
if (!(header << ACE_OutputCDR::from_boolean (ACE_CDR_BYTE_ORDER)))
{
ACE_ERROR ((LM_ERROR,
ACE_TEXT ("Can't insert byte order\n")));
return -1;
}
// Store the size of the payload that follows
if (!(header << ACE_CDR::ULong (length)))
{
ACE_ERROR ((LM_ERROR,
ACE_TEXT ("Can't insert length\n")));
return -1;
}
// Use an iovec to send both buffer and payload simultaneously.
iovec iov[2];
iov[0].iov_base = header.begin ()->rd_ptr ();
iov[0].iov_len = 8;
iov[1].iov_base = payload.begin ()->rd_ptr ();
iov[1].iov_len = length;
// We're running over sockets, so send header and payload
// efficiently using "gather-write".
if (ACE::sendv_n (this->logging_output_,iov, 2) == -1)
{
ACE_DEBUG ((LM_DEBUG,
"Something about the sendv_n() failed, so switch to stderr\n"));
if (ACE_Log_Msg::instance ()->msg_ostream () == 0)
// Switch over to logging to stderr for now. At some
// point, we'll improve the implementation to queue up the
// message, try to reestablish a connection, and then send
// the queued data once we've reconnect to the logging
// server. If you'd like to implement this functionality
// and contribute it back to ACE that would be great!
this->logging_output_ = ACE_STDERR;
}
else
ACE_DEBUG ((LM_DEBUG,
"Sent logging message %s successfully to Server Logging Daemon!\n",
log_record.priority_name (ACE_Log_Priority (log_record.type ()))));
}
return 0;
}
class ACE_Client_Logging_Acceptor : public ACE_Acceptor
{
// = TITLE
// This factory creates connections with the
// .
//
// = DESCRIPTION
// This class contains the service-specific methods that can't
// easily be factored into the .
public:
ACE_Client_Logging_Acceptor ();
// Default constructor.
protected:
// = Dynamic linking hooks.
virtual int init (int argc, ACE_TCHAR *argv[]);
// Called when service is linked.
virtual int fini ();
// Called when service is unlinked.
virtual int info (ACE_TCHAR **strp, size_t length) const;
// Called to determine info about the service.
virtual int make_svc_handler (ACE_Client_Logging_Handler *&sh);
// Factory that always returns the .
// = Scheduling hooks.
virtual int suspend ();
virtual int resume ();
private:
int parse_args (int argc, ACE_TCHAR *argv[]);
// Parse svc.conf arguments.
const ACE_TCHAR *server_host_;
// Host where the logging server is located.
u_short server_port_;
// Port number where the logging server is listening for
// connections.
ACE_INET_Addr server_addr_;
// Address to connect to the server logging daemon.
ACE_INET_Addr local_addr_;
// Local IP/port number to use for the connection to the server logging
// daemon.
const ACE_TCHAR *logger_key_;
// Communication endpoint where the client logging daemon will
// listen for connections from clients.
ACE_Client_Logging_Handler *handler_;
// Pointer to the singleton handler that receives messages from
// clients and forwards to the server.
};
int
ACE_Client_Logging_Acceptor::fini ()
{
this->close ();
if (this->handler_ != 0)
this->handler_->close (0);
// Try to unlink the logger key so weird things don't happen if
// we're using STREAM pipes.
ACE_OS::unlink (this->logger_key_);
// This memory was allocated by .
ACE_OS::free ((void *) this->logger_key_);
ACE_OS::free ((void *) this->server_host_);
return 0;
}
int
ACE_Client_Logging_Acceptor::make_svc_handler (ACE_Client_Logging_Handler *&sh)
{
// Always return a pointer to the Singleton handler.
sh = this->handler_;
return 0;
}
int
ACE_Client_Logging_Acceptor::info (ACE_TCHAR **strp, size_t length) const
{
ACE_TCHAR buf[BUFSIZ];
ACE_OS::sprintf (buf, ACE_TEXT ("%d/%s %s"),
this->server_addr_.get_port_number (), "tcp",
"# client logging daemon\n");
if (*strp == 0 && (*strp = ACE_OS::strdup (buf)) == 0)
return -1;
else
ACE_OS::strncpy (*strp, buf, length);
return ACE_OS::strlen (buf);
}
ACE_Client_Logging_Acceptor::ACE_Client_Logging_Acceptor ()
: server_host_ (ACE_OS::strdup (ACE_DEFAULT_SERVER_HOST)),
server_port_ (ACE_DEFAULT_LOGGING_SERVER_PORT),
logger_key_ (ACE_OS::strdup (ACE_DEFAULT_LOGGER_KEY)),
handler_ (0)
{
}
int
ACE_Client_Logging_Acceptor::init (int argc, ACE_TCHAR *argv[])
{
// We'll log *our* error and debug messages to stderr!
if (ACE_LOG_MSG->open (ACE_TEXT ("Client Logging Service")) == -1)
ACE_ERROR_RETURN ((LM_ERROR,
ACE_TEXT ("Can't open ACE_Log_Msg\n")),
-1);
// Use the options hook to parse the command line arguments and set
// options.
this->parse_args (argc, argv);
// Try to unlink the logger key so weird things don't happen if
// we're using STREAM pipes.
ACE_OS::unlink (this->logger_key_);
// Initialize the acceptor endpoint.
if (this->open (LOGGING_ADDR (this->logger_key_)) == -1)
ACE_ERROR_RETURN ((LM_ERROR,
ACE_TEXT ("%p\n"),
this->logger_key_),
-1);
// Establish connection with the server.
ACE_SOCK_Connector con;
ACE_SOCK_Stream stream;
ACE_INET_Addr server_addr;
#if (ACE_HAS_STREAM_LOG_MSG_IPC == 1)
ACE_SPIPE_Addr lserver_addr;
// Figure out what local port we're really bound to.
if (this->acceptor ().get_local_addr (lserver_addr) == -1)
ACE_ERROR_RETURN ((LM_ERROR,
ACE_TEXT ("%p\n"),
ACE_TEXT ("get_local_addr")),
-1);
ACE_DEBUG ((LM_DEBUG,
ACE_TEXT ("Starting up Client Logging Daemon, ")
ACE_TEXT ("bounded to STREAM addr %s on handle %u\n"),
lserver_addr.get_path_name (),
this->acceptor ().get_handle ()));
#else
ACE_INET_Addr lserver_addr;
// Figure out what local port we're really bound to.
if (this->acceptor ().get_local_addr (lserver_addr) == -1)
ACE_ERROR_RETURN ((LM_ERROR,
ACE_TEXT ("%p\n"),
ACE_TEXT ("get_local_addr")),
-1);
ACE_DEBUG ((LM_DEBUG,
ACE_TEXT ("Starting up Client Logging Daemon, ")
ACE_TEXT ("bounded to local port %d on handle %u\n"),
lserver_addr.get_port_number (),
this->acceptor ().get_handle ()));
#endif /* ACE_HAS_STREAM_LOG_MSG_IPC == 1 */
if (con.connect (stream,
this->server_addr_,
0,
this->local_addr_) == -1)
{
ACE_ERROR ((LM_ERROR,
ACE_TEXT ("Can't connect to logging server %C on port %d: ")
ACE_TEXT ("%m, using stderr\n"),
this->server_addr_.get_host_name (),
this->server_addr_.get_port_number (),
ACE_ERRNO_GET));
if (ACE_Log_Msg::instance ()->msg_ostream () == 0)
// If we can't connect to the server then we'll send the logging
// messages to stderr.
stream.set_handle (ACE_STDERR);
}
else
{
// Figure out what remote port we're really bound to.
if (stream.get_remote_addr (server_addr) == -1)
ACE_ERROR_RETURN ((LM_ERROR,
ACE_TEXT ("%p\n"),
ACE_TEXT ("get_remote_addr")),
-1);
ACE_DEBUG ((LM_DEBUG,
ACE_TEXT ("Client Logging Daemon is connected to Server ")
ACE_TEXT ("Logging Daemon %C on port %d on handle %u\n"),
server_addr.get_host_name (),
server_addr.get_port_number (),
stream.get_handle ()));
}
// Create the Singleton .
ACE_NEW_RETURN (this->handler_,
ACE_Client_Logging_Handler (stream.get_handle ()),
-1);
return 0;
}
int
ACE_Client_Logging_Acceptor::parse_args (int argc, ACE_TCHAR *argv[])
{
ACE_Get_Opt get_opt (argc, argv, ACE_TEXT ("h:k:p:l:"), 0);
ACE_TString local_addr_str;
for (int c; (c = get_opt ()) != -1; )
{
switch (c)
{
case 'h':
ACE_OS::free ((void *) this->server_host_);
this->server_host_ = ACE_OS::strdup (get_opt.opt_arg ());
break;
case 'k':
ACE_OS::free ((void *) this->logger_key_);
this->logger_key_ = ACE_OS::strdup (get_opt.opt_arg ());
break;
case 'p':
this->server_port_ = ACE_OS::atoi (get_opt.opt_arg ());
break;
case 'l':
local_addr_str = get_opt.opt_arg ();
break;
default:
ACE_ERROR_RETURN ((LM_ERROR,
ACE_TEXT ("%n:\n[-p server-port]\n")
ACE_TEXT ("[-l local-ip[:local-port]]\n")),
-1);
}
}
this->local_addr_.set ((u_short)0); // "any"
if (local_addr_str.length () > 0)
{
if (local_addr_str.rfind (ACE_TCHAR(':')) == ACE_TString::npos)
local_addr_str += ACE_TEXT (":0");
ACE_TCHAR *local_addr_cstr = local_addr_str.rep ();
if (-1 == local_addr_.string_to_addr (ACE_TEXT_ALWAYS_CHAR (local_addr_cstr)))
ACE_ERROR ((LM_ERROR, ACE_TEXT ("%p\n"), local_addr_cstr));
delete [] local_addr_cstr;
}
if (this->server_addr_.set (this->server_port_,
this->server_host_) == -1)
ACE_ERROR_RETURN ((LM_ERROR,
ACE_TEXT ("%p\n"),
this->server_host_),
-1);
return 0;
}
int
ACE_Client_Logging_Acceptor::suspend ()
{
// To be done...
return 0;
}
int
ACE_Client_Logging_Acceptor::resume ()
{
// To be done...
return 0;
}
// The following is a "Factory" used by the ACE_Service_Config and
// svc.conf file to dynamically initialize the state of the
// single-threaded logging server.
ACE_SVC_FACTORY_DEFINE (ACE_Client_Logging_Acceptor)
ace-8.0.1+dfsg.orig/netsvcs/lib/Client_Logging_Handler.h 0000644 0001750 0001750 00000006024 14653111173 022111 0 ustar sudip sudip // -*- C++ -*-
//=============================================================================
/**
* @file Client_Logging_Handler.h
*
* @author Doug Schmidt
*/
//=============================================================================
#ifndef ACE_CLIENT_LOGGER_H
#define ACE_CLIENT_LOGGER_H
#include "ace/SPIPE_Stream.h"
#if !defined (ACE_LACKS_PRAGMA_ONCE)
# pragma once
#endif /* ACE_LACKS_PRAGMA_ONCE */
#include "ace/SOCK_Stream.h"
#include "ace/Svc_Handler.h"
#include "ace/svc_export.h"
#if (ACE_HAS_STREAM_LOG_MSG_IPC == 1)
#define LOGGING_STREAM ACE_SPIPE_STREAM
#define LOGGING_ACCEPTOR ACE_SPIPE_ACCEPTOR
#define LOGGING_ADDR ACE_SPIPE_Addr
#else
#define LOGGING_STREAM ACE_SOCK_STREAM
#define LOGGING_ACCEPTOR ACE_SOCK_ACCEPTOR
#define LOGGING_ADDR ACE_INET_Addr
#endif /* ACE_HAS_STREAM_LOG_MSG_IPC == 1 */
#if defined ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION_EXPORT
template class ACE_Svc_Export ACE_Svc_Handler;
#endif /* ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION_EXPORT */
/**
* @class ACE_Client_Logging_Handler
*
* @brief This client logging daemon is a mediator that receives logging
* records from local applications processes and forwards them to
* the server logging daemon running on another host.
*
* The default implementation uses an ACE_SPIPE_Stream to
* receive the logging message from the application and an
* ACE_SOCK_Stream to forward the logging message to the
* server. However, on platforms that don't support
* (e.g., Win32) we use sockets instead.
*/
class ACE_Svc_Export ACE_Client_Logging_Handler :
public ACE_Svc_Handler
{
public:
/// Default constructor. @a handle is where the output is sent.
ACE_Client_Logging_Handler (ACE_HANDLE handle = ACE_STDERR);
/// Activate this instance of the ACE_Client_Logging_Handler
/// (called by the ACE_Client_Logging_Acceptor).
virtual int open (void * = 0);
/// Return the handle of the IPC endpoint.
virtual ACE_HANDLE get_handle () const;
/// Called when object is removed from the ACE_Reactor.
virtual int close (u_long);
private:
/// Handle SIGPIPE.
virtual int handle_signal (int signum,
siginfo_t *,
ucontext_t *);
/// Receive logging records from applications.
virtual int handle_input (ACE_HANDLE);
/**
* Receive logging records from applications. This is necessary to
* handle madness with UNIX select, which can't deal with MSG_BAND
* data easily due to its overly simple interface... This just
* calls handle_input().
*/
virtual int handle_exception (ACE_HANDLE);
/// Called back when it's ok to send.
virtual int handle_output (ACE_HANDLE);
/// Send the @a log_record to the logging server.
int send (ACE_Log_Record &log_record);
/// This is either a SOCKET (if we're connected to a logging server)
/// or ACE_STDERR.
ACE_HANDLE logging_output_;
};
ACE_SVC_FACTORY_DECLARE (ACE_Client_Logging_Acceptor)
#endif /* ACE_CLIENT_LOGGER_H */
ace-8.0.1+dfsg.orig/netsvcs/lib/Log_Message_Receiver.cpp 0000644 0001750 0001750 00000010773 14653111173 022142 0 ustar sudip sudip #if !defined (LOG_MESSAGE_RECEIVER_CPP)
#define LOG_MESSAGE_RECEIVER_CPP
#include "ace/Log_Msg.h"
#include "Log_Message_Receiver.h"
// Type based log message receiver
template void
Static_Log_Message_Receiver::log_record (const ACE_TCHAR *hostname,
ACE_Log_Record &record)
{
#if defined (ACE_HAS_THREADS)
static ACE_SYNCH_MUTEX_T lock_;
ACE_GUARD (ACE_SYNCH_MUTEX_T, guard, lock_);
#endif /* ACE_HAS_THREADS */
record.print (hostname,
ACE_Log_Msg::instance ()->flags (),
stderr);
}
template void
Static_Log_Message_Receiver::log_output (const ACE_TCHAR *hostname,
ACE_Log_Record &record,
ostream *outputfile)
{
if (outputfile != 0)
{
#if defined (ACE_HAS_THREADS)
static ACE_SYNCH_MUTEX_T lock_;
ACE_GUARD (ACE_SYNCH_MUTEX_T, guard, lock_);
#endif /* ACE_HAS_THREADS */
record.print (hostname,
ACE_Log_Msg::instance ()->flags (),
*outputfile);
}
}
template
ACE_SYNCH_MUTEX_T Log_Message_Receiver_Impl::copy_lock_;
template
Log_Message_Receiver_Impl::Log_Message_Receiver_Impl ()
: count_ (0)
{
}
template
Log_Message_Receiver_Impl *
Log_Message_Receiver_Impl::create ()
{
return new Log_Message_Receiver_Impl;
}
template
Log_Message_Receiver_Impl *
Log_Message_Receiver_Impl::attach (Log_Message_Receiver_Impl *body)
{
ACE_ASSERT (body != 0);
#if defined (ACE_HAS_THREADS)
ACE_GUARD_RETURN (ACE_SYNCH_MUTEX_T, guard, copy_lock_, 0);
#endif /* ACE_HAS_THREADS */
++body->count_;
return body;
}
template void
Log_Message_Receiver_Impl::detach (Log_Message_Receiver_Impl *body)
{
ACE_ASSERT (body != 0);
#if defined (ACE_HAS_THREADS)
ACE_GUARD (ACE_SYNCH_MUTEX_T, guard, copy_lock_);
#endif /* ACE_HAS_THREADS */
if (body->count_-- == 0)
delete body;
}
// Type based log message receiver
template void
Log_Message_Receiver_Impl::log_record (const ACE_TCHAR *hostname,
ACE_Log_Record &record)
{
ACE_GUARD (ACE_SYNCH_MUTEX_T, guard, print_lock_);
record.print (hostname,
ACE_Log_Msg::instance ()->flags (),
stderr);
}
template void
Log_Message_Receiver_Impl::log_output (const ACE_TCHAR *hostname,
ACE_Log_Record &record,
ostream *outputfile)
{
if (outputfile != 0)
{
ACE_GUARD (ACE_SYNCH_MUTEX_T, guard, print_lock_);
record.print (hostname,
ACE_Log_Msg::instance ()->flags (),
*outputfile);
}
}
template
Log_Message_Receiver_Impl::~Log_Message_Receiver_Impl ()
{
ACE_ASSERT (count_ == 0 - 1);
}
template
Log_Message_Receiver::Log_Message_Receiver ()
: receiver_impl_ (Log_Message_Receiver_Impl::create ())
{
ACE_ASSERT (receiver_impl_ != 0);
}
template
Log_Message_Receiver::Log_Message_Receiver
(Log_Message_Receiver const &rhs)
: receiver_impl_ (Log_Message_Receiver_Impl::attach (rhs.receiver_impl_))
{
ACE_ASSERT (receiver_impl_ != 0);
}
// Type based log message receiver
template void
Log_Message_Receiver::log_record(const ACE_TCHAR *hostname,
ACE_Log_Record &record)
{
ACE_ASSERT (receiver_impl_ != 0);
receiver_impl_->log_record (hostname, record);
}
template void
Log_Message_Receiver::log_output(const ACE_TCHAR *hostname,
ACE_Log_Record &record,
ostream *outputfile)
{
ACE_ASSERT (receiver_impl_ != 0);
receiver_impl_->log_output (hostname, record, outputfile);
}
template
Log_Message_Receiver::~Log_Message_Receiver ()
{
ACE_ASSERT (receiver_impl_ != 0);
Log_Message_Receiver_Impl::detach (receiver_impl_);
}
#endif /* LOG_MESSAGE_RECEIVER_CPP */
ace-8.0.1+dfsg.orig/netsvcs/lib/Token_Handler.cpp 0000644 0001750 0001750 00000041137 14653111173 020644 0 ustar sudip sudip #include "ace/Get_Opt.h"
#include "Token_Handler.h"
#if defined (ACE_HAS_TOKENS_LIBRARY)
#include "ace/Signal.h"
int
ACE_Token_Acceptor::parse_args (int argc, ACE_TCHAR *argv[])
{
ACE_TRACE ("ACE_Token_Acceptor::parse_args");
u_short svc_port = ACE_DEFAULT_SERVER_PORT;
ACE_LOG_MSG->open (ACE_TEXT ("Token Service"));
ACE_Get_Opt get_opt (argc, argv, ACE_TEXT ("p:"), 0);
for (int c; (c = get_opt ()) != -1; )
{
switch (c)
{
case 'p':
svc_port = static_cast (ACE_OS::atoi (get_opt.opt_arg ()));
break;
default:
ACE_ERROR_RETURN ((LM_ERROR,
ACE_TEXT ("%n:\n[-p server-port]\n"), 1),
-1);
}
}
this->service_addr_.set (svc_port);
return 0;
}
int
ACE_Token_Acceptor::init (int argc, ACE_TCHAR *argv[])
{
ACE_TRACE ("ACE_Token_Acceptor::init");
// Use the options hook to parse the command line arguments and set
// options.
this->parse_args (argc, argv);
// Set the acceptor endpoint into listen mode (use the Singleton
// global Reactor...).
if (this->open (this->service_addr_, ACE_Reactor::instance (),
0, 0, 0,
&this->scheduling_strategy_,
ACE_TEXT ("Token Server"),
ACE_TEXT ("ACE token service")) == -1)
ACE_ERROR_RETURN ((LM_ERROR, ACE_TEXT ("%n: %p on port %d\n"),
ACE_TEXT ("acceptor::open failed"),
this->service_addr_.get_port_number ()), -1);
// Ignore SIGPIPE so that each can handle this on its
// own.
ACE_Sig_Action sig ((ACE_SignalHandler) SIG_IGN, SIGPIPE);
ACE_UNUSED_ARG (sig);
ACE_INET_Addr server_addr;
if (this->acceptor ().get_local_addr (server_addr) == -1)
ACE_ERROR_RETURN
((LM_ERROR, ACE_TEXT ("%p\n"), ACE_TEXT ("get_remote_addr")), -1);
ACE_DEBUG ((LM_DEBUG,
ACE_TEXT ("starting up Token Server at port %d on handle %d\n"),
server_addr.get_port_number (),
this->acceptor ().get_handle ()));
return 0;
}
// The following is a "Factory" used by the ACE_Service_Config and
// svc.conf file to dynamically initialize the state of the Naming
// Server.
ACE_SVC_FACTORY_DEFINE (ACE_Token_Acceptor)
// Default constructor.
ACE_Token_Handler::ACE_Token_Handler (ACE_Thread_Manager *tm)
: ACE_Svc_Handler (tm),
collection_ (1),
timeout_id_ (0)
{
ACE_TRACE ("ACE_Token_Handler::ACE_Token_Handler");
}
// Create and send a reply to the client.
/* VIRTUAL */ int
ACE_Token_Handler::send_reply (ACE_UINT32 err)
{
ACE_TRACE ("ACE_Token_Handler::send_reply");
void *buf;
size_t len;
ssize_t n;
this->token_reply_.errnum (err);
len = this->token_reply_.encode (buf);
n = this->peer ().send (buf, len);
if (n != (ssize_t) len)
ACE_ERROR_RETURN ((LM_ERROR,
ACE_TEXT ("%p, expected len = %d, actual len = %d\n"),
ACE_TEXT ("send failed"), len, n), -1);
else
return 0;
}
// Acquire the token.
/* VIRTUAL */ int
ACE_Token_Handler::acquire (ACE_Token_Proxy *proxy)
{
ACE_TRACE ("ACE_Token_Handler::acquire");
#if 0
ACE_DEBUG ((LM_DEBUG, "in acquire for client id = %s\n",
proxy->client_id ()));
#endif /* 0 */
// @@ add notify in token request reply
if (proxy->acquire (0, 0, ACE_Synch_Options::asynch) == -1)
{
if (errno != EWOULDBLOCK)
// bad bad bad
return this->send_reply (errno);
// acquire would block
if (request_options_[ACE_Synch_Options::USE_TIMEOUT] == 1)
{
// check for polling
if ((request_options_.timeout ().sec () == 0) &&
(request_options_.timeout ().usec () == 0))
return this->send_reply (EWOULDBLOCK);
// schedule a timer
this->timeout_id_ = this->reactor ()->schedule_timer
(this, (void *) proxy, request_options_.timeout ());
if (timeout_id_ == -1)
{
ACE_ERROR ((LM_ERROR, ACE_TEXT ("%p\n"),
ACE_TEXT ("schedule_timer")));
return this->send_reply (errno);
}
}
// send no reply. wait until we acquire it or until the timer
// goes off.
return 0;
}
else // success
return this->send_reply (0);
}
// Try to acquire the token. Never block.
/* VIRTUAL */ int
ACE_Token_Handler::try_acquire (ACE_Token_Proxy *proxy)
{
ACE_TRACE ("ACE_Token_Handler::try_acquire");
#if 0
ACE_DEBUG ((LM_DEBUG, "in try_acquire for client id = %s\n",
proxy->client_id ()));
#endif /* 0 */
// @@ add notify in token request reply
if (proxy->tryacquire () == -1)
return this->send_reply (errno);
else
return this->send_reply (0);
}
// Release the token and allow the next client that is waiting to
// proceed.
/* VIRTUAL */ int
ACE_Token_Handler::release (ACE_Token_Proxy *proxy)
{
ACE_TRACE ("ACE_Token_Handler::release");
#if 0
ACE_DEBUG ((LM_DEBUG,
"in release for client id = %s\n",
proxy->client_id ()));
#endif /* 0 */
if (proxy->release (ACE_Synch_Options::asynch) == -1)
// oops, it failed
return this->send_reply (ACE_LOG_MSG->errnum ());
// success
if (this->timeout_id_ != 0)
{
this->reactor ()->cancel_timer (timeout_id_);
this->timeout_id_ = 0;
}
return this->send_reply (0);
}
// Yield the token if any clients are waiting, otherwise keep the
// token.
/* VIRTUAL */ int
ACE_Token_Handler::renew (ACE_Token_Proxy *proxy)
{
ACE_TRACE ("ACE_Token_Handler::renew");
#if 0
ACE_DEBUG ((LM_DEBUG, "in renew for client id = %s\n",
proxy->client_id ()));
#endif /* 0 */
if (proxy->renew (token_request_.requeue_position (),
ACE_Synch_Options::asynch) == -1)
{
int result = ACE_LOG_MSG->errnum ();
if (result != EWOULDBLOCK)
// bad bad bad
return this->send_reply (result);
// acquire would block
if (request_options_[ACE_Synch_Options::USE_TIMEOUT] == 1)
{
this->timeout_id_ = this->reactor ()->schedule_timer
(this, 0, request_options_.timeout ());
if (timeout_id_ == -1)
{
ACE_ERROR ((LM_ERROR, ACE_TEXT ("%p\n"),
ACE_TEXT ("schedule_timer")));
return this->send_reply (ACE_LOG_MSG->errnum ());
}
}
// Send no reply. wait until we acquire it or until the timer
// goes off.
return 0;
}
else
// Success, we still hold the token.
return this->send_reply (0);
}
/* VIRTUAL */ int
ACE_Token_Handler::remove (ACE_Token_Proxy * /* proxy */)
{
ACE_TRACE ("ACE_Token_Handler::remove");
#if 0
ACE_DEBUG ((LM_DEBUG, "in remove for client id = %s\n",
proxy->client_id ()));
#endif /* 0 */
ACE_ERROR
((LM_ERROR,
ACE_TEXT ("sorry: ACE_Token_Handler::remove() is not implemented")));
return this->send_reply (ENOTSUP);
}
// Enable clients to limit the amount of time they'll wait for a
// token.
/* VIRTUAL */ int
ACE_Token_Handler::handle_timeout (const ACE_Time_Value &,
const void *tp)
{
ACE_TRACE ("ACE_Token_Handler::handle_timeout");
this->timeout_id_ = 0;
// @@ add a try acquire here!
// Try to acquire the token, but if we can't get it immediately
// then abandon the wait.
// if (this->try_acquire (&token_entry) == -1)
// return this->abandon (token_entry);
ACE_Token_Proxy *proxy = (ACE_Token_Proxy *) tp;
#if 0
ACE_DEBUG ((LM_DEBUG, "in handle_timeout for client id = %s\n",
proxy->client_id ()));
#endif /* 0 */
// Remove ourselves from the waiter list.
proxy->release ();
this->send_reply (ETIME);
return 0;
}
// Dispatch the appropriate operation to handle the client request.
ACE_Token_Proxy *
ACE_Token_Handler::get_proxy ()
{
ACE_TRACE ("ACE_Token_Handler::get_proxy");
// See if the proxy already exists in the collection.
ACE_Token_Proxy *proxy = collection_.is_member (token_request_.token_name ());
// If not, create one.
if (proxy == 0)
{
proxy = this->create_proxy ();
// Put the new_proxy in this client_id's collection.
if (collection_.insert (*proxy) == -1)
ACE_ERROR_RETURN ((LM_ERROR, ACE_TEXT ("insert failed\n")), 0);
// Delete our copy (one was created in the collection).
delete proxy;
proxy = collection_.is_member (token_request_.token_name ());
if (proxy == 0)
ACE_ERROR_RETURN ((LM_ERROR, ACE_TEXT ("is_member failed\n")), 0);
// Set the client_id (it was set to 1 since we're
// single-threaded.
proxy->client_id (token_request_.client_id ());
}
return proxy;
}
ACE_Token_Proxy *
ACE_Token_Handler::create_proxy ()
{
ACE_TRACE ("ACE_Token_Handler::create_proxy");
ACE_Token_Proxy *proxy;
switch (token_request_.token_type ())
{
case ACE_Tokens::RWLOCK:
if (token_request_.proxy_type () == ACE_RW_Token::READER)
ACE_NEW_RETURN (proxy,
ACE_TS_RLock (token_request_.token_name (), this),
0);
else
ACE_NEW_RETURN (proxy,
ACE_TS_WLock (token_request_.token_name (), this),
0);
break;
case ACE_Tokens::MUTEX:
ACE_NEW_RETURN (proxy,
ACE_TS_Mutex (token_request_.token_name (), this),
0);
break;
default:
// Nonexistent token type.
errno = EINVAL;
return 0;
}
// Check for failed new.
if (proxy == 0)
errno = ENOMEM;
return proxy;
}
int
ACE_Token_Handler::dispatch ()
{
ACE_TRACE ("ACE_Token_Handler::dispatch");
ACE_Token_Proxy *proxy = this->get_proxy ();
if (proxy == 0)
return -1;
// Dispatch the appropriate request.
switch (this->token_request_.operation_type ())
{
case ACE_Token_Request::ACQUIRE:
return this->acquire (proxy);
case ACE_Token_Request::TRY_ACQUIRE:
return this->try_acquire (proxy);
case ACE_Token_Request::RELEASE:
return this->release (proxy);
case ACE_Token_Request::RENEW:
return this->renew (proxy);
case ACE_Token_Request::REMOVE:
return this->remove (proxy);
default:
ACE_ERROR_RETURN ((LM_ERROR, ACE_TEXT ("invalid type = %d\n"),
this->token_request_.operation_type ()), -1);
/* NOTREACHED */
}
}
// Receive, frame, and decode the client's request.
// Note, this method should use non-blocking I/O.
/* VIRTUAL */ int
ACE_Token_Handler::recv_request ()
{
ACE_TRACE ("ACE_Token_Handler::recv_request");
ssize_t n;
// Read the first 4 bytes to get the length of the message
// This implementation assumes that the first 4 bytes are
// the length of the message.
n = this->peer ().recv ((void *) &this->token_request_,
sizeof (ACE_UINT32));
switch (n)
{
case -1:
ACE_FALLTHROUGH;
default:
ACE_ERROR ((LM_ERROR, ACE_TEXT ("%p got %d bytes, expected %d bytes\n"),
ACE_TEXT ("recv failed"), n, sizeof (ACE_UINT32)));
ACE_FALLTHROUGH;
case 0:
// We've shutdown unexpectedly, let's abandon the connection.
this->abandon (0);
return -1;
/* NOTREACHED */
case sizeof (ACE_UINT32):
{
// Transform the length into host byte order.
ssize_t length = this->token_request_.length ();
// Do a sanity check on the length of the message.
if (length > (ssize_t) sizeof this->token_request_)
{
ACE_ERROR ((LM_ERROR, ACE_TEXT ("length %d too long\n"), length));
return this->abandon (1);
}
// Receive the rest of the request message.
// @@ beware of blocking read!!!.
n = this->peer ().recv ((void *) (((char *) &this->token_request_)
+ sizeof (ACE_UINT32)),
length - sizeof (ACE_UINT32));
// Subtract off the size of the part we skipped over...
if (n != (length - (ssize_t) sizeof (ACE_UINT32)))
{
ACE_ERROR ((LM_ERROR, ACE_TEXT ("%p expected %d, got %d\n"),
ACE_TEXT ("invalid length"), length, n));
return this->abandon (1);
}
// Decode the request into host byte order.
if (this->token_request_.decode () == -1)
{
ACE_ERROR
((LM_ERROR, ACE_TEXT ("%p\n"), ACE_TEXT ("decode failed")));
return this->abandon (1);
}
// if (OS::debug)
this->token_request_.dump ();
}
}
return 0;
}
// Callback method invoked by the ACE_Reactor when
// events arrive from the client.
/* VIRTUAL */ int
ACE_Token_Handler::handle_input (ACE_HANDLE)
{
ACE_TRACE ("ACE_Token_Handler::handle_input");
#if 0
ACE_DEBUG ((LM_DEBUG, "****************** in handle_input\n"));
#endif /* 0 */
if (this->recv_request () == -1)
return -1;
else
return this->dispatch ();
}
void
ACE_Token_Handler::sleep_hook ()
{
ACE_TRACE ("ACE_Token_Handler::sleep_hook");
// @@ what should we do?
return;
}
void
ACE_Token_Handler::token_acquired (ACE_TPQ_Entry *)
{
ACE_TRACE ("ACE_Token_Handler::token_acquired");
if (this->timeout_id_ != 0)
{
this->reactor ()->cancel_timer (this->timeout_id_);
this->timeout_id_ = 0;
}
this->send_reply (0);
}
int
ACE_Token_Handler::abandon (int send_error)
{
ACE_TRACE ("ACE_Token_Handler::abandon");
// Release ownership or remove us from the waiter list.
if (this->timeout_id_ != 0)
{
this->reactor ()->cancel_timer (timeout_id_);
this->timeout_id_ = 0;
}
// @@ release all tokens
collection_.release ();
if (send_error)
return this->send_reply (EIO);
else
return -1;
}
// ************************************************************
// ************************************************************
// ************************************************************
ACE_TS_Mutex::ACE_TS_Mutex (const ACE_TCHAR *name,
ACE_Token_Handler *th)
: ACE_Local_Mutex (name, 0, 1), // The 1 is debug.
th_ (th)
{
ACE_TRACE ("ACE_TS_Mutex::ACE_TS_Mutex");
}
ACE_TS_Mutex::ACE_TS_Mutex (const ACE_TS_Mutex &m)
: ACE_Local_Mutex (m),
th_ (m.th_)
{
ACE_TRACE ("ACE_TS_Mutex::ACE_TS_Mutex");
this->open (m.name (), m.ignore_deadlock_, m.debug_);
}
void
ACE_TS_Mutex::sleep_hook ()
{
ACE_TRACE ("ACE_TS_Mutex::sleep_hook");
th_->sleep_hook ();
return;
}
void
ACE_TS_Mutex::token_acquired (ACE_TPQ_Entry *e)
{
ACE_TRACE ("ACE_TS_Mutex::token_acquired");
// Notify the token handler.
th_->token_acquired (e);
return;
}
ACE_Token_Proxy *
ACE_TS_Mutex::clone () const
{
ACE_TRACE ("ACE_TS_Mutex::clone");
ACE_Token_Proxy *temp;
ACE_NEW_RETURN (temp, ACE_TS_Mutex (*this), 0);
return temp;
}
// ************************************************************
ACE_TS_RLock::ACE_TS_RLock (const ACE_TCHAR *name,
ACE_Token_Handler *th)
: ACE_Local_RLock (name, 0, 1), // The 1 is debug.
th_ (th)
{
ACE_TRACE ("ACE_TS_RLock::ACE_TS_RLock");
}
ACE_TS_RLock::ACE_TS_RLock (const ACE_TS_RLock &r)
: ACE_Local_RLock (r),
th_ (r.th_)
{
ACE_TRACE ("ACE_TS_RLock::ACE_TS_RLock");
this->open (r.name (), r.ignore_deadlock_, r.debug_);
}
void
ACE_TS_RLock::sleep_hook ()
{
ACE_TRACE ("ACE_TS_RLock::sleep_hook");
th_->sleep_hook ();
return;
}
void
ACE_TS_RLock::token_acquired (ACE_TPQ_Entry *e)
{
ACE_TRACE ("ACE_TS_RLock::token_acquired");
// Notify the token handler.
th_->token_acquired (e);
return;
}
ACE_Token_Proxy *
ACE_TS_RLock::clone () const
{
ACE_TRACE ("ACE_TS_RLock::clone");
ACE_Token_Proxy *temp;
ACE_NEW_RETURN (temp, ACE_TS_RLock (*this), 0);
return temp;
}
// ************************************************************
ACE_TS_WLock::ACE_TS_WLock (const ACE_TCHAR *name,
ACE_Token_Handler *th)
: ACE_Local_WLock (name, 0, 1), // The 1 is debug.
th_ (th)
{
ACE_TRACE ("ACE_TS_WLock::ACE_TS_WLock");
}
ACE_TS_WLock::ACE_TS_WLock (const ACE_TS_WLock &w)
: ACE_Local_WLock (w),
th_ (w.th_)
{
ACE_TRACE ("ACE_TS_WLock::ACE_TS_WLock");
this->open (w.name (), w.ignore_deadlock_, w.debug_);
}
void
ACE_TS_WLock::sleep_hook ()
{
ACE_TRACE ("ACE_TS_WLock::sleep_hook");
th_->sleep_hook ();
return;
}
void
ACE_TS_WLock::token_acquired (ACE_TPQ_Entry *e)
{
ACE_TRACE ("ACE_TS_WLock::token_acquired");
// Notify the token handler.
th_->token_acquired (e);
return;
}
ACE_Token_Proxy *
ACE_TS_WLock::clone () const
{
ACE_TRACE ("ACE_TS_WLock::clone");
ACE_Token_Proxy *temp;
ACE_NEW_RETURN (temp, ACE_TS_WLock (*this), 0);
return temp;
}
#endif /* ACE_HAS_TOKENS_LIBRARY */
ace-8.0.1+dfsg.orig/netsvcs/lib/Token_Handler.h 0000644 0001750 0001750 00000017437 14653111173 020317 0 ustar sudip sudip /* -*- C++ -*- */
//=============================================================================
/**
* @file Token_Handler.h
*
* @author Douglas C. Schmidt (d.schmidt@vanderbilt.edu)
* Tim Harrison (harrison@cs.wustl.edu)
*/
//=============================================================================
#ifndef ACE_TOKEN_HANDLER_H
#define ACE_TOKEN_HANDLER_H
#include "ace/Acceptor.h"
#if !defined (ACE_LACKS_PRAGMA_ONCE)
# pragma once
#endif /* ACE_LACKS_PRAGMA_ONCE */
#include "ace/SOCK_Acceptor.h"
#include "ace/Local_Tokens.h"
#include "ace/Token_Collection.h"
#include "ace/Token_Request_Reply.h"
#include "ace/svc_export.h"
#if defined (ACE_HAS_TOKENS_LIBRARY)
/**
* @class ACE_Token_Handler
*
* @brief Product object created by an . A
* exchanges messages with a object
* on the client-side.
*
* This class is the main workhorse of the ACE Token service. It
* receives token operation requests from remote clients and turns
* them into calls on local tokens (acquire, release, renew, and
* remove). In OMG CORBA terms, it is an object adapter. It also
* schedules and handles timeouts that are used to support "timed
* waits." Clients used timed waits to bound the amount of time
* they block trying to get a token.
*/
class ACE_Svc_Export ACE_Token_Handler : public ACE_Svc_Handler
{
public:
/// Default constructor.
ACE_Token_Handler (ACE_Thread_Manager * = 0);
// = Accessor and mutator methods.
// = Remote operations "exported" to a client.
/**
* Try to acquire the token.
* Precondition: client *may* hold the token already (i.e.,
* supports recursive acquisitions).
*/
virtual int acquire (ACE_Token_Proxy *proxy);
/// Try to acquire the token.
virtual int try_acquire (ACE_Token_Proxy *proxy);
/// Release the token and allow the next client that is waiting to
/// proceed. Preconditions: client must hold the token.
virtual int release (ACE_Token_Proxy *proxy);
/// Yield the token if any clients are waiting, otherwise keep the
/// token. Preconditions: client must hold the token.
virtual int renew (ACE_Token_Proxy *proxy);
/**
* Remove the specified token from the Token_Map. Preconditions:
* ACE_Token must exist. @@ Any other preconditions, e.g., must
* client hold token, must there be no waiters, etc.?
*/
virtual int remove (ACE_Token_Proxy *proxy);
/// Called by TS_[Mutex,RLock,WLock] when we hold the mutex and
/// someone wants it.
void sleep_hook ();
/// Called by TS_[Mutex,RLock,WLock] when we are waiting and acquire
/// the mutex.
void token_acquired (ACE_TPQ_Entry *);
protected:
// = Low level routines for framing requests, dispatching
// operations, and returning replies.
/// Our connection has been closed.
virtual int abandon (int send_error);
/// Receive, frame, and decode the client's request.
virtual int recv_request ();
/// Dispatch the appropriate operation to handle the client's
/// request.
virtual int dispatch ();
/// Create and send a reply to the client.
virtual int send_reply (ACE_UINT32 errnum);
// = Demultiplexing hooks.
/// Callback method invoked by the when client events
/// arrive.
virtual int handle_input (ACE_HANDLE);
// = Timer hook.
/// Enable clients to limit the amount of time they wait for a token.
virtual int handle_timeout (const ACE_Time_Value &tv, const void *arg);
/// return a proxy for the calling client_id and token name.
ACE_Token_Proxy *get_proxy ();
private:
/// Switches on the type of token_request_ and creates a new
/// Token_Proxy.
virtual ACE_Token_Proxy *create_proxy ();
/// Keeps track of the synchronization options (i.e., the timeout
/// interval).
ACE_Synch_Options request_options_;
/// collection of the client's token proxies.
ACE_Token_Collection collection_;
/// ID returned by the Reactor that is used to kill registered timers
/// when a token operation times out.
long timeout_id_;
/// Cache request from the client.
ACE_Token_Request token_request_;
/// Cache reply to the client.
ACE_Token_Reply token_reply_;
};
// = DESCRIPTION of ACE_TS_* classes:
// When Tokens are released, waiting token proxies are notified
// when the releasing thread calls token_acquired on the waiting
// proxy. The Token Server specializes ACE_Token_Proxy to
// redefine the implementation of token_acquired. When
// token_acquired is called, the Token_Handler can then send the
// response back over the socket connection to unblock the
// client side.
// Since only the Token_Handler uses ACE_TS_Mutex, we've moved
// the definition to the .cpp file.
/**
* @class ACE_TS_Mutex
*
* @brief ACE_TS_Mutex -- ACE_*T*oken_*S*erver_Mutex
*/
class ACE_TS_Mutex : public ACE_Local_Mutex
{
public:
/// Creation.
ACE_TS_Mutex (const ACE_TCHAR *name,
ACE_Token_Handler *th);
protected:
/// Somebody wants our token!
virtual void sleep_hook ();
/**
* We've been taken off the waiters list and given the token! Call
* the Token_Handler associated at construction, so it can tell the
* remote client.
*/
virtual void token_acquired (ACE_TPQ_Entry *);
/// Duplication.
ACE_TS_Mutex (const ACE_TS_Mutex &);
/// Return a deep copy.
virtual ACE_Token_Proxy *clone () const;
private:
/// The Token Handler associated with this proxy. Set at
/// construction and notified when blocking acquires succeed.
ACE_Token_Handler* th_;
};
/**
* @class ACE_TS_RLock
*
* @brief ACE_TS_RLock -- ACE_*T*oken_*S*erver_RLock
*/
class ACE_TS_RLock : public ACE_Local_RLock
{
public:
/// Creation.
ACE_TS_RLock (const ACE_TCHAR *name,
ACE_Token_Handler *th);
protected:
/// Somebody wants our token!
virtual void sleep_hook ();
/**
* We've been taken off the waiters list and given the token! Call
* the Token_Handler associated at construction, so it can tell the
* remote client.
*/
virtual void token_acquired (ACE_TPQ_Entry *);
/// Duplication.
ACE_TS_RLock (const ACE_TS_RLock&);
/// Return a deep copy.
virtual ACE_Token_Proxy *clone () const;
private:
/// the Token Handler associated with this proxy. Set at
/// construction and notified when blocking acquires succeed.
ACE_Token_Handler* th_;
};
/**
* @class ACE_TS_WLock
*
* @brief ACE_TS_WLock -- ACE_*T*oken_*S*erver_WLock
*/
class ACE_TS_WLock : public ACE_Local_WLock
{
public:
/// Creation.
ACE_TS_WLock (const ACE_TCHAR *name,
ACE_Token_Handler *th);
protected:
/// Somebody wants our token!
virtual void sleep_hook ();
/**
* We've been taken off the waiters list and given the token! Call
* the Token_Handler associated at construction, so it can tell the
* remote client.
*/
virtual void token_acquired (ACE_TPQ_Entry *);
/// Duplication.
ACE_TS_WLock (const ACE_TS_WLock&);
/// Return a deep copy.
virtual ACE_Token_Proxy *clone () const;
private:
/// the Token Handler associated with this proxy. Set at
/// construction and notified when blocking acquires succeed.
ACE_Token_Handler* th_;
};
/**
* @class ACE_Token_Acceptor
*
* @brief This class contains the service-specific methods that can't
* easily be factored into the .
*/
class ACE_Token_Acceptor : public ACE_Strategy_Acceptor
{
public:
/// Dynamic linking hook.
virtual int init (int argc, ACE_TCHAR *argv[]);
/// Parse svc.conf arguments.
int parse_args (int argc, ACE_TCHAR *argv[]);
private:
/// The scheduling strategy is designed for Reactive services.
ACE_Schedule_All_Reactive_Strategy scheduling_strategy_;
};
ACE_SVC_FACTORY_DECLARE (ACE_Token_Acceptor)
#endif /* ACE_HAS_TOKENS_LIBRARY */
#endif /* ACE_TOKEN_HANDLER_H */
ace-8.0.1+dfsg.orig/netsvcs/lib/Time_Request_Reply.cpp 0000644 0001750 0001750 00000012442 14653111173 021705 0 ustar sudip sudip #include "ace/Basic_Types.h"
#include "ace/CDR_Base.h"
#include "ace/Log_Msg.h"
#include "ace/Truncate.h"
#include "ace/os_include/netinet/os_in.h"
#include "ace/os_include/arpa/os_inet.h"
#include "Time_Request_Reply.h"
// Default "do nothing" constructor.
ACE_Time_Request::ACE_Time_Request ()
{
ACE_TRACE ("ACE_Time_Request::ACE_Time_Request");
}
// Create a ACE_Time_Request message.
ACE_Time_Request::ACE_Time_Request (ACE_INT32 t, // Type of request.
const time_t time,
ACE_Time_Value *timeout) // Max time waiting for request.
{
ACE_TRACE ("ACE_Time_Request::ACE_Time_Request");
this->msg_type (t);
// If timeout is a NULL pointer, then block forever...
if (timeout == 0)
{
this->transfer_.block_forever_ = 1;
this->transfer_.sec_timeout_ = 0;
this->transfer_.usec_timeout_ = 0;
}
else // Do a "timed wait."
{
this->block_forever (0);
// Keep track of how long client is willing to wait.
this->transfer_.sec_timeout_ = timeout->sec ();
this->transfer_.usec_timeout_ = timeout->usec ();
}
// Copy time into request
this->transfer_.time_ = this->time_ = time;
}
// Get the fixed size of message
ssize_t
ACE_Time_Request::size () const
{
ACE_TRACE ("ACE_Time_Request::size");
return sizeof (this->transfer_);
}
// = Set/get the type of the message.
ACE_INT32
ACE_Time_Request::msg_type () const
{
ACE_TRACE ("ACE_Time_Request::msg_type");
return this->transfer_.msg_type_;
}
void
ACE_Time_Request::msg_type (ACE_INT32 t)
{
ACE_TRACE ("ACE_Time_Request::msg_type");
this->transfer_.msg_type_ = t;
}
// = Set/get the blocking semantics.
ACE_UINT32
ACE_Time_Request::block_forever () const
{
ACE_TRACE ("ACE_Time_Request::block_forever");
return this->transfer_.block_forever_;
}
void
ACE_Time_Request::block_forever (ACE_UINT32 bs)
{
ACE_TRACE ("ACE_Time_Request::block_forever");
this->transfer_.block_forever_ = bs;
}
// = Set/get the timeout.
ACE_Time_Value
ACE_Time_Request::timeout () const
{
ACE_TRACE ("ACE_Time_Request::timeout");
time_t sec = ACE_Utils::truncate_cast (this->transfer_.sec_timeout_);
return ACE_Time_Value (sec, this->transfer_.usec_timeout_);
}
void
ACE_Time_Request::timeout (const ACE_Time_Value& timeout)
{
ACE_TRACE ("ACE_Time_Request::timeout");
this->transfer_.sec_timeout_ = timeout.sec ();
this->transfer_.usec_timeout_ = timeout.usec ();
}
// = Set/get the time
time_t
ACE_Time_Request::time () const
{
ACE_TRACE ("ACE_Time_Request::time");
return this->time_;
}
void
ACE_Time_Request::time (time_t t)
{
ACE_TRACE ("ACE_Time_Request::time");
this->time_ = t;
}
// Encode the transfer buffer into network byte order
// so that it can be sent to the server.
int
ACE_Time_Request::encode (void *&buf)
{
ACE_TRACE ("ACE_Time_Request::encode");
// Compute the length *before* doing the marshaling.
buf = (void *) &this->transfer_;
this->transfer_.block_forever_ = ACE_HTONL (this->transfer_.block_forever_);
this->transfer_.usec_timeout_ = ACE_HTONL (this->transfer_.usec_timeout_);
this->transfer_.msg_type_ = ACE_HTONL (this->transfer_.msg_type_);
#if defined (ACE_LITTLE_ENDIAN)
ACE_UINT64 secs = this->transfer_.sec_timeout_;
ACE_CDR::swap_8 ((const char *)&secs, (char *)&this->transfer_.sec_timeout_);
secs = this->transfer_.time_;
ACE_CDR::swap_8 ((const char *)&secs, (char *)&this->transfer_.time_);
#endif
return this->size (); // Always fixed
}
// Decode the transfer buffer into host byte byte order
// so that it can be used by the server.
int
ACE_Time_Request::decode ()
{
ACE_TRACE ("ACE_Time_Request::decode");
// Decode
this->transfer_.block_forever_ = ACE_NTOHL (this->transfer_.block_forever_);
this->transfer_.usec_timeout_ = ACE_NTOHL (this->transfer_.usec_timeout_);
this->transfer_.msg_type_ = ACE_NTOHL (this->transfer_.msg_type_);
#if defined (ACE_LITTLE_ENDIAN)
ACE_UINT64 secs = this->transfer_.sec_timeout_;
ACE_CDR::swap_8 ((const char *)&secs, (char *)&this->transfer_.sec_timeout_);
secs = this->transfer_.time_;
ACE_CDR::swap_8 ((const char *)&secs, (char *)&this->transfer_.time_);
#endif
this->time_ = ACE_Utils::truncate_cast (this->transfer_.time_);
return 0;
}
// Print out the current values of the ACE_Time_Request.
void
ACE_Time_Request::dump () const
{
#if defined (ACE_HAS_DUMP)
ACE_TRACE ("ACE_Time_Request::dump");
ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("*******\nlength = %d\n"),
this->size ()));
ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("message-type = ")));
switch (this->msg_type ())
{
case ACE_Time_Request::TIME_UPDATE:
ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("TIME_UPDATE\n")));
break;
default:
ACE_DEBUG ((LM_DEBUG, ACE_TEXT (" = %d\n"), this->msg_type ()));
break;
}
if (this->block_forever ())
ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("blocking forever\n")));
else
{
#if !defined (ACE_NLOGGING)
ACE_Time_Value tv = this->timeout ();
#endif /* ! ACE_NLOGGING */
ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("waiting for %d secs and %d usecs\n"),
(int)(tv.sec ()), tv.usec ()));
}
ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("*******\ntime = %d\n"),
(int)(this->time ())));
ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("+++++++\n")));
#endif /* ACE_HAS_DUMP */
}
ace-8.0.1+dfsg.orig/netsvcs/lib/Name_Handler.cpp 0000644 0001750 0001750 00000047673 14653111173 020457 0 ustar sudip sudip #include "ace/Containers.h"
#include "ace/Get_Opt.h"
#include "ace/Singleton.h"
#include
#include "Name_Handler.h"
#include "ace/Signal.h"
#include "ace/OS_NS_string.h"
// Simple macro that does bitwise AND -- useful in table lookup
#define ACE_TABLE_MAP(INDEX, MASK) (INDEX & MASK)
// Simple macro that does bitwise AND and then right shift bits by 3
#define ACE_LIST_MAP(INDEX, MASK) (((unsigned long) (INDEX & MASK)) >> 3)
int
ACE_Name_Acceptor::parse_args (int argc, ACE_TCHAR *argv[])
{
ACE_TRACE ("ACE_Name_Acceptor::parse_args");
int service_port = ACE_DEFAULT_SERVER_PORT;
ACE_LOG_MSG->open (ACE_TEXT ("Name Service"));
this->naming_context()->name_options()->parse_args( argc, argv );
service_port = this->naming_context()->name_options()->nameserver_port();
// dont allow to connect to another name serever
if(this->naming_context()->name_options()->context() == ACE_Naming_Context::NET_LOCAL)
this->naming_context()->name_options()->nameserver_host(ACE_TEXT ("localhost"));
if (this->naming_context()->open( this->naming_context()->name_options()->context() ) == -1)
ACE_ERROR_RETURN ((LM_ERROR,
ACE_TEXT ("%n:\n open naming context failed.\n")),
-1);
this->service_addr_.set (service_port);
return 0;
}
int
ACE_Name_Acceptor::init (int argc, ACE_TCHAR *argv[])
{
ACE_TRACE ("ACE_Name_Acceptor::init");
// Use the options hook to parse the command line arguments and set
// options.
if( this->parse_args (argc, argv) == -1 )
ACE_ERROR_RETURN ((LM_ERROR,
ACE_TEXT ("%p\n"),
ACE_TEXT ("ACE_Name_Acceptor::parse_args failed")),
-1);
// Set the acceptor endpoint into listen mode (use the Singleton
// global Reactor...).
if (this->open (this->service_addr_,
ACE_Reactor::instance (),
0, 0, 0,
&this->scheduling_strategy_,
ACE_TEXT ("Name Server"),
ACE_TEXT ("ACE naming service")) == -1)
ACE_ERROR_RETURN ((LM_ERROR,
ACE_TEXT ("%n: %p on port %d\n"),
ACE_TEXT ("acceptor::open failed"),
this->service_addr_.get_port_number ()),
-1);
// Ignore SIGPIPE so that each can handle this on its
// own.
ACE_Sig_Action sig ((ACE_SignalHandler) SIG_IGN, SIGPIPE);
ACE_UNUSED_ARG (sig);
ACE_INET_Addr server_addr;
// Figure out what port we're really bound to.
if (this->acceptor ().get_local_addr (server_addr) == -1)
ACE_ERROR_RETURN ((LM_ERROR,
ACE_TEXT ("%p\n"),
ACE_TEXT ("get_local_addr")),
-1);
ACE_DEBUG ((LM_DEBUG,
ACE_TEXT ("starting up Name Server at port %d on handle %d\n"),
server_addr.get_port_number (),
this->acceptor ().get_handle ()));
return 0;
}
// The following is a "Factory" used by the ACE_Service_Config and
// svc.conf file to dynamically initialize the state of the Naming
// Server.
ACE_SVC_FACTORY_DEFINE (ACE_Name_Acceptor)
// Default constructor.
ACE_Name_Handler::ACE_Name_Handler (ACE_Thread_Manager *tm)
: ACE_Svc_Handler (tm)
{
ACE_TRACE ("ACE_Name_Handler::ACE_Name_Handler");
// Set up pointers to member functions for the top-level dispatching
// of client requests.
this->op_table_[ACE_Name_Request::BIND] = &ACE_Name_Handler::bind;
this->op_table_[ACE_Name_Request::REBIND] = &ACE_Name_Handler::rebind;
this->op_table_[ACE_Name_Request::RESOLVE] = &ACE_Name_Handler::resolve;
this->op_table_[ACE_Name_Request::UNBIND] = &ACE_Name_Handler::unbind;
this->op_table_[ACE_Name_Request::LIST_NAMES] = &ACE_Name_Handler::lists;
this->op_table_[ACE_Name_Request::LIST_NAME_ENTRIES] = &ACE_Name_Handler::lists_entries;
// Assign references to simplify subsequent code.
LIST_ENTRY &list_names_ref = this->list_table_[ACE_LIST_MAP (ACE_Name_Request::LIST_NAMES,
ACE_Name_Request::LIST_OP_MASK)];
LIST_ENTRY &list_values_ref = this->list_table_[ACE_LIST_MAP (ACE_Name_Request::LIST_VALUES,
ACE_Name_Request::LIST_OP_MASK)];
LIST_ENTRY &list_types_ref = this->list_table_[ACE_LIST_MAP (ACE_Name_Request::LIST_TYPES,
ACE_Name_Request::LIST_OP_MASK)];
// Set up pointers to member functions for dispatching within the
// LIST_{NAMES,VALUES,TYPES} methods.
list_names_ref.operation_ = &ACE_Naming_Context::list_names;
list_names_ref.request_factory_ = &ACE_Name_Handler::name_request;
list_names_ref.description_ = "request for LIST_NAMES\n";
list_values_ref.operation_ = &ACE_Naming_Context::list_values;
list_values_ref.request_factory_ = &ACE_Name_Handler::value_request;
list_values_ref.description_ = "request for LIST_VALUES\n";
list_types_ref.operation_ = &ACE_Naming_Context::list_types;
list_types_ref.request_factory_ = &ACE_Name_Handler::type_request;
list_types_ref.description_ = "request for LIST_TYPES\n";
}
// Activate this instance of the ACE_Name_Handler (called by the
// ACE_Name_Acceptor).
/* VIRTUAL */ int
ACE_Name_Handler::open (void * v)
{
ACE_TRACE ("ACE_Name_Handler::open");
// Call down to our parent to register ourselves with the Reactor.
if (ACE_Svc_Handler::open (0) == -1)
ACE_ERROR_RETURN ((LM_ERROR,
ACE_TEXT ("%p\n"),
ACE_TEXT ("open")),
-1);
ACE_Name_Acceptor* acceptor_ = static_cast(v);
naming_context_ = acceptor_->naming_context();
return 0;
}
// Create and send a reply to the client.
/* VIRTUAL */ int
ACE_Name_Handler::send_reply (ACE_INT32 status,
ACE_UINT32 err)
{
ACE_TRACE ("ACE_Name_Handler::send_reply");
void *buf;
this->name_reply_.msg_type (status);
this->name_reply_.errnum (err);
this->name_reply_.init ();
int len = this->name_reply_.encode (buf);
if (len == -1)
return -1;
ssize_t n = this->peer ().send (buf, len);
if (n != len)
ACE_ERROR_RETURN ((LM_ERROR,
ACE_TEXT ("%p\n, expected len = %d, actual len = %d"),
ACE_TEXT ("send failed"),
len,
n),
-1);
else
return 0;
}
/* VIRTUAL */ int
ACE_Name_Handler::send_request (ACE_Name_Request &request)
{
ACE_TRACE ("ACE_Name_Handler::send_request");
void *buffer;
ssize_t length = request.encode (buffer);
if (length == -1)
ACE_ERROR_RETURN ((LM_ERROR,
ACE_TEXT ("%p\n"),
ACE_TEXT ("encode failed")),
-1);
// Transmit request via a blocking send.
if (this->peer ().send_n (buffer, length) != length)
ACE_ERROR_RETURN ((LM_ERROR,
ACE_TEXT ("%p\n"),
ACE_TEXT ("send_n failed")),
-1);
return 0;
}
// Give up waiting (e.g., when a timeout occurs or a client shuts down
// unexpectedly).
/* VIRTUAL */ int
ACE_Name_Handler::abandon ()
{
ACE_TRACE ("ACE_Name_Handler::abandon");
return this->send_reply (-1, errno);
}
// Enable clients to limit the amount of time they'll wait
/* VIRTUAL */ int
ACE_Name_Handler::handle_timeout (const ACE_Time_Value &, const void *)
{
ACE_TRACE ("ACE_Name_Handler::handle_timeout");
return this->abandon ();
}
// Return the underlying ACE_HANDLE.
/* VIRTUAL */ ACE_HANDLE
ACE_Name_Handler::get_handle () const
{
ACE_TRACE ("ACE_Name_Handler::get_handle");
return this->peer ().get_handle ();
}
// Dispatch the appropriate operation to handle the client request.
/* VIRTUAL */ int
ACE_Name_Handler::dispatch ()
{
ACE_TRACE ("ACE_Name_Handler::dispatch");
// Dispatch the appropriate request.
int index = this->name_request_.msg_type ();
// Invoke the appropriate member function obtained by indexing into
// the op_table_. ACE_TABLE_MAP returns the same index (by bitwise
// AND) for list_names, list_values, and list_types since they are
// all handled by the same method. Similarly, it returns the same
// index for list_name_entries, list_value_entries, and
// list_type_entries.
return (this->*op_table_[ACE_TABLE_MAP (index,
ACE_Name_Request::OP_TABLE_MASK)]) ();
}
// Receive, frame, and decode the client's request. Note, this method
// should use non-blocking I/O.
/* VIRTUAL */ int
ACE_Name_Handler::recv_request ()
{
ACE_TRACE ("ACE_Name_Handler::recv_request");
// Read the first 4 bytes to get the length of the message This
// implementation assumes that the first 4 bytes are the length of
// the message.
ssize_t n = this->peer ().recv ((void *) &this->name_request_,
sizeof (ACE_UINT32));
switch (n)
{
case -1:
ACE_DEBUG ((LM_DEBUG,
ACE_TEXT ("****************** recv_request returned -1\n")));
ACE_FALLTHROUGH;
default:
ACE_ERROR ((LM_ERROR,
ACE_TEXT ("%p got %d bytes, expected %d bytes\n"),
ACE_TEXT ("recv failed"),
n,
sizeof (ACE_UINT32)));
ACE_FALLTHROUGH;
case 0:
// We've shutdown unexpectedly, let's abandon the connection.
this->abandon ();
return -1;
/* NOTREACHED */
case sizeof (ACE_UINT32):
{
// Transform the length into host byte order.
ssize_t length = ACE_NTOHL (this->name_request_.length ());
// Do a sanity check on the length of the message.
if (length > (ssize_t) sizeof this->name_request_)
{
ACE_ERROR ((LM_ERROR,
ACE_TEXT ("length %d too long\n"),
length));
return this->abandon ();
}
// Receive the rest of the request message.
// @@ beware of blocking read!!!.
n = this->peer ().recv ((void *) (((char *) &this->name_request_)
+ sizeof (ACE_UINT32)),
length - sizeof (ACE_UINT32));
// Subtract off the size of the part we skipped over...
if (n != (length - (ssize_t) sizeof (ACE_UINT32)))
{
ACE_ERROR ((LM_ERROR, ACE_TEXT ("%p expected %d, got %d\n"),
ACE_TEXT ("invalid length"), length, n));
return this->abandon ();
}
// Decode the request into host byte order.
if (this->name_request_.decode () == -1)
{
ACE_ERROR ((LM_ERROR,
ACE_TEXT ("%p\n"),
ACE_TEXT ("decode failed")));
return this->abandon ();
}
}
}
return 0;
}
// Callback method invoked by the ACE_Reactor when events arrive from
// the client.
/* VIRTUAL */ int
ACE_Name_Handler::handle_input (ACE_HANDLE)
{
ACE_TRACE ("ACE_Name_Handler::handle_input");
if (this->recv_request () == -1)
return -1;
else
return this->dispatch ();
}
int
ACE_Name_Handler::bind ()
{
ACE_TRACE ("ACE_Name_Handler::bind");
return this->shared_bind (0);
}
int
ACE_Name_Handler::rebind ()
{
ACE_TRACE ("ACE_Name_Handler::rebind");
int result = this->shared_bind (1);
return result == 1 ? 0 : result;
}
int
ACE_Name_Handler::shared_bind (int rebind)
{
ACE_TRACE ("ACE_Name_Handler::shared_bind");
ACE_NS_WString a_name (this->name_request_.name (),
this->name_request_.name_len () / sizeof (ACE_WCHAR_T));
ACE_NS_WString a_value (this->name_request_.value (),
this->name_request_.value_len () / sizeof (ACE_WCHAR_T));
int result;
if (rebind == 0)
{
#if 0
ACE_DEBUG ((LM_DEBUG,
ACE_TEXT ("request for BIND\n")));
#endif /* 0 */
result = this->naming_context ()->bind (a_name,
a_value,
this->name_request_.type ());
}
else
{
#if 0
ACE_DEBUG ((LM_DEBUG,
ACE_TEXT ("request for REBIND\n")));
#endif /* 0 */
result = this->naming_context ()->rebind (a_name,
a_value,
this->name_request_.type ());
if (result == 1)
result = 0;
}
if (result == 0)
return this->send_reply (0);
else
return this->send_reply (-1);
}
int
ACE_Name_Handler::resolve ()
{
ACE_TRACE ("ACE_Name_Handler::resolve");
#if 0
ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("request for RESOLVE\n")));
#endif /* 0 */
ACE_NS_WString a_name (this->name_request_.name (),
this->name_request_.name_len () / sizeof (ACE_WCHAR_T));
// The following will deliver our reply back to client we
// pre-suppose success (indicated by type RESOLVE).
ACE_NS_WString avalue;
char *atype;
if (this->naming_context ()->resolve (a_name, avalue, atype) == 0)
{
std::unique_ptr avalue_urep (avalue.rep ());
ACE_Name_Request nrq (ACE_Name_Request::RESOLVE,
0,
0,
avalue_urep.get (),
avalue.length () * sizeof (ACE_WCHAR_T),
atype, ACE_OS::strlen (atype));
delete[] atype;
return this->send_request (nrq);
}
ACE_Name_Request nrq (ACE_Name_Request::BIND, 0, 0, 0, 0, 0, 0);
this->send_request (nrq);
return 0;
}
int
ACE_Name_Handler::unbind ()
{
ACE_TRACE ("ACE_Name_Handler::unbind");
#if 0
ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("request for UNBIND\n")));
#endif /* 0 */
ACE_NS_WString a_name (this->name_request_.name (),
this->name_request_.name_len () / sizeof (ACE_WCHAR_T));
if (this->naming_context ()->unbind (a_name) == 0)
return this->send_reply (0);
else
return this->send_reply (-1);
}
ACE_Name_Request
ACE_Name_Handler::name_request (ACE_NS_WString *one_name)
{
ACE_TRACE ("ACE_Name_Handler::name_request");
std::unique_ptr one_name_urep (one_name->rep ());
return ACE_Name_Request (ACE_Name_Request::LIST_NAMES,
one_name_urep.get (),
one_name->length () * sizeof (ACE_WCHAR_T),
0, 0,
0, 0);
}
ACE_Name_Request
ACE_Name_Handler::value_request (ACE_NS_WString *one_value)
{
ACE_TRACE ("ACE_Name_Handler::value_request");
std::unique_ptr one_value_urep (one_value->rep ());
return ACE_Name_Request (ACE_Name_Request::LIST_VALUES,
0, 0,
one_value_urep.get (),
one_value->length () * sizeof (ACE_WCHAR_T),
0, 0);
}
ACE_Name_Request
ACE_Name_Handler::type_request (ACE_NS_WString *one_type)
{
ACE_TRACE ("ACE_Name_Handler::type_request");
return ACE_Name_Request (ACE_Name_Request::LIST_TYPES,
0, 0,
0, 0,
std::unique_ptr (one_type->char_rep ()).get (),
one_type->length ());
}
int
ACE_Name_Handler::lists ()
{
ACE_TRACE ("ACE_Name_Handler::lists");
ACE_PWSTRING_SET set;
ACE_NS_WString pattern (this->name_request_.name (),
this->name_request_.name_len () / sizeof (ACE_WCHAR_T));
// Get the index into the list table
int index = ACE_LIST_MAP (this->name_request_.msg_type (),
ACE_Name_Request::LIST_OP_MASK);
// Print the message type
ACE_DEBUG ((LM_DEBUG, list_table_[index].description_));
// Call the appropriate method
if ((this->naming_context ()->*list_table_[index].operation_) (set, pattern) != 0)
{
// None found so send blank request back
ACE_Name_Request end_rq (ACE_Name_Request::MAX_ENUM, 0, 0, 0, 0, 0, 0);
if (this->send_request (end_rq) == -1)
return -1;
}
else
{
ACE_NS_WString *one_entry = 0;
for (ACE_Unbounded_Set_Iterator set_iterator (set);
set_iterator.next (one_entry) !=0;
set_iterator.advance())
{
ACE_Name_Request nrq ((this->*list_table_[index].request_factory_) (one_entry));
// Create a request by calling the appropriate method obtained
// by accessing into the table. Then send the request across.
if (this->send_request (nrq) == -1)
return -1;
}
// Send last message indicator.
ACE_Name_Request nrq (ACE_Name_Request::MAX_ENUM,
0, 0,
0, 0,
0, 0);
return this->send_request (nrq);
}
return 0;
}
int
ACE_Name_Handler::lists_entries ()
{
ACE_TRACE ("ACE_Name_Handler::lists_entries");
ACE_BINDING_SET set;
ACE_NS_WString pattern (this->name_request_.name (),
this->name_request_.name_len () / sizeof (ACE_WCHAR_T));
int result = -1;
const ACE_Name_Request::Constants msg_type =
static_cast (this->name_request_.msg_type ());
// NOTE: This multi-branch conditional statement used to be
// (and should be) a switch statement. However, it caused
// Internal compiler error 980331 with egcs 1.1 (2.91.57).
// So, the pointer-to-member-function temporary has been removed.
if (msg_type == ACE_Name_Request::LIST_NAME_ENTRIES)
{
#if 0
ACE_DEBUG ((LM_DEBUG,
ACE_TEXT ("request for LIST_NAME_ENTRIES\n")));
#endif /* 0 */
result = this->naming_context ()->
ACE_Naming_Context::list_name_entries (set, pattern);
}
else if (msg_type == ACE_Name_Request::LIST_VALUE_ENTRIES)
{
#if 0
ACE_DEBUG ((LM_DEBUG,
ACE_TEXT ("request for LIST_VALUE_ENTRIES\n")));
#endif /* 0 */
result = this->naming_context ()->
ACE_Naming_Context::list_value_entries (set, pattern);
}
else if (msg_type == ACE_Name_Request::LIST_TYPE_ENTRIES)
{
#if 0
ACE_DEBUG ((LM_DEBUG,
ACE_TEXT ("request for LIST_TYPE_ENTRIES\n")));
#endif /* 0 */
result = this->naming_context ()->
ACE_Naming_Context::list_type_entries (set, pattern);
}
else
return -1;
if (result == 0)
{
ACE_Name_Binding *one_entry = 0;
for (ACE_Unbounded_Set_Iterator set_iterator (set);
set_iterator.next (one_entry) !=0;
set_iterator.advance())
{
std::unique_ptr name_urep (one_entry->name_.rep ());
std::unique_ptr value_urep (one_entry->value_.rep ());
ACE_Name_Request mynrq (this->name_request_.msg_type (),
name_urep.get (),
one_entry->name_.length () * sizeof (ACE_WCHAR_T),
value_urep.get (),
one_entry->value_.length () * sizeof (ACE_WCHAR_T),
one_entry->type_,
ACE_OS::strlen (one_entry->type_));
if (this->send_request (mynrq) == -1)
return -1;
}
// send last message indicator
ACE_Name_Request nrq (ACE_Name_Request::MAX_ENUM, 0, 0, 0, 0, 0, 0);
if (this->send_request (nrq) == -1)
return -1;
}
else
{
// None found so send blank request back.
ACE_Name_Request end_rq (ACE_Name_Request::MAX_ENUM, 0, 0, 0, 0, 0, 0);
if (this->send_request (end_rq) == -1)
return -1;
}
return 0;
}
ACE_Naming_Context *
ACE_Name_Handler::naming_context ()
{
return naming_context_;
}
ACE_Naming_Context *
ACE_Name_Acceptor::naming_context ()
{
return &naming_context_;
}
ACE_Name_Handler::~ACE_Name_Handler ()
{
ACE_TRACE ("ACE_Name_Handler::~ACE_Name_Handler");
#if 0
ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("closing down Handle %d\n"),
this->get_handle ()));
#endif /* 0 */
}
ace-8.0.1+dfsg.orig/netsvcs/lib/Server_Logging_Handler.cpp 0000644 0001750 0001750 00000001464 14653111173 022477 0 ustar sudip sudip #if !defined (ACE_SERVER_LOGGING_HANDLER_C)
#define ACE_SERVER_LOGGING_HANDLER_C
#include "Server_Logging_Handler.h"
// The following are "Factories" used by the ACE_Service_Config and
// svc.conf file to dynamically initialize the state of the
// single-threaded and multi-threaded logging server.
ACE_SVC_FACTORY_DEFINE (ACE_Server_Logging_Acceptor)
ACE_SVC_FACTORY_DEFINE (ACE_Thr_Server_Logging_Acceptor)
#if defined (ACE_HAS_EXPLICIT_STATIC_TEMPLATE_MEMBER_INSTANTIATION)
template u_long
ACE_Server_Logging_Handler_T::request_count_;
#endif /* ACE_HAS_EXPLICIT_STATIC_TEMPLATE_MEMBER_INSTANTIATION */
#endif /* ACE_SERVER_LOGGING_HANDLER_C */
ace-8.0.1+dfsg.orig/netsvcs/lib/Base_Optimizer.cpp 0000644 0001750 0001750 00000001030 14653111173 021027 0 ustar sudip sudip #if !defined (BASE_OPTIMIZER_CPP)
#define BASE_OPTIMIZER_CPP
#include "Base_Optimizer.h"
template
Base_Optimizer::Base_Optimizer ()
{
}
template
Base_Optimizer::Base_Optimizer (const Base &base,
const Member &member)
: Base (base),
m_ (member)
{
}
template
Base_Optimizer::Base_Optimizer (const Base &base)
: Base (base)
{
}
#endif /* BASE_OPTIMIZER_CPP */
ace-8.0.1+dfsg.orig/netsvcs/lib/Name_Handler.h 0000644 0001750 0001750 00000013520 14653111173 020104 0 ustar sudip sudip // -*- C++ -*-
//=============================================================================
/**
* @file Name_Handler.h
*
* @author Prashant Jain
* @author Gerhard Lenzer
* @author and Douglas C. Schmidt
*/
//=============================================================================
#ifndef ACE_NAME_HANDLER_H
#define ACE_NAME_HANDLER_H
#include "ace/Acceptor.h"
#if !defined (ACE_LACKS_PRAGMA_ONCE)
# pragma once
#endif /* ACE_LACKS_PRAGMA_ONCE */
#include "ace/SOCK_Acceptor.h"
#include "ace/SString.h"
#include "ace/Svc_Handler.h"
#include "ace/Naming_Context.h"
#include "ace/Name_Request_Reply.h"
#include "ace/Null_Mutex.h"
#include "ace/svc_export.h"
#if defined ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION_EXPORT
template class ACE_Svc_Export ACE_Svc_Handler;
#endif /* ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION_EXPORT */
/**
* @class ACE_Name_Handler
*
* @brief Product object created by . An
* exchanges messages with a
* object on the client-side.
*
* This class is the main workhorse of the . It
* handles client requests to bind, rebind, resolve, and unbind
* names. It also schedules and handles timeouts that are used to
* support "timed waits." Clients used timed waits to bound the
* amount of time they block trying to get a name.
*/
class ACE_Svc_Export ACE_Name_Handler : public ACE_Svc_Handler
{
public:
/// Pointer to a member function of ACE_Name_Handler returning int
typedef int (ACE_Name_Handler::*OPERATION) ();
/// Pointer to a member function of ACE_Naming_Context returning int
typedef int (ACE_Naming_Context::*LIST_OP) (ACE_PWSTRING_SET &, const ACE_NS_WString &);
/// Pointer to a member function of ACE_Name_Handler returning ACE_Name_Request
typedef ACE_Name_Request (ACE_Name_Handler::*REQUEST) (ACE_NS_WString *);
/// Default constructor.
ACE_Name_Handler (ACE_Thread_Manager * = 0);
/// Activate this instance of the (called by the
/// ).
virtual int open (void * = 0);
protected:
// = Helper routines for the operations exported to clients.
/// Give up waiting (e.g., when a timeout occurs or a client shuts
/// down unexpectedly).
virtual int abandon ();
// = Low level routines for framing requests, dispatching
// operations, and returning replies.
/// Receive, frame, and decode the client's request.
virtual int recv_request ();
/// Dispatch the appropriate operation to handle the client's
/// request.
virtual int dispatch ();
/// Create and send a reply to the client.
virtual int send_reply (ACE_INT32 status,
ACE_UINT32 errnum = 0);
/// Special kind of reply
virtual int send_request (ACE_Name_Request &);
// = Demultiplexing hooks.
/// Return the underlying .
virtual ACE_HANDLE get_handle () const;
/// Callback method invoked by the when client events
/// arrive.
virtual int handle_input (ACE_HANDLE);
// = Timer hook.
/// Enable clients to limit the amount of time they wait for a name.
virtual int handle_timeout (const ACE_Time_Value &tv, const void *arg);
/// Ensure dynamic allocation...
~ACE_Name_Handler ();
private:
/// Table of pointers to member functions
OPERATION op_table_[ACE_Name_Request::MAX_ENUM];
struct LIST_ENTRY
{
LIST_OP operation_;
// A member function pointer that performs the appropriate
// operation (e.g., LIST_NAMES, LIST_VALUES, or LIST_TYPES).
REQUEST request_factory_;
// A member function pointer that serves as a factory to create a
// request that is passed back to the client.
const char *description_;
// Name of the operation we're dispatching (used for debugging).
};
/// This is the table of pointers to functions that we use to
/// simplify the handling of list requests.
LIST_ENTRY list_table_[ACE_Name_Request::MAX_LIST];
/// Cache request from the client.
ACE_Name_Request name_request_;
/// Special kind of reply for resolve and listnames.
ACE_Name_Request name_request_back_;
/// Cache reply to the client.
ACE_Name_Reply name_reply_;
/// Address of client we are connected with.
ACE_INET_Addr addr_;
/// Naming Context
ACE_Naming_Context *naming_context_;
ACE_Naming_Context *naming_context ();
/// Handle binds.
int bind ();
/// Handle rebinds.
int rebind ();
/// Handle binds and rebinds.
int shared_bind (int rebind);
/// Handle find requests.
int resolve ();
/// Handle unbind requests.
int unbind ();
/// Handle LIST_NAMES, LIST_VALUES, and LIST_TYPES requests.
int lists ();
/// Handle LIST_NAME_ENTRIES, LIST_VALUE_ENTRIES, and
/// LIST_TYPE_ENTRIES requests.
int lists_entries ();
/// Create a name request.
ACE_Name_Request name_request (ACE_NS_WString *one_name);
/// Create a value request.
ACE_Name_Request value_request (ACE_NS_WString *one_name);
/// Create a type request.
ACE_Name_Request type_request (ACE_NS_WString *one_name);
};
/**
* @class ACE_Name_Acceptor
*
* @brief This class contains the service-specific methods that can't
* easily be factored into the .
*/
class ACE_Name_Acceptor : public ACE_Strategy_Acceptor
{
public:
/// Dynamic linking hook.
virtual int init (int argc, ACE_TCHAR *argv[]);
/// Parse svc.conf arguments.
int parse_args (int argc, ACE_TCHAR *argv[]);
/// Naming context for acceptor /for the listening port/
ACE_Naming_Context *naming_context ();
private:
/// The scheduling strategy is designed for Reactive services.
ACE_Schedule_All_Reactive_Strategy scheduling_strategy_;
/// The Naming Context
ACE_Naming_Context naming_context_;
};
ACE_SVC_FACTORY_DECLARE (ACE_Name_Acceptor)
#endif /* ACE_NAME_HANDLER_H */
ace-8.0.1+dfsg.orig/netsvcs/lib/TS_Server_Handler.h 0000644 0001750 0001750 00000005770 14653111173 021110 0 ustar sudip sudip /* -*- C++ -*- */
//=============================================================================
/**
* @file TS_Server_Handler.h
*
* @author Prashant Jain
*/
//=============================================================================
#ifndef ACE_TS_SERVER_HANDLER_H
#define ACE_TS_SERVER_HANDLER_H
#include "ace/Acceptor.h"
#if !defined (ACE_LACKS_PRAGMA_ONCE)
# pragma once
#endif /* ACE_LACKS_PRAGMA_ONCE */
#include "ace/SOCK_Acceptor.h"
#include "ace/Svc_Handler.h"
#include "ace/svc_export.h"
#include "Time_Request_Reply.h"
#if defined ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION_EXPORT
template class ACE_Svc_Export ACE_Svc_Handler;
#endif /* ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION_EXPORT */
/**
* @class ACE_TS_Server_Handler
*
* @brief Product object created by .
*/
class ACE_Svc_Export ACE_TS_Server_Handler : public ACE_Svc_Handler
{
public:
/// Default constructor.
ACE_TS_Server_Handler (ACE_Thread_Manager * = 0);
/// Activate this instance of the (called by the
/// ).
virtual int open (void * = 0);
protected:
/// Must be allocated dynamically.
~ACE_TS_Server_Handler ();
// = Helper routines for the operations exported to clients.
/// Give up waiting (e.g., when a timeout occurs or a client shuts
/// down unexpectedly).
virtual int abandon ();
// = Low level routines for framing requests, dispatching
// operations, and returning replies.
/// Receive, frame, and decode the client's request.
virtual int recv_request ();
/// Dispatch the appropriate operation to handle the client's
/// request.
virtual int dispatch ();
/// Special kind of reply
virtual int send_request (ACE_Time_Request &);
// = Demultiplexing hooks.
/// Return the underlying .
virtual ACE_HANDLE get_handle () const;
/// Callback method invoked by the when client events
/// arrive.
virtual int handle_input (ACE_HANDLE);
// = Timer hook.
/// Enable clients to limit the amount of time they wait.
virtual int handle_timeout (const ACE_Time_Value &tv, const void *arg);
private:
/// Cache request from the client.
ACE_Time_Request time_request_;
/// Address of client we are connected with.
ACE_INET_Addr addr_;
};
/**
* @class ACE_TS_Server_Acceptor
*
* @brief This class contains the service-specific methods that can't
* easily be factored into the .
*/
class ACE_TS_Server_Acceptor : public ACE_Strategy_Acceptor
{
public:
/// Dynamic linking hook.
virtual int init (int argc, ACE_TCHAR *argv[]);
/// Parse svc.conf arguments.
int parse_args (int argc, ACE_TCHAR *argv[]);
private:
/// The scheduling strategy is designed for Reactive services.
ACE_Schedule_All_Reactive_Strategy scheduling_strategy_;
};
ACE_SVC_FACTORY_DECLARE (ACE_TS_Server_Acceptor)
#endif /* ACE_TS_SERVER_HANDLER_H */
ace-8.0.1+dfsg.orig/netsvcs/lib/Time_Request_Reply.h 0000644 0001750 0001750 00000005661 14653111173 021357 0 ustar sudip sudip // -*- C++ -*-
//=============================================================================
/**
* @file Time_Request_Reply.h
*
* Define the format used to exchange messages between the
* ACE time server and clerks.
*
* @author Prashant Jain
*/
//=============================================================================
#ifndef ACE_TIME_REQUEST_REPLY_H
#define ACE_TIME_REQUEST_REPLY_H
#include /**/ "ace/pre.h"
#include "ace/Time_Value.h"
#include "ace/svc_export.h"
#if !defined (ACE_LACKS_PRAGMA_ONCE)
# pragma once
#endif /* ACE_LACKS_PRAGMA_ONCE */
/**
* @class ACE_Time_Request
*
* @brief Message format for delivering requests to the ACE_Time Server.
*
* This class is implemented to minimize data copying.
* In particular, all marshaling is done in situ...
*/
class ACE_Svc_Export ACE_Time_Request
{
public:
enum Constants
{
/// Request message types.
TIME_UPDATE = 01,
/// Class-specific constant values.
MAX_TIME_LEN = MAXPATHLEN + 1
};
/// Default constructor.
ACE_Time_Request ();
/**
* Create a ACE_Time_Request message.
* @param msg_type Type of request.
* @param time Time.
* @param timeout Max time waiting for request.
*/
ACE_Time_Request (ACE_INT32 msg_type,
const time_t time,
ACE_Time_Value *timeout = 0);
// Get the fixed size of message
ssize_t size () const;
/// Get the type of the message.
ACE_INT32 msg_type () const;
/// Set the type of the message.
void msg_type (ACE_INT32);
/// Get the time
time_t time () const;
// Set the time
void time (time_t t);
/// Get the blocking semantics.
ACE_UINT32 block_forever () const;
/// Set the blocking semantics.
void block_forever (ACE_UINT32);
/// Get the timeout.
ACE_Time_Value timeout () const;
/// Set the timeout.
void timeout (const ACE_Time_Value& timeout);
/// Encode the message before transmission.
int encode (void *&);
/// Decode message after reception.
int decode ();
/// Print out the values of the message for debugging purposes.
void dump () const;
private:
// = The 5 fields in the struct are transmitted to the server.
// The remaining 2 fields are not tranferred -- they are used only on
// the server-side to simplify lookups.
struct Transfer
{
/// Type of the request (i.e., )
ACE_INT32 msg_type_;
/// Indicates if we should block forever. If 0, then sec_timeout_
/// and usec_timeout_ indicates how long we should wait.
ACE_UINT32 block_forever_;
/// Max seconds willing to wait for name if not blocking forever.
ACE_UINT64 sec_timeout_;
/// Max micro seconds to wait for name if not blocking forever.
ACE_UINT32 usec_timeout_;
/// The data portion contains
ACE_UINT64 time_;
};
/// Transfer buffer.
Transfer transfer_;
/// Time
time_t time_;
};
#include /**/ "ace/post.h"
#endif /* ACE_TIME_REQUEST_REPLY_H */
ace-8.0.1+dfsg.orig/netsvcs/lib/TS_Clerk_Handler.cpp 0000644 0001750 0001750 00000045367 14653111173 021243 0 ustar sudip sudip #include "ace/Get_Opt.h"
#include "TS_Clerk_Handler.h"
#include "ace/Lib_Find.h"
#include "ace/Signal.h"
#include "ace/OS_NS_stdio.h"
#include "ace/OS_NS_string.h"
#include "ace/OS_NS_time.h"
#include "ace/os_include/os_netdb.h"
ACE_TS_Clerk_Handler::ACE_TS_Clerk_Handler (ACE_TS_Clerk_Processor *processor,
ACE_INET_Addr &addr)
: state_ (ACE_TS_Clerk_Handler::IDLE),
timeout_ (ACE_DEFAULT_TIMEOUT),
max_timeout_ (ACE_TS_Clerk_Handler::MAX_RETRY_TIMEOUT),
remote_addr_ (addr),
processor_ (processor)
{
ACE_TRACE ("ACE_TS_Clerk_Handler::ACE_TS_Clerk_Handler");
this->time_info_.delta_time_ = 0;
this->time_info_.sequence_num_ = 0;
}
// Set the connection state
void
ACE_TS_Clerk_Handler::state (ACE_TS_Clerk_Handler::State state)
{
ACE_TRACE ("ACE_TS_Clerk_Handler::state");
this->state_ = state;
}
// Get the connection state
ACE_TS_Clerk_Handler::State
ACE_TS_Clerk_Handler::state ()
{
ACE_TRACE ("ACE_TS_Clerk_Handler::state");
return this->state_;
}
// Sets the timeout delay.
void
ACE_TS_Clerk_Handler::timeout (long to)
{
ACE_TRACE ("ACE_TS_Clerk_Handler::timeout");
if (to > this->max_timeout_)
to = this->max_timeout_;
this->timeout_ = to;
}
// Recalculate the current retry timeout delay using exponential
// backoff. Returns the original timeout (i.e., before the
// recalculation).
long
ACE_TS_Clerk_Handler::timeout ()
{
ACE_TRACE ("ACE_TS_Clerk_Handler::timeout");
long old_timeout = this->timeout_;
this->timeout_ *= 2;
if (this->timeout_ > this->max_timeout_)
this->timeout_ = this->max_timeout_;
return old_timeout;
}
// This is called when a to the logging server fails...
int
ACE_TS_Clerk_Handler::handle_signal (int, siginfo_t *, ucontext_t *)
{
return -1;
}
// Set the max timeout delay.
void
ACE_TS_Clerk_Handler::max_timeout (long mto)
{
ACE_TRACE ("ACE_TS_Clerk_Handler::max_timeout");
this->max_timeout_ = mto;
}
// Gets the max timeout delay.
long
ACE_TS_Clerk_Handler::max_timeout ()
{
ACE_TRACE ("ACE_TS_Clerk_Handler::max_timeout");
return this->max_timeout_;
}
int
ACE_TS_Clerk_Handler::open (void *)
{
ACE_TRACE ("ACE_TS_Clerk_Handler::open");
ACE_INET_Addr server_addr;
// Set connection state as established
this->state (ACE_TS_Clerk_Handler::ESTABLISHED);
// Register ourselves to receive SIGPIPE so we can attempt
// reconnections.
#if !defined (ACE_WIN32)
if (ACE_Reactor::instance ()->register_handler (SIGPIPE, this) == -1)
ACE_ERROR_RETURN ((LM_ERROR, ACE_TEXT ("%n: %p\n"),
ACE_TEXT ("register_handler (SIGPIPE)")), -1);
#endif /* ACE_WIN32 */
// Register ourselves with the reactor to receive input
if (ACE_Reactor::instance ()->register_handler (this->get_handle (),
this,
ACE_Event_Handler::READ_MASK |
ACE_Event_Handler::EXCEPT_MASK) == -1)
ACE_ERROR ((LM_ERROR, ACE_TEXT ("%n: %p\n"),
ACE_TEXT ("register_handler (this)")));
// Figure out what remote port we're really bound to.
else if (this->peer ().get_remote_addr (server_addr) == -1)
ACE_ERROR_RETURN ((LM_ERROR, ACE_TEXT ("%p\n"),
ACE_TEXT ("get_remote_addr")),
-1);
ACE_DEBUG ((LM_DEBUG,
ACE_TEXT ("TS Clerk Daemon connected to port %d on handle %d\n"),
server_addr.get_port_number (),
this->peer ().get_handle ()));
return 0;
}
ACE_HANDLE
ACE_TS_Clerk_Handler::get_handle () const
{
ACE_TRACE ("ACE_TS_Clerk_Handler::get_handle");
return this->peer().get_handle ();
}
int
ACE_TS_Clerk_Handler::handle_close (ACE_HANDLE,
ACE_Reactor_Mask mask)
{
ACE_TRACE ("ACE_TS_Clerk_Handler::handle_close");
ACE_UNUSED_ARG (mask);
ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("(%t) shutting down on handle %d\n"),
this->get_handle ()));
return this->reinitiate_connection ();
}
int
ACE_TS_Clerk_Handler::reinitiate_connection ()
{
ACE_TRACE ("ACE_TS_Clerk_Handler::reinitiate_connection");
// Skip over deactivated descriptors.
// Set state to connecting so that we don't try to send anything
// using this handler
this->state (ACE_TS_Clerk_Handler::CONNECTING);
if (this->get_handle () != ACE_INVALID_HANDLE)
{
ACE_DEBUG ((LM_DEBUG,
ACE_TEXT ("(%t) Scheduling reinitiation of connection\n")));
// Reschedule ourselves to try and connect again.
ACE_Time_Value const timeout (this->timeout ());
if (ACE_Reactor::instance ()->schedule_timer (this, 0,
timeout) == -1)
ACE_ERROR_RETURN ((LM_ERROR, ACE_TEXT ("(%t) %p\n"),
ACE_TEXT ("schedule_timer")), -1);
}
return 0;
}
// Receive a time update from a server
int
ACE_TS_Clerk_Handler::handle_input (ACE_HANDLE)
{
ACE_TRACE ("ACE_TS_Clerk_Handler::handle_input");
// We're getting a time update message from a server
ACE_Time_Request reply;
if (this->recv_reply (reply) != 0)
return -1;
else
{
// Get current local time
time_t local_time = ACE_OS::time (0);
// Compure delta time (difference between current local time and
// system time obtained from the server)
time_t t = reply.time () - local_time;
// Compute round trip delay and adjust time accordingly
time_t one_way_time = (local_time - this->start_time_)/2;
t += one_way_time;
// Now update time info (to be retrieved by Clerk_Processor)
this->time_info_.delta_time_ = t;
this->time_info_.sequence_num_ = this->cur_sequence_num_;
}
return 0;
}
// Restart connection asynchronously when timeout occurs.
int
ACE_TS_Clerk_Handler::handle_timeout (const ACE_Time_Value &,
const void *)
{
ACE_TRACE ("ACE_TS_Clerk_Handler::handle_timeout");
ACE_DEBUG ((LM_DEBUG,
ACE_TEXT ("(%t) attempting to reconnect to server with timeout = %d\n"),
this->timeout_));
// Close down peer to reclaim descriptor if need be. Note this is
// necessary to reconnect.
this->peer ().close ();
return this->processor_->initiate_connection (this, ACE_Synch_Options::asynch);
}
void
ACE_TS_Clerk_Handler::remote_addr (ACE_INET_Addr &addr)
{
ACE_TRACE ("ACE_TS_Clerk_Handler::remote_addr");
this->remote_addr_ = addr;
}
ACE_INET_Addr &
ACE_TS_Clerk_Handler::remote_addr ()
{
ACE_TRACE ("ACE_TS_Clerk_Handler::remote_addr");
return this->remote_addr_;
}
int
ACE_TS_Clerk_Handler::recv_reply (ACE_Time_Request &reply)
{
ACE_TRACE ("ACE_TS_Clerk_Handler::recv_reply");
const int bytes_expected = reply.size ();
// Since Time_Request messages are fixed size, read the entire
// message in one go.
ssize_t n = this->peer ().recv ((void *) &reply, bytes_expected);
if (n != bytes_expected)
{
switch (n)
{
case -1:
ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("****************** recv_reply returned -1\n")));
ACE_FALLTHROUGH;
default:
ACE_ERROR ((LM_ERROR, ACE_TEXT ("%p got %d bytes, expected %d bytes\n"),
ACE_TEXT ("recv failed"), n, bytes_expected));
ACE_FALLTHROUGH;
case 0:
// We've shutdown unexpectedly
return -1;
// NOTREACHED
}
}
else if (reply.decode () == -1) // Decode the request into host byte order.
ACE_ERROR_RETURN ((LM_ERROR, ACE_TEXT ("%p\n"),
ACE_TEXT ("decode failed")), -1);
return 0;
}
int
ACE_TS_Clerk_Handler::send_request (ACE_UINT32 sequence_num, ACE_Time_Info &time_info)
{
ACE_TRACE ("ACE_TS_Clerk_Handler::send_request");
void *buffer;
ssize_t length;
// Update current sequence number
this->cur_sequence_num_ = sequence_num;
// First update the current time info.
time_info.delta_time_ = this->time_info_.delta_time_;
time_info.sequence_num_ = this->time_info_.sequence_num_;
// Now prepare a new time update request
ACE_Time_Request request (ACE_Time_Request::TIME_UPDATE, 0, 0);
if ((length = request.encode (buffer)) == -1)
ACE_ERROR_RETURN ((LM_ERROR, ACE_TEXT ("%p\n"),
ACE_TEXT ("encode failed")), -1);
// Compute start time of sending request (needed to compute
// roundtrip delay)
this->start_time_ = ACE_OS::time (0);
// Send the request
if (this->peer ().send_n (buffer, length) != length)
ACE_ERROR_RETURN ((LM_ERROR, ACE_TEXT ("%p\n"),
ACE_TEXT ("send_n failed")),
-1);
return 0;
}
ACE_TS_Clerk_Processor::ACE_TS_Clerk_Processor ()
: timeout_ (ACE_DEFAULT_TIMEOUT),
blocking_semantics_ (0),
cur_sequence_num_ (0)
{
#if defined (ACE_DEFAULT_BACKING_STORE)
// Create a temporary file.
ACE_OS::strcpy (this->poolname_,
ACE_DEFAULT_BACKING_STORE);
#else /* ACE_DEFAULT_BACKING_STORE */
if (ACE::get_temp_dir (this->poolname_,
MAXPATHLEN - 17) == -1) // -17 for ace-malloc-XXXXXX
{
ACE_ERROR ((LM_ERROR,
ACE_TEXT ("Temporary path too long, ")
ACE_TEXT ("defaulting to current directory\n")));
this->poolname_[0] = 0;
}
// Add the filename to the end
ACE_OS::strcat (this->poolname_, ACE_TEXT ("ace-malloc-XXXXXX"));
#endif /* ACE_DEFAULT_BACKING_STORE */
}
void
ACE_TS_Clerk_Processor::alloc ()
{
ACE_TRACE ("ACE_TS_Clerk_Processor::alloc");
ACE_NEW (this->shmem_, ALLOCATOR (this->poolname_));
void *temp = 0;
// Only create the state if it doesn't already exist.
if (this->shmem_->find (ACE_DEFAULT_TIME_SERVER_STR, temp) == -1)
{
// Allocate the space out of shared memory for the system time entry
temp = (this->shmem_->malloc (2 * sizeof (time_t)));
// Give it a name binding
this->shmem_->bind (ACE_DEFAULT_TIME_SERVER_STR, temp);
}
// Set up pointers. Note that we add one to get to the second
// field in the structure
time_t *time_p = (time_t *)temp;
this->system_time_.delta_time_ = time_p;
this->system_time_.last_local_time_ = time_p + 1;
// Initialize
*(this->system_time_.delta_time_) = 0;
*(this->system_time_.last_local_time_) = ACE_OS::time (0);
}
// Query the servers for the latest time
int
ACE_TS_Clerk_Processor::handle_timeout (const ACE_Time_Value &,
const void *)
{
ACE_TRACE ("ACE_TS_Clerk_Processor::handle_timeout");
return this->update_time ();
}
int
ACE_TS_Clerk_Processor::update_time ()
{
ACE_TRACE ("ACE_TS_Clerk_Processor::update_time");
ACE_UINT32 expected_sequence_num = this->cur_sequence_num_;
// Increment sequence number
this->cur_sequence_num_++;
int count = 0;
time_t total_delta = 0;
ACE_Time_Info time_info;
// Call send_request() on all handlers
ACE_TS_Clerk_Handler **handler = 0;
for (HANDLER_SET_ITERATOR set_iterator (this->handler_set_);
set_iterator.next (handler) != 0;
set_iterator.advance ())
{
if ((*handler)->state () == ACE_TS_Clerk_Handler::ESTABLISHED)
{
if ((*handler)->send_request (this->cur_sequence_num_, time_info) == -1)
return -1;
// Check if sequence numbers match; otherwise discard
else if (expected_sequence_num != 0 &&
time_info.sequence_num_ == expected_sequence_num)
{
count++;
ACE_DEBUG ((LM_DEBUG,
ACE_TEXT ("[%d] Delta time: %d\n"),
count, time_info.delta_time_));
// #### Can check here if delta value falls within a threshold ####
total_delta += time_info.delta_time_;
}
}
}
// Update system_time_ using average of times obtained from all the servers.
// Note that we are keeping two things in shared memory: the delta
// time (difference between our system clock and the local clock),
// and the last local time
if (count > 0)
{
// At least one server is out there
*(this->system_time_.delta_time_) = total_delta/count;
}
else
{
// No servers are out there (or this is the first time around
// computing the time) so set delta time to zero. This
// would mean that clients would use the actual local system time.
*(this->system_time_.delta_time_) = 0;
}
// Update the last local time
*(this->system_time_.last_local_time_) = ACE_OS::time (0);
ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("Average delta time: %d\n"),
(int)(*(this->system_time_.delta_time_))));
return 0;
}
int
ACE_TS_Clerk_Processor::fini ()
{
ACE_TRACE ("ACE_TS_Clerk_Processor::fini");
// Cancel the timer
if (this->timer_id_ != -1)
ACE_Reactor::instance ()->cancel_timer (this->timer_id_);
// Destroy all the handlers
ACE_TS_Clerk_Handler **handler = 0;
for (HANDLER_SET_ITERATOR set_iterator (this->handler_set_);
set_iterator.next (handler) != 0;
set_iterator.advance ())
{
if ((*handler)->state () != ACE_TS_Clerk_Handler::IDLE)
// Mark state as DISCONNECTING so we don't try to reconnect...
(*handler)->state (ACE_TS_Clerk_Handler::DISCONNECTING);
// Deallocate resources.
(*handler)->destroy (); // Will trigger a delete
}
// Remove the backing store
this->shmem_->remove ();
ACE_Connector ::fini ();
return 0;
}
int
ACE_TS_Clerk_Processor::info (ACE_TCHAR **, size_t) const
{
ACE_TRACE ("ACE_TS_Clerk_Processor::info");
return 0;
}
int
ACE_TS_Clerk_Processor::init (int argc, ACE_TCHAR *argv[])
{
ACE_TRACE ("ACE_TS_Clerk_Processor::init");
// Use the options hook to parse the command line arguments and set
// options.
this->parse_args (argc, argv);
this->alloc ();
#if !defined (ACE_WIN32)
// Ignore SIPPIPE so each Output_Channel can handle it.
ACE_Sig_Action sig ((ACE_SignalHandler) SIG_IGN, SIGPIPE);
ACE_UNUSED_ARG (sig);
#endif /* ACE_WIN32 */
ACE_Synch_Options &synch_options = this->blocking_semantics_ == 0
? ACE_Synch_Options::asynch : ACE_Synch_Options::synch;
// Now set up connections to all servers
ACE_TS_Clerk_Handler **handler = 0;
for (HANDLER_SET_ITERATOR set_iterator (this->handler_set_);
set_iterator.next (handler) != 0;
set_iterator.advance ())
{
this->initiate_connection (*handler, synch_options);
}
// Now set up timer to receive updates from server
// set the timer to go off after timeout value
this->timer_id_ = ACE_Reactor::instance ()->schedule_timer (this,
0,
ACE_Time_Value (this->timeout_),
ACE_Time_Value (this->timeout_));
return 0;
}
int
ACE_TS_Clerk_Processor::initiate_connection (ACE_TS_Clerk_Handler *handler,
ACE_Synch_Options &synch_options)
{
ACE_TRACE ("ACE_TS_Clerk_Processor::initiate_connection");
ACE_TCHAR buf[MAXHOSTNAMELEN + 1];
// Mark ourselves as idle so that the various iterators will ignore
// us until we are connected/reconnected.
handler->state (ACE_TS_Clerk_Handler::IDLE);
if (handler->remote_addr ().addr_to_string (buf, MAXHOSTNAMELEN) == -1)
ACE_ERROR_RETURN ((LM_ERROR, ACE_TEXT ("(%t) %p\n"),
ACE_TEXT ("can't obtain peer's address")), -1);
// Establish connection with the server.
if (this->connect (handler,
handler->remote_addr (),
synch_options) == -1)
{
if (errno != EWOULDBLOCK)
{
handler->state (ACE_TS_Clerk_Handler::FAILED);
ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("(%t) %p on address %s\n"),
ACE_TEXT ("connect"), buf));
// Reschedule ourselves to try and connect again.
if (synch_options[ACE_Synch_Options::USE_REACTOR])
{
ACE_Time_Value const handler_timeout (handler->timeout ());
if (ACE_Reactor::instance ()->schedule_timer (handler,
0,
handler_timeout) == -1)
ACE_ERROR_RETURN ((LM_ERROR, ACE_TEXT ("(%t) %p\n"),
ACE_TEXT ("schedule_timer")), -1);
}
else
// Failures on synchronous connects are reported as errors
// so that the caller can decide how to proceed.
return -1;
}
else
{
handler->state (ACE_TS_Clerk_Handler::CONNECTING);
ACE_DEBUG ((LM_DEBUG,
ACE_TEXT ("(%t) in the process of connecting %s to %s\n"),
synch_options[ACE_Synch_Options::USE_REACTOR] ?
ACE_TEXT ("asynchronously") : ACE_TEXT ("synchronously"),
buf));
}
}
else
{
handler->state (ACE_TS_Clerk_Handler::ESTABLISHED);
ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("(%t) connected to %s on %d\n"),
buf, handler->get_handle ()));
}
return 0;
}
int
ACE_TS_Clerk_Processor::parse_args (int argc, ACE_TCHAR *argv[])
{
ACE_TRACE ("ACE_TS_Clerk_Processor::parse_args");
ACE_INET_Addr server_addr;
ACE_TS_Clerk_Handler *handler;
ACE_Get_Opt get_opt (argc, argv, ACE_TEXT ("h:t:p:b"), 0);
for (int c; (c = get_opt ()) != -1; )
{
switch (c)
{
case 'h':
// Get the hostname:port and create an ADDR
server_addr.set (get_opt.opt_arg ());
// Create a new handler
ACE_NEW_RETURN (handler,
ACE_TS_Clerk_Handler (this, server_addr),
-1);
// Cache the handler
this->handler_set_.insert (handler);
break;
case 't':
// Get the timeout value
this->timeout_ = ACE_OS::atoi (get_opt.opt_arg ());
break;
case 'p':
// Get the poolname
ACE_OS::strncpy (this->poolname_,
get_opt.opt_arg (),
sizeof this->poolname_ / sizeof (ACE_TCHAR));
break;
case 'b':
// Blocking semantics
this->blocking_semantics_ = 1;
break;
default:
ACE_ERROR_RETURN ((LM_ERROR,
ACE_TEXT ("%n:\n[-h hostname:port] [-t timeout] [-p poolname]\n")),
-1);
}
}
return 0;
}
int
ACE_TS_Clerk_Processor::suspend ()
{
ACE_TRACE ("ACE_TS_Clerk_Processor::suspend");
return 0;
}
int
ACE_TS_Clerk_Processor::resume ()
{
ACE_TRACE ("ACE_TS_Clerk_Processor::resume");
return 0;
}
// The following is a "Factory" used by the ACE_Service_Config and
// svc.conf file to dynamically initialize the state of the TS_Clerk.
ACE_SVC_FACTORY_DEFINE (ACE_TS_Clerk_Processor)
ace-8.0.1+dfsg.orig/netsvcs/lib/Server_Logging_Handler_T.cpp 0000644 0001750 0001750 00000035542 14653111173 022766 0 ustar sudip sudip #ifndef ACE_SERVER_LOGGING_HANDLERT_C
#define ACE_SERVER_LOGGING_HANDLERT_C
#include "ace/config-all.h"
#include
#include "ace/Get_Opt.h"
#include "ace/Log_Record.h"
#include "ace/CDR_Stream.h"
#include "Server_Logging_Handler_T.h"
#include "ace/Signal.h"
// Track number of requests.
template
COUNTER ACE_Server_Logging_Handler_T::request_count_ = (COUNTER) 0;
template
ACE_Server_Logging_Handler_T::ACE_Server_Logging_Handler_T
(ACE_Thread_Manager *,
LMR const &receiver)
// Initialize the CString to something that is not the empty string
// to avoid problems when calling fast_rep()
#if !defined (__GNUG__)
: receiver_ (receiver, ACE_TString (ACE_TEXT(" "), 1))
#else
: receiver_ (receiver),
host_name_ (ACE_TString (ACE_TEXT (" "), 1))
#endif /* ! __GNUG__ */
{
}
// Callback routine for handling the reception of remote logging
// transmissions.
template int
ACE_Server_Logging_Handler_T::handle_input (ACE_HANDLE)
{
int result = this->handle_logging_record ();
return result >= 0 ? 0 : -1;
}
template const ACE_TCHAR *
ACE_Server_Logging_Handler_T::host_name ()
{
#if !defined (__GNUG__)
return this->receiver_.m_.fast_rep ();
#else
return this->host_name_.fast_rep ();
#endif /* ! __GNUG__ */
}
template int
ACE_Server_Logging_Handler_T::handle_logging_record ()
{
ACE_Log_Record log_record;
// We need to use the old two-read trick here since TCP sockets
// don't support framing natively. Allocate a message block for the
// payload; initially at least large enough to hold the header, but
// needs some room for alignment.
ACE_Message_Block *payload_p = 0;
ACE_Message_Block *header_p = 0;
ACE_NEW_RETURN (header_p,
ACE_Message_Block (ACE_DEFAULT_CDR_BUFSIZE),
-1);
std::unique_ptr header (header_p);
// Align the Message Block for a CDR stream
ACE_CDR::mb_align (header.get ());
ACE_CDR::Boolean byte_order;
ACE_CDR::ULong length;
ssize_t count = ACE::recv_n (this->peer ().get_handle (),
header->wr_ptr (),
8);
switch (count)
{
// Handle shutdown and error cases.
default:
case -1:
case 0:
ACE_DEBUG ((LM_DEBUG,
ACE_TEXT ("server logging daemon closing down at host %s\n"),
this->host_name ()));
return -1;
/* NOTREACHED */
case 8:
// Just fall through in this case..
break;
}
header->wr_ptr (8); // Reflect addition of 8 bytes.
// Create a CDR stream to parse the 8-byte header.
ACE_InputCDR header_cdr (header.get ());
// Extract the byte-order and use helper methods to disambiguate
// octet, booleans, and chars.
if (!(header_cdr >> ACE_InputCDR::to_boolean (byte_order)))
{
ACE_ERROR ((LM_ERROR,
ACE_TEXT ("Can't extract byte_order\n")));
return 0;
}
// Set the byte-order on the stream...
header_cdr.reset_byte_order (byte_order);
// Extract the length
if (!(header_cdr >> length))
{
ACE_ERROR ((LM_ERROR,
ACE_TEXT ("Can't extract length\n")));
return 0;
}
ACE_NEW_RETURN (payload_p,
ACE_Message_Block (length),
-1);
std::unique_ptr payload (payload_p);
// Ensure there's sufficient room for log record payload.
ACE_CDR::grow (payload.get (), 8 + ACE_CDR::MAX_ALIGNMENT + length);
// Use to obtain the contents.
if (ACE::recv_n (this->peer ().get_handle (),
payload->wr_ptr (),
length) <= 0)
{
ACE_ERROR ((LM_ERROR,
ACE_TEXT ("%p\n"),
ACE_TEXT ("recv_n()")));
return -1;
}
payload->wr_ptr (length); // Reflect additional bytes
ACE_InputCDR payload_cdr (payload.get ());
payload_cdr.reset_byte_order (byte_order);
if (!(payload_cdr >> log_record)) // Finally extract the .
{
ACE_ERROR ((LM_ERROR,
ACE_TEXT ("Can't extract log_record\n")));
return 0;
}
log_record.length (length);
// Send the log record to the log message receiver for processing.
if (ACE_BIT_ENABLED (ACE_Log_Msg::instance ()->flags (), ACE_Log_Msg::STDERR))
receiver ().log_record (this->host_name (), log_record);
ostream *orig_ostream = ACE_Log_Msg::instance ()->msg_ostream ();
receiver ().log_output (this->host_name (),
log_record,
orig_ostream);
return 0;
#if 0
ACE_INT32 length;
// We need to use the ol' two-read trick here since TCP sockets
// don't support framing natively. Note that the first call is just
// a "peek" -- we don't actually remove the data until the second
// call. Note that this code is portable as long as ACE_UNIT32 is
// always 32 bits on both the sender and receiver side.
switch (this->peer ().recv ((void *) &length,
sizeof length,
MSG_PEEK))
{
default:
case -1:
ACE_ERROR_RETURN ((LM_ERROR,
ACE_TEXT ("%p at host %s\n"),
ACE_TEXT ("server logger"),
this->host_name ()),
-1);
/* NOTREACHED */
case 0:
ACE_ERROR_RETURN ((LM_ERROR,
ACE_TEXT ("closing log daemon at host %C\n"),
this->host_name ()),
-1);
/* NOTREACHED */
case sizeof length:
{
ACE_Log_Record lp;
// Use ACE_NTOHL to get around bug in egcs 2.91.6x.
length = ACE_NTOHL (length);
++this->request_count_;
u_long count = this->request_count_;
ACE_DEBUG ((LM_DEBUG,
ACE_TEXT ("request count = %d, length = %d\n"),
count,
length));
// Perform the actual this time.
ssize_t n = this->peer ().recv_n ((void *) &lp,
length);
if (n != length)
ACE_ERROR_RETURN ((LM_ERROR,
ACE_TEXT ("%d != %d, %p at host %C\n"),
n,
length,
ACE_TEXT ("server logger"),
this->host_name ()),
-1);
lp.decode ();
if (lp.length () == n)
{
// Send the log record to the log message receiver for
// processing.
if (ACE_BIT_ENABLED (ACE_Log_Msg::instance ()->flags (),
ACE_Log_Msg::STDERR))
receiver ().log_record (this->host_name (),
lp);
ostream *orig_ostream = ACE_Log_Msg::instance ()->msg_ostream ();
receiver ().log_output (this->host_name (),
lp,
orig_ostream);
}
else
ACERROR ((LM_ERROR,
ACE_TEXT ("error, lp.length = %d, n = %d\n"),
lp.length (),
n));
return n;
}
}
#endif
ACE_NOTREACHED (return -1;)
}
// Hook called by Server_Logging_Acceptor when connection is
// established.
template int
ACE_Server_Logging_Handler_T::open_common ()
{
// Shut off non-blocking IO if it was enabled...
if (this->peer ().disable (ACE_NONBLOCK) == -1)
ACE_ERROR_RETURN ((LM_ERROR,
ACE_TEXT ("%p\n"),
ACE_TEXT ("disable")),
-1);
ACE_PEER_STREAM_ADDR client_addr;
// Determine the address of the client and display it.
if (this->peer ().get_remote_addr (client_addr) == -1)
ACE_ERROR_RETURN ((LM_ERROR,
ACE_TEXT ("%p\n"),
ACE_TEXT ("get_remote_addr")),
-1);
#if !defined (__GNUG__)
this->receiver_.m_ =
ACE_TString (ACE_TEXT_CHAR_TO_TCHAR (client_addr.get_host_name ()));
#else
this->host_name_ =
ACE_TString (ACE_TEXT_CHAR_TO_TCHAR (client_addr.get_host_name ()));
#endif /* ! __GNUG__ */
ACE_DEBUG ((LM_DEBUG,
ACE_TEXT ("(%t) accepted connection from host %C on fd %d\n"),
client_addr.get_host_name (),
this->peer ().get_handle ()));
return 0;
}
template
ACE_Server_Logging_Acceptor_T::ACE_Server_Logging_Acceptor_T ()
{
}
template LMR &
ACE_Server_Logging_Acceptor_T::receiver ()
{
return receiver_;
}
template SST &
ACE_Server_Logging_Acceptor_T::scheduling_strategy ()
{
#if !defined (__GNUG__)
return receiver_.m_;
#else
return schedule_strategy_;
#endif /* ! __GNUG__ */
}
template int
ACE_Server_Logging_Acceptor_T::init (int argc, ACE_TCHAR *argv[])
{
ACE_TRACE ("ACE_Server_Logging_Acceptor_T::init");
// Use the options hook to parse the command line arguments and set
// options.
this->parse_args (argc, argv);
// Set the acceptor endpoint into listen mode (use the Singleton
// global Reactor...).
if (this->open (this->service_addr_,
ACE_Reactor::instance (),
0, 0, 0,
&this->scheduling_strategy(),
ACE_TEXT ("Logging Server"),
ACE_TEXT ("ACE logging service")) == -1)
ACE_ERROR_RETURN ((LM_ERROR,
ACE_TEXT ("%n: %p on port %d\n"),
ACE_TEXT ("acceptor::open failed"),
this->service_addr_.get_port_number ()),
-1);
// Ignore SIGPIPE so that each can handle this on its
// own.
ACE_Sig_Action sig ((ACE_SignalHandler) SIG_IGN, SIGPIPE);
ACE_UNUSED_ARG (sig);
ACE_INET_Addr server_addr;
// Figure out what port we're really bound to.
if (this->acceptor ().get_local_addr (server_addr) == -1)
ACE_ERROR_RETURN ((LM_ERROR,
ACE_TEXT ("%p\n"),
ACE_TEXT ("get_local_addr")),
-1);
ACE_DEBUG ((LM_DEBUG,
ACE_TEXT ("starting up Logging Server at port %d on handle %d\n"),
server_addr.get_port_number (),
this->acceptor ().get_handle ()));
return 0;
}
template int
ACE_Server_Logging_Acceptor_T::parse_args (int argc, ACE_TCHAR *argv[])
{
ACE_TRACE ("ACE_Server_Logging_Acceptor_T::parse_args");
int service_port = ACE_DEFAULT_SERVER_PORT;
ACE_LOG_MSG->open (ACE_TEXT ("Logging Service"), ACE_LOG_MSG->flags ());
ACE_Get_Opt get_opt (argc, argv, ACE_TEXT ("p:"), 0);
for (int c; (c = get_opt ()) != -1; )
{
switch (c)
{
case 'p':
service_port = ACE_OS::atoi (get_opt.opt_arg ());
break;
default:
ACE_ERROR_RETURN ((LM_ERROR,
ACE_TEXT ("%n:\n[-p server-port]\n")),
-1);
}
}
this->service_addr_.set (service_port);
return 0;
}
template int
ACE_Server_Logging_Acceptor_T
::make_svc_handler (SERVER_LOGGING_HANDLER *&handler)
{
ACE_NEW_RETURN (handler,
SERVER_LOGGING_HANDLER (ACE_Thread_Manager::instance (),
this->receiver()),
-1);
return 0;
}
template
ACE_Server_Logging_Handler::ACE_Server_Logging_Handler (ACE_Thread_Manager * tm,
LOG_MESSAGE_RECEIVER const& receiver)
: ACE_Server_Logging_Handler_T(tm,
receiver)
{
}
template
ACE_Server_Logging_Handler::ACE_Server_Logging_Handler(ACE_Thread_Manager * tm)
: ACE_Server_Logging_Handler_T(tm, LOG_MESSAGE_RECEIVER())
{
}
template int
ACE_Server_Logging_Handler::open (void *)
{
// call base class open_common
if (this->open_common () != 0)
return -1;
// Register ourselves with the Reactor to enable subsequent
// dispatching.
if (ACE_Reactor::instance ()->register_handler
(this, ACE_Event_Handler::READ_MASK) == -1)
return -1;
return 0;
}
template
ACE_Thr_Server_Logging_Handler::ACE_Thr_Server_Logging_Handler (ACE_Thread_Manager *tm, LOG_MESSAGE_RECEIVER const &receiver)
: ACE_Server_Logging_Handler_T(tm, receiver)
{
}
template
ACE_Thr_Server_Logging_Handler::ACE_Thr_Server_Logging_Handler (ACE_Thread_Manager *tm)
: ACE_Server_Logging_Handler_T(tm, LOG_MESSAGE_RECEIVER ())
{
}
template int
ACE_Thr_Server_Logging_Handler::open (void *)
{
// call base class open_common
if (this->open_common () != 0)
return -1;
// Spawn a new thread of control to handle logging records with the
// client using a thread-per-connection concurrency model. Note
// that this implicitly uses the to
// control all the threads.
if (this->activate (THR_BOUND | THR_DETACHED) == -1)
ACE_ERROR_RETURN ((LM_ERROR,
ACE_TEXT ("%p\n"),
ACE_TEXT ("spawn")),
-1);
return 0;
}
// Process remote logging records.
template int
ACE_Thr_Server_Logging_Handler::svc ()
{
int result = 0;
// Loop until the client terminates the connection or an error occurs.
while ((result = this->handle_input ()) == 0)
continue;
return result;
}
#endif /* ACE_SERVER_LOGGING_HANDLER_TT_C */
ace-8.0.1+dfsg.orig/netsvcs/lib/README 0000644 0001750 0001750 00000023337 14653111173 016305 0 ustar sudip sudip
This directory provides a number of network services that utilize the
ACE wrapper features.
. Logging_Strategy -- Controls the output of all services that are
invoked along with the Logging_Strategy service. Please see below for
details on how to control the output.
. [Thr_]Server_Logging_Handler.* -- Implements server portion
of the ACE distributed logging service. Both multi-threaded
and single-threaded implementations are provided.
. Client_Logging_Handler.* -- Implements the client portion
of the ACE distributed logging service.
. Name_Handler.* -- Implements a distributed name service that
allows applications to bind, find, and unbind names in
a distributed system.
. Token_Handler.* -- Implements a distributed token
service that allows applications to acquire and release
locks in a distributed system.
. Time_Handler.* -- Implements a distributed time service that
allows distributed applications to synchronize their
time.
The remainder of this README file explains how these services work.
==================== Logging_Strategy Service ====================
The Logging_Strategy Service can be used to control the output of all the
network services. It can be invoked with certain flags that determine
where the output of all the services should go.
The Logging_Strategy Service sets the flags in ACE_Log_Msg which in turn
controls all the streams through macros such as ACE_DEBUG, ACE_ERROR,
and ACE_ERROR_RETURN.
If default behavior is required, the Logging_Strategy Service need not be
invoked or it can be invoked with no paramaters. Here are the command
line arguments that can be given to the Logging_Strategy Service:
-f ||