summaryrefslogtreecommitdiff
path: root/ace
diff options
context:
space:
mode:
authoralex <alex@ae88bc3d-4319-0410-8dbf-d08b4c9d3795>1999-02-16 06:38:49 +0000
committeralex <alex@ae88bc3d-4319-0410-8dbf-d08b4c9d3795>1999-02-16 06:38:49 +0000
commit7211c1e2fcda52e3bce16a29f05cc8f94fbab56c (patch)
tree6103a5605b624fe5306a57d8c8db1e4888734bc1 /ace
parentc3ea40ae39854fb98b82ab6c9e415010ff09b26d (diff)
downloadATCD-7211c1e2fcda52e3bce16a29f05cc8f94fbab56c.tar.gz
*** empty log message ***
Diffstat (limited to 'ace')
-rw-r--r--ace/Asynch_IO_Impl.cpp14
-rw-r--r--ace/Asynch_IO_Impl.h464
-rw-r--r--ace/Asynch_IO_Impl.i87
-rw-r--r--ace/POSIX_Asynch_IO.h1085
-rw-r--r--ace/POSIX_Proactor.cpp1138
-rw-r--r--ace/WIN32_Proactor.i2
6 files changed, 2790 insertions, 0 deletions
diff --git a/ace/Asynch_IO_Impl.cpp b/ace/Asynch_IO_Impl.cpp
new file mode 100644
index 00000000000..9baab6f5e04
--- /dev/null
+++ b/ace/Asynch_IO_Impl.cpp
@@ -0,0 +1,14 @@
+// $Id$
+#define ACE_BUILD_DLL
+#include "ace/OS.h"
+#include "ace/Asynch_IO_Impl.h"
+
+#if (defined (ACE_WIN32) && !defined (ACE_HAS_WINCE)) || (defined (ACE_HAS_AIO_CALLS))
+// This only works on Win32 platforms and on Unix platforms supporting
+// aio calls.
+
+#if !defined (__ACE_INLINE__)
+#include "ace/Asynch_IO_Impl.i"
+#endif /* __ACE_INLINE__ */
+
+#endif /* ACE_WIN32 || ACE_HAS_WINCE */
diff --git a/ace/Asynch_IO_Impl.h b/ace/Asynch_IO_Impl.h
new file mode 100644
index 00000000000..21b8a9e245c
--- /dev/null
+++ b/ace/Asynch_IO_Impl.h
@@ -0,0 +1,464 @@
+/* -*- C++ -*- */
+// $Id$
+
+// ============================================================================
+//
+// = LIBRARY
+//
+// ace
+//
+// = FILENAME
+//
+// Asynch_IO_Impl.h
+//
+// = DESCRIPTION
+//
+// This class contains asbtract base classes for all the concrete
+// implementation classes for the various asynchronous operations
+// that are used with the Praoctor.
+//
+// = AUTHOR
+//
+// Irfan Pyarali (irfan@cs.wustl.edu),
+// Tim Harrison (harrison@cs.wustl.edu) and
+// Alexander Babu Arulanthu <alex@cs.wustl.edu>
+//
+// ============================================================================
+
+#if !defined (ACE_ASYNCH_IO_IMPL_H)
+#define ACE_ASYNCH_IO_IMPL_H
+
+#if !defined (ACE_LACKS_PRAGMA_ONCE)
+#pragma once
+#endif /* ACE_LACKS_PRAGMA_ONCE */
+
+#if (defined (ACE_WIN32) && !defined (ACE_HAS_WINCE)) || (defined (ACE_HAS_AIO_CALLS))
+// This only works on Win32 platforms and on Unix platforms supporting
+// aio calls.
+
+#include "ace/Asynch_IO.h"
+
+class ACE_Export ACE_Asynch_Result_Impl
+{
+ // = TITLE
+ //
+ // Abstract base class for the all the classes that provide
+ // concrete implementations for ACE_Asynch_Result.
+ //
+ // = DESCRIPTION
+ //
+public:
+ virtual ~ACE_Asynch_Result_Impl (void) {}
+
+ virtual u_long bytes_transferred (void) const = 0;
+ // Number of bytes transferred by the operation.
+
+ virtual const void *act (void) const = 0;
+ // ACT associated with the operation.
+
+ virtual int success (void) const = 0;
+ // Did the operation succeed?
+
+ virtual const void *completion_key (void) const = 0;
+ // This ACT is not the same as the ACT associated with the
+ // asynchronous operation.
+
+ virtual u_long error (void) const = 0;
+ // Error value if the operation fail.
+
+ virtual ACE_HANDLE event (void) const = 0;
+ // Event associated with the OVERLAPPED structure.
+
+ virtual u_long offset (void) const = 0;
+ virtual u_long offset_high (void) const = 0;
+ // This really make sense only when doing file I/O.
+
+ virtual int priority (void) const = 0;
+ // Priority of the operation.
+
+ // protected:
+ //
+ // These two should really be protected. But sometimes it
+ // simplifies code to be able to "fake" a result. Use carefully.
+ virtual void complete (u_long bytes_transferred,
+ int success,
+ const void *completion_key,
+ u_long error = 0) = 0;
+ // This is called when the asynchronous operation completes.
+
+protected:
+ ACE_Asynch_Result_Impl (void);
+ // Do-nothing constructor.
+};
+
+class ACE_Export ACE_Asynch_Operation_Impl
+{
+ // = TITLE
+ //
+ // Abstract base class for all the concrete implementation
+ // classes that provide different implementations for the
+ // ACE_Asynch_Operation.
+ //
+ // = DESCRIPTION
+ //
+public:
+ virtual ~ACE_Asynch_Operation_Impl () {}
+
+ virtual int open (ACE_Handler &handler,
+ ACE_HANDLE handle,
+ const void *completion_key,
+ ACE_Proactor *proactor) = 0;
+ // Initializes the factory with information which will be used with
+ // each asynchronous call. If (<handle> == ACE_INVALID_HANDLE),
+ // <ACE_Handler::handle> will be called on the <handler> to get the
+ // correct handle.
+
+ virtual int cancel (void) = 0;
+ // 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.
+
+ virtual ACE_Proactor* proactor (void) const = 0;
+ // Return the underlying proactor.
+
+protected:
+ ACE_Asynch_Operation_Impl (void);
+ // Do-nothing constructor.
+};
+
+class ACE_Export ACE_Asynch_Read_Stream_Impl : public virtual ACE_Asynch_Operation_Impl
+{
+ // = TITLE
+ //
+ // Abstract base class for all the concrete implementation
+ // classes that provide different implementations for the
+ // ACE_Asynch_Read_Stream
+ //
+ // = DESCRIPTION
+ //
+public:
+ virtual ~ACE_Asynch_Read_Stream_Impl (void) {}
+
+ virtual int read (ACE_Message_Block &message_block,
+ u_long bytes_to_read,
+ const void *act,
+ int priority) = 0;
+ // This starts off an asynchronous read. Upto <bytes_to_read> will
+ // be read and stored in the <message_block>.
+
+protected:
+ ACE_Asynch_Read_Stream_Impl (void);
+ // Do-nothing constructor.
+};
+
+class ACE_Export ACE_Asynch_Read_Stream_Result_Impl : public virtual ACE_Asynch_Result_Impl
+{
+ // = TITLE
+ //
+ // Abstract base class for all the concrete implementation
+ // classes that provide different implementations for the
+ // ACE_Asynch_Read_Stream::Result class.
+ //
+ // = DESCRIPTION
+ //
+public:
+ virtual ~ACE_Asynch_Read_Stream_Result_Impl () {}
+
+ virtual u_long bytes_to_read (void) const = 0;
+ // The number of bytes which were requested at the start of the
+ // asynchronous read.
+
+ virtual ACE_Message_Block &message_block (void) const = 0;
+ // Message block which contains the read data.
+
+ virtual ACE_HANDLE handle (void) const = 0;
+ // I/O handle used for reading.
+
+protected:
+ ACE_Asynch_Read_Stream_Result_Impl (void);
+ // Do-nothing constructor.
+};
+
+class ACE_Export ACE_Asynch_Write_Stream_Impl : public virtual ACE_Asynch_Operation_Impl
+{
+ // = TITLE
+ //
+ // Abstract base class for all the concrete implementation
+ // classes that provide different implementations for the
+ // ACE_Asynch_Write_Stream class.
+ //
+ // = DESCRIPTION
+ //
+public:
+ virtual ~ACE_Asynch_Write_Stream_Impl (void) {}
+
+ virtual int write (ACE_Message_Block &message_block,
+ u_long bytes_to_write,
+ const void *act,
+ int priority) = 0;
+ // This starts off an asynchronous write. Upto <bytes_to_write>
+ // will be written from the <message_block>.
+
+protected:
+ ACE_Asynch_Write_Stream_Impl (void);
+ // Do-nothing constructor.
+};
+
+class ACE_Export ACE_Asynch_Write_Stream_Result_Impl : public virtual ACE_Asynch_Result_Impl
+{
+ // = TITLE
+ //
+ // Abstract base class for all the concrete implementation
+ // classes that provide different implementations for the
+ // ACE_Asynch_Write_Stream::Result.
+ //
+ // = DESCRIPTION
+ //
+public:
+ virtual ~ACE_Asynch_Write_Stream_Result_Impl () {}
+
+ virtual u_long bytes_to_write (void) const = 0;
+ // The number of bytes which were requested at the start of the
+ // asynchronous write.
+
+ virtual ACE_Message_Block &message_block (void) const = 0;
+ // Message block that contains the data to be written.
+
+ virtual ACE_HANDLE handle (void) const = 0;
+ // I/O handle used for writing.
+
+protected:
+ ACE_Asynch_Write_Stream_Result_Impl (void);
+ // Do-nothing constructor.
+};
+
+class ACE_Export ACE_Asynch_Read_File_Impl : public virtual ACE_Asynch_Read_Stream_Impl
+{
+ // = TITLE
+ //
+ // Abstract base class for all the concrete implementation
+ // classes that provide different implementations for the
+ // ACE_Asynch_Read_File::Result.
+ //
+ // = DESCRIPTION
+ //
+public:
+ virtual ~ACE_Asynch_Read_File_Impl () {}
+
+ virtual int read (ACE_Message_Block &message_block,
+ u_long bytes_to_read,
+ u_long offset,
+ u_long offset_high,
+ const void *act,
+ int priority) = 0;
+ // This starts off an asynchronous read. Upto <bytes_to_read> will
+ // be read and stored in the <message_block>. The read will start
+ // at <offset> from the beginning of the file.
+
+protected:
+ ACE_Asynch_Read_File_Impl (void);
+ // Do-nothing constructor.
+};
+
+class ACE_Export ACE_Asynch_Read_File_Result_Impl : public virtual ACE_Asynch_Read_Stream_Result_Impl
+{
+ // = TITLE
+ // This is the abstract base class for all the concrete
+ // implementation classes for ACE_Asynch_Read_File::Result.
+ //
+ // = DESCRIPTION
+ //
+public:
+ virtual ~ACE_Asynch_Read_File_Result_Impl () {}
+ // Destructor.
+
+protected:
+ ACE_Asynch_Read_File_Result_Impl (void);
+ // Do-nothing constructor.
+};
+
+class ACE_Export ACE_Asynch_Write_File_Impl : public virtual ACE_Asynch_Write_Stream_Impl
+{
+ // = TITLE
+ //
+ // Abstract base class for all the concrete implementation
+ // classes that provide different implementations for the
+ // ACE_Asynch_Write_File.
+ //
+ // = DESCRIPTION
+ //
+public:
+ virtual ~ACE_Asynch_Write_File_Impl (void) {}
+
+ virtual int write (ACE_Message_Block &message_block,
+ u_long bytes_to_write,
+ u_long offset,
+ u_long offset_high,
+ const void *act,
+ int priority) = 0;
+ // This starts off an asynchronous write. Upto <bytes_to_write>
+ // will be write and stored in the <message_block>. The write will
+ // start at <offset> from the beginning of the file.
+
+protected:
+ ACE_Asynch_Write_File_Impl (void);
+ // Do-nothing constructor.
+};
+
+class ACE_Export ACE_Asynch_Write_File_Result_Impl : public virtual ACE_Asynch_Write_Stream_Result_Impl
+{
+ // = TITLE
+ //
+ // This is the abstract base class for all the concrete
+ // implementation classes that provide different implementations
+ // for the ACE_Asynch_Write_File::Result.
+ //
+ // = DESCRIPTION
+ //
+public:
+ virtual ~ACE_Asynch_Write_File_Result_Impl () {}
+
+protected:
+ ACE_Asynch_Write_File_Result_Impl (void);
+ // Do-nothing constructor.
+};
+
+class ACE_Export ACE_Asynch_Accept_Impl : public virtual ACE_Asynch_Operation_Impl
+{
+ // = TITLE
+ //
+ // Abstract base class for all the concrete implementation
+ // classes that provide different implementations for the
+ // ACE_Asynch_Accept.
+ //
+ // = DESCRIPTION
+ //
+public:
+ virtual ~ACE_Asynch_Accept_Impl (void) {}
+
+ virtual int accept (ACE_Message_Block &message_block,
+ u_long bytes_to_read,
+ ACE_HANDLE accept_handle,
+ const void *act,
+ int priority) = 0;
+ // This starts off an asynchronous accept. The asynchronous accept
+ // call also allows any initial data to be returned to the
+ // <handler>. Upto <bytes_to_read> will be read and stored in the
+ // <message_block>. The <accept_handle> will be used for the
+ // <accept> call. If (<accept_handle> == INVALID_HANDLE), a new
+ // handle will be created.
+ //
+ // <message_block> must be specified. This is because the address of
+ // the new connection is placed at the end of this buffer.
+
+protected:
+ ACE_Asynch_Accept_Impl (void);
+ // Do-nothing constructor.
+};
+
+class ACE_Export ACE_Asynch_Accept_Result_Impl : public virtual ACE_Asynch_Result_Impl
+{
+ // = TITLE
+ //
+ // Abstract base class for all the concrete implementation
+ // classes that provide different implementations for the
+ // ACE_Asynch_Accept.
+ //
+ // = DESCRIPTION
+ //
+public:
+ virtual ~ACE_Asynch_Accept_Result_Impl () {}
+
+ virtual u_long bytes_to_read (void) const = 0;
+ // The number of bytes which were requested at the start of the
+ // asynchronous accept.
+
+ virtual ACE_Message_Block &message_block (void) const = 0;
+ // Message block which contains the read data.
+
+ virtual ACE_HANDLE listen_handle (void) const = 0;
+ // I/O handle used for accepting new connections.
+
+ virtual ACE_HANDLE accept_handle (void) const = 0;
+ // I/O handle for the new connection.
+
+protected:
+ ACE_Asynch_Accept_Result_Impl (void);
+ // Do-nothing constructor.
+};
+
+class ACE_Asynch_Transmit_File_Impl : public virtual ACE_Asynch_Operation_Impl
+{
+ // = TITLE
+ //
+ // Abstract base class for all the concrete implementation
+ // classes that provide different implementations for the
+ // ACE_Asynch_Transmit_File.
+ //
+ // = DESCRIPTION
+ //
+public:
+ virtual ~ACE_Asynch_Transmit_File_Impl () {}
+
+ virtual int transmit_file (ACE_HANDLE file,
+ ACE_Asynch_Transmit_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,
+ int priority) = 0;
+ // This starts off an asynchronous transmit file.
+
+protected:
+ ACE_Asynch_Transmit_File_Impl (void);
+ // Do-nothing constructor.
+};
+
+class ACE_Export ACE_Asynch_Transmit_File_Result_Impl : public virtual ACE_Asynch_Result_Impl
+{
+ // = TITLE
+ //
+ // Abstract base class for all the concrete implementation
+ // classes that provide different implementations for the
+ // ACE_Asynch_Transmit_File::Result.
+ //
+ // = DESCRIPTION
+ //
+public:
+ virtual ~ACE_Asynch_Transmit_File_Result_Impl () {}
+
+ virtual ACE_HANDLE socket (void) const = 0;
+ // Socket used for transmitting the file.
+
+ virtual ACE_HANDLE file (void) const = 0;
+ // File from which the data is read.
+
+ virtual ACE_Asynch_Transmit_File::Header_And_Trailer *header_and_trailer (void) const = 0;
+ // Header and trailer data associated with this transmit file.
+
+ virtual u_long bytes_to_write (void) const = 0;
+ // The number of bytes which were requested at the start of the
+ // asynchronous transmit file.
+
+ virtual u_long bytes_per_send (void) const = 0;
+ // Number of bytes per send requested at the start of the transmit
+ // file.
+
+ virtual u_long flags (void) const = 0;
+ // Flags which were passed into transmit file.
+
+protected:
+ ACE_Asynch_Transmit_File_Result_Impl (void);
+ // Do-nothing constructor.
+};
+
+#if defined (__ACE_INLINE__)
+#include "ace/Asynch_IO_Impl.i"
+#endif /* __ACE_INLINE__ */
+
+#endif /* ACE_HAS_AIO_CALLS || !ACE_HAS_WINCE && ACE_WIN32 */
+#endif /* ACE_ASYNCH_IO_IMPL_H */
diff --git a/ace/Asynch_IO_Impl.i b/ace/Asynch_IO_Impl.i
new file mode 100644
index 00000000000..a6c36925943
--- /dev/null
+++ b/ace/Asynch_IO_Impl.i
@@ -0,0 +1,87 @@
+// $Id$
+
+ACE_INLINE
+ACE_Asynch_Result_Impl::ACE_Asynch_Result_Impl (void)
+{
+}
+
+ACE_INLINE
+ACE_Asynch_Operation_Impl::ACE_Asynch_Operation_Impl (void)
+{
+}
+
+ACE_INLINE
+ACE_Asynch_Read_Stream_Impl::ACE_Asynch_Read_Stream_Impl (void)
+ : ACE_Asynch_Operation_Impl ()
+{
+}
+
+ACE_INLINE
+ACE_Asynch_Read_Stream_Result_Impl::ACE_Asynch_Read_Stream_Result_Impl (void)
+ : ACE_Asynch_Result_Impl ()
+{
+}
+
+ACE_INLINE
+ACE_Asynch_Write_Stream_Impl::ACE_Asynch_Write_Stream_Impl (void)
+ : ACE_Asynch_Operation_Impl ()
+{
+}
+
+ACE_INLINE
+ACE_Asynch_Write_Stream_Result_Impl::ACE_Asynch_Write_Stream_Result_Impl (void)
+ : ACE_Asynch_Result_Impl ()
+{
+}
+
+ACE_INLINE
+ACE_Asynch_Read_File_Impl::ACE_Asynch_Read_File_Impl (void)
+ : ACE_Asynch_Operation_Impl (),
+ ACE_Asynch_Read_Stream_Impl ()
+{
+}
+
+ACE_INLINE
+ACE_Asynch_Read_File_Result_Impl::ACE_Asynch_Read_File_Result_Impl (void)
+ : ACE_Asynch_Result_Impl (),
+ ACE_Asynch_Read_Stream_Result_Impl ()
+{
+}
+
+ACE_INLINE
+ACE_Asynch_Write_File_Impl::ACE_Asynch_Write_File_Impl (void)
+ : ACE_Asynch_Operation_Impl (),
+ ACE_Asynch_Write_Stream_Impl ()
+{
+}
+
+ACE_INLINE
+ACE_Asynch_Write_File_Result_Impl::ACE_Asynch_Write_File_Result_Impl (void)
+ : ACE_Asynch_Result_Impl (),
+ ACE_Asynch_Write_Stream_Result_Impl ()
+{
+}
+
+ACE_INLINE
+ACE_Asynch_Accept_Impl::ACE_Asynch_Accept_Impl (void)
+ : ACE_Asynch_Operation_Impl ()
+{
+}
+
+ACE_INLINE
+ACE_Asynch_Accept_Result_Impl::ACE_Asynch_Accept_Result_Impl (void)
+ : ACE_Asynch_Result_Impl ()
+{
+}
+
+ACE_INLINE
+ACE_Asynch_Transmit_File_Impl::ACE_Asynch_Transmit_File_Impl (void)
+ : ACE_Asynch_Operation_Impl ()
+{
+}
+
+ACE_INLINE
+ACE_Asynch_Transmit_File_Result_Impl::ACE_Asynch_Transmit_File_Result_Impl (void)
+ : ACE_Asynch_Result_Impl ()
+{
+}
diff --git a/ace/POSIX_Asynch_IO.h b/ace/POSIX_Asynch_IO.h
new file mode 100644
index 00000000000..e572d1d73df
--- /dev/null
+++ b/ace/POSIX_Asynch_IO.h
@@ -0,0 +1,1085 @@
+/* -*- C++ -*- */
+// $Id$
+
+// ============================================================================
+//
+// = LIBRARY
+//
+// ace
+//
+// = FILENAME
+//
+// POSIX_Asynch_IO.h
+//
+// = DESCRIPTION
+//
+// The implementation classes for POSIX implementation of Asynch
+// Operations are defined here in this file.
+//
+// = AUTHOR
+//
+// Irfan Pyarali (irfan@cs.wustl.edu),
+// Tim Harrison (harrison@cs.wustl.edu) and
+// Alexander Babu Arulanthu <alex@cs.wustl.edu>
+//
+// ============================================================================
+
+#if !defined (ACE_POSIX_ASYNCH_IO_H)
+#define ACE_POSIX_ASYNCH_IO_H
+
+#include "ace/OS.h"
+
+#if !defined (ACE_LACKS_PRAGMA_ONCE)
+#pragma once
+#endif /* ACE_LACKS_PRAGMA_ONCE */
+
+#if defined (ACE_HAS_AIO_CALLS)
+
+#include "ace/Asynch_IO_Impl.h"
+#include "ace/Reactor.h"
+
+// Forward declarations
+class ACE_POSIX_SIG_Proactor;
+class ACE_POSIX_AIOCB_Proactor;
+
+class ACE_Export ACE_POSIX_Asynch_Result : public virtual ACE_Asynch_Result_Impl,
+ public aiocb
+{
+ // = TITLE
+ //
+ // This class provides concrete implementation for
+ // ACE_Asynch_Result for POSIX4 platforms. This class extends
+ // <aiocb> and makes it more useful.
+ //
+ // = DESCRIPTION
+ //
+public:
+ 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 is the ACT associated with the handle on which the
+ // Asynch_Operation takes place.
+ //
+ // @@ This is not implemented for POSIX4 platforms.
+ //
+
+ u_long error (void) const;
+ // Error value if the operation fail.
+
+ ACE_HANDLE event (void) const;
+ // This returns ACE_INVALID_HANDLE on POSIX4-Unix platforms.
+
+ u_long offset (void) const;
+ u_long offset_high (void) const;
+ // This really make sense only when doing file I/O.
+ //
+ // @@ On POSIX4-Unix, offset_high should be supported using
+ // aiocb64.
+ //
+
+ int priority (void) const;
+ // Priority of the operation.
+
+ virtual ~ACE_POSIX_Asynch_Result (void);
+ // Destructor.
+
+protected:
+ ACE_POSIX_Asynch_Result (ACE_Handler &handler,
+ const void* act,
+ ACE_HANDLE event,
+ u_long offset,
+ u_long offset_high,
+ int priority);
+ // Constructor. <Event> is not used on POSIX.
+
+ ACE_Handler &handler_;
+ // Handler that will be called back.
+
+ const void *act_;
+ // ACT for this operation.
+ // We could use <aiocb::aio_sigevent.sigev_value.sival_ptr> for
+ // this. But it doesnot provide the constness, so this may be
+ // better.
+
+ // aiocb::aio_resultp.aio_return
+ // Bytes transferred by this operation.
+
+ int success_;
+ // Success indicator.
+
+ const void *completion_key_;
+ // ACT associated with handle.
+
+ // aiocb::aio_resultp.aio_errno
+ // Error if operation failed.
+};
+
+class ACE_Export ACE_POSIX_Asynch_Operation : public virtual ACE_Asynch_Operation_Impl
+{
+ // = TITLE
+ //
+ // This class abstracts out the common things needed for
+ // implementing Asynch_Operation for POSIX platforms. Specific
+ // implementations such as POSIX_AIOCB_Asynch_Operation and
+ // POSIX_SIG_Asynch_Operation etc., can derive from this class.
+ //
+ // = DESCRIPTION
+ //
+public:
+ int open (ACE_Handler &handler,
+ ACE_HANDLE handle,
+ const void *completion_key,
+ ACE_Proactor *proactor);
+ // Initializes the factory with information which will be used with
+ // each asynchronous call. If (<handle> == ACE_INVALID_HANDLE),
+ // <ACE_Handler::handle> will be called on the <handler> to get the
+ // correct handle.
+
+ int cancel (void);
+ //
+ // @@ Not implemented. Returns 0.
+
+ // = Access methods.
+
+ ACE_Proactor* proactor (void) const;
+ // Return the underlying proactor.
+
+protected:
+ ACE_POSIX_Asynch_Operation (void);
+ // No op contructor.
+
+ virtual ~ACE_POSIX_Asynch_Operation (void);
+ // Destructor.
+
+ 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_POSIX_AIOCB_Asynch_Operation : public virtual ACE_POSIX_Asynch_Operation
+{
+ // = TITLE
+ //
+ // This class implements ACE_Asynch_Operation for AIOCB
+ // (Asynchronous I/O Control Blocks) based implementation of
+ // Proactor.
+ //
+ // = DESCRIPTION
+ //
+protected:
+ ACE_POSIX_AIOCB_Asynch_Operation (ACE_POSIX_AIOCB_Proactor *posix_aiocb_proactor);
+ // Contructor.
+
+ virtual ~ACE_POSIX_AIOCB_Asynch_Operation (void);
+ // Destructor.
+
+ int register_aio_with_proactor (aiocb *aiocb_ptr);
+ // This call is for the POSIX implementation. This method is used by
+ // <ACE_Asynch_Operation> to store some information with the
+ // Proactor after an <aio_> call is issued, so that the Proactor can
+ // retrive this information to do <aio_return> and <aio_error>.
+ // 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.
+
+ ACE_POSIX_AIOCB_Proactor *posix_aiocb_proactor_;
+ // It is easy to get this specific implementation proactor here,
+ // since it is the one that creates the correct POSIX_Asynch_*
+ // objects. We can use this to get to the implementation proactor
+ // directly.
+};
+
+class ACE_Export ACE_POSIX_SIG_Asynch_Operation : public virtual ACE_POSIX_Asynch_Operation
+{
+ // = TITLE
+ //
+ // This class implements ACE_Asynch_Operation for Real-Time
+ // Signal (<sigtimedwait>) based implementation of Proactor.
+ //
+ // = DESCRIPTION
+ //
+protected:
+ ACE_POSIX_SIG_Asynch_Operation (ACE_POSIX_SIG_Proactor *posix_sig_proactor);
+ // Contructor.
+
+ virtual ~ACE_POSIX_SIG_Asynch_Operation (void);
+ // Destructor.
+
+ ACE_POSIX_SIG_Proactor *posix_sig_proactor_;
+ // It is easy to get this specific implementation proactor here,
+ // since it is the one that creates the correct POSIX_Asynch_*
+ // objects. We can use this to get to the implementation proactor
+ // directly.
+};
+
+class ACE_Export ACE_POSIX_Asynch_Read_Stream_Result : public virtual ACE_Asynch_Read_Stream_Result_Impl,
+ public ACE_POSIX_Asynch_Result
+{
+ // = TITLE
+ //
+ // This class provides concrete implementation for
+ // ACE_Asynch_Read_Stream::Result class for POSIX platforms.
+ //
+ // = DESCRIPTION
+ //
+
+ friend class ACE_POSIX_AIOCB_Asynch_Read_Stream;
+ friend class ACE_POSIX_SIG_Asynch_Read_Stream;
+ // Factory classes willl have special permissions.
+
+ friend class ACE_POSIX_Proactor;
+ // The Proactor constructs the Result class for faking results.
+
+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:
+ ACE_POSIX_Asynch_Read_Stream_Result (ACE_Handler &handler,
+ ACE_HANDLE handle,
+ ACE_Message_Block &message_block,
+ u_long bytes_to_read,
+ const void* act,
+ ACE_HANDLE event,
+ int priority);
+ // 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);
+ // Get the data copied to this class, before calling application
+ // handler.
+
+ virtual ~ACE_POSIX_Asynch_Read_Stream_Result (void);
+ // Destrcutor.
+
+ // aiocb::aio_nbytes
+ // Bytes requested when the asynchronous read was initiated.
+
+ ACE_Message_Block &message_block_;
+ // Message block for reading the data into.
+
+ // aiocb::aio_filedes
+ // I/O handle used for reading.
+};
+
+class ACE_Export ACE_POSIX_AIOCB_Asynch_Read_Stream : public virtual ACE_Asynch_Read_Stream_Impl,
+ public ACE_POSIX_AIOCB_Asynch_Operation
+{
+ // = TITLE
+ //
+ // This class implements ACE_Asynch_Read_Stream for AIOCB
+ // (Asynchronous I/O Control Blocks) based implementation of
+ // Proactor.
+ //
+ // = DESCRIPTION
+ //
+public:
+ ACE_POSIX_AIOCB_Asynch_Read_Stream (ACE_POSIX_AIOCB_Proactor *posix_aiocb_proactor);
+ // Constructor.
+
+ int read (ACE_Message_Block &message_block,
+ u_long bytes_to_read,
+ const void *act,
+ int priority);
+ // This starts off an asynchronous read. Upto <bytes_to_read> will
+ // be read and stored in the <message_block>.
+
+ virtual ~ACE_POSIX_AIOCB_Asynch_Read_Stream (void);
+ // Destructor.
+
+protected:
+ int shared_read (ACE_POSIX_Asynch_Read_Stream_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.
+};
+
+
+class ACE_Export ACE_POSIX_SIG_Asynch_Read_Stream : public virtual ACE_Asynch_Read_Stream_Impl,
+ public ACE_POSIX_SIG_Asynch_Operation
+{
+ // = TITLE
+ //
+ // This class implements ACE_Asynch_Read_Stream for Real-Time
+ // Signal (<sigtimedwait>) based implementation of Proactor.
+ //
+ // = DESCRIPTION
+ //
+public:
+ ACE_POSIX_SIG_Asynch_Read_Stream (ACE_POSIX_SIG_Proactor *posix_sig_proactor);
+ // Constructor.
+
+ int read (ACE_Message_Block &message_block,
+ u_long bytes_to_read,
+ const void *act,
+ int priority);
+ // This starts off an asynchronous read. Upto <bytes_to_read> will
+ // be read and stored in the <message_block>.
+
+ virtual ~ACE_POSIX_SIG_Asynch_Read_Stream (void);
+ // Destructor.
+
+protected:
+ int shared_read (ACE_POSIX_Asynch_Read_Stream_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.
+};
+
+class ACE_Export ACE_POSIX_Asynch_Write_Stream_Result : public virtual ACE_Asynch_Write_Stream_Result_Impl,
+ public ACE_POSIX_Asynch_Result
+{
+ // = TITLE
+ //
+ // This class provides concrete implementation for
+ // ACE_Asynch_Write_Stream::Result on POSIX platforms.
+ //
+ // = DESCRIPTION
+ //
+ // This class has all the information necessary for the
+ // <handler> to uniquiely identify the completion of the
+ // asynchronous write.
+
+ friend class ACE_POSIX_AIOCB_Asynch_Write_Stream;
+ friend class ACE_POSIX_SIG_Asynch_Write_Stream;
+ // Factory classes will have special privilages.
+
+ friend class ACE_POSIX_Proactor;
+ // The Proactor constructs the Result class for faking results.
+
+public:
+ 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:
+ ACE_POSIX_Asynch_Write_Stream_Result (ACE_Handler &handler,
+ ACE_HANDLE handle,
+ ACE_Message_Block &message_block,
+ u_long bytes_to_write,
+ const void* act,
+ ACE_HANDLE event,
+ int priority);
+ // 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);
+ // ACE_Proactor will call this method when the write completes.
+
+ virtual ~ACE_POSIX_Asynch_Write_Stream_Result (void);
+ // Destructor.
+
+protected:
+ // aiocb::aio_nbytes
+ // 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.
+
+ // aiocb::aio_filedes
+ // I/O handle used for writing.
+};
+
+class ACE_Export ACE_POSIX_AIOCB_Asynch_Write_Stream : public virtual ACE_Asynch_Write_Stream_Impl,
+ public ACE_POSIX_AIOCB_Asynch_Operation
+{
+ // = TITLE
+ //
+ // This class implements ACE_Asynch_Write_Stream for AIOCB
+ // (Asynchronous I/O Control Blocks) based implementation of
+ // Proactor.
+ //
+ // = DESCRIPTION
+ //
+public:
+ ACE_POSIX_AIOCB_Asynch_Write_Stream (ACE_POSIX_AIOCB_Proactor *posix_aiocb_proactor);
+ // Constructor.
+
+ int write (ACE_Message_Block &message_block,
+ u_long bytes_to_write,
+ const void *act,
+ int priority);
+ // This starts off an asynchronous write. Upto <bytes_to_write>
+ // will be written from the <message_block>.
+
+ virtual ~ACE_POSIX_AIOCB_Asynch_Write_Stream (void);
+ // Destrcutor.
+
+protected:
+ int shared_write (ACE_POSIX_Asynch_Write_Stream_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.
+};
+
+class ACE_Export ACE_POSIX_SIG_Asynch_Write_Stream : public virtual ACE_Asynch_Write_Stream_Impl,
+ public ACE_POSIX_SIG_Asynch_Operation
+{
+ // = TITLE
+ //
+ // This class implements ACE_Asynch_Write_Stream for Real-Time
+ // Signal (<sigtimedwait>) based implementation of Proactor.
+ //
+ // = DESCRIPTION
+ //
+public:
+ ACE_POSIX_SIG_Asynch_Write_Stream (ACE_POSIX_SIG_Proactor *posix_sig_proactor);
+ // Constrctor.
+
+ int write (ACE_Message_Block &message_block,
+ u_long bytes_to_write,
+ const void *act,
+ int priority);
+ // This starts off an asynchronous write. Upto <bytes_to_write>
+ // will be written from the <message_block>.
+
+ virtual ~ACE_POSIX_SIG_Asynch_Write_Stream (void);
+ // Destructor.
+
+protected:
+ int shared_write (ACE_POSIX_Asynch_Write_Stream_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.
+};
+
+class ACE_Export ACE_POSIX_Asynch_Read_File_Result : public virtual ACE_Asynch_Read_File_Result_Impl,
+ public ACE_POSIX_Asynch_Read_Stream_Result
+{
+ // = TITLE
+ //
+ // This class provides concrete implementation for
+ // ACE_Asynch_Read_File::Result class for POSIX platforms.
+ //
+ // = DESCRIPTION
+ //
+
+ friend class ACE_POSIX_AIOCB_Asynch_Read_File;
+ friend class ACE_POSIX_SIG_Asynch_Read_File;
+ // Factory classes willl have special permissions.
+
+ friend class ACE_POSIX_Proactor;
+ // The Proactor constructs the Result class for faking results.
+
+protected:
+ ACE_POSIX_Asynch_Read_File_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,
+ int priority);
+ // 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);
+ // ACE_Proactor will call this method when the read completes.
+
+ virtual ~ACE_POSIX_Asynch_Read_File_Result (void);
+ // Destructor.
+};
+
+class ACE_Export ACE_POSIX_AIOCB_Asynch_Read_File : public virtual ACE_Asynch_Read_File_Impl,
+ public ACE_POSIX_AIOCB_Asynch_Read_Stream
+{
+ // = TITLE
+ //
+ // This class is a factory for starting off asynchronous reads
+ // on a file. This class implements ACE_Asynch_Read_File for
+ // AIOCB (Asynchronous I/O Control Blocks) based implementation
+ // of Proactor.
+ //
+ // = DESCRIPTION
+ //
+ // Once <open> is called, multiple asynchronous <read>s can
+ // started using this class. A ACE_Asynch_Read_File::Result
+ // will be passed back to the <handler> when the asynchronous
+ // reads completes through the <ACE_Handler::handle_read_file>
+ // callback.
+ //
+ // This class differs slightly from ACE_Asynch_Read_Stream as it
+ // allows the user to specify an offset for the read.
+
+public:
+ ACE_POSIX_AIOCB_Asynch_Read_File (ACE_POSIX_AIOCB_Proactor *posix_aiocb_proactor);
+ // Constructor.
+
+ int read (ACE_Message_Block &message_block,
+ u_long bytes_to_read,
+ u_long offset,
+ u_long offset_high,
+ const void *act,
+ int priority);
+ // This starts off an asynchronous read. Upto <bytes_to_read> will
+ // be read and stored in the <message_block>. The read will start
+ // at <offset> from the beginning of the file.
+
+ virtual ~ACE_POSIX_AIOCB_Asynch_Read_File (void);
+ // Destructor.
+
+private:
+ int read (ACE_Message_Block &message_block,
+ u_long bytes_to_read,
+ const void *act,
+ int priority);
+ // This belongs to ACE_POSIX_AIOCB_Asynch_Read_Stream. We have
+ // defined this here to avoid compiler warnings and forward the
+ // method to <ACE_POSIX_AIOCB_Asynch_Read_Stream::read>.
+};
+
+class ACE_Export ACE_POSIX_SIG_Asynch_Read_File : public virtual ACE_Asynch_Read_File_Impl,
+ public ACE_POSIX_SIG_Asynch_Read_Stream
+{
+ // = TITLE
+ //
+ // This class is a factory for starting off asynchronous reads
+ // on a file. This class implements ACE_Asynch_Operation for
+ // Real-Time Signal (<sigtimedwait>) based implementation of
+ // Proactor.
+ //
+ // = DESCRIPTION
+ //
+ // Once <open> is called, multiple asynchronous <read>s can
+ // started using this class. A ACE_Asynch_Read_File::Result
+ // will be passed back to the <handler> when the asynchronous
+ // reads completes through the <ACE_Handler::handle_read_file>
+ // callback.
+
+public:
+ ACE_POSIX_SIG_Asynch_Read_File (ACE_POSIX_SIG_Proactor *posix_sig_proactor);
+ // Constructor.
+
+ int read (ACE_Message_Block &message_block,
+ u_long bytes_to_read,
+ u_long offset,
+ u_long offset_high,
+ const void *act,
+ int priority);
+ // This starts off an asynchronous read. Upto <bytes_to_read> will
+ // be read and stored in the <message_block>. The read will start
+ // at <offset> from the beginning of the file.
+
+ virtual ~ACE_POSIX_SIG_Asynch_Read_File (void);
+ // Destructor.
+
+private:
+ int read (ACE_Message_Block &message_block,
+ u_long bytes_to_read,
+ const void *act,
+ int priority);
+ // This belongs to ACE_POSIX_SIG_Asynch_Read_Stream. We have
+ // defined this here to avoid compiler warnings and forward the
+ // method to <ACE_POSIX_SIG_Asynch_Read_Stream::read>.
+};
+
+class ACE_Export ACE_POSIX_Asynch_Write_File_Result : public virtual ACE_Asynch_Write_File_Result_Impl,
+ public ACE_POSIX_Asynch_Write_Stream_Result
+{
+ // = TITLE
+ //
+ // This class provides implementation for
+ // ACE_Asynch_Write_File_Result for POSIX platforms.
+ //
+ // = DESCRIPTION
+ //
+ // This class has all the information necessary for the
+ // <handler> to uniquiely identify the completion of the
+ // asynchronous write.
+ //
+ // This class differs slightly from
+ // ACE_Asynch_Write_Stream::Result as it calls back
+ // <ACE_Handler::handle_write_file> on the <handler> instead
+ // of <ACE_Handler::handle_write_stream>. No additional state
+ // is required by this class as ACE_Asynch_Result can store
+ // the <offset>.
+
+ friend class ACE_POSIX_AIOCB_Asynch_Write_File;
+ friend class ACE_POSIX_SIG_Asynch_Write_File;
+ // Factory classes will have special permissions.
+
+ friend class ACE_POSIX_Proactor;
+ // The Proactor constructs the Result class for faking results.
+
+protected:
+ ACE_POSIX_Asynch_Write_File_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,
+ int priority);
+ // 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);
+ // ACE_Proactor will call this method when the write completes.
+
+ virtual ~ACE_POSIX_Asynch_Write_File_Result (void);
+ // Destructor.
+};
+
+class ACE_Export ACE_POSIX_AIOCB_Asynch_Write_File : public virtual ACE_Asynch_Write_File_Impl,
+ public ACE_POSIX_AIOCB_Asynch_Write_Stream
+{
+ // = TITLE
+ //
+ // This class provides concrete implementation for
+ // ACE_Asynch_Write_File for POSIX platforms where the
+ // completion strategy for Proactor is based on AIOCB (AIO
+ // Control Blocks).
+ //
+ // = DESCRIPTION
+ //
+public:
+ ACE_POSIX_AIOCB_Asynch_Write_File (ACE_POSIX_AIOCB_Proactor *posix_aiocb_proactor);
+ // Constructor.
+
+ int write (ACE_Message_Block &message_block,
+ u_long bytes_to_write,
+ u_long offset,
+ u_long offset_high,
+ const void *act,
+ int priority);
+ // This starts off an asynchronous write. Upto <bytes_to_write>
+ // will be write and stored in the <message_block>. The write will
+ // start at <offset> from the beginning of the file.
+
+ virtual ~ACE_POSIX_AIOCB_Asynch_Write_File (void);
+ // Destructor.
+
+private:
+ int write (ACE_Message_Block &message_block,
+ u_long bytes_to_write,
+ const void *act,
+ int priority);
+ // This <write> belongs to ACE_POSIX_SIG_Asynch_Write_Stream. We
+ // have put this here to avoid compiler warnings. We forward this
+ // method call to the <ACE_POSIX_SIG_Asynch_Write_Stream::write>
+ // one.
+};
+
+class ACE_Export ACE_POSIX_SIG_Asynch_Write_File : public virtual ACE_Asynch_Write_File_Impl,
+ public ACE_POSIX_SIG_Asynch_Write_Stream
+{
+ // = TITLE
+ //
+ // This class is a factory for starting off asynchronous reads
+ // on a file. This class implements ACE_Asynch_Operation for
+ // Real-Time Signal (<sigtimedwait>) based implementation of
+ // Proactor.
+ //
+ // = DESCRIPTION
+ //
+ // Once <open> is called, multiple asynchronous <read>s can
+ // started using this class. A ACE_Asynch_Read_File::Result
+ // will be passed back to the <handler> when the asynchronous
+ // reads completes through the <ACE_Handler::handle_read_file>
+ // callback.
+
+public:
+ ACE_POSIX_SIG_Asynch_Write_File (ACE_POSIX_SIG_Proactor *posix_sig_proactor);
+ // Constructor.
+
+ int write (ACE_Message_Block &message_block,
+ u_long bytes_to_write,
+ u_long offset,
+ u_long offset_high,
+ const void *act,
+ int priority);
+ // This starts off an asynchronous write. Upto <bytes_to_write>
+ // will be write and stored in the <message_block>. The write will
+ // start at <offset> from the beginning of the file.
+
+ virtual ~ACE_POSIX_SIG_Asynch_Write_File (void);
+ // Destrcutor.
+
+private:
+ int write (ACE_Message_Block &message_block,
+ u_long bytes_to_write,
+ const void *act,
+ int priority);
+ // This <write> belongs to ACE_POSIX_SIG_Asynch_Write_Stream. We
+ // have put this here to avoid compiler warnings. We forward this
+ // method call to the <ACE_POSIX_SIG_Asynch_Write_Stream::write>
+ // one.
+};
+
+class ACE_Export ACE_POSIX_Asynch_Accept_Result : public virtual ACE_Asynch_Accept_Result_Impl,
+ public ACE_POSIX_Asynch_Result
+{
+ // = TITLE
+ //
+ // This is that class which will be passed back to the
+ // <handler> when the asynchronous accept completes.
+ //
+ // = DESCRIPTION
+ //
+ // This class has all the information necessary for the
+ // <handler> to uniquiely identify the completion of the
+ // asynchronous accept.
+
+ friend class ACE_POSIX_AIOCB_Asynch_Accept;
+ friend class ACE_POSIX_SIG_Asynch_Accept;
+ // Factory classes willl have special permissions.
+
+ friend class ACE_POSIX_Proactor;
+ // The Proactor constructs the Result class for faking results.
+
+public:
+ 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:
+ ACE_POSIX_Asynch_Accept_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,
+ int priority);
+ // 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);
+ // ACE_Proactor will call this method when the accept completes.
+
+ virtual ~ACE_POSIX_Asynch_Accept_Result (void);
+ // Destructor.
+
+ // aiocb::aio_nbytes
+ // Bytes requested when the asynchronous read was initiated.
+ // Actually, on POSIX implementation, we dont read any intial data.
+
+ ACE_Message_Block &message_block_;
+ // Message block for reading the data into.
+
+ ACE_HANDLE listen_handle_;
+ // I/O handle used for accepting new connections.
+
+ // aiocb::aio_filedes
+ // I/O handle for the new connection.
+};
+
+class ACE_POSIX_AIOCB_Asynch_Accept_Handler;
+// Forward declaration. This class is defined the in the cpp file,
+// since this is internal to the implementation.
+
+class ACE_Export ACE_POSIX_AIOCB_Asynch_Accept : public virtual ACE_Asynch_Accept_Impl,
+ public ACE_POSIX_AIOCB_Asynch_Operation
+{
+public:
+ ACE_POSIX_AIOCB_Asynch_Accept (ACE_POSIX_AIOCB_Proactor *posix_aiocb_proactor);
+ // Constructor.
+
+ int open (ACE_Handler &handler,
+ ACE_HANDLE handle,
+ const void *completion_key,
+ ACE_Proactor *proactor);
+ // This <open> belongs to ACE_AIOCB_Asynch_Operation. We forward
+ // this call to that method. We have put this here to avoid the
+ // compiler warnings.
+
+ int accept (ACE_Message_Block &message_block,
+ u_long bytes_to_read,
+ ACE_HANDLE accept_handle,
+ const void *act,
+ int priority);
+ // This starts off an asynchronous accept. The asynchronous accept
+ // call also allows any initial data to be returned to the
+ // <handler>. Upto <bytes_to_read> will be read and stored in the
+ // <message_block>. The <accept_handle> will be used for the
+ // <accept> call. If (<accept_handle> == INVALID_HANDLE), a new
+ // handle will be created.
+ //
+ // <message_block> must be specified. This is because the address of
+ // the new connection is placed at the end of this buffer.
+
+ virtual ~ACE_POSIX_AIOCB_Asynch_Accept (void);
+ // Destructor.
+
+private:
+ static void* thread_function (void* reactor);
+ // The thread function that does handle events.
+
+ ACE_Reactor reactor_;
+ // Reactor to wait on the <listen_handle>.
+
+ ACE_POSIX_AIOCB_Asynch_Accept_Handler* accept_handler_;
+ // The Event Handler to do handle_input.
+};
+
+class ACE_POSIX_SIG_Asynch_Accept_Handler;
+// Forward declaration. This class is defined the in the cpp file,
+// since this is internal to the implementation.
+
+class ACE_Export ACE_POSIX_SIG_Asynch_Accept : public virtual ACE_Asynch_Accept_Impl,
+ public ACE_POSIX_SIG_Asynch_Operation
+{
+ // = TITLE
+ //
+ // This class implements ACE_Asynch_Accept for Real-Time
+ // Signal (<sigtimedwait>) based implementation of Proactor.
+ //
+ // = DESCRIPTION
+ //
+public:
+ ACE_POSIX_SIG_Asynch_Accept (ACE_POSIX_SIG_Proactor *posix_sig_proactor);
+ // Constructor.
+
+ int open (ACE_Handler &handler,
+ ACE_HANDLE handle,
+ const void *completion_key,
+ ACE_Proactor *proactor);
+ // This <open> belongs to ACE_SIG_Asynch_Operation. We forward this
+ // call to that method. We have put this here to avoid the compiler
+ // warnings.
+
+ int accept (ACE_Message_Block &message_block,
+ u_long bytes_to_read,
+ ACE_HANDLE accept_handle,
+ const void *act,
+ int priority);
+ // This starts off an asynchronous accept. The asynchronous accept
+ // call also allows any initial data to be returned to the
+ // <handler>. Upto <bytes_to_read> will be read and stored in the
+ // <message_block>. The <accept_handle> will be used for the
+ // <accept> call. If (<accept_handle> == INVALID_HANDLE), a new
+ // handle will be created.
+ //
+ // <message_block> must be specified. This is because the address of
+ // the new connection is placed at the end of this buffer.
+
+ virtual ~ACE_POSIX_SIG_Asynch_Accept (void);
+ // Destructor.
+
+private:
+ static void* thread_function (void* reactor);
+ // The thread function that does handle events.
+
+ ACE_Reactor reactor_;
+ // Reactor to wait on the <listen_handle>.
+
+ ACE_POSIX_SIG_Asynch_Accept_Handler* accept_handler_;
+ // The Event Handler to do handle_input.
+};
+
+class ACE_Export ACE_POSIX_Asynch_Transmit_File_Result : public virtual ACE_Asynch_Transmit_File_Result_Impl,
+ public ACE_POSIX_Asynch_Result
+{
+ // = TITLE
+ //
+ // This is that class which will be passed back to the
+ // <handler> when the asynchronous transmit file completes.
+ //
+ // = DESCRIPTION
+ //
+ // This class has all the information necessary for the
+ // <handler> to uniquiely identify the completion of the
+ // asynchronous transmit file.
+
+ friend class ACE_POSIX_AIOCB_Asynch_Transmit_File;
+ friend class ACE_POSIX_SIG_Asynch_Transmit_File;
+ // Factory classes willl have special permissions.
+
+ friend class ACE_POSIX_Asynch_Transmit_Handler;
+ friend class ACE_POSIX_AIOCB_Asynch_Transmit_Handler;
+ friend class ACE_POSIX_SIG_Asynch_Transmit_Handler;
+ // Handlers do all the job.
+
+ friend class ACE_POSIX_Proactor;
+ // The Proactor constructs the Result class for faking results.
+
+public:
+ ACE_HANDLE socket (void) const;
+ // Socket used for transmitting the file.
+
+ ACE_HANDLE file (void) const;
+ // File from which the data is read.
+
+ ACE_Asynch_Transmit_File::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:
+ ACE_POSIX_Asynch_Transmit_File_Result (ACE_Handler &handler,
+ ACE_HANDLE socket,
+ ACE_HANDLE file,
+ ACE_Asynch_Transmit_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,
+ int priority);
+ // 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);
+ // ACE_Proactor will call this method when the write completes.
+
+ virtual ~ACE_POSIX_Asynch_Transmit_File_Result (void);
+ // Destructor.
+
+ ACE_HANDLE socket_;
+ // Network I/O handle.
+
+ // aiocb::aio_filedes
+ // File I/O handle.
+
+ ACE_Asynch_Transmit_File::Header_And_Trailer *header_and_trailer_;
+ // Header and trailer data associated with this transmit file.
+
+ // aiocb::aio_nbytes
+ // 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 ACE_POSIX_AIOCB_Asynch_Transmit_File : public virtual ACE_Asynch_Transmit_File_Impl,
+ public ACE_POSIX_AIOCB_Asynch_Operation
+{
+ // = DESCRIPTION
+ // Implementation for transmit_file will make use of
+ // POSIX_AIOCB_Asynch_Transmit_Handler.
+public:
+ ACE_POSIX_AIOCB_Asynch_Transmit_File (ACE_POSIX_AIOCB_Proactor *posix_aiocb_proactor);
+ // Constructor.
+
+ int transmit_file (ACE_HANDLE file,
+ ACE_Asynch_Transmit_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,
+ int priority);
+ // This starts off an asynchronous transmit file. The <file> is a
+ // handle to an open file. <header_and_trailer> 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 <bytes_to_write> will be
+ // written to the <socket>. If you want to send the entire file,
+ // let <bytes_to_write> = 0. <bytes_per_send> is the size of each
+ // block of data sent per send operation. Please read the Win32
+ // documentation on what the flags should be.
+
+ virtual ~ACE_POSIX_AIOCB_Asynch_Transmit_File (void);
+ // Destructor.
+};
+
+class ACE_Export ACE_POSIX_SIG_Asynch_Transmit_File : public virtual ACE_Asynch_Transmit_File_Impl,
+ public ACE_POSIX_SIG_Asynch_Operation
+{
+ // = TITLE
+ //
+ // This class implements ACE_Asynch_Transmit_File for Real-Time
+ // Signal (<sigtimedwait>) based implementation of Proactor.
+ //
+ // = DESCRIPTION
+ //
+public:
+ ACE_POSIX_SIG_Asynch_Transmit_File (ACE_POSIX_SIG_Proactor *posix_sig_proactor);
+ // Constructor.
+
+ int transmit_file (ACE_HANDLE file,
+ ACE_Asynch_Transmit_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,
+ int priority);
+ // This starts off an asynchronous transmit file. The <file> is a
+ // handle to an open file. <header_and_trailer> 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 <bytes_to_write> will be
+ // written to the <socket>. If you want to send the entire file,
+ // let <bytes_to_write> = 0. <bytes_per_send> is the size of each
+ // block of data sent per send operation.
+
+ virtual ~ACE_POSIX_SIG_Asynch_Transmit_File (void);
+ // Destructor.
+};
+
+#if defined (__ACE_INLINE__)
+#include "ace/POSIX_Asynch_IO.i"
+#endif /* __ACE_INLINE__ */
+
+#endif /* ACE_HAS_AIO_CALLS */
+#endif /* ACE_POSIX_ASYNCH_IO_H */
diff --git a/ace/POSIX_Proactor.cpp b/ace/POSIX_Proactor.cpp
new file mode 100644
index 00000000000..05bac013d1c
--- /dev/null
+++ b/ace/POSIX_Proactor.cpp
@@ -0,0 +1,1138 @@
+// $Id$
+
+#define ACE_BUILD_DLL
+#include "ace/POSIX_Proactor.h"
+
+#if defined (ACE_HAS_AIO_CALLS)
+
+#include "ace/Task_T.h"
+#include "ace/Log_Msg.h"
+#include "ace/Object_Manager.h"
+
+#if !defined (__ACE_INLINE__)
+#include "ace/POSIX_Proactor.i"
+#endif /* __ACE_INLINE__ */
+
+ACE_POSIX_Proactor::~ACE_POSIX_Proactor (void)
+{
+}
+
+int
+ACE_POSIX_Proactor::close (void)
+{
+#if 0
+ // Take care of the timer handler
+ if (this->timer_handler_)
+ {
+ delete this->timer_handler_;
+ this->timer_handler_ = 0;
+ }
+
+ // Take care of the timer queue
+ if (this->delete_timer_queue_)
+ {
+ delete this->timer_queue_;
+ this->timer_queue_ = 0;
+ this->delete_timer_queue_ = 0;
+ }
+#endif /* 0 */
+ return 0;
+}
+
+int
+ACE_POSIX_Proactor::register_handle (ACE_HANDLE handle,
+ const void *completion_key)
+{
+ ACE_UNUSED_ARG (handle);
+ ACE_UNUSED_ARG (completion_key);
+ return 0;
+}
+
+long
+ACE_POSIX_Proactor::schedule_timer (ACE_Handler &handler,
+ const void *act,
+ const ACE_Time_Value &time)
+{
+ return this->schedule_timer (handler,
+ act,
+ time,
+ ACE_Time_Value::zero);
+}
+
+long
+ACE_POSIX_Proactor::schedule_repeating_timer (ACE_Handler &handler,
+ const void *act,
+ const ACE_Time_Value &interval)
+{
+ return this->schedule_timer (handler,
+ act,
+ interval,
+ interval);
+}
+
+long
+ACE_POSIX_Proactor::schedule_timer (ACE_Handler &handler,
+ const void *act,
+ const ACE_Time_Value &time,
+ const ACE_Time_Value &interval)
+{
+ ACE_UNUSED_ARG (handler);
+ ACE_UNUSED_ARG (act);
+ ACE_UNUSED_ARG (time);
+ ACE_UNUSED_ARG (interval);
+ ACE_NOTSUP_RETURN ((long) -1);
+
+#if 0
+ // absolute time.
+ ACE_Time_Value absolute_time =
+ this->timer_queue_->gettimeofday () + time;
+
+ // Only one guy goes in here at a time
+ ACE_GUARD_RETURN (ACE_Recursive_Thread_Mutex, ace_mon, this->timer_queue_->mutex (), -1);
+
+ // Schedule the timer
+ long result = this->timer_queue_->schedule (&handler,
+ act,
+ absolute_time,
+ interval);
+ if (result != -1)
+ {
+ // no failures: check to see if we are the earliest time
+ if (this->timer_queue_->earliest_time () == absolute_time)
+
+ // wake up the timer thread
+ if (this->timer_handler_->timer_event_.signal () == -1)
+ {
+ // Cancel timer
+ this->timer_queue_->cancel (result);
+ result = -1;
+ }
+ }
+ return result;
+#endif /* 0 */
+}
+
+int
+ACE_POSIX_Proactor::cancel_timer (long timer_id,
+ const void **arg,
+ int dont_call_handle_close)
+{
+ ACE_NOTSUP_RETURN (-1);
+#if 0
+ // No need to singal timer event here. Even if the cancel timer was
+ // the earliest, we will have an extra wakeup.
+ return this->timer_queue_->cancel (timer_id,
+ arg,
+ dont_call_handle_close);
+#endif /* 0 */
+}
+
+int
+ACE_POSIX_Proactor::cancel_timer (ACE_Handler &handler,
+ int dont_call_handle_close)
+{
+ ACE_NOTSUP_RETURN (-1);
+#if 0
+ // No need to signal timer event here. Even if the cancel timer was
+ // the earliest, we will have an extra wakeup.
+ return this->timer_queue_->cancel (&handler,
+ dont_call_handle_close);
+#endif /* 0 */
+}
+
+int
+ACE_POSIX_Proactor::post_completion (ACE_POSIX_Asynch_Result *result)
+{
+ ACE_UNUSED_ARG (result);
+ return 0;
+}
+
+#if 0
+int
+ACE_POSIX_Proactor::handle_signal (int, siginfo_t *, ucontext_t *)
+{
+ // Perform a non-blocking "poll" for all the I/O events that have
+ // completed in the I/O completion queue.
+
+ ACE_Time_Value timeout (0, 0);
+ int result = 0;
+
+ while (1)
+ {
+ result = this->handle_events (timeout);
+ if (result != 0 || errno == ETIME)
+ break;
+ }
+
+ // If our handle_events failed, we'll report a failure to the
+ // Reactor.
+ return result == -1 ? -1 : 0;
+}
+
+int
+ACE_POSIX_Proactor::handle_close (ACE_HANDLE handle,
+ ACE_Reactor_Mask close_mask)
+{
+ ACE_UNUSED_ARG (close_mask);
+ ACE_UNUSED_ARG (handle);
+
+ return this->close ();
+}
+#endif /* 0 */
+
+ACE_HANDLE
+ACE_POSIX_Proactor::get_handle (void) const
+{
+ // @@ Implement this.
+ return ACE_INVALID_HANDLE;
+}
+
+ACE_Asynch_Read_Stream_Result_Impl *
+ACE_POSIX_Proactor::create_asynch_read_stream_result (ACE_Handler &handler,
+ ACE_HANDLE handle,
+ ACE_Message_Block &message_block,
+ u_long bytes_to_read,
+ const void* act,
+ ACE_HANDLE event,
+ int priority)
+{
+ ACE_Asynch_Read_Stream_Result_Impl *implementation;
+ ACE_NEW_RETURN (implementation,
+ ACE_POSIX_Asynch_Read_Stream_Result (handler,
+ handle,
+ message_block,
+ bytes_to_read,
+ act,
+ event,
+ priority),
+ 0);
+ return implementation;
+}
+
+ACE_Asynch_Write_Stream_Result_Impl *
+ACE_POSIX_Proactor::create_asynch_write_stream_result (ACE_Handler &handler,
+ ACE_HANDLE handle,
+ ACE_Message_Block &message_block,
+ u_long bytes_to_write,
+ const void* act,
+ ACE_HANDLE event,
+ int priority)
+{
+ ACE_Asynch_Write_Stream_Result_Impl *implementation;
+ ACE_NEW_RETURN (implementation,
+ ACE_POSIX_Asynch_Write_Stream_Result (handler,
+ handle,
+ message_block,
+ bytes_to_write,
+ act,
+ event,
+ priority),
+ 0);
+ return implementation;
+}
+
+ACE_Asynch_Read_File_Result_Impl *
+ACE_POSIX_Proactor::create_asynch_read_file_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,
+ int priority)
+{
+ ACE_Asynch_Read_File_Result_Impl *implementation;
+ ACE_NEW_RETURN (implementation,
+ ACE_POSIX_Asynch_Read_File_Result (handler,
+ handle,
+ message_block,
+ bytes_to_read,
+ act,
+ offset,
+ offset_high,
+ event,
+ priority),
+ 0);
+ return implementation;
+}
+
+ACE_Asynch_Write_File_Result_Impl *
+ACE_POSIX_Proactor::create_asynch_write_file_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,
+ int priority)
+{
+ ACE_Asynch_Write_File_Result_Impl *implementation;
+ ACE_NEW_RETURN (implementation,
+ ACE_POSIX_Asynch_Write_File_Result (handler,
+ handle,
+ message_block,
+ bytes_to_write,
+ act,
+ offset,
+ offset_high,
+ event,
+ priority),
+ 0);
+ return implementation;
+}
+
+ACE_Asynch_Accept_Result_Impl *
+ACE_POSIX_Proactor::create_asynch_accept_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,
+ int priority)
+{
+ ACE_Asynch_Accept_Result_Impl *implementation;
+ ACE_NEW_RETURN (implementation,
+ ACE_POSIX_Asynch_Accept_Result (handler,
+ listen_handle,
+ accept_handle,
+ message_block,
+ bytes_to_read,
+ act,
+ event,
+ priority),
+ 0);
+ return implementation;
+}
+
+ACE_Asynch_Transmit_File_Result_Impl *
+ACE_POSIX_Proactor::create_asynch_transmit_file_result (ACE_Handler &handler,
+ ACE_HANDLE socket,
+ ACE_HANDLE file,
+ ACE_Asynch_Transmit_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,
+ int priority)
+{
+ ACE_Asynch_Transmit_File_Result_Impl *implementation;
+ ACE_NEW_RETURN (implementation,
+ ACE_POSIX_Asynch_Transmit_File_Result (handler,
+ socket,
+ file,
+ header_and_trailer,
+ bytes_to_write,
+ offset,
+ offset_high,
+ bytes_per_send,
+ flags,
+ act,
+ event,
+ priority),
+ 0);
+ return implementation;
+}
+
+ACE_POSIX_Proactor::ACE_POSIX_Proactor (void)
+{
+}
+
+void
+ACE_POSIX_Proactor::application_specific_code (ACE_POSIX_Asynch_Result *asynch_result,
+ u_long bytes_transferred,
+ int success,
+ const void *completion_key,
+ u_long error)
+{
+ ACE_SEH_TRY
+ {
+ // Call completion hook
+ asynch_result->complete (bytes_transferred,
+ success,
+ (void *) completion_key,
+ error);
+ }
+ ACE_SEH_FINALLY
+ {
+ // This is crucial to prevent memory leaks
+ delete asynch_result;
+ }
+}
+
+
+
+int
+ACE_POSIX_Proactor::wake_up_dispatch_threads (void)
+{
+ return 0;
+}
+
+int
+ACE_POSIX_Proactor::close_dispatch_threads (int)
+{
+ return 0;
+}
+
+size_t
+ACE_POSIX_Proactor::number_of_threads (void) const
+{
+ // @@ Implement it.
+ return 0;
+}
+
+void
+ACE_POSIX_Proactor::number_of_threads (size_t threads)
+{
+ // @@ Implement it.
+ ACE_UNUSED_ARG (threads);
+}
+
+#if 0
+ACE_Proactor::Timer_Queue *
+ACE_POSIX_Proactor::timer_queue (void) const
+{
+ return this->timer_queue_;
+}
+
+void
+ACE_POSIX_Proactor::timer_queue (Timer_Queue *tq)
+{
+ // cleanup old timer queue
+ if (this->delete_timer_queue_)
+ {
+ delete this->timer_queue_;
+ this->delete_timer_queue_ = 0;
+ }
+
+ // new timer queue
+ if (tq == 0)
+ {
+ this->timer_queue_ = new Timer_Heap;
+ this->delete_timer_queue_ = 1;
+ }
+ else
+ {
+ this->timer_queue_ = tq;
+ this->delete_timer_queue_ = 0;
+ }
+
+ // Set the proactor in the timer queue's functor
+ this->timer_queue_->upcall_functor ().proactor (*this);
+}
+#endif /* 0 */
+
+// *********************************************************************
+
+class ACE_Export ACE_AIO_Accept_Handler : public ACE_Handler
+{
+ // = TITLE
+ // Helper class for doing Asynch_Accept in POSIX4 systems, in
+ // the case of doing AIO_CONTROL_BLOCKS strategy.
+ //
+ // = DESCRIPTION
+ // Doing Asynch_Accept in POSIX4 implementation is tricky. In
+ // the case of doing the things with AIO_CONTROL_BLOCKS and not
+ // with Real-Time Signals, this becomes even more trickier. We
+ // use a notifyn pipe here to implement Asynch_Accpet. This class
+ // will issue a <Asynch_Read> on the pipe. <Asynch_Accept> will
+ // send a result pointer containg all the information through
+ // this pipe.
+ // Handling the MessageBlock:
+ // We give this message block to read the result pointer through
+ // the notify pipe. We expect that to read 4 bytes from the
+ // notify pipe, for each <accept> call. Before giving this
+ // message block to another <accept>, we update <wr_ptr> and put
+ // it in its initial position.
+public:
+ ACE_AIO_Accept_Handler (ACE_POSIX_AIOCB_Proactor *posix_aiocb_proactor);
+ // Constructor. You need the posix proactor because you need to call
+ // things like application_specific_code etc. Having the main
+ // proactor is good so that life is easier when we use Asynch_Read,
+ // while issuing asynchronous read on the notify pipe.
+
+ virtual ~ACE_AIO_Accept_Handler (void);
+ // Destructor.
+
+#if 0
+ void proactor (ACE_Proactor *proactor);
+ // Set the Proactor pointer. POSIX_AIOCB_Proactor may not have the
+ // Proactor pointer when it creates this object and so we have this
+ // method so that it can set it when it gets it.
+#endif /* 0 */
+
+ int notify (ACE_POSIX_Asynch_Accept_Result *result);
+ // Send this Result to Proactor through the notification pipe.
+
+ virtual void handle_read_stream (const ACE_Asynch_Read_Stream::Result &result);
+ // Read from the pipe is complete. We get the <Result> from
+ // Asynch_Handler. We have to do the notification here.
+
+private:
+#if 0
+ ACE_Proactor *proactor_;
+ // The main proactor interface.
+#endif /* 0 */
+
+ ACE_POSIX_AIOCB_Proactor *posix_aiocb_proactor_;
+ // The implementation proactor class.
+
+ ACE_Message_Block message_block_;
+ // Message block to get ACE_Asynch_Accept::Result pointer from
+ // ACE_Asych_Accept.
+
+ ACE_Pipe pipe_;
+ // Pipe for the communication between Proactor and the
+ // Asynch_Accept.
+
+ ACE_POSIX_AIOCB_Asynch_Read_Stream read_stream_;
+ // To do asynch_read on the pipe.
+
+ ACE_AIO_Accept_Handler (void);
+ // Default constructor. Shouldnt be called.
+};
+
+ACE_AIO_Accept_Handler::ACE_AIO_Accept_Handler (ACE_POSIX_AIOCB_Proactor *posix_aiocb_proactor)
+ : posix_aiocb_proactor_ (posix_aiocb_proactor),
+ message_block_ (sizeof (ACE_POSIX_Asynch_Accept_Result *)),
+ read_stream_ (posix_aiocb_proactor)
+{
+ // Open the pipe.
+ this->pipe_.open ();
+
+ // Open the read stream.
+ if (this->read_stream_.open (*this,
+ this->pipe_.read_handle (),
+ 0, // Completion Key
+ 0) // Proactor
+ == -1)
+ ACE_ERROR ((LM_ERROR,
+ "%N:%l:%p\n",
+ "Open on Read Stream failed"));
+
+ // Issue an asynch_read on the read_stream of the notify pipe.
+ if (this->read_stream_.read (this->message_block_,
+ sizeof (ACE_POSIX_Asynch_Accept_Result *),
+ 0, // ACT
+ 0) // Priority
+ == -1)
+ ACE_ERROR ((LM_ERROR,
+ "%N:%l:%p\n",
+ "Read from stream failed"));
+}
+
+ACE_AIO_Accept_Handler::~ACE_AIO_Accept_Handler (void)
+{
+}
+
+int
+ACE_AIO_Accept_Handler::notify (ACE_POSIX_Asynch_Accept_Result *result)
+{
+ // Send the result pointer through the pipe.
+ int return_val = ACE::send (this->pipe_.write_handle (),
+ (char *) &result,
+ sizeof (result));
+ if (return_val != sizeof (result))
+ ACE_ERROR_RETURN ((LM_ERROR,
+ "(%P %t):%p\n",
+ "Error:Writing on to pipe failed"),
+ -1);
+ return 0;
+}
+
+void
+ACE_AIO_Accept_Handler::handle_read_stream (const ACE_Asynch_Read_Stream::Result &result)
+{
+ // @@
+ ACE_DEBUG ((LM_DEBUG, "ACE_AIO_Accept_Handler::handle_read_stream called\n"));
+
+ // The message block actually contains the ACE_POSIX_Asynch_Accept_Result
+ // pointer.
+ ACE_POSIX_Asynch_Accept_Result *accept_result = 0;
+ accept_result = *(ACE_POSIX_Asynch_Accept_Result **) result.message_block ().rd_ptr ();
+
+ // Do the upcall.
+ this->posix_aiocb_proactor_->application_specific_code (accept_result,
+ 0, // No Bytes transferred.
+ 1, // Success.
+ 0, // Completion token.
+ 0); // Error.
+
+ // Set the message block properly. Put the <wr_ptr> back in the
+ // initial position.
+ if (this->message_block_.length () > 0)
+ this->message_block_.wr_ptr (this->message_block_.rd_ptr ());
+
+ // One accept has completed. Issue a read to handle any <accept>s in
+ // the future.
+ if (this->read_stream_.read (this->message_block_,
+ sizeof (ACE_POSIX_Asynch_Accept_Result),
+ 0, // ACT
+ 0) // Priority
+ == -1)
+ ACE_ERROR ((LM_ERROR,
+ "%N:%l:%p\n",
+ "Read from stream failed"));
+}
+
+// *********************************************************************
+
+ACE_POSIX_AIOCB_Proactor::ACE_POSIX_AIOCB_Proactor (void)
+ : aio_accept_handler_ (0),
+ aiocb_list_max_size_ (ACE_RTSIG_MAX),
+ aiocb_list_cur_size_ (0)
+{
+ // Initialize the array.
+ for (size_t ai = 0; ai < this->aiocb_list_max_size_; ai++)
+ aiocb_list_[ai] = 0;
+
+ // Accept Handler for aio_accept. Remember! this issues a Asynch_Read
+ // on the notify pipe for doing the Asynch_Accept.
+ ACE_NEW (aio_accept_handler_,
+ ACE_AIO_Accept_Handler (this));
+}
+
+// Destructor.
+ACE_POSIX_AIOCB_Proactor::~ACE_POSIX_AIOCB_Proactor (void)
+{
+}
+
+int
+ACE_POSIX_AIOCB_Proactor::handle_events (ACE_Time_Value &wait_time)
+{
+ // Decrement <wait_time> with the amount of time spent in the method
+ ACE_Countdown_Time countdown (&wait_time);
+ return this->handle_events (wait_time.msec ());
+}
+
+int
+ACE_POSIX_AIOCB_Proactor::handle_events (void)
+{
+ return this->handle_events (ACE_INFINITE);
+}
+
+ACE_Asynch_Read_Stream_Impl *
+ACE_POSIX_AIOCB_Proactor::create_asynch_read_stream (void)
+{
+ ACE_Asynch_Read_Stream_Impl *implementation = 0;
+ ACE_NEW_RETURN (implementation,
+ ACE_POSIX_AIOCB_Asynch_Read_Stream (this),
+ 0);
+ return implementation;
+}
+
+ACE_Asynch_Write_Stream_Impl *
+ACE_POSIX_AIOCB_Proactor::create_asynch_write_stream (void)
+{
+ ACE_Asynch_Write_Stream_Impl *implementation = 0;
+ ACE_NEW_RETURN (implementation,
+ ACE_POSIX_AIOCB_Asynch_Write_Stream (this),
+ 0);
+ return implementation;
+}
+
+ACE_Asynch_Read_File_Impl *
+ACE_POSIX_AIOCB_Proactor::create_asynch_read_file (void)
+{
+ ACE_Asynch_Read_File_Impl *implementation = 0;
+ ACE_NEW_RETURN (implementation,
+ ACE_POSIX_AIOCB_Asynch_Read_File (this),
+ 0);
+ return implementation;
+}
+
+ACE_Asynch_Write_File_Impl *
+ACE_POSIX_AIOCB_Proactor::create_asynch_write_file (void)
+{
+ ACE_Asynch_Write_File_Impl *implementation = 0;
+ ACE_NEW_RETURN (implementation,
+ ACE_POSIX_AIOCB_Asynch_Write_File (this),
+ 0);
+ return implementation;
+}
+
+ACE_Asynch_Accept_Impl *
+ACE_POSIX_AIOCB_Proactor::create_asynch_accept (void)
+{
+ ACE_Asynch_Accept_Impl *implementation = 0;
+ ACE_NEW_RETURN (implementation,
+ ACE_POSIX_AIOCB_Asynch_Accept (this),
+ 0);
+ return implementation;
+}
+
+ACE_Asynch_Transmit_File_Impl *
+ACE_POSIX_AIOCB_Proactor::create_asynch_transmit_file (void)
+{
+ ACE_Asynch_Transmit_File_Impl *implementation = 0;
+ ACE_NEW_RETURN (implementation,
+ ACE_POSIX_AIOCB_Asynch_Transmit_File (this),
+ 0);
+ return implementation;
+}
+
+int
+ACE_POSIX_AIOCB_Proactor::notify_asynch_accept (ACE_POSIX_Asynch_Accept_Result* result)
+{
+ this->aio_accept_handler_->notify (result);
+
+ return 0;
+}
+
+int
+ACE_POSIX_AIOCB_Proactor::handle_events (unsigned long milli_seconds)
+{
+ if (this->aiocb_list_cur_size_ == 0)
+ // No aio is pending.
+ return 0;
+
+ // Wait for asynch operation to complete.
+ // @@ Assing milli seconds correctly.
+ timespec timeout;
+ timeout.tv_sec = milli_seconds;
+ timeout.tv_nsec = 0;
+
+ if (aio_suspend (this->aiocb_list_,
+ this->aiocb_list_max_size_,
+ &timeout) == -1)
+ {
+ // If failure is coz of timeout, then return *0* but set errno
+ // appropriately. This is what the WinNT proactor does.
+ if (errno == EAGAIN)
+ ACE_ERROR_RETURN ((LM_ERROR,
+ "Error:%p\n",
+ "aio_suspend"),
+ 0);
+ else
+ ACE_ERROR_RETURN ((LM_ERROR,
+ "Error:%p\n",
+ "aio_suspend"),
+ -1);
+ }
+
+ // Check which aio has finished.
+ size_t ai;
+ int error_status = 0;
+ int return_status = 0;
+ for (ai = 0; ai < this->aiocb_list_max_size_; ai++)
+ {
+ if (aiocb_list_ [ai] == 0)
+ continue;
+
+ // Analyze error and return values.
+
+ // Get the error status of the aio_ operation.
+ error_status = aio_error (aiocb_list_[ai]);
+ if (error_status == -1)
+ // <aio_error> itself has failed.
+ ACE_ERROR_RETURN ((LM_ERROR,
+ "Error:%p\n",
+ "<aio_error> has failed"),
+ -1);
+
+ if (error_status == EINPROGRESS)
+ // <aio_> operation is still in progress.
+ continue;
+
+ // Error_status is not -1 and not EINPROGRESS. So, an <aio_>
+ // operation has finished (successfully or unsuccessfully!!!)
+
+ ACE_ERROR ((LM_ERROR,
+ "%N:%l:error_status = %d\n",
+ error_status));
+
+ // Get the return_status of the <aio_> operation.
+ return_status = aio_return (aiocb_list_[ai]);
+ if (return_status == -1)
+ {
+ // <aio_return> itself has failed.
+ ACE_ERROR_RETURN ((LM_ERROR,
+ "Error:%p\n",
+ "<aio_return> failed"),
+ -1);
+ }
+ else
+ {
+ ACE_DEBUG ((LM_DEBUG, "An aio has finished\n"));
+ break;
+ }
+ }
+
+ if (ai == this->aiocb_list_max_size_)
+ // Nothing completed.
+ return 0;
+
+ // Retrive the result pointer.
+ ACE_POSIX_Asynch_Result *asynch_result =
+ // dynamic_cast <ACE_POSIX_Asynch_Result *> (this->aiocb_list_[ai]);
+ (ACE_POSIX_Asynch_Result *) (this->aiocb_list_[ai]);
+ if (asynch_result == 0)
+ ACE_ERROR_RETURN ((LM_ERROR,
+ "Error:%N:%l:%p\n",
+ "Dynamic cast failed"),
+ -1);
+
+ // Invalidate entry in the aiocb list.
+ this->aiocb_list_[ai] = 0;
+ this->aiocb_list_cur_size_--;
+
+ // Call the application code.
+ // @@ Pass <errno> instead of 0. Check out on LynxOS. It is set
+ // to 77 somewhere.
+ this->application_specific_code (asynch_result,
+ return_status, // Bytes transferred.
+ 1, // Success
+ 0, // No completion key.
+ error_status); // Error
+
+ return 0;
+}
+
+void
+ACE_POSIX_AIOCB_Proactor::application_specific_code (ACE_POSIX_Asynch_Result *asynch_result,
+ u_long bytes_transferred,
+ int success,
+ const void *completion_key,
+ u_long error)
+{
+ ACE_POSIX_Proactor::application_specific_code (asynch_result,
+ bytes_transferred,
+ success,
+ completion_key,
+ error);
+}
+
+int
+ACE_POSIX_AIOCB_Proactor::register_aio_with_proactor (aiocb *aiocb_ptr)
+{
+ if (aiocb_ptr == 0)
+ {
+ ACE_DEBUG ((LM_DEBUG,
+ "Status check max %d cur %d\n",
+ this->aiocb_list_max_size_,
+ this->aiocb_list_cur_size_));
+
+ // Just check the status of the list.
+ if (this->aiocb_list_cur_size_ >=
+ this->aiocb_list_max_size_)
+ return -1;
+ else
+ return 0;
+ }
+
+ // Non-zero ptr. Find a free slot and store.
+
+ // Make sure again.
+ if (this->aiocb_list_cur_size_ >=
+ this->aiocb_list_max_size_)
+ ACE_ERROR_RETURN ((LM_ERROR,
+ "Error:Asynch_Operation: No space to store the <aio> info.\n"),
+ -1);
+
+ // Slot(s) available. Find a free one.
+ size_t ai;
+ for (ai = 0;
+ ai < this->aiocb_list_max_size_;
+ ai++)
+ if (this->aiocb_list_[ai] == 0)
+ break;
+
+ // Sanity check.
+ if (ai == this->aiocb_list_max_size_)
+ ACE_ERROR_RETURN ((LM_ERROR,
+ "Error:Asynch_Operation: No space to store the <aio> info.\n"),
+ -1);
+
+ // Store the pointers.
+ this->aiocb_list_[ai] = aiocb_ptr;
+ this->aiocb_list_cur_size_ ++;
+
+ return 0;
+}
+
+// *********************************************************************
+
+ACE_POSIX_SIG_Proactor::ACE_POSIX_SIG_Proactor (void)
+{
+ // Make the sigset_t consisting of the completion signals.
+ if (sigemptyset (&this->RT_completion_signals_) < 0)
+ ACE_ERROR ((LM_ERROR,
+ "Error:%p\n",
+ "Couldn't init the RT completion signal set"));
+
+ if (sigaddset (&this->RT_completion_signals_, ACE_SIG_AIO) < 0)
+ ACE_ERROR ((LM_ERROR,
+ "Error:%p\n",
+ "Couldnt init the RT completion signal set"));
+
+ // Mask them.
+ if (sigprocmask (SIG_BLOCK, &RT_completion_signals_, 0) < 0)
+ ACE_ERROR ((LM_ERROR,
+ "Error:%p\n",
+ "Couldnt mask the RT completion signals"));
+
+ // Setting up the handler(actually Null handler) for these signals.
+ struct sigaction reaction;
+ sigemptyset (&reaction.sa_mask); // Nothing else to mask.
+ reaction.sa_flags = SA_SIGINFO; // Realtime flag.
+#if defined (SA_SIGACTION)
+ // Lynx says, it is better to set this bit to be portable.
+ reaction.sa_flags &= SA_SIGACTION;
+#endif /* SA_SIGACTION */
+ reaction.sa_sigaction = 0; // No handler.
+ int sigaction_return = sigaction (ACE_SIG_AIO,
+ &reaction,
+ 0);
+ if (sigaction_return == -1)
+ ACE_ERROR ((LM_ERROR,
+ "Error:%p\n",
+ "Proactor couldnt do sigaction for the RT SIGNAL"));
+}
+
+
+ACE_POSIX_SIG_Proactor::~ACE_POSIX_SIG_Proactor (void)
+{
+ // @@ Enable the masked signals again.
+}
+
+int
+ACE_POSIX_SIG_Proactor::handle_events (ACE_Time_Value &wait_time)
+{
+ // Decrement <wait_time> with the amount of time spent in the method
+ ACE_Countdown_Time countdown (&wait_time);
+ return this->handle_events (wait_time.msec ());
+}
+
+int
+ACE_POSIX_SIG_Proactor::handle_events (void)
+{
+ return this->handle_events (ACE_INFINITE);
+}
+
+ACE_Asynch_Read_Stream_Impl *
+ACE_POSIX_SIG_Proactor::create_asynch_read_stream (void)
+{
+ ACE_Asynch_Read_Stream_Impl *implementation = 0;
+ ACE_NEW_RETURN (implementation, ACE_POSIX_SIG_Asynch_Read_Stream (this), 0);
+ return implementation;
+}
+
+ACE_Asynch_Write_Stream_Impl *
+ACE_POSIX_SIG_Proactor::create_asynch_write_stream (void)
+{
+ ACE_Asynch_Write_Stream_Impl *implementation = 0;
+ ACE_NEW_RETURN (implementation, ACE_POSIX_SIG_Asynch_Write_Stream (this), 0);
+ return implementation;
+}
+
+ACE_Asynch_Read_File_Impl *
+ACE_POSIX_SIG_Proactor::create_asynch_read_file (void)
+{
+ ACE_Asynch_Read_File_Impl *implementation = 0;
+ ACE_NEW_RETURN (implementation, ACE_POSIX_SIG_Asynch_Read_File (this), 0);
+ return implementation;
+}
+
+ACE_Asynch_Write_File_Impl *
+ACE_POSIX_SIG_Proactor::create_asynch_write_file (void)
+{
+ ACE_Asynch_Write_File_Impl *implementation = 0;
+ ACE_NEW_RETURN (implementation, ACE_POSIX_SIG_Asynch_Write_File (this), 0);
+ return implementation;
+}
+
+ACE_Asynch_Accept_Impl *
+ACE_POSIX_SIG_Proactor::create_asynch_accept (void)
+{
+ ACE_Asynch_Accept_Impl *implementation = 0;
+ ACE_NEW_RETURN (implementation, ACE_POSIX_SIG_Asynch_Accept (this), 0);
+ return implementation;
+}
+
+ACE_Asynch_Transmit_File_Impl *
+ACE_POSIX_SIG_Proactor::create_asynch_transmit_file (void)
+{
+ ACE_Asynch_Transmit_File_Impl *implementation = 0;
+ ACE_NEW_RETURN (implementation,
+ ACE_POSIX_SIG_Asynch_Transmit_File (this),
+ 0);
+ return implementation;
+}
+
+int
+ACE_POSIX_SIG_Proactor::handle_events (unsigned long milli_seconds)
+{
+ // Wait for <milli_seconds> amount of time.
+ // @@ Assigning <milli_seconds> to tv_sec.
+ timespec timeout;
+ timeout.tv_sec = milli_seconds;
+ timeout.tv_nsec = 0;
+
+ // To get back the signal info.
+ siginfo_t sig_info;
+
+ // Await the RT completion signal.
+ int sig_return = sigtimedwait (&this->RT_completion_signals_,
+ &sig_info,
+ &timeout);
+
+ // Error case.
+ // If failure is coz of timeout, then return *0* but set
+ // errno appropriately. This is what the WinNT proactor
+ // does.
+ if (sig_return == -1)
+ ACE_ERROR_RETURN ((LM_ERROR,
+ "Error:%p\n",
+ "Waiting for RT completion signals"),
+ 0);
+
+ // RT completion signals returned.
+ if (sig_return != ACE_SIG_AIO)
+ ACE_ERROR_RETURN ((LM_ERROR,
+ "Unexpected signal (%d) has been received while waiting for RT Completion Signals\n",
+ sig_return),
+ -1);
+
+ // @@ Debugging.
+ ACE_DEBUG ((LM_DEBUG,
+ "Sig number found in the sig_info block : %d\n",
+ sig_info.si_signo));
+
+ // Is the signo returned consistent?
+ if (sig_info.si_signo != sig_return)
+ ACE_ERROR_RETURN ((LM_ERROR,
+ "Inconsistent signal number (%d) in the signal info block\n",
+ sig_info.si_signo),
+ -1);
+
+ // @@ Debugging.
+ ACE_DEBUG ((LM_DEBUG,
+ "Signal code for this signal delivery : %d\n",
+ sig_info.si_code));
+
+ // Retrive the result pointer.
+ ACE_POSIX_Asynch_Result *asynch_result =
+ (ACE_POSIX_Asynch_Result *) sig_info.si_value.sival_ptr;
+
+ // Check the <signal code> and act according to that.
+ if (sig_info.si_code == SI_ASYNCIO)
+ {
+ // Retrieve the aiocb from Result ptr.
+ // @@ Some checking should be done to make sure this pointer
+ // is valid. Otherwise <aio_error> will bomb.
+ aiocb* aiocb_ptr =
+ (aiocb *)asynch_result;
+
+ // Analyze error and return values. Return values are
+ // actually <errno>'s associated with the <aio_> call
+ // corresponding to aiocb_ptr.
+ int error_status = aio_error (aiocb_ptr);
+ if (error_status == -1)
+ ACE_ERROR_RETURN ((LM_ERROR,
+ "Error:%p\n",
+ "Invalid control block was sent to <aio_error> for compleion querying"),
+ -1);
+
+ // Completion signal has been received, so it can't be in
+ // progress.
+ // ACE_ASSERT (error_status != EINPROGRESS)
+
+ // No error occured in the AIO operation.
+ int return_status = aio_return (aiocb_ptr);
+ if (return_status == -1)
+ {
+ ACE_ERROR_RETURN ((LM_ERROR,
+ "Error:%p\n",
+ "Invalid control block was send to <aio_return>"),
+ -1);
+ }
+ else
+ {
+ ACE_DEBUG ((LM_DEBUG, "An aio has finished\n"));
+
+ this->application_specific_code (asynch_result,
+ return_status,
+ 1, // Result : True.
+ 0, // No completion_signal.
+ error_status); // Error.
+ }
+ }
+ else if (sig_info.si_code == SI_QUEUE)
+ {
+ // @@ Just debugging.
+ ACE_DEBUG ((LM_DEBUG, "<sigqueue>'d signal received\n"));
+
+ this->application_specific_code (asynch_result,
+ 0, // No bytes transferred.
+ 1, // Result : True.
+ 0, // No completion key.
+ 0); // No error.
+ }
+ else
+ // Unknown signal code.
+ ACE_ERROR_RETURN ((LM_DEBUG,
+ "Unexpected signal code (%d) returned on completion querying\n",
+ sig_info.si_code),
+ -1);
+
+ return 0;
+}
+
+#if defined (ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION)
+#if 0
+template class ACE_Timer_Queue_T<ACE_Handler *,
+ ACE_Proactor_Handle_Timeout_Upcall,
+ ACE_SYNCH_RECURSIVE_MUTEX>;
+template class ACE_Timer_Queue_Iterator_T<ACE_Handler *,
+ ACE_Proactor_Handle_Timeout_Upcall,
+ ACE_SYNCH_RECURSIVE_MUTEX>;
+template class ACE_Timer_List_T<ACE_Handler *,
+ ACE_Proactor_Handle_Timeout_Upcall,
+ ACE_SYNCH_RECURSIVE_MUTEX>;
+template class ACE_Timer_List_Iterator_T<ACE_Handler *,
+ ACE_Proactor_Handle_Timeout_Upcall,
+ ACE_SYNCH_RECURSIVE_MUTEX>;
+template class ACE_Timer_Node_T<ACE_Handler *>;
+template class ACE_Unbounded_Set<ACE_Timer_Node_T<ACE_Handler *> *>;
+template class ACE_Unbounded_Set_Iterator<ACE_Timer_Node_T<ACE_Handler *> *>;
+template class ACE_Node <ACE_Timer_Node_T<ACE_Handler *> *>;
+template class ACE_Free_List<ACE_Timer_Node_T<ACE_Handler *> >;
+template class ACE_Locked_Free_List<ACE_Timer_Node_T<ACE_Handler *>, ACE_Null_Mutex>;
+template class ACE_Timer_Heap_T<ACE_Handler *,
+ ACE_Proactor_Handle_Timeout_Upcall,
+ ACE_SYNCH_RECURSIVE_MUTEX>;
+template class ACE_Timer_Heap_Iterator_T<ACE_Handler *,
+ ACE_Proactor_Handle_Timeout_Upcall,
+ ACE_SYNCH_RECURSIVE_MUTEX>;
+template class ACE_Timer_Wheel_T<ACE_Handler *,
+ ACE_Proactor_Handle_Timeout_Upcall,
+ ACE_SYNCH_RECURSIVE_MUTEX>;
+template class ACE_Timer_Wheel_Iterator_T<ACE_Handler *,
+ ACE_Proactor_Handle_Timeout_Upcall,
+ ACE_SYNCH_RECURSIVE_MUTEX>;
+#endif /* 0 */
+#elif defined (ACE_HAS_TEMPLATE_INSTANTIATION_PRAGMA)
+#pragma instantiate ACE_Timer_Queue_T<ACE_Handler *,\
+ ACE_Proactor_Handle_Timeout_Upcall, ACE_SYNCH_RECURSIVE_MUTEX>
+#pragma instantiate ACE_Timer_Queue_Iterator_T<ACE_Handler *,\
+ ACE_Proactor_Handle_Timeout_Upcall, ACE_SYNCH_RECURSIVE_MUTEX>
+#pragma instantiate ACE_Timer_List_T<ACE_Handler *,\
+ ACE_Proactor_Handle_Timeout_Upcall, ACE_SYNCH_RECURSIVE_MUTEX>
+#pragma instantiate ACE_Timer_List_Iterator_T<ACE_Handler *,\
+ ACE_Proactor_Handle_Timeout_Upcall, ACE_SYNCH_RECURSIVE_MUTEX>
+#pragma instantiate ACE_Timer_Heap_T<ACE_Handler *,\
+ ACE_Proactor_Handle_Timeout_Upcall, ACE_SYNCH_RECURSIVE_MUTEX>
+#pragma instantiate ACE_Timer_Heap_Iterator_T<ACE_Handler *,\
+ ACE_Proactor_Handle_Timeout_Upcall, ACE_SYNCH_RECURSIVE_MUTEX>
+#pragma instantiate ACE_Timer_Wheel_T<ACE_Handler *,
+ ACE_Proactor_Handle_Timeout_Upcall, ACE_SYNCH_RECURSIVE_MUTEX>
+#pragma instantiate ACE_Timer_Wheel_Iterator_T<ACE_Handler *,\
+ ACE_Proactor_Handle_Timeout_Upcall, ACE_SYNCH_RECURSIVE_MUTEX>
+#endif /* ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION */
+
+#endif /* ACE_HAS_AIO_CALLS */
diff --git a/ace/WIN32_Proactor.i b/ace/WIN32_Proactor.i
new file mode 100644
index 00000000000..6318deb79a0
--- /dev/null
+++ b/ace/WIN32_Proactor.i
@@ -0,0 +1,2 @@
+/* -*- C++ -*- */
+// $Id$