ACE_SPIPE_Acceptor Class Reference

A factory class that produces ACE_SPIPE_Stream objects. More...

#include <SPIPE_Acceptor.h>

Inheritance diagram for ACE_SPIPE_Acceptor:

Inheritance graph
[legend]
Collaboration diagram for ACE_SPIPE_Acceptor:

Collaboration graph
[legend]
List of all members.

Public Types

typedef ACE_SPIPE_Addr PEER_ADDR
typedef ACE_SPIPE_Stream PEER_STREAM

Public Member Functions

 ACE_SPIPE_Acceptor (void)
 Default constructor.

 ACE_SPIPE_Acceptor (const ACE_SPIPE_Addr &local_sap, int reuse_addr=1, int perms=ACE_DEFAULT_FILE_PERMS, LPSECURITY_ATTRIBUTES sa=0, int pipe_mode=PIPE_TYPE_MESSAGE|PIPE_READMODE_MESSAGE)
 Initiate a passive-mode STREAM pipe listener.

int open (const ACE_SPIPE_Addr &local_sap, int reuse_addr=1, int perms=ACE_DEFAULT_FILE_PERMS, LPSECURITY_ATTRIBUTES sa=0, int pipe_mode=PIPE_TYPE_MESSAGE|PIPE_READMODE_MESSAGE)
 Initiate a passive-mode STREAM pipe listener.

int close (void)
 Close down the passive-mode STREAM pipe listener.

int remove (void)
 Remove the underlying mounted pipe from the file system.

int accept (ACE_SPIPE_Stream &ipc_sap_spipe, ACE_SPIPE_Addr *remote_addr=0, ACE_Time_Value *timeout=0, int restart=1, int reset_new_handle=0)
void dump (void) const
 Dump the state of an object.


Public Attributes

 ACE_ALLOC_HOOK_DECLARE
 Declare the dynamic allocation hooks.


Private Member Functions

int create_new_instance (int perms=0)
 Create a new instance of an SPIPE.


Detailed Description

A factory class that produces ACE_SPIPE_Stream objects.

ACE_SPIPE_Acceptor is a factory class that accepts SPIPE connections. Each accepted connection produces an ACE_SPIPE_Stream object.

Warning:
Windows: Works only on Windows NT 4 and higher. To use this class with the ACE_Reactor framework, note that the handle to demultiplex on is an event handle and should be registered with the ACE_Reactor::register_handler (ACE_Event_Handler *, ACE_HANDLE) method.

Works on non-Windows platforms only when ACE_HAS_STREAM_PIPES is defined.

Definition at line 48 of file SPIPE_Acceptor.h.


Member Typedef Documentation

typedef ACE_SPIPE_Addr ACE_SPIPE_Acceptor::PEER_ADDR
 

Definition at line 128 of file SPIPE_Acceptor.h.

typedef ACE_SPIPE_Stream ACE_SPIPE_Acceptor::PEER_STREAM
 

Definition at line 129 of file SPIPE_Acceptor.h.


Constructor & Destructor Documentation

ACE_BEGIN_VERSIONED_NAMESPACE_DECL ACE_SPIPE_Acceptor::ACE_SPIPE_Acceptor void   ) 
 

Default constructor.

Definition at line 16 of file SPIPE_Acceptor.cpp.

References ACE_TRACE.

00018   : sa_ (0), pipe_handle_ (ACE_INVALID_HANDLE)
00019 #endif /* ACE_WIN32 */
00020 {
00021   ACE_TRACE ("ACE_SPIPE_Acceptor::ACE_SPIPE_Acceptor");
00022 }

ACE_SPIPE_Acceptor::ACE_SPIPE_Acceptor const ACE_SPIPE_Addr local_sap,
int  reuse_addr = 1,
int  perms = ACE_DEFAULT_FILE_PERMS,
LPSECURITY_ATTRIBUTES  sa = 0,
int  pipe_mode = PIPE_TYPE_MESSAGE|PIPE_READMODE_MESSAGE
 

Initiate a passive-mode STREAM pipe listener.

Parameters:
local_sap The name of the pipe instance to open and listen on.
reuse_addr Optional, and ignored. Needed for API compatibility with other acceptor classes.
perms Optional, the protection mask to create the pipe with. Ignored on Windows.
sa Optional, ignored on non-Windows. The SECURITY_ATTRIBUTES to create the named pipe instances with. This pointer is remembered and reused on each new named pipe instance, so only pass a value that remains valid as long as this object does.
pipe_mode Optional, ignored on non-Windows. The NT pipe mode used when creating the pipe.

