diff options
author | levine <levine@ae88bc3d-4319-0410-8dbf-d08b4c9d3795> | 1996-10-21 21:41:34 +0000 |
---|---|---|
committer | levine <levine@ae88bc3d-4319-0410-8dbf-d08b4c9d3795> | 1996-10-21 21:41:34 +0000 |
commit | a5fdebc5f6375078ec1763850a4ca23ec7fe6458 (patch) | |
tree | bcf0a25c3d45a209a6e3ac37b233a4812f29c732 /netsvcs | |
download | ATCD-a5fdebc5f6375078ec1763850a4ca23ec7fe6458.tar.gz |
Initial revision
Diffstat (limited to 'netsvcs')
74 files changed, 11885 insertions, 0 deletions
diff --git a/netsvcs/ACE-netsvcs.html b/netsvcs/ACE-netsvcs.html new file mode 100644 index 00000000000..1fef080dc3e --- /dev/null +++ b/netsvcs/ACE-netsvcs.html @@ -0,0 +1,895 @@ +<HTML> + +<HEAD> +<TITLE>Overview of the ACE Network Services</TITLE> + +<BODY text = "#000000" +link="#000fff" +vlink="#ff0f0f" +bgcolor="#ffffff"> + +<HR> +<H3>Overview of the ACE Network Services</H3> + +ACE provides a <A +HREF="http://www.cs.wustl.edu/~schmidt/ACE_wrappers/netsvcs/"> +standard library</A> of <A HREF="#service-overviews">network +services</A>:<P> + +<TABLE> +<TD> +<UL> +<LI><A HREF="#name-overview">Naming Service</A> +<LI><A HREF="#time-overview">Time Service</A> +<LI><A HREF="#token-overview">Token Service</A> +</UL> +</TD> + +<TD> +<UL> +<LI><A HREF="#server-logging-overview">Server Logging Service</A> +<LI><A HREF="#client-logging-overview">Client Logging Service</A> +<LI><A HREF="#logging-strategy-overview">Logging Strategy Service</A> +</UL> +</TD> +</TABLE> + +These services play two roles in ACE:<P> + +<UL> +<LI> They provide reusable components for common distributed system + tasks such as logging, naming, locking, and time synchronization.<P> +<LI> They illustrate how to utilize ACE features such as the <A + HREF="ACE-papers.html#ipc">IPC wrappers</A>, <A HREF="ACE-papers.html#reactor">Reactor</A>, + <A HREF="ACE-papers.html#config">Service Configurator</A>, <A + HREF="ACE-papers.html#initialize">Service Initialization</A>, and <A HREF="ACE-papers.html#concurrency">Concurrency</A> components. <P> +</UL> + +The heart of the ACE network services is the <A +HREF="http://www.cs.wustl.edu/~schmidt/ACE-papers#config">Service +Configurator</A>, which is an object-oriented framework that automates +the configuration and reconfiguration of multi-service daemons. All +the ACE network services are configured using the Service +Configurator. Please refer to the <A +HREF="NETSVC-INSTALL.html">online documentation</a> for more +information on installing and testing the ACE network services.<P> + +<P><HR> +<A NAME="name-overview"> +<H3> Overview of Naming Service</H3> + +A Naming Service associates names with values in a distributed +system. Clients can query these values using these names as keys. Such +a name-to-value association is called a <I> Name Binding </I>. Name +bindings are defined relative to a <I> Naming Context </I>. A naming +context is a collection that contains a set of name bindings in which +each name is unique. Different names can be bound to the same value in +the same or different naming contexts at the same time. There are +three types of naming contexts: <P> + +<OL> +<LI> Process Local Naming Context: Name bindings are accessible from +processes with the same name running on the same host. <P> +<LI> Node Local Naming Context: Name bindings are accessible from all +processes running on the same host. <P> +<LI> Network Local Naming Context: Name bindings are accessible from +all processes running on any machine within a (sub)network. <P> +</OL> + +<P> +To bind a name is to create a name binding in a given context. +Querying a value using a name determines the value associated with the +name in a given context. Note that a name is always bound relative to +a context. Thus, there are no absolute names. <P> + +The following are the key classes in the ACE Naming Service: <P> + +<UL> +<LI> <B><TT> Class Naming_Context </TT></B> <P> + +This is the main class ``entry point'' into the Naming Service. It is +used both by client processes and by server process. It manages access +to the appropriate Name/Binding database (that is the file where +Name/Bindings are stored) and it also manages the communication +between a client process and the server (by using class Name_Proxy, +which is a private member of Naming_Context). If a client process +runs on the same host as the server no IPC is necessary because the +Naming_Context uses shared memory. <P> + +<LI> <B><TT> Class Name_Acceptor </TT></B> <P> + +The Name_Acceptor allocates in its handle_input() routine a new +instance of class Name_Handler on the heap, and accepts connections +into this Name_Handler. <P> + +<LI> <B><TT> Class Name_Handler </TT></B> <P> + +The class Name_Handler represents the server side of communication +between client and server. It interprets incoming requests to the +Net_Local namespace and delegates the requests to its own +Naming_Context (which is the Net_Local namespace on the current +host). For communication it uses the helper classes Name_Request and +Name_Reply.<P> + +<LI> <B> Dependencies </B> <P> + +The ACE Naming Service uses ACE_WString String classes since it must +handle wide character strings in order to support +internationalization. <P> +</UL> + +The following describes how to configure the Name_Server server and +client test applications. <P> + +<UL> +<LI> <B> Startup configuration </B> <P> +Configuring a Name_Server server or client requires specifying all or +some of the following parameters. These parameters can be passed in to +main through command line as follows:<P> + +<TABLE cellpadding = 10 cellspacing = 0 border = 5> +<TD VALIGN = TOP ALIGN = LEFT> +<B> Option </B> +</TD> +<TD VALIGN = TOP ALIGN = LEFT> +<B> Description </B> +</TD> +<TD VALIGN = TOP ALIGN = LEFT> +<B> Default value </B> +</TD> +<TR> +<TD VALIGN = TOP ALIGN = LEFT> +-c <naming context> <BR> +</TD> +<TD VALIGN = TOP ALIGN = LEFT> +Naming Context to use. Can be either "PROC_LOCAL" or "NODE_LOCAL" or +"NET_LOCAL" <BR> +</TD> +<TD VALIGN = TOP ALIGN = LEFT> +PROC_LOCAL +</TD> +<TR> +<TD VALIGN = TOP ALIGN = LEFT> +-h <hostname> +</TD> +<TD VALIGN = TOP ALIGN = LEFT> +Specify the server hostname (needed by Name Server clients for +PROC_LOCAL naming context) +</TD> +<TD VALIGN = TOP ALIGN = LEFT> +ACE_DEFAULT_SERVER_HOST +</TD> +<TR> +<TD VALIGN = TOP ALIGN = LEFT> +-p <nameserver port> <BR> +</TD> +<TD VALIGN = TOP ALIGN = LEFT> +Port number where the server process expects requests <BR> +</TD> +<TD VALIGN = TOP ALIGN = LEFT> +ACE_DEFAULT_SERVER_PORT +</TD> +<TR> +<TD VALIGN = TOP ALIGN = LEFT> +-l <namespace dir> <BR> +</TD> +<TD VALIGN = TOP ALIGN = LEFT> +Directory that holds the NameBinding databases <BR> +</TD> +<TD VALIGN = TOP ALIGN = LEFT> +ACE_DEFAULT_NAMESPACE_DIR +</TD> +<TR> +<TD VALIGN = TOP ALIGN = LEFT> +-P <process name> <BR> +</TD> +<TD VALIGN = TOP ALIGN = LEFT> +Name of the client process +</TD> +<TD VALIGN = TOP ALIGN = LEFT> +argv[0] +</TD> +<TR> +<TD VALIGN = TOP ALIGN = LEFT> +-s <database name> <BR> +</TD> +<TD VALIGN = TOP ALIGN = LEFT> +Name of the database. NameBindings for the appropriate naming context +are stored in file <namespace_dir>/<database name>. +</TD> +<TD VALIGN = TOP ALIGN = LEFT> +<I> null </I> +</TD> +<TR> +<TD VALIGN = TOP ALIGN = LEFT> +-d <debug> +</TD> +<TD VALIGN = TOP ALIGN = LEFT> +Turn debugging on/off +</TD> +<TD VALIGN = TOP ALIGN = LEFT> +0 (off) +</TD> +<TR> +<TD VALIGN = TOP ALIGN = LEFT> +-T <trace> +</TD> +<TD VALIGN = TOP ALIGN = LEFT> +Turn tracing on/off +</TD> +<TD VALIGN = TOP ALIGN = LEFT> +0 (off) +</TD> +<TR> +<TD VALIGN = TOP ALIGN = LEFT> +-v <verbose> +</TD> +<TD VALIGN = TOP ALIGN = LEFT> +Turn verbose on/off +</TD> +<TD VALIGN = TOP ALIGN = LEFT> +0 (off) +</TD> + +</TABLE> +<P> + +<LI><B>Examples</B><P> +<OL> +<LI> Here is what a config file would look like for starting up a +server at port 20222 using NET_LOCAL naming context with database +called MYDATABSE located in directory /tmp: + +<PRE> <CODE> +dynamic Naming_Service Service_Object * + ../lib/libnetsvcs.so:_make_ACE_Name_Acceptor() + "-p 20222 -c NET_LOCAL -l /tmp -s MYDATABASE" +</PRE> </CODE> + +<LI> Here is what a config file would look like for starting up a +client that connects to a Name Server running on host +tango.cs.wustl.edu at port 20222: + +<PRE> <CODE> +dynamic Naming_Service_Client Service_Object * + ../lib/libnetsvcs.so:_make_Client_Test() + "-h tango.cs.wustl.edu -p 20222" +</PRE> </CODE> +</OL> + +Note:<P> +<UL> +<LI> These files would vary if the services are run on NT. For +example, instead of using *.so, we would have to use *.dll.<P> +<LI> 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). <P> +<LI> 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 an absolute 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. +</UL> + +</UL> + +<P><HR><P> +<A NAME="time-overview"> +<H3> Overview of Time Service</H3> + +Time Service provides accurate, fault-tolerant clock synchronization +for computers collaborating in local area networks and wide area +networks. Synchronized time services are important in distributed +systems that require multiple hosts to maintain accurate global +time. The architecture of the distributed time service contains the +following Time Server, Clerk, and Client components: <P> + +<UL> +<LI> <I> Time Server </I> answers queries about the time made by +Clerks. <P> + +<LI> <I> Clerk </I> queries one or more Time Servers to determine +the correct time, calculates the approximate correct time using one of +several distributed time algorithms and updates its own local system +time. <P> + +<LI> <I> Client </I> uses the global time information maintained by +a Clerk to provide consistency with the notion of time used by clients +on other hosts. <P> +</UL> +<P> +The following are the key classes in the ACE Time Service: <P> + +<UL> +<LI> <B><TT> Class TS_Server_Handler </TT></B> <P> + +TS_Server_Handler represents the server side of communication between +clerk and server. It interprets incoming requests for time updates, +gets the system time, creates a reply in response to the request and +then sends the reply to the clerk from which it received the request. +For communication it uses the helper class Time_Request.<P> + +<LI> <B><TT> Class TS_Server_Acceptor </TT></B> <P> + +TS_Server_Acceptor allocates in its handle_input routine a new instance +of class TS_Server_Handler on the heap, and accepts connections into this +TS_Server_Handler.<P> + +<LI> <B><TT> Class TS_Clerk_Handler </TT></B> <P> + +TS_Clerk_Handler represents the clerk side of communication between +clerk and server. It generates requests for time updates every timeout +period and then sends these requests to all the servers it is +connected to asynchronously. It receives the replies to these requests +from the servers through its handle_input method and then adjusts the +time using the roundtrip estimate. It caches this time, which is +subsequently retrieved by TS_Clerk_Processor.<P> + +<LI> <B><TT> Class TS_Clerk_Processor </TT></B> <P> + +TS_Clerk_Processor creates a new instance of TS_Clerk_Handler for +every server connection it needs to create. It periodically calls +send_request() of every TS_Clerk_Handler to send a request for time +update to all the servers. In the process, it retrieves the latest +time cached by each TS_Clerk_Handler and then uses it to compute its +notion of the local system time.<P> + +<LI> <B> Algorithms </B> <P> + +Currently, updating the system time involves taking the average of all +the times received from the servers.<P> +</UL> + +The following is a description of how to configure the Time Server +clerk and server services: <P> + +<UL> + +<LI> <B> Startup configuration </B> <P> + +Configuring a server requires specifying the port number of the +server. This can be specified as a command line argument as follows: <P> + + -p <port number> + +<P> +A clerk communicates with one or more server processes. To communicate +with the server process, a client needs to know the INET_Addr, where +the server offers its service. The configuration parameters namely the +server port and server host are passed as command line arguments when +starting up the clerk service as follows: <P> + + -h <server host1>:<server port1> -h <server host2>:<server port2> ... +<P> +Note that multiple servers can be specified in this manner for the +clerk to connect to when it starts up. The server name and the port +number need to be concatenated and separated by a ":". In addition, +the timeout value can also be specified as a command line argument as +follows: +<P> + + -t timeout + +<P> +The timeout value specifies the time interval at which the clerk +should query the servers for time updates. +<P> +By default a Clerk does a non-blocking connect to a server. This can +be overridden and a Clerk can be made to do a blocking connect by +using the -b flag. +<P> + +<LI> <B>Examples</B> <P> +<OL> +<LI> Here is what a config file would look like for starting up a +server at port 20202: + +<PRE> <CODE> +dynamic Time_Service Service_Object * + ../lib/libnetsvcs.so:_make_ACE_TS_Server_Acceptor() + "-p 20202" +</PRE> </CODE> + +<LI> Here is what a config file would look like for starting up a +clerk that needs to connect to two servers, one at tango and one at +lambada: + +<PRE> <CODE> +dynamic Time_Server_test Service_Object * + ../lib/libnetsvcs.so:_make_ACE_TS_Clerk_Connector () + "-h tango:20202 -h lambada:20202 -t 4" +</PRE> </CODE> +</OL> + +Note:<P> +<UL> +<LI> These files would vary if the services are run on NT. For +example, instead of using *.so, we would have to use *.dll.<P> +<LI> 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). <P> +<LI> 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 an absolute 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. +</UL> +<P> + +</UL> + +<P><HR><P> +<H3><A NAME="token-overview">Token Service</A></H3> + +The ACE Token Service provides local and remove mutexes and +readers/writer locks. For information regarding the deadlock +detection algorithm, check out ACE_Token_Manager.h. For information +about an implementation of the Composite Pattern for Tokens, check out +Token_Collection.h. The classes which implement the local and remote +synchronization primitives are listed below:<P> + +<UL> + <LI> <B><TT>ACE_Local_Mutex</TT></B><P> + + This class is a more general-purpose synchronization mechanism + than SunOS 5.x mutexes. For example, it implements "recursive + mutex" semantics, where a thread that owns the token can + reacquire it without deadlocking. In addition, threads that + are blocked awaiting the token are serviced in strict FIFO + order as other threads release the token (SunOS 5.x mutexes + don't strictly enforce an acquisition order). Lastly, + ACE_Local_Mutex performs deadlock detection on acquire + calls.<p> + + <LI> <B><TT>ACE_Remote_Mutex</TT></B><P> + + This is the remote equivalent to ACE_Local_Mutex. The + Remote_Mutex class offers methods for acquiring, renewing, and + releasing a distributed synchronization mutex. Similar to + ACE_Local_Mutex, ACE_Remote_Token_Proxy offers recursive + acquisition, FIFO waiter ordering, and deadlock detection. It + depends on the Token Server for its distributed synchronization + semantics.<p> + + <LI> <B><TT>ACE_Local_RLock</TT></B><P> + + This class implements the reader interface to canonical + readers/writer locks. Multiple readers can hold the lock + simultaneously when no writers have the lock. Alternatively, + when a writer holds the lock, no other participants (readers or + writers) may hold the lock. This class is a more + general-purpose synchronization mechanism than SunOS 5.x + RLocks. For example, it implements "recursive RLock" + semantics, where a thread that owns the token can reacquire it + without deadlocking. In addition, threads that are blocked + awaiting the token are serviced in strict FIFO order as other + threads release the token (SunOS 5.x RLockes don't strictly + enforce an acquisition order).<P> + + <LI> <B><TT>ACE_Local_WLock</TT></B><P> + + This class implements the writer interface to canonical + readers/writer locks. Multiple readers can hold the lock + simultaneously when no writers have the lock. Alternatively, + when a writer holds the lock, no other participants (readers or + writers) may hold the lock. This class is a more + general-purpose synchronization mechanism than SunOS 5.x WLock. + For example, it implements "recursive WLock" semantics, where a + thread that owns the token can reacquire it without + deadlocking. In addition, threads that are blocked awaiting + the token are serviced in strict FIFO order as other threads + release the token (SunOS 5.x WLocks don't strictly enforce an + acquisition order).<P> + + <LI> <B><TT>ACE_Remote_RLock</TT></B><P> + + This is the remote equivalent to ACE_Local_RLock. Multiple + readers can hold the lock simultaneously when no writers have + the lock. Alternatively, when a writer holds the lock, no + other participants (readers or writers) may hold the lock. + ACE_Remote_RLock depends on the ACE Token Server for its + distributed synchronization semantics.<P> + + <LI> <B><TT>ACE_Remote_RLock</TT></B><P> + + This is the remote equivalent to ACE_Local_WLock.<P> +</UL> + +The Token Server provides distributed mutex and readers/writer lock +semantics to the ACE Token library. ACE_Remote_Mutex, +ACE_Remote_RLock, and ACE_Remote_WLock, are proxies to the Token +Server. The following are the key classes in the ACE Token +Server:<P> + +<UL> + <LI> <B><TT>class Token_Acceptor</TT></B><P> + + The Token_Acceptor is a Token_Handler factory. It accepts + connections and passes the service responsibilities off to a + new Token_Handler.<p> + + <LI> <B><TT>class Token_Handler</TT></B><P> + + This class is the main class ``entry point'' 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 terminology, 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.<P> +</UL> + +The following describes how to configure the Token Server:<P> +<UL> + <LI> <b>Startup configuration</B><P> + + The only parameter that the Token Server takes is a listen port + number. You can specify a port number by passing a "-p + <port_number>" to the application. This can be done via the + svc.conf file.<P> + + <LI> <B>Examples </B><P> + + Here is an example NT svc.conf entry that dynamically loads the + Token Server specifying port number to listen on for client + connections:<P> + + <code><pre> + dynamic Token_Service Service_Object * + ../../ace/libnet_svcs.dll:_make_ACE_Token_Acceptor() + "-p 10202" + </code></pre> + <P> + + Here is an example UNIX svc.conf entry that dynamically loads the + Token Server specifying port number to listen on for client + connections. Notice that only the name of the library file + changed:<P> + + <code><pre> + dynamic Token_Service Service_Object * + ../../ace/netsvcs.so:_make_ACE_Token_Acceptor() + "-p 10202" + </code></pre> +</UL> +Note:<P> +<UL> +<LI> These files would vary if the services are run on NT. For +example, instead of using *.so, we would have to use *.dll.<P> +<LI> 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). <P> +<LI> 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 an absolute 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. +</UL> + + +<P><HR><P> +<A NAME="server-logging-overview"> +<H3>Overview of Server Logging Service</H3> + +The Server Logging Service provides a concurrent, multi-service daemon +that processes logging records received from one or more client hosts +simultaneously. The object-oriented design of the Server Logging +Service is decomposed into several modular components that perform +well-defined tasks. <P> + +The following are the key classes in the Server Logging Service: <P> +<UL> +<LI> <B> <TT> Server_Logging_Handler </TT> </B> <P> +The Server_Logging_Handler class is a parameterized type that is +responsible for processing logging records sent to the Server from +participating client hosts. When logging records arrive from the +client host associated with a particular Logging Handler object, the +handle_input() method of the Server_Logging_Handler class is called +which in turn formats and displays the records on one or more output +devices (such as the printer, persistent storage, and/or console +devices. <P> + +<LI> <B> <TT> Server_Logging_Acceptor </TT> </B> <P> +The class Server_Logging_Acceptor allocates in its handle_input() +routine a new instance of class Server_Logging_Handler on the heap, +and accepts connections into this Server_Logging_Handler. <P> +</UL> + +The following describes how to configure the Logging Server:<P> +<UL> + <LI> <b>Startup configuration</B><P> + + The only parameter that the Logging Server takes is a listen + port number. You can specify a port number by passing a "-p + <port_number>" to the application. This can be done via the + svc.conf file.<P> + + <LI> <B>Examples </B><P> + + Here is an example NT svc.conf entry that dynamically loads the + Logging Server specifying port number to listen on for client + connections:<P> + + <PRE> <CODE> + dynamic Server_Logging_Service Service_Object * + ../../ace/libnet_svcs.dll:_make_ACE_Server_Logging_Acceptor() + "-p 10202" + </PRE></CODE> + <P> + + Here is an example UNIX svc.conf entry that dynamically loads the + Logging Server specifying port number to listen on for client + connections. Notice that only the name of the library file + changed:<P> + + <PRE> <CODE> + dynamic Server_Logging_Service Service_Object * + ../../ace/netsvcs.so:_make_ACE_Server_Logging_Acceptor() + "-p 10202" + </PRE></CODE> +</UL> +Note:<P> +<UL> +<LI> These files would vary if the services are run on NT. For +example, instead of using *.so, we would have to use *.dll.<P> +<LI> 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). <P> +<LI> 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 an absolute 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. +</UL> + +<P><HR><P> +<A NAME="client-logging-overview"> +<H3>Overview of Client Logging Service</H3> + +The Client Logging Service multiplexes messages recevied from +different applications to the Server Logging Daemon running on a +designated host in a network/internetwork. + + +The following are the key classes in the Client Logging Service: <P> +<UL> +<LI> <B> <TT> Client_Logging_Handler </TT> </B> <P> +The Client_Logging_Handler class is a parameterized type that is +responsible for setting up a named pipe and using it to communicate +with different user processes on the same host. Once logging records +arrive from these processes, the handler reads these records in +priority order, performs network-byte order conversions on +multiple-header fields, and then transmits these records to the Server +Logging daemon across the network. <P> + +<LI> <B> <TT> Client_Logging_Connector </TT> </B> <P> +The class Client_Logging_Connector connects to the Server Logging +daemon and then in its handle_input() routine it allocates a new +instance of the Client_Logging_Handler on the heap. <P> +</UL> + +The following describes how to configure the Logging Client:<P> +<UL> + <LI> <b>Startup configuration</B><P> + +Configuring a Logging Client requires specifying all or some of the +following parameters. These parameters can be passed in to main +through command line as follows:<P> + +<TABLE cellpadding = 10 cellspacing = 0 border = 5> +<TD VALIGN = TOP ALIGN = LEFT> +<B> Option </B> +</TD> +<TD VALIGN = TOP ALIGN = LEFT> +<B> Description </B> +</TD> +<TD VALIGN = TOP ALIGN = LEFT> +<B> Default value </B> +</TD> +<TR> +<TD VALIGN = TOP ALIGN = LEFT> +-h &hostname> <BR> +</TD> +<TD VALIGN = TOP ALIGN = LEFT> +Hostname of the Server Logging Daemon <BR> +</TD> +<TD VALIGN = TOP ALIGN = LEFT> +ACE_DEFAULT_SERVER_HOST +</TD> +<TR> +<TD VALIGN = TOP ALIGN = LEFT> +-p <port number> +</TD> +<TD VALIGN = TOP ALIGN = LEFT> +Port number of the Server Logging Daemon <BR> +</TD> +<TD VALIGN = TOP ALIGN = LEFT> +ACE_DEFAULT_LOGGING_SERVER_PORT +</TD> +<TR> +<TD VALIGN = TOP ALIGN = LEFT> +-p <rendezvous key> +</TD> +<TD VALIGN = TOP ALIGN = LEFT> +Rendezvous key used to create named pipe +</TD> +<TD VALIGN = TOP ALIGN = LEFT> +ACE_DEFAULT_RENDEZVOUS +</TD> +</TABLE> +<P> + + <LI> <B>Examples </B><P> + + Here is an example NT svc.conf entry that dynamically loads the + Logging Client specifying host name and port number of the + Logging Server: <P> + + <PRE> <CODE> + dynamic Client_Logging_Service Service_Object * + ../../ace/libnet_svcs.dll:_make_ACE_Client_Logging_Connector() + "-h tango.cs.wustl.edu -p 10202" + </PRE></CODE> + <P> + + Here is an example UNIX svc.conf entry that dynamically loads the + Logging Client specifying host name and port number of the + Logging Server. Notice that only the name of the library file + changed:<P> + + <PRE> <CODE> + dynamic Client_Logging_Service Service_Object * + ../../ace/netsvcs.so:_make_ACE_Client_Logging_Connector() + "-h tango.cs.wustl.edu -p 10202" + </PRE></CODE> +</UL> +Note:<P> +<UL> +<LI> These files would vary if the services are run on NT. For +example, instead of using *.so, we would have to use *.dll.<P> +<LI> 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). <P> +<LI> 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 an absolute 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. +</UL> + +<P><HR><P> +<A NAME="logging-strategy-overview"> +<H3> Overview of Logging Strategy Service</H3> + +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. <P> + +The following describes how to configure the Logging Strategy +Service:<p> + +<UL> +<LI> <b>Startup configuration</B><P> + +Here are the command line arguments that can be given to the Logging +Strategy Service: <P> + + -f <flag1>|<flag2>|<flag3> (etc...) <P> + + where a flag can be any of the following: <P> + +<TABLE cellpadding = 10 cellspacing = 0 border = 5> +<TD VALIGN = TOP ALIGN = LEFT> + <B> Flags </B> +</TD> +<TD VALIGN = TOP ALIGN = LEFT> + <B> Description </B> +</TD> +<TR> +<TD VALIGN = TOP ALIGN = LEFT> + STDERR <BR> +</TD> +<TD VALIGN = TOP ALIGN = LEFT> + Write messages to stderr. <BR> +</TD> +<TR> +<TD VALIGN = TOP ALIGN = LEFT> + LOGGER <BR> +</TD> +<TD VALIGN = TOP ALIGN = LEFT> + Write messages to the local client logger deamon. <BR> +</TD> +<TR> +<TD VALIGN = TOP ALIGN = LEFT> + OSTREAM <BR> +</TD> +<TD VALIGN = TOP ALIGN = LEFT> + Write messages to the ostream that gets created by specifying a + filename (see below) <BR> +</TD> +<TR> +<TD VALIGN = TOP ALIGN = LEFT> + VERBOSE <BR> +</TD> +<TD VALIGN = TOP ALIGN = LEFT> + Display messages in a verbose manner <BR> +</TD> +<TR> +<TD VALIGN = TOP ALIGN = LEFT> + SILENT <BR> +</TD> +<TD VALIGN = TOP ALIGN = LEFT> + Do not print messages at all <BR> +</TD> + +</TABLE> +<P> + +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 '|'. <P> + + -s filename + <P> + +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. <P> + +<LI> <B> Examples: </B> <P> +<OL> +<LI> To direct output only to STDERR, specify command line arguments as: <P> + "-f STDERR" +<P> + +<LI> To direct output to both STDERR and a file called "mylog", specify +command line arguments as: <P> + "-f STDERR|OSTREAM -s mylog" +</OL> +Note:<P> +<UL> +<LI> These files would vary if the services are run on NT. For +example, instead of using *.so, we would have to use *.dll.<P> +<LI> 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). <P> +<LI> 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 an absolute 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. +</UL> +</UL> + +<P><HR><P> +Back to the <A HREF="http://www.cs.wustl.edu/~schmidt/ACE.html"> +ACE</A> home page. diff --git a/netsvcs/Makefile b/netsvcs/Makefile new file mode 100644 index 00000000000..c9e4b544788 --- /dev/null +++ b/netsvcs/Makefile @@ -0,0 +1,27 @@ +#---------------------------------------------------------------------------- +# @(#)Makefile 1.1 10/18/96 +# +# Makefile for the ACE network services +#---------------------------------------------------------------------------- + +#---------------------------------------------------------------------------- +# Local macros +#---------------------------------------------------------------------------- + +INFO = README + +# lib must come first! +DIRS = lib \ + clients \ + servers + +#---------------------------------------------------------------------------- +# Include macros and targets +#---------------------------------------------------------------------------- + +include $(WRAPPER_ROOT)/include/makeinclude/wrapper_macros.GNU +include $(WRAPPER_ROOT)/include/makeinclude/macros.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.common.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.nested.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.nolocal.GNU + diff --git a/netsvcs/README b/netsvcs/README new file mode 100644 index 00000000000..e9dff4c7dfc --- /dev/null +++ b/netsvcs/README @@ -0,0 +1,20 @@ +This directory contains the ACE network service implementations and +sample driver programs for dynamically configuring them into client +and server processes. The subdirectories include the following: + + . lib -- contains implementations of the ACE network services. + These services include a logging service, a name service, + a distributed locking service, and a distributed time service. + These can be built as shared libraries (i.e., DLLs), which + are then linked into applications either statically or + dynamically. + + . servers -- contains the driver program that links the various + services together, either statically or dynamically, to + form complete server programs. + + . clients -- contains a number of test programs that illustrate + how to write clients for the various ACE network services. + +Please see the ACE-netsvcs.html file for an overview of the various +services. diff --git a/netsvcs/clients/Logger/Makefile b/netsvcs/clients/Logger/Makefile new file mode 100644 index 00000000000..bc9a34890f3 --- /dev/null +++ b/netsvcs/clients/Logger/Makefile @@ -0,0 +1,77 @@ +#---------------------------------------------------------------------------- +# @(#)Makefile 1.1 10/18/96 +# +# Makefile for client logging applications +#---------------------------------------------------------------------------- + +#---------------------------------------------------------------------------- +# Local macros +#---------------------------------------------------------------------------- + +BIN = direct_logging \ + indirect_logging + +LSRC = $(addsuffix .cpp,$(BIN)) + +VLDLIBS = $(LDLIBS:%=%$(VAR)) + +BUILD = $(VBIN) + +#---------------------------------------------------------------------------- +# Include macros and targets +#---------------------------------------------------------------------------- + +include $(WRAPPER_ROOT)/include/makeinclude/wrapper_macros.GNU +include $(WRAPPER_ROOT)/include/makeinclude/macros.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.common.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.nonested.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.bin.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.local.GNU + +#---------------------------------------------------------------------------- +# Local targets +#---------------------------------------------------------------------------- + +#---------------------------------------------------------------------------- +# Dependencies +#---------------------------------------------------------------------------- + +# DO NOT DELETE THIS LINE -- g++dep uses it. +# DO NOT PUT ANYTHING AFTER THIS LINE, IT WILL GO AWAY. + +.obj/direct_logging.o .shobj/direct_logging.so: direct_logging.cpp \ + $(WRAPPER_ROOT)/ace/SOCK_Connector.h \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.h \ + $(WRAPPER_ROOT)/ace/SOCK_IO.h \ + $(WRAPPER_ROOT)/ace/SOCK.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/Addr.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.i \ + $(WRAPPER_ROOT)/ace/SOCK.i \ + $(WRAPPER_ROOT)/ace/SOCK_IO.i \ + $(WRAPPER_ROOT)/ace/INET_Addr.h \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.i \ + $(WRAPPER_ROOT)/ace/SOCK_Connector.i +.obj/indirect_logging.o .shobj/indirect_logging.so: indirect_logging.cpp \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i + +# IF YOU PUT ANYTHING HERE IT WILL GO AWAY diff --git a/netsvcs/clients/Logger/README b/netsvcs/clients/Logger/README new file mode 100644 index 00000000000..87e324ab0d8 --- /dev/null +++ b/netsvcs/clients/Logger/README @@ -0,0 +1,18 @@ +This directory contains two sample logging applications that implement +and test the ACE distributed logging service. + + . indirect_logging.cpp + + This program talks to the ACE Client Logging Daemon on + the localhost, which forwards the messages to Server + Logging Daemon. The Client Logging Daemon and Server + Logging Daemon both must be started before you can run + this test. + + . direct_logging.cpp + + This program talks directly to the Server Logging + Daemon. The Server Logging Daemon must be started + before you can run this test. + +To start these daemons, please check out the ../../servers/ directory. diff --git a/netsvcs/clients/Logger/direct_logging.cpp b/netsvcs/clients/Logger/direct_logging.cpp new file mode 100644 index 00000000000..26b63657efd --- /dev/null +++ b/netsvcs/clients/Logger/direct_logging.cpp @@ -0,0 +1,42 @@ +// This program sends logging records directly to the server, rather +// @(#)direct_logging.cpp 1.1 10/18/96 + +// than going through the client logging daemon. + +#include "ace/SOCK_Connector.h" +#include "ace/Log_Msg.h" +#include "ace/Log_Record.h" + +static u_short LOGGER_PORT = ACE_DEFAULT_SERVER_PORT; +static const char *const LOGGER_HOST = ACE_DEFAULT_SERVER_HOST; +static const char *const DATA = "hello world\n"; + +int +main (int argc, char *argv[]) +{ + u_short logger_port = argc > 1 ? atoi (argv[1]) : LOGGER_PORT; + const char *logger_host = argc > 2 ? argv[2] : LOGGER_HOST; + + ACE_SOCK_Stream logger; + ACE_SOCK_Connector connector; + ACE_INET_Addr addr (logger_port, logger_host); + ACE_Log_Record log_record (LM_DEBUG, + ACE_OS::time ((time_t *) 0), + ACE_OS::getpid ()); + + if (connector.connect (logger, addr) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "open"), -1); + + log_record.msg_data (DATA); + size_t len = log_record.length (); + size_t encoded_len = htonl (len); + + log_record.encode (); + + if (logger.send (4, &encoded_len, sizeof encoded_len, + (char *) &log_record, len) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "send"), -1); + else if (logger.close () == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "close"), -1); + return 0; +} diff --git a/netsvcs/clients/Logger/indirect_logging.cpp b/netsvcs/clients/Logger/indirect_logging.cpp new file mode 100644 index 00000000000..8b1ac5841f7 --- /dev/null +++ b/netsvcs/clients/Logger/indirect_logging.cpp @@ -0,0 +1,34 @@ +// This is a simple test that sends logging records to the Client +// @(#)indirect_logging.cpp 1.1 10/18/96 + +// Logging Daemon running on the localhost. This daemon then forwards +// them to the Server Logging Daemon. If there is no Server Logging +// Daemon, the logging records will be written to stderr. + +#include "ace/Log_Msg.h" + +int +main (int argc, char *argv[]) +{ + char *prog_name = argv[0]; + int iterations = argc < 2 ? 10 : ACE_OS::atoi (argv[1]); + char *logger_key = argc < 3 ? ACE_DEFAULT_RENDEZVOUS : argv[2]; + + ACE_OS::srand ((u_int) ACE_OS::time (0)); + + ACE_LOG_MSG->open (prog_name, ACE_Log_Msg::LOGGER, logger_key); + + ACE_DEBUG ((LM_STARTUP, "starting up the test\n")); + + for (int i = 0; i < iterations; i++) + { + int priority = ACE_OS::rand () % int (LM_MAX); + ACE_POW (priority); + ACE_DEBUG ((ACE_Log_Priority (priority), + "random message %d...\n", + priority)); + } + + ACE_DEBUG ((LM_SHUTDOWN, "closing down the test\n")); + return 0; +} diff --git a/netsvcs/clients/Makefile b/netsvcs/clients/Makefile new file mode 100644 index 00000000000..9e5d9d5025a --- /dev/null +++ b/netsvcs/clients/Makefile @@ -0,0 +1,24 @@ +#---------------------------------------------------------------------------- +# @(#)Makefile 1.1 10/18/96 +# +# Makefile for the client programs that test the ACE network services +#---------------------------------------------------------------------------- + +#---------------------------------------------------------------------------- +# Local macros +#---------------------------------------------------------------------------- + +DIRS = Logger \ + Naming \ + Tokens + +#---------------------------------------------------------------------------- +# Include macros and targets +#---------------------------------------------------------------------------- + +include $(WRAPPER_ROOT)/include/makeinclude/wrapper_macros.GNU +include $(WRAPPER_ROOT)/include/makeinclude/macros.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.common.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.nested.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.nolocal.GNU + diff --git a/netsvcs/clients/Naming/Client/Client_Test.cpp b/netsvcs/clients/Naming/Client/Client_Test.cpp new file mode 100644 index 00000000000..da1c4c0836c --- /dev/null +++ b/netsvcs/clients/Naming/Client/Client_Test.cpp @@ -0,0 +1,561 @@ +#define ACE_BUILD_SVC_DLL +// @(#)Client_Test.cpp 1.1 10/18/96 + +#include "ace/Service_Config.h" +#include "ace/Naming_Context.h" +#include "ace/Dynamic_Service.h" +#include "Client_Test.h" + +class ACE_Svc_Export Client_Test : public ACE_Service_Object +{ +public: + Client_Test (void); + + int open (void); + // Cache reactor and then register self with reactor + + int close (void); + // Close things down and free up resources. + + virtual int handle_input (ACE_HANDLE handle); + // Handle user entered commands + + virtual int init (int argc, char *argv[]); + // Initialize name options and naming context when dynamically + // linked. + + virtual int fini (void); + // Close down the test when dynamically unlinked. + + void list_options (void); + // Print name options + + int bind (char *key, char *value, char *type = ""); + // Bind a key to a value + + int unbind (char *key); + // Unbind a name binding + + int rebind (char *key, char *value, char *type = ""); + // Rebind a name binding + + int find (char *key); + // Find the value associated with a key + + int list_names (char *pattern); + // Find all names that match pattern + + int list_values (char *pattern); + // Find all values that match pattern + + int list_types (char *pattern); + // Find all types that match pattern + + int list_name_entries (char *pattern); + // Find all names that match pattern + + int list_value_entries (char *pattern); + // Find all values that match pattern + + int list_type_entries (char *pattern); + // Find all types that match pattern + +private: + ACE_Name_Options *name_options_; + // Name Options associated with the Naming Context + + void display_menu (void); + // Display user menu + + int set_proc_local (void); + // Set options to use PROC_LOCAL naming context + + int set_node_local (void); + // Set options to use NODE_LOCAL naming context + + int set_host (char *hostname, int port); + // Set options to use NET_LOCAL naming context + // specifying host name and port number + + int quit (void); + // Gracefully exit +}; + +// The following Factory is used by the ACE_Service_Config and +// svc.conf file to dynamically initialize the state of the client +// test. + +ACE_SVC_FACTORY_DEFINE (Client_Test) + +// Get the instance of Name_Service using Dynamic_Service + +//inline Name_Service * +//NAME_SERVICE (void) + +inline ACE_Naming_Context * +NAMING_CONTEXT (void) +{ + return ACE_Dynamic_Service<ACE_Naming_Context>::instance ("ACE_Naming_Context"); +} + +Client_Test::Client_Test (void) +{ + ACE_DEBUG ((LM_DEBUG, "Client_Test::Client_Test\n")); +} + +int +Client_Test::init (int argc, char *argv[]) +{ + ACE_DEBUG ((LM_DEBUG, "Client_Test::init\n")); + + // Cache the name options. + this->name_options_ = NAMING_CONTEXT ()->name_options (); + return this->open (); +} + +int +Client_Test::open (void) +{ + this->display_menu (); + + if (ACE::register_stdin_handler (this, + ACE_Service_Config::reactor (), + ACE_Service_Config::thr_mgr ()) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "register_stdin_handler"), -1); +} + + +int +Client_Test::close (void) +{ + // Deregister this handler with the ACE_Reactor. + return ACE_Service_Config::reactor ()->remove_handler + (ACE_STDIN, + ACE_Event_Handler::DONT_CALL | ACE_Event_Handler::READ_MASK); +} + +int +Client_Test::fini (void) +{ + ACE_DEBUG ((LM_DEBUG, "Client_Test::fini\n")); + return this->close (); +} + +int +Client_Test::handle_input (ACE_HANDLE) +{ + char option[BUFSIZ]; + char buf1[BUFSIZ]; + char buf2[BUFSIZ]; + char buf3[BUFSIZ]; + char *temp_buf; + int port; + char input[256]; + + if (::scanf ("%s", option) <= 0) + { + ACE_ERROR_RETURN ((LM_ERROR, "%p Try again!\n", + "Client_Test::handle_input"), 0); + } + + int result = -1; + + switch (isupper (option[0]) ? tolower (option[0]) : option[0]) + { + case 'p' : + result = this->set_proc_local (); + break; + case 'n' : + result = this->set_node_local (); + break; + case 'h' : + if (::scanf ("%s %d", buf1, &port) <= 0) + break; + result = this->set_host (buf1, port); + break; + case 'b' : + // get the input from stdin + ACE_OS::gets (input); + + // get the key + if (temp_buf = ACE_OS::strtok (input, " ")) + { + ACE_OS::strcpy (buf1, temp_buf); + + // get the value + if (temp_buf = ACE_OS::strtok (0, " ")) + { + ACE_OS::strcpy (buf2, temp_buf); + + // get the type (if entered) + if (temp_buf = ACE_OS::strtok (0, " ")) + { + ACE_OS::strcpy (buf3, temp_buf); + result = this->bind (buf1, buf2, buf3); + } + else + result = this->bind (buf1, buf2); + } + else + ACE_ERROR ((LM_ERROR, "Bind Failed! Value not entered.\n")); + } + else + ACE_ERROR ((LM_ERROR, "Bind Failed! Key and Value not entered.\n")); + break; + case 'u' : + if (::scanf ("%s", buf1) <= 0) + break; + result = this->unbind (buf1); + break; + case 'r' : + // get the input from stdin + ACE_OS::gets (input); + + // get the key + if (temp_buf = ACE_OS::strtok (input, " ")) + { + ACE_OS::strcpy (buf1, temp_buf); + + // get the value + if (temp_buf = ACE_OS::strtok (0, " ")) + { + ACE_OS::strcpy (buf2, temp_buf); + + // get the type (if entered) + if (temp_buf = ACE_OS::strtok (0, " ")) + { + ACE_OS::strcpy (buf3, temp_buf); + result = this->rebind (buf1, buf2, buf3); + } + else + result = this->rebind (buf1, buf2); + } + else + ACE_ERROR ((LM_ERROR, "Rebind Failed! Value not entered.\n")); + } + else + ACE_ERROR ((LM_ERROR, "Reind Failed! Key and value not entered.\n")); + break; + case 'f' : + if (::scanf ("%s", buf1) <= 0) + break; + result = this->find (buf1); + break; + case 'j' : + if (::scanf ("%s", buf1) <= 0) + break; + else + result = this->list_names (buf1); + break; + case 'k' : + if (::scanf ("%s", buf1) <= 0) + break; + else + result = this->list_values (buf1); + break; + case 'l' : + if (::scanf ("%s", buf1) <= 0) + break; + else + result = this->list_types (buf1); + break; + case 'c' : + if (::scanf ("%s", buf1) <= 0) + break; + else + result = this->list_name_entries (buf1); + break; + case 'd' : + if (::scanf ("%s", buf1) <= 0) + break; + else + result = this->list_value_entries (buf1); + break; + case 'e' : + if (::scanf ("%s", buf1) <= 0) + break; + else + result = this->list_type_entries (buf1); + break; + case 'q' : + result = this->quit (); + break; + default : + ACE_DEBUG ((LM_DEBUG, "Unrecognized command.\n")); + } + + this->display_menu (); + return result; +} + +void +Client_Test::display_menu (void) +{ + ACE_DEBUG ((LM_DEBUG, "\n")); + this->list_options (); + ACE_DEBUG ((LM_DEBUG, " Name Service Main Menu\n")); + ACE_DEBUG ((LM_DEBUG, " ----------------------\n")); + ACE_DEBUG ((LM_DEBUG, "<P> Use Process Local Database\n")); + ACE_DEBUG ((LM_DEBUG, "<N> Use Node Local Database\n"));; + ACE_DEBUG ((LM_DEBUG, "<H> Set Remote Name server <host> and <port>\n\n")); + ACE_DEBUG ((LM_DEBUG, "<B> Bind <key> <value> [<type>]\n")); + ACE_DEBUG ((LM_DEBUG, "<U> Unbind <key>\n")); + ACE_DEBUG ((LM_DEBUG, "<R> Rebind <key> <value> [<type>]\n")); + ACE_DEBUG ((LM_DEBUG, "<F> Find <key>\n")); + ACE_DEBUG ((LM_DEBUG, "<J> Lookup keys matching <pattern>\n")); + ACE_DEBUG ((LM_DEBUG, "<K> Lookup values matching <pattern>\n")); + ACE_DEBUG ((LM_DEBUG, "<L> Lookup types matching <pattern>\n")); + ACE_DEBUG ((LM_DEBUG, "<C> Complete lookup keys matching <pattern>\n")); + ACE_DEBUG ((LM_DEBUG, "<D> Complete lookup values matching <pattern>\n")); + ACE_DEBUG ((LM_DEBUG, "<E> Complete lookup types matching <pattern>\n")); + + ACE_DEBUG ((LM_DEBUG, "<Q> or ^C (exit)\n")); +} + +void +Client_Test::list_options (void) +{ +// ACE_DEBUG ((LM_DEBUG, " *** Process Name is %s ***\n", +// this->name_options_->process_name ())); + switch (this->name_options_->context ()) + { + case ACE_Naming_Context::PROC_LOCAL: + ACE_DEBUG ((LM_DEBUG, " *** Using Process Local Database\n")); + break; + case ACE_Naming_Context::NODE_LOCAL: + ACE_DEBUG ((LM_DEBUG, " *** Using Node Local Database\n")); + break; + case ACE_Naming_Context::NET_LOCAL: + ACE_DEBUG ((LM_DEBUG, " *** Hostname: %s\n", + this->name_options_->nameserver_host ())); + ACE_DEBUG ((LM_DEBUG, " *** Port Number: %d\n", + this->name_options_->nameserver_port ())); + break; + default: + assert (!"shouldn't occur!\n"); + /* NOTREACHED */ + } + ACE_DEBUG ((LM_DEBUG, " *** Namespace directory is %s ***\n", + this->name_options_->namespace_dir ())); +} + +int +Client_Test::set_proc_local (void) +{ + // Close down original name space + NAMING_CONTEXT ()->close (); + this->name_options_->nameserver_host ("localhost"); + this->name_options_->context (ACE_Naming_Context::PROC_LOCAL); + return NAMING_CONTEXT ()->open (ACE_Naming_Context::PROC_LOCAL); +} + +int +Client_Test::set_node_local (void) +{ + // Close down original name space + NAMING_CONTEXT ()->close (); + this->name_options_->nameserver_host ("localhost"); + this->name_options_->context (ACE_Naming_Context::NODE_LOCAL); + return NAMING_CONTEXT ()->open (ACE_Naming_Context::NODE_LOCAL); +} + +int +Client_Test::set_host (char* hostname, int port) +{ + // Close down original name space + NAMING_CONTEXT ()->close (); + + this->name_options_->context (ACE_Naming_Context::NET_LOCAL); + // Set Name Options + this->name_options_->nameserver_host (hostname); + this->name_options_->nameserver_port (port); + + return NAMING_CONTEXT ()->open (ACE_Naming_Context::NET_LOCAL); +} + +int +Client_Test::quit (void) +{ + // Send ourselves a SIGINT! + return ACE_OS::kill (ACE_OS::getpid (), SIGINT); +} + +int +Client_Test::bind (char* key, char* value, char* type) +{ + if (NAMING_CONTEXT ()->bind (key, value, type) != 0) + ACE_ERROR_RETURN ((LM_ERROR, "%p Bind failed! Key %s exists\n", + "Client_Test::bind", key), 0); + return 0; +} + +int +Client_Test::unbind (char* key) +{ + if (NAMING_CONTEXT ()->unbind (key) != 0) + ACE_ERROR_RETURN ((LM_ERROR, "%p Unbind failed! Key %s not found\n", + "Client_Test::unbind", key), 0); + return 0; +} + +int +Client_Test::rebind (char* key, char* value, char* type) +{ + int result = NAMING_CONTEXT ()->rebind (key, value, type ); + return result == 1 ? 0 : result; +} + +int +Client_Test::list_names (char *pattern) +{ + ACE_PWSTRING_SET set; + + if (NAMING_CONTEXT ()->list_names (set, pattern) != 0) + ACE_ERROR_RETURN ((LM_ERROR, "%p Pattern matching failed!\n", + "Client_Test::list_names"), 0); + else + { + ACE_PWSTRING_ITERATOR set_iterator (set); + + for (ACE_WString *name = 0; + set_iterator.next (name) !=0; + set_iterator.advance()) + ACE_DEBUG ((LM_DEBUG, "%s\n", name->char_rep ())); + } + return 0; +} + +int +Client_Test::list_values (char *pattern) +{ + ACE_PWSTRING_SET set; + + if (NAMING_CONTEXT ()->list_values (set, pattern) != 0) + ACE_ERROR_RETURN ((LM_ERROR, "%p Pattern matching failed!\n", + "Client_Test::list_values"), 0); + else + { + ACE_PWSTRING_ITERATOR set_iterator (set); + + for (ACE_WString *value = 0; + set_iterator.next (value) !=0; + set_iterator.advance()) + ACE_DEBUG ((LM_DEBUG, "%s\n", value->char_rep ())); + } + return 0; +} + +int +Client_Test::list_types (char *pattern) +{ + ACE_PWSTRING_SET set; + + if (NAMING_CONTEXT ()->list_types (set, pattern) != 0) + ACE_ERROR_RETURN ((LM_ERROR, "%p Pattern matching failed!\n", + "Client_Test::list_types"), 0); + else + { + ACE_PWSTRING_ITERATOR set_iterator (set); + + for (ACE_WString *type = 0; + set_iterator.next (type) !=0; + set_iterator.advance()) + ACE_DEBUG ((LM_DEBUG, "%s\n", type->char_rep ())); + } + return 0; +} + +int +Client_Test::list_name_entries (char *pattern) +{ + ACE_BINDING_SET set; + + if (NAMING_CONTEXT ()->list_name_entries (set, pattern) != 0) + ACE_ERROR_RETURN ((LM_ERROR, "%p Pattern matching failed!\n", + "Client_Test::list_names"), 0); + else + { + ACE_BINDING_ITERATOR set_iterator (set); + + for (ACE_Name_Binding *entry = 0; + set_iterator.next (entry) !=0; + set_iterator.advance()) + { + ACE_DEBUG ((LM_DEBUG, "%s\t", entry->name_.char_rep ())); + ACE_DEBUG ((LM_DEBUG, "%s\t", entry->value_.char_rep ())); + if (entry->type_) + ACE_DEBUG ((LM_DEBUG, "%s\n", entry->type_)); + } + } + return 0; +} + +int +Client_Test::list_value_entries (char *pattern) +{ + ACE_BINDING_SET set; + + if (NAMING_CONTEXT ()->list_value_entries (set, pattern) != 0) + ACE_ERROR_RETURN ((LM_ERROR, "%p Pattern matching failed!\n", + "Client_Test::list_values"), 0); + else + { + ACE_BINDING_ITERATOR set_iterator (set); + for (ACE_Name_Binding *entry = 0; + set_iterator.next (entry) !=0; + set_iterator.advance()) + { + ACE_DEBUG ((LM_DEBUG, "%s\t", entry->name_.char_rep ())); + ACE_DEBUG ((LM_DEBUG, "%s\t", entry->value_.char_rep ())); + if (entry->type_) + ACE_DEBUG ((LM_DEBUG, "%s\n", entry->type_)); + } + } + return 0; +} + +int +Client_Test::list_type_entries (char *pattern) +{ + ACE_BINDING_SET set; + + if (NAMING_CONTEXT ()->list_type_entries (set, pattern) != 0) + ACE_ERROR_RETURN ((LM_ERROR, "%p Pattern matching failed!\n", + "Client_Test::list_types"), 0); + else + { + ACE_BINDING_ITERATOR set_iterator (set); + + for (ACE_Name_Binding *entry = 0; + set_iterator.next (entry) !=0; + set_iterator.advance()) + { + ACE_DEBUG ((LM_DEBUG, "%s\t", entry->name_.char_rep ())); + ACE_DEBUG ((LM_DEBUG, "%s\t", entry->value_.char_rep ())); + ACE_DEBUG ((LM_DEBUG, "%s\n", entry->type_)); + } + } + return 0; +} + + +int +Client_Test::find (char *key) +{ + char *value = 0; + char *type = 0; + + if (NAMING_CONTEXT ()->resolve (key, value, type) != 0) + ACE_ERROR_RETURN ((LM_ERROR, "%p Find failed! Key %s not found\n", + "Client_Test::list_find", key), 0); + else + { + ACE_DEBUG ((LM_DEBUG, + "Binding for %s : value = %s\ttype = %s\n", + key, value, type)); + if (type) + delete [] type; + return 0; + } +} + diff --git a/netsvcs/clients/Naming/Client/Client_Test.h b/netsvcs/clients/Naming/Client/Client_Test.h new file mode 100644 index 00000000000..825ca528f87 --- /dev/null +++ b/netsvcs/clients/Naming/Client/Client_Test.h @@ -0,0 +1,9 @@ +/* -*- C++ -*- */ +// @(#)Client_Test.h 1.1 10/18/96 + + +#include "ace/OS.h" + +// Define the external Client_Test interface. + +ACE_SVC_FACTORY_DECLARE (Client_Test) diff --git a/netsvcs/clients/Naming/Client/Makefile b/netsvcs/clients/Naming/Client/Makefile new file mode 100644 index 00000000000..1c4a908feb0 --- /dev/null +++ b/netsvcs/clients/Naming/Client/Makefile @@ -0,0 +1,175 @@ +#---------------------------------------------------------------------------- +# @(#)Makefile 1.1 10/18/96 +# +# Makefile for the ACE client-side Name_Server test +#---------------------------------------------------------------------------- + +#---------------------------------------------------------------------------- +# Local macros +#---------------------------------------------------------------------------- + +BIN = main +LIB = libClient_Test.a +SHLIB = libClient_Test.so + +FILES = Client_Test + +SRC = $(addsuffix .cpp,$(BIN)) +OBJ = $(SRC:%.cpp=$(VDIR)%.o) + +LSRC = $(addsuffix .cpp,$(FILES)) +LOBJ = $(LSRC:%.cpp=$(VDIR)%.o) +SHOBJ = $(addsuffix .so,$(FILES)) + +LDLIBS = -lClient_Test +LIBS = -lACE + +VLDLIBS = $(LDLIBS:%=%$(VAR)) + +BUILD = $(VLIB) $(VSHLIB) $(SHLIBA) $(VBIN) + +#---------------------------------------------------------------------------- +# Include macros and targets +#---------------------------------------------------------------------------- + +include $(WRAPPER_ROOT)/include/makeinclude/wrapper_macros.GNU +include $(WRAPPER_ROOT)/include/makeinclude/macros.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.common.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.nonested.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.lib.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.bin.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.local.GNU + +#---------------------------------------------------------------------------- +# Local targets +#---------------------------------------------------------------------------- + +#---------------------------------------------------------------------------- +# Dependencies +#---------------------------------------------------------------------------- +# DO NOT DELETE THIS LINE -- g++dep uses it. +# DO NOT PUT ANYTHING AFTER THIS LINE, IT WILL GO AWAY. + +.obj/Client_Test.o .shobj/Client_Test.so: Client_Test.cpp \ + $(WRAPPER_ROOT)/ace/Service_Config.h \ + $(WRAPPER_ROOT)/ace/Service_Object.h \ + $(WRAPPER_ROOT)/ace/Shared_Object.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/Event_Handler.h \ + $(WRAPPER_ROOT)/ace/Thread_Manager.h \ + $(WRAPPER_ROOT)/ace/Thread.h \ + $(WRAPPER_ROOT)/ace/Synch.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.i \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.i \ + $(WRAPPER_ROOT)/ace/Synch_T.h \ + $(WRAPPER_ROOT)/ace/Set.h \ + $(WRAPPER_ROOT)/ace/Proactor.h \ + $(WRAPPER_ROOT)/ace/Message_Block.h \ + $(WRAPPER_ROOT)/ace/Malloc.h \ + $(WRAPPER_ROOT)/ace/Malloc_T.h \ + $(WRAPPER_ROOT)/ace/Memory_Pool.h \ + $(WRAPPER_ROOT)/ace/Signal.h \ + $(WRAPPER_ROOT)/ace/Mem_Map.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.i \ + $(WRAPPER_ROOT)/ace/ReactorEx.h \ + $(WRAPPER_ROOT)/ace/Token.h \ + $(WRAPPER_ROOT)/ace/Reactor.h \ + $(WRAPPER_ROOT)/ace/Handle_Set.h \ + $(WRAPPER_ROOT)/ace/Pipe.h \ + $(WRAPPER_ROOT)/ace/Pipe.i \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.h \ + $(WRAPPER_ROOT)/ace/SOCK_IO.h \ + $(WRAPPER_ROOT)/ace/SOCK.h \ + $(WRAPPER_ROOT)/ace/Addr.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.i \ + $(WRAPPER_ROOT)/ace/SOCK.i \ + $(WRAPPER_ROOT)/ace/SOCK_IO.i \ + $(WRAPPER_ROOT)/ace/INET_Addr.h \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.i \ + $(WRAPPER_ROOT)/ace/Reactor.i \ + $(WRAPPER_ROOT)/ace/Svc_Conf_Tokens.h \ + $(WRAPPER_ROOT)/ace/Naming_Context.h \ + $(WRAPPER_ROOT)/ace/SString.h \ + $(WRAPPER_ROOT)/ace/Name_Proxy.h \ + $(WRAPPER_ROOT)/ace/SOCK_Connector.h \ + $(WRAPPER_ROOT)/ace/SOCK_Connector.i \ + $(WRAPPER_ROOT)/ace/Synch_Options.h \ + $(WRAPPER_ROOT)/ace/Name_Request_Reply.h \ + $(WRAPPER_ROOT)/ace/Name_Space.h \ + $(WRAPPER_ROOT)/ace/Dynamic_Service.h \ + Client_Test.h +.obj/main.o .shobj/main.so: main.cpp \ + $(WRAPPER_ROOT)/ace/Service_Config.h \ + $(WRAPPER_ROOT)/ace/Service_Object.h \ + $(WRAPPER_ROOT)/ace/Shared_Object.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/Event_Handler.h \ + $(WRAPPER_ROOT)/ace/Thread_Manager.h \ + $(WRAPPER_ROOT)/ace/Thread.h \ + $(WRAPPER_ROOT)/ace/Synch.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.i \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.i \ + $(WRAPPER_ROOT)/ace/Synch_T.h \ + $(WRAPPER_ROOT)/ace/Set.h \ + $(WRAPPER_ROOT)/ace/Proactor.h \ + $(WRAPPER_ROOT)/ace/Message_Block.h \ + $(WRAPPER_ROOT)/ace/Malloc.h \ + $(WRAPPER_ROOT)/ace/Malloc_T.h \ + $(WRAPPER_ROOT)/ace/Memory_Pool.h \ + $(WRAPPER_ROOT)/ace/Signal.h \ + $(WRAPPER_ROOT)/ace/Mem_Map.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.i \ + $(WRAPPER_ROOT)/ace/ReactorEx.h \ + $(WRAPPER_ROOT)/ace/Token.h \ + $(WRAPPER_ROOT)/ace/Reactor.h \ + $(WRAPPER_ROOT)/ace/Handle_Set.h \ + $(WRAPPER_ROOT)/ace/Pipe.h \ + $(WRAPPER_ROOT)/ace/Pipe.i \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.h \ + $(WRAPPER_ROOT)/ace/SOCK_IO.h \ + $(WRAPPER_ROOT)/ace/SOCK.h \ + $(WRAPPER_ROOT)/ace/Addr.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.i \ + $(WRAPPER_ROOT)/ace/SOCK.i \ + $(WRAPPER_ROOT)/ace/SOCK_IO.i \ + $(WRAPPER_ROOT)/ace/INET_Addr.h \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.i \ + $(WRAPPER_ROOT)/ace/Reactor.i \ + $(WRAPPER_ROOT)/ace/Svc_Conf_Tokens.h \ + $(WRAPPER_ROOT)/ace/Naming_Context.h \ + $(WRAPPER_ROOT)/ace/SString.h \ + $(WRAPPER_ROOT)/ace/Name_Proxy.h \ + $(WRAPPER_ROOT)/ace/SOCK_Connector.h \ + $(WRAPPER_ROOT)/ace/SOCK_Connector.i \ + $(WRAPPER_ROOT)/ace/Synch_Options.h \ + $(WRAPPER_ROOT)/ace/Name_Request_Reply.h \ + $(WRAPPER_ROOT)/ace/Name_Space.h \ + Client_Test.h + +# IF YOU PUT ANYTHING HERE IT WILL GO AWAY diff --git a/netsvcs/clients/Naming/Client/main.cpp b/netsvcs/clients/Naming/Client/main.cpp new file mode 100644 index 00000000000..20e8c53ef7e --- /dev/null +++ b/netsvcs/clients/Naming/Client/main.cpp @@ -0,0 +1,42 @@ +// Test the client-side of the ACE Name Server... +// @(#)main.cpp 1.1 10/18/96 + + +#include "ace/Service_Config.h" +#include "ace/Naming_Context.h" +#include "Client_Test.h" + +int +main (int argc, char *argv[]) +{ + ACE_Service_Config daemon; + + if (daemon.open (argc, argv) == -1) + { + if (errno != ENOENT) + ACE_ERROR ((LM_ERROR, "%p\n%a", "open", 1)); + else // Use static binding. + { + char *l_argv[3]; + l_argv[0] = argv[0]; + l_argv[1] = "-p 10011"; + l_argv[2] = 0; + ACE_Service_Object *so = ACE_SVC_INVOKE (ACE_Naming_Context); + + if (so->init (2, l_argv) == -1) + ACE_ERROR ((LM_ERROR, "%p\n%a", "ACE_Naming_Context", 1)); + + so = ACE_SVC_INVOKE (Client_Test); + + if (so->init (0, l_argv) == -1) + ACE_ERROR ((LM_ERROR, "%p\n%a", "Client_Test", 1)); + } + } + + // Run forever, performing the configured services until we are shut + // down by a SIGINT/SIGQUIT signal. + + ACE_Service_Config::run_reactor_event_loop (); + + return 0; +} diff --git a/netsvcs/clients/Naming/Client/svc.conf b/netsvcs/clients/Naming/Client/svc.conf new file mode 100644 index 00000000000..7625547e8d8 --- /dev/null +++ b/netsvcs/clients/Naming/Client/svc.conf @@ -0,0 +1,6 @@ +# Note that $DB and $PORT are environment variables that are +# automatically interpreted and substituted by ACE! +static ACE_Naming_Context "main -s $DB -p $PORT -h tango" +dynamic Name_Server_test Service_Object * ./libClient_Test.so:_make_Client_Test () +# Note: Client_Test must come after ACE_Naming_Context since it relies +# on the ACE_Naming_Context having been linked... diff --git a/netsvcs/clients/Naming/Client/svc2.conf b/netsvcs/clients/Naming/Client/svc2.conf new file mode 100644 index 00000000000..41075e1bf29 --- /dev/null +++ b/netsvcs/clients/Naming/Client/svc2.conf @@ -0,0 +1,9 @@ +# Note that $DB and $PORT are environment variables that are +# automatically interpreted and substituted by ACE! In addition, note +# how you can give a relative name for the libACE_svcs.so and ACE will +# locate this for you automatically by reading your LD search path! +dynamic ACE_Naming_Context Service_Object * libACE.so:_make_ACE_Naming_Context () "main -s $DB" +dynamic ACE_Naming_Context2 Service_Object * libACE.so:_make_ACE_Naming_Context () "main -s $DB" +dynamic Name_Server_test Service_Object * .shobj/Client_Test.so:_make_Client_Test () +# Note: Client_Test must come after ACE_Naming_Context since it relies +# on the ACE_Naming_Context having been dynamically linked. diff --git a/netsvcs/clients/Naming/Dump_Restore/Dump_Restore.cpp b/netsvcs/clients/Naming/Dump_Restore/Dump_Restore.cpp new file mode 100644 index 00000000000..91617d11662 --- /dev/null +++ b/netsvcs/clients/Naming/Dump_Restore/Dump_Restore.cpp @@ -0,0 +1,388 @@ +#include <fstream.h> +// @(#)Dump_Restore.cpp 1.1 10/18/96 + +#include "ace/Service_Config.h" +#include "ace/Read_Buffer.h" +#include "Dump_Restore.h" + +Dump_Restore::Dump_Restore (int argc, char *argv[]) + : infile_ (0) +{ + ACE_NEW (this->ns_context_, ACE_Naming_Context); + + // Cache the name options + this->name_options_ = this->ns_context_->name_options (); + this->name_options_->parse_args (argc, argv); + + //determine name context + if (ACE_OS::strcmp (this->name_options_->nameserver_host (), "localhost") == 0) + { + if (ns_context_->open (ACE_Naming_Context::PROC_LOCAL) == -1) + ACE_ERROR ( (LM_ERROR, "%p\n", "ns_context_->open")); + } + else + { + // Don't really need to do this but it's a hack to fix + // the problme of Display () not printing the right hostname + ACE_OS::strcpy (this->hostname_, + this->name_options_->nameserver_host ()); + this->port_ = this->name_options_->nameserver_port (); + + if (this->ns_context_->open (ACE_Naming_Context::NET_LOCAL) == -1) + ACE_ERROR ((LM_ERROR, "%p\n", "ns_context_->open")); + } + + this->display_menu (); + + if (ACE::register_stdin_handler (this, + ACE_Service_Config::reactor (), + ACE_Service_Config::thr_mgr ()) == -1) + ACE_ERROR ((LM_ERROR, "%p\n", "register_stdin_handler")); +} + +Dump_Restore::~Dump_Restore (void) +{ + // Deregister this handler with the ACE_Reactor. + ACE_Service_Config::reactor ()->remove_handler + (ACE_STDIN, + ACE_Event_Handler::DONT_CALL | ACE_Event_Handler::READ_MASK); + + ACE_OS::fclose (this->infile_); +} + +int +Dump_Restore::handle_input (ACE_HANDLE) +{ + char option[BUFSIZ]; + char buf1[BUFSIZ]; + char buf2[BUFSIZ]; + char buf3[BUFSIZ]; + char *temp_buf; + int port; + char input[256]; + + if (::scanf ("%s", option) <= 0) + { + cerr << "try again" << endl; + return 0; + } + + int result = -1; + switch (option[0]) + { + case 'P' : + case 'p' : + result = set_proc_local (); + break; + case 'N' : + case 'n' : + result = set_node_local (); + break; + case 'H' : + case 'h' : + if (::scanf ("%s %d", buf1, &port) <= 0) + break; + result = set_host (buf1, port); + break; + case 'F': + case 'f': + if (::scanf ("%s", filename_) <= 0) + break; + if (this->infile_) + ACE_OS::fclose (this->infile_); + this->infile_ = fopen(filename_,"r"); + break; + case 'B' : + case 'b' : + result = populate (Dump_Restore::BIND); + break; + case 'U' : + case 'u' : + result = populate (Dump_Restore::UNBIND); + break; + case 'R' : + case 'r' : + result = populate (Dump_Restore::REBIND); + break; + case 'D': + case 'd': + if (::scanf ("%s", dump_filename_) <= 0) + break; + this->dump (); + break; + case 'Q' : + case 'q' : + result = quit (); + break; + default : + cout << "Unrecognized command." << endl; + } +// if (result == 0) +// cout << "Last operation was successful!" << endl; +// else +// cout << "Last operation returned: " << result << endl; + + display_menu (); + return 0; +} + +void +Dump_Restore::display_menu (void) +{ + cout << endl; + cout << " Name Service Main Menu" << endl; + cout << " ----------------------" << endl; + + // Check if using local name space or remote name space + if (ACE_OS::strcmp (this->name_options_->nameserver_host (), "localhost") == 0) + { + if (this->ns_scope_ == ACE_Naming_Context::PROC_LOCAL) + cout << " *** Using Process Local Database ***" << endl << endl; + else + cout << " *** Using Node Local Database ***" << endl << endl; + } + else + { + cout << " Hostname: " << this->hostname_; + cout << " Port Number: " << this->port_ << endl << endl; + } + if (this->infile_) + cout << "Input File: " << filename_ << endl << endl; + else + cout << "** No Input File Specified **" << endl; + cout << "<P> Use Process Local Database" << endl; + cout << "<N> Use Node Local Database" << endl; + cout << "<H> Set Remote Name server <host> and <port>" << endl; + cout << "<F> Set Input File <file name>" << endl << endl; + cout << "<B> Bind" << endl; + cout << "<U> Unbind" << endl; + cout << "<R> Rebind" << endl; + cout << "<D> Dump <file name>" << endl; + cout << "<Q> or ^C (exit) " << endl; +} + + +int +Dump_Restore::set_proc_local (void) +{ + // Set Name Options + this->name_options_->nameserver_host ("localhost"); + this->name_options_->nameserver_port (0); + + // Set Naming Context scope + this->ns_scope_ = ACE_Naming_Context::PROC_LOCAL; + + // Remove old naming context + delete this->ns_context_; + + // Create new Naming Context + ACE_NEW_RETURN (this->ns_context_, ACE_Naming_Context, -1); + + if (this->ns_context_->open (ACE_Naming_Context::PROC_LOCAL) == -1) + ACE_ERROR_RETURN ( (LM_ERROR, "%p\n", "ns_context_->open"), -1); + + return 0; +} + +int +Dump_Restore::set_node_local (void) +{ + // Set Name Options + this->name_options_->nameserver_host ("localhost"); + this->name_options_->nameserver_port (0); + + // Set Naming Context scope + this->ns_scope_ = ACE_Naming_Context::NODE_LOCAL; + + // Remove old naming context + delete this->ns_context_; + + // Create new Naming Context + ACE_NEW_RETURN (this->ns_context_, ACE_Naming_Context, -1); + + if (ns_context_->open (ACE_Naming_Context::NODE_LOCAL) == -1) + ACE_ERROR_RETURN ( (LM_ERROR, "%p\n", "ns_context_->open"), -1); + return 0; +} + +int +Dump_Restore::set_host (char* hostname, int port) +{ + // Set Name Options + this->name_options_->nameserver_host (hostname); + this->name_options_->nameserver_port (port); + + // don't really need to do this but it's a hack to fix + // the problme of Display () not printing the right hostname + ACE_OS::strcpy (this->hostname_, hostname); + this->port_ = port; + this->ns_scope_ = ACE_Naming_Context::NET_LOCAL; + + // remove old naming context + delete this->ns_context_; + + // Create new Naming Context + ACE_NEW_RETURN (this->ns_context_, ACE_Naming_Context, -1); + + // assume net_local context + if (ns_context_->open (ACE_Naming_Context::NET_LOCAL) == -1) + ACE_ERROR_RETURN ( (LM_ERROR, "%p\n", "ns_context_->open"), -1); + + return 0; +} + +int +Dump_Restore::doit (Dump_Restore::Operation_Type op, + char *name, + char* value, + char* type) +{ + int result = -1; + + switch (op) + { + case Dump_Restore::BIND: + { + result = this->bind (name, value, type); + break; + } + case Dump_Restore::UNBIND: + { + result = this->unbind (name); + break; + } + case Dump_Restore::REBIND: + { + result = this->rebind (name, value, type); + break; + } + } + + return result; +} + +int +Dump_Restore::populate (Dump_Restore::Operation_Type op) +{ + if (this->infile_) + { + int result = -1; + enum State { NAME, VALUE, TYPE }; + + State state = NAME; + // reset file pointer + ACE_OS::rewind (this->infile_); + + ACE_Allocator *allocator = ACE_Service_Config::allocator (); + ACE_Read_Buffer read_buffer (this->infile_, 0, allocator); + + for (char *temp; (temp = read_buffer.read ('\n')) != 0; ) + { + char *name = 0; + char *actual_name = 0; + char *value = 0; + char *actual_value = 0; + char *type = 0; + char *actual_type = 0; + + switch (state) + { + case NAME: + name = temp; + ACE_OS::strtok (name, "="); + actual_name = ACE_OS::strtok (0, "="); + state = VALUE; + break; + case VALUE: + value = temp; + ACE_OS::strtok (value, "="); + actual_value = ACE_OS::strtok (0, "="); + state = TYPE; + break; + case TYPE: + type = temp; + ACE_OS::strtok (type, "="); + actual_type = ACE_OS::strtok (0, "="); + + if (actual_type) + result = this->doit (op, + actual_name, + actual_value, + actual_type); + else + result = this->doit (op, + actual_name, + actual_value); + if (name) + allocator->free(name); + if (value) + allocator->free(value); + if (type) + allocator->free(type); + state = NAME; + break; + default: + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "populate"), -1); + break; + } + } + + return result; + } + else + return -1; +} + +int +Dump_Restore::bind (char* key, char* value, char* type) +{ + int result = ns_context_->bind (key, value, type); + + if (result == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "ns_context_->bind"), -1); + else if (result == 1) + ACE_ERROR_RETURN ((LM_ERROR, "%s%s%s\n", "key <", key, "> already bound"), 1); + return 0; +} + +int +Dump_Restore::unbind (char* key) +{ + int result = ns_context_->unbind (key); + + if (result == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "ns_context_->unbind"), -1); + + return 0; +} + +int +Dump_Restore::rebind (char* key, char* value, char* type) +{ + if (ns_context_->rebind (key, value, type) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "ns_context_->rebind"), -1); + + return 0; +} + +int +Dump_Restore::quit (void) +{ + return ACE_OS::kill (ACE_OS::getpid (), SIGINT); +} + +void +Dump_Restore::dump (void) +{ + ofstream output_file (dump_filename_); + + ostream *orig_stream = ACE_Log_Msg::instance ()->msg_ostream (); + ACE_Log_Msg::instance ()->msg_ostream (&output_file); + ACE_Log_Msg::instance ()->clr_flags (ACE_Log_Msg::STDERR | ACE_Log_Msg::LOGGER ); + ACE_Log_Msg::instance ()->set_flags (ACE_Log_Msg::OSTREAM); + + ns_context_->dump (); + + ACE_Log_Msg::instance ()->msg_ostream (orig_stream); + ACE_Log_Msg::instance ()->clr_flags (ACE_Log_Msg::STDERR); +} diff --git a/netsvcs/clients/Naming/Dump_Restore/Dump_Restore.h b/netsvcs/clients/Naming/Dump_Restore/Dump_Restore.h new file mode 100644 index 00000000000..218e842f2e9 --- /dev/null +++ b/netsvcs/clients/Naming/Dump_Restore/Dump_Restore.h @@ -0,0 +1,74 @@ +/* -*- C++ -*- */ +// @(#)Dump_Restore.h 1.1 10/18/96 + +#include "ace/Event_Handler.h" +#include "ace/Reactor.h" +#include "ace/Naming_Context.h" + +class Dump_Restore : public ACE_Event_Handler +{ +public: + enum Operation_Type + { + BIND, + UNBIND, + REBIND + }; + Dump_Restore (int argc, char *argv[]); + // Initialize name options and naming context + + ~Dump_Restore (void); + + virtual int handle_input (ACE_HANDLE handle); + // Handle user entered commands + + void dump (void); + +private: + char hostname_[MAXHOSTNAMELEN + 1]; + // Cache the hostname and port number for remote case + + void display_menu (void); + // Display user menu. + + int set_proc_local (void); + // Set options to use PROC_LOCAL naming context. + + int set_node_local (void); + // Set options to use NODE_LOCAL naming context. + + int set_host (char* hostname, int port); + // Set options to use NET_LOCAL naming context specifying host name + // and port number. + + int quit (void); + // Gracefully exit. + + int populate (Dump_Restore::Operation_Type op); + + int doit (Dump_Restore::Operation_Type op, + char *name, + char *value, + char *type = ""); + int bind (char* key, char* value, char* type = ""); + int unbind (char* key); + int rebind (char* key, char* value, char* type = ""); + + char filename_[MAXPATHLEN]; + char dump_filename_[MAXPATHLEN]; + + u_short port_; + // port server is listening on + + ACE_Naming_Context *ns_context_; + // Current naming context + + ACE_Naming_Context::Context_Scope_Type ns_scope_; + // Defines the scope of the naming context + + FILE *infile_; + // input file + + ACE_Name_Options *name_options_; + // Name Options associated with the Naming Context +}; diff --git a/netsvcs/clients/Naming/Dump_Restore/Makefile b/netsvcs/clients/Naming/Dump_Restore/Makefile new file mode 100644 index 00000000000..62b517b4e40 --- /dev/null +++ b/netsvcs/clients/Naming/Dump_Restore/Makefile @@ -0,0 +1,176 @@ +#---------------------------------------------------------------------------- +# @(#)Makefile 1.1 10/18/96 +# +# Makefile for the ACE Dump-Restore Name_Server utility +#---------------------------------------------------------------------------- + +#---------------------------------------------------------------------------- +# Local macros +#---------------------------------------------------------------------------- + +BIN = main +LIB = libDump_Restore.a +SHLIB = libDump_Restore.so + +FILES = Dump_Restore + +SRC = $(addsuffix .cpp,$(BIN)) +OBJ = $(SRC:%.cpp=$(VDIR)%.o) + +LSRC = $(addsuffix .cpp,$(FILES)) +LOBJ = $(LSRC:%.cpp=$(VDIR)%.o) +SHOBJ = $(addsuffix .so,$(FILES)) + +LDLIBS = -lDump_Restore +LIBS += -lACE + +VLDLIBS = $(LDLIBS:%=%$(VAR)) + +BUILD = $(VLIB) $(VSHLIB) $(SHLIBA) $(VBIN) + +#---------------------------------------------------------------------------- +# Include macros and targets +#---------------------------------------------------------------------------- + +include $(WRAPPER_ROOT)/include/makeinclude/wrapper_macros.GNU +include $(WRAPPER_ROOT)/include/makeinclude/macros.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.common.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.nonested.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.lib.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.bin.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.local.GNU + +#---------------------------------------------------------------------------- +# Local targets +#---------------------------------------------------------------------------- + +#---------------------------------------------------------------------------- +# Dependencies +#---------------------------------------------------------------------------- +# DO NOT DELETE THIS LINE -- g++dep uses it. +# DO NOT PUT ANYTHING AFTER THIS LINE, IT WILL GO AWAY. + +.obj/Dump_Restore.o .shobj/Dump_Restore.so: Dump_Restore.cpp \ + $(WRAPPER_ROOT)/ace/Service_Config.h \ + $(WRAPPER_ROOT)/ace/Service_Object.h \ + $(WRAPPER_ROOT)/ace/Shared_Object.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/Event_Handler.h \ + $(WRAPPER_ROOT)/ace/Thread_Manager.h \ + $(WRAPPER_ROOT)/ace/Thread.h \ + $(WRAPPER_ROOT)/ace/Synch.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.i \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.i \ + $(WRAPPER_ROOT)/ace/Synch_T.h \ + $(WRAPPER_ROOT)/ace/Set.h \ + $(WRAPPER_ROOT)/ace/Proactor.h \ + $(WRAPPER_ROOT)/ace/Message_Block.h \ + $(WRAPPER_ROOT)/ace/Malloc.h \ + $(WRAPPER_ROOT)/ace/Malloc_T.h \ + $(WRAPPER_ROOT)/ace/Memory_Pool.h \ + $(WRAPPER_ROOT)/ace/Signal.h \ + $(WRAPPER_ROOT)/ace/Mem_Map.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.i \ + $(WRAPPER_ROOT)/ace/ReactorEx.h \ + $(WRAPPER_ROOT)/ace/Token.h \ + $(WRAPPER_ROOT)/ace/Reactor.h \ + $(WRAPPER_ROOT)/ace/Handle_Set.h \ + $(WRAPPER_ROOT)/ace/Pipe.h \ + $(WRAPPER_ROOT)/ace/Pipe.i \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.h \ + $(WRAPPER_ROOT)/ace/SOCK_IO.h \ + $(WRAPPER_ROOT)/ace/SOCK.h \ + $(WRAPPER_ROOT)/ace/Addr.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.i \ + $(WRAPPER_ROOT)/ace/SOCK.i \ + $(WRAPPER_ROOT)/ace/SOCK_IO.i \ + $(WRAPPER_ROOT)/ace/INET_Addr.h \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.i \ + $(WRAPPER_ROOT)/ace/Reactor.i \ + $(WRAPPER_ROOT)/ace/Svc_Conf_Tokens.h \ + $(WRAPPER_ROOT)/ace/Read_Buffer.h \ + $(WRAPPER_ROOT)/ace/Read_Buffer.i \ + Dump_Restore.h \ + $(WRAPPER_ROOT)/ace/Naming_Context.h \ + $(WRAPPER_ROOT)/ace/SString.h \ + $(WRAPPER_ROOT)/ace/Name_Proxy.h \ + $(WRAPPER_ROOT)/ace/SOCK_Connector.h \ + $(WRAPPER_ROOT)/ace/SOCK_Connector.i \ + $(WRAPPER_ROOT)/ace/Synch_Options.h \ + $(WRAPPER_ROOT)/ace/Name_Request_Reply.h \ + $(WRAPPER_ROOT)/ace/Name_Space.h +.obj/main.o .shobj/main.so: main.cpp \ + $(WRAPPER_ROOT)/ace/Service_Config.h \ + $(WRAPPER_ROOT)/ace/Service_Object.h \ + $(WRAPPER_ROOT)/ace/Shared_Object.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/Event_Handler.h \ + $(WRAPPER_ROOT)/ace/Thread_Manager.h \ + $(WRAPPER_ROOT)/ace/Thread.h \ + $(WRAPPER_ROOT)/ace/Synch.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.i \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.i \ + $(WRAPPER_ROOT)/ace/Synch_T.h \ + $(WRAPPER_ROOT)/ace/Set.h \ + $(WRAPPER_ROOT)/ace/Proactor.h \ + $(WRAPPER_ROOT)/ace/Message_Block.h \ + $(WRAPPER_ROOT)/ace/Malloc.h \ + $(WRAPPER_ROOT)/ace/Malloc_T.h \ + $(WRAPPER_ROOT)/ace/Memory_Pool.h \ + $(WRAPPER_ROOT)/ace/Signal.h \ + $(WRAPPER_ROOT)/ace/Mem_Map.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.i \ + $(WRAPPER_ROOT)/ace/ReactorEx.h \ + $(WRAPPER_ROOT)/ace/Token.h \ + $(WRAPPER_ROOT)/ace/Reactor.h \ + $(WRAPPER_ROOT)/ace/Handle_Set.h \ + $(WRAPPER_ROOT)/ace/Pipe.h \ + $(WRAPPER_ROOT)/ace/Pipe.i \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.h \ + $(WRAPPER_ROOT)/ace/SOCK_IO.h \ + $(WRAPPER_ROOT)/ace/SOCK.h \ + $(WRAPPER_ROOT)/ace/Addr.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.i \ + $(WRAPPER_ROOT)/ace/SOCK.i \ + $(WRAPPER_ROOT)/ace/SOCK_IO.i \ + $(WRAPPER_ROOT)/ace/INET_Addr.h \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.i \ + $(WRAPPER_ROOT)/ace/Reactor.i \ + $(WRAPPER_ROOT)/ace/Svc_Conf_Tokens.h \ + Dump_Restore.h \ + $(WRAPPER_ROOT)/ace/Naming_Context.h \ + $(WRAPPER_ROOT)/ace/SString.h \ + $(WRAPPER_ROOT)/ace/Name_Proxy.h \ + $(WRAPPER_ROOT)/ace/SOCK_Connector.h \ + $(WRAPPER_ROOT)/ace/SOCK_Connector.i \ + $(WRAPPER_ROOT)/ace/Synch_Options.h \ + $(WRAPPER_ROOT)/ace/Name_Request_Reply.h \ + $(WRAPPER_ROOT)/ace/Name_Space.h + +# IF YOU PUT ANYTHING HERE IT WILL GO AWAY diff --git a/netsvcs/clients/Naming/Dump_Restore/README b/netsvcs/clients/Naming/Dump_Restore/README new file mode 100644 index 00000000000..3bb13935d87 --- /dev/null +++ b/netsvcs/clients/Naming/Dump_Restore/README @@ -0,0 +1,67 @@ +This file describes the usage of the Dump-Restore utility for the ACE +Name Server. + +Similar to the test application provided in the Client-Server +directory, a simple ASCII menu-driven interface is provided to the +user: + + Name Service Main Menu + ---------------------- + *** Using Process Local Database *** + +** No Input File Specified ** +<P> Use Process Local Database +<N> Use Node Local Database +<H> Set Remote Name server <host> and <port> +<F> Set Input File <file name> + +<B> Bind +<U> Unbind +<R> Rebind +<D> Dump <file name> +<Q> or ^C (exit) + +Initially, the user can select the type of database from the menu: + +<P> uses the process local database (i.e., the + database is called the same name as the process + and stored in /tmp). +<N> uses the node local database (which defaults + to /tmp/localnames). +<H> uses the net local database by specifying host and port + number (by default this is stored in a file called + /tmp/globalnames on the server). +<F> Sets the name of the input file that will be used by the + test application to populate the database. The format of + the file should be: + + name=<name1> + value=<value1> + type=[<type1>] + name=<name2> + value=<value2> + type=[<type2>] + . + . + . + + Note that the type field is optional. However, if no type + information is associated with a name binding, a null entry still + needs to be present (i.e., type=). + +Once the input file has been specified, the user can then do one of +the following: + +<B> Bind -- bind all the bindings in the file to the database. + This can be used to "restore" the state of the + Name Server. +<U> Unbind -- unbind all the bindings in the file from the database. +<R> Rebind -- rebind all the bindings in the file to the database. +<D> Dump <file name> -- dump the state of the database to <filename>. +<Q> or ^C (exit) -- exit gracefully, saving the contents of the + Name Server in persistent shared memory. + +Note that the dump file is stored in ASCII with exactly the same +format as the input file. Also, one can easily change the test +application so that a call to Dump results in the state of the +database dumped to standard output instead of a file. diff --git a/netsvcs/clients/Naming/Dump_Restore/createfile.cpp b/netsvcs/clients/Naming/Dump_Restore/createfile.cpp new file mode 100644 index 00000000000..4880cfe7883 --- /dev/null +++ b/netsvcs/clients/Naming/Dump_Restore/createfile.cpp @@ -0,0 +1,32 @@ +#include <stdio.h> +// @(#)createfile.cpp 1.1 10/18/96 + +#include <string.h> +#include <math.h> + +int +main (int argc, char **argv) +{ + FILE *infile, *outfile; + char buf[BUFSIZ]; + + if ((infile = fopen (argv[1], "r")) == NULL) + return -1; + + if ((outfile = fopen (argv[2], "w")) == NULL) + return -1; + + int count = 0; + while (::fgets (buf, BUFSIZ, infile)) + { + buf[::strlen(buf) - 1] = '\0'; + fputs (buf, outfile); + if (count % 2 == 0) + fputs (" ", outfile); + else + fputs ("\n", outfile); + count++; + } + fclose (outfile); + fclose (infile); +} diff --git a/netsvcs/clients/Naming/Dump_Restore/main.cpp b/netsvcs/clients/Naming/Dump_Restore/main.cpp new file mode 100644 index 00000000000..a30b94c6cd3 --- /dev/null +++ b/netsvcs/clients/Naming/Dump_Restore/main.cpp @@ -0,0 +1,22 @@ +// Test the client-side of the ACE Name Server... +// @(#)main.cpp 1.1 10/18/96 + +#include "ace/Service_Config.h" +#include "Dump_Restore.h" + +int +main (int argc, char *argv[]) +{ + ACE_Service_Config daemon (argv[0]); + + ACE_DEBUG ((LM_DEBUG, "entering main\n")); + + // Get a handler + Dump_Restore client_handler (argc, argv); + + for (;;) + daemon.run_reactor_event_loop (); + + ACE_DEBUG ((LM_DEBUG, "leaving main\n")); + return 0; +} diff --git a/netsvcs/clients/Naming/Dump_Restore/nametest.cpp b/netsvcs/clients/Naming/Dump_Restore/nametest.cpp new file mode 100644 index 00000000000..d5347b7206a --- /dev/null +++ b/netsvcs/clients/Naming/Dump_Restore/nametest.cpp @@ -0,0 +1,112 @@ +#include "ace/Naming_Context.h" +// @(#)nametest.cpp 1.1 10/18/96 + +#include "ace/Name_Options.h" +#include "nametest.h" + +void +Nametest::listopt (void) +{ + cout << "serverport is " + << ACE_Name_Options::instance ()->nameserver_port() + << endl; + cout << "serverhost is " + << ACE_Name_Options::instance ()->nameserver_host() + << endl; + cout << "process_name is " + << ACE_Name_Options::instance ()->process_name() + << endl; + cout << "namespace_dir is " + << ACE_Name_Options::instance ()->namespace_dir() + << endl; +} + +int +Nametest::init (int argc, char *argv[]) +{ + ACE_Server_Record *sr; + ACE_Service_Config::svc_rep ()->find ("Name_Server_Proxy", &sr); + ACE_Service_Type *st = sr->type (); + ACE_Server_Object *so = st->object (); +dynamic_cast<ACE_Name_Server_Proxy *> (so); + + ACE_Name_Server_Proxy *ns_proxy = ACE_Service_Config::name_server_proxy (); + + ns_proxy->bind (...); + + this->listopt (); + + ACE_Naming_Context ns_context; + + if (ns_context.open (ACE_Naming_Context::NET_LOCAL) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "ns_context.open"), -1); + + const char *mykey = argv[0]; + char *myvalue = argv[1]; + char *ns_value = 0; + char *ns_type = 0; + + if (ns_context.bind (mykey, myvalue, "ottotype") == -1) + cout << "bind failed" << endl; + else + cout << "bind succeeded" << endl; + + + if (ns_context.resolve (mykey, ns_value, ns_type) == -1) + cout << "resolve of " << mykey << " failed" << endl; + else + cout << "resolve of " << mykey << " succeeded, value = " + << ns_value << ", type = " << ns_type << endl; + + delete [] ns_value; + delete [] ns_type; + ns_value = 0; + ns_type = 0; + + if (ns_context.rebind (mykey, myvalue, "newottotype") == -1) + cout << "rebind failed" << endl; + else + cout << "rebind succeeded" << endl; + + if (ns_context.resolve (mykey, ns_value, ns_type) == -1) + cout << "resolve of " << mykey << " failed" << endl; + else + cout << "resolve of " << mykey << " succeeded, value = " + << ns_value << ", type = " << ns_type << endl; + + delete [] ns_value; + delete [] ns_type; + ns_value = 0; + ns_type = 0; + + if (ns_context.unbind (mykey) == -1) + cout << "unbind failed" << endl; + else + cout << "unbind succeeded" << endl; + + return 0; +} + +int +Nametest::fini (void) +{ + cout << "Nametest::fini called" << endl; + return 0; +} + +int +Nametest::info (char **, unsigned) const +{ + cout << "Nametest::info called" << endl; + return 0; +} + +extern "C" ACE_Service_Object *_alloc(void); + +// Factory function that is called automatically when the ACE +// framework dynamically links this shared object file. + +ACE_Service_Object *_alloc (void) +{ + return new Nametest; +} diff --git a/netsvcs/clients/Naming/Dump_Restore/nametest.h b/netsvcs/clients/Naming/Dump_Restore/nametest.h new file mode 100644 index 00000000000..423f2ea1a5c --- /dev/null +++ b/netsvcs/clients/Naming/Dump_Restore/nametest.h @@ -0,0 +1,15 @@ +/* -*- C++ -*- */ +// @(#)nametest.h 1.1 10/18/96 + +#include "ace/Service_Object.h" + +class Nametest : public ACE_Service_Object +{ +public: + virtual int init (int argc, char *argv[]); + virtual int fini (void); + virtual int info (char **, size_t) const; + + void listopt (void); +}; + diff --git a/netsvcs/clients/Naming/Makefile b/netsvcs/clients/Naming/Makefile new file mode 100644 index 00000000000..db15cce1cf5 --- /dev/null +++ b/netsvcs/clients/Naming/Makefile @@ -0,0 +1,25 @@ +#---------------------------------------------------------------------------- +# @(#)Makefile 1.1 10/18/96 +# +# Makefile for the Name Server test applications +#---------------------------------------------------------------------------- + +#---------------------------------------------------------------------------- +# Local macros +#---------------------------------------------------------------------------- + +INFO = README + +DIRS = Client \ + Dump_Restore + +#---------------------------------------------------------------------------- +# Include macros and targets +#---------------------------------------------------------------------------- + +include $(WRAPPER_ROOT)/include/makeinclude/wrapper_macros.GNU +include $(WRAPPER_ROOT)/include/makeinclude/macros.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.common.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.nested.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.nolocal.GNU + diff --git a/netsvcs/clients/Naming/README b/netsvcs/clients/Naming/README new file mode 100644 index 00000000000..7249a2b23c0 --- /dev/null +++ b/netsvcs/clients/Naming/README @@ -0,0 +1,124 @@ +This directory contains a set of tests for the ACE_Name_Server +library. There are two directories -- client and server, which test +the client and server, respectively. In addition, these tests +illustrate how to use the ACE Service_Config mechanism, which enables +the client and server code to be dynamically linked into the process +at installation-time or run-time! + +The client test is an application that allows the user to vary the +test parameters through the following menu driven interface: + + Name Service Main Menu + ---------------------- + *** Using Process Local Database *** + +<P> Use Process Local Database +<N> Use Node Local Database +<H> Set Remote Name server <host> and <port> + +<B> Bind <key> <value> [<type>] +<U> Unbind <key> +<R> Rebind <key> <value> [<type>] +<F> Find <key> +<J> Lookup keys matching <pattern> +<K> Lookup values matching <pattern> +<L> Lookup types matching <pattern> +<C> Complete lookup keys matching <pattern> +<D> Complete lookup values matching <pattern> +<E> Complete lookup types matching <pattern> + +<Q> or ^C (exit) + +Initially, the user can select the type of database -- process local, +node local, or net local -- from the menu. + +<P> uses the process local database (i.e., the database is called the + same name as the process and stored in /tmp). +<N> uses the node local database (which defaults to /tmp/localnames). +<H> uses the net local database by specifying host and port number (by + default this is stored in a file called /tmp/globalnames on the server). + +The user can then create new bindings, delete existing bindings, or +rebind bindings: + +<B> Bind <key> <value> [<type>] + -- binds the key to the value and adds the + binding to the database. Note that type + information is optional. +<U> Unbind <key> -- unbind a binding whose key is <key> +<R> Rebind <key> <value> [<type>] + -- rebind <key> to <value>. Once again <type> is optional. +<F> Find <key> -- find the binding associated with key <key> +<Q> or ^C (exit) -- exit gracefully, saving the contents of the + Name Server in persistent shared memory. + +In addition, the user can do pattern matching for keys, values, and +types. Note that pattern matching is supported using regular expressions. + +<J> Lookup keys matching <pattern> + -- find all keys that match <pattern> +<K> Lookup values matching <pattern> + -- find all values that match <pattern> +<L> Lookup types matching <pattern> + -- find all types that match <pattern> + +<C> Complete lookup keys matching <pattern> + -- find all bindings whose keys match <pattern> +<D> Complete lookup values matching <pattern> + -- find all bindings whose values match <pattern> +<E> Complete lookup types matching <pattern> + -- find all bindings whose types match <pattern> + +------------------------- +Running the tests: + +Both the client and the server test programs use DLL supported by +svc.conf which allows them to configure the client-side and the +server-side (respectively) dynamically. The client test program +accomplishes this by making use of a Singleton proxy object +(Name_Service) to provide an interface to the client-side. + +The test programs rely on svc.conf to provide the necessary parameters +for dynamically linking the Name Service library and then +executing. In the absence of svc.conf, the test programs would use +static binding. + +client: + +The client test can be started without any parameters. However, if the +user wants to use the net local database, the hostname and the port +number of the server containing the net local database can be given at +"command line" in the svc.conf file, e.g.: + +dynamic ACE_Naming_Context Service_Object * libACE.so:_make_ACE_Naming_Context () + "main -h tango.cs -p 7891" +dynamic Name_Server_test Service_Object * .shobj/Client_Test.so:_make_Client_Test () "" + +The above example starts the client test application and sets up a +connection to port 7891 to a Name Server running on tango.cs, which +has the net local database. The Client_Test directive must come after +ACE_Naming_Context since it relies on the ACE_Naming_Context having +been dynamically linked. + +Note that you can also use environment variables in the "command +line", as follows: + +dynamic ACE_Naming_Context Service_Object * libACE.so:_make_ACE_Naming_Context () + "main -s $DB -p $PORT -h tango" +dynamic Name_Server_test Service_Object * .shobj/Client_Test.so:_make_Client_Test () "" + +In this example, $DB and $PORT are environment variables that are +automatically interpreted and substituted by ACE. In addition, note +how you can give a relative name for the libACE_svcs.so and ACE will +locate this for you automatically by reading your LD search path. + +server: + +The name server is needed only in the case where the net local +database needs to be accessed. The server test needs to run on the +machine that contains the net local database. To execute the server +test, the user has to specify the port number at which the server will +be listening in the svc.conf file. An implementation of a name +service for ACE is available in the $WRAPPER_ROOT/netsvcs/bin +directory. Please see the README file there for an explanation of how +to run the server. diff --git a/netsvcs/clients/README b/netsvcs/clients/README new file mode 100644 index 00000000000..d47c9bfe7ff --- /dev/null +++ b/netsvcs/clients/README @@ -0,0 +1,8 @@ +This directory contains a number of test programs that illustrate how +to write clients for the various ACE network services. + + . Logger -- client programs that illustrate the ACE logging service. + + . Naming -- client programs that illustrate the ACE name service. + + . Tokens -- client programs that illustrate the ACE token service. diff --git a/netsvcs/clients/Tokens/Makefile b/netsvcs/clients/Tokens/Makefile new file mode 100644 index 00000000000..051e0b90dae --- /dev/null +++ b/netsvcs/clients/Tokens/Makefile @@ -0,0 +1,26 @@ +#---------------------------------------------------------------------------- +# @(#)Makefile 1.1 10/18/96 +# +# Makefile for the Token tests +#---------------------------------------------------------------------------- + +#---------------------------------------------------------------------------- +# Local macros +#---------------------------------------------------------------------------- + +DIRS = collection \ + deadlock \ + invariant \ + manual \ + mutex \ + rw_lock + +#---------------------------------------------------------------------------- +# Include macros and targets +#---------------------------------------------------------------------------- + +include $(WRAPPER_ROOT)/include/makeinclude/wrapper_macros.GNU +include $(WRAPPER_ROOT)/include/makeinclude/macros.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.common.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.nested.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.nolocal.GNU diff --git a/netsvcs/clients/Tokens/README b/netsvcs/clients/Tokens/README new file mode 100644 index 00000000000..3b6313a1df7 --- /dev/null +++ b/netsvcs/clients/Tokens/README @@ -0,0 +1,34 @@ +This directory contains a set of tests for the ACE Tokens library. + + . mutex + + Runs a few tests on ACE_Local_Mutex and + ACE_Remote_Mutex. Tests recursive acquisition and + global vs local proxies. + + . rw_locks + + App for testing ACE_Local_RLock, ACE_Local_WLock, + ACE_Remote_RLock, and ACE_Remote_WLock. + + . deadlock + + Tests the deadlock detection algorithm of the token + manager using ACE_Local_Mutex and ACE_Remote_Mutex. + + . collection + + Tests the ACE_Token_Collection utility. Uses local + and remote tokens and readers/writer locks. + + . invariant + + Tests the token Invariant testing utilities. Yes, + this tests a testing utility. + + . manual + + Gives users a text-based interactive interface to + local or remote tokens. This is extremely useful for + manually testing the token server and setting up + deadlock scenarios. diff --git a/netsvcs/clients/Tokens/collection/Makefile b/netsvcs/clients/Tokens/collection/Makefile new file mode 100644 index 00000000000..76090600a11 --- /dev/null +++ b/netsvcs/clients/Tokens/collection/Makefile @@ -0,0 +1,108 @@ +#---------------------------------------------------------------------------- +# @(#)Makefile 1.1 10/18/96 +# +# Makefile for repeating token client application +#---------------------------------------------------------------------------- + +#---------------------------------------------------------------------------- +# Local macros +#---------------------------------------------------------------------------- + +BIN = collection + +FILES = collection + +LSRC = $(addsuffix .cpp,$(FILES)) +LOBJ = $(LSRC:%.cpp=$(VDIR)%.o) +SHOBJ = $(addsuffix .so,$(FILES)) + +BUILD = $(VBIN) + +#---------------------------------------------------------------------------- +# Include macros and targets +#---------------------------------------------------------------------------- + +include $(WRAPPER_ROOT)/include/makeinclude/wrapper_macros.GNU +include $(WRAPPER_ROOT)/include/makeinclude/macros.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.common.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.nonested.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.lib.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.bin.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.local.GNU + +#---------------------------------------------------------------------------- +# Local targets +#---------------------------------------------------------------------------- + +#---------------------------------------------------------------------------- +# Dependencies +#---------------------------------------------------------------------------- + +# IF YOU PUT ANYTHING HERE IT WILL GO AWAY +# DO NOT DELETE THIS LINE -- g++dep uses it. +# DO NOT PUT ANYTHING AFTER THIS LINE, IT WILL GO AWAY. + +.obj/collection.o .shobj/collection.so: collection.cpp \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/Get_Opt.h \ + $(WRAPPER_ROOT)/ace/Local_Tokens.h \ + $(WRAPPER_ROOT)/ace/Synch.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.i \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.i \ + $(WRAPPER_ROOT)/ace/Synch_T.h \ + $(WRAPPER_ROOT)/ace/Event_Handler.h \ + $(WRAPPER_ROOT)/ace/Stack.h \ + $(WRAPPER_ROOT)/ace/Synch_Options.h \ + $(WRAPPER_ROOT)/ace/Map_Manager.h \ + $(WRAPPER_ROOT)/ace/Token_Collection.h \ + $(WRAPPER_ROOT)/ace/SString.h \ + $(WRAPPER_ROOT)/ace/Remote_Tokens.h \ + $(WRAPPER_ROOT)/ace/INET_Addr.h \ + $(WRAPPER_ROOT)/ace/Addr.h \ + $(WRAPPER_ROOT)/ace/SOCK_Connector.h \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.h \ + $(WRAPPER_ROOT)/ace/SOCK_IO.h \ + $(WRAPPER_ROOT)/ace/SOCK.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.i \ + $(WRAPPER_ROOT)/ace/SOCK.i \ + $(WRAPPER_ROOT)/ace/SOCK_IO.i \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.i \ + $(WRAPPER_ROOT)/ace/SOCK_Connector.i \ + $(WRAPPER_ROOT)/ace/Token_Request_Reply.h \ + $(WRAPPER_ROOT)/ace/Thread_Manager.h \ + $(WRAPPER_ROOT)/ace/Thread.h \ + $(WRAPPER_ROOT)/ace/Service_Config.h \ + $(WRAPPER_ROOT)/ace/Service_Object.h \ + $(WRAPPER_ROOT)/ace/Shared_Object.h \ + $(WRAPPER_ROOT)/ace/Set.h \ + $(WRAPPER_ROOT)/ace/Proactor.h \ + $(WRAPPER_ROOT)/ace/Message_Block.h \ + $(WRAPPER_ROOT)/ace/Malloc.h \ + $(WRAPPER_ROOT)/ace/Malloc_T.h \ + $(WRAPPER_ROOT)/ace/Memory_Pool.h \ + $(WRAPPER_ROOT)/ace/Signal.h \ + $(WRAPPER_ROOT)/ace/Mem_Map.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.i \ + $(WRAPPER_ROOT)/ace/ReactorEx.h \ + $(WRAPPER_ROOT)/ace/Token.h \ + $(WRAPPER_ROOT)/ace/Reactor.h \ + $(WRAPPER_ROOT)/ace/Handle_Set.h \ + $(WRAPPER_ROOT)/ace/Pipe.h \ + $(WRAPPER_ROOT)/ace/Pipe.i \ + $(WRAPPER_ROOT)/ace/Reactor.i \ + $(WRAPPER_ROOT)/ace/Svc_Conf_Tokens.h + +# IF YOU PUT ANYTHING HERE IT WILL GO AWAY diff --git a/netsvcs/clients/Tokens/collection/README b/netsvcs/clients/Tokens/collection/README new file mode 100644 index 00000000000..4c25a1f729e --- /dev/null +++ b/netsvcs/clients/Tokens/collection/README @@ -0,0 +1,25 @@ + +Shows how applications can use the ACE_Token_Collection utility. This +example creates three collections and spawns a thread to operate on +each. The threads use the collective acquire, renew, and release +features of ACE_Token_Collection. + +Here are the command-line parameters for collection: + +./collection: +[-h <remote host>] +[-p <remote port>] +[-n <iterations>] +[-d debug] + +To run the collection locally with debugging info, type + +% ./collection -d + +To run the collection remotely with debugging info, first start a +token server and the type: + +% ./collection -d -h <token-server-host> -p <token-server-port> + +The -n <iterations> option is to control how often each thread +iterates on the acquire, renew, release cycle. diff --git a/netsvcs/clients/Tokens/collection/collection.cpp b/netsvcs/clients/Tokens/collection/collection.cpp new file mode 100644 index 00000000000..797546f3f92 --- /dev/null +++ b/netsvcs/clients/Tokens/collection/collection.cpp @@ -0,0 +1,217 @@ +// ============================================================================ +// @(#)collection.cpp 1.1 10/18/96 + +// +// = LIBRARY +// examples +// +// = FILENAME +// collection.cpp +// +// = DESCRIPTION +// Shows how applications can use the ACE_Token_Collection +// utility. This example creates three collections and spawns a +// thread to operate on each. The threads use the collective +// acquire, renew, and release features of ACE_Token_Collection. +// +// = AUTHOR +// Tim Harrison +// +// ============================================================================ + +#include "ace/OS.h" +#include "ace/Log_Msg.h" +#include "ace/Get_Opt.h" +#include "ace/Local_Tokens.h" +#include "ace/Token_Collection.h" +#include "ace/Remote_Tokens.h" +#include "ace/Thread_Manager.h" +#include "ace/Service_Config.h" + +#if defined (ACE_HAS_THREADS) + +static char *server_host = ACE_DEFAULT_SERVER_HOST; +static int server_port = ACE_DEFAULT_SERVER_PORT; +static int threads = 2; +static int iterations = 50; +static int debug = 0; +static int remote = 0; +static int tokens = 5; + +static void * +run_thread (void *vp) +{ + ACE_Thread_Control tc (ACE_Service_Config::thr_mgr ()); + ACE_Token_Proxy *collection = (ACE_Token_Proxy *) vp; + + int count = iterations; + while (count--) + { + if (collection->acquire () == -1) + { + if (ACE_OS::last_error () == EDEADLK) + { + ACE_DEBUG ((LM_DEBUG, "deadlock detected in acquire")); + continue; + } + ACE_ERROR ((LM_ERROR, "(%t) %p acquire failed\n","run_thread")); + return (void *) -1; + } + + ACE_DEBUG ((LM_DEBUG, "(%t) %s acquired.\n", collection->name ())); + + if (collection->renew () == -1) + { + if (ACE_OS::last_error () == EDEADLK) + { + ACE_DEBUG ((LM_DEBUG, "deadlock detected")); + goto deadlock; + } + ACE_ERROR ((LM_ERROR, "(%t) %p renew failed\n","run_thread")); + return (void *) -1; + } + + ACE_DEBUG ((LM_DEBUG, "(%t) %s renewed.\n", collection->name ())); + + deadlock: + if (collection->release () == -1) + { + ACE_ERROR ((LM_ERROR, "(%t) %p release failed\n","run_thread")); + return (void *) -1; + } + + ACE_DEBUG ((LM_DEBUG, "(%t) %s released.\n", collection->name ())); + } + + + ACE_DEBUG ((LM_DEBUG, "(%t) thread exiting.\n")); + return 0; +} + +static int +parse_args (int argc, char *argv[]) +{ + ACE_LOG_MSG->open (argv[0], ACE_Log_Msg::STDERR); // | ACE_Log_Msg::VERBOSE); + + ACE_Get_Opt get_opt (argc, argv, "un:dp:h:", 1); + + for (int c; (c = get_opt ()) != -1; ) + { + switch (c) + { + case 'h': // specify the host machine on which the server is running + server_host = get_opt.optarg; + remote = 1; + break; + case 'p': // specify the port on which the server is running + server_port = ACE_OS::atoi (get_opt.optarg); + remote = 1; + break; + case 'd': + debug = 1; + break; + case 'n': + iterations = ACE_OS::atoi (get_opt.optarg); + break; + case 'u': + // usage: fallthrough + default: + ACE_ERROR_RETURN ((LM_ERROR, + "%n:\n" + "[-h <remote host>]\n" + "[-p <remote port>]\n" + "[-n <iterations>]\n" + "[-d debug]\n", 1), -1); + break; + } + } + + return 0; +} + +#if defined (ACE_HAS_PTHREADS) +#define SUSPEND 0 +#else +#define SUSPEND THR_SUSPENDED +#endif + +int +main (int argc, char* argv[]) +{ + if (parse_args (argc, argv) == -1) + return -1; + + ACE_Token_Proxy *A; // Mutex *A*. + ACE_Token_Proxy *B; // Mutex *B*. + ACE_Token_Proxy *R; // *R*eader Lock. + ACE_Token_Proxy *W; // *W*riter Lock. + + // Depending on the command line arguments, we will create local or + // remote tokens. The names of the tokens are not important as long + // as they are unique. + if (remote) + { + ACE_Remote_Mutex::set_server_address (ACE_INET_Addr (server_port, server_host)); + A = new ACE_Remote_Mutex ("R Mutex A", 0, debug); + B = new ACE_Remote_Mutex ("R Mutex B", 0, debug); + R = new ACE_Remote_RLock ("R Reader Lock", 0, debug); + W = new ACE_Remote_WLock ("R Writer Lock", 0, debug); + } + else + { + A = new ACE_Local_Mutex ("L Mutex A", 0, debug); + B = new ACE_Local_Mutex ("L Mutex B", 0, debug); + R = new ACE_Local_RLock ("L Reader Lock", 0, debug); + W = new ACE_Local_WLock ("L Writer Lock", 0, debug); + } + + // These collections will be treated as Tokens by the threads. + ACE_Token_Collection collectionAR (debug, "A and Reader"); + ACE_Token_Collection collectionAW (debug, "A and Writer"); + ACE_Token_Collection collectionBR (debug, "B and Reader"); + + // AR and BR can run concurrently. Neither AR or BR can run when AW + // is running. + collectionAR.insert (*A); + collectionAR.insert (*R); + + collectionAW.insert (*A); + collectionAW.insert (*W); + + collectionBR.insert (*B); + collectionBR.insert (*R); + + // Spawn off three threads. + ACE_Thread_Manager *mgr = ACE_Service_Config::thr_mgr (); + + if (mgr->spawn (ACE_THR_FUNC (run_thread), + (void *) &collectionAR, THR_BOUND | SUSPEND) == -1) + ACE_ERROR_RETURN ((LM_DEBUG, "%p\n", "spawn 1 failed"), -1); + + if (mgr->spawn (ACE_THR_FUNC (run_thread), + (void *) &collectionAW, THR_BOUND | SUSPEND) == -1) + ACE_ERROR_RETURN ((LM_DEBUG, "%p\n", "spawn 2 failed"), -1); + + if (mgr->spawn (ACE_THR_FUNC (run_thread), + (void *) &collectionBR, THR_BOUND | SUSPEND) == -1) + ACE_ERROR_RETURN ((LM_DEBUG, "%p\n", "spawn 3 failed"), -1); + +#if ! defined (ACE_HAS_PTHREADS) + if (mgr->resume_all () == -1) + ACE_ERROR_RETURN ((LM_DEBUG, "%p\n", "resume failed"), -1); +#endif + + // Wait for all threads to exit. + mgr->wait (); + + return 42; +} + +#else +int +main (int, char *[]) +{ + ACE_ERROR_RETURN ((LM_ERROR, + "threads not supported on this platform\n"), -1); +} +#endif /* ACE_HAS_THREADS */ diff --git a/netsvcs/clients/Tokens/collection/rw_locks.cpp b/netsvcs/clients/Tokens/collection/rw_locks.cpp new file mode 100644 index 00000000000..8717c7687b6 --- /dev/null +++ b/netsvcs/clients/Tokens/collection/rw_locks.cpp @@ -0,0 +1,175 @@ +#include "ace/OS.h" +// @(#)rw_locks.cpp 1.1 10/18/96 + +#include "ace/Log_Msg.h" +#include "ace/Get_Opt.h" +#include "ace/Local_Tokens.h" +#include "ace/Remote_Tokens.h" +#include "ace/Thread_Manager.h" + +#if defined (ACE_HAS_THREADS) + +static ACE_Token_Proxy *global_rlock; +static ACE_Token_Proxy *global_wlock; + +static char *server_host = ACE_DEFAULT_SERVER_HOST; +static int server_port = ACE_DEFAULT_SERVER_PORT; +static int ignore_deadlock = 0; +static int threads = 2; +static int iterations = 50; +static int debug = 0; +static int remote = 0; +static int reads = 4; +static int write_sleep = 0; + +static void * +run_thread (void *vp) +{ + ACE_Thread_Manager *thr_mgr = (ACE_Thread_Manager*) vp; + ACE_Thread_Control tc (thr_mgr); + + for (int x = 0; x < iterations; x++) + { + int y = 0; + for (; y < reads; y++) + { + if (global_rlock->acquire () == -1) + { + if (ACE_Log_Msg::instance ()->errnum () == EDEADLK) + { + ACE_DEBUG ((LM_DEBUG, "rlock deadlock detected\n")); + goto READ_DEADLOCK; + } + else return 0; + } + + ACE_DEBUG ((LM_DEBUG, "(%t) rlock acquired.\n")); + } + + READ_DEADLOCK: + + for (; y > 0; y--) + { + if (global_rlock->release () == 0) + ACE_DEBUG ((LM_DEBUG, "(%t) r-released.\n")); + } + + if (global_wlock->acquire () == -1) + { + ACE_DEBUG ((LM_DEBUG, "wlock deadlock detected\n")); + } + else + { + if (write_sleep) + ACE_OS::sleep (1); + ACE_DEBUG ((LM_DEBUG, "\t\t(%t) wlock acquired.\n")); + if (global_wlock->release () == 0) + ACE_DEBUG ((LM_DEBUG, "\t\t(%t) w-released.\n")); + } + } + + ACE_DEBUG ((LM_DEBUG, "(%t) thread exiting.\n")); + return 0; +} + +static int +parse_args (int argc, char *argv[]) +{ + ACE_LOG_MSG->open (argv[0], ACE_Log_Msg::STDERR); // | ACE_Log_Msg::VERBOSE); + + ACE_Get_Opt get_opt (argc, argv, "t:iun:drR:sp:h:", 1); + + for (int c; (c = get_opt ()) != -1; ) + { + switch (c) + { + case 'h': // specify the host machine on which the server is running + server_host = get_opt.optarg; + break; + case 'p': // specify the port on which the server is running + server_port = ACE_OS::atoi (get_opt.optarg); + break; + case 't': + threads = ACE_OS::atoi (get_opt.optarg); + break; + case 'R': + reads = ACE_OS::atoi (get_opt.optarg); + break; + case 'd': + debug = 1; + break; + case 'r': + remote = 1; + break; + case 's': + write_sleep = 1; + break; + case 'n': + iterations = ACE_OS::atoi (get_opt.optarg); + break; + case 'i': + ignore_deadlock = 1; + break; + case 'u': + // usage: fallthrough + default: + ACE_ERROR_RETURN ((LM_ERROR, + "%n:\n" + "[-i ignore deadlock]\n" + "[-n <iterations>]\n" + "[-R <reads>]\n" + "[-r use remote locks]\n" + "[-d debug]\n" + "[-s sleep during writes]\n" + "[-t <threads>\n", 1), -1); + break; + } + } + + return 0; +} + +int +main (int argc, char* argv[]) +{ + if (parse_args (argc, argv) == -1) + return -1; + + if (remote) + { + ACE_Remote_Mutex::set_server_address (ACE_INET_Addr (server_port, server_host)); + global_rlock = (ACE_Token_Proxy *) new + ACE_Remote_RLock ("THE_TOKEN", ignore_deadlock, debug); + global_wlock = (ACE_Token_Proxy *) new + ACE_Remote_WLock ("THE_TOKEN", ignore_deadlock, debug); + } + else + { + global_rlock = (ACE_Token_Proxy *) new + ACE_Local_RLock ("THE_TOKEN", ignore_deadlock, debug); + global_wlock = (ACE_Token_Proxy *) new + ACE_Local_WLock ("THE_TOKEN", ignore_deadlock, debug); + } + + ACE_Thread_Manager mgr; + + if (mgr.spawn_n (threads, ACE_THR_FUNC (run_thread), + (void *) &mgr, THR_BOUND | THR_SUSPENDED) == -1) + ACE_ERROR_RETURN ((LM_DEBUG, "%p\n", "spawn failed"), -1); + + if (mgr.resume_all () == -1) + ACE_ERROR_RETURN ((LM_DEBUG, "%p\n", "resume failed"), -1); + + mgr.wait (); + + return 42; +} + +#else +int +main (int, char *[]) +{ + ACE_ERROR_RETURN ((LM_ERROR, + "threads not supported on this platform\n"), -1); +} +#endif /* ACE_HAS_THREADS */ diff --git a/netsvcs/clients/Tokens/deadlock/Makefile b/netsvcs/clients/Tokens/deadlock/Makefile new file mode 100644 index 00000000000..27dfd2a4253 --- /dev/null +++ b/netsvcs/clients/Tokens/deadlock/Makefile @@ -0,0 +1,87 @@ +#---------------------------------------------------------------------------- +# @(#)Makefile 1.1 10/18/96 +# +# Makefile for repeating token client application +#---------------------------------------------------------------------------- + +#---------------------------------------------------------------------------- +# Local macros +#---------------------------------------------------------------------------- + +BIN = deadlock_detection_test + +FILES = deadlock_detection_test + +LSRC = $(addsuffix .cpp,$(FILES)) +LOBJ = $(LSRC:%.cpp=$(VDIR)%.o) +SHOBJ = $(addsuffix .so,$(FILES)) + +BUILD = $(VBIN) + +#---------------------------------------------------------------------------- +# Include macros and targets +#---------------------------------------------------------------------------- + +include $(WRAPPER_ROOT)/include/makeinclude/wrapper_macros.GNU +include $(WRAPPER_ROOT)/include/makeinclude/macros.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.common.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.nonested.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.lib.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.bin.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.local.GNU + +#---------------------------------------------------------------------------- +# Local targets +#---------------------------------------------------------------------------- + +#---------------------------------------------------------------------------- +# Dependencies +#---------------------------------------------------------------------------- + +# IF YOU PUT ANYTHING HERE IT WILL GO AWAY +# DO NOT DELETE THIS LINE -- g++dep uses it. +# DO NOT PUT ANYTHING AFTER THIS LINE, IT WILL GO AWAY. + +.obj/deadlock_detection_test.o .shobj/deadlock_detection_test.so: deadlock_detection_test.cpp \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/Token_Manager.h \ + $(WRAPPER_ROOT)/ace/Synch.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.i \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.i \ + $(WRAPPER_ROOT)/ace/Synch_T.h \ + $(WRAPPER_ROOT)/ace/Event_Handler.h \ + $(WRAPPER_ROOT)/ace/Map_Manager.h \ + $(WRAPPER_ROOT)/ace/Local_Tokens.h \ + $(WRAPPER_ROOT)/ace/Stack.h \ + $(WRAPPER_ROOT)/ace/Synch_Options.h \ + $(WRAPPER_ROOT)/ace/Remote_Tokens.h \ + $(WRAPPER_ROOT)/ace/INET_Addr.h \ + $(WRAPPER_ROOT)/ace/Addr.h \ + $(WRAPPER_ROOT)/ace/SOCK_Connector.h \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.h \ + $(WRAPPER_ROOT)/ace/SOCK_IO.h \ + $(WRAPPER_ROOT)/ace/SOCK.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.i \ + $(WRAPPER_ROOT)/ace/SOCK.i \ + $(WRAPPER_ROOT)/ace/SOCK_IO.i \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.i \ + $(WRAPPER_ROOT)/ace/SOCK_Connector.i \ + $(WRAPPER_ROOT)/ace/Token_Request_Reply.h \ + $(WRAPPER_ROOT)/ace/Thread.h \ + $(WRAPPER_ROOT)/ace/Thread_Manager.h \ + $(WRAPPER_ROOT)/ace/Get_Opt.h \ + $(WRAPPER_ROOT)/ace/Token_Invariants.h + +# IF YOU PUT ANYTHING HERE IT WILL GO AWAY diff --git a/netsvcs/clients/Tokens/deadlock/README b/netsvcs/clients/Tokens/deadlock/README new file mode 100644 index 00000000000..74fffde05cd --- /dev/null +++ b/netsvcs/clients/Tokens/deadlock/README @@ -0,0 +1,98 @@ + +deadlock_detection_test + +This example contains two deadlock tests, mutex and rwlock tests. +% ./deadlock_detection_test -u +./deadlock_detection_test: +[-r test readers/writer locks] +[-n <iterations>] +[-h <remote host>] +[-p <remote port>] +[-i ignore deadlock] + +For both mutex and rwlock tests, -h and -p specify to use remote +mutexes. -i specifies to ignore deadlock. -n is repetitions through +the respective algorithms (default 100). Both tests also use Token +Invariants to ensure correctness of the mutexes and readers/writer +locks. + +------------------------------------------------------------ + +If you run ./deadlock_detection_test without -r, then the following +mutex test is run. + +The mutex test spawns two threads which attempt to deadlock. +Logically, there are two tokens A and B. Here is what both threads +try to do: + +Thread 1 Thread 2 +-------- -------- +Repeat 100 times Repeat 100 times + acquire A acquire B + acquire B acquire A + release A and B release A and B +repeat repeat + +Notice that A and B are reversed in 1 and 2. If the token manager +(which is not in the public interface, but hidden behind +ACE_Local_Mutex) works properly, they should detect the deadlock. If +a thread detects deadlock, the resources held are released, and it +starts the whole process over again. + +What can be confusing about the test program is all the other tricks +I'm pulling to test other aspects of the library. For instance, I'm +using both "global" and "local" ACE_Local_Mutexes. This is to test +the ability to have multiple threads using one token proxy as well as +multiple threads each using their own proxies. All the while, the +same logical token is being used. If this doesn't make sense, don't +worry about it. Just use the ACE_Local_Mutex any way you want. + +Another confusing trick is that I'm testing recursive acquisition. +(Two acquires in a row.) I have to make sure that the token manager +doesn't detect a recursive acquire as deadlock. + +To run a test, simply type: +% ./deadlock_detection_test + +This should run 100 times through the above pseudo code. If the +application halts, then we have trouble. It should never ever halt. +I've included a little flag with the ACE_Local_Mutex class to allow +deadlock detection to be ignored. So, if you run the test as follows, +deadlock detection will be ignored. + +% ./deadlock_detection_test -i + +In this case, the application should only run about a second before +deadlock occurs and the application halts. This is good. + +------------------------------------------------------------ + +If you run ./deadlock_detection_test *with* -r, then the following +rwlock test is run: + +There are four tokens and four threads in the rwlock test. The +readers/writer tokens are: + +reader first +writer first 1 +writer first 2 +writer first 3 + +There are three reader threads that only acquire reader locks on the +above tokens. Each of the reader threads first acquire "reader first" +and then one "writer first <tid>" (where <tid> is the corresponding +thread's id). So reader thread 1 acquires "reader first" and then +"writer first 1". + +There is a single writer thread that uses the following algorithm: + +repeat 100 + acquire "writer first 1" + acquire "reader first" + acquire "writer first 2" + acquire "reader first" + acquire "writer first 3" + acquire "reader first" + +This strange mix of readers and writer create an interesting graph of +tokens that the deadlock detection algorithm must traverse. diff --git a/netsvcs/clients/Tokens/deadlock/deadlock_detection_test.cpp b/netsvcs/clients/Tokens/deadlock/deadlock_detection_test.cpp new file mode 100644 index 00000000000..7f03ec512ae --- /dev/null +++ b/netsvcs/clients/Tokens/deadlock/deadlock_detection_test.cpp @@ -0,0 +1,342 @@ +// ============================================================================ +// @(#)deadlock_detection_test.cpp 1.1 10/18/96 + +// +// = LIBRARY +// examples +// +// = FILENAME +// deadlock_detection_test.cpp +// +// = DESCRIPTION +// +// = AUTHOR +// Tim Harrison +// +// ============================================================================ + +#include "ace/OS.h" +#include "ace/Log_Msg.h" +#include "ace/Token_Manager.h" +#include "ace/Remote_Tokens.h" +#include "ace/Thread.h" +#include "ace/Thread_Manager.h" +#include "ace/Get_Opt.h" +#include "ace/Token_Invariants.h" + +#if defined (ACE_HAS_THREADS) + +typedef ACE_Token_Invariant_Manager ACE_TOKEN_INVARIANTS; + +static ACE_Token_Proxy *global_mutex; + +struct Two_Tokens +{ +public: + Two_Tokens (ACE_Thread_Manager *tm): thr_mgr_ (tm) {} + ACE_Token_Proxy *first_; + ACE_Token_Proxy *second_; + ACE_Thread_Manager *thr_mgr_; +}; + +struct Four_Tokens +{ +public: + Four_Tokens (ACE_Thread_Manager *tm): thr_mgr_ (tm) {} + ACE_Token_Proxy *first1_; + ACE_Token_Proxy *first2_; + ACE_Token_Proxy *first3_; + ACE_Token_Proxy *second_; + ACE_Thread_Manager *thr_mgr_; +}; + +static int ignore_deadlock = 0; +static int remote_mutexes = 0; +static char *server_host = ACE_DEFAULT_SERVER_HOST; +static int server_port = ACE_DEFAULT_SERVER_PORT; +static int iterations = 100; +static int rwlocks = 0; + +static void * +two_token_thread (void *vp) +{ + Two_Tokens* tm = (Two_Tokens*) vp; + ACE_Thread_Control (tm->thr_mgr_); + + for (int x = 0; x < iterations; x++) + { + if (tm->first_->acquire () == -1) + { + ACE_DEBUG ((LM_DEBUG, "Deadlock detected\n")); + continue; + } + + if (ACE_TOKEN_INVARIANTS::instance ()->acquired (tm->first_) == 0) + { + tm->first_->dump (); + ACE_ERROR_RETURN ((LM_ERROR, "violated invariant.\n"), 0); + } + + if (tm->second_->acquire () == -1) + { + ACE_DEBUG ((LM_DEBUG, "Deadlock Detected\n")); + goto G1; + } + + if (ACE_TOKEN_INVARIANTS::instance ()->acquired (tm->second_) == 0) + { + tm->second_->dump (); + ACE_ERROR_RETURN ((LM_ERROR, "violated invariant.\n"), 0); + } + + ACE_TOKEN_INVARIANTS::instance ()->releasing (tm->second_); + + tm->second_->release (); + G1: + ACE_TOKEN_INVARIANTS::instance ()->releasing (tm->first_); + + tm->first_->release (); + } + + ACE_DEBUG ((LM_DEBUG, "thread %t exiting\n")); + return 0; +} + +static void * +run_writer (void *vp) +{ + Four_Tokens* ft = (Four_Tokens *) vp; + ACE_Thread_Control (ft->thr_mgr_); + int acquire_number = 0; + + for (int x = 0; x < iterations; x++) + { + // Cycle through each of the first three tokens. + ACE_Token_Proxy *t; + switch (acquire_number) + { + case 0: + t = ft->first1_; + break; + case 1: + t = ft->first2_; + break; + case 2: + t = ft->first3_; + break; + } + + acquire_number = (acquire_number + 1) % 3; + + if (t->acquire () == -1) + { + ACE_ASSERT (errno == EDEADLK); + ACE_DEBUG ((LM_DEBUG, "Deadlock detected.\n")); + continue; + } + + if (ACE_TOKEN_INVARIANTS::instance ()->acquired (t) == 0) + { + t->dump (); + ACE_ERROR_RETURN ((LM_ERROR, "violated invariant.\n"), 0); + } + + if (ft->second_->acquire () == -1) + { + ACE_ASSERT (errno == EDEADLK); + ACE_DEBUG ((LM_DEBUG, "Deadlock Detected..\n")); + goto G1; + } + + if (ACE_TOKEN_INVARIANTS::instance ()->acquired (ft->second_) == 0) + { + ft->second_->dump (); + ACE_ERROR_RETURN ((LM_ERROR, "violated invariant.\n"), 0); + } + + ACE_TOKEN_INVARIANTS::instance ()->releasing (ft->second_); + + ft->second_->release (); + G1: + ACE_TOKEN_INVARIANTS::instance ()->releasing (t); + + t->release (); + } + + ACE_DEBUG ((LM_DEBUG, "thread %t exiting\n")); + return 0; +} + +static int +parse_args (int argc, char *argv[]) +{ + ACE_LOG_MSG->open (argv[0]); + + ACE_Get_Opt get_opt (argc, argv, "iuh:rp:n:", 1); + + for (int c; (c = get_opt ()) != -1; ) + { + switch (c) + { + case 'r': + rwlocks = 1; + break; + case 'i': + ignore_deadlock = 1; + break; + case 'h': + server_host = get_opt.optarg; + remote_mutexes = 1; + break; + case 'p': + server_port = ACE_OS::atoi (get_opt.optarg); + remote_mutexes = 1; + break; + case 'n': + iterations = ACE_OS::atoi (get_opt.optarg); + break; + case 'u': + default: + ACE_ERROR_RETURN ((LM_ERROR, + "%n:\n" + "[-r test readers/writer locks]\n" + "[-n <iterations>]\n" + "[-h <remote host>]\n" + "[-p <remote port>]\n" + "[-i ignore deadlock]\n%a", 1), -1); + break; + } + } + + return 0; +} + +int +mutex_test (void) +{ + ACE_Thread_Manager thr_mgr; + + Two_Tokens one (&thr_mgr), two (&thr_mgr); + + if (remote_mutexes == 0) + { + global_mutex = new ACE_Local_Mutex ("global proxy", ignore_deadlock, 1); + one.first_ = new ACE_Local_Mutex ("local proxy", ignore_deadlock, 1); + two.second_ = new ACE_Local_Mutex ("local proxy", ignore_deadlock, 1); + } + else + { + ACE_Remote_Mutex::set_server_address (ACE_INET_Addr (server_port, server_host)); + global_mutex = new ACE_Remote_Mutex ("global proxy", ignore_deadlock, 1); + one.first_ = new ACE_Remote_Mutex ("local proxy", ignore_deadlock, 1); + two.second_ = new ACE_Remote_Mutex ("local proxy", ignore_deadlock, 1); + } + + one.second_ = global_mutex; + two.first_ = global_mutex; + + // Tell the token manager to be verbose when reporting deadlock. + ACE_Token_Manager::instance ()->debug (1); + + if (thr_mgr.spawn (ACE_THR_FUNC (two_token_thread), + (void *) &one, THR_BOUND) == -1) + ACE_ERROR_RETURN ((LM_DEBUG, "%p\n", "first spawn"), -1); + + if (thr_mgr.spawn (ACE_THR_FUNC (two_token_thread), + (void *) &two, THR_BOUND) == -1) + ACE_ERROR_RETURN ((LM_DEBUG, "%p\n", "second spawn"), -1); + + // Wait for all threads to exit. + thr_mgr.wait (); + + return 0; +} + +int +rwlock_test (void) +{ + ACE_Thread_Manager thr_mgr; + + Two_Tokens reader1 (&thr_mgr); + Two_Tokens reader2 (&thr_mgr); + Two_Tokens reader3 (&thr_mgr); + Four_Tokens writer (&thr_mgr); + + if (remote_mutexes == 0) + { + reader1.first_ = new ACE_Local_RLock ("reader first", ignore_deadlock, 1); + reader1.second_ = new ACE_Local_RLock ("writer first 1", ignore_deadlock, 1); + reader2.first_ = new ACE_Local_RLock ("reader first", ignore_deadlock, 1); + reader2.second_ = new ACE_Local_RLock ("writer first 2", ignore_deadlock, 1); + reader3.first_ = new ACE_Local_RLock ("reader first", ignore_deadlock, 1); + reader3.second_ = new ACE_Local_RLock ("writer first 3", ignore_deadlock, 1); + + writer.first1_ = new ACE_Local_WLock ("writer first 1", ignore_deadlock, 1); + writer.first2_ = new ACE_Local_WLock ("writer first 2", ignore_deadlock, 1); + writer.first3_ = new ACE_Local_WLock ("writer first 3", ignore_deadlock, 1); + writer.second_ = new ACE_Local_WLock ("reader first", ignore_deadlock, 1); + } + else + { + ACE_Remote_Mutex::set_server_address (ACE_INET_Addr (server_port, server_host)); + + reader1.first_ = new ACE_Remote_RLock ("writer first 1", ignore_deadlock, 1); + reader1.second_ = new ACE_Remote_RLock ("reader first", ignore_deadlock, 1); + reader2.first_ = new ACE_Remote_RLock ("writer first 2", ignore_deadlock, 1); + reader2.second_ = new ACE_Remote_RLock ("reader first", ignore_deadlock, 1); + reader3.first_ = new ACE_Remote_RLock ("writer first 3", ignore_deadlock, 1); + reader3.second_ = new ACE_Remote_RLock ("reader first", ignore_deadlock, 1); + + writer.first1_ = new ACE_Remote_WLock ("writer first 1", ignore_deadlock, 1); + writer.first2_ = new ACE_Remote_WLock ("writer first 2", ignore_deadlock, 1); + writer.first3_ = new ACE_Remote_WLock ("writer first 3", ignore_deadlock, 1); + writer.second_ = new ACE_Remote_WLock ("reader first", ignore_deadlock, 1); + } + + // Tell the token manager to be verbose when reporting deadlock. + ACE_Token_Manager::instance ()->debug (1); + + if (thr_mgr.spawn (ACE_THR_FUNC (two_token_thread), + (void *) &reader1, THR_BOUND) == -1) + ACE_ERROR_RETURN ((LM_DEBUG, "%p\n", "first spawn"), -1); + + if (thr_mgr.spawn (ACE_THR_FUNC (two_token_thread), + (void *) &reader2, THR_BOUND) == -1) + ACE_ERROR_RETURN ((LM_DEBUG, "%p\n", "first spawn"), -1); + + if (thr_mgr.spawn (ACE_THR_FUNC (two_token_thread), + (void *) &reader3, THR_BOUND) == -1) + ACE_ERROR_RETURN ((LM_DEBUG, "%p\n", "first spawn"), -1); + + if (thr_mgr.spawn (ACE_THR_FUNC (run_writer), + (void *) &writer, THR_BOUND) == -1) + ACE_ERROR_RETURN ((LM_DEBUG, "%p\n", "second spawn"), -1); + + // Wait for all threads to exit. + thr_mgr.wait (); + + return 0; +} + +int +main (int argc, char* argv[]) +{ + if (parse_args (argc, argv) == -1) + return -1; + + if (rwlocks) + rwlock_test (); + else + mutex_test (); + + ACE_DEBUG ((LM_DEBUG, "test exiting.\n")); + return 42; +} +#else +int +main (int, char *[]) +{ + ACE_ERROR_RETURN ((LM_ERROR, + "threads not supported on this platform\n"), -1); +} +#endif /* ACE_HAS_THREADS */ diff --git a/netsvcs/clients/Tokens/invariant/Makefile b/netsvcs/clients/Tokens/invariant/Makefile new file mode 100644 index 00000000000..8f1c727d6c9 --- /dev/null +++ b/netsvcs/clients/Tokens/invariant/Makefile @@ -0,0 +1,72 @@ +#---------------------------------------------------------------------------- +# @(#)Makefile 1.1 10/18/96 +# +# Makefile for repeating token client application +#---------------------------------------------------------------------------- + +#---------------------------------------------------------------------------- +# Local macros +#---------------------------------------------------------------------------- + +BIN = invariant + +FILES = invariant + +LSRC = $(addsuffix .cpp,$(FILES)) +LOBJ = $(LSRC:%.cpp=$(VDIR)%.o) +SHOBJ = $(addsuffix .so,$(FILES)) + +BUILD = $(VBIN) + +#---------------------------------------------------------------------------- +# Include macros and targets +#---------------------------------------------------------------------------- + +include $(WRAPPER_ROOT)/include/makeinclude/wrapper_macros.GNU +include $(WRAPPER_ROOT)/include/makeinclude/macros.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.common.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.nonested.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.lib.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.bin.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.local.GNU + +#---------------------------------------------------------------------------- +# Local targets +#---------------------------------------------------------------------------- + +#---------------------------------------------------------------------------- +# Dependencies +#---------------------------------------------------------------------------- + +# IF YOU PUT ANYTHING HERE IT WILL GO AWAY +# DO NOT DELETE THIS LINE -- g++dep uses it. +# DO NOT PUT ANYTHING AFTER THIS LINE, IT WILL GO AWAY. + +.obj/invariant.o .shobj/invariant.so: invariant.cpp \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/Get_Opt.h \ + $(WRAPPER_ROOT)/ace/Thread_Manager.h \ + $(WRAPPER_ROOT)/ace/Thread.h \ + $(WRAPPER_ROOT)/ace/Synch.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.i \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.i \ + $(WRAPPER_ROOT)/ace/Synch_T.h \ + $(WRAPPER_ROOT)/ace/Event_Handler.h \ + $(WRAPPER_ROOT)/ace/Token_Invariants.h \ + $(WRAPPER_ROOT)/ace/Map_Manager.h \ + $(WRAPPER_ROOT)/ace/Local_Tokens.h \ + $(WRAPPER_ROOT)/ace/Stack.h \ + $(WRAPPER_ROOT)/ace/Synch_Options.h + +# IF YOU PUT ANYTHING HERE IT WILL GO AWAY diff --git a/netsvcs/clients/Tokens/invariant/README b/netsvcs/clients/Tokens/invariant/README new file mode 100644 index 00000000000..f078c2d6be4 --- /dev/null +++ b/netsvcs/clients/Tokens/invariant/README @@ -0,0 +1,27 @@ + +invariants.cpp tests the ACE Token Invariant utilities. The ACE Token +Invariant utilities allow an application to test the correctness of +mutex and readers/writer locks. + +invariants.cpp takes no command-line arguments. invariants.cpp first +tests readers/writer locks. This is done by spawning two threads +which simulate reader and writer acquire/renew/release loops. +However, the loops are performed without actual locks, so the +competing threads quickly reach and invalid state. The test should +report this violation of readers/writer lock invariants and both +threads should exit. + +The second test is for mutexes. Similar to the readers/writer lock +test, this test spawns two threads which perform acquire/renew/release +loops. When to two threads reach an invalid mutex state, the error +should be reported and the threads should exit. + +For these two previous tests, it is theoretically possible that the +threads never reach an invalid token state. However, it is highly +unlikely since the threads would have to execute the same code +simultaneously for the duration of the test. Nevertheless, it is +possible. + +The last test hardwires invalid token states. It runs two mutex and +two readers/writer lock tests. It should report "succeeded" for the +four tests. diff --git a/netsvcs/clients/Tokens/invariant/invariant.cpp b/netsvcs/clients/Tokens/invariant/invariant.cpp new file mode 100644 index 00000000000..85dfd0885dc --- /dev/null +++ b/netsvcs/clients/Tokens/invariant/invariant.cpp @@ -0,0 +1,199 @@ +// ============================================================================ +// @(#)invariant.cpp 1.1 10/18/96 + +// +// = LIBRARY +// examples +// +// = FILENAME +// invariant.cpp +// +// = DESCRIPTION +// +// = AUTHOR +// Tim Harrison +// +// ============================================================================ + +#include "ace/OS.h" +#include "ace/Log_Msg.h" +#include "ace/Get_Opt.h" +#include "ace/Thread_Manager.h" +#include "ace/Token_Invariants.h" + +#if defined (ACE_HAS_THREADS) + +typedef ACE_Token_Invariant_Manager ACE_TOKEN_INVARIANTS; + +static char * rwname = "reader/writer"; +static char * mutexname = "mutex"; + +static void * +run_reader_writer (void *vp) +{ + ACE_Thread_Manager *thr_mgr = (ACE_Thread_Manager*) vp; + ACE_Thread_Control tc (thr_mgr); + + for (int x = 0; x < 50; x++) + { + int y = 0; + for (; y < 5; y++) + { + if (ACE_TOKEN_INVARIANTS::instance ()->reader_acquired (rwname) == 0) + ACE_ERROR_RETURN ((LM_ERROR, "reader acquire violated invariant.\n"), 0); + + ACE_DEBUG ((LM_DEBUG, "(%t) rlock acquired.\n")); + } + + ACE_TOKEN_INVARIANTS::instance ()->rwlock_releasing (rwname); + + if (ACE_TOKEN_INVARIANTS::instance ()->reader_acquired (rwname) == 0) + ACE_ERROR_RETURN ((LM_ERROR, "reader renew violated invariant.\n"), 0); + + ACE_DEBUG ((LM_DEBUG, "(%t) rlock renewed.\n")); + + for (; y > 0; y--) + { + ACE_TOKEN_INVARIANTS::instance ()->rwlock_releasing (rwname); + ACE_DEBUG ((LM_DEBUG, "(%t) r-released.\n")); + } + + if (ACE_TOKEN_INVARIANTS::instance ()->writer_acquired (rwname) == 0) + ACE_ERROR_RETURN ((LM_ERROR, "writer acquire violated invariant.\n"), 0); + + ACE_DEBUG ((LM_DEBUG, "\t\t(%t) wlock acquired.\n")); + + ACE_TOKEN_INVARIANTS::instance ()->rwlock_releasing (rwname); + + if (ACE_TOKEN_INVARIANTS::instance ()->writer_acquired (rwname) == 0) + ACE_ERROR_RETURN ((LM_ERROR, "writer renew violated invariant.\n"), 0); + + ACE_DEBUG ((LM_DEBUG, "(%t) rlock renewed.\n")); + + ACE_TOKEN_INVARIANTS::instance ()->rwlock_releasing (rwname); + } + + ACE_DEBUG ((LM_DEBUG, "(%t) thread exiting.\n")); + return 0; +} + +static void * +run_mutex (void *vp) +{ + ACE_Thread_Manager *thr_mgr = (ACE_Thread_Manager*) vp; + ACE_Thread_Control tc (thr_mgr); + + for (int x = 0; x < 50; x++) + { + if (ACE_TOKEN_INVARIANTS::instance ()->mutex_acquired (mutexname) == 0) + ACE_ERROR_RETURN ((LM_ERROR, "mutex acquire violated invariant.\n"), 0); + + ACE_DEBUG ((LM_DEBUG, "(%t) mutex acquired.\n")); + + ACE_TOKEN_INVARIANTS::instance ()->mutex_releasing (mutexname); + + if (ACE_TOKEN_INVARIANTS::instance ()->mutex_acquired (mutexname) == 0) + ACE_ERROR_RETURN ((LM_ERROR, "mutex renew violated invariant.\n"), 0); + + ACE_DEBUG ((LM_DEBUG, "(%t) mutex renewed.\n")); + + ACE_TOKEN_INVARIANTS::instance ()->mutex_releasing (mutexname); + ACE_DEBUG ((LM_DEBUG, "(%t) mutex released.\n")); + } + + ACE_DEBUG ((LM_DEBUG, "(%t) thread exiting.\n")); + return 0; +} + +static int +run_final_test (void) +{ + ACE_DEBUG ((LM_DEBUG, "starting mutex tests 1 & 2\n")); + + // Mutex tests. + if (ACE_TOKEN_INVARIANTS::instance ()->mutex_acquired ("testing mutex") == 0) + ACE_ERROR_RETURN ((LM_ERROR, "mutex test 1 failed.\n"), 0); + if (ACE_TOKEN_INVARIANTS::instance ()->mutex_acquired ("testing mutex2") == 0) + ACE_ERROR_RETURN ((LM_ERROR, "mutex test 2 failed.\n"), 0); + if (ACE_TOKEN_INVARIANTS::instance ()->mutex_acquired ("testing mutex") == 0) + ACE_DEBUG ((LM_DEBUG, "mutex test 1 succeeded.\n")); + else + ACE_ERROR_RETURN ((LM_ERROR, "mutex test 1 failed..\n"), 0); + + if (ACE_TOKEN_INVARIANTS::instance ()->mutex_acquired ("testing mutex2") == 0) + ACE_DEBUG ((LM_DEBUG, "mutex test 2 succeeded.\n")); + else + ACE_ERROR_RETURN ((LM_ERROR, "mutex test 2 failed..\n"), 0); + + // RW tests. + ACE_DEBUG ((LM_DEBUG, "starting rwlock tests 1 & 2\n")); + + // Multiple readers. + if (ACE_TOKEN_INVARIANTS::instance ()->reader_acquired ("testing rwlock") == 0) + ACE_ERROR_RETURN ((LM_ERROR, "rwlock test 1 failed.\n"), 0); + if (ACE_TOKEN_INVARIANTS::instance ()->reader_acquired ("testing rwlock 2") == 0) + ACE_ERROR_RETURN ((LM_ERROR, "rwlock test 2 failed.\n"), 0); + if (ACE_TOKEN_INVARIANTS::instance ()->reader_acquired ("testing rwlock") == 0) + ACE_ERROR_RETURN ((LM_ERROR, "rwlock test 1 failed..\n"), 0); + if (ACE_TOKEN_INVARIANTS::instance ()->reader_acquired ("testing rwlock 2") == 0) + ACE_ERROR_RETURN ((LM_ERROR, "rwlock test 2 failed..\n"), 0); + + // Writer. + if (ACE_TOKEN_INVARIANTS::instance ()->writer_acquired ("testing rwlock") == 0) + ACE_DEBUG ((LM_ERROR, "rwlock test 1 succeded.\n")); + else + ACE_ERROR_RETURN ((LM_ERROR, "rwlock test 1 failed...\n"), 0); + + // Releasing reader. + ACE_TOKEN_INVARIANTS::instance ()->rwlock_releasing ("testing rwlock 2"); + ACE_TOKEN_INVARIANTS::instance ()->rwlock_releasing ("testing rwlock 2"); + + // Writer. + if (ACE_TOKEN_INVARIANTS::instance ()->writer_acquired ("testing rwlock 2") == 0) + ACE_ERROR_RETURN ((LM_ERROR, "rwlock test 2 failed....\n"), 0); + + // Reader. + if (ACE_TOKEN_INVARIANTS::instance ()->reader_acquired ("testing rwlock 2") == 0) + ACE_DEBUG ((LM_DEBUG, "rwlock test 2 succeeded.\n")); + else + ACE_ERROR_RETURN ((LM_ERROR, "rwlock test 2 failed.....\n"), 0); + + return 0; +} + +int +main (int argc, char* argv[]) +{ + ACE_Thread_Manager mgr; + + // Run reader/writer test + if (mgr.spawn_n (2, ACE_THR_FUNC (run_reader_writer), + (void *) &mgr, THR_NEW_LWP | THR_DETACHED) == -1) + ACE_ERROR_RETURN ((LM_DEBUG, "%p\n", "spawn failed"), -1); + + mgr.wait (); + + ACE_OS::sleep (2); + + // Run mutex test. + if (mgr.spawn_n (2, ACE_THR_FUNC (run_mutex), + (void *) &mgr, THR_NEW_LWP | THR_DETACHED) == -1) + ACE_ERROR_RETURN ((LM_DEBUG, "%p\n", "spawn failed"), -1); + + mgr.wait (); + + ACE_OS::sleep (2); + + run_final_test (); + + return 42; +} + +#else +int +main (int, char *[]) +{ + ACE_ERROR_RETURN ((LM_ERROR, + "threads not supported on this platform\n"), -1); +} +#endif /* ACE_HAS_THREADS */ diff --git a/netsvcs/clients/Tokens/manual/Makefile b/netsvcs/clients/Tokens/manual/Makefile new file mode 100644 index 00000000000..bc38106c2f8 --- /dev/null +++ b/netsvcs/clients/Tokens/manual/Makefile @@ -0,0 +1,109 @@ +#---------------------------------------------------------------------------- +# @(#)Makefile 1.1 10/18/96 +# +# Makefile for repeating token client application +#---------------------------------------------------------------------------- + +#---------------------------------------------------------------------------- +# Local macros +#---------------------------------------------------------------------------- + +BIN = manual + +FILES = manual + +LSRC = $(addsuffix .cpp,$(FILES)) +LOBJ = $(LSRC:%.cpp=$(VDIR)%.o) +SHOBJ = $(addsuffix .so,$(FILES)) + +BUILD = $(VBIN) + +#---------------------------------------------------------------------------- +# Include macros and targets +#---------------------------------------------------------------------------- + +include $(WRAPPER_ROOT)/include/makeinclude/wrapper_macros.GNU +include $(WRAPPER_ROOT)/include/makeinclude/macros.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.common.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.nonested.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.lib.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.bin.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.local.GNU + +#---------------------------------------------------------------------------- +# Local targets +#---------------------------------------------------------------------------- + +#---------------------------------------------------------------------------- +# Dependencies +#---------------------------------------------------------------------------- + +# IF YOU PUT ANYTHING HERE IT WILL GO AWAY +# DO NOT DELETE THIS LINE -- g++dep uses it. +# DO NOT PUT ANYTHING AFTER THIS LINE, IT WILL GO AWAY. + +.obj/manual.o .shobj/manual.so: manual.cpp \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/Get_Opt.h \ + $(WRAPPER_ROOT)/ace/Local_Tokens.h \ + $(WRAPPER_ROOT)/ace/Synch.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.i \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.i \ + $(WRAPPER_ROOT)/ace/Synch_T.h \ + $(WRAPPER_ROOT)/ace/Event_Handler.h \ + $(WRAPPER_ROOT)/ace/Stack.h \ + $(WRAPPER_ROOT)/ace/Synch_Options.h \ + $(WRAPPER_ROOT)/ace/Map_Manager.h \ + $(WRAPPER_ROOT)/ace/Remote_Tokens.h \ + $(WRAPPER_ROOT)/ace/INET_Addr.h \ + $(WRAPPER_ROOT)/ace/Addr.h \ + $(WRAPPER_ROOT)/ace/SOCK_Connector.h \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.h \ + $(WRAPPER_ROOT)/ace/SOCK_IO.h \ + $(WRAPPER_ROOT)/ace/SOCK.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.i \ + $(WRAPPER_ROOT)/ace/SOCK.i \ + $(WRAPPER_ROOT)/ace/SOCK_IO.i \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.i \ + $(WRAPPER_ROOT)/ace/SOCK_Connector.i \ + $(WRAPPER_ROOT)/ace/Token_Request_Reply.h \ + $(WRAPPER_ROOT)/ace/Thread_Manager.h \ + $(WRAPPER_ROOT)/ace/Thread.h \ + $(WRAPPER_ROOT)/ace/Token_Invariants.h \ + $(WRAPPER_ROOT)/ace/Token_Collection.h \ + $(WRAPPER_ROOT)/ace/SString.h \ + $(WRAPPER_ROOT)/ace/Service_Config.h \ + $(WRAPPER_ROOT)/ace/Service_Object.h \ + $(WRAPPER_ROOT)/ace/Shared_Object.h \ + $(WRAPPER_ROOT)/ace/Set.h \ + $(WRAPPER_ROOT)/ace/Proactor.h \ + $(WRAPPER_ROOT)/ace/Message_Block.h \ + $(WRAPPER_ROOT)/ace/Malloc.h \ + $(WRAPPER_ROOT)/ace/Malloc_T.h \ + $(WRAPPER_ROOT)/ace/Memory_Pool.h \ + $(WRAPPER_ROOT)/ace/Signal.h \ + $(WRAPPER_ROOT)/ace/Mem_Map.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.i \ + $(WRAPPER_ROOT)/ace/ReactorEx.h \ + $(WRAPPER_ROOT)/ace/Token.h \ + $(WRAPPER_ROOT)/ace/Reactor.h \ + $(WRAPPER_ROOT)/ace/Handle_Set.h \ + $(WRAPPER_ROOT)/ace/Pipe.h \ + $(WRAPPER_ROOT)/ace/Pipe.i \ + $(WRAPPER_ROOT)/ace/Reactor.i \ + $(WRAPPER_ROOT)/ace/Svc_Conf_Tokens.h + +# IF YOU PUT ANYTHING HERE IT WILL GO AWAY diff --git a/netsvcs/clients/Tokens/manual/README b/netsvcs/clients/Tokens/manual/README new file mode 100644 index 00000000000..09b9b9a365a --- /dev/null +++ b/netsvcs/clients/Tokens/manual/README @@ -0,0 +1,67 @@ + +./manual gives users a text-based interactive interface to local or +remote tokens. This is extremely useful for manually testing the +token server and setting up deadlock scenarios. + +Run it as follows + +% ./manual -u +./manual: +[-h <remote host>] +[-p <remote port>] +[-i ignore deadlock] +[-d debug] + +./manual gives you the following prompt. +<tid> <token> <type> <operation> + +<tid> This is the client id of the current operation. This is set + manually by ./manual for every operation. Be careful when + using multiple <tid>'s during a remote session (see BUGS + below). + +<token> This is the name of the token for the operation. + +<type> This is the type of the token. This can be: + M - Corresponds to a Mutex lock. + R - Corresponds to Readers/Writer lock. + W - Corresponds to Readers/Writer lock. + Obviously, a single <token> can be M or it can R and/or W. If + you perform and operation like this "tid1 tokenA M A" then + don't do this "tid1 tokenA R A". This doesn't make sense. + +<operation> This is the operation to perform on the + <tid>-<token>-<type> proxy. These include: + A - acquire. + N - renew. + R - release. + T - tryacquire. + +BUGS!!!! + +When performing remote tests, be careful when using a single running +./manual to impersonate two <tid>'s. The Token Server client +connection policy is currently, one per thread. The Token Server +assumes that the same <tid> is always on the other end of a +connection. If you do something like the following, you will break +it: + +lambada:Tokens/manual> ./manual -h tango -p 20202 +<tid> <token> <type> <operation> +tid1 tokenA M A +ACE_TSS_Connection new connection +(1) acquired tokenA remotely. +Succeeded. +<tid> <token> <type> <operation> +tid2 tokenA M A +(1) acquired tokenA remotely. <------ This is remote BADness!!! +Succeeded. +Violated invariant. <------ Locally detected badness. +<tid> <token> <type> <operation> + + +Notice that the local side discovered that this was incorrect. +However, the Token Server thinks it was a recursive acquisition for +tid1. Keep in mind that this is not a problem with the Token library. +It is just a problem with how this primitive ./manual application maps +STDIN to the ACE Token API. diff --git a/netsvcs/clients/Tokens/manual/manual.cpp b/netsvcs/clients/Tokens/manual/manual.cpp new file mode 100644 index 00000000000..664d9017f66 --- /dev/null +++ b/netsvcs/clients/Tokens/manual/manual.cpp @@ -0,0 +1,347 @@ +// ============================================================================ +// @(#)manual.cpp 1.1 10/18/96 + +// +// = LIBRARY +// examples +// +// = FILENAME +// manual.cpp +// +// = DESCRIPTION +// Allows manual operations on local and remote tokens. +// +// = AUTHOR +// Tim Harrison +// +// ============================================================================ + +#include "ace/OS.h" +#include "ace/Log_Msg.h" +#include "ace/Get_Opt.h" +#include "ace/Local_Tokens.h" +#include "ace/Remote_Tokens.h" +#include "ace/Thread_Manager.h" +#include "ace/Token_Invariants.h" +#include "ace/Token_Collection.h" +#include "ace/Map_Manager.h" +#include "ace/Service_Config.h" + +typedef ACE_Token_Invariant_Manager ACE_TOKEN_INVARIANTS; + +class STDIN_Token : public ACE_Event_Handler + // = TITLE + // STDIN Token + // + // = DESCRIPTION + // Translates STDIN commands to ACE Token commands. +{ +public: + STDIN_Token (void); + // Construction. + + int parse_args (int argc, char *argv[]); + // Parse command-line arguments. + + int open (int argc, char *argv[]); + // Register with whatever event dispatcher is needed and run. + + // = Event_Handler methods. + int handle_input (ACE_HANDLE); + handle_exception (ACE_HANDLE); + +private: + + void display_menu (void); + // Display options. + + ACE_Token_Proxy *get_proxy (const char *tid, const char *token, char type); + // Get or make a proxy to <token> with a <tid> client id. + + ACE_Token_Proxy *create_proxy (const char *token, char type); + // Create a proxy to <token> with a <tid> client id. + + typedef ACE_CString TID; + + // = Mapping from tid to Token_Collection. + typedef ACE_Map_Manager<TID, ACE_Token_Collection *, ACE_Null_Mutex> + COLLECTIONS; + // COLLECTION maintains a mapping from tid to a collection. + + typedef ACE_Map_Iterator<TID, ACE_Token_Collection *, ACE_Null_Mutex> + COLLECTIONS_ITERATOR; + // Allows iterations through collections_. + + typedef ACE_Map_Entry<TID, ACE_Token_Collection *> + COLLECTIONS_ENTRY; + // Allows iterations through collections_. + + COLLECTIONS collections_; + // A collection for each <tid>. + + char *server_host_; + int server_port_; + int ignore_deadlock_; + int debug_; + int remote_; +}; + +STDIN_Token::STDIN_Token (void) +: server_host_ (ACE_DEFAULT_SERVER_HOST), + server_port_ (ACE_DEFAULT_SERVER_PORT), + ignore_deadlock_ (0), + debug_ (0), + remote_ (0) +{ +} + +int +STDIN_Token::parse_args (int argc, char *argv[]) +{ + ACE_LOG_MSG->open (argv[0], ACE_Log_Msg::STDERR); + + ACE_Get_Opt get_opt (argc, argv, "h:p:diu", 1); + + for (int c; (c = get_opt ()) != -1; ) + { + switch (c) + { + case 'h': // specify the host machine on which the server is running + server_host_ = get_opt.optarg; + remote_ = 1; + break; + case 'p': // specify the port on which the server is running + server_port_ = ACE_OS::atoi (get_opt.optarg); + remote_ = 1; + break; + case 'd': + debug_ = 1; + break; + case 'i': + ignore_deadlock_ = 1; + break; + case 'u': + // usage: fallthrough + default: + ACE_ERROR_RETURN ((LM_ERROR, + "%n:\n" + "[-h <remote host>]\n" + "[-p <remote port>]\n" + "[-i ignore deadlock]\n" + "[-d debug]\n", 1), -1); + break; + } + } + + if (remote_) + ACE_Remote_Mutex::set_server_address (ACE_INET_Addr (server_port_, server_host_)); + + return 0; +} + +int +STDIN_Token::open (int argc, char *argv[]) +{ + if (this->parse_args (argc, argv) == -1) + return -1; + + // Register for signals. + if (ACE_Service_Config::reactor ()->register_handler + (SIGINT, this) == -1) + ACE_DEBUG ((LM_DEBUG, "Can't register signal handler\n")); + +#if (ACE_WIN32) + +#else + // Register for STDIN events with Reactor. + if (ACE_Service_Config::reactor ()->register_handler + (ACE_STDIN, this, ACE_Event_Handler::READ_MASK) == -1) + ACE_ERROR_RETURN ((LM_DEBUG, "Can't register signal handler\n"), 0); + + +#endif /* ACE_WIN32 */ + + + this->display_menu (); + +#if (ACE_WIN32) + +#else + ACE_Service_Config::run_reactor_event_loop (); +#endif /* ACE_WIN32 */ + + ACE_OS::printf ("Exiting...\n"); + return 0; +} + +int +STDIN_Token::handle_input (ACE_HANDLE fd) +{ + char tid[BUFSIZ]; + char token[BUFSIZ]; + char type[16]; + char operation[16]; + + if (::scanf ("%s %s %s %s", tid, token, type, operation) <= 0) + { + ACE_OS::printf ("Try again.\n"); + return 0; + } + + ACE_Token_Proxy *proxy = + this->get_proxy (tid, token, type[0]); + + if (proxy == 0) + return -1; + + switch (operation[0]) + { + case 'a': + case 'A': + if (proxy->acquire () == 0) + { + ACE_OS::printf ("Succeeded.\n"); + if (ACE_TOKEN_INVARIANTS::instance ()->acquired (proxy) == 0) + ACE_OS::printf ("Violated invariant.\n"); + } + else + ACE_ERROR ((LM_ERROR, "%p.\n", "Acquire failed")); + break; + + case 'n': + case 'N': + ACE_TOKEN_INVARIANTS::instance ()->releasing (proxy); + if (proxy->renew () == 0) + { + ACE_OS::printf ("Succeeded.\n"); + if (ACE_TOKEN_INVARIANTS::instance ()->acquired (proxy) == 0) + ACE_OS::printf ("Violated invariant.\n"); + } + else + ACE_ERROR ((LM_ERROR, "%p.\n", "Renew failed")); + break; + + case 'r': + case 'R': + ACE_TOKEN_INVARIANTS::instance ()->releasing (proxy); + if (proxy->release () == 0) + ACE_OS::printf ("Succeeded.\n"); + else + ACE_ERROR ((LM_ERROR, "%p.\n", "Release failed")); + break; + + case 't': + case 'T': + if (proxy->tryacquire () == 0) + { + ACE_OS::printf ("Succeeded.\n"); + if (ACE_TOKEN_INVARIANTS::instance ()->acquired (proxy) == 0) + ACE_OS::printf ("Violated invariant.\n"); + } + else + ACE_ERROR ((LM_ERROR, "%p.\n", "Tryacquire failed")); + break; + } + + this->display_menu (); + return 0; +} + +void +STDIN_Token::display_menu (void) +{ + ACE_OS::printf ("<tid> <token> <type> <operation>\n"); +} + +int +STDIN_Token::handle_exception (ACE_HANDLE fd) +{ + ACE_Service_Config::run_reactor_event_loop (); + return -1; +} + +ACE_Token_Proxy * +STDIN_Token::get_proxy (const char *_tid, const char *token, char type) +{ + ACE_Token_Collection *proxy_collection; + + TID tid (_tid); + + if (collections_.find (tid, proxy_collection) == -1) + // We did not find a proxy_collection. + { + // Make one. + proxy_collection = new ACE_Token_Collection (debug_, "no name collection"); + + // Put it in the collections. + if (collections_.bind (tid, proxy_collection) == -1) + { + delete proxy_collection; + return 0; + } + } + + // Either way, we have a proxy_collection now. + + // See if the proxy already exists in the collection. + ACE_Token_Proxy *proxy = proxy_collection->is_member (token); + + // If not, create one. + if (proxy == 0) + { + proxy = this->create_proxy (token, type); + + // Put the new_proxy in this tid's collection. + if (proxy_collection->insert (*proxy) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "insert failed\n"), 0); + + // Delete our copy (one was created in the collection). + delete proxy; + proxy = proxy_collection->is_member (token); + + if (proxy == 0) + ACE_ERROR_RETURN ((LM_ERROR, "is_member failed\n"), 0); + + // Set the client_id (it was set to 1 since we're + // single-threaded. + proxy->client_id (_tid); + } + + return proxy; +} + +ACE_Token_Proxy * +STDIN_Token::create_proxy (const char *token, char type) +{ + switch (type) + { + case 'm': + case 'M': + if (remote_) + return new ACE_Remote_Mutex (token, ignore_deadlock_, debug_); + else + return new ACE_Local_Mutex (token, ignore_deadlock_, debug_); + + case 'r': + case 'R': + if (remote_) + return new ACE_Remote_RLock (token, ignore_deadlock_, debug_); + else + return new ACE_Local_RLock (token, ignore_deadlock_, debug_); + + case 'w': + case 'W': + if (remote_) + return new ACE_Remote_WLock (token, ignore_deadlock_, debug_); + else + return new ACE_Local_WLock (token, ignore_deadlock_, debug_); + } +} + + +int +main (int argc, char* argv[]) +{ + STDIN_Token st; + return st.open (argc, argv); +} diff --git a/netsvcs/clients/Tokens/mutex/Makefile b/netsvcs/clients/Tokens/mutex/Makefile new file mode 100644 index 00000000000..fbd5fd4c597 --- /dev/null +++ b/netsvcs/clients/Tokens/mutex/Makefile @@ -0,0 +1,85 @@ +#---------------------------------------------------------------------------- +# @(#)Makefile 1.1 10/18/96 +# +# Makefile for repeating token client application +#---------------------------------------------------------------------------- + +#---------------------------------------------------------------------------- +# Local macros +#---------------------------------------------------------------------------- + +BIN = test_mutex + +FILES = test_mutex + +LSRC = $(addsuffix .cpp,$(FILES)) +LOBJ = $(LSRC:%.cpp=$(VDIR)%.o) +SHOBJ = $(addsuffix .so,$(FILES)) + +BUILD = $(VBIN) + +#---------------------------------------------------------------------------- +# Include macros and targets +#---------------------------------------------------------------------------- + +include $(WRAPPER_ROOT)/include/makeinclude/wrapper_macros.GNU +include $(WRAPPER_ROOT)/include/makeinclude/macros.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.common.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.nonested.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.lib.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.bin.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.local.GNU + +#---------------------------------------------------------------------------- +# Local targets +#---------------------------------------------------------------------------- + +#---------------------------------------------------------------------------- +# Dependencies +#---------------------------------------------------------------------------- + +# IF YOU PUT ANYTHING HERE IT WILL GO AWAY +# DO NOT DELETE THIS LINE -- g++dep uses it. +# DO NOT PUT ANYTHING AFTER THIS LINE, IT WILL GO AWAY. + +.obj/test_mutex.o .shobj/test_mutex.so: test_mutex.cpp \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/Get_Opt.h \ + $(WRAPPER_ROOT)/ace/Local_Tokens.h \ + $(WRAPPER_ROOT)/ace/Synch.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.i \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.i \ + $(WRAPPER_ROOT)/ace/Synch_T.h \ + $(WRAPPER_ROOT)/ace/Event_Handler.h \ + $(WRAPPER_ROOT)/ace/Stack.h \ + $(WRAPPER_ROOT)/ace/Synch_Options.h \ + $(WRAPPER_ROOT)/ace/Map_Manager.h \ + $(WRAPPER_ROOT)/ace/Remote_Tokens.h \ + $(WRAPPER_ROOT)/ace/INET_Addr.h \ + $(WRAPPER_ROOT)/ace/Addr.h \ + $(WRAPPER_ROOT)/ace/SOCK_Connector.h \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.h \ + $(WRAPPER_ROOT)/ace/SOCK_IO.h \ + $(WRAPPER_ROOT)/ace/SOCK.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.i \ + $(WRAPPER_ROOT)/ace/SOCK.i \ + $(WRAPPER_ROOT)/ace/SOCK_IO.i \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.i \ + $(WRAPPER_ROOT)/ace/SOCK_Connector.i \ + $(WRAPPER_ROOT)/ace/Token_Request_Reply.h \ + $(WRAPPER_ROOT)/ace/Thread.h \ + $(WRAPPER_ROOT)/ace/Thread_Manager.h + +# IF YOU PUT ANYTHING HERE IT WILL GO AWAY diff --git a/netsvcs/clients/Tokens/mutex/README b/netsvcs/clients/Tokens/mutex/README new file mode 100644 index 00000000000..cbd1e9c7d6c --- /dev/null +++ b/netsvcs/clients/Tokens/mutex/README @@ -0,0 +1,23 @@ + +test_mutex + +test_mutex tests ACE_Local_Mutex and ACE_Remote_Mutex with both local +and global proxies. "Local proxies" mean that each thread uses its +own proxy (but same logical token.) "Global proxy" means that all +threads access the same proxy (and, of course, the same logical +token.) + +test_mutex can take the number of threads to run from the +command-line. Thus, to run the test with one thread and local +mutexes, type: + +% ./test_mutex + +To run the test with 10 threads and local mutexes, type: + +% ./test_mutex -t 10 + +To run the test with 10 threads and remote mutexes, type: + +% ./test_mutex -t 10 -r + diff --git a/netsvcs/clients/Tokens/mutex/test_mutex.cpp b/netsvcs/clients/Tokens/mutex/test_mutex.cpp new file mode 100644 index 00000000000..3b7b94dba0d --- /dev/null +++ b/netsvcs/clients/Tokens/mutex/test_mutex.cpp @@ -0,0 +1,144 @@ +// ============================================================================ +// @(#)test_mutex.cpp 1.1 10/18/96 + +// +// = LIBRARY +// examples +// +// = FILENAME +// test_mutex.cpp +// +// = DESCRIPTION +// +// = AUTHOR +// Tim Harrison +// +// ============================================================================ + +#include "ace/OS.h" +#include "ace/Log_Msg.h" +#include "ace/Get_Opt.h" +#include "ace/Local_Tokens.h" +#include "ace/Remote_Tokens.h" +#include "ace/Thread.h" +#include "ace/Thread_Manager.h" + +#if defined (ACE_HAS_THREADS) + +static ACE_Token_Proxy *mutex; +static int remote_mutexes = 0; +static char *server_host = ACE_DEFAULT_SERVER_HOST; +static int server_port = ACE_DEFAULT_SERVER_PORT; +static int iterations = 100; +static int spawn_count = 2; + +static void * +run_test (void *vp) +{ + ACE_Thread_Manager *thr_mgr = (ACE_Thread_Manager*) vp; + ACE_Thread_Control tc (thr_mgr); + + int count = iterations; + // test recursive acquisition of a global proxy + while (count--) + { + if (mutex->acquire () == -1) + { + ACE_ERROR ((LM_ERROR, "(%t) %p acquire failed\n","test_mutex")); + return (void *) -1; + } + +// mutex->acquire (); + if (mutex->renew () == -1) + { + ACE_ERROR ((LM_ERROR, "(%t) %p renew failed\n","test_mutex")); + return (void *) -1; + } + + if (mutex->release () == -1) + { + ACE_ERROR ((LM_ERROR, "(%t) %p release failed\n","test_mutex")); + return (void *) -1; + } + +// mutex->release (); + } + + return 0; +} + +static int +parse_args (int argc, char *argv[]) +{ + ACE_LOG_MSG->open (argv[0]); + + ACE_Get_Opt get_opt (argc, argv, "t:uh:p:n:", 1); + + for (int c; (c = get_opt ()) != -1; ) + { + switch (c) + { + case 't': + spawn_count = ACE_OS::atoi (get_opt.optarg); + break; + case 'h': // specify the host machine on which the server is running + server_host = get_opt.optarg; + remote_mutexes = 1; + break; + case 'p': // specify the port on which the server is running + server_port = ACE_OS::atoi (get_opt.optarg); + remote_mutexes = 1; + break; + case 'n': // specify the port on which the server is running + iterations = ACE_OS::atoi (get_opt.optarg); + break; + case 'u': + default: + ACE_ERROR_RETURN ((LM_ERROR, + "%n:\n" + "[-h <remote host>]\n" + "[-p <remote port>]\n" + "[-n <iterations>]\n" + "[-t <threads>]\n" + "[-h <remote host>]\n" + "[-p <remote port>]\n", 1), -1); + break; + } + } + + return 0; +} + +int +main (int argc, char* argv[]) +{ + ACE_Thread_Manager thread_mgr; + + if (parse_args (argc, argv) == -1) + return -1; + + if (remote_mutexes) + { + ACE_Remote_Mutex::set_server_address (ACE_INET_Addr (server_port, server_host)); + mutex = new ACE_Remote_Mutex ("Remote TOKEN", 0, 1); + } + else + { + mutex = new ACE_Local_Mutex ("Local TOKEN", 0, 1); + } + + if (thread_mgr.spawn_n (spawn_count, + ACE_THR_FUNC (run_test), + (void *) &thread_mgr, THR_BOUND) == -1) + ACE_ERROR_RETURN ((LM_DEBUG, "%p\n", "spawn"), -1); + + thread_mgr.wait (); + + return 42; +} +#else +int main (void) +{ + ACE_ERROR_RETURN ((LM_ERROR, "you must have threads to run this test program\n"), -1); +} +#endif /* ACE_HAS_THREADS */ diff --git a/netsvcs/clients/Tokens/rw_lock/Makefile b/netsvcs/clients/Tokens/rw_lock/Makefile new file mode 100644 index 00000000000..3bf51a6fa51 --- /dev/null +++ b/netsvcs/clients/Tokens/rw_lock/Makefile @@ -0,0 +1,86 @@ +#---------------------------------------------------------------------------- +# @(#)Makefile 1.1 10/18/96 +# +# Makefile for repeating token client application +#---------------------------------------------------------------------------- + +#---------------------------------------------------------------------------- +# Local macros +#---------------------------------------------------------------------------- + +BIN = rw_locks + +FILES = rw_locks + +LSRC = $(addsuffix .cpp,$(FILES)) +LOBJ = $(LSRC:%.cpp=$(VDIR)%.o) +SHOBJ = $(addsuffix .so,$(FILES)) + +BUILD = $(VBIN) + +#---------------------------------------------------------------------------- +# Include macros and targets +#---------------------------------------------------------------------------- + +include $(WRAPPER_ROOT)/include/makeinclude/wrapper_macros.GNU +include $(WRAPPER_ROOT)/include/makeinclude/macros.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.common.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.nonested.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.lib.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.bin.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.local.GNU + +#---------------------------------------------------------------------------- +# Local targets +#---------------------------------------------------------------------------- + +#---------------------------------------------------------------------------- +# Dependencies +#---------------------------------------------------------------------------- + +# IF YOU PUT ANYTHING HERE IT WILL GO AWAY +# DO NOT DELETE THIS LINE -- g++dep uses it. +# DO NOT PUT ANYTHING AFTER THIS LINE, IT WILL GO AWAY. + +.obj/rw_locks.o .shobj/rw_locks.so: rw_locks.cpp \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/Get_Opt.h \ + $(WRAPPER_ROOT)/ace/Local_Tokens.h \ + $(WRAPPER_ROOT)/ace/Synch.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.i \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.i \ + $(WRAPPER_ROOT)/ace/Synch_T.h \ + $(WRAPPER_ROOT)/ace/Event_Handler.h \ + $(WRAPPER_ROOT)/ace/Stack.h \ + $(WRAPPER_ROOT)/ace/Synch_Options.h \ + $(WRAPPER_ROOT)/ace/Map_Manager.h \ + $(WRAPPER_ROOT)/ace/Remote_Tokens.h \ + $(WRAPPER_ROOT)/ace/INET_Addr.h \ + $(WRAPPER_ROOT)/ace/Addr.h \ + $(WRAPPER_ROOT)/ace/SOCK_Connector.h \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.h \ + $(WRAPPER_ROOT)/ace/SOCK_IO.h \ + $(WRAPPER_ROOT)/ace/SOCK.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.i \ + $(WRAPPER_ROOT)/ace/SOCK.i \ + $(WRAPPER_ROOT)/ace/SOCK_IO.i \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.i \ + $(WRAPPER_ROOT)/ace/SOCK_Connector.i \ + $(WRAPPER_ROOT)/ace/Token_Request_Reply.h \ + $(WRAPPER_ROOT)/ace/Thread_Manager.h \ + $(WRAPPER_ROOT)/ace/Thread.h \ + $(WRAPPER_ROOT)/ace/Token_Invariants.h + +# IF YOU PUT ANYTHING HERE IT WILL GO AWAY diff --git a/netsvcs/clients/Tokens/rw_lock/README b/netsvcs/clients/Tokens/rw_lock/README new file mode 100644 index 00000000000..dabc0a3741d --- /dev/null +++ b/netsvcs/clients/Tokens/rw_lock/README @@ -0,0 +1,40 @@ + +test_rw_locks shows how to use ACE_Local_RLock, ACE_Local_WLock, +ACE_Remote_RLock, and ACE_Remote_WLock. + +Here are the options to test_rw_locks: +% ./test_rw_lock -u + -i ignore deadlock + -n <iterations> + -r <reads> + -d debug + -s sleep during writes + -t <threads> + +test_rw_locks spawns <threads> number of threads which perform the +following algorithm: + +for <iterations> + { + for <reads> + acquire read lock + for <reads> + release read lock + + acquire write lock + if (sleep during writes) + sleep for 1 second + release write lock + } + + +The output should show that multiple readers can acquire the lock for +reading simultaneously (note that this also tests recursive +acquisition.) When a writer lock is acquired, the output should show +that no thread holds a reader lock. + +To run a test, simply type: +% ./test_rw_lock + +This should show output as described above. + diff --git a/netsvcs/clients/Tokens/rw_lock/rw_locks.cpp b/netsvcs/clients/Tokens/rw_lock/rw_locks.cpp new file mode 100644 index 00000000000..3c6295ce0a5 --- /dev/null +++ b/netsvcs/clients/Tokens/rw_lock/rw_locks.cpp @@ -0,0 +1,255 @@ +// ============================================================================ +// @(#)rw_locks.cpp 1.1 10/18/96 + +// +// = LIBRARY +// examples +// +// = FILENAME +// rw_locks.cpp +// +// = DESCRIPTION +// test_rw_locks shows how to use ACE_Local_RLock, ACE_Local_WLock, +// ACE_Remote_RLock, and ACE_Remote_WLock. +// +// = AUTHOR +// Tim Harrison +// +// ============================================================================ + +#include "ace/OS.h" +#include "ace/Log_Msg.h" +#include "ace/Get_Opt.h" +#include "ace/Local_Tokens.h" +#include "ace/Remote_Tokens.h" +#include "ace/Thread_Manager.h" +#include "ace/Token_Invariants.h" + +#if defined (ACE_HAS_THREADS) + +typedef ACE_Token_Invariant_Manager ACE_TOKEN_INVARIANTS; + +static ACE_Token_Proxy *global_rlock; +static ACE_Token_Proxy *global_wlock; + +static char *server_host = ACE_DEFAULT_SERVER_HOST; +static int server_port = ACE_DEFAULT_SERVER_PORT; +static int ignore_deadlock = 0; +static int threads = 2; +static int iterations = 50; +static int debug = 0; +static int remote = 0; +static int reads = 4; +static int write_sleep = 0; +static int renew = 0; + +static void * +run_thread (void *vp) +{ + ACE_Thread_Manager *thr_mgr = (ACE_Thread_Manager*) vp; + ACE_Thread_Control tc (thr_mgr); + + for (int x = 0; x < iterations; x++) + { + int y = 0; + for (; y < reads; y++) + { + if (global_rlock->acquire () == -1) + { + if (ACE_Log_Msg::instance ()->errnum () == EDEADLK) + { + ACE_DEBUG ((LM_DEBUG, "rlock deadlock detected\n")); + goto READ_DEADLOCK; + } + else return 0; + } + + if (ACE_TOKEN_INVARIANTS::instance ()->acquired (global_rlock) == 0) + ACE_ERROR_RETURN ((LM_ERROR, "reader acquire violated invariant.\n"), 0); + + ACE_DEBUG ((LM_DEBUG, "(%t) rlock acquired.\n")); + } + + if (renew) + { + ACE_TOKEN_INVARIANTS::instance ()->releasing (global_rlock); + + if (global_rlock->renew () == -1) + { + if (ACE_Log_Msg::instance ()->errnum () == EDEADLK) + { + ACE_DEBUG ((LM_DEBUG, "rlock deadlock detected during renew\n")); + goto READ_DEADLOCK; + } + else return 0; + } + + ACE_DEBUG ((LM_DEBUG, "(%t) rlock renewed.\n")); + + if (ACE_TOKEN_INVARIANTS::instance ()->acquired (global_rlock) == 0) + ACE_ERROR_RETURN ((LM_ERROR, "reader renew violated invariant.\n"), 0); + } + + READ_DEADLOCK: + + for (; y > 0; y--) + { + ACE_TOKEN_INVARIANTS::instance ()->releasing (global_rlock); + if (global_rlock->release () == 0) + ACE_DEBUG ((LM_DEBUG, "(%t) r-released.\n")); + } + + if (global_wlock->acquire () == -1) + ACE_DEBUG ((LM_DEBUG, "wlock deadlock detected\n")); + else + { + if (write_sleep) + ACE_OS::sleep (1); + ACE_DEBUG ((LM_DEBUG, "\t\t(%t) wlock acquired.\n")); + + if (ACE_TOKEN_INVARIANTS::instance ()->acquired (global_wlock) == 0) + ACE_ERROR_RETURN ((LM_ERROR, "writer acquire violated invariant.\n"), 0); + + if (renew) + { + ACE_TOKEN_INVARIANTS::instance ()->releasing (global_wlock); + + if (global_wlock->renew () == -1) + { + if (ACE_Log_Msg::instance ()->errnum () == EDEADLK) + { + ACE_DEBUG ((LM_DEBUG, "wlock deadlock detected during renew\n")); + } + else return 0; + } + + ACE_DEBUG ((LM_DEBUG, "(%t) rlock renewed.\n")); + + if (ACE_TOKEN_INVARIANTS::instance ()->acquired (global_wlock) == 0) + ACE_ERROR_RETURN ((LM_ERROR, "writer renew violated invariant.\n"), 0); + } + + ACE_TOKEN_INVARIANTS::instance ()->releasing (global_wlock); + + if (global_wlock->release () == 0) + ACE_DEBUG ((LM_DEBUG, "\t\t(%t) w-released.\n")); + } + } + + ACE_DEBUG ((LM_DEBUG, "(%t) thread exiting.\n")); + return 0; +} + +static int +parse_args (int argc, char *argv[]) +{ + ACE_LOG_MSG->open (argv[0], ACE_Log_Msg::STDERR); // | ACE_Log_Msg::VERBOSE); + + ACE_Get_Opt get_opt (argc, argv, "t:iun:dr:sp:h:R", 1); + + for (int c; (c = get_opt ()) != -1; ) + { + switch (c) + { + case 'h': // specify the host machine on which the server is running + server_host = get_opt.optarg; + remote = 1; + break; + case 'p': // specify the port on which the server is running + server_port = ACE_OS::atoi (get_opt.optarg); + remote = 1; + break; + case 't': + threads = ACE_OS::atoi (get_opt.optarg); + break; + case 'R': + renew = 1; + break; + case 'r': + reads = ACE_OS::atoi (get_opt.optarg); + break; + case 'd': + debug = 1; + break; + case 's': + write_sleep = 1; + break; + case 'n': + iterations = ACE_OS::atoi (get_opt.optarg); + break; + case 'i': + ignore_deadlock = 1; + break; + case 'u': + // usage: fallthrough + default: + ACE_ERROR_RETURN ((LM_ERROR, + "%n:\n" + "[-h <remote host>]\n" + "[-p <remote port>]\n" + "[-i ignore deadlock]\n" + "[-n <iterations>]\n" + "[-R perform renews]\n" + "[-r <reads>]\n" + "[-d debug]\n" + "[-s sleep during writes]\n" + "[-t <threads>\n", 1), -1); + break; + } + } + + return 0; +} + +#if defined (ACE_HAS_PTHREADS) +#define SUSPEND 0 +#else +#define SUSPEND THR_SUSPENDED +#endif + +int +main (int argc, char* argv[]) +{ + if (parse_args (argc, argv) == -1) + return -1; + + if (remote) + { + ACE_Remote_Mutex::set_server_address (ACE_INET_Addr (server_port, server_host)); + global_rlock = (ACE_Token_Proxy *) new + ACE_Remote_RLock ("THE_TOKEN", ignore_deadlock, debug); + global_wlock = (ACE_Token_Proxy *) new + ACE_Remote_WLock ("THE_TOKEN", ignore_deadlock, debug); + } + else + { + global_rlock = (ACE_Token_Proxy *) new + ACE_Local_RLock ("THE_TOKEN", ignore_deadlock, debug); + global_wlock = (ACE_Token_Proxy *) new + ACE_Local_WLock ("THE_TOKEN", ignore_deadlock, debug); + } + + ACE_Thread_Manager mgr; + + if (mgr.spawn_n (threads, ACE_THR_FUNC (run_thread), + (void *) &mgr, THR_BOUND | SUSPEND) == -1) + ACE_ERROR_RETURN ((LM_DEBUG, "%p\n", "spawn failed"), -1); + +#if ! defined (ACE_HAS_PTHREADS) + if (mgr.resume_all () == -1) + ACE_ERROR_RETURN ((LM_DEBUG, "%p\n", "resume failed"), -1); +#endif + + mgr.wait (); + + return 42; +} + +#else +int +main (int, char *[]) +{ + ACE_ERROR_RETURN ((LM_ERROR, + "threads not supported on this platform\n"), -1); +} +#endif /* ACE_HAS_THREADS */ diff --git a/netsvcs/lib/Client_Logging_Handler.cpp b/netsvcs/lib/Client_Logging_Handler.cpp new file mode 100644 index 00000000000..9ef906172b5 --- /dev/null +++ b/netsvcs/lib/Client_Logging_Handler.cpp @@ -0,0 +1,373 @@ +// Client_Logging_Handler.cpp +// @(#)Client_Logging_Handler.cpp 1.1 10/18/96 + +#define ACE_BUILD_SVC_DLL +#include "ace/Service_Config.h" +#include "ace/Connector.h" +#include "ace/Log_Msg.h" +#include "ace/Get_Opt.h" +#include "ace/SOCK_Connector.h" +#include "ace/SOCK_Stream.h" +#include "ace/FIFO_Recv_Msg.h" +#include "Client_Logging_Handler.h" + +class ACE_Svc_Export ACE_Client_Logging_Handler : public ACE_Svc_Handler<ACE_SOCK_STREAM, ACE_NULL_SYNCH> + // = TITLE + // 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. + // + // = DESCRIPTION + // +{ +public: + // = Initialization and termination. + + ACE_Client_Logging_Handler (const char rendezvous[]); + // Default constructor. + + virtual int open (void * = 0); + // Activate this instance of the <ACE_Client_Logging_Handler> + // (called by the <ACE_Client_Logging_Connector>). + + virtual ACE_HANDLE get_handle (void) const; + // Return the handle of the message_fifo_; + + virtual int close (u_long); + // Called when object is removed from the ACE_Reactor + +protected: + virtual int handle_signal (int signum, siginfo_t *, ucontext_t *); + // Handle SIGINT. + + virtual int handle_input (ACE_HANDLE); + // Receive logging records from applications. + + virtual int handle_exception (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_output (ACE_HANDLE); + // Called back when it's ok to send. + + int send (ACE_Log_Record &log_record); + // Send the <log_record> to the logging server. + + ACE_FIFO_Recv_Msg message_fifo_; + // Message queue we use to receive logging records from clients. + + ACE_HANDLE logging_output_; + // This is either a SOCKET (if we're connected to a logging server) + // or ACE_STDOUT. + + static void stderr_output (int = 0); +}; + +ACE_Client_Logging_Handler::ACE_Client_Logging_Handler (const char rendezvous[]) + : logging_output_ (ACE_STDOUT) +{ + if (ACE_OS::unlink (rendezvous) == -1 && errno == EACCES) + ACE_ERROR ((LM_ERROR, "%p\n", "unlink")); + else if (this->message_fifo_.open (rendezvous) == -1) + ACE_ERROR ((LM_ERROR, "%p\n", "open")); + // Register message FIFO to receive input from clients. Note that we need to + // put the EXCEPT_MASK here to deal with SVR4 MSG_BAND data correctly... + else if (ACE_Service_Config::reactor ()->register_handler + (this->message_fifo_.get_handle (), this, + ACE_Event_Handler::READ_MASK | ACE_Event_Handler::EXCEPT_MASK) == -1) + ACE_ERROR ((LM_ERROR, "%n: %p\n", + "register_handler (message_fifo)")); + ACE_DEBUG ((LM_DEBUG, + "opened fifo at %s on handle %d\n", + rendezvous, + this->message_fifo_.get_handle ())); +} + +// This is called when a <send> to the logging server fails... + +int +ACE_Client_Logging_Handler::handle_signal (int signum, siginfo_t *, ucontext_t *) +{ + ACE_TRACE ("ACE_Client_Logging_Connector::handle_signal"); +// return 0; + return -1; +} + +int +ACE_Client_Logging_Handler::open (void *) +{ + ACE_INET_Addr server_addr; + + this->logging_output_ = this->peer ().get_handle (); + + // Register ourselves to receive SIGPIPE so we can attempt + // reconnections. + if (ACE_Service_Config::reactor ()->register_handler (SIGPIPE, this) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%n: %p\n", + "register_handler (SIGPIPE)"), -1); + + // 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, "%p\n", "get_remote_addr"), -1); + + ACE_DEBUG ((LM_DEBUG, + "starting up Client Logging Daemon, " + "connected to port %d on handle %d\n", + server_addr.get_port_number (), + this->peer ().get_handle ())); + return 0; +} + +/* VIRTUAL */ ACE_HANDLE +ACE_Client_Logging_Handler::get_handle (void) const +{ + ACE_TRACE ("ACE_Client_Logging_Handler::get_handle"); + return this->message_fifo_.get_handle (); +} + + +// Receive a logging record from an application. + +int +ACE_Client_Logging_Handler::handle_input (ACE_HANDLE handle) +{ + if (handle == this->message_fifo_.get_handle ()) + { + // We're getting a logging message from a local application. + + ACE_Log_Record log_record; + ACE_Str_Buf msg ((void *) &log_record, + 0, sizeof log_record); + + ACE_DEBUG ((LM_DEBUG, "in handle_input\n")); + if (this->message_fifo_.recv (msg) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "ACE_FIFO_Recv_Msg::recv"), -1); + else if (this->send (log_record) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "send"), 0); + return 0; + } + else if (handle == this->peer ().get_handle ()) + { + // We're getting a message from the logging server! + ACE_ASSERT (!"this shouldn't happen yet...\n"); + } + 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) +{ + ACE_DEBUG ((LM_DEBUG, "shutting down!!!\n")); + this->message_fifo_.close (); + return 0; +} + +int +ACE_Client_Logging_Handler::handle_output (ACE_HANDLE 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) +{ + if (this->logging_output_ == ACE_STDOUT) + log_record.print ("<localhost>", 0, stderr); + else + { + long len = log_record.length (); + long encoded_len = htonl (len); + + log_record.encode (); + + if (this->peer ().send (4, &encoded_len, sizeof encoded_len, + (char *) &log_record, len) == -1) + // Switch over to logging to stdout for now. In the long + // run, we'll need to queue up the message, try to + // reestablish a connection, and then send the queued data + // once we've reconnect to the logging server. + this->logging_output_ = ACE_STDOUT; + } + + return 0; +} + + +class ACE_Client_Logging_Connector : public ACE_Connector<ACE_Client_Logging_Handler, ACE_SOCK_CONNECTOR> + // = TITLE + // This class contains the service-specific methods that can't + // easily be factored into the <ACE_Connector>. +{ +protected: + // = Dynamic linking hooks. + virtual int init (int argc, char *argv[]); + // Called when service is linked. + + virtual int fini (void); + // Called when service is unlinked. + + virtual int info (char **strp, size_t length) const; + // Called to determine info about the service. + + // = Scheduling hooks. + virtual int suspend (void); + virtual int resume (void); + + virtual int handle_signal (int signum, siginfo_t *, ucontext_t *); + // Handle SIGINT. + +private: + int parse_args (int argc, char *argv[]); + // Parse svc.conf arguments. + + const char *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 of the logging server. + + const char *rendezvous_key_; + // Filename where the FIFO will listen for application logging + // records. + + ACE_Client_Logging_Handler *handler_; + // Pointer to the handler that does the work. +}; + +int +ACE_Client_Logging_Connector::fini (void) +{ + this->handler_->destroy (); + return 0; +} + +int +ACE_Client_Logging_Connector::info (char **strp, size_t length) const +{ + char buf[BUFSIZ]; + + ACE_OS::sprintf (buf, "%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); +} + +int +ACE_Client_Logging_Connector::init (int argc, char *argv[]) +{ + ACE_LOG_MSG->open ("Client Logging Service"); + + // Use the options hook to parse the command line arguments and set + // options. + this->parse_args (argc, argv); + + // Register ourselves to receive SIGINT so we can shutdown + // gracefully. + if (ACE_Service_Config::reactor ()->register_handler (SIGINT, this) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%n: %p\n", + "register_handler (SIGINT)"), -1); + + ACE_NEW_RETURN (this->handler_, + ACE_Client_Logging_Handler (this->rendezvous_key_), + -1); + + // Establish connection with the server. + if (this->connect (this->handler_, + this->server_addr_, + ACE_Synch_Options::synch) == -1) + ACE_ERROR ((LM_ERROR, "%p, using stdout\n", + "can't connect to logging server")); + return 0; +} + +int +ACE_Client_Logging_Connector::parse_args (int argc, char *argv[]) +{ + this->rendezvous_key_ = ACE_DEFAULT_RENDEZVOUS; + this->server_port_ = ACE_DEFAULT_LOGGING_SERVER_PORT; + this->server_host_ = ACE_DEFAULT_SERVER_HOST; + + ACE_Get_Opt get_opt (argc, argv, "h:k:p:", 0); + + for (int c; (c = get_opt ()) != -1; ) + { + switch (c) + { + case 'h': + this->server_host_ = get_opt.optarg; + break; + case 'k': + this->rendezvous_key_ = get_opt.optarg; + break; + case 'p': + this->server_port_ = ACE_OS::atoi (get_opt.optarg); + break; + default: + ACE_ERROR_RETURN ((LM_ERROR, + "%n:\n[-p server-port]\n%a", 1), + -1); + break; + } + } + + this->server_addr_.set (this->server_port_, this->server_host_); + return 0; +} + +int +ACE_Client_Logging_Connector::suspend (void) +{ + // To be done... + return 0; +} + +int +ACE_Client_Logging_Connector::resume (void) +{ + // To be done... + return 0; +} + +// Signal the server to shutdown gracefully. + +int +ACE_Client_Logging_Connector::handle_signal (int signum, siginfo_t *, ucontext_t *) +{ + ACE_TRACE ("ACE_Client_Logging_Connector::handle_signal"); + ACE_Service_Config::end_reactor_event_loop (); + 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_Connector) + +#if defined (ACE_TEMPLATES_REQUIRE_SPECIALIZATION) +template class ACE_Connector<ACE_Client_Logging_Handler, ACE_SOCK_Connector, ACE_INET_Addr>; +#endif /* ACE_TEMPLATES_REQUIRE_SPECIALIZATION */ diff --git a/netsvcs/lib/Client_Logging_Handler.h b/netsvcs/lib/Client_Logging_Handler.h new file mode 100644 index 00000000000..7d18a7af6e7 --- /dev/null +++ b/netsvcs/lib/Client_Logging_Handler.h @@ -0,0 +1,25 @@ +/* -*- C++ -*- */ +// @(#)Client_Logging_Handler.h 1.1 10/18/96 + + +// ============================================================================ +// +// = LIBRARY +// ace +// +// = FILENAME +// Client_Logging_Handler.h +// +// = AUTHOR +// Doug Schmidt +// +// ============================================================================ + +#if !defined (ACE_CLIENT_LOGGER_H) +#define ACE_CLIENT_LOGGER_H + +#include "ace/OS.h" + +ACE_SVC_FACTORY_DECLARE (ACE_Client_Logging_Connector) + +#endif /* ACE_CLIENT_LOGGER_H */ diff --git a/netsvcs/lib/Client_Logging_Handler.i b/netsvcs/lib/Client_Logging_Handler.i new file mode 100644 index 00000000000..e5cdb810e6b --- /dev/null +++ b/netsvcs/lib/Client_Logging_Handler.i @@ -0,0 +1,4 @@ +/* -*- C++ -*- */ +// @(#)Client_Logging_Handler.i 1.1 10/18/96 + + diff --git a/netsvcs/lib/Logging_Strategy.cpp b/netsvcs/lib/Logging_Strategy.cpp new file mode 100644 index 00000000000..af2a0fc5f31 --- /dev/null +++ b/netsvcs/lib/Logging_Strategy.cpp @@ -0,0 +1,145 @@ +// Logging_Strategy.cpp +// @(#)Logging_Strategy.cpp 1.1 10/18/96 + +#define ACE_BUILD_SVC_DLL +#include "iostream.h" +#include "fstream.h" +#include "ace/Get_Opt.h" +#include "ace/Log_Msg.h" +#include "ace/Service_Object.h" +#include "Logging_Strategy.h" + +class ACE_Logging_Strategy : public ACE_Service_Object + // = TITLE + // This class provides the hooks to control the output produced + // by any of the network services. + // + // = DESCRIPTION + // Depending upon when this service is invoked and with what + // flags, the output of other network services can be + // controlled. The output can be streamed to stderr, to a file, + // to a logging daemon, or it can be set to be "silent". +{ +public: + virtual int init (int argc, char *argv[]); + // Dynamic linking hook. + + int parse_args (int argc, char *argv[]); + // Parse svc.conf arguments. +private: + void tokenize (char *flag_string); + // Tokenize to set all the flags + u_long flags_; + char *filename_; +}; + +// Parse the string containing all the flags and set the flags accordingly +void +ACE_Logging_Strategy::tokenize (char *flag_string) +{ + char *flag; + if ((flag = ACE_OS::strtok (flag_string, "|")) != NULL) + { + while (flag) + { + if (ACE_OS::strcmp (flag, "STDERR") == 0) + ACE_SET_BITS (this->flags_, ACE_Log_Msg::STDERR); + else if (ACE_OS::strcmp (flag, "LOGGER") == 0) + ACE_SET_BITS (this->flags_, ACE_Log_Msg::LOGGER); + else if (ACE_OS::strcmp (flag, "OSTREAM") == 0) + ACE_SET_BITS (this->flags_, ACE_Log_Msg::OSTREAM); + else if (ACE_OS::strcmp (flag, "VERBOSE") == 0) + ACE_SET_BITS (this->flags_, ACE_Log_Msg::VERBOSE); + else if (ACE_OS::strcmp (flag, "SILENT") == 0) + ACE_SET_BITS (this->flags_, ACE_Log_Msg::SILENT); + + // Get the next flag + flag = ACE_OS::strtok(0, "|"); + } + } +} + +int +ACE_Logging_Strategy::parse_args (int argc, char *argv[]) +{ + ACE_TRACE ("ACE_Logging_Strategy::parse_args"); + char *temp; + u_long flag = 0; + + this->flags_ = 0; + this->filename_ = ACE_DEFAULT_LOGFILE; + + ACE_LOG_MSG->open ("Logging_Strategy"); + + ACE_Get_Opt get_opt (argc, argv, "f:s:", 0); + + for (int c; (c = get_opt ()) != -1; ) + { + switch (c) + { + case 'f': + temp = get_opt.optarg; + // Now tokenize the string to get all the flags + this->tokenize (temp); + break; + case 's': + // Ensure that the OSTREAM flag is set + ACE_SET_BITS (this->flags_, ACE_Log_Msg::OSTREAM); + this->filename_ = get_opt.optarg; + break; + default: + break; + } + } + return 0; +} + +int +ACE_Logging_Strategy::init (int argc, char *argv[]) +{ + ACE_TRACE ("ACE_Logging_Strategy::init"); + + // Use the options hook to parse the command line arguments. + this->parse_args (argc, argv); + + // Check if any flags were specified. If none were specified, let + // the default behavior take effect. + if (this->flags_ != 0) + { + // Clear all flags + ACE_Log_Msg::instance()->clr_flags (ACE_Log_Msg::STDERR | + ACE_Log_Msg::LOGGER | + ACE_Log_Msg::OSTREAM | + ACE_Log_Msg::VERBOSE | + ACE_Log_Msg::SILENT); + // Check if OSTREAM bit is set + if (ACE_BIT_ENABLED (this->flags_, ACE_Log_Msg::OSTREAM)) + { + // Create a new ofstream to direct output to the file + ofstream *output_file = new ofstream (this->filename_); + ACE_Log_Msg::instance()->msg_ostream (output_file); + } + // Now set the flags for Log_Msg + ACE_Log_Msg::instance()->set_flags (this->flags_); + } + return 0; +} + +// The following is a "Factory" used by the ACE_Service_Config and +// svc.conf file to dynamically initialize the state of the Logging_Strategy. + +ACE_SVC_FACTORY_DEFINE (ACE_Logging_Strategy) + +#if defined (ACE_TEMPLATES_REQUIRE_SPECIALIZATION) +template class ACE_Strategy_Acceptor<ACE_TS_Server_Handler, ACE_SOCK_Acceptor, ACE_INET_Addr>; +template class ACE_Schedule_All_Reactive_Strategy<ACE_TS_Server_Handler>; +#if defined (ACE_HAS_THREADS) +template class ACE_Svc_Handler<ACE_SOCK_Stream, ACE_INET_Addr, ACE_Null_Mutex, ACE_Null_Condition_Mutex>; +template class ACE_Task<ACE_Null_Mutex, ACE_Null_Condition_Mutex>; +template class ACE_Message_Queue<ACE_Null_Mutex, ACE_Null_Condition_Mutex>; +template class ACE_Module<ACE_Null_Mutex, ACE_Null_Condition_Mutex>; +template class ACE_Task_Exit<ACE_Null_Mutex, ACE_Null_Condition_Mutex>; +template class ACE_TSS<ACE_Task_Exit<ACE_Null_Mutex, ACE_Null_Condition_Mutex> >; +template class ACE_Thru_Task<ACE_Null_Mutex, ACE_Null_Condition_Mutex>; +#endif +#endif /* ACE_TEMPLATES_REQUIRE_SPECIALIZATION */ diff --git a/netsvcs/lib/Logging_Strategy.h b/netsvcs/lib/Logging_Strategy.h new file mode 100644 index 00000000000..c1d94f48313 --- /dev/null +++ b/netsvcs/lib/Logging_Strategy.h @@ -0,0 +1,25 @@ +/* -*- C++ -*- */ +// @(#)Logging_Strategy.h 1.1 10/18/96 + + +// ============================================================================ +// +// = LIBRARY +// ace +// +// = FILENAME +// Logging_Strategy.h +// +// = AUTHOR +// Prashant Jain +// +// ============================================================================ + +#if !defined (ACE_LOGGING_STRATEGY_H) +#define ACE_LOGGING_STRATEGY_H + +#include "ace/OS.h" + +ACE_SVC_FACTORY_DECLARE (ACE_Logging_Strategy) + +#endif /* ACE_LOGGING_STRATEGY_H */ diff --git a/netsvcs/lib/Makefile b/netsvcs/lib/Makefile new file mode 100644 index 00000000000..05b70cdbab2 --- /dev/null +++ b/netsvcs/lib/Makefile @@ -0,0 +1,465 @@ +#---------------------------------------------------------------------------- +# @(#)Makefile 1.1 10/18/96 +# +# Makefile for the server-side ACE network services +#---------------------------------------------------------------------------- + +#LIB = libnet_svcs.a +SHLIB = libnet_svcs.so + +FILES = TS_Server_Handler \ + TS_Clerk_Handler \ + Client_Logging_Handler \ + Name_Handler \ + Server_Logging_Handler \ + Token_Handler \ + Logging_Strategy + +DEFS = $(addsuffix .h,$(FILES)) +LSRC = $(addsuffix .cpp,$(FILES)) + +LIBS += -lACE + +BUILD = $(VLIB) $(VSHLIB) + +#---------------------------------------------------------------------------- +# Include macros and targets +#---------------------------------------------------------------------------- + +include $(WRAPPER_ROOT)/include/makeinclude/wrapper_macros.GNU +include $(WRAPPER_ROOT)/include/makeinclude/macros.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.common.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.nonested.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.lib.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.local.GNU + +#---------------------------------------------------------------------------- +# Dependencies +#---------------------------------------------------------------------------- +# DO NOT DELETE THIS LINE -- g++dep uses it. +# DO NOT PUT ANYTHING AFTER THIS LINE, IT WILL GO AWAY. + +.obj/TS_Server_Handler.o .shobj/TS_Server_Handler.so: TS_Server_Handler.cpp \ + $(WRAPPER_ROOT)/ace/SString.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/Set.h \ + $(WRAPPER_ROOT)/ace/Get_Opt.h \ + $(WRAPPER_ROOT)/ace/Acceptor.h \ + $(WRAPPER_ROOT)/ace/Service_Config.h \ + $(WRAPPER_ROOT)/ace/Service_Object.h \ + $(WRAPPER_ROOT)/ace/Shared_Object.h \ + $(WRAPPER_ROOT)/ace/Event_Handler.h \ + $(WRAPPER_ROOT)/ace/Thread_Manager.h \ + $(WRAPPER_ROOT)/ace/Thread.h \ + $(WRAPPER_ROOT)/ace/Synch.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.i \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.i \ + $(WRAPPER_ROOT)/ace/Synch_T.h \ + $(WRAPPER_ROOT)/ace/Proactor.h \ + $(WRAPPER_ROOT)/ace/Message_Block.h \ + $(WRAPPER_ROOT)/ace/Malloc.h \ + $(WRAPPER_ROOT)/ace/Malloc_T.h \ + $(WRAPPER_ROOT)/ace/Memory_Pool.h \ + $(WRAPPER_ROOT)/ace/Signal.h \ + $(WRAPPER_ROOT)/ace/Mem_Map.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.i \ + $(WRAPPER_ROOT)/ace/ReactorEx.h \ + $(WRAPPER_ROOT)/ace/Token.h \ + $(WRAPPER_ROOT)/ace/Reactor.h \ + $(WRAPPER_ROOT)/ace/Handle_Set.h \ + $(WRAPPER_ROOT)/ace/Pipe.h \ + $(WRAPPER_ROOT)/ace/Pipe.i \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.h \ + $(WRAPPER_ROOT)/ace/SOCK_IO.h \ + $(WRAPPER_ROOT)/ace/SOCK.h \ + $(WRAPPER_ROOT)/ace/Addr.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.i \ + $(WRAPPER_ROOT)/ace/SOCK.i \ + $(WRAPPER_ROOT)/ace/SOCK_IO.i \ + $(WRAPPER_ROOT)/ace/INET_Addr.h \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.i \ + $(WRAPPER_ROOT)/ace/Reactor.i \ + $(WRAPPER_ROOT)/ace/Svc_Conf_Tokens.h \ + $(WRAPPER_ROOT)/ace/Svc_Handler.h \ + $(WRAPPER_ROOT)/ace/Synch_Options.h \ + $(WRAPPER_ROOT)/ace/Task.h \ + $(WRAPPER_ROOT)/ace/Message_Queue.h \ + $(WRAPPER_ROOT)/ace/IO_Cntl_Msg.h \ + $(WRAPPER_ROOT)/ace/Strategies.h \ + $(WRAPPER_ROOT)/ace/Acceptor.i \ + $(WRAPPER_ROOT)/ace/SOCK_Acceptor.h \ + $(WRAPPER_ROOT)/ace/Time_Request_Reply.h \ + TS_Server_Handler.h +.obj/TS_Clerk_Handler.o .shobj/TS_Clerk_Handler.so: TS_Clerk_Handler.cpp \ + $(WRAPPER_ROOT)/ace/Service_Config.h \ + $(WRAPPER_ROOT)/ace/Service_Object.h \ + $(WRAPPER_ROOT)/ace/Shared_Object.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/Event_Handler.h \ + $(WRAPPER_ROOT)/ace/Thread_Manager.h \ + $(WRAPPER_ROOT)/ace/Thread.h \ + $(WRAPPER_ROOT)/ace/Synch.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.i \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.i \ + $(WRAPPER_ROOT)/ace/Synch_T.h \ + $(WRAPPER_ROOT)/ace/Set.h \ + $(WRAPPER_ROOT)/ace/Proactor.h \ + $(WRAPPER_ROOT)/ace/Message_Block.h \ + $(WRAPPER_ROOT)/ace/Malloc.h \ + $(WRAPPER_ROOT)/ace/Malloc_T.h \ + $(WRAPPER_ROOT)/ace/Memory_Pool.h \ + $(WRAPPER_ROOT)/ace/Signal.h \ + $(WRAPPER_ROOT)/ace/Mem_Map.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.i \ + $(WRAPPER_ROOT)/ace/ReactorEx.h \ + $(WRAPPER_ROOT)/ace/Token.h \ + $(WRAPPER_ROOT)/ace/Reactor.h \ + $(WRAPPER_ROOT)/ace/Handle_Set.h \ + $(WRAPPER_ROOT)/ace/Pipe.h \ + $(WRAPPER_ROOT)/ace/Pipe.i \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.h \ + $(WRAPPER_ROOT)/ace/SOCK_IO.h \ + $(WRAPPER_ROOT)/ace/SOCK.h \ + $(WRAPPER_ROOT)/ace/Addr.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.i \ + $(WRAPPER_ROOT)/ace/SOCK.i \ + $(WRAPPER_ROOT)/ace/SOCK_IO.i \ + $(WRAPPER_ROOT)/ace/INET_Addr.h \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.i \ + $(WRAPPER_ROOT)/ace/Reactor.i \ + $(WRAPPER_ROOT)/ace/Svc_Conf_Tokens.h \ + $(WRAPPER_ROOT)/ace/Connector.h \ + $(WRAPPER_ROOT)/ace/Map_Manager.h \ + $(WRAPPER_ROOT)/ace/Svc_Handler.h \ + $(WRAPPER_ROOT)/ace/Synch_Options.h \ + $(WRAPPER_ROOT)/ace/Task.h \ + $(WRAPPER_ROOT)/ace/Message_Queue.h \ + $(WRAPPER_ROOT)/ace/IO_Cntl_Msg.h \ + $(WRAPPER_ROOT)/ace/Strategies.h \ + $(WRAPPER_ROOT)/ace/Connector.i \ + $(WRAPPER_ROOT)/ace/Get_Opt.h \ + $(WRAPPER_ROOT)/ace/SOCK_Connector.h \ + $(WRAPPER_ROOT)/ace/SOCK_Connector.i \ + $(WRAPPER_ROOT)/ace/Time_Request_Reply.h \ + $(WRAPPER_ROOT)/ace/SString.h \ + TS_Clerk_Handler.h +.obj/Client_Logging_Handler.o .shobj/Client_Logging_Handler.so: Client_Logging_Handler.cpp \ + $(WRAPPER_ROOT)/ace/Service_Config.h \ + $(WRAPPER_ROOT)/ace/Service_Object.h \ + $(WRAPPER_ROOT)/ace/Shared_Object.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/Event_Handler.h \ + $(WRAPPER_ROOT)/ace/Thread_Manager.h \ + $(WRAPPER_ROOT)/ace/Thread.h \ + $(WRAPPER_ROOT)/ace/Synch.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.i \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.i \ + $(WRAPPER_ROOT)/ace/Synch_T.h \ + $(WRAPPER_ROOT)/ace/Set.h \ + $(WRAPPER_ROOT)/ace/Proactor.h \ + $(WRAPPER_ROOT)/ace/Message_Block.h \ + $(WRAPPER_ROOT)/ace/Malloc.h \ + $(WRAPPER_ROOT)/ace/Malloc_T.h \ + $(WRAPPER_ROOT)/ace/Memory_Pool.h \ + $(WRAPPER_ROOT)/ace/Signal.h \ + $(WRAPPER_ROOT)/ace/Mem_Map.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.i \ + $(WRAPPER_ROOT)/ace/ReactorEx.h \ + $(WRAPPER_ROOT)/ace/Token.h \ + $(WRAPPER_ROOT)/ace/Reactor.h \ + $(WRAPPER_ROOT)/ace/Handle_Set.h \ + $(WRAPPER_ROOT)/ace/Pipe.h \ + $(WRAPPER_ROOT)/ace/Pipe.i \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.h \ + $(WRAPPER_ROOT)/ace/SOCK_IO.h \ + $(WRAPPER_ROOT)/ace/SOCK.h \ + $(WRAPPER_ROOT)/ace/Addr.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.i \ + $(WRAPPER_ROOT)/ace/SOCK.i \ + $(WRAPPER_ROOT)/ace/SOCK_IO.i \ + $(WRAPPER_ROOT)/ace/INET_Addr.h \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.i \ + $(WRAPPER_ROOT)/ace/Reactor.i \ + $(WRAPPER_ROOT)/ace/Svc_Conf_Tokens.h \ + $(WRAPPER_ROOT)/ace/Connector.h \ + $(WRAPPER_ROOT)/ace/Map_Manager.h \ + $(WRAPPER_ROOT)/ace/Svc_Handler.h \ + $(WRAPPER_ROOT)/ace/Synch_Options.h \ + $(WRAPPER_ROOT)/ace/Task.h \ + $(WRAPPER_ROOT)/ace/Message_Queue.h \ + $(WRAPPER_ROOT)/ace/IO_Cntl_Msg.h \ + $(WRAPPER_ROOT)/ace/Strategies.h \ + $(WRAPPER_ROOT)/ace/Connector.i \ + $(WRAPPER_ROOT)/ace/Get_Opt.h \ + $(WRAPPER_ROOT)/ace/SOCK_Connector.h \ + $(WRAPPER_ROOT)/ace/SOCK_Connector.i \ + $(WRAPPER_ROOT)/ace/FIFO_Recv_Msg.h \ + $(WRAPPER_ROOT)/ace/FIFO_Recv.h \ + $(WRAPPER_ROOT)/ace/FIFO.h \ + $(WRAPPER_ROOT)/ace/FIFO_Recv.i \ + $(WRAPPER_ROOT)/ace/FIFO_Recv_Msg.i \ + Client_Logging_Handler.h +.obj/Name_Handler.o .shobj/Name_Handler.so: Name_Handler.cpp \ + $(WRAPPER_ROOT)/ace/SString.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/Set.h \ + $(WRAPPER_ROOT)/ace/Get_Opt.h \ + $(WRAPPER_ROOT)/ace/Naming_Context.h \ + $(WRAPPER_ROOT)/ace/Service_Object.h \ + $(WRAPPER_ROOT)/ace/Shared_Object.h \ + $(WRAPPER_ROOT)/ace/Event_Handler.h \ + $(WRAPPER_ROOT)/ace/Name_Proxy.h \ + $(WRAPPER_ROOT)/ace/INET_Addr.h \ + $(WRAPPER_ROOT)/ace/Addr.h \ + $(WRAPPER_ROOT)/ace/SOCK_Connector.h \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.h \ + $(WRAPPER_ROOT)/ace/SOCK_IO.h \ + $(WRAPPER_ROOT)/ace/SOCK.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.i \ + $(WRAPPER_ROOT)/ace/SOCK.i \ + $(WRAPPER_ROOT)/ace/SOCK_IO.i \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.i \ + $(WRAPPER_ROOT)/ace/SOCK_Connector.i \ + $(WRAPPER_ROOT)/ace/Service_Config.h \ + $(WRAPPER_ROOT)/ace/Thread_Manager.h \ + $(WRAPPER_ROOT)/ace/Thread.h \ + $(WRAPPER_ROOT)/ace/Synch.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.i \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.i \ + $(WRAPPER_ROOT)/ace/Synch_T.h \ + $(WRAPPER_ROOT)/ace/Proactor.h \ + $(WRAPPER_ROOT)/ace/Message_Block.h \ + $(WRAPPER_ROOT)/ace/Malloc.h \ + $(WRAPPER_ROOT)/ace/Malloc_T.h \ + $(WRAPPER_ROOT)/ace/Memory_Pool.h \ + $(WRAPPER_ROOT)/ace/Signal.h \ + $(WRAPPER_ROOT)/ace/Mem_Map.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.i \ + $(WRAPPER_ROOT)/ace/ReactorEx.h \ + $(WRAPPER_ROOT)/ace/Token.h \ + $(WRAPPER_ROOT)/ace/Reactor.h \ + $(WRAPPER_ROOT)/ace/Handle_Set.h \ + $(WRAPPER_ROOT)/ace/Pipe.h \ + $(WRAPPER_ROOT)/ace/Pipe.i \ + $(WRAPPER_ROOT)/ace/Reactor.i \ + $(WRAPPER_ROOT)/ace/Svc_Conf_Tokens.h \ + $(WRAPPER_ROOT)/ace/Synch_Options.h \ + $(WRAPPER_ROOT)/ace/Name_Request_Reply.h \ + $(WRAPPER_ROOT)/ace/Name_Space.h \ + $(WRAPPER_ROOT)/ace/Acceptor.h \ + $(WRAPPER_ROOT)/ace/Svc_Handler.h \ + $(WRAPPER_ROOT)/ace/Task.h \ + $(WRAPPER_ROOT)/ace/Message_Queue.h \ + $(WRAPPER_ROOT)/ace/IO_Cntl_Msg.h \ + $(WRAPPER_ROOT)/ace/Strategies.h \ + $(WRAPPER_ROOT)/ace/Acceptor.i \ + $(WRAPPER_ROOT)/ace/SOCK_Acceptor.h \ + Name_Handler.h +.obj/Server_Logging_Handler.o .shobj/Server_Logging_Handler.so: Server_Logging_Handler.cpp \ + $(WRAPPER_ROOT)/ace/Synch.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.i \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.i \ + $(WRAPPER_ROOT)/ace/Synch_T.h \ + $(WRAPPER_ROOT)/ace/Event_Handler.h \ + $(WRAPPER_ROOT)/ace/TLI_Acceptor.h \ + $(WRAPPER_ROOT)/ace/TLI.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.i \ + $(WRAPPER_ROOT)/ace/Addr.h \ + $(WRAPPER_ROOT)/ace/TLI.i \ + $(WRAPPER_ROOT)/ace/TLI_Stream.h \ + $(WRAPPER_ROOT)/ace/INET_Addr.h \ + $(WRAPPER_ROOT)/ace/TLI_Stream.i \ + $(WRAPPER_ROOT)/ace/TLI_Acceptor.i \ + $(WRAPPER_ROOT)/ace/SOCK_Acceptor.h \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.h \ + $(WRAPPER_ROOT)/ace/SOCK_IO.h \ + $(WRAPPER_ROOT)/ace/SOCK.h \ + $(WRAPPER_ROOT)/ace/SOCK.i \ + $(WRAPPER_ROOT)/ace/SOCK_IO.i \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.i \ + $(WRAPPER_ROOT)/ace/Get_Opt.h \ + $(WRAPPER_ROOT)/ace/Acceptor.h \ + $(WRAPPER_ROOT)/ace/Service_Config.h \ + $(WRAPPER_ROOT)/ace/Service_Object.h \ + $(WRAPPER_ROOT)/ace/Shared_Object.h \ + $(WRAPPER_ROOT)/ace/Thread_Manager.h \ + $(WRAPPER_ROOT)/ace/Thread.h \ + $(WRAPPER_ROOT)/ace/Set.h \ + $(WRAPPER_ROOT)/ace/Proactor.h \ + $(WRAPPER_ROOT)/ace/Message_Block.h \ + $(WRAPPER_ROOT)/ace/Malloc.h \ + $(WRAPPER_ROOT)/ace/Malloc_T.h \ + $(WRAPPER_ROOT)/ace/Memory_Pool.h \ + $(WRAPPER_ROOT)/ace/Signal.h \ + $(WRAPPER_ROOT)/ace/Mem_Map.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.i \ + $(WRAPPER_ROOT)/ace/ReactorEx.h \ + $(WRAPPER_ROOT)/ace/Token.h \ + $(WRAPPER_ROOT)/ace/Reactor.h \ + $(WRAPPER_ROOT)/ace/Handle_Set.h \ + $(WRAPPER_ROOT)/ace/Pipe.h \ + $(WRAPPER_ROOT)/ace/Pipe.i \ + $(WRAPPER_ROOT)/ace/Reactor.i \ + $(WRAPPER_ROOT)/ace/Svc_Conf_Tokens.h \ + $(WRAPPER_ROOT)/ace/Svc_Handler.h \ + $(WRAPPER_ROOT)/ace/Synch_Options.h \ + $(WRAPPER_ROOT)/ace/Task.h \ + $(WRAPPER_ROOT)/ace/Message_Queue.h \ + $(WRAPPER_ROOT)/ace/IO_Cntl_Msg.h \ + $(WRAPPER_ROOT)/ace/Strategies.h \ + $(WRAPPER_ROOT)/ace/Acceptor.i \ + Server_Logging_Handler.h +.obj/Token_Handler.o .shobj/Token_Handler.so: Token_Handler.cpp \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/Get_Opt.h \ + $(WRAPPER_ROOT)/ace/Acceptor.h \ + $(WRAPPER_ROOT)/ace/Service_Config.h \ + $(WRAPPER_ROOT)/ace/Service_Object.h \ + $(WRAPPER_ROOT)/ace/Shared_Object.h \ + $(WRAPPER_ROOT)/ace/Event_Handler.h \ + $(WRAPPER_ROOT)/ace/Thread_Manager.h \ + $(WRAPPER_ROOT)/ace/Thread.h \ + $(WRAPPER_ROOT)/ace/Synch.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.h \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Simple.i \ + $(WRAPPER_ROOT)/ace/SV_Semaphore_Complex.i \ + $(WRAPPER_ROOT)/ace/Synch_T.h \ + $(WRAPPER_ROOT)/ace/Set.h \ + $(WRAPPER_ROOT)/ace/Proactor.h \ + $(WRAPPER_ROOT)/ace/Message_Block.h \ + $(WRAPPER_ROOT)/ace/Malloc.h \ + $(WRAPPER_ROOT)/ace/Malloc_T.h \ + $(WRAPPER_ROOT)/ace/Memory_Pool.h \ + $(WRAPPER_ROOT)/ace/Signal.h \ + $(WRAPPER_ROOT)/ace/Mem_Map.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.h \ + $(WRAPPER_ROOT)/ace/Timer_Queue.i \ + $(WRAPPER_ROOT)/ace/ReactorEx.h \ + $(WRAPPER_ROOT)/ace/Token.h \ + $(WRAPPER_ROOT)/ace/Reactor.h \ + $(WRAPPER_ROOT)/ace/Handle_Set.h \ + $(WRAPPER_ROOT)/ace/Pipe.h \ + $(WRAPPER_ROOT)/ace/Pipe.i \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.h \ + $(WRAPPER_ROOT)/ace/SOCK_IO.h \ + $(WRAPPER_ROOT)/ace/SOCK.h \ + $(WRAPPER_ROOT)/ace/Addr.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.h \ + $(WRAPPER_ROOT)/ace/IPC_SAP.i \ + $(WRAPPER_ROOT)/ace/SOCK.i \ + $(WRAPPER_ROOT)/ace/SOCK_IO.i \ + $(WRAPPER_ROOT)/ace/INET_Addr.h \ + $(WRAPPER_ROOT)/ace/SOCK_Stream.i \ + $(WRAPPER_ROOT)/ace/Reactor.i \ + $(WRAPPER_ROOT)/ace/Svc_Conf_Tokens.h \ + $(WRAPPER_ROOT)/ace/Svc_Handler.h \ + $(WRAPPER_ROOT)/ace/Synch_Options.h \ + $(WRAPPER_ROOT)/ace/Task.h \ + $(WRAPPER_ROOT)/ace/Message_Queue.h \ + $(WRAPPER_ROOT)/ace/IO_Cntl_Msg.h \ + $(WRAPPER_ROOT)/ace/Strategies.h \ + $(WRAPPER_ROOT)/ace/Acceptor.i \ + $(WRAPPER_ROOT)/ace/SOCK_Acceptor.h \ + $(WRAPPER_ROOT)/ace/Token_Request_Reply.h \ + $(WRAPPER_ROOT)/ace/Local_Tokens.h \ + $(WRAPPER_ROOT)/ace/Stack.h \ + $(WRAPPER_ROOT)/ace/Map_Manager.h \ + $(WRAPPER_ROOT)/ace/Token_Collection.h \ + $(WRAPPER_ROOT)/ace/SString.h \ + Token_Handler.h +.obj/Logging_Strategy.o .shobj/Logging_Strategy.so: Logging_Strategy.cpp \ + /pkg/gnu/lib/g++-include/iostream.h \ + /pkg/gnu/lib/g++-include/fstream.h \ + $(WRAPPER_ROOT)/ace/Get_Opt.h \ + $(WRAPPER_ROOT)/ace/ACE.h \ + $(WRAPPER_ROOT)/ace/OS.h \ + $(WRAPPER_ROOT)/ace/Time_Value.h \ + $(WRAPPER_ROOT)/ace/config.h \ + $(WRAPPER_ROOT)/ace/Trace.h \ + $(WRAPPER_ROOT)/ace/ACE.i \ + $(WRAPPER_ROOT)/ace/Log_Msg.h \ + $(WRAPPER_ROOT)/ace/Log_Record.h \ + $(WRAPPER_ROOT)/ace/Log_Priority.h \ + $(WRAPPER_ROOT)/ace/Log_Record.i \ + $(WRAPPER_ROOT)/ace/Service_Object.h \ + $(WRAPPER_ROOT)/ace/Shared_Object.h \ + $(WRAPPER_ROOT)/ace/Event_Handler.h \ + Logging_Strategy.h + +# IF YOU PUT ANYTHING HERE IT WILL GO AWAY diff --git a/netsvcs/lib/Name_Handler.cpp b/netsvcs/lib/Name_Handler.cpp new file mode 100644 index 00000000000..e036f42b68b --- /dev/null +++ b/netsvcs/lib/Name_Handler.cpp @@ -0,0 +1,738 @@ +// Name_Handler.cpp +// @(#)Name_Handler.cpp 1.1 10/18/96 + +#define ACE_BUILD_SVC_DLL +#include "ace/SString.h" +#include "ace/Set.h" +#include "ace/Get_Opt.h" +#include "ace/Naming_Context.h" +#include "ace/Acceptor.h" +#include "ace/SOCK_Acceptor.h" +#include "ace/SOCK_Stream.h" +#include "ace/Name_Request_Reply.h" +#include "Name_Handler.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) + +// Forward declaration. +class ACE_Naming_Context; + +class ACE_Svc_Export ACE_Name_Handler : public ACE_Svc_Handler<ACE_SOCK_STREAM, ACE_NULL_SYNCH> + // = TITLE + // Product object created by <ACE_Name_Acceptor>. An + // <ACE_Name_Handler> exchanges messages with a <ACE_Name_Proxy> + // object on the client-side. + // + // = DESCRIPTION + // This class is the main workhorse of the <ACE_Name_Server>. 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. +{ + friend class ACE_Shutup_GPlusPlus; // Turn off g++ warning +public: + typedef int (ACE_Name_Handler::*OPERATION) (void); + // Pointer to a member function of ACE_Name_Handler returning int + + typedef int (ACE_Naming_Context::*LIST_OP) (ACE_PWSTRING_SET &, const ACE_WString &); + // Pointer to a member function of ACE_Naming_Context returning int + + typedef ACE_Name_Request (ACE_Name_Handler::*REQUEST) (ACE_WString *); + // Pointer to a member function of ACE_Name_Handler returning ACE_Name_Request + + // = Initialization and termination. + + ACE_Name_Handler (ACE_Thread_Manager * = 0); + // Default constructor. + + virtual int open (void * = 0); + // Activate this instance of the <ACE_Name_Handler> (called by the + // <ACE_Strategy_Acceptor>). + +protected: + // = Helper routines for the operations exported to clients. + + virtual int abandon (void); + // Give up waiting (e.g., when a timeout occurs or a client shuts + // down unexpectedly). + + // = Low level routines for framing requests, dispatching + // operations, and returning replies. + + virtual int recv_request (void); + // Receive, frame, and decode the client's request. + + virtual int dispatch (void); + // Dispatch the appropriate operation to handle the client's + // request. + + virtual int send_reply (ACE_UINT32 status, ACE_UINT32 errnum = 0); + // Create and send a reply to the client. + + virtual int send_request (ACE_Name_Request &); + // Special kind of reply + + // = Demultiplexing hooks. + virtual ACE_HANDLE get_handle (void) const; + // Return the underlying <ACE_HANDLE>. + + virtual int handle_input (ACE_HANDLE); + // Callback method invoked by the <ACE_Reactor> when client events + // arrive. + + // = Timer hook. + virtual int handle_timeout (const ACE_Time_Value &tv, const void *arg); + // Enable clients to limit the amount of time they wait for a name. + +private: + + OPERATION op_table_[ACE_Name_Request::MAX_ENUM]; + // Table of pointers to member functions + + 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. + + char *description_; + // Name of the operation we're dispatching (used for debugging). + }; + + LIST_ENTRY list_table_[ACE_Name_Request::MAX_LIST]; + // This is the table of pointers to functions that we use to + // simplify the handling of list requests. + + ACE_Naming_Context *naming_context_; + // ACE_Naming_Context of this Handler. + + ACE_Name_Request name_request_; + // Cache request from the client. + + ACE_Name_Request name_request_back_; + // Special kind of reply for resolve and listnames. + + ACE_Name_Reply name_reply_; + // Cache reply to the client. + + ACE_INET_Addr addr_; + // Address of client we are connected with. + + ~ACE_Name_Handler (void); + // Ensure dynamic allocation... + + int bind (void); + // Handle binds. + + int rebind (void); + // Handle rebinds. + + int shared_bind (int rebind); + // Handle binds and rebinds. + + int resolve (void); + // Handle find requests. + + int unbind (void); + // Handle unbind requests. + + int lists (void); + // Handle LIST_NAMES, LIST_VALUES, and LIST_TYPES requests. + + int lists_entries (void); + // Handle LIST_NAME_ENTRIES, LIST_VALUE_ENTRIES, and + // LIST_TYPE_ENTRIES requests. + + ACE_Name_Request name_request (ACE_WString *one_name); + // Create a name request. + + ACE_Name_Request value_request (ACE_WString *one_name); + // Create a value request. + + ACE_Name_Request type_request (ACE_WString *one_name); + // Create a type request. +}; + +class ACE_Name_Acceptor : public ACE_Strategy_Acceptor<ACE_Name_Handler, ACE_SOCK_ACCEPTOR> + // = TITLE + // This class contains the service-specific methods that can't + // easily be factored into the <ACE_Strategy_Acceptor>. +{ +public: + virtual int init (int argc, char *argv[]); + // Dynamic linking hook. + + int parse_args (int argc, char *argv[]); + // Parse svc.conf arguments. + + int handle_signal (int, siginfo_t *, ucontext_t *); + +private: + ACE_Schedule_All_Reactive_Strategy<ACE_Name_Handler> scheduling_strategy_; + // The scheduling strategy is designed for Reactive services. +}; + +int +ACE_Name_Acceptor::handle_signal (int, siginfo_t *, ucontext_t *) +{ + ACE_DEBUG ((LM_DEBUG, "ACE_Name_Acceptor::handle_signal got called\n")); + return 0; +} + +int +ACE_Name_Acceptor::parse_args (int argc, char *argv[]) +{ + ACE_TRACE ("ACE_Name_Acceptor::parse_args"); + + this->service_port_ = ACE_DEFAULT_SERVER_PORT; + + ACE_LOG_MSG->open ("Name Service"); + + ACE_Get_Opt get_opt (argc, argv, "p:", 0); + + for (int c; (c = get_opt ()) != -1; ) + { + switch (c) + { + case 'p': + this->service_port_ = ACE_OS::atoi (get_opt.optarg); + break; + default: + ACE_ERROR_RETURN ((LM_ERROR, + "%n:\n[-p server-port]\n%a", 1), + -1); + break; + } + } + + this->service_addr_.set (this->service_port_); + return 0; +} + +int +ACE_Name_Acceptor::init (int argc, char *argv[]) +{ + ACE_TRACE ("ACE_Name_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_Service_Config::reactor (), + 0, 0, 0, + &this->scheduling_strategy_, + "Name Server", "ACE naming service") == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%n: %p on port %d\n", + "acceptor::open failed", + this->service_addr_.get_port_number ()), -1); + + // Register ourselves to receive SIGINT so we can shutdown + // gracefully. + if (this->reactor ()->register_handler (SIGINT, this) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%n: %p\n", + "register_handler (SIGINT)"), -1); + + // Ignore SIGPIPE so that each <SVC_HANDLER> can handle this on its + // own. + ACE_Sig_Action sig (ACE_SignalHandler (SIG_IGN), SIGPIPE); + + 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, "%p\n", "get_local_addr"), -1); + + ACE_DEBUG ((LM_DEBUG, + "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<ACE_SOCK_STREAM, ACE_NULL_SYNCH> (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 *) +{ + ACE_TRACE ("ACE_Name_Handler::open"); + + // Call down to our parent to register ourselves with the Reactor. + if (ACE_Svc_Handler<ACE_SOCK_STREAM, ACE_NULL_SYNCH>::open (0) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "open"), -1); + + // Instantiate our associated ACE_Naming_Context + ACE_NEW_RETURN (naming_context_, ACE_Naming_Context (ACE_Naming_Context::NET_LOCAL), -1); + + return 0; +} + +// Create and send a reply to the client. + +/* VIRTUAL */ int +ACE_Name_Handler::send_reply (ACE_UINT32 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, "%p\n, expected len = %d, actual len = %d", + "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, "%p\n", "encode failed"), -1); + + // Transmit request via a blocking send. + + if (this->peer ().send_n (buffer, length) != length) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "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 (void) +{ + ACE_TRACE ("ACE_Name_Handler::abandon"); + int failure_reason = errno; + return this->send_reply (ACE_Name_Reply::FAILURE, failure_reason); +} + +// 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 (void) 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 (void) +{ + 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 (void) +{ + 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: + /* FALLTHROUGH */ + ACE_DEBUG ((LM_DEBUG, "****************** recv_request returned -1\n")); + default: + ACE_ERROR ((LM_ERROR, "%p got %d bytes, expected %d bytes\n", + "recv failed", n, sizeof (ACE_UINT32))); + /* 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 = ntohl (this->name_request_.length ()); + + // Do a sanity check on the length of the message. + if (length > sizeof this->name_request_) + { + ACE_ERROR ((LM_ERROR, "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 - sizeof (ACE_UINT32))) + { + ACE_ERROR ((LM_ERROR, "%p expected %d, got %d\n", + "invalid length", length, n)); + return this->abandon (); + } + + // Decode the request into host byte order. + if (this->name_request_.decode () == -1) + { + ACE_ERROR ((LM_ERROR, "%p\n", "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 (void) +{ + ACE_TRACE ("ACE_Name_Handler::bind"); + return this->shared_bind (0); +} + +int +ACE_Name_Handler::rebind (void) +{ + 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_WString a_name (this->name_request_.name (), + this->name_request_.name_len () / sizeof (ACE_USHORT16)); + ACE_WString a_value (this->name_request_.value (), + this->name_request_.value_len () / sizeof (ACE_USHORT16)); + int result; + if (rebind == 0) + { + ACE_DEBUG ((LM_DEBUG, "request for BIND \n")); + result = this->naming_context_->bind (a_name, a_value, + this->name_request_.type ()); + } + else + { + ACE_DEBUG ((LM_DEBUG, "request for REBIND \n")); + 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 (ACE_Name_Reply::SUCCESS); + else return this->send_reply (ACE_Name_Reply::FAILURE); +} + +int +ACE_Name_Handler::resolve (void) +{ + ACE_TRACE ("ACE_Name_Handler::resolve"); + ACE_DEBUG ((LM_DEBUG, "request for RESOLVE \n")); + ACE_WString a_name (this->name_request_.name (), + this->name_request_.name_len () / sizeof (ACE_USHORT16)); + + // The following will deliver our reply back to client we + // pre-suppose success (indicated by type RESOLVE). + + ACE_WString avalue; + char *atype; + if (this->naming_context_->resolve (a_name, avalue, atype) == 0) + { + ACE_Name_Request nrq (ACE_Name_Request::RESOLVE, + NULL, 0, + avalue.rep (), + avalue.length () * sizeof (ACE_USHORT16), + atype, ACE_OS::strlen (atype)); + return this->send_request (nrq); + } + + ACE_Name_Request nrq (ACE_Name_Request::BIND, NULL, 0, NULL, 0, NULL, 0); + this->send_request (nrq); + return 0; +} + +int +ACE_Name_Handler::unbind (void) +{ + ACE_TRACE ("ACE_Name_Handler::unbind"); + ACE_DEBUG ((LM_DEBUG, "request for UNBIND \n")); + ACE_WString a_name (this->name_request_.name (), + this->name_request_.name_len () / sizeof (ACE_USHORT16)); + if (this->naming_context_->unbind (a_name) == 0) + return this->send_reply (ACE_Name_Reply::SUCCESS); + else return this->send_reply (ACE_Name_Reply::FAILURE); +} + +ACE_Name_Request +ACE_Name_Handler::name_request (ACE_WString *one_name) +{ + ACE_TRACE ("ACE_Name_Handler::name_request"); + return ACE_Name_Request (ACE_Name_Request::LIST_NAMES, + one_name->rep (), + one_name->length () * sizeof (ACE_USHORT16), + NULL, 0, + NULL, 0); +} + +ACE_Name_Request +ACE_Name_Handler::value_request (ACE_WString *one_value) +{ + ACE_TRACE ("ACE_Name_Handler::value_request"); + return ACE_Name_Request (ACE_Name_Request::LIST_VALUES, + NULL, 0, + one_value->rep (), + one_value->length () * sizeof (ACE_USHORT16), + NULL, 0); +} + +ACE_Name_Request +ACE_Name_Handler::type_request (ACE_WString *one_type) +{ + ACE_TRACE ("ACE_Name_Handler::type_request"); + return ACE_Name_Request (ACE_Name_Request::LIST_TYPES, + NULL, 0, + NULL, 0, + one_type->char_rep (), + one_type->length ()); +} + +int +ACE_Name_Handler::lists (void) +{ + ACE_TRACE ("ACE_Name_Handler::lists"); + + ACE_PWSTRING_SET set; + ACE_WString pattern (this->name_request_.name (), + this->name_request_.name_len () / sizeof (ACE_USHORT16)); + + // 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, NULL, 0, NULL, 0, NULL, 0); + + if (this->send_request (end_rq) == -1) + return -1; + } + else + { + ACE_WString *one_entry = 0; + + for (ACE_Unbounded_Set_Iterator<ACE_WString> 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, + NULL, 0, + NULL, 0, + NULL, 0); + return this->send_request (nrq); + } + return 0; +} + +int +ACE_Name_Handler::lists_entries (void) +{ + ACE_TRACE ("ACE_Name_Handler::lists_entries"); + ACE_BINDING_SET set; + ACE_WString pattern (this->name_request_.name (), + this->name_request_.name_len () / sizeof (ACE_USHORT16)); + + int (ACE_Naming_Context::*ptmf) (ACE_BINDING_SET &, const ACE_WString &); + + switch (this->name_request_.msg_type ()) + { + case ACE_Name_Request::LIST_NAME_ENTRIES: + ACE_DEBUG ((LM_DEBUG, "request for LIST_NAME_ENTRIES \n")); + ptmf = &ACE_Naming_Context::list_name_entries; + break; + case ACE_Name_Request::LIST_VALUE_ENTRIES: + ACE_DEBUG ((LM_DEBUG, "request for LIST_VALUE_ENTRIES \n")); + ptmf = &ACE_Naming_Context::list_value_entries; + break; + case ACE_Name_Request::LIST_TYPE_ENTRIES: + ACE_DEBUG ((LM_DEBUG, "request for LIST_TYPE_ENTRIES \n")); + ptmf = &ACE_Naming_Context::list_type_entries; + break; + default: + return -1; + } + + if ((this->naming_context_->*ptmf) (set, pattern) != 0) + { + // None found so send blank request back. + ACE_Name_Request end_rq (ACE_Name_Request::MAX_ENUM, NULL, 0, NULL, 0, NULL, 0); + + if (this->send_request (end_rq) == -1) + return -1; + } + else + { + ACE_Name_Binding *one_entry = 0; + + for (ACE_Unbounded_Set_Iterator<ACE_Name_Binding> set_iterator (set); + set_iterator.next (one_entry) !=0; + set_iterator.advance()) + { + ACE_Name_Request mynrq (this->name_request_.msg_type (), + one_entry->name_.rep (), + one_entry->name_.length () * sizeof (ACE_USHORT16), + one_entry->value_.rep (), + one_entry->value_.length () * sizeof (ACE_USHORT16), + 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, NULL, 0, NULL, 0, NULL, 0); + + if (this->send_request (nrq) == -1) + return -1; + } + return 0; +} + +ACE_Name_Handler::~ACE_Name_Handler (void) +{ + ACE_TRACE ("ACE_Name_Handler::~ACE_Name_Handler"); + ACE_DEBUG ((LM_DEBUG, "closing down Handle %d\n", + this->get_handle ())); + + // Delete associated Naming Context. + delete this->naming_context_; +} + +#if defined (ACE_TEMPLATES_REQUIRE_SPECIALIZATION) +template class ACE_Strategy_Acceptor<ACE_Name_Handler, ACE_SOCK_Acceptor, ACE_INET_Addr>; +template class ACE_Schedule_All_Reactive_Strategy<ACE_Name_Handler>; +#endif /* ACE_TEMPLATES_REQUIRE_SPECIALIZATION */ diff --git a/netsvcs/lib/Name_Handler.h b/netsvcs/lib/Name_Handler.h new file mode 100644 index 00000000000..0de9b44ca77 --- /dev/null +++ b/netsvcs/lib/Name_Handler.h @@ -0,0 +1,24 @@ +/* -*- C++ -*- */ +// @(#)Name_Handler.h 1.1 10/18/96 + +// ============================================================================ +// +// = LIBRARY +// ace +// +// = FILENAME +// Name_Handler.h +// +// = AUTHOR +// Prashant Jain, Gerhard Lenzer and Douglas C. Schmidt +// +// ============================================================================ + +#if !defined (ACE_NAME_HANDLER_H) +#define ACE_NAME_HANDLER_H + +#include "ace/OS.h" + +ACE_SVC_FACTORY_DECLARE (ACE_Name_Acceptor) + +#endif /* ACE_NAME_HANDLER_H */ diff --git a/netsvcs/lib/README b/netsvcs/lib/README new file mode 100644 index 00000000000..a85ce77b82f --- /dev/null +++ b/netsvcs/lib/README @@ -0,0 +1,270 @@ +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 distributed 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: +<CODE> + + -f <flag1>|<flag2>|<flag3> (etc...) +</CODE> + where a flag can be any of the following: + + 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: + +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" + +==================== Name Service ==================== + +This file describes the principles of the Name_Server server test +application. + +1. Startup configuration + --------------------- + +To communicate with the server process, a client needs to know the +INET_Addr, where the server offers its service. Class Name_Options +holds all the configuration information of the Name Service. This +consists of : + + - nameserver_port : Port number where the server process expects requests + - nameserver_host : hostname where the server process resides + - namespace_dir : directory that holds the NameBinding databases + - process_name : name of the client process (argv[0]), NameBindings of + a ProcessLocal namespace are stored in file + "namespace_dir/process_name". NameBindings of NodeGlobal + namespace are stored in "namespace_dir/localnames". + NameBindings of Net_Local namespace are stored in file + "namespace_dir/globalnames" on the server host. + These configuration parameters are passed to the process as commandline + arguments to main: + -p nameserver port + -h nameserver host + -l namespace directory + + The main program _must_ initialize an instance of Name_Options with name + name_options (since the shared libraries depend on this). Main should + look like : + + #include "ace/Name_Options.h" + + Name_Options name_options; + + int main(int argc, char **argv) + { + name_options.process_name(argv[0]); + name_options.parse_args (argc, argv); + ...... + } + +See the examples in the tests subdirectory of +...Name_Server/Client-Server/client and +...Name_Server/Client-Server/server + + +2. Class Naming_Context + ------------------- + +This is the main workhorse of the Name Service. It is used by client +processes as well as by the server process. It manages all accesses to +the appropriate NameBinding database (that is the file where +NameBindings are stored) and it also manages the communication between +a client process and the server (by using class Name_Proxy, which is a +private member of Naming_Context). (Note: no IPC is necessary, if a +client process runs on the same host as the server). + +The strategy for all public methods of Naming_Context is common : + +1. Transform the format of the arguments to ACE_SString (which is + internally used) if necessary. + +2. check if work can be done locally : -> call the appropriate local_* method + otherwise call the appropriate global_* method. + +Removing Name_Bindings from the database (either with unbind or +rebind) uses the ACE_Malloc class configured with the +ACE_MMAP_Memory_Pool. This allows memory to be reclaimed when +name/value tuples are unbound. + +3. Class Name_Server + ---------------- + +The Name_Server registers in its run method its Name_Acceptor +(instantiated with the INET_Addr) at the Reactor, to receive incoming +requests. + +4. Class Name_Acceptor + ------------------ + +The Name_Acceptor allocates in its handle_input routine a new instance +of class Name_Handler on the heap, and accepts connections into this +Name_Handler. + +5. Class Name_Handler + ----------------- + +The Name_Handler represents the server side of communication between +client and server. It interprets incoming requests to the Net_Local +namespace and dele- gates the requests to its own Naming_Context +(which is the Net_Local namespace on the current host). For +communication it uses the helper classes Name_Request (which up to now +needs not only contain the request from the client, but also the +appropriate reply from the server) and Name_Reply. Note that I want +to change the usage of these classes to make the structure of the +software clearer. + +6. Dependencies + ------------ + +As the Name service must be able to handle wide character strings, it +uses ACE_WString String classes. + + +==================== Time Service ==================== + +The following is a description of the Time Server clerk and server +services: + +1. Startup configuration + --------------------- + +Configuring a server requires specifying the port number of the +server. This can be specified as a command line argument as follows: + + -p <port number> + +A clerk communicates with one or more server processes. To communicate +with the server process, a client needs to know the INET_Addr, where +the server offers its service. The configuration parameters namely the +server port and server host are passed as command line arguments when +starting up the clerk service as follows: + + -h <server host1>:<server port1> -h <server host2>:<server port2> ... + +Note that multiple servers can be specified in this manner for the +clerk to connect to when it starts up. The server name and the port +number need to be concatenated and separated by a ":". In addition, +the timeout value can also be specified as a command line argument as +follows: + + -t timeout + +The timeout value specifies the time interval at which the clerk +should query the servers for time updates. + +By default a Clerk does a non-blocking connect to a server. This can +be overridden and a Clerk can be made to do a blocking connect by +using the -b flag. + +Here is what a config file would look like for starting up a server at +port 20202: + +dynamic Time_Service Service_Object * ../lib/libnet_svcs.so:_make_ACE_TS_Server_Acceptor() "-p 20202" + +Here is what a config file would look like for starting up a clerk +that needs to connect to two servers, one at tango and one at lambada: + +dynamic Time_Server_test Service_Object *../lib/libnet_svcs.so:_make_ACE_TS_Clerk_Connector () "-h tango:20202 -h lambada:20202 -t 4" + +[Note: these files would vary if the services are run on NT] + + +2. Class TS_Server_Handler + ----------------------- + +TS_Server_Handler represents the server side of communication between +clerk and server. It interprets incoming requests for time updates, +gets the system time, creates a reply in response to the request and +then sends the reply to the clerk from which it received the request. +For communication it uses the helper class Time_Request. + +3. Class TS_Server_Acceptor + ------------------------ + +TS_Server_Acceptor allocates in its handle_input routine a new instance +of class TS_Server_Handler on the heap, and accepts connections into this +TS_Server_Handler. + +4. Class TS_Clerk_Handler + ---------------------- + +TS_Clerk_Handler represents the clerk side of communication between +clerk and server. It generates requests for time updates every timeout +period and then sends these requests to all the servers it is +connected to asynchronously. It receives the replies to these requests +from the servers through its handle_input method and then adjusts the +time using the roundtrip estimate. It caches this time which is later +retrieved by TS_Clerk_Processor. + +5. Class TS_Clerk_Processor + ------------------------ + +TS_Clerk_Processor creates a new instance of TS_Clerk_Handler for +every server connection it needs to create. It periodically calls +send_request() of every TS_Clerk_Handler to send a request for time +update to all the servers. In the process, it retrieves the latest +time cached by each TS_Clerk_Handler and then uses it to compute its +notion of the local system time. + +6. Algorithms + ---------- + +Currently, updating the system time involves taking the average of all +the times received from the servers.
\ No newline at end of file diff --git a/netsvcs/lib/Server_Logging_Handler.cpp b/netsvcs/lib/Server_Logging_Handler.cpp new file mode 100644 index 00000000000..d784cb6af37 --- /dev/null +++ b/netsvcs/lib/Server_Logging_Handler.cpp @@ -0,0 +1,453 @@ +// Server_Logging_Handler.cpp +// @(#)Server_Logging_Handler.cpp 1.1 10/18/96 + +#define ACE_BUILD_SVC_DLL +#include "ace/Synch.h" +#include "ace/TLI_Acceptor.h" +#include "ace/SOCK_Acceptor.h" +#include "ace/Log_Msg.h" +#include "ace/Get_Opt.h" +#include "ace/Acceptor.h" +#include "Server_Logging_Handler.h" + +template <ACE_PEER_STREAM_1, class COUNTER, ACE_SYNCH_1> +class ACE_Server_Logging_Handler : public ACE_Svc_Handler<ACE_PEER_STREAM_2, ACE_SYNCH_2> +{ + // = TITLE + // Product object created by an <ACE_Server_Logging_Acceptor>. An + // <ACE_Server_Logging_Handler> receives, frames, and processes logging + // records. + // + // = DESCRIPTION + // Defines the classes that perform server logging daemon + // functionality. +public: + ACE_Server_Logging_Handler (ACE_Thread_Manager * = 0); + + virtual int open (void * = 0); + // Hook called by Server_Logging_Acceptor when connection is + // established. + + virtual int handle_input (ACE_HANDLE = ACE_INVALID_HANDLE); + // Process remote logging records. + +protected: + int handle_logging_record (void); + // Receive the logging record from a client. + +#if !defined (ACE_LACKS_STATIC_DATA_MEMBER_TEMPLATES) + static COUNTER request_count_; + // Count the number of logging records that arrive. +#endif /* ACE_LACKS_STATIC_DATA_MEMBER_TEMPLATES */ + + char host_name_[MAXHOSTNAMELEN + 1]; + // Name of the host we are connected to. +}; + +#if !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 */ + +#if !defined (ACE_LACKS_STATIC_DATA_MEMBER_TEMPLATES) +// Track number of requests. +template <ACE_PEER_STREAM_1, class COUNTER, ACE_SYNCH_1> +COUNTER ACE_Server_Logging_Handler<ACE_PEER_STREAM_2, COUNTER, ACE_SYNCH_2>::request_count_ = 0L; +#endif /* ACE_LACKS_STATIC_DATA_MEMBER_TEMPLATES */ + +typedef ACE_Server_Logging_Handler<LOGGING_PEER_STREAM, u_long, ACE_NULL_SYNCH> + SERVER_LOGGING_HANDLER; + +class ACE_Server_Logging_Acceptor : public ACE_Strategy_Acceptor<SERVER_LOGGING_HANDLER, LOGGING_PEER_ACCEPTOR> + // = TITLE + // This class implements the ACE single-threaded logging service. + // + // = DESCRIPTION + // This class contains the service-specific methods that can't + // easily be factored into the <ACE_Strategy_Acceptor>. +{ +public: + virtual int init (int argc, char *argv[]); + // Dynamic linking hook. + + int parse_args (int argc, char *argv[]); + // Parse svc.conf arguments. + +private: + ACE_Schedule_All_Reactive_Strategy<SERVER_LOGGING_HANDLER> scheduling_strategy_; + // The scheduling strategy is designed for Reactive services. +}; + +int +ACE_Server_Logging_Acceptor::parse_args (int argc, char *argv[]) +{ + ACE_TRACE ("ACE_Server_Logging_Acceptor::parse_args"); + + this->service_port_ = ACE_DEFAULT_SERVER_PORT; + + ACE_LOG_MSG->open ("Logging Service"); + + ACE_Get_Opt get_opt (argc, argv, "p:", 0); + + for (int c; (c = get_opt ()) != -1; ) + { + switch (c) + { + case 'p': + this->service_port_ = ACE_OS::atoi (get_opt.optarg); + break; + default: + ACE_ERROR_RETURN ((LM_ERROR, + "%n:\n[-p server-port]\n%a", 1), + -1); + break; + } + } + + this->service_addr_.set (this->service_port_); + return 0; +} + +int +ACE_Server_Logging_Acceptor::init (int argc, + char *argv[]) +{ + ACE_TRACE ("ACE_Server_Logging_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_Service_Config::reactor (), + 0, 0, 0, + &this->scheduling_strategy_, + "Logging Server", "ACE single-threaded logging service") == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%n: %p on port %d\n", + "acceptor::open failed", + this->service_addr_.get_port_number ()), -1); + + // Register ourselves to receive SIGINT so we can shutdown + // gracefully. + if (this->reactor ()->register_handler (SIGINT, this) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%n: %p\n", + "register_handler (SIGINT)"), -1); + + // Ignore SIGPIPE so that each <SVC_HANDLER> can handle this on its + // own. + ACE_Sig_Action sig (ACE_SignalHandler (SIG_IGN), SIGPIPE); + + 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, "%p\n", "get_local_addr"), -1); + + ACE_DEBUG ((LM_DEBUG, + "starting up Logging Server at port %d on handle %d\n", + server_addr.get_port_number (), + this->acceptor ().get_handle ())); + return 0; +} + +template <ACE_PEER_STREAM_1, class COUNTER, ACE_SYNCH_1> +ACE_Server_Logging_Handler<ACE_PEER_STREAM_2, COUNTER, ACE_SYNCH_2>::ACE_Server_Logging_Handler (ACE_Thread_Manager *) +{ + this->host_name_[0] = '\0'; // Initialize to a known state. +} + +template <ACE_PEER_STREAM_1, class COUNTER, ACE_SYNCH_1> int +ACE_Server_Logging_Handler<ACE_PEER_STREAM_2, COUNTER, ACE_SYNCH_2>::handle_logging_record (void) +{ + ssize_t n; + size_t len; + // Lock used to serialize access to std output + // (this should be in the class, but the SunC++ compiler is broken...) + static ACE_SYNCH_MUTEX lock; + + // Perform two recv's to emulate record-oriented semantiCLS. + // Note that this code is not entirely portable since it + // relies on the fact that sizeof (ssize_t) is the same + // on both the sender and receiver side. To correctly + // handle this is painful, and we leave it as an exercise + // for the reader ;-). + + switch (n = this->peer ().recv (&len, sizeof len)) + { + case -1: + ACE_ERROR_RETURN ((LM_ERROR, "%p at host %s\n", + "server logger", this->host_name_), -1); + /* NOTREACHED */ + case 0: + ACE_ERROR_RETURN ((LM_ERROR, "closing log daemon at host %s\n", + this->host_name_), -1); + /* NOTREACHED */ + case sizeof (ssize_t): + { + ACE_Log_Record lp; + +#if !defined (ACE_LACKS_STATIC_DATA_MEMBER_TEMPLATES) + u_long count = ++this->request_count_; + ACE_DEBUG ((LM_DEBUG, "request count = %d\n", count)); +#endif /* ACE_LACKS_STATIC_DATA_MEMBER_TEMPLATES */ + + len = ntohl (len); + if ((n = this->peer ().recv_n ((void *) &lp, len)) != len) + ACE_ERROR_RETURN ((LM_ERROR, "len = %d, %p at host %s\n", + n, "server logger", this->host_name_), -1); + /* NOTREACHED */ + + lp.decode (); + + if (lp.length () == n) + { + // Serialize output, if necessary (i.e., if we are running + // in separate threads). + ACE_GUARD_RETURN (ACE_SYNCH_MUTEX, ace_mon, lock, -1); + + lp.print (this->host_name_, 0, stderr); + } + else + ACE_ERROR ((LM_ERROR, "error, lp.length = %d, n = %d\n", + lp.length (), n)); + break; + } + default: + ACE_ERROR_RETURN ((LM_ERROR, "%p at host %s\n", + "server logger", this->host_name_), -1); + /* NOTREACHED */ + } + + return n; +} + +// Hook called by Server_Logging_Acceptor when connection is +// established. + +template <ACE_PEER_STREAM_1, class COUNTER, ACE_SYNCH_1> int +ACE_Server_Logging_Handler<ACE_PEER_STREAM_2, COUNTER, ACE_SYNCH_2>::open (void *arg) +{ + // Register ourselves with the Reactor to enable subsequent + // dispatching. + if (ACE_Service_Config::reactor ()->register_handler + (this, ACE_Event_Handler::READ_MASK) == -1) + return -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, "%p\n", "get_remote_addr"), -1); + + ACE_OS::strncpy (this->host_name_, client_addr.get_host_name (), MAXHOSTNAMELEN + 1); + + ACE_DEBUG ((LM_DEBUG, "(%t) accepted connection from host %s on fd %d\n", + client_addr.get_host_name (), this->peer ().get_handle ())); + + // Shut off non-blocking IO if it was enabled... + if (this->peer ().disable (ACE_NONBLOCK) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "disable"), -1); + + return 0; +} + +// Callback routine for handling the reception of remote logging +// transmissions. + +template <ACE_PEER_STREAM_1, class COUNTER, ACE_SYNCH_1> int +ACE_Server_Logging_Handler<ACE_PEER_STREAM_2, COUNTER, ACE_SYNCH_2>::handle_input (ACE_HANDLE) +{ + return this->handle_logging_record () > 0 ? 0 : -1; +} + +#if !defined (ACE_HAS_THREADS) +typedef u_long COUNTER; +#define ACE_LOGGER_SYNCH ACE_NULL_SYNCH +#else +typedef ACE_Atomic_Op <ACE_Thread_Mutex, u_long> COUNTER; +#define ACE_LOGGER_SYNCH ACE_MT_SYNCH +#endif /* ACE_HAS_THREADS */ + +class ACE_Svc_Export ACE_Thr_Server_Logging_Handler : public ACE_Server_Logging_Handler<LOGGING_PEER_STREAM, COUNTER, ACE_LOGGER_SYNCH> + // = TITLE + // Product object created by a <ACE_Thr_Server_Logging_Acceptor>. An + // <ACE_Thr_Server_Logging_Handler> receives, frames, and processes + // logging records. + // + // = DESCRIPTION + // Each client is handled in its own separate thread. +{ +public: + ACE_Thr_Server_Logging_Handler (ACE_Thread_Manager * = 0); + + virtual int open (void * = 0); + // Override activation definition in the ACE_Svc_Handler class (will + // spawn a new thread if we've got threads). + + virtual int svc (void); + // Process remote logging records. +}; + +class ACE_Thr_Server_Logging_Acceptor : public ACE_Strategy_Acceptor<ACE_Thr_Server_Logging_Handler, LOGGING_PEER_ACCEPTOR> + // = TITLE + // This class implements the ACE multi-threaded logging service. + // + // = DESCRIPTION + // This class contains the service-specific methods that can't + // easily be factored into the <ACE_Strategy_Acceptor>. +{ +public: + virtual int init (int argc, char *argv[]); + // Dynamic linking hook. + + int parse_args (int argc, char *argv[]); + // Parse svc.conf arguments. + +private: + ACE_Schedule_All_Threaded_Strategy<ACE_Thr_Server_Logging_Handler> scheduling_strategy_; + // The scheduling strategy is designed for multi-threaded services. +}; + +int +ACE_Thr_Server_Logging_Acceptor::parse_args (int argc, char *argv[]) +{ + ACE_TRACE ("ACE_Thr_Server_Logging_Acceptor::parse_args"); + + this->service_port_ = ACE_DEFAULT_SERVER_PORT; + + ACE_LOG_MSG->open ("Logging Service"); + + ACE_Get_Opt get_opt (argc, argv, "p:", 0); + + for (int c; (c = get_opt ()) != -1; ) + { + switch (c) + { + case 'p': + this->service_port_ = ACE_OS::atoi (get_opt.optarg); + break; + default: + ACE_ERROR_RETURN ((LM_ERROR, + "%n:\n[-p server-port]\n%a", 1), + -1); + break; + } + } + + this->service_addr_.set (this->service_port_); + return 0; +} + +int +ACE_Thr_Server_Logging_Acceptor::init (int argc, + char *argv[]) +{ + ACE_TRACE ("ACE_Thr_Server_Logging_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_Service_Config::reactor (), + 0, 0, 0, + &this->scheduling_strategy_, + "Thr Logging Server", "ACE multi-threaded logging service") == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%n: %p on port %d\n", + "acceptor::open failed", + this->service_addr_.get_port_number ()), -1); + + // Register ourselves to receive SIGINT so we can shutdown + // gracefully. + if (this->reactor ()->register_handler (SIGINT, this) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%n: %p\n", + "register_handler (SIGINT)"), -1); + + // Ignore SIGPIPE so that each <SVC_HANDLER> can handle this on its + // own. + ACE_Sig_Action sig (ACE_SignalHandler (SIG_IGN), SIGPIPE); + + 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, "%p\n", "get_local_addr"), -1); + + ACE_DEBUG ((LM_DEBUG, + "starting up Threaded Logging Server at port %d on handle %d\n", + server_addr.get_port_number (), + this->acceptor ().get_handle ())); + return 0; +} + +// 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) + +// No-op... + +ACE_Thr_Server_Logging_Handler::ACE_Thr_Server_Logging_Handler (ACE_Thread_Manager *) +{ +} + +// Override definition in the ACE_Svc_Handler class (spawn a new +// thread if we're configured with ACE_HAS_THREADS!). + +ACE_INLINE int +ACE_Thr_Server_Logging_Handler::open (void *) +{ + // Shut off non-blocking IO since now we can block in our own + // thread! + if (this->peer ().disable (ACE_NONBLOCK) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "disable"), -1); + + 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, "%p\n", "get_remote_addr"), -1); + + ACE_OS::strncpy (this->host_name_, client_addr.get_host_name (), MAXHOSTNAMELEN + 1); + + ACE_DEBUG ((LM_DEBUG, "(%t) accepted connection from host %s on fd %d\n", + client_addr.get_host_name (), this->peer ().get_handle ())); + + // Spawn a new thread of control to handle logging records with the + // client. Note that this implicitly uses the + // ACE_Service_Config::thr_mgr () to control all the threads. + if (this->activate (THR_BOUND | THR_DETACHED) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "spawn"), -1); + return 0; +} + +// Process remote logging records. + +ACE_INLINE int +ACE_Thr_Server_Logging_Handler::svc (void) +{ + int result = 0; + + // Loop until the client terminates the connection or an error occurs. + + while ((result = this->handle_input ()) > 0) + continue; + + return result; +} + +#if defined (ACE_TEMPLATES_REQUIRE_SPECIALIZATION) +template class ACE_Strategy_Acceptor<ACE_Thr_Server_Logging_Handler, LOGGING_PEER_ACCEPTOR>; +template class ACE_Schedule_All_Threaded_Strategy<ACE_Thr_Server_Logging_Handler>; +template class ACE_Strategy_Acceptor<ACE_Server_Logging_Handler<LOGGING_PEER_STREAM, unsigned long, ACE_Null_Mutex, ACE_Null_Condition_Mutex>, LOGGING_PEER_ACCEPTOR>; +template class ACE_Schedule_All_Reactive_Strategy<ACE_Server_Logging_Handler<LOGGING_PEER_STREAM, unsigned long, ACE_Null_Mutex, ACE_Null_Condition_Mutex> >; +#endif /* ACE_TEMPLATES_REQUIRE_SPECIALIZATION */ + + diff --git a/netsvcs/lib/Server_Logging_Handler.h b/netsvcs/lib/Server_Logging_Handler.h new file mode 100644 index 00000000000..b73ba1eb8bb --- /dev/null +++ b/netsvcs/lib/Server_Logging_Handler.h @@ -0,0 +1,26 @@ +/* -*- C++ -*- */ +// @(#)Server_Logging_Handler.h 1.1 10/18/96 + + +// ============================================================================ +// +// = LIBRARY +// ace +// +// = FILENAME +// Server_Logging_Handler.h +// +// = AUTHOR +// Doug Schmidt +// +// ============================================================================ + +#if !defined (ACE_SERVER_LOGGING_HANDLER_H) +#define ACE_SERVER_LOGGING_HANDLER_H + +#include "ace/OS.h" + +ACE_SVC_FACTORY_DECLARE (ACE_Server_Logging_Acceptor) +ACE_SVC_FACTORY_DECLARE (ACE_Thr_Server_Logging_Acceptor) + +#endif /* ACE_SERVER_LOGGING_HANDLER_H */ diff --git a/netsvcs/lib/Server_Logging_Handler.i b/netsvcs/lib/Server_Logging_Handler.i new file mode 100644 index 00000000000..91a235b2847 --- /dev/null +++ b/netsvcs/lib/Server_Logging_Handler.i @@ -0,0 +1,4 @@ +/* -*- C++ -*- */ +// @(#)Server_Logging_Handler.i 1.1 10/18/96 + + diff --git a/netsvcs/lib/TS_Clerk_Handler.cpp b/netsvcs/lib/TS_Clerk_Handler.cpp new file mode 100644 index 00000000000..6a4b181fd47 --- /dev/null +++ b/netsvcs/lib/TS_Clerk_Handler.cpp @@ -0,0 +1,826 @@ +// TS_Clerk_Handler.cpp +// @(#)TS_Clerk_Handler.cpp 1.1 10/18/96 + +#define ACE_BUILD_SVC_DLL +#include "ace/Service_Config.h" +#include "ace/Connector.h" +#include "ace/Log_Msg.h" +#include "ace/Get_Opt.h" +#include "ace/SOCK_Connector.h" +#include "ace/SOCK_Stream.h" +#include "ace/Svc_Handler.h" +#include "ace/Time_Value.h" +#include "ace/Time_Request_Reply.h" +#include "ace/OS.h" +#include "ace/Malloc.h" +#include "TS_Clerk_Handler.h" + +// A simple struct containing delta time and a sequence number +struct ACE_Time_Info +{ + long delta_time_; + ACE_UINT32 sequence_num_; +}; + +class ACE_TS_Clerk_Processor; // forward declaration + +class ACE_Svc_Export ACE_TS_Clerk_Handler : public ACE_Svc_Handler<ACE_SOCK_STREAM, ACE_NULL_SYNCH> + // = TITLE + // 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 + // + // = DESCRIPTION + // 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. +{ +public: + ACE_TS_Clerk_Handler (ACE_TS_Clerk_Processor *processor, + ACE_INET_Addr &addr); + // Default constructor. + + // = 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); + void state (State); + + // = Set/get the current retry timeout delay. + int timeout (void); + void timeout (int); + + // = Set/get the maximum retry timeout delay. + int max_timeout (void); + void max_timeout (int); + + virtual int open (void * = 0); + // Activate this instance of the <ACE_TS_Clerk_Handler> + // (called by the <ACE_TS_Clerk_Processor>). + + virtual ACE_HANDLE get_handle (void) const; + // Return the handle of the message_fifo_; + + virtual int handle_close (ACE_HANDLE = ACE_INVALID_HANDLE, + ACE_Reactor_Mask = ACE_Event_Handler::RWE_MASK); + // Called when object is removed from the ACE_Reactor + + virtual int handle_input (ACE_HANDLE); + // Receive time update from a server. + + virtual int handle_timeout (const ACE_Time_Value &tv, + const void *arg); + // Restart connection asynchronously when timeout occurs. + + void remote_addr (ACE_INET_Addr &addr); + ACE_INET_Addr &remote_addr (void); + // Get/Set remote addr + + int send_request (ACE_UINT32 sequence_num, ACE_Time_Info &time_info); + // Send request for time update to the server as well as return the + // current time info by reference. + +protected: + virtual int handle_signal (int signum, siginfo_t *, ucontext_t *); + // Handle SIGINT. + + static void stderr_output (int = 0); + + enum + { + MAX_RETRY_TIMEOUT = 300 // 5 minutes is the maximum timeout. + }; +private: + int recv_reply (ACE_Time_Request &reply); + // Receive a reply from a server containing time update + + int reinitiate_connection (void); + // Reinitiate connection with the server + + State state_; + // The current state of the connection + + int timeout_; + // Amount of time to wait between reconnection attempts + + int max_timeout_; + // Maximum amount of time to wait between reconnection attempts + + ACE_INET_Addr remote_addr_; + // Remote Addr used for connecting to the server + + ACE_TS_Clerk_Processor *processor_; + // Instance of Clerk Processor used for re-establishing connections + + ACE_UINT32 start_time_; + // Time at which request was sent (used to compute round trip delay) + + ACE_UINT32 cur_sequence_num_; + // Next sequence number of time request (waiting for this update from + // the server). + + ACE_Time_Info time_info_; + // Record of current delta time and current sequence number +}; + +class ACE_TS_Clerk_Processor : public ACE_Connector <ACE_TS_Clerk_Handler, ACE_SOCK_CONNECTOR> + // = TITLE + // This class manages all the connections to the servers along + // with querying them periodically for time updates. + // = DESCRIPTION + // 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. +{ +public: + ACE_TS_Clerk_Processor (); + // Default constructor + + virtual int handle_timeout (const ACE_Time_Value &tv, + const void *arg); + // Query servers for time periodically (timeout value) + + int initiate_connection (ACE_TS_Clerk_Handler *, ACE_Synch_Options &); + // Set up connections to all servers + +protected: + // = Dynamic linking hooks. + virtual int init (int argc, char *argv[]); + // Called when service is linked. + + virtual int fini (void); + // Called when service is unlinked. + + virtual int info (char **strp, size_t length) const; + // Called to determine info about the service. + + // = Scheduling hooks. + virtual int suspend (void); + virtual int resume (void); + + virtual int handle_signal (int signum, siginfo_t *, ucontext_t *); + // Handle SIGINT. + +private: + int parse_args (int argc, char *argv[]); + // Parse svc.conf arguments. + + void alloc (void); + // Allocate entry in shared memory for system time + + int update_time (); + // Update delta_time using times obtained from all servers + + typedef ACE_Malloc <ACE_MMAP_Memory_Pool, ACE_Null_Mutex> MALLOC; + typedef ACE_Allocator_Adapter<MALLOC> ALLOCATOR; + ALLOCATOR *shmem_; + // Allocator (used for reading/writing system time from/to shared memory) + + typedef ACE_Unbounded_Set <ACE_TS_Clerk_Handler *> HANDLER_SET; + typedef ACE_Unbounded_Set_Iterator <ACE_TS_Clerk_Handler *> HANDLER_SET_ITERATOR; + HANDLER_SET handler_set_; + // Set of TS_Clerk_Handlers and iterator over the set. + + struct System_Time + { + long *delta_time_; // Difference between system time and local time + long *last_local_time_; // Last local time + }; + + System_Time system_time_; + // Clerk system time containing pointers to entries in shared memory + + int timer_id_; + // Timer id returned by Reactor + + int timeout_; + // Time period for updating system time + + const char *poolname_; + // Pool name for backing store + + int blocking_semantics_; + // Do a blocking/non-blocking connect + + ACE_UINT32 cur_sequence_num_; + // Sequence number of next expected update from servers +}; + + +ACE_TS_Clerk_Handler::ACE_TS_Clerk_Handler (ACE_TS_Clerk_Processor *processor, + ACE_INET_Addr &addr) +: processor_ (processor), + remote_addr_ (addr), + state_ (ACE_TS_Clerk_Handler::IDLE), + timeout_ (ACE_DEFAULT_TIMEOUT), + max_timeout_ (ACE_TS_Clerk_Handler::MAX_RETRY_TIMEOUT) +{ + ACE_TRACE ("ACE_TS_Clerk_Handler::ACE_TS_Clerk_Handler"); + this->time_info_.delta_time_ = 0; + this->time_info_.sequence_num_ = 0; +} + +// This is called when a <send> to a server fails... +int +ACE_TS_Clerk_Handler::handle_signal (int signum, siginfo_t *, ucontext_t *) +{ + ACE_TRACE ("ACE_TS_Clerk_Handler::handle_signal"); + return 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 (void) +{ + ACE_TRACE ("ACE_TS_Clerk_Handler::state"); + return this->state_; +} + +// Sets the timeout delay. +void +ACE_TS_Clerk_Handler::timeout (int 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). +int +ACE_TS_Clerk_Handler::timeout (void) +{ + ACE_TRACE ("ACE_TS_Clerk_Handler::timeout"); + int old_timeout = this->timeout_; + this->timeout_ *= 2; + + if (this->timeout_ > this->max_timeout_) + this->timeout_ = this->max_timeout_; + + return old_timeout; +} + +// Set the max timeout delay. +void +ACE_TS_Clerk_Handler::max_timeout (int mto) +{ + ACE_TRACE ("ACE_TS_Clerk_Handler::max_timeout"); + this->max_timeout_ = mto; +} + +// Gets the max timeout delay. +int +ACE_TS_Clerk_Handler::max_timeout (void) +{ + 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_Service_Config::reactor ()->register_handler (SIGPIPE, this) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%n: %p\n", + "register_handler (SIGPIPE)"), -1); +#endif + + // Register ourselves with the reactor to receive input + if (ACE_Service_Config::reactor ()->register_handler (this->get_handle (), + this, + ACE_Event_Handler::READ_MASK | + ACE_Event_Handler::EXCEPT_MASK) == -1) + ACE_ERROR ((LM_ERROR, "%n: %p\n", "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, "%p\n", "get_remote_addr"), -1); + + ACE_DEBUG ((LM_DEBUG, + "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 (void) 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) +{ + ACE_TRACE ("ACE_TS_Clerk_Handler::handle_close"); + ACE_DEBUG ((LM_DEBUG, "(%t) shutting down on handle %d\n", this->get_handle ())); + return this->reinitiate_connection (); +} + +int +ACE_TS_Clerk_Handler::reinitiate_connection (void) +{ + 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, "(%t) Scheduling reinitiation of connection\n")); + + // Reschedule ourselves to try and connect again. + if (ACE_Service_Config::reactor ()->schedule_timer (this, 0, + this->timeout ()) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "(%t) %p\n", "schedule_timer"), -1); + } + return 0; +} + +// Receive a time update from a server +int +ACE_TS_Clerk_Handler::handle_input (ACE_HANDLE 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 + ACE_UINT32 local_time = ACE_OS::time (0); + + // Compure delta time (difference between current local time and + // system time obtained from the server) + long t = reply.time () - local_time; + + // Compute round trip delay and adjust time accordingly + ACE_UINT32 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 &tv, + const void *arg) +{ + ACE_TRACE ("ACE_TS_Clerk_Handler::handle_timeout"); + ACE_DEBUG ((LM_DEBUG, + "(%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 (void) +{ + 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: + // FALLTHROUGH + ACE_DEBUG ((LM_DEBUG, "****************** recv_reply returned -1\n")); + default: + ACE_ERROR ((LM_ERROR, "%p got %d bytes, expected %d bytes\n", + "recv failed", n, bytes_expected)); + // 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, "%p\n", "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, "%p\n", "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, "%p\n", "send_n failed"), -1); + + return 0; +} + +ACE_TS_Clerk_Processor::ACE_TS_Clerk_Processor () +: timeout_ (ACE_DEFAULT_TIMEOUT), + poolname_ (ACE_DEFAULT_BACKING_STORE), + blocking_semantics_ (0), + cur_sequence_num_ (0) +{ +} + +void +ACE_TS_Clerk_Processor::alloc (void) +{ + 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 (sizeof (this->system_time_)); + + // 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 + this->system_time_.delta_time_ = (long *) temp; + this->system_time_.last_local_time_ = ((long *) temp) + 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 &tv, + const void *arg) +{ + 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; + long 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, "[%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, "Average delta time: %d\n", *(this->system_time_.delta_time_))); + return 0; +} + + +int +ACE_TS_Clerk_Processor::fini (void) +{ + ACE_TRACE ("ACE_TS_Clerk_Processor::fini"); + + // Cancel the timer + if (this->timer_id_ != -1) + ACE_Service_Config::reactor ()->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 (); + return 0; +} + +int +ACE_TS_Clerk_Processor::info (char **strp, size_t length) const +{ + ACE_TRACE ("ACE_TS_Clerk_Processor::info"); + return 0; +} + +int +ACE_TS_Clerk_Processor::init (int argc, char *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_Sig_Set sig_set; +// sig_set.sig_add (SIGINT); + + // Register ourselves to receive SIGINT and SIGPIPE + // so we can shut down gracefully via signals. + if (ACE_Service_Config::reactor ()->register_handler (SIGINT, + this) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%n: %p\n", + "register_handler"), -1); +#endif + 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_Service_Config::reactor ()->schedule_timer (this, + NULL, + 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"); + char buf[MAXHOSTNAMELEN]; + + // 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, sizeof buf) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "(%t) %p\n", + "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, "(%t) %p on address %s\n", "connect", buf)); + + // Reschedule ourselves to try and connect again. + if (synch_options[ACE_Synch_Options::USE_REACTOR]) + { + if (ACE_Service_Config::reactor ()->schedule_timer (handler, + 0, + handler->timeout ()) == 0) + ACE_ERROR_RETURN ((LM_ERROR, "(%t) %p\n", "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, + "(%t) in the process of connecting %s to %s\n", + synch_options[ACE_Synch_Options::USE_REACTOR] + ? "asynchronously" : "synchronously", buf)); + } + } + else + { + handler->state (ACE_TS_Clerk_Handler::ESTABLISHED); + ACE_DEBUG ((LM_DEBUG, "(%t) connected to %s on %d\n", + buf, handler->get_handle ())); + } + return 0; +} + +int +ACE_TS_Clerk_Processor::parse_args (int argc, char *argv[]) +{ + ACE_TRACE ("ACE_TS_Clerk_Processor::parse_args"); + ACE_INET_Addr server_addr; + ACE_TS_Clerk_Handler *handler; + char server_host[BUFSIZ]; + + // Create a default entry + ACE_OS::sprintf (server_host, "%s:%d", + ACE_DEFAULT_SERVER_HOST, + ACE_DEFAULT_LOGGING_SERVER_PORT); + + ACE_Get_Opt get_opt (argc, argv, "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.optarg); + + // 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.optarg); + break; + case 'p': + // Get the poolname + this->poolname_ = get_opt.optarg; + break; + case 'b': + // Blocking semantics + this->blocking_semantics_ = 1; + break; + default: + ACE_ERROR_RETURN ((LM_ERROR, + "%n:\n[-p hostname:port] [-t timeout] [-p poolname]\n%a", 1), + -1); + break; + } + } + return 0; +} + +int +ACE_TS_Clerk_Processor::suspend (void) +{ + ACE_TRACE ("ACE_TS_Clerk_Processor::suspend"); + return 0; +} + +int +ACE_TS_Clerk_Processor::resume (void) +{ + ACE_TRACE ("ACE_TS_Clerk_Processor::resume"); + return 0; +} + +// Signal the server to shutdown gracefully. + +int +ACE_TS_Clerk_Processor::handle_signal (int signum, siginfo_t *, ucontext_t *) +{ + ACE_TRACE ("ACE_TS_Clerk_Processor::handle_signal"); + ACE_Service_Config::end_reactor_event_loop (); + 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) + +#if defined (ACE_TEMPLATES_REQUIRE_SPECIALIZATION) +template class ACE_Connector<ACE_TS_Clerk_Handler, ACE_SOCK_Connector, ACE_INET_Addr>; +#endif /* ACE_TEMPLATES_REQUIRE_SPECIALIZATION */ diff --git a/netsvcs/lib/TS_Clerk_Handler.h b/netsvcs/lib/TS_Clerk_Handler.h new file mode 100644 index 00000000000..8a1c63a5a8d --- /dev/null +++ b/netsvcs/lib/TS_Clerk_Handler.h @@ -0,0 +1,23 @@ +/* -*- C++ -*- */ +// @(#)TS_Clerk_Handler.h 1.1 10/18/96 + + +// ============================================================================ +// +// = LIBRARY +// ace +// +// = FILENAME +// TS_Clerk_Handler.h +// +// = AUTHOR +// Prashant Jain +// +// ============================================================================ + +#if !defined (ACE_TS_CLERK_HANDLER_H) +#define ACE_TS_CLERK_HANDLER_H + +ACE_SVC_FACTORY_DECLARE (ACE_TS_Clerk_Processor) + +#endif /* ACE_TS_CLERK_HANDLER_H */ diff --git a/netsvcs/lib/TS_Server_Handler.cpp b/netsvcs/lib/TS_Server_Handler.cpp new file mode 100644 index 00000000000..8b60c1562bf --- /dev/null +++ b/netsvcs/lib/TS_Server_Handler.cpp @@ -0,0 +1,324 @@ +// TS_Server_Handler.cpp +// @(#)TS_Server_Handler.cpp 1.1 10/18/96 + +#define ACE_BUILD_SVC_DLL +#include "ace/SString.h" +#include "ace/Set.h" +#include "ace/Get_Opt.h" +#include "ace/Acceptor.h" +#include "ace/SOCK_Acceptor.h" +#include "ace/SOCK_Stream.h" +#include "ace/Time_Request_Reply.h" +#include "TS_Server_Handler.h" + +class ACE_Svc_Export ACE_TS_Server_Handler : public ACE_Svc_Handler<ACE_SOCK_STREAM, ACE_NULL_SYNCH> + // = TITLE + // Product object created by <ACE_TS_Server_Acceptor>. + // + // = DESCRIPTION +{ + friend class ACE_Shutup_GPlusPlus; // Turn off g++ warning +public: + // = Initialization and termination. + + ACE_TS_Server_Handler (ACE_Thread_Manager * = 0); + // Default constructor. + + virtual int open (void * = 0); + // Activate this instance of the <ACE_TS_Server_Handler> (called by the + // <ACE_Strategy_Acceptor>). + +protected: + // = Helper routines for the operations exported to clients. + + virtual int abandon (void); + // Give up waiting (e.g., when a timeout occurs or a client shuts + // down unexpectedly). + + // = Low level routines for framing requests, dispatching + // operations, and returning replies. + + virtual int recv_request (void); + // Receive, frame, and decode the client's request. + + virtual int dispatch (void); + // Dispatch the appropriate operation to handle the client's + // request. + + virtual int send_request (ACE_Time_Request &); + // Special kind of reply + + // = Demultiplexing hooks. + virtual ACE_HANDLE get_handle (void) const; + // Return the underlying <ACE_HANDLE>. + + virtual int handle_input (ACE_HANDLE); + // Callback method invoked by the <ACE_Reactor> when client events + // arrive. + + // = Timer hook. + virtual int handle_timeout (const ACE_Time_Value &tv, const void *arg); + // Enable clients to limit the amount of time they wait. + +private: + ACE_Time_Request time_request_; + // Cache request from the client. + + ACE_INET_Addr addr_; + // Address of client we are connected with. + + ~ACE_TS_Server_Handler (void); + // Ensure dynamic allocation... +}; + +class ACE_TS_Server_Acceptor : public ACE_Strategy_Acceptor<ACE_TS_Server_Handler, ACE_SOCK_ACCEPTOR> + // = TITLE + // This class contains the service-specific methods that can't + // easily be factored into the <ACE_Strategy_Acceptor>. +{ +public: + virtual int init (int argc, char *argv[]); + // Dynamic linking hook. + + int parse_args (int argc, char *argv[]); + // Parse svc.conf arguments. + +private: + ACE_Schedule_All_Reactive_Strategy<ACE_TS_Server_Handler> scheduling_strategy_; + // The scheduling strategy is designed for Reactive services. +}; + +int +ACE_TS_Server_Acceptor::parse_args (int argc, char *argv[]) +{ + ACE_TRACE ("ACE_TS_Server_Acceptor::parse_args"); + + this->service_port_ = ACE_DEFAULT_SERVER_PORT; + + ACE_LOG_MSG->open ("Time Service"); + + ACE_Get_Opt get_opt (argc, argv, "p:", 0); + + for (int c; (c = get_opt ()) != -1; ) + { + switch (c) + { + case 'p': + this->service_port_ = ACE_OS::atoi (get_opt.optarg); + break; + default: + ACE_ERROR_RETURN ((LM_ERROR, + "%n:\n[-p server-port]\n%a", 1), + -1); + break; + } + } + this->service_addr_.set (this->service_port_); + return 0; +} + +int +ACE_TS_Server_Acceptor::init (int argc, char *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_Service_Config::reactor (), + 0, 0, 0, + &this->scheduling_strategy_, + "Time Server", "ACE time service") == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%n: %p on port %d\n", + "acceptor::open failed", + this->service_addr_.get_port_number ()), -1); + + // Register ourselves to receive SIGINT so we can shutdown + // gracefully. + if (this->reactor ()->register_handler (SIGINT, this) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%n: %p\n", + "register_handler (SIGINT)"), -1); + + // Ignore SIGPIPE so that each <SVC_HANDLER> can handle this on its + // own. + ACE_Sig_Action sig (ACE_SignalHandler (SIG_IGN), SIGPIPE); + + 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, "%p\n", "get_local_addr"), -1); + + ACE_DEBUG ((LM_DEBUG, + "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<ACE_SOCK_STREAM, ACE_NULL_SYNCH> (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, "%p\n", "get_remote_addr"), -1); + + ACE_DEBUG ((LM_DEBUG, "(%t) accepted connection from host %s 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<ACE_SOCK_STREAM, ACE_NULL_SYNCH>::open (0) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "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, "%p\n", "encode failed"), -1); + + // Transmit request via a blocking send. + + if (this->peer ().send_n (buffer, length) != length) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "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 (void) +{ + 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 (ACE_Time_Request::FAILURE, 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 (void) 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 (void) +{ + 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 (void) +{ + ACE_TRACE ("ACE_TS_Server_Handler::recv_request"); + ssize_t bytes_expected = this->time_request_.size (); + + // Since Time_Request messages are fixed size, read the entire + // message in one go. + ssize_t n = this->peer ().recv ((void *) &this->time_request_, bytes_expected); + if (n != bytes_expected) + { + switch (n) + { + case -1: + /* FALLTHROUGH */ + ACE_DEBUG ((LM_DEBUG, "****************** recv_request returned -1\n")); + default: + ACE_ERROR ((LM_ERROR, "%p got %d bytes, expected %d bytes\n", + "recv failed", n, bytes_expected)); + /* 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, "%p\n", "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 (void) +{ + ACE_TRACE ("ACE_TS_Server_Handler::~ACE_TS_Server_Handler"); + ACE_DEBUG ((LM_DEBUG, "closing down Handle %d\n", + this->get_handle ())); +} + +#if defined (ACE_TEMPLATES_REQUIRE_SPECIALIZATION) +template class ACE_Strategy_Acceptor<ACE_TS_Server_Handler, ACE_SOCK_Acceptor, ACE_INET_Addr>; +template class ACE_Schedule_All_Reactive_Strategy<ACE_TS_Server_Handler>; +#endif /* ACE_TEMPLATES_REQUIRE_SPECIALIZATION */ diff --git a/netsvcs/lib/TS_Server_Handler.h b/netsvcs/lib/TS_Server_Handler.h new file mode 100644 index 00000000000..5d571bd2aac --- /dev/null +++ b/netsvcs/lib/TS_Server_Handler.h @@ -0,0 +1,25 @@ +/* -*- C++ -*- */ +// @(#)TS_Server_Handler.h 1.1 10/18/96 + + +// ============================================================================ +// +// = LIBRARY +// ace +// +// = FILENAME +// TS_Server_Handler.h +// +// = AUTHOR +// Prashant Jain +// +// ============================================================================ + +#if !defined (ACE_TS_SERVER_HANDLER_H) +#define ACE_TS_SERVER_HANDLER_H + +#include "ace/OS.h" + +ACE_SVC_FACTORY_DECLARE (ACE_TS_Server_Acceptor) + +#endif /* ACE_TS_SERVER_HANDLER_H */ diff --git a/netsvcs/lib/Token_Handler.cpp b/netsvcs/lib/Token_Handler.cpp new file mode 100644 index 00000000000..bdb2a425a8e --- /dev/null +++ b/netsvcs/lib/Token_Handler.cpp @@ -0,0 +1,882 @@ +// Token_Handler.cpp +// @(#)Token_Handler.cpp 1.1 10/18/96 + +#define ACE_BUILD_SVC_DLL +#include "ace/Log_Msg.h" +#include "ace/Get_Opt.h" +#include "ace/Acceptor.h" +#include "ace/SOCK_Acceptor.h" +#include "ace/Token_Request_Reply.h" +#include "ace/Token_Collection.h" +#include "ace/Local_Tokens.h" +#include "Token_Handler.h" + +class ACE_Svc_Export ACE_Token_Handler : public ACE_Svc_Handler<ACE_SOCK_STREAM, ACE_NULL_SYNCH> + // = TITLE + // Product object created by an <ACE_Token_Acceptor>. A + // <Token_Handler> exchanges messages with a <Token_Proxy> object + // on the client-side. + // + // = DESCRIPTION + // 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. + +{ +public: + // = Initialization and termination. + + ACE_Token_Handler (ACE_Thread_Manager * = 0); + // Default constructor. + + // = Accessor and mutator methods. + + // = Remote operations "exported" to a client. + virtual int acquire (ACE_Token_Proxy *proxy); + // Try to acquire the token. + // Precondition: client *may* hold the token already (i.e., + // supports recursive acquisitions). + + virtual int try_acquire (ACE_Token_Proxy *proxy); + // Try to acquire the token. + + virtual int release (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 renew (ACE_Token_Proxy *proxy); + // Yield the token if any clients are waiting, otherwise keep the + // token. Preconditions: client must hold the token. + + virtual int remove (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.? + + void sleep_hook (void); + // Called by TS_[Mutex,RLock,WLock] when we hold the mutex and + // someone wants it. + + void token_acquired (ACE_TPQ_Entry *); + // Called by TS_[Mutex,RLock,WLock] when we are waiting and acquire + // the mutex. + +protected: + // = Low level routines for framing requests, dispatching + // operations, and returning replies. + + virtual int abandon (int send_error); + // Our connection has been closed. + + virtual int recv_request (void); + // Receive, frame, and decode the client's request. + + virtual int dispatch (void); + // Dispatch the appropriate operation to handle the client's + // request. + + virtual int send_reply (ACE_UINT32 errnum); + // Create and send a reply to the client. + + // = Demultiplexing hooks. + virtual int handle_input (ACE_HANDLE); + // Callback method invoked by the <ACE_Reactor> when client events + // arrive. + + // = Timer hook. + virtual int handle_timeout (const ACE_Time_Value &tv, const void *arg); + // Enable clients to limit the amount of time they wait for a token. + + ACE_Token_Proxy *get_proxy (void); + // return a proxy for the calling client_id and token name. + +private: + + virtual ACE_Token_Proxy *create_proxy (void); + // Switches on the type of token_request_ and creates a new + // Token_Proxy. + + ACE_Synch_Options request_options_; + // Keeps track of the synchronization options (i.e., the timeout + // interval). + + int timeout_id_; + // ID returned by the Reactor that is used to kill registered timers + // when a token operation times out. + + ACE_Token_Collection collection_; + // collection of the client's token proxies. + + ACE_Token_Request token_request_; + // Cache request from the client. + + ACE_Token_Reply token_reply_; + // Cache reply to the client. +}; + +// = 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 : public ACE_Local_Mutex + // = TITLE + // ACE_TS_Mutex -- ACE_*T*oken_*S*erver_Mutex +{ +public: + ACE_TS_Mutex (const char *name, + ACE_Token_Handler *th); + // Creation. + +protected: + virtual void sleep_hook (void); + // Somebody wants our token! + + virtual void token_acquired (ACE_TPQ_Entry *); + // 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. + + ACE_TS_Mutex (const ACE_TS_Mutex &); + // Duplication. + + virtual ACE_Token_Proxy *clone (void) const; + // Return a deep copy. + +private: + ACE_Token_Handler* th_; + // The Token Handler associated with this proxy. Set at + // construction and notified when blocking acquires succeed. +}; + +class ACE_TS_RLock : public ACE_Local_RLock + // = TITLE + // ACE_TS_RLock -- ACE_*T*oken_*S*erver_RLock +{ +public: + ACE_TS_RLock (const char *name, + ACE_Token_Handler *th); + // Creation. + +protected: + virtual void sleep_hook (void); + // Somebody wants our token! + + virtual void token_acquired (ACE_TPQ_Entry *); + // 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. + + ACE_TS_RLock (const ACE_TS_RLock&); + // Duplication. + + virtual ACE_Token_Proxy *clone (void) const; + // Return a deep copy. + +private: + ACE_Token_Handler* th_; + // the Token Handler associated with this proxy. Set at + // construction and notified when blocking acquires succeed. +}; + +class ACE_TS_WLock : public ACE_Local_WLock + // = TITLE + // ACE_TS_WLock -- ACE_*T*oken_*S*erver_WLock +{ +public: + ACE_TS_WLock (const char *name, + ACE_Token_Handler *th); + // Creation. + +protected: + virtual void sleep_hook (void); + // Somebody wants our token! + + virtual void token_acquired (ACE_TPQ_Entry *); + // 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. + + ACE_TS_WLock (const ACE_TS_WLock&); + // Duplication. + + virtual ACE_Token_Proxy *clone (void) const; + // Return a deep copy. + +private: + ACE_Token_Handler* th_; + // the Token Handler associated with this proxy. Set at + // construction and notified when blocking acquires succeed. +}; + +// ************************************************************ + +class ACE_Token_Acceptor : public ACE_Strategy_Acceptor<ACE_Token_Handler, ACE_SOCK_ACCEPTOR> + // = TITLE + // This class contains the service-specific methods that can't + // easily be factored into the <ACE_Strategy_Acceptor>. +{ +public: + virtual int init (int argc, char *argv[]); + // Dynamic linking hook. + + int parse_args (int argc, char *argv[]); + // Parse svc.conf arguments. + +private: + ACE_Schedule_All_Reactive_Strategy<ACE_Token_Handler> scheduling_strategy_; + // The scheduling strategy is designed for Reactive services. +}; + +int +ACE_Token_Acceptor::parse_args (int argc, char *argv[]) +{ + ACE_TRACE ("ACE_Token_Acceptor::parse_args"); + + this->service_port_ = ACE_DEFAULT_SERVER_PORT; + + ACE_LOG_MSG->open ("Token Service"); + + ACE_Get_Opt get_opt (argc, argv, "p:", 0); + + for (int c; (c = get_opt ()) != -1; ) + { + switch (c) + { + case 'p': + this->service_port_ = ACE_OS::atoi (get_opt.optarg); + break; + default: + ACE_ERROR_RETURN ((LM_ERROR, + "%n:\n[-p server-port]\n%a", 1), + -1); + break; + } + } + + this->service_addr_.set (this->service_port_); + return 0; +} + +int +ACE_Token_Acceptor::init (int argc, char *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_Service_Config::reactor (), + 0, 0, 0, + &this->scheduling_strategy_, + "Token Server", "ACE token service") == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%n: %p on port %d\n", + "acceptor::open failed", + this->service_addr_.get_port_number ()), -1); + + // Register ourselves to receive SIGINT so we can shutdown + // gracefully. + if (this->reactor ()->register_handler (SIGINT, this) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%n: %p\n", + "register_handler (SIGINT)"), -1); + + // Ignore SIGPIPE so that each <SVC_HANDLER> can handle this on its + // own. + ACE_Sig_Action sig (ACE_SignalHandler (SIG_IGN), SIGPIPE); + + ACE_INET_Addr server_addr; + + if (this->acceptor ().get_local_addr (server_addr) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "get_remote_addr"), -1); + + ACE_DEBUG ((LM_DEBUG, + "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<ACE_SOCK_STREAM, ACE_NULL_SYNCH> (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 != len) + ACE_ERROR_RETURN ((LM_ERROR, + "%p, expected len = %d, actual len = %d\n", + "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"); + ACE_DEBUG ((LM_DEBUG, "in acquire for client id = %s\n", + proxy->client_id ())); + + // @@ 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, "%p\n", "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 (ACE_Token_Reply::SUCCESS); +} + +// 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"); + + ACE_DEBUG ((LM_DEBUG, "in try_acquire for client id = %s\n", + proxy->client_id ())); + + // @@ add notify in token request reply + if (proxy->tryacquire () == -1) + return this->send_reply (errno); + else + return this->send_reply (ACE_Token_Reply::SUCCESS); +} + +// 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"); + ACE_DEBUG ((LM_DEBUG, + "in release for client id = %s\n", + proxy->client_id ())); + + 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 (ACE_Token_Reply::SUCCESS); +} + +// 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"); + + ACE_DEBUG ((LM_DEBUG, "in renew for client id = %s\n", + proxy->client_id ())); + + 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, "%p\n", "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 (ACE_Token_Reply::SUCCESS); +} + +/* VIRTUAL */ int +ACE_Token_Handler::remove (ACE_Token_Proxy *proxy) +{ + ACE_TRACE ("ACE_Token_Handler::remove"); + ACE_DEBUG ((LM_DEBUG, "in remove for client id = %s\n", + proxy->client_id ())); + ACE_ERROR ((LM_ERROR, "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; + + ACE_DEBUG ((LM_DEBUG, "in handle_timeout for client id = %s\n", + proxy->client_id ())); + + // 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 (void) +{ + 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, "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, "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 (void) +{ + ACE_TRACE ("ACE_Token_Handler::new_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 (void) +{ + 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, "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 (void) +{ + 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: + /* FALLTHROUGH */ + default: + ACE_ERROR ((LM_ERROR, "%p got %d bytes, expected %d bytes\n", + "recv failed", n, sizeof (ACE_UINT32))); + /* 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 > sizeof this->token_request_) + { + ACE_ERROR ((LM_ERROR, "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 - sizeof (ACE_UINT32))) + { + ACE_ERROR ((LM_ERROR, "%p expected %d, got %d\n", + "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, "%p\n", "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"); + + ACE_DEBUG ((LM_DEBUG, "****************** in handle_input\n")); + + if (this->recv_request () == -1) + return -1; + else + return this->dispatch (); +} + +void +ACE_Token_Handler::sleep_hook (void) +{ + 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 (ACE_Token_Reply::SUCCESS); +} + +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 char *name, + ACE_Token_Handler *th) +: th_ (th), + ACE_Local_Mutex (name, 0, 1) // The 1 is debug. +{ + ACE_TRACE ("ACE_TS_Mutex::ACE_TS_Mutex"); +} + +ACE_TS_Mutex::ACE_TS_Mutex (const ACE_TS_Mutex &m) +: th_ (m.th_), + ACE_Local_Mutex (m) +{ + ACE_TRACE ("ACE_TS_Mutex::ACE_TS_Mutex"); + this->open (m.name (), m.ignore_deadlock_, m.debug_); +} + +void +ACE_TS_Mutex::sleep_hook (void) +{ + 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 (void) 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 char *name, + ACE_Token_Handler *th) +: th_ (th), + ACE_Local_RLock (name, 0, 1) // The 1 is debug. +{ + ACE_TRACE ("ACE_TS_RLock::ACE_TS_RLock"); +} + +ACE_TS_RLock::ACE_TS_RLock (const ACE_TS_RLock &r) +: th_ (r.th_), + ACE_Local_RLock (r) +{ + ACE_TRACE ("ACE_TS_RLock::ACE_TS_RLock"); + this->open (r.name (), r.ignore_deadlock_, r.debug_); +} + +void +ACE_TS_RLock::sleep_hook (void) +{ + 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 (void) 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 char *name, + ACE_Token_Handler *th) +: th_ (th), + ACE_Local_WLock (name, 0, 1) // The 1 is debug. +{ + ACE_TRACE ("ACE_TS_WLock::ACE_TS_WLock"); +} + +ACE_TS_WLock::ACE_TS_WLock (const ACE_TS_WLock &w) +: th_ (w.th_), + ACE_Local_WLock (w) +{ + ACE_TRACE ("ACE_TS_WLock::ACE_TS_WLock"); + this->open (w.name (), w.ignore_deadlock_, w.debug_); +} + +void +ACE_TS_WLock::sleep_hook (void) +{ + 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 (void) const +{ + ACE_TRACE ("ACE_TS_WLock::clone"); + ACE_Token_Proxy *temp; + + ACE_NEW_RETURN (temp, ACE_TS_WLock (*this), 0); + return temp; +} + +#if defined (ACE_TEMPLATES_REQUIRE_SPECIALIZATION) +template class ACE_Strategy_Acceptor<ACE_Token_Handler, ACE_SOCK_Acceptor, ACE_INET_Addr>; +template class ACE_Schedule_All_Reactive_Strategy<ACE_Token_Handler>; +#endif /* ACE_TEMPLATES_REQUIRE_SPECIALIZATION */ + + diff --git a/netsvcs/lib/Token_Handler.h b/netsvcs/lib/Token_Handler.h new file mode 100644 index 00000000000..6858347f2b8 --- /dev/null +++ b/netsvcs/lib/Token_Handler.h @@ -0,0 +1,26 @@ +/* -*- C++ -*- */ +// @(#)Token_Handler.h 1.1 10/18/96 + + +// ============================================================================ +// +// = LIBRARY +// ACE +// +// = FILENAME +// Token_Handler.h +// +// = AUTHOR +// Douglas C. Schmidt (schmidt@cs.wustl.edu) +// Tim Harrison (harrison@cs.wustl.edu) +// +// ============================================================================ + +#if !defined (ACE_TOKEN_HANDLER_H) +#define ACE_TOKEN_HANDLER_H + +#include "ace/OS.h" + +ACE_SVC_FACTORY_DECLARE (ACE_Token_Acceptor) + +#endif /* ACE_TOKEN_HANDLER_H */ diff --git a/netsvcs/lib/netsvcs.mak b/netsvcs/lib/netsvcs.mak new file mode 100644 index 00000000000..e5bc6ebd557 --- /dev/null +++ b/netsvcs/lib/netsvcs.mak @@ -0,0 +1,1082 @@ +# Microsoft Developer Studio Generated NMAKE File, Format Version 4.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
+
+!IF "$(CFG)" == ""
+CFG=netsvcs - Win32 Debug
+!MESSAGE No configuration specified. Defaulting to netsvcs - Win32 Debug.
+!ENDIF
+
+!IF "$(CFG)" != "netsvcs - Win32 Release" && "$(CFG)" !=\
+ "netsvcs - Win32 Debug"
+!MESSAGE Invalid configuration "$(CFG)" specified.
+!MESSAGE You can specify a configuration when running NMAKE on this makefile
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "netsvcs.mak" CFG="netsvcs - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "netsvcs - Win32 Release" (based on\
+ "Win32 (x86) Dynamic-Link Library")
+!MESSAGE "netsvcs - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE
+!ERROR An invalid configuration is specified.
+!ENDIF
+
+!IF "$(OS)" == "Windows_NT"
+NULL=
+!ELSE
+NULL=nul
+!ENDIF
+################################################################################
+# Begin Project
+# PROP Target_Last_Scanned "netsvcs - Win32 Debug"
+RSC=rc.exe
+MTL=mktyplib.exe
+CPP=cl.exe
+
+!IF "$(CFG)" == "netsvcs - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "netsvcs\Release"
+# PROP BASE Intermediate_Dir "netsvcs\Release"
+# PROP BASE Target_Dir "netsvcs"
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "netsvcs\Release"
+# PROP Intermediate_Dir "netsvcs\Release"
+# PROP Target_Dir "netsvcs"
+OUTDIR=.\netsvcs\Release
+INTDIR=.\netsvcs\Release
+
+ALL : "$(OUTDIR)\netsvcs.dll"
+
+CLEAN :
+ -@erase ".\netsvcs\Release\netsvcs.dll"
+ -@erase ".\netsvcs\Release\Token_Handler.obj"
+ -@erase ".\netsvcs\Release\Server_Logging_Handler.obj"
+ -@erase ".\netsvcs\Release\TS_Server_Handler.obj"
+ -@erase ".\netsvcs\Release\Client_Logging_Handler.obj"
+ -@erase ".\netsvcs\Release\TS_Clerk_Handler.obj"
+ -@erase ".\netsvcs\Release\Name_Handler.obj"
+ -@erase ".\netsvcs\Release\Logging_Strategy.obj"
+ -@erase ".\netsvcs\Release\netsvcs.lib"
+ -@erase ".\netsvcs\Release\netsvcs.exp"
+
+"$(OUTDIR)" :
+ if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
+
+# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /c
+# ADD CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /c
+CPP_PROJ=/nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS"\
+ /Fp"$(INTDIR)/netsvcs.pch" /YX /Fo"$(INTDIR)/" /c
+CPP_OBJS=.\netsvcs\Release/
+CPP_SBRS=
+# ADD BASE MTL /nologo /D "NDEBUG" /win32
+# ADD MTL /nologo /D "NDEBUG" /win32
+MTL_PROJ=/nologo /D "NDEBUG" /win32
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+BSC32_FLAGS=/nologo /o"$(OUTDIR)/netsvcs.bsc"
+BSC32_SBRS=
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /machine:I386
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /machine:I386
+LINK32_FLAGS=kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib\
+ advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib\
+ odbccp32.lib /nologo /subsystem:windows /dll /incremental:no\
+ /pdb:"$(OUTDIR)/netsvcs.pdb" /machine:I386 /out:"$(OUTDIR)/netsvcs.dll"\
+ /implib:"$(OUTDIR)/netsvcs.lib"
+LINK32_OBJS= \
+ "$(INTDIR)/Token_Handler.obj" \
+ "$(INTDIR)/Server_Logging_Handler.obj" \
+ "$(INTDIR)/TS_Server_Handler.obj" \
+ "$(INTDIR)/Client_Logging_Handler.obj" \
+ "$(INTDIR)/TS_Clerk_Handler.obj" \
+ "$(INTDIR)/Name_Handler.obj" \
+ "$(INTDIR)/Logging_Strategy.obj" \
+ "..\..\ace\ace.lib"
+
+"$(OUTDIR)\netsvcs.dll" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
+ $(LINK32) @<<
+ $(LINK32_FLAGS) $(LINK32_OBJS)
+<<
+
+!ELSEIF "$(CFG)" == "netsvcs - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "netsvcs\Debug"
+# PROP BASE Intermediate_Dir "netsvcs\Debug"
+# PROP BASE Target_Dir "netsvcs"
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "..\..\ace"
+# PROP Intermediate_Dir "debug"
+# PROP Target_Dir "netsvcs"
+OUTDIR=.\..\..\ace
+INTDIR=.\debug
+
+ALL : "$(OUTDIR)\netsvcs.dll"
+
+CLEAN :
+ -@erase ".\debug\vc40.pdb"
+ -@erase ".\debug\vc40.idb"
+ -@erase "..\..\ace\netsvcs.dll"
+ -@erase ".\debug\Client_Logging_Handler.obj"
+ -@erase ".\debug\Server_Logging_Handler.obj"
+ -@erase ".\debug\Token_Handler.obj"
+ -@erase ".\debug\TS_Server_Handler.obj"
+ -@erase ".\debug\Name_Handler.obj"
+ -@erase ".\debug\TS_Clerk_Handler.obj"
+ -@erase ".\debug\Logging_Strategy.obj"
+ -@erase "..\..\ace\netsvcs.ilk"
+ -@erase "..\..\ace\netsvcs.lib"
+ -@erase "..\..\ace\netsvcs.exp"
+ -@erase "..\..\ace\netsvcs.pdb"
+
+"$(OUTDIR)" :
+ if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
+
+"$(INTDIR)" :
+ if not exist "$(INTDIR)/$(NULL)" mkdir "$(INTDIR)"
+
+# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /c
+# ADD CPP /nologo /MDd /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /c
+CPP_PROJ=/nologo /MDd /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS"\
+ /Fp"$(INTDIR)/netsvcs.pch" /YX /Fo"$(INTDIR)/" /Fd"$(INTDIR)/" /c
+CPP_OBJS=.\debug/
+CPP_SBRS=
+# ADD BASE MTL /nologo /D "_DEBUG" /win32
+# ADD MTL /nologo /D "_DEBUG" /win32
+MTL_PROJ=/nologo /D "_DEBUG" /win32
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+BSC32_FLAGS=/nologo /o"$(OUTDIR)/netsvcs.bsc"
+BSC32_SBRS=
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /debug /machine:I386
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib wsock32.lib /nologo /subsystem:windows /dll /debug /machine:I386
+LINK32_FLAGS=kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib\
+ advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib\
+ odbccp32.lib wsock32.lib /nologo /subsystem:windows /dll /incremental:yes\
+ /pdb:"$(OUTDIR)/netsvcs.pdb" /debug /machine:I386 /out:"$(OUTDIR)/netsvcs.dll"\
+ /implib:"$(OUTDIR)/netsvcs.lib"
+LINK32_OBJS= \
+ "$(INTDIR)/Client_Logging_Handler.obj" \
+ "$(INTDIR)/Server_Logging_Handler.obj" \
+ "$(INTDIR)/Token_Handler.obj" \
+ "$(INTDIR)/TS_Server_Handler.obj" \
+ "$(INTDIR)/Name_Handler.obj" \
+ "$(INTDIR)/TS_Clerk_Handler.obj" \
+ "$(INTDIR)/Logging_Strategy.obj" \
+ "..\..\ace\ace.lib"
+
+"$(OUTDIR)\netsvcs.dll" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
+ $(LINK32) @<<
+ $(LINK32_FLAGS) $(LINK32_OBJS)
+<<
+
+!ENDIF
+
+.c{$(CPP_OBJS)}.obj:
+ $(CPP) $(CPP_PROJ) $<
+
+.cpp{$(CPP_OBJS)}.obj:
+ $(CPP) $(CPP_PROJ) $<
+
+.cxx{$(CPP_OBJS)}.obj:
+ $(CPP) $(CPP_PROJ) $<
+
+.c{$(CPP_SBRS)}.sbr:
+ $(CPP) $(CPP_PROJ) $<
+
+.cpp{$(CPP_SBRS)}.sbr:
+ $(CPP) $(CPP_PROJ) $<
+
+.cxx{$(CPP_SBRS)}.sbr:
+ $(CPP) $(CPP_PROJ) $<
+
+################################################################################
+# Begin Target
+
+# Name "netsvcs - Win32 Release"
+# Name "netsvcs - Win32 Debug"
+
+!IF "$(CFG)" == "netsvcs - Win32 Release"
+
+!ELSEIF "$(CFG)" == "netsvcs - Win32 Debug"
+
+!ENDIF
+
+################################################################################
+# Begin Source File
+
+SOURCE=\ACE_wrappers\ace\ace.lib
+
+!IF "$(CFG)" == "netsvcs - Win32 Release"
+
+!ELSEIF "$(CFG)" == "netsvcs - Win32 Debug"
+
+!ENDIF
+
+# End Source File
+################################################################################
+# Begin Source File
+
+SOURCE=.\Token_Handler.cpp
+DEP_CPP_TOKEN=\
+ {$(INCLUDE)}"\ace\Log_Msg.h"\
+ {$(INCLUDE)}"\ace\Get_Opt.h"\
+ {$(INCLUDE)}"\ace\Acceptor.h"\
+ {$(INCLUDE)}"\ace\SOCK_Acceptor.h"\
+ {$(INCLUDE)}"\ace\Token_Request_Reply.h"\
+ {$(INCLUDE)}"\ace\Token_Collection.h"\
+ {$(INCLUDE)}"\ace\Local_Tokens.h"\
+ ".\Token_Handler.h"\
+ {$(INCLUDE)}"\ace\Log_Record.h"\
+ {$(INCLUDE)}"\ace\ACE.h"\
+ {$(INCLUDE)}"\ace\Log_Priority.h"\
+ {$(INCLUDE)}"\ace\Log_Record.i"\
+ {$(INCLUDE)}"\ace\OS.h"\
+ {$(INCLUDE)}"\ace\ACE.i"\
+ {$(INCLUDE)}"\ace\Time_Value.h"\
+ {$(INCLUDE)}"\sys\TYPES.H"\
+ {$(INCLUDE)}"\sys\STAT.H"\
+ {$(INCLUDE)}"\sys\TIMEB.H"\
+ {$(INCLUDE)}"\ace\Trace.h"\
+ {$(INCLUDE)}"\ace\OS.i"\
+ {$(INCLUDE)}"\ace\config.h"\
+ {$(INCLUDE)}"\ace\Time_Value.i"\
+ {$(INCLUDE)}"\ace\Get_Opt.i"\
+ {$(INCLUDE)}"\ace\Service_Config.h"\
+ {$(INCLUDE)}"\ace\Service_Object.h"\
+ {$(INCLUDE)}"\ace\Svc_Handler.h"\
+ {$(INCLUDE)}"\ace\Strategies.h"\
+ {$(INCLUDE)}"\ace\Acceptor.i"\
+ {$(INCLUDE)}"\ace\Acceptor.cpp"\
+ {$(INCLUDE)}"\ace\Thread_Manager.h"\
+ {$(INCLUDE)}"\ace\Set.h"\
+ {$(INCLUDE)}"\ace\Proactor.h"\
+ {$(INCLUDE)}"\ace\ReactorEx.h"\
+ {$(INCLUDE)}"\ace\Service_Config.i"\
+ {$(INCLUDE)}"\ace\Reactor.h"\
+ {$(INCLUDE)}"\ace\Svc_Conf_Tokens.h"\
+ {$(INCLUDE)}"\ace\Thread.h"\
+ {$(INCLUDE)}"\ace\Synch.h"\
+ {$(INCLUDE)}"\ace\Thread_Manager.i"\
+ {$(INCLUDE)}"\ace\Thread.i"\
+ {$(INCLUDE)}"\ace\SV_Semaphore_Complex.h"\
+ {$(INCLUDE)}"\ace\Synch.i"\
+ {$(INCLUDE)}"\ace\Synch_T.h"\
+ {$(INCLUDE)}"\ace\SV_Semaphore_Simple.h"\
+ {$(INCLUDE)}"\ace\SV_Semaphore_Complex.i"\
+ {$(INCLUDE)}"\ace\SV_Semaphore_Simple.i"\
+ {$(INCLUDE)}"\ace\Synch_T.i"\
+ {$(INCLUDE)}"\ace\Synch_T.cpp"\
+ {$(INCLUDE)}"\ace\Set.i"\
+ {$(INCLUDE)}"\ace\Set.cpp"\
+ {$(INCLUDE)}"\ace\Message_Block.h"\
+ {$(INCLUDE)}"\ace\Timer_Queue.h"\
+ {$(INCLUDE)}"\ace\Event_Handler.h"\
+ {$(INCLUDE)}"\ace\Proactor.i"\
+ {$(INCLUDE)}"\ace\Malloc.h"\
+ {$(INCLUDE)}"\ace\Message_Block.i"\
+ {$(INCLUDE)}"\ace\Malloc.i"\
+ {$(INCLUDE)}"\ace\Malloc_T.h"\
+ {$(INCLUDE)}"\ace\Memory_Pool.h"\
+ {$(INCLUDE)}"\ace\Malloc_T.i"\
+ {$(INCLUDE)}"\ace\Malloc_T.cpp"\
+ {$(INCLUDE)}"\ace\Signal.h"\
+ {$(INCLUDE)}"\ace\Mem_Map.h"\
+ {$(INCLUDE)}"\ace\Memory_Pool.i"\
+ {$(INCLUDE)}"\ace\Signal.i"\
+ {$(INCLUDE)}"\ace\Mem_Map.i"\
+ {$(INCLUDE)}"\ace\Timer_Queue.i"\
+ {$(INCLUDE)}"\ace\Event_Handler.i"\
+ {$(INCLUDE)}"\ace\Token.h"\
+ {$(INCLUDE)}"\ace\ReactorEx.i"\
+ {$(INCLUDE)}"\ace\Token.i"\
+ {$(INCLUDE)}"\ace\Handle_Set.h"\
+ {$(INCLUDE)}"\ace\Pipe.h"\
+ {$(INCLUDE)}"\ace\SOCK_Stream.h"\
+ {$(INCLUDE)}"\ace\Reactor.i"\
+ {$(INCLUDE)}"\ace\Handle_Set.i"\
+ {$(INCLUDE)}"\ace\Pipe.i"\
+ {$(INCLUDE)}"\ace\SOCK_IO.h"\
+ {$(INCLUDE)}"\ace\INET_Addr.h"\
+ {$(INCLUDE)}"\ace\SOCK_Stream.i"\
+ {$(INCLUDE)}"\ace\SOCK.h"\
+ {$(INCLUDE)}"\ace\SOCK_IO.i"\
+ {$(INCLUDE)}"\ace\Addr.h"\
+ {$(INCLUDE)}"\ace\IPC_SAP.h"\
+ {$(INCLUDE)}"\ace\SOCK.i"\
+ {$(INCLUDE)}"\ace\Addr.i"\
+ {$(INCLUDE)}"\ace\IPC_SAP.i"\
+ {$(INCLUDE)}"\ace\INET_Addr.i"\
+ {$(INCLUDE)}"\ace\Shared_Object.h"\
+ {$(INCLUDE)}"\ace\Service_Object.i"\
+ {$(INCLUDE)}"\ace\Shared_Object.i"\
+ {$(INCLUDE)}"\ace\Synch_Options.h"\
+ {$(INCLUDE)}"\ace\Task.h"\
+ {$(INCLUDE)}"\ace\Svc_Handler.i"\
+ {$(INCLUDE)}"\ace\Svc_Handler.cpp"\
+ {$(INCLUDE)}"\ace\Message_Queue.h"\
+ {$(INCLUDE)}"\ace\Task.i"\
+ {$(INCLUDE)}"\ace\Task.cpp"\
+ {$(INCLUDE)}"\ace\IO_Cntl_Msg.h"\
+ {$(INCLUDE)}"\ace\Message_Queue.i"\
+ {$(INCLUDE)}"\ace\Message_Queue.cpp"\
+ {$(INCLUDE)}"\ace\Module.h"\
+ {$(INCLUDE)}"\ace\Module.i"\
+ {$(INCLUDE)}"\ace\Module.cpp"\
+ {$(INCLUDE)}"\ace\Stream_Modules.h"\
+ {$(INCLUDE)}"\ace\Stream_Modules.i"\
+ {$(INCLUDE)}"\ace\Stream_Modules.cpp"\
+ {$(INCLUDE)}"\ace\Dynamic.h"\
+ {$(INCLUDE)}"\ace\Dynamic.i"\
+ {$(INCLUDE)}"\ace\Strategies.cpp"\
+ {$(INCLUDE)}"\ace\SOCK_Acceptor.i"\
+ {$(INCLUDE)}"\ace\Token_Request_Reply.i"\
+ {$(INCLUDE)}"\ace\Map_Manager.h"\
+ {$(INCLUDE)}"\ace\SString.h"\
+ {$(INCLUDE)}"\ace\Token_Collection.i"\
+ {$(INCLUDE)}"\ace\Map_Manager.i"\
+ {$(INCLUDE)}"\ace\Map_Manager.cpp"\
+ {$(INCLUDE)}"\ace\SString.i"\
+ {$(INCLUDE)}"\ace\Stack.h"\
+ {$(INCLUDE)}"\ace\Local_Tokens.i"\
+ {$(INCLUDE)}"\ace\Stack.i"\
+ {$(INCLUDE)}"\ace\Stack.cpp"\
+
+NODEP_CPP_TOKEN=\
+ ".\..\..\ace\ace\Sync_T.h"\
+
+
+"$(INTDIR)\Token_Handler.obj" : $(SOURCE) $(DEP_CPP_TOKEN) "$(INTDIR)"
+
+
+# End Source File
+################################################################################
+# Begin Source File
+
+SOURCE=.\TS_Clerk_Handler.cpp
+DEP_CPP_TS_CL=\
+ {$(INCLUDE)}"\ace\Service_Config.h"\
+ {$(INCLUDE)}"\ace\Connector.h"\
+ {$(INCLUDE)}"\ace\Log_Msg.h"\
+ {$(INCLUDE)}"\ace\Get_Opt.h"\
+ {$(INCLUDE)}"\ace\SOCK_Connector.h"\
+ {$(INCLUDE)}"\ace\SOCK_Stream.h"\
+ {$(INCLUDE)}"\ace\Svc_Handler.h"\
+ {$(INCLUDE)}"\ace\Time_Value.h"\
+ {$(INCLUDE)}"\ace\Time_Request_Reply.h"\
+ {$(INCLUDE)}"\ace\OS.h"\
+ {$(INCLUDE)}"\ace\Malloc.h"\
+ ".\TS_Clerk_Handler.h"\
+ {$(INCLUDE)}"\ace\Service_Object.h"\
+ {$(INCLUDE)}"\ace\Thread_Manager.h"\
+ {$(INCLUDE)}"\ace\Set.h"\
+ {$(INCLUDE)}"\ace\Proactor.h"\
+ {$(INCLUDE)}"\ace\ReactorEx.h"\
+ {$(INCLUDE)}"\ace\Service_Config.i"\
+ {$(INCLUDE)}"\ace\Reactor.h"\
+ {$(INCLUDE)}"\ace\Svc_Conf_Tokens.h"\
+ {$(INCLUDE)}"\ace\Shared_Object.h"\
+ {$(INCLUDE)}"\ace\Event_Handler.h"\
+ {$(INCLUDE)}"\ace\Service_Object.i"\
+ {$(INCLUDE)}"\ace\ACE.h"\
+ {$(INCLUDE)}"\ace\Shared_Object.i"\
+ {$(INCLUDE)}"\ace\ACE.i"\
+ {$(INCLUDE)}"\ace\Event_Handler.i"\
+ {$(INCLUDE)}"\ace\Thread.h"\
+ {$(INCLUDE)}"\ace\Synch.h"\
+ {$(INCLUDE)}"\ace\Thread_Manager.i"\
+ {$(INCLUDE)}"\ace\Thread.i"\
+ {$(INCLUDE)}"\ace\SV_Semaphore_Complex.h"\
+ {$(INCLUDE)}"\ace\Synch.i"\
+ {$(INCLUDE)}"\ace\Synch_T.h"\
+ {$(INCLUDE)}"\ace\SV_Semaphore_Simple.h"\
+ {$(INCLUDE)}"\ace\SV_Semaphore_Complex.i"\
+ {$(INCLUDE)}"\ace\SV_Semaphore_Simple.i"\
+ {$(INCLUDE)}"\ace\Trace.h"\
+ {$(INCLUDE)}"\ace\Synch_T.i"\
+ {$(INCLUDE)}"\ace\Synch_T.cpp"\
+ {$(INCLUDE)}"\ace\Set.i"\
+ {$(INCLUDE)}"\ace\Set.cpp"\
+ {$(INCLUDE)}"\ace\Message_Block.h"\
+ {$(INCLUDE)}"\ace\Timer_Queue.h"\
+ {$(INCLUDE)}"\ace\Proactor.i"\
+ {$(INCLUDE)}"\ace\Message_Block.i"\
+ {$(INCLUDE)}"\ace\Timer_Queue.i"\
+ {$(INCLUDE)}"\ace\Token.h"\
+ {$(INCLUDE)}"\ace\Local_Tokens.h"\
+ {$(INCLUDE)}"\ace\ReactorEx.i"\
+ {$(INCLUDE)}"\ace\Token.i"\
+ {$(INCLUDE)}"\ace\Stack.h"\
+ {$(INCLUDE)}"\ace\Synch_Options.h"\
+ {$(INCLUDE)}"\ace\Map_Manager.h"\
+ {$(INCLUDE)}"\ace\Local_Tokens.i"\
+ {$(INCLUDE)}"\ace\Stack.i"\
+ {$(INCLUDE)}"\ace\Stack.cpp"\
+ {$(INCLUDE)}"\ace\Map_Manager.i"\
+ {$(INCLUDE)}"\ace\Map_Manager.cpp"\
+ {$(INCLUDE)}"\ace\Handle_Set.h"\
+ {$(INCLUDE)}"\ace\Signal.h"\
+ {$(INCLUDE)}"\ace\Pipe.h"\
+ {$(INCLUDE)}"\ace\Reactor.i"\
+ {$(INCLUDE)}"\ace\Handle_Set.i"\
+ {$(INCLUDE)}"\ace\Signal.i"\
+ {$(INCLUDE)}"\ace\Pipe.i"\
+ {$(INCLUDE)}"\ace\Strategies.h"\
+ {$(INCLUDE)}"\ace\Connector.i"\
+ {$(INCLUDE)}"\ace\Connector.cpp"\
+ {$(INCLUDE)}"\ace\Strategies.cpp"\
+ {$(INCLUDE)}"\ace\Log_Record.h"\
+ {$(INCLUDE)}"\ace\Log_Priority.h"\
+ {$(INCLUDE)}"\ace\Log_Record.i"\
+ {$(INCLUDE)}"\ace\Get_Opt.i"\
+ {$(INCLUDE)}"\ace\SOCK_Connector.i"\
+ {$(INCLUDE)}"\ace\SOCK_IO.h"\
+ {$(INCLUDE)}"\ace\INET_Addr.h"\
+ {$(INCLUDE)}"\ace\SOCK_Stream.i"\
+ {$(INCLUDE)}"\ace\SOCK.h"\
+ {$(INCLUDE)}"\ace\SOCK_IO.i"\
+ {$(INCLUDE)}"\ace\Addr.h"\
+ {$(INCLUDE)}"\ace\IPC_SAP.h"\
+ {$(INCLUDE)}"\ace\SOCK.i"\
+ {$(INCLUDE)}"\ace\Addr.i"\
+ {$(INCLUDE)}"\ace\IPC_SAP.i"\
+ {$(INCLUDE)}"\ace\INET_Addr.i"\
+ {$(INCLUDE)}"\ace\Task.h"\
+ {$(INCLUDE)}"\ace\Svc_Handler.i"\
+ {$(INCLUDE)}"\ace\Svc_Handler.cpp"\
+ {$(INCLUDE)}"\ace\Message_Queue.h"\
+ {$(INCLUDE)}"\ace\Task.i"\
+ {$(INCLUDE)}"\ace\Task.cpp"\
+ {$(INCLUDE)}"\ace\IO_Cntl_Msg.h"\
+ {$(INCLUDE)}"\ace\Message_Queue.i"\
+ {$(INCLUDE)}"\ace\Message_Queue.cpp"\
+ {$(INCLUDE)}"\ace\Module.h"\
+ {$(INCLUDE)}"\ace\Module.i"\
+ {$(INCLUDE)}"\ace\Module.cpp"\
+ {$(INCLUDE)}"\ace\Stream_Modules.h"\
+ {$(INCLUDE)}"\ace\Stream_Modules.i"\
+ {$(INCLUDE)}"\ace\Stream_Modules.cpp"\
+ {$(INCLUDE)}"\ace\Dynamic.h"\
+ {$(INCLUDE)}"\ace\Dynamic.i"\
+ {$(INCLUDE)}"\ace\config.h"\
+ {$(INCLUDE)}"\ace\Time_Value.i"\
+ {$(INCLUDE)}"\ace\SString.h"\
+ {$(INCLUDE)}"\ace\SString.i"\
+ {$(INCLUDE)}"\sys\TYPES.H"\
+ {$(INCLUDE)}"\sys\STAT.H"\
+ {$(INCLUDE)}"\sys\TIMEB.H"\
+ {$(INCLUDE)}"\ace\OS.i"\
+ {$(INCLUDE)}"\ace\Malloc.i"\
+ {$(INCLUDE)}"\ace\Malloc_T.h"\
+ {$(INCLUDE)}"\ace\Memory_Pool.h"\
+ {$(INCLUDE)}"\ace\Malloc_T.i"\
+ {$(INCLUDE)}"\ace\Malloc_T.cpp"\
+ {$(INCLUDE)}"\ace\Mem_Map.h"\
+ {$(INCLUDE)}"\ace\Memory_Pool.i"\
+ {$(INCLUDE)}"\ace\Mem_Map.i"\
+
+NODEP_CPP_TS_CL=\
+ ".\..\..\ace\ace\Sync_T.h"\
+
+
+"$(INTDIR)\TS_Clerk_Handler.obj" : $(SOURCE) $(DEP_CPP_TS_CL) "$(INTDIR)"
+
+
+# End Source File
+################################################################################
+# Begin Source File
+
+SOURCE=.\TS_Server_Handler.cpp
+DEP_CPP_TS_SE=\
+ {$(INCLUDE)}"\ace\SString.h"\
+ {$(INCLUDE)}"\ace\Set.h"\
+ {$(INCLUDE)}"\ace\Get_Opt.h"\
+ {$(INCLUDE)}"\ace\Acceptor.h"\
+ {$(INCLUDE)}"\ace\SOCK_Acceptor.h"\
+ {$(INCLUDE)}"\ace\SOCK_Stream.h"\
+ {$(INCLUDE)}"\ace\Time_Request_Reply.h"\
+ ".\TS_Server_Handler.h"\
+ {$(INCLUDE)}"\ace\ACE.h"\
+ {$(INCLUDE)}"\ace\SString.i"\
+ {$(INCLUDE)}"\ace\OS.h"\
+ {$(INCLUDE)}"\ace\ACE.i"\
+ {$(INCLUDE)}"\ace\Time_Value.h"\
+ {$(INCLUDE)}"\sys\TYPES.H"\
+ {$(INCLUDE)}"\sys\STAT.H"\
+ {$(INCLUDE)}"\sys\TIMEB.H"\
+ {$(INCLUDE)}"\ace\Trace.h"\
+ {$(INCLUDE)}"\ace\OS.i"\
+ {$(INCLUDE)}"\ace\config.h"\
+ {$(INCLUDE)}"\ace\Time_Value.i"\
+ {$(INCLUDE)}"\ace\Log_Msg.h"\
+ {$(INCLUDE)}"\ace\Log_Record.h"\
+ {$(INCLUDE)}"\ace\Log_Priority.h"\
+ {$(INCLUDE)}"\ace\Log_Record.i"\
+ {$(INCLUDE)}"\ace\Set.i"\
+ {$(INCLUDE)}"\ace\Set.cpp"\
+ {$(INCLUDE)}"\ace\Get_Opt.i"\
+ {$(INCLUDE)}"\ace\Service_Config.h"\
+ {$(INCLUDE)}"\ace\Service_Object.h"\
+ {$(INCLUDE)}"\ace\Svc_Handler.h"\
+ {$(INCLUDE)}"\ace\Strategies.h"\
+ {$(INCLUDE)}"\ace\Acceptor.i"\
+ {$(INCLUDE)}"\ace\Acceptor.cpp"\
+ {$(INCLUDE)}"\ace\Thread_Manager.h"\
+ {$(INCLUDE)}"\ace\Proactor.h"\
+ {$(INCLUDE)}"\ace\ReactorEx.h"\
+ {$(INCLUDE)}"\ace\Service_Config.i"\
+ {$(INCLUDE)}"\ace\Reactor.h"\
+ {$(INCLUDE)}"\ace\Svc_Conf_Tokens.h"\
+ {$(INCLUDE)}"\ace\Thread.h"\
+ {$(INCLUDE)}"\ace\Synch.h"\
+ {$(INCLUDE)}"\ace\Thread_Manager.i"\
+ {$(INCLUDE)}"\ace\Thread.i"\
+ {$(INCLUDE)}"\ace\SV_Semaphore_Complex.h"\
+ {$(INCLUDE)}"\ace\Synch.i"\
+ {$(INCLUDE)}"\ace\Synch_T.h"\
+ {$(INCLUDE)}"\ace\SV_Semaphore_Simple.h"\
+ {$(INCLUDE)}"\ace\SV_Semaphore_Complex.i"\
+ {$(INCLUDE)}"\ace\SV_Semaphore_Simple.i"\
+ {$(INCLUDE)}"\ace\Synch_T.i"\
+ {$(INCLUDE)}"\ace\Synch_T.cpp"\
+ {$(INCLUDE)}"\ace\Message_Block.h"\
+ {$(INCLUDE)}"\ace\Timer_Queue.h"\
+ {$(INCLUDE)}"\ace\Event_Handler.h"\
+ {$(INCLUDE)}"\ace\Proactor.i"\
+ {$(INCLUDE)}"\ace\Malloc.h"\
+ {$(INCLUDE)}"\ace\Message_Block.i"\
+ {$(INCLUDE)}"\ace\Malloc.i"\
+ {$(INCLUDE)}"\ace\Malloc_T.h"\
+ {$(INCLUDE)}"\ace\Memory_Pool.h"\
+ {$(INCLUDE)}"\ace\Malloc_T.i"\
+ {$(INCLUDE)}"\ace\Malloc_T.cpp"\
+ {$(INCLUDE)}"\ace\Signal.h"\
+ {$(INCLUDE)}"\ace\Mem_Map.h"\
+ {$(INCLUDE)}"\ace\Memory_Pool.i"\
+ {$(INCLUDE)}"\ace\Signal.i"\
+ {$(INCLUDE)}"\ace\Mem_Map.i"\
+ {$(INCLUDE)}"\ace\Timer_Queue.i"\
+ {$(INCLUDE)}"\ace\Event_Handler.i"\
+ {$(INCLUDE)}"\ace\Token.h"\
+ {$(INCLUDE)}"\ace\Local_Tokens.h"\
+ {$(INCLUDE)}"\ace\ReactorEx.i"\
+ {$(INCLUDE)}"\ace\Token.i"\
+ {$(INCLUDE)}"\ace\Stack.h"\
+ {$(INCLUDE)}"\ace\Synch_Options.h"\
+ {$(INCLUDE)}"\ace\Map_Manager.h"\
+ {$(INCLUDE)}"\ace\Local_Tokens.i"\
+ {$(INCLUDE)}"\ace\Stack.i"\
+ {$(INCLUDE)}"\ace\Stack.cpp"\
+ {$(INCLUDE)}"\ace\Map_Manager.i"\
+ {$(INCLUDE)}"\ace\Map_Manager.cpp"\
+ {$(INCLUDE)}"\ace\Handle_Set.h"\
+ {$(INCLUDE)}"\ace\Pipe.h"\
+ {$(INCLUDE)}"\ace\Reactor.i"\
+ {$(INCLUDE)}"\ace\Handle_Set.i"\
+ {$(INCLUDE)}"\ace\Pipe.i"\
+ {$(INCLUDE)}"\ace\Shared_Object.h"\
+ {$(INCLUDE)}"\ace\Service_Object.i"\
+ {$(INCLUDE)}"\ace\Shared_Object.i"\
+ {$(INCLUDE)}"\ace\Task.h"\
+ {$(INCLUDE)}"\ace\Svc_Handler.i"\
+ {$(INCLUDE)}"\ace\Svc_Handler.cpp"\
+ {$(INCLUDE)}"\ace\Message_Queue.h"\
+ {$(INCLUDE)}"\ace\Task.i"\
+ {$(INCLUDE)}"\ace\Task.cpp"\
+ {$(INCLUDE)}"\ace\IO_Cntl_Msg.h"\
+ {$(INCLUDE)}"\ace\Message_Queue.i"\
+ {$(INCLUDE)}"\ace\Message_Queue.cpp"\
+ {$(INCLUDE)}"\ace\Module.h"\
+ {$(INCLUDE)}"\ace\Module.i"\
+ {$(INCLUDE)}"\ace\Module.cpp"\
+ {$(INCLUDE)}"\ace\Stream_Modules.h"\
+ {$(INCLUDE)}"\ace\Stream_Modules.i"\
+ {$(INCLUDE)}"\ace\Stream_Modules.cpp"\
+ {$(INCLUDE)}"\ace\Dynamic.h"\
+ {$(INCLUDE)}"\ace\Dynamic.i"\
+ {$(INCLUDE)}"\ace\Strategies.cpp"\
+ {$(INCLUDE)}"\ace\SOCK_Acceptor.i"\
+ {$(INCLUDE)}"\ace\SOCK_IO.h"\
+ {$(INCLUDE)}"\ace\INET_Addr.h"\
+ {$(INCLUDE)}"\ace\SOCK_Stream.i"\
+ {$(INCLUDE)}"\ace\SOCK.h"\
+ {$(INCLUDE)}"\ace\SOCK_IO.i"\
+ {$(INCLUDE)}"\ace\Addr.h"\
+ {$(INCLUDE)}"\ace\IPC_SAP.h"\
+ {$(INCLUDE)}"\ace\SOCK.i"\
+ {$(INCLUDE)}"\ace\Addr.i"\
+ {$(INCLUDE)}"\ace\IPC_SAP.i"\
+ {$(INCLUDE)}"\ace\INET_Addr.i"\
+
+NODEP_CPP_TS_SE=\
+ ".\..\..\ace\ace\Sync_T.h"\
+
+
+"$(INTDIR)\TS_Server_Handler.obj" : $(SOURCE) $(DEP_CPP_TS_SE) "$(INTDIR)"
+
+
+# End Source File
+################################################################################
+# Begin Source File
+
+SOURCE=.\Server_Logging_Handler.cpp
+DEP_CPP_SERVE=\
+ {$(INCLUDE)}"\ace\Synch.h"\
+ {$(INCLUDE)}"\ace\TLI_Acceptor.h"\
+ {$(INCLUDE)}"\ace\SOCK_Acceptor.h"\
+ {$(INCLUDE)}"\ace\Log_Msg.h"\
+ {$(INCLUDE)}"\ace\Get_Opt.h"\
+ {$(INCLUDE)}"\ace\Acceptor.h"\
+ ".\Server_Logging_Handler.h"\
+ {$(INCLUDE)}"\ace\ACE.h"\
+ {$(INCLUDE)}"\ace\SV_Semaphore_Complex.h"\
+ {$(INCLUDE)}"\ace\Synch.i"\
+ {$(INCLUDE)}"\ace\Synch_T.h"\
+ {$(INCLUDE)}"\ace\OS.h"\
+ {$(INCLUDE)}"\ace\ACE.i"\
+ {$(INCLUDE)}"\ace\Time_Value.h"\
+ {$(INCLUDE)}"\sys\TYPES.H"\
+ {$(INCLUDE)}"\sys\STAT.H"\
+ {$(INCLUDE)}"\sys\TIMEB.H"\
+ {$(INCLUDE)}"\ace\Trace.h"\
+ {$(INCLUDE)}"\ace\OS.i"\
+ {$(INCLUDE)}"\ace\config.h"\
+ {$(INCLUDE)}"\ace\Time_Value.i"\
+ {$(INCLUDE)}"\ace\SV_Semaphore_Simple.h"\
+ {$(INCLUDE)}"\ace\SV_Semaphore_Complex.i"\
+ {$(INCLUDE)}"\ace\SV_Semaphore_Simple.i"\
+ {$(INCLUDE)}"\ace\Synch_T.i"\
+ {$(INCLUDE)}"\ace\Synch_T.cpp"\
+ {$(INCLUDE)}"\ace\Thread.h"\
+ {$(INCLUDE)}"\ace\Thread.i"\
+ {$(INCLUDE)}"\ace\TLI.h"\
+ {$(INCLUDE)}"\ace\TLI_Stream.h"\
+ {$(INCLUDE)}"\ace\TLI_Acceptor.i"\
+ {$(INCLUDE)}"\ace\IPC_SAP.h"\
+ {$(INCLUDE)}"\ace\Addr.h"\
+ {$(INCLUDE)}"\ace\TLI.i"\
+ {$(INCLUDE)}"\ace\IPC_SAP.i"\
+ {$(INCLUDE)}"\ace\Addr.i"\
+ {$(INCLUDE)}"\ace\INET_Addr.h"\
+ {$(INCLUDE)}"\ace\TLI_Stream.i"\
+ {$(INCLUDE)}"\ace\INET_Addr.i"\
+ {$(INCLUDE)}"\ace\SOCK_Stream.h"\
+ {$(INCLUDE)}"\ace\SOCK_Acceptor.i"\
+ {$(INCLUDE)}"\ace\SOCK_IO.h"\
+ {$(INCLUDE)}"\ace\SOCK_Stream.i"\
+ {$(INCLUDE)}"\ace\SOCK.h"\
+ {$(INCLUDE)}"\ace\SOCK_IO.i"\
+ {$(INCLUDE)}"\ace\SOCK.i"\
+ {$(INCLUDE)}"\ace\Log_Record.h"\
+ {$(INCLUDE)}"\ace\Log_Priority.h"\
+ {$(INCLUDE)}"\ace\Log_Record.i"\
+ {$(INCLUDE)}"\ace\Get_Opt.i"\
+ {$(INCLUDE)}"\ace\Service_Config.h"\
+ {$(INCLUDE)}"\ace\Service_Object.h"\
+ {$(INCLUDE)}"\ace\Svc_Handler.h"\
+ {$(INCLUDE)}"\ace\Strategies.h"\
+ {$(INCLUDE)}"\ace\Acceptor.i"\
+ {$(INCLUDE)}"\ace\Acceptor.cpp"\
+ {$(INCLUDE)}"\ace\Thread_Manager.h"\
+ {$(INCLUDE)}"\ace\Set.h"\
+ {$(INCLUDE)}"\ace\Proactor.h"\
+ {$(INCLUDE)}"\ace\ReactorEx.h"\
+ {$(INCLUDE)}"\ace\Service_Config.i"\
+ {$(INCLUDE)}"\ace\Reactor.h"\
+ {$(INCLUDE)}"\ace\Svc_Conf_Tokens.h"\
+ {$(INCLUDE)}"\ace\Thread_Manager.i"\
+ {$(INCLUDE)}"\ace\Set.i"\
+ {$(INCLUDE)}"\ace\Set.cpp"\
+ {$(INCLUDE)}"\ace\Message_Block.h"\
+ {$(INCLUDE)}"\ace\Timer_Queue.h"\
+ {$(INCLUDE)}"\ace\Event_Handler.h"\
+ {$(INCLUDE)}"\ace\Proactor.i"\
+ {$(INCLUDE)}"\ace\Malloc.h"\
+ {$(INCLUDE)}"\ace\Message_Block.i"\
+ {$(INCLUDE)}"\ace\Malloc.i"\
+ {$(INCLUDE)}"\ace\Malloc_T.h"\
+ {$(INCLUDE)}"\ace\Memory_Pool.h"\
+ {$(INCLUDE)}"\ace\Malloc_T.i"\
+ {$(INCLUDE)}"\ace\Malloc_T.cpp"\
+ {$(INCLUDE)}"\ace\Signal.h"\
+ {$(INCLUDE)}"\ace\Mem_Map.h"\
+ {$(INCLUDE)}"\ace\Memory_Pool.i"\
+ {$(INCLUDE)}"\ace\Signal.i"\
+ {$(INCLUDE)}"\ace\Mem_Map.i"\
+ {$(INCLUDE)}"\ace\Timer_Queue.i"\
+ {$(INCLUDE)}"\ace\Event_Handler.i"\
+ {$(INCLUDE)}"\ace\Token.h"\
+ {$(INCLUDE)}"\ace\Local_Tokens.h"\
+ {$(INCLUDE)}"\ace\ReactorEx.i"\
+ {$(INCLUDE)}"\ace\Token.i"\
+ {$(INCLUDE)}"\ace\Stack.h"\
+ {$(INCLUDE)}"\ace\Synch_Options.h"\
+ {$(INCLUDE)}"\ace\Map_Manager.h"\
+ {$(INCLUDE)}"\ace\Local_Tokens.i"\
+ {$(INCLUDE)}"\ace\Stack.i"\
+ {$(INCLUDE)}"\ace\Stack.cpp"\
+ {$(INCLUDE)}"\ace\Map_Manager.i"\
+ {$(INCLUDE)}"\ace\Map_Manager.cpp"\
+ {$(INCLUDE)}"\ace\Handle_Set.h"\
+ {$(INCLUDE)}"\ace\Pipe.h"\
+ {$(INCLUDE)}"\ace\Reactor.i"\
+ {$(INCLUDE)}"\ace\Handle_Set.i"\
+ {$(INCLUDE)}"\ace\Pipe.i"\
+ {$(INCLUDE)}"\ace\Shared_Object.h"\
+ {$(INCLUDE)}"\ace\Service_Object.i"\
+ {$(INCLUDE)}"\ace\Shared_Object.i"\
+ {$(INCLUDE)}"\ace\Task.h"\
+ {$(INCLUDE)}"\ace\Svc_Handler.i"\
+ {$(INCLUDE)}"\ace\Svc_Handler.cpp"\
+ {$(INCLUDE)}"\ace\Message_Queue.h"\
+ {$(INCLUDE)}"\ace\Task.i"\
+ {$(INCLUDE)}"\ace\Task.cpp"\
+ {$(INCLUDE)}"\ace\IO_Cntl_Msg.h"\
+ {$(INCLUDE)}"\ace\Message_Queue.i"\
+ {$(INCLUDE)}"\ace\Message_Queue.cpp"\
+ {$(INCLUDE)}"\ace\Module.h"\
+ {$(INCLUDE)}"\ace\Module.i"\
+ {$(INCLUDE)}"\ace\Module.cpp"\
+ {$(INCLUDE)}"\ace\Stream_Modules.h"\
+ {$(INCLUDE)}"\ace\Stream_Modules.i"\
+ {$(INCLUDE)}"\ace\Stream_Modules.cpp"\
+ {$(INCLUDE)}"\ace\Dynamic.h"\
+ {$(INCLUDE)}"\ace\Dynamic.i"\
+ {$(INCLUDE)}"\ace\Strategies.cpp"\
+
+NODEP_CPP_SERVE=\
+ ".\..\..\ace\ace\Sync_T.h"\
+
+
+"$(INTDIR)\Server_Logging_Handler.obj" : $(SOURCE) $(DEP_CPP_SERVE) "$(INTDIR)"
+
+
+# End Source File
+################################################################################
+# Begin Source File
+
+SOURCE=.\Name_Handler.cpp
+DEP_CPP_NAME_=\
+ {$(INCLUDE)}"\ace\SString.h"\
+ {$(INCLUDE)}"\ace\Set.h"\
+ {$(INCLUDE)}"\ace\Get_Opt.h"\
+ {$(INCLUDE)}"\ace\Naming_Context.h"\
+ {$(INCLUDE)}"\ace\Acceptor.h"\
+ {$(INCLUDE)}"\ace\SOCK_Acceptor.h"\
+ {$(INCLUDE)}"\ace\SOCK_Stream.h"\
+ {$(INCLUDE)}"\ace\Name_Request_Reply.h"\
+ ".\Name_Handler.h"\
+ {$(INCLUDE)}"\ace\ACE.h"\
+ {$(INCLUDE)}"\ace\SString.i"\
+ {$(INCLUDE)}"\ace\OS.h"\
+ {$(INCLUDE)}"\ace\ACE.i"\
+ {$(INCLUDE)}"\ace\Time_Value.h"\
+ {$(INCLUDE)}"\sys\TYPES.H"\
+ {$(INCLUDE)}"\sys\STAT.H"\
+ {$(INCLUDE)}"\sys\TIMEB.H"\
+ {$(INCLUDE)}"\ace\Trace.h"\
+ {$(INCLUDE)}"\ace\OS.i"\
+ {$(INCLUDE)}"\ace\config.h"\
+ {$(INCLUDE)}"\ace\Time_Value.i"\
+ {$(INCLUDE)}"\ace\Log_Msg.h"\
+ {$(INCLUDE)}"\ace\Log_Record.h"\
+ {$(INCLUDE)}"\ace\Log_Priority.h"\
+ {$(INCLUDE)}"\ace\Log_Record.i"\
+ {$(INCLUDE)}"\ace\Set.i"\
+ {$(INCLUDE)}"\ace\Set.cpp"\
+ {$(INCLUDE)}"\ace\Get_Opt.i"\
+ {$(INCLUDE)}"\ace\Service_Object.h"\
+ {$(INCLUDE)}"\ace\Name_Proxy.h"\
+ {$(INCLUDE)}"\ace\Name_Space.h"\
+ {$(INCLUDE)}"\ace\Shared_Object.h"\
+ {$(INCLUDE)}"\ace\Event_Handler.h"\
+ {$(INCLUDE)}"\ace\Service_Object.i"\
+ {$(INCLUDE)}"\ace\Shared_Object.i"\
+ {$(INCLUDE)}"\ace\Event_Handler.i"\
+ {$(INCLUDE)}"\ace\INET_Addr.h"\
+ {$(INCLUDE)}"\ace\SOCK_Connector.h"\
+ {$(INCLUDE)}"\ace\Service_Config.h"\
+ {$(INCLUDE)}"\ace\Synch_Options.h"\
+ {$(INCLUDE)}"\ace\Addr.h"\
+ {$(INCLUDE)}"\ace\INET_Addr.i"\
+ {$(INCLUDE)}"\ace\Addr.i"\
+ {$(INCLUDE)}"\ace\SOCK_Connector.i"\
+ {$(INCLUDE)}"\ace\Thread_Manager.h"\
+ {$(INCLUDE)}"\ace\Proactor.h"\
+ {$(INCLUDE)}"\ace\ReactorEx.h"\
+ {$(INCLUDE)}"\ace\Service_Config.i"\
+ {$(INCLUDE)}"\ace\Reactor.h"\
+ {$(INCLUDE)}"\ace\Svc_Conf_Tokens.h"\
+ {$(INCLUDE)}"\ace\Thread.h"\
+ {$(INCLUDE)}"\ace\Synch.h"\
+ {$(INCLUDE)}"\ace\Thread_Manager.i"\
+ {$(INCLUDE)}"\ace\Thread.i"\
+ {$(INCLUDE)}"\ace\SV_Semaphore_Complex.h"\
+ {$(INCLUDE)}"\ace\Synch.i"\
+ {$(INCLUDE)}"\ace\Synch_T.h"\
+ {$(INCLUDE)}"\ace\SV_Semaphore_Simple.h"\
+ {$(INCLUDE)}"\ace\SV_Semaphore_Complex.i"\
+ {$(INCLUDE)}"\ace\SV_Semaphore_Simple.i"\
+ {$(INCLUDE)}"\ace\Synch_T.i"\
+ {$(INCLUDE)}"\ace\Synch_T.cpp"\
+ {$(INCLUDE)}"\ace\Message_Block.h"\
+ {$(INCLUDE)}"\ace\Timer_Queue.h"\
+ {$(INCLUDE)}"\ace\Proactor.i"\
+ {$(INCLUDE)}"\ace\Malloc.h"\
+ {$(INCLUDE)}"\ace\Message_Block.i"\
+ {$(INCLUDE)}"\ace\Malloc.i"\
+ {$(INCLUDE)}"\ace\Malloc_T.h"\
+ {$(INCLUDE)}"\ace\Memory_Pool.h"\
+ {$(INCLUDE)}"\ace\Malloc_T.i"\
+ {$(INCLUDE)}"\ace\Malloc_T.cpp"\
+ {$(INCLUDE)}"\ace\Signal.h"\
+ {$(INCLUDE)}"\ace\Mem_Map.h"\
+ {$(INCLUDE)}"\ace\Memory_Pool.i"\
+ {$(INCLUDE)}"\ace\Signal.i"\
+ {$(INCLUDE)}"\ace\Mem_Map.i"\
+ {$(INCLUDE)}"\ace\Timer_Queue.i"\
+ {$(INCLUDE)}"\ace\Token.h"\
+ {$(INCLUDE)}"\ace\Local_Tokens.h"\
+ {$(INCLUDE)}"\ace\ReactorEx.i"\
+ {$(INCLUDE)}"\ace\Token.i"\
+ {$(INCLUDE)}"\ace\Stack.h"\
+ {$(INCLUDE)}"\ace\Map_Manager.h"\
+ {$(INCLUDE)}"\ace\Local_Tokens.i"\
+ {$(INCLUDE)}"\ace\Stack.i"\
+ {$(INCLUDE)}"\ace\Stack.cpp"\
+ {$(INCLUDE)}"\ace\Map_Manager.i"\
+ {$(INCLUDE)}"\ace\Map_Manager.cpp"\
+ {$(INCLUDE)}"\ace\Handle_Set.h"\
+ {$(INCLUDE)}"\ace\Pipe.h"\
+ {$(INCLUDE)}"\ace\Reactor.i"\
+ {$(INCLUDE)}"\ace\Handle_Set.i"\
+ {$(INCLUDE)}"\ace\Pipe.i"\
+ {$(INCLUDE)}"\ace\Svc_Handler.h"\
+ {$(INCLUDE)}"\ace\Strategies.h"\
+ {$(INCLUDE)}"\ace\Acceptor.i"\
+ {$(INCLUDE)}"\ace\Acceptor.cpp"\
+ {$(INCLUDE)}"\ace\Task.h"\
+ {$(INCLUDE)}"\ace\Svc_Handler.i"\
+ {$(INCLUDE)}"\ace\Svc_Handler.cpp"\
+ {$(INCLUDE)}"\ace\Message_Queue.h"\
+ {$(INCLUDE)}"\ace\Task.i"\
+ {$(INCLUDE)}"\ace\Task.cpp"\
+ {$(INCLUDE)}"\ace\IO_Cntl_Msg.h"\
+ {$(INCLUDE)}"\ace\Message_Queue.i"\
+ {$(INCLUDE)}"\ace\Message_Queue.cpp"\
+ {$(INCLUDE)}"\ace\Module.h"\
+ {$(INCLUDE)}"\ace\Module.i"\
+ {$(INCLUDE)}"\ace\Module.cpp"\
+ {$(INCLUDE)}"\ace\Stream_Modules.h"\
+ {$(INCLUDE)}"\ace\Stream_Modules.i"\
+ {$(INCLUDE)}"\ace\Stream_Modules.cpp"\
+ {$(INCLUDE)}"\ace\Dynamic.h"\
+ {$(INCLUDE)}"\ace\Dynamic.i"\
+ {$(INCLUDE)}"\ace\Strategies.cpp"\
+ {$(INCLUDE)}"\ace\SOCK_Acceptor.i"\
+ {$(INCLUDE)}"\ace\SOCK_IO.h"\
+ {$(INCLUDE)}"\ace\SOCK_Stream.i"\
+ {$(INCLUDE)}"\ace\SOCK.h"\
+ {$(INCLUDE)}"\ace\SOCK_IO.i"\
+ {$(INCLUDE)}"\ace\IPC_SAP.h"\
+ {$(INCLUDE)}"\ace\SOCK.i"\
+ {$(INCLUDE)}"\ace\IPC_SAP.i"\
+
+NODEP_CPP_NAME_=\
+ ".\..\..\ace\ace\Sync_T.h"\
+
+
+"$(INTDIR)\Name_Handler.obj" : $(SOURCE) $(DEP_CPP_NAME_) "$(INTDIR)"
+
+
+# End Source File
+################################################################################
+# Begin Source File
+
+SOURCE=.\Client_Logging_Handler.cpp
+DEP_CPP_CLIEN=\
+ {$(INCLUDE)}"\ace\Service_Config.h"\
+ {$(INCLUDE)}"\ace\Connector.h"\
+ {$(INCLUDE)}"\ace\Log_Msg.h"\
+ {$(INCLUDE)}"\ace\Get_Opt.h"\
+ {$(INCLUDE)}"\ace\SOCK_Connector.h"\
+ {$(INCLUDE)}"\ace\SOCK_Stream.h"\
+ {$(INCLUDE)}"\ace\FIFO_Recv_Msg.h"\
+ ".\Client_Logging_Handler.h"\
+ {$(INCLUDE)}"\ace\Service_Object.h"\
+ {$(INCLUDE)}"\ace\Thread_Manager.h"\
+ {$(INCLUDE)}"\ace\Set.h"\
+ {$(INCLUDE)}"\ace\Proactor.h"\
+ {$(INCLUDE)}"\ace\ReactorEx.h"\
+ {$(INCLUDE)}"\ace\Service_Config.i"\
+ {$(INCLUDE)}"\ace\Reactor.h"\
+ {$(INCLUDE)}"\ace\Svc_Conf_Tokens.h"\
+ {$(INCLUDE)}"\ace\Shared_Object.h"\
+ {$(INCLUDE)}"\ace\Event_Handler.h"\
+ {$(INCLUDE)}"\ace\Service_Object.i"\
+ {$(INCLUDE)}"\ace\ACE.h"\
+ {$(INCLUDE)}"\ace\Shared_Object.i"\
+ {$(INCLUDE)}"\ace\OS.h"\
+ {$(INCLUDE)}"\ace\ACE.i"\
+ {$(INCLUDE)}"\ace\Time_Value.h"\
+ {$(INCLUDE)}"\sys\TYPES.H"\
+ {$(INCLUDE)}"\sys\STAT.H"\
+ {$(INCLUDE)}"\sys\TIMEB.H"\
+ {$(INCLUDE)}"\ace\Trace.h"\
+ {$(INCLUDE)}"\ace\OS.i"\
+ {$(INCLUDE)}"\ace\config.h"\
+ {$(INCLUDE)}"\ace\Time_Value.i"\
+ {$(INCLUDE)}"\ace\Event_Handler.i"\
+ {$(INCLUDE)}"\ace\Thread.h"\
+ {$(INCLUDE)}"\ace\Synch.h"\
+ {$(INCLUDE)}"\ace\Thread_Manager.i"\
+ {$(INCLUDE)}"\ace\Thread.i"\
+ {$(INCLUDE)}"\ace\SV_Semaphore_Complex.h"\
+ {$(INCLUDE)}"\ace\Synch.i"\
+ {$(INCLUDE)}"\ace\Synch_T.h"\
+ {$(INCLUDE)}"\ace\SV_Semaphore_Simple.h"\
+ {$(INCLUDE)}"\ace\SV_Semaphore_Complex.i"\
+ {$(INCLUDE)}"\ace\SV_Semaphore_Simple.i"\
+ {$(INCLUDE)}"\ace\Synch_T.i"\
+ {$(INCLUDE)}"\ace\Synch_T.cpp"\
+ {$(INCLUDE)}"\ace\Set.i"\
+ {$(INCLUDE)}"\ace\Set.cpp"\
+ {$(INCLUDE)}"\ace\Message_Block.h"\
+ {$(INCLUDE)}"\ace\Timer_Queue.h"\
+ {$(INCLUDE)}"\ace\Proactor.i"\
+ {$(INCLUDE)}"\ace\Malloc.h"\
+ {$(INCLUDE)}"\ace\Message_Block.i"\
+ {$(INCLUDE)}"\ace\Malloc.i"\
+ {$(INCLUDE)}"\ace\Malloc_T.h"\
+ {$(INCLUDE)}"\ace\Memory_Pool.h"\
+ {$(INCLUDE)}"\ace\Malloc_T.i"\
+ {$(INCLUDE)}"\ace\Malloc_T.cpp"\
+ {$(INCLUDE)}"\ace\Signal.h"\
+ {$(INCLUDE)}"\ace\Mem_Map.h"\
+ {$(INCLUDE)}"\ace\Memory_Pool.i"\
+ {$(INCLUDE)}"\ace\Signal.i"\
+ {$(INCLUDE)}"\ace\Mem_Map.i"\
+ {$(INCLUDE)}"\ace\Timer_Queue.i"\
+ {$(INCLUDE)}"\ace\Token.h"\
+ {$(INCLUDE)}"\ace\Local_Tokens.h"\
+ {$(INCLUDE)}"\ace\ReactorEx.i"\
+ {$(INCLUDE)}"\ace\Token.i"\
+ {$(INCLUDE)}"\ace\Stack.h"\
+ {$(INCLUDE)}"\ace\Synch_Options.h"\
+ {$(INCLUDE)}"\ace\Map_Manager.h"\
+ {$(INCLUDE)}"\ace\Local_Tokens.i"\
+ {$(INCLUDE)}"\ace\Stack.i"\
+ {$(INCLUDE)}"\ace\Stack.cpp"\
+ {$(INCLUDE)}"\ace\Map_Manager.i"\
+ {$(INCLUDE)}"\ace\Map_Manager.cpp"\
+ {$(INCLUDE)}"\ace\Handle_Set.h"\
+ {$(INCLUDE)}"\ace\Pipe.h"\
+ {$(INCLUDE)}"\ace\Reactor.i"\
+ {$(INCLUDE)}"\ace\Handle_Set.i"\
+ {$(INCLUDE)}"\ace\Pipe.i"\
+ {$(INCLUDE)}"\ace\Svc_Handler.h"\
+ {$(INCLUDE)}"\ace\Strategies.h"\
+ {$(INCLUDE)}"\ace\Connector.i"\
+ {$(INCLUDE)}"\ace\Connector.cpp"\
+ {$(INCLUDE)}"\ace\Task.h"\
+ {$(INCLUDE)}"\ace\Svc_Handler.i"\
+ {$(INCLUDE)}"\ace\Svc_Handler.cpp"\
+ {$(INCLUDE)}"\ace\Message_Queue.h"\
+ {$(INCLUDE)}"\ace\Task.i"\
+ {$(INCLUDE)}"\ace\Task.cpp"\
+ {$(INCLUDE)}"\ace\IO_Cntl_Msg.h"\
+ {$(INCLUDE)}"\ace\Message_Queue.i"\
+ {$(INCLUDE)}"\ace\Message_Queue.cpp"\
+ {$(INCLUDE)}"\ace\Module.h"\
+ {$(INCLUDE)}"\ace\Module.i"\
+ {$(INCLUDE)}"\ace\Module.cpp"\
+ {$(INCLUDE)}"\ace\Stream_Modules.h"\
+ {$(INCLUDE)}"\ace\Stream_Modules.i"\
+ {$(INCLUDE)}"\ace\Stream_Modules.cpp"\
+ {$(INCLUDE)}"\ace\Dynamic.h"\
+ {$(INCLUDE)}"\ace\Dynamic.i"\
+ {$(INCLUDE)}"\ace\Strategies.cpp"\
+ {$(INCLUDE)}"\ace\Log_Record.h"\
+ {$(INCLUDE)}"\ace\Log_Priority.h"\
+ {$(INCLUDE)}"\ace\Log_Record.i"\
+ {$(INCLUDE)}"\ace\Get_Opt.i"\
+ {$(INCLUDE)}"\ace\SOCK_Connector.i"\
+ {$(INCLUDE)}"\ace\SOCK_IO.h"\
+ {$(INCLUDE)}"\ace\INET_Addr.h"\
+ {$(INCLUDE)}"\ace\SOCK_Stream.i"\
+ {$(INCLUDE)}"\ace\SOCK.h"\
+ {$(INCLUDE)}"\ace\SOCK_IO.i"\
+ {$(INCLUDE)}"\ace\Addr.h"\
+ {$(INCLUDE)}"\ace\IPC_SAP.h"\
+ {$(INCLUDE)}"\ace\SOCK.i"\
+ {$(INCLUDE)}"\ace\Addr.i"\
+ {$(INCLUDE)}"\ace\IPC_SAP.i"\
+ {$(INCLUDE)}"\ace\INET_Addr.i"\
+ {$(INCLUDE)}"\ace\FIFO_Recv.h"\
+ {$(INCLUDE)}"\ace\FIFO_Recv_Msg.i"\
+ {$(INCLUDE)}"\ace\FIFO.h"\
+ {$(INCLUDE)}"\ace\FIFO_Recv.i"\
+ {$(INCLUDE)}"\ace\FIFO.i"\
+
+NODEP_CPP_CLIEN=\
+ ".\..\..\ace\ace\Sync_T.h"\
+
+
+"$(INTDIR)\Client_Logging_Handler.obj" : $(SOURCE) $(DEP_CPP_CLIEN) "$(INTDIR)"
+
+
+# End Source File
+################################################################################
+# Begin Source File
+
+SOURCE=.\Logging_Strategy.cpp
+DEP_CPP_LOGGI=\
+ {$(INCLUDE)}"\ace\Get_Opt.h"\
+ {$(INCLUDE)}"\ace\Log_Msg.h"\
+ {$(INCLUDE)}"\ace\Service_Object.h"\
+ ".\Logging_Strategy.h"\
+ {$(INCLUDE)}"\ace\ACE.h"\
+ {$(INCLUDE)}"\ace\Get_Opt.i"\
+ {$(INCLUDE)}"\ace\OS.h"\
+ {$(INCLUDE)}"\ace\ACE.i"\
+ {$(INCLUDE)}"\ace\Time_Value.h"\
+ {$(INCLUDE)}"\sys\TYPES.H"\
+ {$(INCLUDE)}"\sys\STAT.H"\
+ {$(INCLUDE)}"\sys\TIMEB.H"\
+ {$(INCLUDE)}"\ace\Trace.h"\
+ {$(INCLUDE)}"\ace\OS.i"\
+ {$(INCLUDE)}"\ace\config.h"\
+ {$(INCLUDE)}"\ace\Time_Value.i"\
+ {$(INCLUDE)}"\ace\Log_Record.h"\
+ {$(INCLUDE)}"\ace\Log_Priority.h"\
+ {$(INCLUDE)}"\ace\Log_Record.i"\
+ {$(INCLUDE)}"\ace\Shared_Object.h"\
+ {$(INCLUDE)}"\ace\Event_Handler.h"\
+ {$(INCLUDE)}"\ace\Service_Object.i"\
+ {$(INCLUDE)}"\ace\Shared_Object.i"\
+ {$(INCLUDE)}"\ace\Event_Handler.i"\
+
+
+"$(INTDIR)\Logging_Strategy.obj" : $(SOURCE) $(DEP_CPP_LOGGI) "$(INTDIR)"
+
+
+# End Source File
+# End Target
+# End Project
+################################################################################
diff --git a/netsvcs/lib/netsvcs.mdp b/netsvcs/lib/netsvcs.mdp Binary files differnew file mode 100644 index 00000000000..84178cff993 --- /dev/null +++ b/netsvcs/lib/netsvcs.mdp diff --git a/netsvcs/servers/Makefile b/netsvcs/servers/Makefile new file mode 100644 index 00000000000..1c9e0d1dc9f --- /dev/null +++ b/netsvcs/servers/Makefile @@ -0,0 +1,51 @@ +#---------------------------------------------------------------------------- +# @(#)Makefile 1.1 10/18/96 +# +# Makefile +#---------------------------------------------------------------------------- + +#---------------------------------------------------------------------------- +# Local macros +#---------------------------------------------------------------------------- + +BIN = main + +FILES = main + +LSRC = $(addsuffix .cpp,$(FILES)) +LOBJ = $(LSRC:%.cpp=$(VDIR)%.o) +SHOBJ = $(addsuffix .so,$(FILES)) + +LDLIBS = -lnet_svcs + +VLDLIBS = $(LDLIBS:%=%$(VAR)) + +BUILD = $(VBIN) + +#---------------------------------------------------------------------------- +# Include macros and targets +#---------------------------------------------------------------------------- + +include $(WRAPPER_ROOT)/include/makeinclude/wrapper_macros.GNU +include $(WRAPPER_ROOT)/include/makeinclude/macros.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.common.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.nonested.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.lib.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.bin.GNU +include $(WRAPPER_ROOT)/include/makeinclude/rules.local.GNU + +#---------------------------------------------------------------------------- +# Local targets +#---------------------------------------------------------------------------- + +CPPFLAGS += -I$(WRAPPER_ROOT)/netsvcs/lib + +#---------------------------------------------------------------------------- +# Dependencies +#---------------------------------------------------------------------------- +# DO NOT DELETE THIS LINE -- g++dep uses it. +# DO NOT PUT ANYTHING AFTER THIS LINE, IT WILL GO AWAY. + + + +# IF YOU PUT ANYTHING HERE IT WILL GO AWAY diff --git a/netsvcs/servers/README b/netsvcs/servers/README new file mode 100644 index 00000000000..d5dee4ff601 --- /dev/null +++ b/netsvcs/servers/README @@ -0,0 +1,29 @@ +This directory contains the driver program that links the various +services together, either statically or dynamically, to form complete +server programs. + +You can configure the following ACE network services into the driver +program by changing how the svc.conf file is setup: + + . Logger -- Controls the output of all services that are + invoked along with the Logger service. Please see the README + file in /netsvcs/lib 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 distributed 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. diff --git a/netsvcs/servers/cli.conf b/netsvcs/servers/cli.conf new file mode 100644 index 00000000000..875e445f813 --- /dev/null +++ b/netsvcs/servers/cli.conf @@ -0,0 +1,11 @@ +# UNIX version +# +# These are the services that can be linked into ACE. +# Note that you can replace the hardcoded "../lib/libnet_svcs.so" with +# a relative path if you set your LD search path correctly -- ACE will +# locate this for you automatically by reading your LD search path! +# In addition, you can replace the hardcoded "-p 20xxx" with "-p +# $PORTxxx" if you set your environment variables correctly. + +# Activate the Client Logging Daemon. +dynamic Client_Logging_Service Service_Object * ../lib/libnet_svcs.so:_make_ACE_Client_Logging_Connector() active "-p 20009 -h merengue" diff --git a/netsvcs/servers/main.cpp b/netsvcs/servers/main.cpp new file mode 100644 index 00000000000..acfb491c7df --- /dev/null +++ b/netsvcs/servers/main.cpp @@ -0,0 +1,77 @@ +#include "ace/Service_Config.h" +// @(#)main.cpp 1.1 10/18/96 + +#include "TS_Clerk_Handler.h" +#include "TS_Server_Handler.h" +#include "Client_Logging_Handler.h" +#include "Name_Handler.h" +#include "Token_Handler.h" +#include "Server_Logging_Handler.h" +#include "Logging_Strategy.h" + +int +main (int argc, char *argv[]) +{ + ACE_Service_Config daemon; + + // Try to link in the svc.conf entries dynamically. + if (daemon.open (argc, argv) == -1) + { + if (errno != ENOENT) + ACE_ERROR ((LM_ERROR, "%p\n%a", "open", 1)); + else // Use static binding. + { + char *l_argv[3]; + ACE_Service_Object *so; + + l_argv[0] = "-p " ACE_DEFAULT_NAME_SERVER_PORT_STR; + l_argv[1] = 0; + so = ACE_SVC_INVOKE (ACE_Name_Acceptor); + + if (so->init (1, l_argv) == -1) + ACE_ERROR ((LM_ERROR, "%p\n%a", "Name_Service", 1)); + + l_argv[0] = "-p " ACE_DEFAULT_TIME_SERVER_PORT_STR; + l_argv[1] = 0; + so = ACE_SVC_INVOKE (ACE_TS_Server_Acceptor); + + if (so->init (2, l_argv) == -1) + ACE_ERROR ((LM_ERROR, "%p\n%a", "ACE_TS_Server_Acceptor", 1)); + + l_argv[0] = argv[0]; + l_argv[1] = "-p 10011"; + so = ACE_SVC_INVOKE (ACE_TS_Clerk_Processor); + + if (so->init (2, l_argv) == -1) + ACE_ERROR ((LM_ERROR, "%p\n%a", "ACE_TS_Clerk_Processor", 1)); + + l_argv[0] = "-p " ACE_DEFAULT_TOKEN_SERVER_PORT_STR; + l_argv[1] = 0; + so = ACE_SVC_INVOKE (ACE_Token_Acceptor); + + if (so->init (1, l_argv) == -1) + ACE_ERROR ((LM_ERROR, "%p\n%a", "Token_Service", 1)); + + l_argv[0] = "-p " ACE_DEFAULT_LOGGING_SERVER_PORT_STR; + l_argv[1] = 0; + so = ACE_SVC_INVOKE (ACE_Server_Logging_Acceptor); + + if (so->init (1, l_argv) == -1) + ACE_ERROR ((LM_ERROR, "%p\n%a", "Logging_Service", 1)); + + l_argv[0] = "-p " ACE_DEFAULT_THR_LOGGING_SERVER_PORT_STR; + l_argv[1] = 0; + so = ACE_SVC_INVOKE (ACE_Thr_Server_Logging_Acceptor); + + if (so->init (1, l_argv) == -1) + ACE_ERROR ((LM_ERROR, "%p\n%a", "Thr_Logging_Service", 1)); + } + } + + // Run forever, performing the configured services until we are shut + // down by a SIGINT/SIGQUIT signal. + + daemon.run_reactor_event_loop (); + + return 0; +} diff --git a/netsvcs/servers/ntsvc.conf b/netsvcs/servers/ntsvc.conf new file mode 100644 index 00000000000..94ed5d78c2a --- /dev/null +++ b/netsvcs/servers/ntsvc.conf @@ -0,0 +1,12 @@ +# Windows NT version. +# +# These are the services that can be linked into ACE. +# Note that your path needs to include the path for netsvcs.dll +# In addition, you can replace the hardcoded "-p 20xxx" with "-p +# $PORTxxx" if you set your environment variables correctly. + +dynamic Token_Service Service_Object * netsvcs.dll:_make_ACE_Token_Acceptor() "-p 20202" +dynamic Name_Server Service_Object * netsvcs.dll:_make_ACE_Name_Acceptor() "-p 20012" +#dynamic Client_Logging_Service Service_Object * netsvcs.dll:_make_ACE_Client_Logging_Connector() active "-p 20008" +#dynamic Server_Logging_Service Service_Object * netsvcs.dll:_make_ACE_Server_Logging_Acceptor() active "-p 20009" +#dynamic Thr_Server_Logging_Service Service_Object * netsvcs.dll:_make_ACE_Thr_Server_Logging_Acceptor() active "-p 20020" diff --git a/netsvcs/servers/servers.mak b/netsvcs/servers/servers.mak new file mode 100644 index 00000000000..b88c04c4b51 --- /dev/null +++ b/netsvcs/servers/servers.mak @@ -0,0 +1,402 @@ +# Microsoft Developer Studio Generated NMAKE File, Format Version 4.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Console Application" 0x0103
+
+!IF "$(CFG)" == ""
+CFG=servers - Win32 Debug
+!MESSAGE No configuration specified. Defaulting to servers - Win32 Debug.
+!ENDIF
+
+!IF "$(CFG)" != "servers - Win32 Release" && "$(CFG)" !=\
+ "servers - Win32 Debug"
+!MESSAGE Invalid configuration "$(CFG)" specified.
+!MESSAGE You can specify a configuration when running NMAKE on this makefile
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "servers.mak" CFG="servers - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "servers - Win32 Release" (based on "Win32 (x86) Console Application")
+!MESSAGE "servers - Win32 Debug" (based on "Win32 (x86) Console Application")
+!MESSAGE
+!ERROR An invalid configuration is specified.
+!ENDIF
+
+!IF "$(OS)" == "Windows_NT"
+NULL=
+!ELSE
+NULL=nul
+!ENDIF
+################################################################################
+# Begin Project
+# PROP Target_Last_Scanned "servers - Win32 Debug"
+RSC=rc.exe
+CPP=cl.exe
+
+!IF "$(CFG)" == "servers - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# PROP Target_Dir ""
+OUTDIR=.\Release
+INTDIR=.\Release
+
+ALL : "$(OUTDIR)\servers.exe"
+
+CLEAN :
+ -@erase ".\Release\servers.exe"
+ -@erase ".\Release\main.obj"
+
+"$(OUTDIR)" :
+ if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
+
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /YX /c
+# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /YX /c
+CPP_PROJ=/nologo /ML /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE"\
+ /Fp"$(INTDIR)/servers.pch" /YX /Fo"$(INTDIR)/" /c
+CPP_OBJS=.\Release/
+CPP_SBRS=
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+BSC32_FLAGS=/nologo /o"$(OUTDIR)/servers.bsc"
+BSC32_SBRS=
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib /nologo /subsystem:console /machine:I386
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib /nologo /subsystem:console /machine:I386
+LINK32_FLAGS=kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib\
+ advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib /nologo\
+ /subsystem:console /incremental:no /pdb:"$(OUTDIR)/servers.pdb" /machine:I386\
+ /out:"$(OUTDIR)/servers.exe"
+LINK32_OBJS= \
+ "$(INTDIR)/main.obj"
+
+"$(OUTDIR)\servers.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
+ $(LINK32) @<<
+ $(LINK32_FLAGS) $(LINK32_OBJS)
+<<
+
+!ELSEIF "$(CFG)" == "servers - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir ""
+# PROP Intermediate_Dir "debug"
+# PROP Target_Dir ""
+OUTDIR=.
+INTDIR=.\debug
+
+ALL : "$(OUTDIR)\main.exe"
+
+CLEAN :
+ -@erase ".\debug\vc40.pdb"
+ -@erase ".\debug\vc40.idb"
+ -@erase ".\main.exe"
+ -@erase ".\debug\main.obj"
+ -@erase ".\main.ilk"
+ -@erase ".\main.pdb"
+
+"$(INTDIR)" :
+ if not exist "$(INTDIR)/$(NULL)" mkdir "$(INTDIR)"
+
+# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /YX /c
+# ADD CPP /nologo /MDd /W3 /Gm /GX /Zi /Od /I "..\lib" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /YX /c
+CPP_PROJ=/nologo /MDd /W3 /Gm /GX /Zi /Od /I "..\lib" /D "WIN32" /D "_DEBUG" /D\
+ "_CONSOLE" /Fp"$(INTDIR)/servers.pch" /YX /Fo"$(INTDIR)/" /Fd"$(INTDIR)/" /c
+CPP_OBJS=.\debug/
+CPP_SBRS=
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+BSC32_FLAGS=/nologo /o"$(OUTDIR)/servers.bsc"
+BSC32_SBRS=
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib /nologo /subsystem:console /debug /machine:I386
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib ace.lib netsvcs.lib /nologo /subsystem:console /debug /machine:I386 /out:"main.exe"
+LINK32_FLAGS=kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib\
+ advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib ace.lib netsvcs.lib\
+ /nologo /subsystem:console /incremental:yes /pdb:"$(OUTDIR)/main.pdb" /debug\
+ /machine:I386 /out:"$(OUTDIR)/main.exe"
+LINK32_OBJS= \
+ "$(INTDIR)/main.obj"
+
+"$(OUTDIR)\main.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
+ $(LINK32) @<<
+ $(LINK32_FLAGS) $(LINK32_OBJS)
+<<
+
+!ENDIF
+
+.c{$(CPP_OBJS)}.obj:
+ $(CPP) $(CPP_PROJ) $<
+
+.cpp{$(CPP_OBJS)}.obj:
+ $(CPP) $(CPP_PROJ) $<
+
+.cxx{$(CPP_OBJS)}.obj:
+ $(CPP) $(CPP_PROJ) $<
+
+.c{$(CPP_SBRS)}.sbr:
+ $(CPP) $(CPP_PROJ) $<
+
+.cpp{$(CPP_SBRS)}.sbr:
+ $(CPP) $(CPP_PROJ) $<
+
+.cxx{$(CPP_SBRS)}.sbr:
+ $(CPP) $(CPP_PROJ) $<
+
+################################################################################
+# Begin Target
+
+# Name "servers - Win32 Release"
+# Name "servers - Win32 Debug"
+
+!IF "$(CFG)" == "servers - Win32 Release"
+
+!ELSEIF "$(CFG)" == "servers - Win32 Debug"
+
+!ENDIF
+
+################################################################################
+# Begin Source File
+
+SOURCE=.\main.cpp
+
+!IF "$(CFG)" == "servers - Win32 Release"
+
+DEP_CPP_MAIN_=\
+ {$(INCLUDE)}"\ace\Service_Config.h"\
+ {$(INCLUDE)}"\ace\Service_Object.h"\
+ {$(INCLUDE)}"\ace\Thread_Manager.h"\
+ {$(INCLUDE)}"\ace\Set.h"\
+ {$(INCLUDE)}"\ace\Proactor.h"\
+ {$(INCLUDE)}"\ace\ReactorEx.h"\
+ {$(INCLUDE)}"\ace\Service_Config.i"\
+ {$(INCLUDE)}"\ace\Reactor.h"\
+ {$(INCLUDE)}"\ace\Svc_Conf_Tokens.h"\
+ {$(INCLUDE)}"\ace\Shared_Object.h"\
+ {$(INCLUDE)}"\ace\Event_Handler.h"\
+ {$(INCLUDE)}"\ace\Log_Msg.h"\
+ {$(INCLUDE)}"\ace\Service_Object.i"\
+ {$(INCLUDE)}"\ace\ACE.h"\
+ {$(INCLUDE)}"\ace\Shared_Object.i"\
+ {$(INCLUDE)}"\ace\OS.h"\
+ {$(INCLUDE)}"\ace\ACE.i"\
+ {$(INCLUDE)}"\ace\Time_Value.h"\
+ {$(INCLUDE)}"\sys\TYPES.H"\
+ {$(INCLUDE)}"\sys\STAT.H"\
+ {$(INCLUDE)}"\sys\TIMEB.H"\
+ {$(INCLUDE)}"\ace\msg_hack.h"\
+ {$(INCLUDE)}"\ace\Trace.h"\
+ {$(INCLUDE)}"\ace\OS.i"\
+ {$(INCLUDE)}"\ace\config.h"\
+ {$(INCLUDE)}"\ace\Time_Value.i"\
+ {$(INCLUDE)}"\ace\Event_Handler.i"\
+ {$(INCLUDE)}"\ace\Log_Record.h"\
+ {$(INCLUDE)}"\ace\Log_Priority.h"\
+ {$(INCLUDE)}"\ace\Log_Record.i"\
+ {$(INCLUDE)}"\ace\Thread.h"\
+ {$(INCLUDE)}"\ace\Synch.h"\
+ {$(INCLUDE)}"\ace\Thread_Manager.i"\
+ {$(INCLUDE)}"\ace\Thread.i"\
+ {$(INCLUDE)}"\ace\SV_Semaphore_Complex.h"\
+ {$(INCLUDE)}"\ace\Synch.i"\
+ {$(INCLUDE)}"\ace\Synch_T.h"\
+ {$(INCLUDE)}"\ace\SV_Semaphore_Simple.h"\
+ {$(INCLUDE)}"\ace\SV_Semaphore_Complex.i"\
+ {$(INCLUDE)}"\ace\SV_Semaphore_Simple.i"\
+ {$(INCLUDE)}"\ace\Synch_T.i"\
+ {$(INCLUDE)}"\ace\Synch_T.cpp"\
+ {$(INCLUDE)}"\ace\Set.i"\
+ {$(INCLUDE)}"\ace\Set.cpp"\
+ {$(INCLUDE)}"\ace\Message_Block.h"\
+ {$(INCLUDE)}"\ace\Timer_Queue.h"\
+ {$(INCLUDE)}"\ace\Proactor.i"\
+ {$(INCLUDE)}"\ace\Malloc.h"\
+ {$(INCLUDE)}"\ace\Message_Block.i"\
+ {$(INCLUDE)}"\ace\Malloc.i"\
+ {$(INCLUDE)}"\ace\Malloc_T.h"\
+ {$(INCLUDE)}"\ace\Memory_Pool.h"\
+ {$(INCLUDE)}"\ace\Malloc_T.i"\
+ {$(INCLUDE)}"\ace\Malloc_T.cpp"\
+ {$(INCLUDE)}"\ace\Signal.h"\
+ {$(INCLUDE)}"\ace\Mem_Map.h"\
+ {$(INCLUDE)}"\ace\Memory_Pool.i"\
+ {$(INCLUDE)}"\ace\Signal.i"\
+ {$(INCLUDE)}"\ace\Mem_Map.i"\
+ {$(INCLUDE)}"\ace\Timer_Queue.i"\
+ {$(INCLUDE)}"\ace\Token.h"\
+ {$(INCLUDE)}"\ace\Local_Tokens.h"\
+ {$(INCLUDE)}"\ace\ReactorEx.i"\
+ {$(INCLUDE)}"\ace\Token.i"\
+ {$(INCLUDE)}"\ace\Stack.h"\
+ {$(INCLUDE)}"\ace\Synch_Options.h"\
+ {$(INCLUDE)}"\ace\Map_Manager.h"\
+ {$(INCLUDE)}"\ace\Local_Tokens.i"\
+ {$(INCLUDE)}"\ace\Stack.i"\
+ {$(INCLUDE)}"\ace\Stack.cpp"\
+ {$(INCLUDE)}"\ace\Map_Manager.i"\
+ {$(INCLUDE)}"\ace\Map_Manager.cpp"\
+ {$(INCLUDE)}"\ace\Handle_Set.h"\
+ {$(INCLUDE)}"\ace\Pipe.h"\
+ {$(INCLUDE)}"\ace\SOCK_Stream.h"\
+ {$(INCLUDE)}"\ace\Reactor.i"\
+ {$(INCLUDE)}"\ace\Handle_Set.i"\
+ {$(INCLUDE)}"\ace\Pipe.i"\
+ {$(INCLUDE)}"\ace\SOCK_IO.h"\
+ {$(INCLUDE)}"\ace\INET_Addr.h"\
+ {$(INCLUDE)}"\ace\SOCK_Stream.i"\
+ {$(INCLUDE)}"\ace\SOCK.h"\
+ {$(INCLUDE)}"\ace\SOCK_IO.i"\
+ {$(INCLUDE)}"\ace\Addr.h"\
+ {$(INCLUDE)}"\ace\IPC_SAP.h"\
+ {$(INCLUDE)}"\ace\SOCK.i"\
+ {$(INCLUDE)}"\ace\Addr.i"\
+ {$(INCLUDE)}"\ace\IPC_SAP.i"\
+ {$(INCLUDE)}"\ace\INET_Addr.i"\
+
+NODEP_CPP_MAIN_=\
+ ".\TS_Clerk_Handler.h"\
+ ".\TS_Server_Handler.h"\
+ ".\Client_Logging_Handler.h"\
+ ".\Name_Handler.h"\
+ ".\Token_Handler.h"\
+ ".\Server_Logging_Handler.h"\
+ ".\Logger.h"\
+ ".\..\..\ace\ace\Sync_T.h"\
+
+
+"$(INTDIR)\main.obj" : $(SOURCE) $(DEP_CPP_MAIN_) "$(INTDIR)"
+
+
+!ELSEIF "$(CFG)" == "servers - Win32 Debug"
+
+DEP_CPP_MAIN_=\
+ {$(INCLUDE)}"\ace\Service_Config.h"\
+ ".\..\lib\TS_Clerk_Handler.h"\
+ ".\..\lib\TS_Server_Handler.h"\
+ ".\..\lib\Client_Logging_Handler.h"\
+ ".\..\lib\Name_Handler.h"\
+ ".\..\lib\Token_Handler.h"\
+ ".\..\lib\Server_Logging_Handler.h"\
+ ".\..\lib\Logger.h"\
+ {$(INCLUDE)}"\ace\Service_Object.h"\
+ {$(INCLUDE)}"\ace\Thread_Manager.h"\
+ {$(INCLUDE)}"\ace\Set.h"\
+ {$(INCLUDE)}"\ace\Proactor.h"\
+ {$(INCLUDE)}"\ace\ReactorEx.h"\
+ {$(INCLUDE)}"\ace\Service_Config.i"\
+ {$(INCLUDE)}"\ace\Reactor.h"\
+ {$(INCLUDE)}"\ace\Svc_Conf_Tokens.h"\
+ {$(INCLUDE)}"\ace\Shared_Object.h"\
+ {$(INCLUDE)}"\ace\Event_Handler.h"\
+ {$(INCLUDE)}"\ace\Log_Msg.h"\
+ {$(INCLUDE)}"\ace\Service_Object.i"\
+ {$(INCLUDE)}"\ace\ACE.h"\
+ {$(INCLUDE)}"\ace\Shared_Object.i"\
+ {$(INCLUDE)}"\ace\OS.h"\
+ {$(INCLUDE)}"\ace\ACE.i"\
+ {$(INCLUDE)}"\ace\Time_Value.h"\
+ {$(INCLUDE)}"\sys\TYPES.H"\
+ {$(INCLUDE)}"\sys\STAT.H"\
+ {$(INCLUDE)}"\sys\TIMEB.H"\
+ {$(INCLUDE)}"\ace\msg_hack.h"\
+ {$(INCLUDE)}"\ace\Trace.h"\
+ {$(INCLUDE)}"\ace\OS.i"\
+ {$(INCLUDE)}"\ace\config.h"\
+ {$(INCLUDE)}"\ace\Time_Value.i"\
+ {$(INCLUDE)}"\ace\Event_Handler.i"\
+ {$(INCLUDE)}"\ace\Log_Record.h"\
+ {$(INCLUDE)}"\ace\Log_Priority.h"\
+ {$(INCLUDE)}"\ace\Log_Record.i"\
+ {$(INCLUDE)}"\ace\Thread.h"\
+ {$(INCLUDE)}"\ace\Synch.h"\
+ {$(INCLUDE)}"\ace\Thread_Manager.i"\
+ {$(INCLUDE)}"\ace\Thread.i"\
+ {$(INCLUDE)}"\ace\SV_Semaphore_Complex.h"\
+ {$(INCLUDE)}"\ace\Synch.i"\
+ {$(INCLUDE)}"\ace\Synch_T.h"\
+ {$(INCLUDE)}"\ace\SV_Semaphore_Simple.h"\
+ {$(INCLUDE)}"\ace\SV_Semaphore_Complex.i"\
+ {$(INCLUDE)}"\ace\SV_Semaphore_Simple.i"\
+ {$(INCLUDE)}"\ace\Synch_T.i"\
+ {$(INCLUDE)}"\ace\Synch_T.cpp"\
+ {$(INCLUDE)}"\ace\Set.i"\
+ {$(INCLUDE)}"\ace\Set.cpp"\
+ {$(INCLUDE)}"\ace\Message_Block.h"\
+ {$(INCLUDE)}"\ace\Timer_Queue.h"\
+ {$(INCLUDE)}"\ace\Proactor.i"\
+ {$(INCLUDE)}"\ace\Malloc.h"\
+ {$(INCLUDE)}"\ace\Message_Block.i"\
+ {$(INCLUDE)}"\ace\Malloc.i"\
+ {$(INCLUDE)}"\ace\Malloc_T.h"\
+ {$(INCLUDE)}"\ace\Memory_Pool.h"\
+ {$(INCLUDE)}"\ace\Malloc_T.i"\
+ {$(INCLUDE)}"\ace\Malloc_T.cpp"\
+ {$(INCLUDE)}"\ace\Signal.h"\
+ {$(INCLUDE)}"\ace\Mem_Map.h"\
+ {$(INCLUDE)}"\ace\Memory_Pool.i"\
+ {$(INCLUDE)}"\ace\Signal.i"\
+ {$(INCLUDE)}"\ace\Mem_Map.i"\
+ {$(INCLUDE)}"\ace\Timer_Queue.i"\
+ {$(INCLUDE)}"\ace\Token.h"\
+ {$(INCLUDE)}"\ace\Local_Tokens.h"\
+ {$(INCLUDE)}"\ace\ReactorEx.i"\
+ {$(INCLUDE)}"\ace\Token.i"\
+ {$(INCLUDE)}"\ace\Stack.h"\
+ {$(INCLUDE)}"\ace\Synch_Options.h"\
+ {$(INCLUDE)}"\ace\Map_Manager.h"\
+ {$(INCLUDE)}"\ace\Local_Tokens.i"\
+ {$(INCLUDE)}"\ace\Stack.i"\
+ {$(INCLUDE)}"\ace\Stack.cpp"\
+ {$(INCLUDE)}"\ace\Map_Manager.i"\
+ {$(INCLUDE)}"\ace\Map_Manager.cpp"\
+ {$(INCLUDE)}"\ace\Handle_Set.h"\
+ {$(INCLUDE)}"\ace\Pipe.h"\
+ {$(INCLUDE)}"\ace\SOCK_Stream.h"\
+ {$(INCLUDE)}"\ace\Reactor.i"\
+ {$(INCLUDE)}"\ace\Handle_Set.i"\
+ {$(INCLUDE)}"\ace\Pipe.i"\
+ {$(INCLUDE)}"\ace\SOCK_IO.h"\
+ {$(INCLUDE)}"\ace\INET_Addr.h"\
+ {$(INCLUDE)}"\ace\SOCK_Stream.i"\
+ {$(INCLUDE)}"\ace\SOCK.h"\
+ {$(INCLUDE)}"\ace\SOCK_IO.i"\
+ {$(INCLUDE)}"\ace\Addr.h"\
+ {$(INCLUDE)}"\ace\IPC_SAP.h"\
+ {$(INCLUDE)}"\ace\SOCK.i"\
+ {$(INCLUDE)}"\ace\Addr.i"\
+ {$(INCLUDE)}"\ace\IPC_SAP.i"\
+ {$(INCLUDE)}"\ace\INET_Addr.i"\
+
+NODEP_CPP_MAIN_=\
+ ".\..\..\ace\ace\Sync_T.h"\
+
+
+"$(INTDIR)\main.obj" : $(SOURCE) $(DEP_CPP_MAIN_) "$(INTDIR)"
+
+
+!ENDIF
+
+# End Source File
+# End Target
+# End Project
+################################################################################
diff --git a/netsvcs/servers/servers.mdp b/netsvcs/servers/servers.mdp Binary files differnew file mode 100644 index 00000000000..5304247a52d --- /dev/null +++ b/netsvcs/servers/servers.mdp diff --git a/netsvcs/servers/svc.conf b/netsvcs/servers/svc.conf new file mode 100644 index 00000000000..8fdb837b6aa --- /dev/null +++ b/netsvcs/servers/svc.conf @@ -0,0 +1,15 @@ +# These are the services that can be linked into ACE. +# Note that you can replace the hardcoded "../lib/libnet_svcs.so" with +# a relative path if you set your LD search path correctly -- ACE will +# locate this for you automatically by reading your LD search path! +# In addition, you can replace the hardcoded "-p 20xxx" with "-p +# $PORTxxx" if you set your environment variables correctly. + +dynamic Logger Service_Object * ../lib/libnet_svcs.so:_make_ACE_Logger() "-s foobar -f STDERR|OSTREAM" +dynamic Time_Service Service_Object * ../lib/libnet_svcs.so:_make_ACE_TS_Server_Acceptor() "-p 10222" +dynamic Name_Server Service_Object * ../lib/libnet_svcs.so:_make_ACE_Name_Acceptor() "-p 10012" +dynamic Token_Service Service_Object * ../lib/libnet_svcs.so:_make_ACE_Token_Acceptor() "-p 10202" +dynamic Server_Logging_Service Service_Object * ../lib/libnet_svcs.so:_make_ACE_Server_Logging_Acceptor() active "-p 10009" +dynamic Thr_Server_Logging_Service Service_Object * ../lib/libnet_svcs.so:_make_ACE_Thr_Server_Logging_Acceptor() active "-p 10020" +dynamic Client_Logging_Service Service_Object * ../lib/libnet_svcs.so:_make_ACE_Client_Logging_Connector() active "-p 10009" + |