summaryrefslogtreecommitdiff
path: root/ACE/examples/Connection/blocking
diff options
context:
space:
mode:
Diffstat (limited to 'ACE/examples/Connection/blocking')
-rw-r--r--ACE/examples/Connection/blocking/Connection_Blocking.mpc21
-rw-r--r--ACE/examples/Connection/blocking/Makefile.am62
-rw-r--r--ACE/examples/Connection/blocking/README36
-rw-r--r--ACE/examples/Connection/blocking/SPIPE-acceptor.cpp224
-rw-r--r--ACE/examples/Connection/blocking/SPIPE-acceptor.h79
-rw-r--r--ACE/examples/Connection/blocking/SPIPE-connector.cpp218
-rw-r--r--ACE/examples/Connection/blocking/SPIPE-connector.h82
-rw-r--r--ACE/examples/Connection/blocking/test_spipe_acceptor.cpp36
-rw-r--r--ACE/examples/Connection/blocking/test_spipe_connector.cpp21
9 files changed, 779 insertions, 0 deletions
diff --git a/ACE/examples/Connection/blocking/Connection_Blocking.mpc b/ACE/examples/Connection/blocking/Connection_Blocking.mpc
new file mode 100644
index 00000000000..758e2bfbf95
--- /dev/null
+++ b/ACE/examples/Connection/blocking/Connection_Blocking.mpc
@@ -0,0 +1,21 @@
+// -*- MPC -*-
+// $Id$
+
+project(*acceptor) : aceexe {
+ avoids += ace_for_tao
+ exename = acceptor
+ Source_Files {
+ SPIPE-acceptor.cpp
+ test_spipe_acceptor.cpp
+ }
+}
+
+project(*connector) : aceexe {
+ avoids += ace_for_tao
+ exename = connector
+ Source_Files {
+ SPIPE-connector.cpp
+ test_spipe_connector.cpp
+ }
+}
+
diff --git a/ACE/examples/Connection/blocking/Makefile.am b/ACE/examples/Connection/blocking/Makefile.am
new file mode 100644
index 00000000000..60957cddcb2
--- /dev/null
+++ b/ACE/examples/Connection/blocking/Makefile.am
@@ -0,0 +1,62 @@
+## Process this file with automake to create Makefile.in
+##
+## $Id$
+##
+## This file was generated by MPC. Any changes made directly to
+## this file will be lost the next time it is generated.
+##
+## MPC Command:
+## ./bin/mwc.pl -type automake -noreldefs ACE.mwc
+
+ACE_BUILDDIR = $(top_builddir)
+ACE_ROOT = $(top_srcdir)
+
+noinst_PROGRAMS =
+
+## Makefile.Connection_Blocking_Acceptor.am
+
+if !BUILD_ACE_FOR_TAO
+
+noinst_PROGRAMS += acceptor
+
+acceptor_CPPFLAGS = \
+ -I$(ACE_ROOT) \
+ -I$(ACE_BUILDDIR)
+
+acceptor_SOURCES = \
+ SPIPE-acceptor.cpp \
+ test_spipe_acceptor.cpp \
+ SPIPE-acceptor.h
+
+acceptor_LDADD = \
+ $(ACE_BUILDDIR)/ace/libACE.la
+
+endif !BUILD_ACE_FOR_TAO
+
+## Makefile.Connection_Blocking_Connector.am
+
+if !BUILD_ACE_FOR_TAO
+
+noinst_PROGRAMS += connector
+
+connector_CPPFLAGS = \
+ -I$(ACE_ROOT) \
+ -I$(ACE_BUILDDIR)
+
+connector_SOURCES = \
+ SPIPE-connector.cpp \
+ test_spipe_connector.cpp \
+ SPIPE-connector.h
+
+connector_LDADD = \
+ $(ACE_BUILDDIR)/ace/libACE.la
+
+endif !BUILD_ACE_FOR_TAO
+
+## Clean up template repositories, etc.
+clean-local:
+ -rm -f *~ *.bak *.rpo *.sym lib*.*_pure_* core core.*
+ -rm -f gcctemp.c gcctemp so_locations *.ics
+ -rm -rf cxx_repository ptrepository ti_files
+ -rm -rf templateregistry ir.out
+ -rm -rf ptrepository SunWS_cache Templates.DB
diff --git a/ACE/examples/Connection/blocking/README b/ACE/examples/Connection/blocking/README
new file mode 100644
index 00000000000..c7763e3ed04
--- /dev/null
+++ b/ACE/examples/Connection/blocking/README
@@ -0,0 +1,36 @@
+Presently, this directory contains only one example application for
+SPIPEs. The test source code is contained in SPIPE-acceptor.h and
+SPIPE-connector.h.
+
+The SPIPE-acceptor example illustrates how named pipes are used on NT.
+Once the server establishes a connection to a single client, it spawns
+a thread pool to handle incoming requests via the proactor event loop.
+That is, a separate thread from the pool is used to process each
+message sent by a client. The size of the thread pool can be
+specified by command-line arguments. This example leverages the
+queueing performed by the NT kernel to trivially implement a thread
+pool architecture.
+
+test_spipe_acceptor has the following command-line arguments:
+
+test_spipe_acceptor -t <threads>
+
+<threads> specifies the size of the thread-pool running in the
+proactor event loop.
+
+Here's how to run the tests:
+
+% test_spipe_acceptor -t 1000000
+starting up daemon test_sock_acceptor
+Opening acepipe
+hello
+
+% test_spipe_connector
+starting up daemon test_sock_connector
+Opening acepipe
+activating 5
+
+please enter input..: hello
+
+There are a number of other options that you can provide. Please see
+the source code for details.
diff --git a/ACE/examples/Connection/blocking/SPIPE-acceptor.cpp b/ACE/examples/Connection/blocking/SPIPE-acceptor.cpp
new file mode 100644
index 00000000000..10b1e8310f2
--- /dev/null
+++ b/ACE/examples/Connection/blocking/SPIPE-acceptor.cpp
@@ -0,0 +1,224 @@
+// $Id$
+
+#if !defined (SPIPE_ACCEPTOR_C)
+#define SPIPE_ACCEPTOR_C
+
+#include "ace/OS_NS_string.h"
+#include "ace/SPIPE_Addr.h"
+#include "ace/SPIPE_Acceptor.h"
+#include "ace/Proactor.h"
+#include "ace/Get_Opt.h"
+#include "ace/Signal.h"
+#include "SPIPE-acceptor.h"
+
+ACE_RCSID(blocking, SPIPE_acceptor, "$Id$")
+
+#if defined (ACE_HAS_WIN32_OVERLAPPED_IO) || defined (ACE_HAS_AIO_CALLS)
+
+Svc_Handler::Svc_Handler (void)
+ : mb_ (BUFSIZ + 1)
+{
+ // An extra byte for null termination.
+ this->mb_.size (BUFSIZ);
+}
+
+Svc_Handler::~Svc_Handler (void)
+{
+}
+
+int
+Svc_Handler::open (void *)
+{
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("client connected on handle %d\n"),
+ this->peer ().get_handle ()));
+ if (this->ar_.open (*this,
+ this->peer ().get_handle ()) == -1)
+ return -1;
+ return this->ar_.read (this->mb_,
+ this->mb_.size ());
+}
+
+void
+Svc_Handler::handle_read_stream (const ACE_Asynch_Read_Stream::Result &result)
+{
+ if (result.success () && result.bytes_transferred () > 0)
+ {
+ result.message_block ().rd_ptr ()[result.message_block ().length ()] = '\0';
+
+ // Print out the message received from the server.
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("(%t) message size %d.\n"),
+ result.message_block ().length ()));
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("%C"),
+ result.message_block ().rd_ptr ()));
+ // Reset the message block here to make sure multiple writes to
+ // the pipe don't keep appending to the message_block!
+ this->mb_.reset ();
+
+ this->ar_.read (this->mb_, this->mb_.size ());
+ }
+ else
+ ACE_Proactor::end_event_loop ();
+}
+
+IPC_Server::IPC_Server (void)
+ : n_threads_ (1),
+ shutdown_ (0)
+{
+ ACE_OS::strcpy (rendezvous_, ACE_TEXT ("acepipe"));
+}
+
+IPC_Server::~IPC_Server (void)
+{
+}
+
+int
+IPC_Server::handle_signal (int,
+ siginfo_t *,
+ ucontext_t *)
+{
+ ACE_LOG_MSG->log (LM_INFO, ACE_TEXT ("IPC_Server::handle_signal().\n"));
+
+ // Flag the main <svc> loop to shutdown.
+ this->shutdown_ = 1;
+
+ this->acceptor ().close (); // Close underlying acceptor.
+ // This should cause the <accept> to fail, which will "bounce"
+ // us out of the loop in <svc>.
+ return 0;
+}
+
+int
+IPC_Server::init (int argc, ACE_TCHAR *argv[])
+{
+ if (this->parse_args (argc, argv) == -1)
+ return -1;
+
+ ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("Opening %s\n"), rendezvous_));
+
+ // Initialize named pipe listener.
+ if (this->open (ACE_SPIPE_Addr (rendezvous_)) == -1)
+ ACE_ERROR_RETURN ((LM_ERROR,
+ ACE_TEXT ("%p\n"),
+ ACE_TEXT ("open")), 1);
+
+ // Register to receive shutdowns using this handler.
+ else if (ACE_Reactor::instance ()->register_handler
+ (SIGINT, this) == -1)
+ return -1;
+ else
+ return 0;
+}
+
+int
+IPC_Server::fini (void)
+{
+ return 0;
+}
+
+int
+IPC_Server::parse_args (int argc, ACE_TCHAR *argv[])
+{
+ ACE_LOG_MSG->open (argv[0]);
+
+ ACE_Get_Opt get_opt (argc, argv, ACE_TEXT ("ut:r:"));
+
+ for (int c; (c = get_opt ()) != -1; )
+ {
+ switch (c)
+ {
+ case 'r':
+ ACE_OS::strncpy (rendezvous_,
+ get_opt.opt_arg (),
+ sizeof (rendezvous_) / sizeof (ACE_TCHAR));
+ break;
+ case 't':
+ n_threads_ = ACE_OS::atoi (get_opt.opt_arg ());
+ ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("%s == %d.\n"),
+ get_opt.opt_arg (),
+ n_threads_));
+ ACE_Proactor::instance (2 * n_threads_);
+ // This is a lame way to tell the proactor how many threads
+ // we'll be using.
+ break;
+ case 'u':
+ default:
+ ACE_ERROR_RETURN ((LM_ERROR,
+ ACE_TEXT ("usage: %n -t <threads>\n")
+ ACE_TEXT (" -r <rendezvous>\n")), -1);
+ }
+ }
+
+ return 0;
+}
+
+static ACE_THR_FUNC_RETURN
+run_reactor_event_loop (void *)
+{
+ ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("(%t) worker thread starting\n")));
+
+ ACE_Proactor::run_event_loop ();
+ return 0;
+}
+
+int
+IPC_Server::svc (void)
+{
+ // Performs the iterative server activities.
+ while (this->shutdown_ == 0)
+ {
+ Svc_Handler sh;
+
+ // Create a new SH endpoint, which performs all processing in
+ // its open() method (note no automatic restart if errno ==
+ // EINTR).
+ if (this->accept (&sh, 0) == -1)
+ ACE_ERROR_RETURN ((LM_ERROR,
+ ACE_TEXT ("%p\n"),
+ ACE_TEXT ("accept")),
+ 1);
+
+ // SH's destructor closes the stream implicitly but the
+ // listening endpoint stays open.
+ else
+ {
+ // Run single-threaded.
+ if (n_threads_ <= 1)
+ run_reactor_event_loop (0);
+ else
+ {
+ if (ACE_Thread_Manager::instance ()->spawn_n
+ (n_threads_,
+ run_reactor_event_loop,
+ 0,
+ THR_NEW_LWP) == -1)
+ ACE_ERROR_RETURN ((LM_ERROR,
+ ACE_TEXT ("%p\n"),
+ ACE_TEXT ("spawn_n")),
+ 1);
+
+ ACE_Thread_Manager::instance ()->wait ();
+ }
+
+ ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("(%t) main thread exiting.\n")));
+
+ // Reset the Proactor so another accept will work.
+ ACE_Proactor::reset_event_loop();
+
+ // Must use some other method now to terminate this thing
+ // instead of the ACE_Signal_Adapter just running
+ // ACE_Proactor::end_event_loop()... Since this is an
+ // ACE_Event_Handler, doesn't it seem possible to implement
+ // a handle_signal() hook, and catch the signal there?
+ }
+ }
+
+ /* NOTREACHED */
+ return 0;
+}
+
+#endif /* ACE_HAS_WIN32_OVERLAPPED_IO || ACE_HAS_AIO_CALLS */
+#endif /* SPIPE_ACCEPTOR_C */
+
diff --git a/ACE/examples/Connection/blocking/SPIPE-acceptor.h b/ACE/examples/Connection/blocking/SPIPE-acceptor.h
new file mode 100644
index 00000000000..af4d3d52aae
--- /dev/null
+++ b/ACE/examples/Connection/blocking/SPIPE-acceptor.h
@@ -0,0 +1,79 @@
+/* -*- C++ -*- */
+// $Id$
+
+#ifndef SP_ACCEPTOR_H
+#define SP_ACCEPTOR_H
+
+#include "ace/Svc_Handler.h"
+#include "ace/Service_Config.h"
+
+#if !defined (ACE_LACKS_PRAGMA_ONCE)
+# pragma once
+#endif /* ACE_LACKS_PRAGMA_ONCE */
+
+#include "ace/Acceptor.h"
+#include "ace/SPIPE_Stream.h"
+#include "ace/SPIPE_Acceptor.h"
+#include "ace/Asynch_IO.h"
+
+// This only works on Win32 platforms and on Unix platforms
+// supporting POSIX aio calls.
+#if defined (ACE_HAS_WIN32_OVERLAPPED_IO) || defined (ACE_HAS_AIO_CALLS)
+
+// This is the class that does the work once the ACE_Oneshot_Acceptor
+// has accepted a connection.
+
+class Svc_Handler : public ACE_Svc_Handler <ACE_SPIPE_STREAM, ACE_NULL_SYNCH>, public ACE_Handler
+{
+public:
+ Svc_Handler (void);
+ ~Svc_Handler (void);
+
+ virtual int open (void *);
+
+ virtual void handle_read_stream (const ACE_Asynch_Read_Stream::Result &result);
+ // This is called when asynchronous read from the socket complete
+ // Handle data from the client.
+
+private:
+ ACE_Asynch_Read_Stream ar_;
+ ACE_Message_Block mb_;
+};
+
+class IPC_Server : public ACE_Oneshot_Acceptor<Svc_Handler, ACE_SPIPE_ACCEPTOR>
+{
+public:
+ IPC_Server (void);
+ ~IPC_Server (void);
+
+ // = Dynamic linking hooks.
+ virtual int init (int argc, ACE_TCHAR *argv[]);
+ // Initialize the network server.
+
+ virtual int fini (void);
+ // Close down the server.
+
+ virtual int svc (void);
+ // Run the interative service.
+
+private:
+ int parse_args (int argc, ACE_TCHAR *argv[]);
+ // Parse command-line arguments.
+
+ int n_threads_;
+ // Size of thread pool to use.
+
+ ACE_TCHAR rendezvous_[MAXPATHLEN + 1];
+ // Meeting place for pipe.
+
+ int shutdown_;
+ // Keeps track of when we shut down due to receipt of the SIGINT
+ // signal.
+
+ int handle_signal (int signum, siginfo_t *, ucontext_t *);
+ // Signal handler method.
+};
+
+#endif /* ACE_HAS_WIN32_OVERLAPPED_IO || ACE_HAS_AIO_CALLS */
+#endif /* SP_ACCEPTOR_H */
+
diff --git a/ACE/examples/Connection/blocking/SPIPE-connector.cpp b/ACE/examples/Connection/blocking/SPIPE-connector.cpp
new file mode 100644
index 00000000000..7ffbffb408e
--- /dev/null
+++ b/ACE/examples/Connection/blocking/SPIPE-connector.cpp
@@ -0,0 +1,218 @@
+// $Id$
+
+#if !defined (SPIPE_CONNECTOR_C)
+
+#define SPIPE_CONNECTOR_C
+
+#include "ace/OS_NS_string.h"
+#include "ace/SPIPE_Addr.h"
+#include "ace/SPIPE_Connector.h"
+#include "ace/Proactor.h"
+#include "ace/Get_Opt.h"
+#include "ace/OS_NS_unistd.h"
+#include "SPIPE-connector.h"
+
+ACE_RCSID(blocking, SPIPE_connector, "$Id$")
+
+Peer_Handler::Peer_Handler (int iterations)
+ : iterations_ (iterations)
+{
+}
+
+Peer_Handler::~Peer_Handler (void)
+{
+}
+
+int
+Peer_Handler::open (void *)
+{
+ ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("activating %d\n"), this->get_handle ()));
+
+ // If iterations_ has not been set, read from stdin.
+ if (iterations_ == 0)
+ {
+ this->display_menu ();
+ if (ACE_Event_Handler::register_stdin_handler
+ (this,
+ ACE_Reactor::instance (),
+ ACE_Thread_Manager::instance ()) == -1)
+ ACE_ERROR_RETURN ((LM_ERROR,
+ ACE_TEXT ("%p\n"),
+ ACE_TEXT ("register_stdin_handler")),
+ -1);
+ else
+ return 0;
+ }
+ else // If iterations_ has been set, send iterations_ buffers.
+ {
+ const char *buffer =
+ "Oh give me a home\n"
+ "Where the buffalo roam,\n"
+ "And the deer and the antelope play.\n"
+ "Where seldom is heard\n"
+ "A discouraging word,\n"
+ "And the skies are not cloudy all day.\n";
+ int length = ACE_OS::strlen (buffer);
+
+ while (iterations_-- > 0
+ && this->peer ().send_n (buffer,
+ length) == length)
+ continue;
+
+ this->peer ().close ();
+ ACE_Reactor::instance ()->end_reactor_event_loop();
+ return 0;
+ }
+}
+
+int
+Peer_Handler::handle_input (ACE_HANDLE)
+{
+ char buf[BUFSIZ];
+
+ ssize_t n = ACE_OS::read (ACE_STDIN,
+ buf,
+ sizeof buf);
+
+ if (n > 0)
+ if (this->peer ().send (buf, n) != n)
+ ACE_ERROR_RETURN ((LM_ERROR,
+ ACE_TEXT ("%p\n"),
+ ACE_TEXT ("write failed")),
+ -1);
+ else if (n == 0) // Explicitly close the connection.
+ {
+ if (this->peer ().close () == -1)
+ ACE_ERROR_RETURN ((LM_ERROR,
+ ACE_TEXT ("%p\n"),
+ ACE_TEXT ("close")),
+ 1);
+ return -1;
+ }
+ else
+ this->display_menu ();
+ return 0;
+}
+
+int
+Peer_Handler::handle_close (ACE_HANDLE,
+ ACE_Reactor_Mask)
+{
+ ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("Shutting down\n")));
+ return 0;
+}
+
+ACE_HANDLE
+Peer_Handler::get_handle (void) const
+{
+ return this->peer ().get_handle ();
+}
+
+void
+Peer_Handler::display_menu (void)
+{
+ ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\nplease enter input..: ")));
+}
+
+IPC_Client::IPC_Client (void)
+ : iterations_ (0),
+ done_handler_ (ACE_Sig_Handler_Ex (ACE_Proactor::end_event_loop))
+{
+ ACE_OS::strcpy (rendezvous_, ACE_TEXT ("acepipe"));
+}
+
+IPC_Client::~IPC_Client (void)
+{
+}
+
+// Dynamic linking hooks.
+
+int
+IPC_Client::init (int argc, ACE_TCHAR *argv[])
+{
+ if (this->parse_args (argc, argv) == -1)
+ return -1;
+ // Handle signals through the ACE_Reactor.
+ else if (ACE_Reactor::instance ()->register_handler
+ (SIGINT,
+ &this->done_handler_) == -1)
+ return -1;
+
+ ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("Opening %s\n"), rendezvous_));
+
+ Peer_Handler *ph;
+
+ ACE_NEW_RETURN (ph,
+ Peer_Handler (iterations_),
+ -1);
+
+ // Connect to the peer, reusing the local addr if necessary.
+ if (this->connect (ph,
+ ACE_SPIPE_Addr (rendezvous_),
+ ACE_Synch_Options::defaults,
+ ACE_sap_any_cast (ACE_SPIPE_Addr &),
+ 0,
+ O_RDWR | FILE_FLAG_OVERLAPPED,
+ 0) == -1)
+ ACE_ERROR_RETURN ((LM_ERROR,
+ ACE_TEXT ("%p\n"),
+ ACE_TEXT ("connect")),
+ -1);
+
+ return 0;
+}
+
+int
+IPC_Client::fini (void)
+{
+ return 0;
+}
+
+int
+IPC_Client::svc (void)
+{
+ ACE_Reactor::instance ()->run_reactor_event_loop ();
+ return 0;
+}
+
+int
+IPC_Client::handle_close (ACE_HANDLE,
+ ACE_Reactor_Mask)
+{
+ return 0;
+}
+
+int
+IPC_Client::parse_args (int argc, ACE_TCHAR *argv[])
+{
+ ACE_LOG_MSG->open (argv[0]);
+
+ ACE_Get_Opt get_opt (argc, argv, ACE_TEXT ("ui:r:"));
+
+ for (int c; (c = get_opt ()) != -1; )
+ {
+ switch (c)
+ {
+ case 'r':
+ ACE_OS::strncpy (rendezvous_,
+ get_opt.opt_arg (),
+ sizeof (rendezvous_) / sizeof (ACE_TCHAR));
+ break;
+ case 'i':
+ iterations_ = ACE_OS::atoi (get_opt.opt_arg ());
+ break;
+ case 'u':
+ default:
+ ACE_ERROR_RETURN ((LM_ERROR,
+ ACE_TEXT ("usage: %n -i <iterations>\n")
+ ACE_TEXT ("-r <rendezvous>\n")),
+ -1);
+ }
+ }
+
+ return 0;
+}
+
+
+#endif /* SPIPE_CONNECTOR */
+
diff --git a/ACE/examples/Connection/blocking/SPIPE-connector.h b/ACE/examples/Connection/blocking/SPIPE-connector.h
new file mode 100644
index 00000000000..66d6ea0d1ed
--- /dev/null
+++ b/ACE/examples/Connection/blocking/SPIPE-connector.h
@@ -0,0 +1,82 @@
+/* -*- C++ -*- */
+// $Id$
+
+#ifndef SP_CONNECTOR_H
+#define SP_CONNECTOR_H
+
+#include "ace/Svc_Handler.h"
+#include "ace/Service_Config.h"
+
+#if !defined (ACE_LACKS_PRAGMA_ONCE)
+# pragma once
+#endif /* ACE_LACKS_PRAGMA_ONCE */
+
+#include "ace/SPIPE_Stream.h"
+#include "ace/Connector.h"
+#include "ace/SPIPE_Connector.h"
+#include "ace/Sig_Adapter.h"
+
+class Peer_Handler : public ACE_Svc_Handler<ACE_SPIPE_STREAM, ACE_NULL_SYNCH>
+{
+public:
+ // = Initialization
+
+ Peer_Handler (int iterations = 0);
+ // <iterations> is the number of buffers to send. If <iterations>
+ // == 0, then read from stdin.
+
+ ~Peer_Handler (void);
+
+ virtual int open (void * = 0);
+ // Activate the handler when connection is established.
+
+ // = Demultiplexing hooks.
+ virtual int handle_input (ACE_HANDLE);
+ virtual int handle_close (ACE_HANDLE handle = ACE_INVALID_HANDLE,
+ ACE_Reactor_Mask mask = ACE_Event_Handler::ALL_EVENTS_MASK);
+
+ virtual ACE_HANDLE get_handle (void) const;
+
+private:
+ void display_menu (void);
+
+ int iterations_;
+ // No. of buffers to send.
+};
+
+class IPC_Client : public ACE_Connector<Peer_Handler, ACE_SPIPE_CONNECTOR>
+{
+public:
+ // Initialization
+ IPC_Client (void);
+ ~IPC_Client (void);
+
+ // = Dynamic linking hooks.
+ virtual int init (int argc, ACE_TCHAR *argv[]);
+ // Initialize the IPC client.
+
+ virtual int fini (void);
+ // Destroy the IPC client.
+
+ virtual int svc (void);
+ // Run the svc.
+
+ virtual int handle_close (ACE_HANDLE, ACE_Reactor_Mask);
+ // Report connection errors.
+
+private:
+ int parse_args (int argc, ACE_TCHAR *argv[]);
+ // Parse command-line arguments.
+
+ int iterations_;
+ // Number of times to send a buffer.
+
+ ACE_TCHAR rendezvous_[MAXPATHLEN + 1];
+ // Meeting place for pipe.
+
+ ACE_Sig_Adapter done_handler_;
+ // Keeps track of when we shut down due to receipt of the SIGINT
+ // signal.
+};
+
+#endif /* SP_CONNECTOR_H */
diff --git a/ACE/examples/Connection/blocking/test_spipe_acceptor.cpp b/ACE/examples/Connection/blocking/test_spipe_acceptor.cpp
new file mode 100644
index 00000000000..023680411c1
--- /dev/null
+++ b/ACE/examples/Connection/blocking/test_spipe_acceptor.cpp
@@ -0,0 +1,36 @@
+// $Id$
+
+// ACE_SPIPE Server.
+
+#include "SPIPE-acceptor.h"
+
+ACE_RCSID(blocking, test_spipe_acceptor, "$Id$")
+
+#if defined (ACE_HAS_WIN32_OVERLAPPED_IO) || defined (ACE_HAS_AIO_CALLS)
+
+int
+ACE_TMAIN (int argc, ACE_TCHAR *argv[])
+{
+ // Perform Service_Config initializations
+ ACE_Service_Config daemon (argv[0]);
+
+ IPC_Server peer_acceptor;
+
+ if (peer_acceptor.init (argc, argv) == -1)
+ ACE_ERROR_RETURN ((LM_ERROR, ACE_TEXT ("%p\n"), ACE_TEXT ("init")), -1);
+
+ return peer_acceptor.svc ();
+}
+
+#else
+
+int
+ACE_TMAIN (int, ACE_TCHAR *[])
+{
+ ACE_DEBUG ((LM_INFO,
+ ACE_TEXT ("Asynchronous IO is unsupported.\n")));
+
+ return 0;
+}
+
+#endif
diff --git a/ACE/examples/Connection/blocking/test_spipe_connector.cpp b/ACE/examples/Connection/blocking/test_spipe_connector.cpp
new file mode 100644
index 00000000000..e10cc023a6f
--- /dev/null
+++ b/ACE/examples/Connection/blocking/test_spipe_connector.cpp
@@ -0,0 +1,21 @@
+// $Id$
+
+// ACE_SPIPE Client.
+
+#include "SPIPE-connector.h"
+
+ACE_RCSID(blocking, test_spipe_connector, "$Id$")
+
+int
+ACE_TMAIN (int argc, ACE_TCHAR *argv[])
+{
+ // Perform Service_Config initializations
+ ACE_Service_Config daemon (argv[0]);
+
+ IPC_Client peer_connector;
+
+ if (peer_connector.init (argc, argv) == -1)
+ ACE_ERROR_RETURN ((LM_ERROR, ACE_TEXT ("%p\n"), ACE_TEXT ("init")), -1);
+
+ return peer_connector.svc ();
+}