Definition at line 231 of file SPIPE_Acceptor.cpp.

References ACE_ERROR, ACE_LIB_TEXT, ACE_TRACE, LM_ERROR, and open().

00236 {
00237   ACE_TRACE ("ACE_SPIPE_Acceptor::ACE_SPIPE_Acceptor");
00238 
00239   if (this->open (local_sap, reuse_addr, perms, sa, pipe_mode) == -1)
00240     ACE_ERROR ((LM_ERROR,
00241                 ACE_LIB_TEXT ("%p\n"),
00242                 ACE_LIB_TEXT ("ACE_SPIPE_Acceptor")));
00243 }


Member Function Documentation

int ACE_SPIPE_Acceptor::accept ACE_SPIPE_Stream ipc_sap_spipe,
ACE_SPIPE_Addr remote_addr = 0,
ACE_Time_Value timeout = 0,
int  restart = 1,
int  reset_new_handle = 0
 

Accept a new data transfer connection.

Parameters:
ipc_sap_spipe The ACE_SPIPE_Stream to initialize with the newly-accepted pipe.
remote_addr Optional, accepts the address of the peer.
timeout 0 means block forever, {0, 0} means poll.
restart 1 means "restart if interrupted."
Return values:
0 for success.
-1 for failure.

Definition at line 248 of file SPIPE_Acceptor.cpp.

References ACE_NOTSUP_RETURN, ACE_TRACE, create_new_instance(), ACE_SPIPE_Addr::group_id(), ACE::handle_timed_accept(), ACE_OS::ioctl(), ACE_SPIPE::local_addr_, ACE_SPIPE_Stream::remote_addr_, ACE_IPC_SAP::set_handle(), ACE_Addr::set_size(), and ACE_SPIPE_Addr::user_id().

Referenced by ACE_UPIPE_Acceptor::accept().

00253 {
00254   ACE_TRACE ("ACE_SPIPE_Acceptor::accept");
00255   ACE_UNUSED_ARG (reset_new_handle);
00256 
00257 #if defined (ACE_HAS_STREAM_PIPES)
00258   strrecvfd r_handle;
00259 
00260   // Note that if THIS->MILLI_SECOND_DELAY == -1 we block on
00261   // ACE_OS::ioctl (). Otherwise, we will wait for the desired number
00262   // of milli seconds using ACE_OS::poll.
00263 
00264   if (timeout != 0 &&
00265       ACE::handle_timed_accept (this->get_handle (),
00266                                 timeout,
00267                                 restart) == -1)
00268     return -1;
00269   else if (ACE_OS::ioctl (this->get_handle (),
00270                           I_RECVFD,
00271                           &r_handle) == -1)
00272     return -1;
00273 
00274   new_io.set_handle (r_handle.fd);
00275   new_io.local_addr_ = this->local_addr_;
00276   new_io.remote_addr_.set_size (sizeof r_handle.gid + sizeof r_handle.uid);
00277   new_io.remote_addr_.group_id (r_handle.gid);
00278   new_io.remote_addr_.user_id (r_handle.uid);
00279 
00280   // This is for compatibility with ACE_SOCK_Acceptor and
00281   // ACE_TLI_Acceptor.
00282   if (remote_addr != 0)
00283     *remote_addr = new_io.remote_addr_;
00284 
00285   return 0;
00286 #elif (defined (ACE_WIN32) && defined (ACE_HAS_WINNT4) && (ACE_HAS_WINNT4 != 0))
00287   ACE_UNUSED_ARG (restart);
00288   ACE_UNUSED_ARG (remote_addr);
00289 
00290   // Check to see if we have a valid pipe
00291   if (this->pipe_handle_ == ACE_INVALID_HANDLE)
00292     return -1;
00293 
00294   // open () started the Connect in asynchronous mode.  Wait for the event
00295   // in the OVERLAPPED structure to be signalled, then grab the status.
00296   if (this->already_connected_ == 0)
00297     {
00298       if (timeout != 0)
00299         {
00300           ACE_Time_Value abstime (ACE_OS::gettimeofday () + *timeout);
00301           if (this->event_.wait (&abstime) == -1)
00302             return -1;
00303         }
00304       else
00305         if (this->event_.wait () == -1)
00306           return -1;
00307 
00308       // Should be here with the ConnectNamedPipe operation complete.
00309       // Steal the already_connected_ flag to record the results.
00310       DWORD unused;
00311       this->already_connected_ = ::GetOverlappedResult (this->pipe_handle_,
00312                                                         &this->overlapped_,
00313                                                         &unused,
00314                                                         FALSE);
00315     }
00316 
00317   if (this->already_connected_)
00318     {
00319       new_io.set_handle (this->pipe_handle_);
00320       this->pipe_handle_ = ACE_INVALID_HANDLE;
00321       new_io.local_addr_ = this->local_addr_;
00322 
00323       // Create a new instance of the pipe for the next connection.
00324       this->create_new_instance ();
00325       return 0;
00326     }
00327   return -1;
00328 #else
00329   ACE_UNUSED_ARG (restart);
00330   ACE_UNUSED_ARG (timeout);
00331   ACE_UNUSED_ARG (remote_addr);
00332   ACE_UNUSED_ARG (new_io);
00333   ACE_NOTSUP_RETURN (-1);
00334 #endif /* ACE_HAS_STREAM_PIPES */
00335 }

