summaryrefslogtreecommitdiff
path: root/ace/SPIPE_Acceptor.cpp
diff options
context:
space:
mode:
authorlevine <levine@ae88bc3d-4319-0410-8dbf-d08b4c9d3795>1996-10-21 21:41:34 +0000
committerlevine <levine@ae88bc3d-4319-0410-8dbf-d08b4c9d3795>1996-10-21 21:41:34 +0000
commita5fdebc5f6375078ec1763850a4ca23ec7fe6458 (patch)
treebcf0a25c3d45a209a6e3ac37b233a4812f29c732 /ace/SPIPE_Acceptor.cpp
downloadATCD-a5fdebc5f6375078ec1763850a4ca23ec7fe6458.tar.gz
Initial revision
Diffstat (limited to 'ace/SPIPE_Acceptor.cpp')
-rw-r--r--ace/SPIPE_Acceptor.cpp212
1 files changed, 212 insertions, 0 deletions
diff --git a/ace/SPIPE_Acceptor.cpp b/ace/SPIPE_Acceptor.cpp
new file mode 100644
index 00000000000..c3d7458257d
--- /dev/null
+++ b/ace/SPIPE_Acceptor.cpp
@@ -0,0 +1,212 @@
+// SPIPE_Acceptor.cpp
+// $Id$
+
+#define ACE_BUILD_DLL
+#include "ace/SPIPE_Acceptor.h"
+#include "ace/Log_Msg.h"
+
+ACE_SPIPE_Acceptor::ACE_SPIPE_Acceptor (void)
+{
+ ACE_TRACE ("ACE_SPIPE_Acceptor::ACE_SPIPE_Acceptor");
+}
+
+int
+ACE_SPIPE_Acceptor::remove (void)
+{
+ ACE_TRACE ("ACE_SPIPE_Acceptor::remove");
+ int result = this->close ();
+#if defined (ACE_HAS_STREAM_PIPES)
+ // Remove the underlying file.
+ return ACE_OS::unlink (this->local_addr_.get_path_name ()) == -1
+ || result == -1 ? -1 : 0;
+#else
+ return 0;
+#endif
+}
+
+ACE_ALLOC_HOOK_DEFINE(ACE_SPIPE_Acceptor)
+
+void
+ACE_SPIPE_Acceptor::dump (void) const
+{
+ ACE_TRACE ("ACE_SPIPE_Acceptor::dump");
+}
+
+// General purpose routine for performing server ACE_SPIPE creation.
+
+int
+ACE_SPIPE_Acceptor::open (const ACE_SPIPE_Addr &local_sap,
+ int reuse_addr,
+ int perms)
+{
+ ACE_TRACE ("ACE_SPIPE_Acceptor::open");
+
+ this->local_addr_ = local_sap;
+ this->set_handle (ACE_INVALID_HANDLE);
+
+ return this->create_new_instance (perms);
+}
+
+int
+ACE_SPIPE_Acceptor::create_new_instance (int perms)
+{
+#if defined (ACE_HAS_STREAM_PIPES)
+ ACE_HANDLE handle;
+ ACE_HANDLE spipe[2];
+
+ handle = ACE_OS::creat (this->local_addr_.get_path_name (), perms);
+
+ if (handle == ACE_INVALID_HANDLE)
+ return -1;
+ else if (ACE_OS::close (handle) == -1)
+ return -1;
+ else if (ACE_OS::pipe (spipe) == -1)
+ return -1;
+ else if (ACE_OS::ioctl (spipe[0], I_PUSH, "connld") == -1)
+ return -1;
+ else if (ACE_OS::fattach (spipe[0], this->local_addr_.get_path_name ()) == -1)
+ return -1;
+
+ this->set_handle (spipe[1]);
+ return 0;
+#elif defined (ACE_WIN32)
+ // Create a new instance of the Named Pipe (WIN32). A new instance
+ // of the named pipe must be created for every client process. If an
+ // instance of the named pipe that is already connected to a client
+ // process is reused with a new client process, ::ConnectNamedPipe()
+ // would fail.
+
+ ACE_TRACE ("ACE_SPIPE_Acceptor::create_new_instance");
+
+ // Create a new instance of the named pipe
+ ACE_HANDLE handle = ::CreateNamedPipe (this->local_addr_.get_path_name (),
+ PIPE_ACCESS_DUPLEX |
+ FILE_FLAG_OVERLAPPED,
+ PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE,
+ MAX_PIPE_INSTANCES,
+ 1024*10,
+ 1024*10,
+ ACE_DEFAULT_TIMEOUT,
+ NULL);
+ if (handle == ACE_INVALID_HANDLE)
+ return -1;
+ else
+ this->set_handle (handle);
+ return 0;
+#else
+ ACE_NOTSUP_RETURN (-1);
+#endif /* ACE_HAS_STREAM_PIPES */
+}
+
+int
+ACE_SPIPE_Acceptor::close (void)
+{
+ ACE_TRACE ("ACE_SPIPE_Acceptor::close");
+
+ // This behavior is shared by UNIX and Win32...
+ int result = this->ACE_SPIPE::close ();
+ this->set_handle (ACE_INVALID_HANDLE);
+
+#if defined (ACE_HAS_STREAM_PIPES)
+ ACE_OS::fdetach (this->local_addr_.get_path_name ());
+#endif /* ACE_HAS_STREAM_PIPES */
+ return result;
+}
+
+ACE_INLINE
+ACE_SPIPE_Acceptor::ACE_SPIPE_Acceptor (const ACE_SPIPE_Addr &local_sap,
+ int reuse_addr,
+ int perms)
+{
+ ACE_TRACE ("ACE_SPIPE_Acceptor::ACE_SPIPE_Acceptor");
+
+ if (this->open (local_sap, reuse_addr, perms) == -1)
+ ACE_ERROR ((LM_ERROR, "%p\n", "ACE_SPIPE_Acceptor"));
+}
+
+// General purpose routine for accepting new connections.
+
+int
+ACE_SPIPE_Acceptor::accept (ACE_SPIPE_Stream &new_io,
+ ACE_SPIPE_Addr *remote_addr,
+ ACE_Time_Value *timeout,
+ int restart)
+{
+ ACE_TRACE ("ACE_SPIPE_Acceptor::accept");
+#if defined (ACE_HAS_STREAM_PIPES)
+ strrecvfd r_handle;
+
+ // Note that if THIS->MILLI_SECOND_DELAY == -1 we block on
+ // ACE_OS::ioctl(). Otherwise, we will wait for the desired number
+ // of milli seconds using ACE_OS::poll.
+
+ if (timeout != 0 &&
+ ACE::handle_timed_accept (this->get_handle (), timeout, restart) == -1)
+ return -1;
+ else if (ACE_OS::ioctl (this->get_handle (), I_RECVFD, &r_handle) == -1)
+ return -1;
+
+ new_io.set_handle (r_handle.fd);
+ new_io.local_addr_ = this->local_addr_;
+ new_io.remote_addr_.set_size (sizeof r_handle.gid + sizeof r_handle.uid);
+ new_io.remote_addr_.group_id (r_handle.gid);
+ new_io.remote_addr_.user_id (r_handle.uid);
+
+ // This is for compatibility with ACE_SOCK_Acceptor and
+ // ACE_TLI_Acceptor.
+ if (remote_addr != 0)
+ *remote_addr = new_io.remote_addr_;
+
+ return 0;
+#elif defined (ACE_WIN32)
+ // Check to see if we have a valid pipe
+ if (this->get_handle () == ACE_INVALID_HANDLE)
+ return -1;
+
+ // Accept connection on the current instance of the named pipe Note
+ // that the connection is done synchronously, by specifying a NULL
+ // OVERLAPPED structure pointer.
+
+ int attempts = 0;
+
+ for (;;)
+ {
+ attempts++;
+
+ if (::ConnectNamedPipe (this->get_handle (), NULL) != 0)
+ break;
+
+ DWORD error = ::GetLastError ();
+
+ if (error == ERROR_NO_DATA)
+ {
+ // A client connected and disconnected in the interval
+ // between the creation of the named pipe instance and the
+ // call to ::ConnectNamedPipe (). The named pipe handle
+ // must be disconnected from this fleeting client before it
+ // can be reconnected to new client.
+
+ if (attempts > MAX_ACCEPT_ATTEMPTS)
+ return -1;
+ else if (::DisconnectNamedPipe (this->get_handle ()) != 0)
+ return -1;
+ // Loop and make another connection attempt.
+ }
+ else if (error == ERROR_PIPE_CONNECTED)
+ // A client connected in the interval between the creation of
+ // the named pipe instance and the call to ::ConnectNamedPipe
+ // (). However, the connection is alright.
+ break;
+ else // Unrecoverable connection failure, so let's bail out...
+ return -1;
+ }
+
+ new_io.set_handle (this->get_handle ());
+ new_io.local_addr_ = this->local_addr_;
+
+ // Create a new instance of the pipe for the next connection.
+ return this->create_new_instance ();
+#else
+ ACE_NOTSUP_RETURN (-1);
+#endif /* ACE_HAS_STREAM_PIPES */
+}