/* -*- C++ -*- */ // $Id$ // ============================================================================ // // = LIBRARY // ace // // = FILENAME // Asynch_IO.h // // = DESCRIPTION // This only works on Win32 platforms or on POSIX platforms with // aio_ routines. // // The implementation of and // are only supported if ACE_HAS_WINSOCK2 is // defined or you are on WinNT 4.0 or higher. // // = AUTHOR // Irfan Pyarali (irfan@cs.wustl.edu), // Tim Harrison (harrison@cs.wustl.edu) and // Alexander Babu Arulanthu // // ============================================================================ #if !defined (ACE_ASYNCH_IO_H) #define ACE_ASYNCH_IO_H #include "ace/OS.h" #if (defined (ACE_WIN32) && !defined (ACE_HAS_WINCE)) || \ (defined (ACE_HAS_AIO_CALLS)) #include "ace/Task.h" #include "ace/Reactor.h" // Forward declarations class ACE_Proactor; class ACE_Handler; class ACE_Message_Block; class ACE_INET_Addr; class ACE_Export ACE_Asynch_Result : public ACE_OVERLAPPED { // = TITLE // An abstract class which adds information to the OVERLAPPED // structure to make it more useful. // // = DESCRIPTION // An abstract base class from which you can obtain some basic // information like the number of bytes transferred, the ACT // associated with the asynchronous operation, indication of // success or failure, etc. Subclasses may want to store more // information that is particular to the asynchronous operation // it represents. public: // Proactor is the only class which is allowed to call the // method. friend class ACE_Proactor; u_long bytes_transferred (void) const; // Number of bytes transferred by the operation. const void *act (void) const; // ACT associated with the operation. int success (void) const; // Did the operation succeed? const void *completion_key (void) const; // This returns the ACT associated with the handle when it was // registered with the I/O completion port. This ACT is not the // same as the ACT associated with the asynchronous operation. u_long error (void) const; // Error value if the operation fail. ACE_HANDLE event (void) const; // Event associated with the OVERLAPPED structure u_long offset (void) const; u_long offset_high (void) const; // Offset associated with the OVERLAPPED structure. This really // make sense only when doing file I/O. ACE_Asynch_Result (ACE_Handler &handler, const void* act, ACE_HANDLE event, u_long offset = 0, u_long offset_high = 0); // Constructor. #if defined (ACE_HAS_AIO_CALLS) aiocb* aiocb_ptr (void); // Returns the underlying used to issue the aio // call. #endif /* ACE_HAS_AIO_CALLS */ virtual ~ACE_Asynch_Result (void); // Destructor. protected: virtual void complete (u_long bytes_transferred, int success, const void *completion_key, u_long error = 0) = 0; // This is the key method. Subclasses will override this method to // call the correct callback on the handler. ACE_Handler &handler_; // Handler that will be called back. const void *act_; // ACT for this operation. u_long bytes_transferred_; // Bytes transferred by this operation. int success_; // Success indicator. const void *completion_key_; // ACT associated with handle. u_long error_; // Error if operation failed. #if defined (ACE_HAS_AIO_CALLS) aiocb *aiocb_ptr_; // This is the used to issue the // call. Let us give this to the OS along with the result, so that // on completion we can take this and use it for and // . #endif /* ACE_HAS_AIO_CALLS */ }; class ACE_Export ACE_Asynch_Operation { // = TITLE // This is a base class for all asynch operations. // // = DESCRIPTION // There are some attributes and functionality which is common // to all asychronous operations. This abstract class will // factor out this code. public: int open (ACE_Handler &handler, ACE_HANDLE handle = ACE_INVALID_HANDLE, const void *completion_key = 0, ACE_Proactor *proactor = 0); // Initializes the factory with information which will be used with // each asynchronous call. If ( == ACE_INVALID_HANDLE), // will be called on the to get the // correct handle. int cancel (void); // This cancels all pending accepts operations that were issued by // the calling thread. The function does not cancel asynchronous // operations issued by other threads. // Access methods. ACE_Proactor* proactor (void); // Return the underlying proactor. protected: #if defined (ACE_HAS_AIO_CALLS) int register_aio_with_proactor (aiocb *aiocb_ptr); // This call is for the POSIX implementation. This method is used by // to store some information with the // Proactor after an call is issued, so that the Proactor can // retrive this information to do and . // Passing a '0' ptr returns the status, indicating whether there // are slots available or no. Passing a valid ptr stores the ptr // with the Proactor. #endif /* ACE_HAS_AIO_CALLS */ ACE_Asynch_Operation (void); // A no-op constructor. ACE_Proactor *proactor_; // Proactor that this Asynch IO will be registered with. ACE_Handler *handler_; // Handler that will receive the callback. ACE_HANDLE handle_; // I/O handle used for reading. }; class ACE_Export ACE_Asynch_Read_Stream : public ACE_Asynch_Operation { // = TITLE // This class is a factory for starting off asynchronous reads // on a stream. // // = DESCRIPTION // Once is called, multiple asynchronous s can // started using this class. An ACE_Asynch_Read_Stream::Result // will be passed back to the when the asynchronous // reads completes through the // callback. public: class Result; // Forward declaration of the Result class. ACE_Asynch_Read_Stream (void); // A do nothing constructor. int read (ACE_Message_Block &message_block, u_long bytes_to_read, const void *act = 0); // This starts off an asynchronous read. Upto will // be read and stored in the . protected: int shared_read (Result *result); // This is the method which does the real work and is there so that // the ACE_Asynch_Read_File class can use it too. public: class ACE_Export Result : public ACE_Asynch_Result { // = TITLE // This is that class which will be passed back to the // when the asynchronous read completes. // // = DESCRIPTION // This class has all the information necessary for the // to uniquiely identify the completion of the // asynchronous read. friend class ACE_Asynch_Read_Stream; // The factory has special privileges. public: u_long bytes_to_read (void) const; // The number of bytes which were requested at the start of the // asynchronous read. ACE_Message_Block &message_block (void) const; // Message block which contains the read data. ACE_HANDLE handle (void) const; // I/O handle used for reading. // protected: // // These two should really be protected. But sometimes it // simplifies code to be able to "fake" a result. Use carefully. Result (ACE_Handler &handler, ACE_HANDLE handle, ACE_Message_Block &message_block, u_long bytes_to_read, const void* act, ACE_HANDLE event); // Constructor is protected since creation is limited to // ACE_Asynch_Read_Stream factory. virtual void complete (u_long bytes_transferred, int success, const void *completion_key, u_long error = 0); // ACE_Proactor will call this method when the read completes. protected: u_long bytes_to_read_; // Bytes requested when the asynchronous read was initiated. ACE_Message_Block &message_block_; // Message block for reading the data into. ACE_HANDLE handle_; // I/O handle used for reading. }; }; class ACE_Export ACE_Asynch_Write_Stream : public ACE_Asynch_Operation { // = TITLE // This class is a factory for starting off asynchronous writes // on a stream. // // = DESCRIPTION // Once is called, multiple asynchronous s can // started using this class. A ACE_Asynch_Write_Stream::Result // will be passed back to the when the asynchronous // write completes through the // callback. public: class Result; // Forward declaration of the Result class. ACE_Asynch_Write_Stream (void); // A do nothing constructor. int write (ACE_Message_Block &message_block, u_long bytes_to_write, const void *act = 0); // This starts off an asynchronous write. Upto // will be written from the . protected: int shared_write (Result *result); // This is the method which does the real work and is there so that // the ACE_Asynch_Write_File class can use it too. public: class ACE_Export Result : public ACE_Asynch_Result { // = TITLE // This is that class which will be passed back to the // when the asynchronous write completes. // // = DESCRIPTION // This class has all the information necessary for the // to uniquiely identify the completion of the // asynchronous write. public: friend class ACE_Asynch_Write_Stream; // The factory has special privileges. u_long bytes_to_write (void) const; // The number of bytes which were requested at the start of the // asynchronous write. ACE_Message_Block &message_block (void) const; // Message block that contains the data to be written. ACE_HANDLE handle (void) const; // I/O handle used for writing. // protected: // // These two should really be protected. But sometimes it // simplifies code to be able to "fake" a result. Use carefully. Result (ACE_Handler &handler, ACE_HANDLE handle, ACE_Message_Block &message_block, u_long bytes_to_write, const void* act, ACE_HANDLE event); // Constructor is protected since creation is limited to // ACE_Asynch_Write_Stream factory. virtual void complete (u_long bytes_transferred, int success, const void *completion_key, u_long error = 0); // ACE_Proactor will call this method when the write completes. protected: u_long bytes_to_write_; // The number of bytes which were requested at the start of the // asynchronous write. ACE_Message_Block &message_block_; // Message block that contains the data to be written. ACE_HANDLE handle_; // I/O handle used for writing. }; }; class ACE_Export ACE_Asynch_Read_File : public ACE_Asynch_Read_Stream { // = TITLE // This class is a factory for starting off asynchronous reads // on a file. // // = DESCRIPTION // Once is called, multiple asynchronous s can // started using this class. A ACE_Asynch_Read_File::Result // will be passed back to the when the asynchronous // reads completes through the // callback. // // This class differs slightly from ACE_Asynch_Read_Stream as it // allows the user to specify an offset for the read. public: int read (ACE_Message_Block &message_block, u_long bytes_to_read, u_long offset = 0, u_long offset_high = 0, const void *act = 0); // This starts off an asynchronous read. Upto will // be read and stored in the . The read will start // at from the beginning of the file. public: class ACE_Export Result : public ACE_Asynch_Read_Stream::Result { // = TITLE // This is that class which will be passed back to the // when the asynchronous read completes. // // = DESCRIPTION // This class has all the information necessary for the // to uniquiely identify the completion of the // asynchronous read. // // This class differs slightly from // ACE_Asynch_Read_Stream::Result as it calls back // on the instead of // . No additional state is // required by this class as ACE_Asynch_Result can store the // . friend class ACE_Asynch_Read_File; // The factory has special privileges. // protected: // // These two should really be protected. But sometimes it // simplifies code to be able to "fake" a result. Use carefully. Result (ACE_Handler &handler, ACE_HANDLE handle, ACE_Message_Block &message_block, u_long bytes_to_read, const void* act, u_long offset, u_long offset_high, ACE_HANDLE event); // Constructor is protected since creation is limited to // ACE_Asynch_Read_File factory. virtual void complete (u_long bytes_transferred, int success, const void *completion_key, u_long error = 0); // ACE_Proactor will call this method when the read completes. }; }; class ACE_Export ACE_Asynch_Write_File : public ACE_Asynch_Write_Stream { public: // = TITLE // This class is a factory for starting off asynchronous writes // on a file. // // = DESCRIPTION // Once is called, multiple asynchronous s can be // started using this class. A ACE_Asynch_Write_File::Result // will be passed back to the when the asynchronous // writes completes through the // callback. // // This class differs slightly from ACE_Asynch_Write_Stream as // it allows the user to specify an offset for the write. int write (ACE_Message_Block &message_block, u_long bytes_to_write, u_long offset = 0, u_long offset_high = 0, const void *act = 0); // This starts off an asynchronous write. Upto // will be write and stored in the . The write will // start at from the beginning of the file. public: class ACE_Export Result : public ACE_Asynch_Write_Stream::Result { // = TITLE // This is that class which will be passed back to the // when the asynchronous write completes. // // = DESCRIPTION // This class has all the information necessary for the // to uniquiely identify the completion of the // asynchronous write. // // This class differs slightly from // ACE_Asynch_Write_Stream::Result as it calls back // on the instead // of . No additional state // is required by this class as ACE_Asynch_Result can store // the . friend class ACE_Asynch_Write_File; // The factory has special privileges. // protected: // // These two should really be protected. But sometimes it // simplifies code to be able to "fake" a result. Use carefully. Result (ACE_Handler &handler, ACE_HANDLE handle, ACE_Message_Block &message_block, u_long bytes_to_write, const void* act, u_long offset, u_long offset_high, ACE_HANDLE event); // Constructor is protected since creation is limited to // ACE_Asynch_Write_File factory. virtual void complete (u_long bytes_transferred, int success, const void *completion_key, u_long error = 0); // ACE_Proactor will call this method when the write completes. }; }; class ACE_Export ACE_Asynch_Accept : public ACE_Asynch_Operation { // = TITLE // This class is a factory for starting off asynchronous accepts // on a listen handle. // // = DESCRIPTION // Once is called, multiple asynchronous s can // started using this class. A ACE_Asynch_Accept::Result will // be passed back to the when the asynchronous accept // completes through the // callback. public: ACE_Asynch_Accept (void); // A do nothing constructor. #if defined (ACE_HAS_AIO_CALLS) int open (ACE_Handler &handler, ACE_HANDLE handle = ACE_INVALID_HANDLE, const void *completion_key = 0, ACE_Proactor *proactor = 0); // (We will also call base class's from here). #endif /* ACE_HAS_AIO_CALLS */ int accept (ACE_Message_Block &message_block, u_long bytes_to_read, ACE_HANDLE accept_handle = ACE_INVALID_HANDLE, const void *act = 0); // This starts off an asynchronous accept. The asynchronous accept // call also allows any initial data to be returned to the // . Upto will be read and stored in the // . The will be used for the // call. If ( == INVALID_HANDLE), a new // handle will be created. // // must be specified. This is because the address of // the new connection is placed at the end of this buffer. public: class ACE_Export Result : public ACE_Asynch_Result { // = TITLE // This is that class which will be passed back to the // when the asynchronous accept completes. // // = DESCRIPTION // This class has all the information necessary for the // to uniquiely identify the completion of the // asynchronous accept. public: friend class ACE_Asynch_Accept; // The factory has special privileges. #if defined (ACE_HAS_AIO_CALLS) friend class ACE_Asynch_Accept_Handler; // This factory does it all, so it needs spl privileges. #endif /* ACE_HAS_AIO_CALLS */ u_long bytes_to_read (void) const; // The number of bytes which were requested at the start of the // asynchronous accept. ACE_Message_Block &message_block (void) const; // Message block which contains the read data. ACE_HANDLE listen_handle (void) const; // I/O handle used for accepting new connections. ACE_HANDLE accept_handle (void) const; // I/O handle for the new connection. // protected: // // These two should really be protected. But sometimes it // simplifies code to be able to "fake" a result. Use carefully. Result (ACE_Handler &handler, ACE_HANDLE listen_handle, ACE_HANDLE accept_handle, ACE_Message_Block &message_block, u_long bytes_to_read, const void* act, ACE_HANDLE event); // Constructor is protected since creation is limited to // ACE_Asynch_Accept factory. virtual void complete (u_long bytes_transferred, int success, const void *completion_key, u_long error = 0); // ACE_Proactor will call this method when the accept completes. protected: u_long bytes_to_read_; // Bytes requested when the asynchronous read was initiated. ACE_Message_Block &message_block_; // Message block for reading the data into. ACE_HANDLE listen_handle_; // I/O handle used for accepting new connections. ACE_HANDLE accept_handle_; // I/O handle for the new connection. }; private: #if defined (ACE_HAS_AIO_CALLS) static void* thread_function (void* reactor); // The thread function that does handle events ACE_Reactor reactor_; // Reactor to wait on the . ACE_Asynch_Accept_Handler* accept_handler_; // The Event Handler to do handle_input. #endif /* ACE_HAS_AIO_CALLS */ }; class ACE_Export ACE_Asynch_Transmit_File : public ACE_Asynch_Operation { // = TITLE // This class is a factory for starting off asynchronous // transmit files on a stream. // // = DESCRIPTION // Once is called, multiple asynchronous s // can started using this class. A // ACE_Asynch_Transmit_File::Result will be passed back to the // when the asynchronous transmit file completes // through the callback. // // The transmit_file function transmits file data over a // connected network connection. The function uses the operating // system's cache manager to retrieve the file data. This // function provides high-performance file data transfer over // network connections. This function would be of great use in // a Web Server, Image Server, etc. public: class Header_And_Trailer; // Forward declaration. ACE_Asynch_Transmit_File (void); // A "do-nothing" constructor. int transmit_file (ACE_HANDLE file, Header_And_Trailer *header_and_trailer = 0, u_long bytes_to_write = 0, u_long offset = 0, u_long offset_high = 0, u_long bytes_per_send = 0, u_long flags = 0, const void *act = 0); // This starts off an asynchronous transmit file. The is a // handle to an open file. is a pointer to a // data structure that contains pointers to data to send before and // after the file data is sent. Set this parameter to 0 if you only // want to transmit the file data. Upto will be // written to the . If you want to send the entire file, // let = 0. is the size of each // block of data sent per send operation. Please read the Win32 // documentation on what the flags should be. public: class ACE_Export Result : public ACE_Asynch_Result { // = TITLE // This is that class which will be passed back to the // when the asynchronous transmit file completes. // // = DESCRIPTION // This class has all the information necessary for the // to uniquiely identify the completion of the // asynchronous transmit file. public: friend class ACE_Asynch_Transmit_File; // The factory has special privileges. ACE_HANDLE socket (void) const; // Socket used for transmitting the file. ACE_HANDLE file (void) const; // File from which the data is read. Header_And_Trailer *header_and_trailer (void) const; // Header and trailer data associated with this transmit file. u_long bytes_to_write (void) const; // The number of bytes which were requested at the start of the // asynchronous transmit file. u_long bytes_per_send (void) const; // Number of bytes per send requested at the start of the transmit // file. u_long flags (void) const; // Flags which were passed into transmit file. // protected: // // These two should really be protected. But sometimes it // simplifies code to be able to "fake" a result. Use carefully. Result (ACE_Handler &handler, ACE_HANDLE socket, ACE_HANDLE file, Header_And_Trailer *header_and_trailer, u_long bytes_to_write, u_long offset, u_long offset_high, u_long bytes_per_send, u_long flags, const void *act, ACE_HANDLE event); // Constructor is protected since creation is limited to // ACE_Asynch_Transmit_File factory. virtual void complete (u_long bytes_transferred, int success, const void *completion_key, u_long error = 0); // ACE_Proactor will call this method when the write completes. protected: ACE_HANDLE socket_; // Network I/O handle. ACE_HANDLE file_; // File I/O handle. Header_And_Trailer *header_and_trailer_; // Header and trailer data associated with this transmit file. u_long bytes_to_write_; // The number of bytes which were requested at the start of the // asynchronous transmit file. u_long bytes_per_send_; // Number of bytes per send requested at the start of the transmit // file. u_long flags_; // Flags which were passed into transmit file. }; class ACE_Export Header_And_Trailer { // = TITLE // The class defines a data structure that contains pointers // to data to send before and after the file data is sent. // // = DESCRIPTION // This class provides a wrapper over TRANSMIT_FILE_BUFFERS // and provided a consistent use of ACE_Message_Blocks. public: Header_And_Trailer (ACE_Message_Block *header = 0, u_long header_bytes = 0, ACE_Message_Block *trailer = 0, u_long trailer_bytes = 0); // Constructor. void header_and_trailer (ACE_Message_Block *header = 0, u_long header_bytes = 0, ACE_Message_Block *trailer = 0, u_long trailer_bytes = 0); // This method allows all the member to be set in one fell swoop. ACE_Message_Block *header (void) const; void header (ACE_Message_Block *message_block); // Header which goes before the file data. u_long header_bytes (void) const; void header_bytes (u_long bytes); // Size of the header data. ACE_Message_Block *trailer (void) const; void trailer (ACE_Message_Block *message_block); // Trailer which goes after the file data. u_long trailer_bytes (void) const; void trailer_bytes (u_long bytes); // Size of the trailer data. ACE_LPTRANSMIT_FILE_BUFFERS transmit_buffers (void); // Conversion routine. protected: ACE_Message_Block *header_; // Header data. u_long header_bytes_; // Size of header data. ACE_Message_Block *trailer_; // Trailer data. u_long trailer_bytes_; // Size of trailer data. ACE_TRANSMIT_FILE_BUFFERS transmit_buffers_; // Target data structure. }; }; class ACE_Export ACE_Handler { // = TITLE // This base class defines the interface for receiving the // results of asynchronous operations. // // = DESCRIPTION // Subclasses of this class will fill in appropriate methods. public: ACE_Handler (void); // A do nothing constructor. ACE_Handler (ACE_Proactor *p); // A do nothing constructor which allows proactor to be set to . virtual ~ACE_Handler (void); // Virtual destruction. virtual void handle_read_stream (const ACE_Asynch_Read_Stream::Result &result); // This method will be called when an asynchronous read completes on // a stream. virtual void handle_write_stream (const ACE_Asynch_Write_Stream::Result &result); // This method will be called when an asynchronous write completes // on a strea_m. virtual void handle_read_file (const ACE_Asynch_Read_File::Result &result); // This method will be called when an asynchronous read completes on // a file. virtual void handle_write_file (const ACE_Asynch_Write_File::Result &result); // This method will be called when an asynchronous write completes // on a file. virtual void handle_accept (const ACE_Asynch_Accept::Result &result); // This method will be called when an asynchronous accept completes. virtual void handle_transmit_file (const ACE_Asynch_Transmit_File::Result &result); // This method will be called when an asynchronous transmit file // completes. virtual void handle_time_out (const ACE_Time_Value &tv, const void *act = 0); // Called when timer expires. was the requested time value and // is the ACT passed when scheduling the timer ACE_Proactor *proactor (void); // Get the proactor associated with this handler. void proactor (ACE_Proactor *p); // Set the proactor. virtual ACE_HANDLE handle (void) const; // Get the I/O handle used by this . This method will be // called by the ACE_Asynch_* classes when an ACE_INVALID_HANDLE is // passed to . protected: ACE_Proactor *proactor_; // The proactor associated with this handler. }; // Forward declartion template class ACE_Asynch_Acceptor; class ACE_Export ACE_Service_Handler : public ACE_Handler { // = TITLE // This base class defines the interface for the // ACE_Asynch_Acceptor to call into when new connection are // accepted. // // = DESCRIPTION // Subclasses of this class will fill in appropriate methods to // define application specific behavior. public: friend class ACE_Asynch_Acceptor; // The Acceptor is the factory and therefore should have special // privileges. ACE_Service_Handler (void); // A do nothing constructor. virtual ~ACE_Service_Handler (void); // Virtual destruction. virtual void open (ACE_HANDLE new_handle, ACE_Message_Block &message_block); // is called by ACE_Asynch_Acceptor to initialize a new // instance of ACE_Service_Handler that has been created after the a // new connection is accepted. The handle for the new connection is // passed along with an initial data that may have shown up. // protected: // This should be corrected after the correct semantics of the // friend has been figured out. virtual void addresses (const ACE_INET_Addr &remote_address, const ACE_INET_Addr &local_address); // Called by ACE_Asynch_Acceptor to pass the addresses of the new // connections. }; #if defined (__ACE_INLINE__) #include "ace/Asynch_IO.i" #endif /* __ACE_INLINE__ */ #endif /* ACE_WIN32 || ACE_HAS_AIO_CALLS*/ #endif /* ACE_ASYNCH_IO_H */