int ACE_SPIPE_Acceptor::close void   ) 
 

Close down the passive-mode STREAM pipe listener.

Reimplemented from ACE_SPIPE.

Reimplemented in ACE_UPIPE_Acceptor.

Definition at line 182 of file SPIPE_Acceptor.cpp.

References ACE_TEXT_ALWAYS_CHAR, ACE_TRACE, ACE_SPIPE::close(), ACE_OS::fdetach(), and ACE_IPC_SAP::set_handle().

Referenced by ACE_UPIPE_Acceptor::close(), create_new_instance(), and remove().

00183 {
00184   ACE_TRACE ("ACE_SPIPE_Acceptor::close");
00185 
00186 #if (defined (ACE_WIN32) && defined (ACE_HAS_WINNT4) && (ACE_HAS_WINNT4 != 0))
00187 
00188   // Check to see if we have a valid pipe; if not, nothing to do.
00189   if (this->pipe_handle_ == ACE_INVALID_HANDLE)
00190     return -1;
00191 
00192   // Substitute the pipe handle back in so it's closed properly in the
00193   // ACE_OS wrapper. But leave the pipe_handle_ value so we can clean up the
00194   // hanging overlapped operation afterwards.
00195   this->set_handle (this->pipe_handle_);
00196 
00197 #endif /* ACE_WIN32 */
00198 
00199   // This behavior is shared by UNIX and Win32...
00200   int result = this->ACE_SPIPE::close ();
00201   this->set_handle (ACE_INVALID_HANDLE);
00202 
00203 #if defined (ACE_HAS_STREAM_PIPES)
00204   ACE_OS::fdetach (ACE_TEXT_ALWAYS_CHAR (this->local_addr_.get_path_name ()));
00205 #elif (defined (ACE_WIN32) && defined (ACE_HAS_WINNT4) && (ACE_HAS_WINNT4 != 0))
00206 
00207   // open () started the Connect in asynchronous mode, and accept() restarts
00208   // the ConnectNamedPipe in overlapped mode.  To avoid leaving a hanging
00209   // overlapped operation that'll write into members of this object,
00210   // wait for the event in the OVERLAPPED structure to be signalled.
00211   if (this->already_connected_ == 0)
00212     {
00213       if (this->event_.wait () != -1)
00214         {
00215           // Should be here with the ConnectNamedPipe operation complete.
00216           // Steal the already_connected_ flag to record the results.
00217           DWORD unused;
00218           ::GetOverlappedResult (this->pipe_handle_,
00219                                  &this->overlapped_,
00220                                  &unused,
00221                                  FALSE);
00222         }
00223       this->pipe_handle_ = ACE_INVALID_HANDLE;
00224       this->already_connected_ = 0;
00225     }
00226 #endif /* ACE_HAS_STREAM_PIPES */
00227 
00228   return result;
00229 }

int ACE_SPIPE_Acceptor::create_new_instance int  perms = 0  )  [private]
 

Create a new instance of an SPIPE.

Definition at line 76 of file SPIPE_Acceptor.cpp.

