summaryrefslogtreecommitdiff
path: root/netsvcs
diff options
context:
space:
mode:
Diffstat (limited to 'netsvcs')
-rw-r--r--netsvcs/ACE-netsvcs.html895
-rw-r--r--netsvcs/Makefile27
-rw-r--r--netsvcs/README20
-rw-r--r--netsvcs/clients/Logger/Makefile77
-rw-r--r--netsvcs/clients/Logger/README18
-rw-r--r--netsvcs/clients/Logger/direct_logging.cpp42
-rw-r--r--netsvcs/clients/Logger/indirect_logging.cpp34
-rw-r--r--netsvcs/clients/Makefile24
-rw-r--r--netsvcs/clients/Naming/Client/Client_Test.cpp561
-rw-r--r--netsvcs/clients/Naming/Client/Client_Test.h9
-rw-r--r--netsvcs/clients/Naming/Client/Makefile175
-rw-r--r--netsvcs/clients/Naming/Client/main.cpp42
-rw-r--r--netsvcs/clients/Naming/Client/svc.conf6
-rw-r--r--netsvcs/clients/Naming/Client/svc2.conf9
-rw-r--r--netsvcs/clients/Naming/Dump_Restore/Dump_Restore.cpp388
-rw-r--r--netsvcs/clients/Naming/Dump_Restore/Dump_Restore.h74
-rw-r--r--netsvcs/clients/Naming/Dump_Restore/Makefile176
-rw-r--r--netsvcs/clients/Naming/Dump_Restore/README67
-rw-r--r--netsvcs/clients/Naming/Dump_Restore/createfile.cpp32
-rw-r--r--netsvcs/clients/Naming/Dump_Restore/main.cpp22
-rw-r--r--netsvcs/clients/Naming/Dump_Restore/nametest.cpp112
-rw-r--r--netsvcs/clients/Naming/Dump_Restore/nametest.h15
-rw-r--r--netsvcs/clients/Naming/Makefile25
-rw-r--r--netsvcs/clients/Naming/README124
-rw-r--r--netsvcs/clients/README8
-rw-r--r--netsvcs/clients/Tokens/Makefile26
-rw-r--r--netsvcs/clients/Tokens/README34
-rw-r--r--netsvcs/clients/Tokens/collection/Makefile108
-rw-r--r--netsvcs/clients/Tokens/collection/README25
-rw-r--r--netsvcs/clients/Tokens/collection/collection.cpp217
-rw-r--r--netsvcs/clients/Tokens/collection/rw_locks.cpp175
-rw-r--r--netsvcs/clients/Tokens/deadlock/Makefile87
-rw-r--r--netsvcs/clients/Tokens/deadlock/README98
-rw-r--r--netsvcs/clients/Tokens/deadlock/deadlock_detection_test.cpp342
-rw-r--r--netsvcs/clients/Tokens/invariant/Makefile72
-rw-r--r--netsvcs/clients/Tokens/invariant/README27
-rw-r--r--netsvcs/clients/Tokens/invariant/invariant.cpp199
-rw-r--r--netsvcs/clients/Tokens/manual/Makefile109
-rw-r--r--netsvcs/clients/Tokens/manual/README67
-rw-r--r--netsvcs/clients/Tokens/manual/manual.cpp347
-rw-r--r--netsvcs/clients/Tokens/mutex/Makefile85
-rw-r--r--netsvcs/clients/Tokens/mutex/README23
-rw-r--r--netsvcs/clients/Tokens/mutex/test_mutex.cpp144
-rw-r--r--netsvcs/clients/Tokens/rw_lock/Makefile86
-rw-r--r--netsvcs/clients/Tokens/rw_lock/README40
-rw-r--r--netsvcs/clients/Tokens/rw_lock/rw_locks.cpp255
-rw-r--r--netsvcs/lib/Client_Logging_Handler.cpp373
-rw-r--r--netsvcs/lib/Client_Logging_Handler.h25
-rw-r--r--netsvcs/lib/Client_Logging_Handler.i4
-rw-r--r--netsvcs/lib/Logging_Strategy.cpp145
-rw-r--r--netsvcs/lib/Logging_Strategy.h25
-rw-r--r--netsvcs/lib/Makefile465
-rw-r--r--netsvcs/lib/Name_Handler.cpp738
-rw-r--r--netsvcs/lib/Name_Handler.h24
-rw-r--r--netsvcs/lib/README270
-rw-r--r--netsvcs/lib/Server_Logging_Handler.cpp453
-rw-r--r--netsvcs/lib/Server_Logging_Handler.h26
-rw-r--r--netsvcs/lib/Server_Logging_Handler.i4
-rw-r--r--netsvcs/lib/TS_Clerk_Handler.cpp826
-rw-r--r--netsvcs/lib/TS_Clerk_Handler.h23
-rw-r--r--netsvcs/lib/TS_Server_Handler.cpp324
-rw-r--r--netsvcs/lib/TS_Server_Handler.h25
-rw-r--r--netsvcs/lib/Token_Handler.cpp882
-rw-r--r--netsvcs/lib/Token_Handler.h26
-rw-r--r--netsvcs/lib/netsvcs.mak1082
-rw-r--r--netsvcs/lib/netsvcs.mdpbin0 -> 47104 bytes
-rw-r--r--netsvcs/servers/Makefile51
-rw-r--r--netsvcs/servers/README29
-rw-r--r--netsvcs/servers/cli.conf11
-rw-r--r--netsvcs/servers/main.cpp77
-rw-r--r--netsvcs/servers/ntsvc.conf12
-rw-r--r--netsvcs/servers/servers.mak402
-rw-r--r--netsvcs/servers/servers.mdpbin0 -> 41984 bytes
-rw-r--r--netsvcs/servers/svc.conf15
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 &ltnaming context&gt <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 &lthostname&gt
+</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 &ltnameserver port&gt <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 &ltnamespace dir&gt <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 &ltprocess name&gt <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 &ltdatabase name&gt <BR>
+</TD>
+<TD VALIGN = TOP ALIGN = LEFT>
+Name of the database. NameBindings for the appropriate naming context
+are stored in file &ltnamespace_dir&gt/&ltdatabase name&gt.
+</TD>
+<TD VALIGN = TOP ALIGN = LEFT>
+<I> null </I>
+</TD>
+<TR>
+<TD VALIGN = TOP ALIGN = LEFT>
+-d &ltdebug&gt
+</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 &lttrace&gt
+</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 &ltverbose&gt
+</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 &ltport number&gt
+
+<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 &ltserver host1&gt:&ltserver port1&gt -h &ltserver host2&gt:&ltserver port2&gt ...
+<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&gt <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 &ltport number&gt
+</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 &ltrendezvous key&gt
+</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 &ltflag1&gt|&ltflag2&gt|&ltflag3&gt (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
new file mode 100644
index 00000000000..84178cff993
--- /dev/null
+++ b/netsvcs/lib/netsvcs.mdp
Binary files differ
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
new file mode 100644
index 00000000000..5304247a52d
--- /dev/null
+++ b/netsvcs/servers/servers.mdp
Binary files differ
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"
+