References ACE_ASSERT, ACE_DEFAULT_TIMEOUT, ACE_NOTSUP_RETURN, ACE_TEXT_ALWAYS_CHAR, ACE_TRACE, close(), ACE_OS::close(), ACE_OS::creat(), ACE_IPC_SAP::get_handle(), ACE_SPIPE_Addr::get_path_name(), ACE_OS::ioctl(), ACE_OS::pipe(), and ACE_IPC_SAP::set_handle().

Referenced by accept(), and open().

00077 {
00078 #if defined (ACE_HAS_STREAM_PIPES)
00079   ACE_HANDLE spipe[2];
00080   char module[] = "connld";
00081 
00082   ACE_HANDLE handle = ACE_OS::creat (this->local_addr_.get_path_name (),
00083                                      perms);
00084   if (handle == ACE_INVALID_HANDLE)
00085     return -1;
00086   else if (ACE_OS::close (handle) == -1)
00087     return -1;
00088   else if (ACE_OS::pipe (spipe) == -1)
00089     return -1;
00090   else if (ACE_OS::ioctl (spipe[0],
00091                           I_PUSH,
00092                           module) == -1)
00093     return -1;
00094   else if (-1 == ACE_OS::fattach
00095                    (spipe[0],
00096                     ACE_TEXT_ALWAYS_CHAR (this->local_addr_.get_path_name ())))
00097     return -1;
00098 
00099   this->set_duplex_handle (spipe[0]);
00100   this->set_handle (spipe[1]);
00101   return 0;
00102 
00103 #elif (defined (ACE_WIN32) && defined (ACE_HAS_WINNT4) && (ACE_HAS_WINNT4 != 0))
00104   // Create a new instance of the Named Pipe (WIN32).  A new instance
00105   // of the named pipe must be created for every client process.  If
00106   // an instance of the named pipe that is already connected to a
00107   // client process is reused with a new client process,
00108   // ::ConnectNamedPipe () would fail.
00109 
00110   ACE_UNUSED_ARG (perms);
00111   ACE_TRACE ("ACE_SPIPE_Acceptor::create_new_instance");
00112   int status;
00113 
00114   // Create a new instance of the named pipe
00115   this->pipe_handle_ =
00116 #if defined (ACE_USES_WCHAR)
00117     ::CreateNamedPipeW (
00118 #else /* ACE_USES_WCHAR */
00119     ::CreateNamedPipeA (
00120 #endif /* ACE_USES_WCHAR */
00121                         this->local_addr_.get_path_name (),
00122                         PIPE_ACCESS_DUPLEX
00123                         | FILE_FLAG_OVERLAPPED,
00124                         pipe_mode_,
00125                         PIPE_UNLIMITED_INSTANCES,
00126                         1024 * 10,
00127                         1024 * 10,
00128                         ACE_DEFAULT_TIMEOUT,
00129                         this->sa_);
00130 
00131   if (this->pipe_handle_ == ACE_INVALID_HANDLE)
00132     return -1;
00133   else
00134     {
00135       // Start the Connect (analogous to listen () for a socket).
00136       // Completion is noted by the event being signalled.  If a
00137       // client connects before this call, the error status will be
00138       // ERROR_PIPE_CONNECTED.  If the client also disconnects before
00139       // this call, the error status will be ERROR_NO_DATA.  In both
00140       // cases, that fact is remembered via already_connected_ and
00141       // noted when the user calls accept().  Else the error status
00142       // should be ERROR_IO_PENDING and the OS will signal the event
00143       // when it's done.
00144       this->already_connected_ = 0;
00145       this->set_handle (this->event_.handle ());
00146       this->overlapped_.hEvent = this->event_.handle ();
00147       this->event_.reset ();
00148 
00149       BOOL result = ::ConnectNamedPipe (this->pipe_handle_,
00150                                         &this->overlapped_);
00151       ACE_UNUSED_ARG (result);
00152       // ConnectNamePipe is suppose to always
00153       // "fail" when passed in overlapped i/o
00154       ACE_ASSERT (!result);
00155 
00156       status = ::GetLastError ();
00157       switch (status)
00158         {
00159         case ERROR_IO_PENDING:
00160           break;
00161         case ERROR_PIPE_CONNECTED:
00162         case ERROR_NO_DATA:
00163           this->already_connected_ = 1;
00164           // Set the associated event as signaled so any reactors or
00165           // proactors waiting for this will respond.
00166           this->event_.signal ();
00167           break;
00168         default:
00169           ACE_ASSERT (FALSE);    // An undocumented error was returned.
00170           this->close ();        // Sets handle to ACE_INVALID_HANDLE.
00171           break;
00172         }
00173     }
00174   return this->get_handle () == ACE_INVALID_HANDLE ? -1 : 0;
00175 #else
00176   ACE_UNUSED_ARG (perms);
00177   ACE_NOTSUP_RETURN (-1);
00178 #endif /* ACE_HAS_STREAM_PIPES */
00179 }

void ACE_SPIPE_Acceptor::dump void   )  const
 

Dump the state of an object.

Reimplemented from ACE_SPIPE.

Reimplemented in ACE_UPIPE_Acceptor.

Definition at line 43 of file SPIPE_Acceptor.cpp.

References ACE_TRACE.

00044 {
00045 #if defined (ACE_HAS_DUMP)
00046   ACE_TRACE ("ACE_SPIPE_Acceptor::dump");
00047 #endif /* ACE_HAS_DUMP */
00048 }

int ACE_SPIPE_Acceptor::open const ACE_SPIPE_Addr local_sap,
int  reuse_addr = 1,
int  perms = ACE_DEFAULT_FILE_PERMS,
LPSECURITY_ATTRIBUTES  sa = 0,
int  pipe_mode = PIPE_TYPE_MESSAGE|PIPE_READMODE_MESSAGE
 

Initiate a passive-mode STREAM pipe listener.

Parameters:
local_sap The name of the pipe instance to open and listen on.
reuse_addr Optional, and ignored. Needed for API compatibility with other acceptor classes.
perms Optional, the protection mask to create the pipe with. Ignored on Windows.
sa Optional, ignored on non-Windows. The SECURITY_ATTRIBUTES to create the named pipe instances with. This pointer is remembered and reused on each new named pipe instance, so only pass a value that remains valid as long as this object does.
pipe_mode Optional, ignored on non-Windows. The NT pipe mode used when creating the pipe.
Return values:
0 for success.
-1 for failure.

Definition at line 53 of file SPIPE_Acceptor.cpp.

References ACE_TRACE, create_new_instance(), and ACE_IPC_SAP::set_handle().

Referenced by ACE_SPIPE_Acceptor(), and ACE_UPIPE_Acceptor::open().

00058 {
00059   ACE_TRACE ("ACE_SPIPE_Acceptor::open");
00060   ACE_UNUSED_ARG (reuse_addr);
00061 
00062   this->local_addr_ = local_sap;
00063   this->set_handle (ACE_INVALID_HANDLE);
00064 #if (defined (ACE_WIN32) && defined (ACE_HAS_WINNT4) && (ACE_HAS_WINNT4 != 0))
00065   this->sa_ = sa;
00066   this->pipe_mode_ = pipe_mode;
00067 #else
00068   ACE_UNUSED_ARG (sa);
00069   ACE_UNUSED_ARG (pipe_mode);
00070 #endif /* ACE_WIN32 */
00071 
00072   return this->create_new_instance (perms);
00073 }

int ACE_SPIPE_Acceptor::remove void   ) 
 

Remove the underlying mounted pipe from the file system.

Reimplemented from ACE_SPIPE.

Reimplemented in ACE_UPIPE_Acceptor.

Definition at line 25 of file SPIPE_Acceptor.cpp.

References ACE_TRACE, close(), and ACE_OS::unlink().

Referenced by ACE_UPIPE_Acceptor::remove().

00026 {
00027   ACE_TRACE ("ACE_SPIPE_Acceptor::remove");
00028 #if defined (ACE_HAS_STREAM_PIPES)
00029   int result = this->close ();
00030 
00031   // Remove the underlying file.
00032   return ACE_OS::unlink (this->local_addr_.get_path_name ()) == -1
00033     || result == -1 ? -1 : 0;
00034 #else
00035   this->close ();
00036   return 0;
00037 #endif
00038 }


Member Data Documentation

ACE_SPIPE_Acceptor::ACE_ALLOC_HOOK_DECLARE
 

Declare the dynamic allocation hooks.

Reimplemented from ACE_SPIPE.

Reimplemented in ACE_UPIPE_Acceptor.

Definition at line 135 of file SPIPE_Acceptor.h.


The documentation for this class was generated from the following files:
Generated on Thu Nov 9 11:30:03 2006 for ACE by doxygen 1.3.6