text: // $Id: POSIX_Asynch_IO.cpp 96985 2013-04-11 15:50:32Z huangh $
  
  #include "ace/POSIX_Asynch_IO.h"
  
  #if defined (ACE_HAS_AIO_CALLS)
  
  #include "ace/Flag_Manip.h"
  #include "ace/Proactor.h"
  #include "ace/Message_Block.h"
  #include "ace/INET_Addr.h"
  #include "ace/Asynch_Pseudo_Task.h"
  #include "ace/POSIX_Proactor.h"
  #include "ace/OS_NS_errno.h"
  #include "ace/OS_NS_sys_socket.h"
  #include "ace/OS_NS_sys_stat.h"
  
  ACE_BEGIN_VERSIONED_NAMESPACE_DECL
  
  size_t
  ACE_POSIX_Asynch_Result::bytes_transferred (void) const
  {
    return this->bytes_transferred_;
  }
  
  void
  ACE_POSIX_Asynch_Result::set_bytes_transferred (size_t nbytes)
  {
    this->bytes_transferred_= nbytes;
  }
  
  const void *
  ACE_POSIX_Asynch_Result::act (void) const
  {
    return this->act_;
  }
  
  int
  ACE_POSIX_Asynch_Result::success (void) const
  {
    return this->success_;
  }
  
  const void *
  ACE_POSIX_Asynch_Result::completion_key (void) const
  {
    return this->completion_key_;
  }
  
  u_long
  ACE_POSIX_Asynch_Result::error (void) const
  {
    return this->error_;
  }
  
  void
  ACE_POSIX_Asynch_Result::set_error (u_long errcode)
  {
    this->error_=errcode;
  }
  ACE_HANDLE
  ACE_POSIX_Asynch_Result::event (void) const
  {
    return ACE_INVALID_HANDLE;
  }
  
  u_long
  ACE_POSIX_Asynch_Result::offset (void) const
  {
    return this->aio_offset;
  }
  
  u_long
  ACE_POSIX_Asynch_Result::offset_high (void) const
  {
    //
    // @@ Support aiocb64??
    //
    ACE_NOTSUP_RETURN (0);
  }
  
  int
  ACE_POSIX_Asynch_Result::priority (void) const
  {
    return this->aio_reqprio;
  }
  
  int
  ACE_POSIX_Asynch_Result::signal_number (void) const
  {
    return this->aio_sigevent.sigev_signo;
  }
  
  int
  ACE_POSIX_Asynch_Result::post_completion (ACE_Proactor_Impl *proactor_impl)
  {
    // Get to the platform specific implementation.
    ACE_POSIX_Proactor *posix_proactor = dynamic_cast<ACE_POSIX_Proactor *> (proactor_impl);
  
    if (posix_proactor == 0)
      ACELIB_ERROR_RETURN ((LM_ERROR, "Dynamic cast to POSIX Proactor failed\n"), -1);
  
    // Post myself.
    return posix_proactor->post_completion (this);
  }
  
  ACE_POSIX_Asynch_Result::~ACE_POSIX_Asynch_Result (void)
  {
  }
  
  ACE_POSIX_Asynch_Result::ACE_POSIX_Asynch_Result
    (const ACE_Handler::Proxy_Ptr &handler_proxy,
     const void* act,
     ACE_HANDLE /* event */,      // Event is not used on POSIX.
     u_long offset,
     u_long offset_high,
     int priority,
     int signal_number)
    : handler_proxy_ (handler_proxy),
      act_ (act),
      bytes_transferred_ (0),
      success_ (0),
      completion_key_ (0),
      error_ (0)
  {
    aio_offset = offset;
    aio_reqprio = priority;
    aio_sigevent.sigev_signo = signal_number;
  
    //
    // @@ Support offset_high with aiocb64.
    //
    ACE_UNUSED_ARG (offset_high);
  
    // Other fields in the <aiocb> will be initialized by the
    // subclasses.
  }
  
  // ****************************************************************
  
  int
  ACE_POSIX_Asynch_Operation::open (const ACE_Handler::Proxy_Ptr &handler_proxy,
                                    ACE_HANDLE handle,
                                    const void * /* completion_key */,
                                    ACE_Proactor *proactor)
  {
    this->proactor_ = proactor;
    this->handler_proxy_ = handler_proxy;
    this->handle_ = handle;
  
    // Grab the handle from the <handler> if <handle> is invalid
    if (this->handle_ == ACE_INVALID_HANDLE)
      {
        ACE_Handler *handler = handler_proxy.get ()->handler ();
        if (handler != 0)
          this->handle_ = handler->handle ();
      }
    if (this->handle_ == ACE_INVALID_HANDLE)
      return -1;
  
  #if 0
    // @@ If <proactor> is 0, let us not bother about getting this
    // Proactor, we have already got the specific implementation
    // Proactor.
  
    // If no proactor was passed
    if (this->proactor_ == 0)
      {
        // Grab the proactor from the <Service_Config> if
        // <handler->proactor> is zero
        this->proactor_ = this->handler_->proactor ();
        if (this->proactor_ == 0)
          this->proactor_ = ACE_Proactor::instance();
      }
  #endif /* 0 */
  
    return 0;
  }
  
  int
  ACE_POSIX_Asynch_Operation::cancel (void)
  {
    if (!posix_proactor_)
      return -1;
    return posix_proactor_->cancel_aio (this->handle_);
  }
  
  ACE_Proactor *
  ACE_POSIX_Asynch_Operation::proactor (void) const
  {
    return this->proactor_;
  }
  
  ACE_POSIX_Proactor *
  ACE_POSIX_Asynch_Operation::posix_proactor (void) const
  {
    return this->posix_proactor_;
  }
  
  ACE_POSIX_Asynch_Operation::~ACE_POSIX_Asynch_Operation (void)
  {
  }
  
  ACE_POSIX_Asynch_Operation::ACE_POSIX_Asynch_Operation (ACE_POSIX_Proactor *posix_proactor)
    : posix_proactor_ (posix_proactor),
      handle_  (ACE_INVALID_HANDLE)
  {
  }
  
  // *********************************************************************
  
  size_t
  ACE_POSIX_Asynch_Read_Stream_Result::bytes_to_read (void) const
  {
    return this->aio_nbytes;
  }
  
  ACE_Message_Block &
  ACE_POSIX_Asynch_Read_Stream_Result::message_block (void) const
  {
    return this->message_block_;
  }
  
  ACE_HANDLE
  ACE_POSIX_Asynch_Read_Stream_Result::handle (void) const
  {
    return this->aio_fildes;
  }
  
  ACE_POSIX_Asynch_Read_Stream_Result::ACE_POSIX_Asynch_Read_Stream_Result
    (const ACE_Handler::Proxy_Ptr &handler_proxy,
     ACE_HANDLE handle,
     ACE_Message_Block &message_block,
     size_t bytes_to_read,
     const void* act,
     ACE_HANDLE event,
     int priority,
     int signal_number)
    : ACE_POSIX_Asynch_Result
        (handler_proxy, act, event, 0, 0, priority, signal_number),
      message_block_ (message_block)
  {
    this->aio_fildes = handle;
    this->aio_buf = message_block.wr_ptr ();
    this->aio_nbytes = bytes_to_read;
  }
  
  void
  ACE_POSIX_Asynch_Read_Stream_Result::complete (size_t bytes_transferred,
                                                 int success,
                                                 const void *completion_key,
                                                 u_long error)
  {
    this->bytes_transferred_ = bytes_transferred;
    this->success_ = success;
    this->completion_key_ = completion_key;
    this->error_ = error;
  
    // <errno> is available in the aiocb.
    ACE_UNUSED_ARG (error);
  
    // Appropriately move the pointers in the message block.
    this->message_block_.wr_ptr (bytes_transferred);
  
    // Create the interface result class.
    ACE_Asynch_Read_Stream::Result result (this);
  
    // Call the application handler.
    ACE_Handler *handler = this->handler_proxy_.get ()->handler ();
    if (handler != 0)
      handler->handle_read_stream (result);
  }
  
  ACE_POSIX_Asynch_Read_Stream_Result::~ACE_POSIX_Asynch_Read_Stream_Result (void)
  {
  }
  
  // ************************************************************
  
  ACE_POSIX_Asynch_Read_Stream::ACE_POSIX_Asynch_Read_Stream (ACE_POSIX_Proactor  *posix_proactor)
    : ACE_POSIX_Asynch_Operation (posix_proactor)
  {
  }
  
  int
  ACE_POSIX_Asynch_Read_Stream::read (ACE_Message_Block &message_block,
                                      size_t bytes_to_read,
                                      const void *act,
                                      int priority,
                                      int signal_number)
  {
    size_t space = message_block.space ();
    if (bytes_to_read > space)
       bytes_to_read=space;
  
    if (bytes_to_read == 0)
      {
        errno = ENOSPC;
        return -1;
      }
  
    // Create the Asynch_Result.
    ACE_POSIX_Asynch_Read_Stream_Result *result = 0;
    ACE_POSIX_Proactor *proactor = this->posix_proactor ();
    ACE_NEW_RETURN (result,
                    ACE_POSIX_Asynch_Read_Stream_Result (this->handler_proxy_,
                                                         this->handle_,
                                                         message_block,
                                                         bytes_to_read,
                                                         act,
                                                         proactor->get_handle (),
                                                         priority,
                                                         signal_number),
                    -1);
  
    int return_val = proactor->start_aio (result, ACE_POSIX_Proactor::ACE_OPCODE_READ);
    if (return_val == -1)
      delete result;
  
    return return_val;
  }
  
  ACE_POSIX_Asynch_Read_Stream::~ACE_POSIX_Asynch_Read_Stream (void)
  {
  }
  
  // *********************************************************************
  
  size_t
  ACE_POSIX_Asynch_Write_Stream_Result::bytes_to_write (void) const
  {
    return this->aio_nbytes;
  }
  
  ACE_Message_Block &
  ACE_POSIX_Asynch_Write_Stream_Result::message_block (void) const
  {
    return this->message_block_;
  }
  
  ACE_HANDLE
  ACE_POSIX_Asynch_Write_Stream_Result::handle (void) const
  {
    return this->aio_fildes;
  }
  
  ACE_POSIX_Asynch_Write_Stream_Result::ACE_POSIX_Asynch_Write_Stream_Result
    (const ACE_Handler::Proxy_Ptr &handler_proxy,
     ACE_HANDLE handle,
     ACE_Message_Block &message_block,
     size_t bytes_to_write,
     const void* act,
     ACE_HANDLE event,
     int priority,
     int signal_number)
    : ACE_POSIX_Asynch_Result
        (handler_proxy, act, event, 0, 0, priority, signal_number),
      message_block_ (message_block)
  {
    this->aio_fildes = handle;
    this->aio_buf = message_block.rd_ptr ();
    this->aio_nbytes = bytes_to_write;
  }
  
  void
  ACE_POSIX_Asynch_Write_Stream_Result::complete (size_t bytes_transferred,
                                                  int success,
                                                  const void *completion_key,
                                                  u_long error)
  {
    // Get all the data copied.
    this->bytes_transferred_ = bytes_transferred;
    this->success_ = success;
    this->completion_key_ = completion_key;
    this->error_ = error;
  
    // <errno> is available in the aiocb.
    ACE_UNUSED_ARG (error);
  
    // Appropriately move the pointers in the message block.
    this->message_block_.rd_ptr (bytes_transferred);
  
    // Create the interface result class.
    ACE_Asynch_Write_Stream::Result result (this);
  
    // Call the application handler.
    ACE_Handler *handler = this->handler_proxy_.get ()->handler ();
    if (handler != 0)
      handler->handle_write_stream (result);
  }
  
  ACE_POSIX_Asynch_Write_Stream_Result::~ACE_POSIX_Asynch_Write_Stream_Result (void)
  {
  }
  
  // *********************************************************************
  
  ACE_POSIX_Asynch_Write_Stream::ACE_POSIX_Asynch_Write_Stream (ACE_POSIX_Proactor *posix_proactor)
    : ACE_POSIX_Asynch_Operation (posix_proactor)
  {
  }
  
  int
  ACE_POSIX_Asynch_Write_Stream::write (ACE_Message_Block &message_block,
                                        size_t bytes_to_write,
                                        const void *act,
                                        int priority,
                                        int signal_number)
  {
    size_t len = message_block.length ();
    if (bytes_to_write > len)
       bytes_to_write = len;
  
    if (bytes_to_write == 0)
      ACELIB_ERROR_RETURN
        ((LM_ERROR,
          ACE_TEXT ("ACE_POSIX_Asynch_Write_Stream::write:")
          ACE_TEXT ("Attempt to write 0 bytes\n")),
        -1);
  
    ACE_POSIX_Asynch_Write_Stream_Result *result = 0;
    ACE_POSIX_Proactor *proactor = this->posix_proactor ();
    ACE_NEW_RETURN (result,
                    ACE_POSIX_Asynch_Write_Stream_Result (this->handler_proxy_,
                                                          this->handle_,
                                                          message_block,
                                                          bytes_to_write,
                                                          act,
                                                          proactor->get_handle (),
                                                          priority,
                                                          signal_number),
                    -1);
  
    int return_val = proactor->start_aio (result, ACE_POSIX_Proactor::ACE_OPCODE_WRITE);
    if (return_val == -1)
      delete result;
  
    return return_val;
  }
  
  ACE_POSIX_Asynch_Write_Stream::~ACE_POSIX_Asynch_Write_Stream (void)
  {
  }
  
  // *********************************************************************
  
  ACE_POSIX_Asynch_Read_File_Result::ACE_POSIX_Asynch_Read_File_Result
    (const ACE_Handler::Proxy_Ptr &handler_proxy,
     ACE_HANDLE handle,
     ACE_Message_Block &message_block,
     size_t bytes_to_read,
     const void* act,
     u_long offset,
     u_long offset_high,
     ACE_HANDLE event,
     int priority,
     int signal_number)
    : ACE_POSIX_Asynch_Read_Stream_Result (handler_proxy,
                                           handle,
                                           message_block,
                                           bytes_to_read,
                                           act,
                                           event,
                                           priority,
                                           signal_number)
  {
    this->aio_offset = offset;
    //
    // @@ Use aiocb64??
    //
    ACE_UNUSED_ARG (offset_high);
  }
  
  void
  ACE_POSIX_Asynch_Read_File_Result::complete (size_t bytes_transferred,
                                               int success,
                                               const void *completion_key,
                                               u_long error)
  {
    // Copy all the data.
    this->bytes_transferred_ = bytes_transferred;
    this->success_ = success;
    this->completion_key_ = completion_key;
    this->error_ = error;
  
    // <errno> is available in the aiocb.
    ACE_UNUSED_ARG (error);
  
    // Appropriately move the pointers in the message block.
    this->message_block_.wr_ptr (bytes_transferred);
  
    // Create the interface result class.
    ACE_Asynch_Read_File::Result result (this);
  
    // Call the application handler.
    ACE_Handler *handler = this->handler_proxy_.get ()->handler ();
    if (handler != 0)
      handler->handle_read_file (result);
  }
  
  ACE_POSIX_Asynch_Read_File_Result::~ACE_POSIX_Asynch_Read_File_Result (void)
  {
  }
  
  // *********************************************************************
  
  ACE_POSIX_Asynch_Read_File::ACE_POSIX_Asynch_Read_File (ACE_POSIX_Proactor *posix_proactor)
    : ACE_POSIX_Asynch_Read_Stream (posix_proactor)
  {
  }
  
  int
  ACE_POSIX_Asynch_Read_File::read (ACE_Message_Block &message_block,
                                    size_t bytes_to_read,
                                    u_long offset,
                                    u_long offset_high,
                                    const void *act,
                                    int priority,
                                    int signal_number)
  {
    size_t space = message_block.space ();
    if ( bytes_to_read > space )
       bytes_to_read=space;
  
    if ( bytes_to_read == 0 )
      ACELIB_ERROR_RETURN
        ((LM_ERROR,
          ACE_TEXT ("ACE_POSIX_Asynch_Read_File::read:")
          ACE_TEXT ("Attempt to read 0 bytes or no space in the message block\n")),
         -1);
  
    ACE_POSIX_Asynch_Read_File_Result *result = 0;
    ACE_POSIX_Proactor *proactor = this->posix_proactor ();
    ACE_NEW_RETURN (result,
                    ACE_POSIX_Asynch_Read_File_Result (this->handler_proxy_,
                                                       this->handle_,
                                                       message_block,
                                                       bytes_to_read,
                                                       act,
                                                       offset,
                                                       offset_high,
                                                       posix_proactor ()->get_handle (),
                                                       priority,
                                                       signal_number),
                    -1);
  
    int return_val = proactor->start_aio (result, ACE_POSIX_Proactor::ACE_OPCODE_READ);
    if (return_val == -1)
      delete result;
  
    return return_val;
  }
  
  ACE_POSIX_Asynch_Read_File::~ACE_POSIX_Asynch_Read_File (void)
  {
  }
  
  int
  ACE_POSIX_Asynch_Read_File::read (ACE_Message_Block &message_block,
                                    size_t bytes_to_read,
                                    const void *act,
                                    int priority,
                                    int signal_number)
  {
    return ACE_POSIX_Asynch_Read_Stream::read (message_block,
                                               bytes_to_read,
                                               act,
                                               priority,
                                               signal_number);
  }
  
  // ************************************************************
  
  ACE_POSIX_Asynch_Write_File_Result::ACE_POSIX_Asynch_Write_File_Result
    (const ACE_Handler::Proxy_Ptr &handler_proxy,
     ACE_HANDLE handle,
     ACE_Message_Block &message_block,
     size_t bytes_to_write,
     const void* act,
     u_long offset,
     u_long offset_high,
     ACE_HANDLE event,
     int priority,
     int signal_number)
    : ACE_POSIX_Asynch_Write_Stream_Result (handler_proxy,
                                            handle,
                                            message_block,
                                            bytes_to_write,
                                            act,
                                            event,
                                            priority,
                                            signal_number)
  {
    this->aio_offset = offset;
    //
    // @@ Support offset_high with aiocb64.
    //
    ACE_UNUSED_ARG (offset_high);
  }
  
  void
  ACE_POSIX_Asynch_Write_File_Result::complete (size_t bytes_transferred,
                                                int success,
                                                const void *completion_key,
                                                u_long error)
  {
    // Copy the data.
    this->bytes_transferred_ = bytes_transferred;
    this->success_ = success;
    this->completion_key_ = completion_key;
    this->error_ = error;
  
    // <error> is available in <aio_resultp.aio_error>
    ACE_UNUSED_ARG (error);
  
    // Appropriately move the pointers in the message block.
    this->message_block_.rd_ptr (bytes_transferred);
  
    // Create the interface result class.
    ACE_Asynch_Write_File::Result result (this);
  
    // Call the application handler.
    ACE_Handler *handler = this->handler_proxy_.get ()->handler ();
    if (handler != 0)
      handler->handle_write_file (result);
  }
  
  ACE_POSIX_Asynch_Write_File_Result::~ACE_POSIX_Asynch_Write_File_Result  (void)
  {
  }
  
  // *********************************************************************
  
  ACE_POSIX_Asynch_Write_File::ACE_POSIX_Asynch_Write_File (ACE_POSIX_Proactor *posix_proactor)
    : ACE_POSIX_Asynch_Write_Stream (posix_proactor)
  {
  }
  
  int
  ACE_POSIX_Asynch_Write_File::write (ACE_Message_Block &message_block,
                                      size_t bytes_to_write,
                                      u_long offset,
                                      u_long offset_high,
                                      const void *act,
                                      int priority,
                                      int signal_number)
  {
    size_t len = message_block.length ();
    if (bytes_to_write > len)
       bytes_to_write = len;
  
    if (bytes_to_write == 0)
      ACELIB_ERROR_RETURN
        ((LM_ERROR,
          ACE_TEXT ("ACE_POSIX_Asynch_Write_File::write:")
          ACE_TEXT ("Attempt to write 0 bytes\n")),
        -1);
  
    ACE_POSIX_Asynch_Write_File_Result *result = 0;
    ACE_POSIX_Proactor *proactor = this->posix_proactor ();
    ACE_NEW_RETURN (result,
                    ACE_POSIX_Asynch_Write_File_Result (this->handler_proxy_,
                                                        this->handle_,
                                                        message_block,
                                                        bytes_to_write,
                                                        act,
                                                        offset,
                                                        offset_high,
                                                        proactor->get_handle (),
                                                        priority,
                                                        signal_number),
                    -1);
  
    int return_val = proactor->start_aio (result, ACE_POSIX_Proactor::ACE_OPCODE_WRITE);
    if (return_val == -1)
      delete result;
  
    return return_val;
  }
  
  ACE_POSIX_Asynch_Write_File::~ACE_POSIX_Asynch_Write_File (void)
  {
  }
  
  int
  ACE_POSIX_Asynch_Write_File::write (ACE_Message_Block &message_block,
                                      size_t bytes_to_write,
                                      const void *act,
                                      int priority,
                                      int signal_number)
  {
    return ACE_POSIX_Asynch_Write_Stream::write (message_block,
                                                       bytes_to_write,
                                                       act,
                                                       priority,
                                                       signal_number);
  }
  
  // *********************************************************************
  
  
  size_t
  ACE_POSIX_Asynch_Accept_Result::bytes_to_read (void) const
  {
    return this->aio_nbytes;
  }
  
  ACE_Message_Block &
  ACE_POSIX_Asynch_Accept_Result::message_block (void) const
  {
    return this->message_block_;
  }
  
  ACE_HANDLE
  ACE_POSIX_Asynch_Accept_Result::listen_handle (void) const
  {
    return this->listen_handle_;
  }
  
  ACE_HANDLE
  ACE_POSIX_Asynch_Accept_Result::accept_handle (void) const
  {
    return this->aio_fildes;
  }
  
  ACE_POSIX_Asynch_Accept_Result::ACE_POSIX_Asynch_Accept_Result
    (const ACE_Handler::Proxy_Ptr &handler_proxy,
     ACE_HANDLE listen_handle,
     ACE_HANDLE accept_handle,
     ACE_Message_Block &message_block,
     size_t bytes_to_read,
     const void* act,
     ACE_HANDLE event,
     int priority,
     int signal_number)
  
    : ACE_POSIX_Asynch_Result
        (handler_proxy, act, event, 0, 0, priority, signal_number),
      message_block_ (message_block),
      listen_handle_ (listen_handle)
  {
    this->aio_fildes = accept_handle;
    this->aio_nbytes = bytes_to_read;
  }
  
  void
  ACE_POSIX_Asynch_Accept_Result::complete (size_t bytes_transferred,
                                            int success,
                                            const void *completion_key,
                                            u_long error)
  {
    // Copy the data.
    this->bytes_transferred_ = bytes_transferred;
    this->success_ = success;
    this->completion_key_ = completion_key;
    this->error_ = error;
  
    // Appropriately move the pointers in the message block.
    this->message_block_.wr_ptr (bytes_transferred);
  
    // Create the interface result class.
    ACE_Asynch_Accept::Result result (this);
  
    // Call the application handler.
    ACE_Handler *handler = this->handler_proxy_.get ()->handler ();
    if (handler != 0)
      handler->handle_accept (result);
  }
  
  ACE_POSIX_Asynch_Accept_Result::~ACE_POSIX_Asynch_Accept_Result (void)
  {
  }
  
  // *********************************************************************
  
  ACE_POSIX_Asynch_Accept::ACE_POSIX_Asynch_Accept (ACE_POSIX_Proactor * posix_proactor)
    : ACE_POSIX_Asynch_Operation (posix_proactor),
      flg_open_ (false)
  {
  }
  
  ACE_POSIX_Asynch_Accept::~ACE_POSIX_Asynch_Accept (void)
  {
    this->close ();
    this->reactor (0); // to avoid purge_pending_notifications
  }
  
  ACE_HANDLE
  ACE_POSIX_Asynch_Accept::get_handle (void) const
  {
    return this->handle_;
  }
  
  void
  ACE_POSIX_Asynch_Accept::set_handle (ACE_HANDLE handle)
  {
    ACE_ASSERT (handle_ == ACE_INVALID_HANDLE);
    this->handle_ = handle;
  }
  
  int
  ACE_POSIX_Asynch_Accept::open (const ACE_Handler::Proxy_Ptr &handler_proxy,
                                 ACE_HANDLE handle,
                                 const void *completion_key,
                                 ACE_Proactor *proactor)
  {
    ACE_TRACE ("ACE_POSIX_Asynch_Accept::open");
  
    // if we are already opened,
    // we could not create a new handler without closing the previous
    if (this->flg_open_)
      ACELIB_ERROR_RETURN ((LM_ERROR,
                         ACE_TEXT("%N:%l:ACE_POSIX_Asynch_Accept::open:")
                         ACE_TEXT("acceptor already open\n")),
                        -1);
  
    if (-1 == ACE_POSIX_Asynch_Operation::open (handler_proxy,
                                                handle,
                                                completion_key,
                                                proactor))
      return -1;
  
    flg_open_ = true;
  
    ACE_Asynch_Pseudo_Task & task =
      this->posix_proactor ()->get_asynch_pseudo_task ();
  
    if (-1 == task.register_io_handler (this->get_handle(),
                                        this,
                                        ACE_Event_Handler::ACCEPT_MASK,
                                        1))  // suspend after register
      {
        this->flg_open_= false;
        this->handle_ = ACE_INVALID_HANDLE;
        return -1 ;
      }
  
    return 0;
  }
  
  int
  ACE_POSIX_Asynch_Accept::accept (ACE_Message_Block &message_block,
                                   size_t bytes_to_read,
                                   ACE_HANDLE accept_handle,
                                   const void *act,
                                   int priority,
                                   int signal_number,
                                   int addr_family)
  {
    ACE_TRACE ("ACE_POSIX_Asynch_Accept::accept");
  
    if (!this->flg_open_)
      ACELIB_ERROR_RETURN ((LM_ERROR,
                         ACE_TEXT("%N:%l:ACE_POSIX_Asynch_Accept::accept")
                         ACE_TEXT("acceptor was not opened before\n")),
                        -1);
  
    // Sanity check: make sure that enough space has been allocated by
    // the caller.
    size_t address_size = sizeof (sockaddr_in);
  #if defined (ACE_HAS_IPV6)
    if (addr_family == AF_INET6)
      address_size = sizeof (sockaddr_in6);
  #else
    ACE_UNUSED_ARG (addr_family);
  #endif
    size_t available_space = message_block.space ();
    size_t space_needed = bytes_to_read + 2 * address_size;
  
    if (available_space < space_needed)
      {
        ACE_OS::last_error (ENOBUFS);
        return -1;
      }
  
    // Common code for both WIN and POSIX.
    // Create future Asynch_Accept_Result
    ACE_POSIX_Asynch_Accept_Result *result = 0;
    ACE_NEW_RETURN (result,
                    ACE_POSIX_Asynch_Accept_Result (this->handler_proxy_,
                                                    this->handle_,
                                                    accept_handle,
                                                    message_block,
                                                    bytes_to_read,
                                                    act,
                                                    this->posix_proactor()->get_handle (),
                                                    priority,
                                                    signal_number),
                    -1);
  
    // Enqueue result
    {
      ACE_MT (ACE_GUARD_RETURN (ACE_SYNCH_MUTEX, ace_mon, this->lock_, -1));
      if (this->result_queue_.enqueue_tail (result) == -1)
        {
          ACELIB_ERROR ((LM_ERROR,
                      ACE_TEXT ("ACE_POSIX_Asynch_Accept::accept: %p\n")
                      ACE_TEXT ("enqueue_tail")));
          delete result;  // to avoid memory  leak
          return -1;
        }
  
      if (this->result_queue_.size () > 1)
        return 0;
    }
  
    // If this is the only item, then it means there the set was empty
    // before. So enable the accept handle in the reactor.
  
    ACE_Asynch_Pseudo_Task & task =
      this->posix_proactor ()->get_asynch_pseudo_task ();
  
    return task.resume_io_handler (this->get_handle ());
  }
  
  //@@ New method cancel_uncompleted
  // It performs cancellation of all pending requests
  //
  // Parameter flg_notify can be
  //     0  - don't send notifications about canceled accepts
  //    !0  - notify user about canceled accepts
  //          according POSIX standards we should receive notifications
  //          on canceled AIO requests
  //
  //  Return value : number of cancelled requests
  //
  
  int
  ACE_POSIX_Asynch_Accept::cancel_uncompleted (int flg_notify)
  {
    ACE_TRACE ("ACE_POSIX_Asynch_Accept::cancel_uncompleted");
  
    int retval = 0;
  
    for (; ; retval++)
      {
        ACE_POSIX_Asynch_Accept_Result* result = 0;
  
        this->result_queue_.dequeue_head (result);
  
        if (result == 0)
          break;
  
        if (this->flg_open_ == 0 || flg_notify == 0) //if we should not notify
          delete result ;                            // we have to delete result
        else                                 //else notify as any cancelled AIO
          {
            // Store the new handle.
            result->aio_fildes = ACE_INVALID_HANDLE ;
            result->set_bytes_transferred (0);
            result->set_error (ECANCELED);
  
            if (this->posix_proactor ()->post_completion (result) == -1)
              ACELIB_ERROR ((LM_ERROR,
                          ACE_TEXT("(%P | %t):%p\n"),
                          ACE_TEXT("ACE_POSIX_Asynch_Accept::")
                          ACE_TEXT("cancel_uncompleted")
                          ));
          }
      }
    return retval;
  }
  
  int
  ACE_POSIX_Asynch_Accept::cancel (void)
  {
    ACE_TRACE ("ACE_POSIX_Asynch_Accept::cancel");
  
    // Since this is not a real POSIX asynch I/O operation, we can't
    // call ::aiocancel () or ACE_POSIX_Asynch_Operation::cancel ().
    // We delegate real cancelation to cancel_uncompleted (1)
  
    int rc = -1 ;  // ERRORS
  
    {
      ACE_MT (ACE_GUARD_RETURN (ACE_SYNCH_MUTEX, ace_mon, this->lock_, -1));
  
      int num_cancelled = cancel_uncompleted (flg_open_);
  
      if (num_cancelled == 0)
        rc = 1 ;        // AIO_ALLDONE
      else if (num_cancelled > 0)
        rc = 0 ;        // AIO_CANCELED
  
      if (!this->flg_open_)
        return rc ;
    }
  
    ACE_Asynch_Pseudo_Task & task =
      this->posix_proactor ()->get_asynch_pseudo_task ();
  
    task.suspend_io_handler (this->get_handle());
    return 0;
  }
  
  int
  ACE_POSIX_Asynch_Accept::close ()
  {
    ACE_TRACE ("ACE_POSIX_Asynch_Accept::close");
  
    // 1. It performs cancellation of all pending requests
    // 2. Removes itself from Reactor ( ACE_Asynch_Pseudo_Task)
    // 3. close the socket
    //
    //  Parameter flg_notify can be
    //     0  - don't send notifications about canceled accepts
    //    !0  - notify user about canceled accepts
    //          according POSIX standards we should receive notifications
    //          on canceled AIO requests
    //
    //  Return codes : 0 - OK ,
    //                -1 - Errors
  
    {
      ACE_MT (ACE_GUARD_RETURN (ACE_SYNCH_MUTEX, ace_mon, this->lock_, -1));
      this->cancel_uncompleted (flg_open_);
    }
  
    if (!this->flg_open_)
      {
        if (this->handle_ != ACE_INVALID_HANDLE)
          {
            ACE_OS::closesocket (this->handle_);
            this->handle_ = ACE_INVALID_HANDLE;
          }
        return 0;
      }
  
    if (this->handle_ == ACE_INVALID_HANDLE)
      return 0;
  
    ACE_Asynch_Pseudo_Task & task =
      this->posix_proactor ()->get_asynch_pseudo_task ();
  
    task.remove_io_handler (this->get_handle ());
    if (this->handle_ != ACE_INVALID_HANDLE)
      {
        ACE_OS::closesocket (this->handle_);
        this->handle_ = ACE_INVALID_HANDLE;
      }
  
    this->flg_open_ = false;
  
    return 0;
  }
  
  int
  ACE_POSIX_Asynch_Accept::handle_close (ACE_HANDLE, ACE_Reactor_Mask)
  {
    ACE_TRACE ("ACE_POSIX_Asynch_Accept::handle_close");
  
    ACE_MT (ACE_GUARD_RETURN (ACE_SYNCH_MUTEX, ace_mon, this->lock_, 0));
  
    // handle_close is called in two cases:
    //  1. Pseudo task is closing (i.e. proactor destructor)
    //  2. The listen handle is closed (we don't have exclusive access to this)
  
    this->cancel_uncompleted (0);
  
    this->flg_open_ = false;
    this->handle_ = ACE_INVALID_HANDLE;
    return 0;
  }
  
  int
  ACE_POSIX_Asynch_Accept::handle_input (ACE_HANDLE /* fd */)
  {
    ACE_TRACE ("ACE_POSIX_Asynch_Accept::handle_input");
  
    // An <accept> has been sensed on the <listen_handle>. We should be
    // able to just go ahead and do the <accept> now on this <fd>. This
    // should be the same as the <listen_handle>.
  
    ACE_POSIX_Asynch_Accept_Result* result = 0;
  
    {
      ACE_MT (ACE_GUARD_RETURN (ACE_SYNCH_MUTEX, ace_mon, this->lock_, 0));
  
      // Deregister this info pertaining to this accept call.
      if (this->result_queue_.dequeue_head (result) != 0)
        ACELIB_ERROR ((LM_ERROR,
                    ACE_TEXT("%N:%l:(%P | %t):%p\n"),
                    ACE_TEXT("ACE_POSIX_Asynch_Accept::handle_input:")
                    ACE_TEXT( " dequeueing failed")));
  
      // Disable the handle in the reactor if no more accepts are pending.
      if (this->result_queue_.size () == 0)
        {
          ACE_Asynch_Pseudo_Task & task =
            this->posix_proactor ()->get_asynch_pseudo_task ();
  
          task.suspend_io_handler (this->get_handle());
        }
    }
  
    // Issue <accept> now.
    // @@ We shouldnt block here since we have already done poll/select
    // thru reactor. But are we sure?
  
    ACE_HANDLE new_handle = ACE_OS::accept (this->handle_, 0, 0);
  
    if (result == 0) // there is nobody to notify
      {
        ACE_OS::closesocket (new_handle);
        return 0;
      }
  
    if (new_handle == ACE_INVALID_HANDLE)
      {
        result->set_error (errno);
        ACELIB_ERROR ((LM_ERROR,
                    ACE_TEXT("%N:%l:(%P | %t):%p\n"),
                    ACE_TEXT("ACE_POSIX_Asynch_Accept::handle_input: ")
                    ACE_TEXT("accept")));
  
        // Notify client as usual, "AIO" finished with errors
      }
  
    // Store the new handle.
    result->aio_fildes = new_handle;
  
    // Notify the main process about this completion
    // Send the Result through the notification pipe.
    if (this->posix_proactor ()->post_completion (result) == -1)
      ACELIB_ERROR ((LM_ERROR,
                  ACE_TEXT("Error:(%P | %t):%p\n"),
                  ACE_TEXT("ACE_POSIX_Asynch_Accept::handle_input: ")
                  ACE_TEXT(" <post_completion> failed")));
  
    return 0;
  }
  
  // *********************************************************************
  
  ACE_HANDLE
  ACE_POSIX_Asynch_Connect_Result::connect_handle (void) const
  {
    return this->aio_fildes;
  }
  
  void ACE_POSIX_Asynch_Connect_Result::connect_handle (ACE_HANDLE handle)
  {
    this->aio_fildes = handle;
  }
  
  
  ACE_POSIX_Asynch_Connect_Result::ACE_POSIX_Asynch_Connect_Result
    (const ACE_Handler::Proxy_Ptr &handler_proxy,
     ACE_HANDLE connect_handle,
     const void* act,
     ACE_HANDLE event,
     int priority,
     int signal_number)
    : ACE_POSIX_Asynch_Result
        (handler_proxy, act, event, 0, 0, priority, signal_number)
  {
    this->aio_fildes = connect_handle;
    this->aio_nbytes = 0;
  }
  
  void
  ACE_POSIX_Asynch_Connect_Result::complete (size_t bytes_transferred,
                                             int success,
                                             const void *completion_key,
                                             u_long error)
  {
    // Copy the data.
    this->bytes_transferred_ = bytes_transferred;
    this->success_ = success;
    this->completion_key_ = completion_key;
    this->error_ = error;
  
    // Create the interface result class.
    ACE_Asynch_Connect::Result result (this);
  
    // Call the application handler.
    ACE_Handler *handler = this->handler_proxy_.get ()->handler ();
    if (handler != 0)
      handler->handle_connect (result);
  }
  
  ACE_POSIX_Asynch_Connect_Result::~ACE_POSIX_Asynch_Connect_Result (void)
  {
  }
  
  // *********************************************************************
  
  ACE_POSIX_Asynch_Connect::ACE_POSIX_Asynch_Connect (ACE_POSIX_Proactor * posix_proactor)
    : ACE_POSIX_Asynch_Operation (posix_proactor),
      flg_open_ (false)
  {
  }
  
  ACE_POSIX_Asynch_Connect::~ACE_POSIX_Asynch_Connect (void)
  {
    this->close ();
    this->reactor(0); // to avoid purge_pending_notifications
  }
  
  ACE_HANDLE
  ACE_POSIX_Asynch_Connect::get_handle (void) const
  {
    ACE_ASSERT (0);
    return  ACE_INVALID_HANDLE;
  }
  
  void
  ACE_POSIX_Asynch_Connect::set_handle (ACE_HANDLE)
  {
    ACE_ASSERT (0) ;
  }
  
  int
  ACE_POSIX_Asynch_Connect::open (const ACE_Handler::Proxy_Ptr &handler_proxy,
                                  ACE_HANDLE handle,
                                  const void *completion_key,
                                  ACE_Proactor *proactor)
  {
    ACE_TRACE ("ACE_POSIX_Asynch_Connect::open");
  
    if (this->flg_open_)
      return -1;
  
    //int result =
    ACE_POSIX_Asynch_Operation::open (handler_proxy,
                                      handle,
                                      completion_key,
                                      proactor);
  
    // Ignore result as we pass ACE_INVALID_HANDLE
    //if (result == -1)
    //  return result;
  
    this->flg_open_ = true;
  
    return 0;
  }
  
  int
  ACE_POSIX_Asynch_Connect::connect (ACE_HANDLE connect_handle,
                                     const ACE_Addr & remote_sap,
                                     const ACE_Addr & local_sap,
                                     int reuse_addr,
                                     const void *act,
                                     int priority,
                                     int signal_number)
  {
    ACE_TRACE ("ACE_POSIX_Asynch_Connect::connect");
  
    if (this->flg_open_ == 0)
      ACELIB_ERROR_RETURN ((LM_ERROR,
                         ACE_TEXT("%N:%l:ACE_POSIX_Asynch_Connect::connect")
                         ACE_TEXT("connector was not opened before\n")),
                        -1);
  
    // Common code for both WIN and POSIX.
    // Create future Asynch_Connect_Result
    ACE_POSIX_Asynch_Connect_Result *result = 0;
    ACE_NEW_RETURN (result,
                    ACE_POSIX_Asynch_Connect_Result (this->handler_proxy_,
                                                     connect_handle,
                                                     act,
                                                     this->posix_proactor ()->get_handle (),
                                                     priority,
                                                     signal_number),
                    -1);
  
    int rc = connect_i (result,
                        remote_sap,
                        local_sap,
                        reuse_addr);
  
    // update handle
    connect_handle = result->connect_handle ();
  
    if (rc != 0)
      return post_result (result, true);
  
    //  Enqueue result we will wait for completion
    {
      ACE_MT (ACE_GUARD_RETURN (ACE_SYNCH_MUTEX, ace_mon, this->lock_, -1));
  
      if (this->result_map_.bind (connect_handle, result) == -1)
        {
          ACELIB_ERROR  ((LM_ERROR,
                       ACE_TEXT ("%N:%l:%p\n"),
                       ACE_TEXT ("ACE_POSIX_Asynch_Connect::connect:")
                       ACE_TEXT ("bind")));
  
          result->set_error (EFAULT);
          return post_result (result, true);
        }
    }
  
    ACE_Asynch_Pseudo_Task & task =
      this->posix_proactor ()->get_asynch_pseudo_task ();
  
    rc = task.register_io_handler (connect_handle,
                                   this,
                                   ACE_Event_Handler::CONNECT_MASK,
                                   0);  // don't suspend after register
    if (rc < 0)
      {
        {
          ACE_MT (ACE_GUARD_RETURN (ACE_SYNCH_MUTEX, ace_mon, this->lock_, -1));
  
          this->result_map_.unbind (connect_handle, result);
        }
        if (result != 0)
          {
            result->set_error (EFAULT);
            this->post_result (result, true);
          }
        return -1;
      }
    else
      result = 0;
  
  
    return 0;
  }
  
  int ACE_POSIX_Asynch_Connect::post_result (ACE_POSIX_Asynch_Connect_Result * result,
                                             bool post_enable)
  {
    if (this->flg_open_ && post_enable != 0)
      {
        if (this->posix_proactor ()->post_completion (result) == 0)
          return 0;
  
        ACELIB_ERROR ((LM_ERROR,
                    ACE_TEXT("Error:(%P | %t):%p\n"),
                    ACE_TEXT("ACE_POSIX_Asynch_Connect::post_result: ")
                    ACE_TEXT(" <post_completion> failed")));
      }
  
    ACE_HANDLE handle = result->connect_handle ();
  
    if (handle != ACE_INVALID_HANDLE)
      ACE_OS::closesocket (handle);
  
     delete result;
  
     return -1;
  }
  
  //connect_i
  //  return code :
  //   -1   errors  before  attempt to connect
  //    0   connect started
  //    1   connect finished ( may be unsuccessfully)
  
  int
  ACE_POSIX_Asynch_Connect::connect_i (ACE_POSIX_Asynch_Connect_Result *result,
                                       const ACE_Addr & remote_sap,
                                       const ACE_Addr & local_sap,
                                       int  reuse_addr)
  {
    result->set_bytes_transferred (0);
  
    ACE_HANDLE handle = result->connect_handle ();
  
    if (handle == ACE_INVALID_HANDLE)
      {
        int protocol_family = remote_sap.get_type ();
  
        handle = ACE_OS::socket (protocol_family,
                                 SOCK_STREAM,
                                 0);
        // save it
        result->connect_handle (handle);
        if (handle == ACE_INVALID_HANDLE)
          {
            result->set_error (errno);
            ACELIB_ERROR_RETURN
              ((LM_ERROR,
                ACE_TEXT("ACE_POSIX_Asynch_Connect::connect_i: %p\n"),
                ACE_TEXT("socket")),
               -1);
          }
  
        // Reuse the address
        int one = 1;
        if (protocol_family != PF_UNIX &&
            reuse_addr != 0 &&
            ACE_OS::setsockopt (handle,
                                SOL_SOCKET,
                                SO_REUSEADDR,
                                (const char*) &one,
                                sizeof one) == -1 )
          {
            result->set_error (errno);
            ACELIB_ERROR_RETURN
              ((LM_ERROR,
                ACE_TEXT("ACE_POSIX_Asynch_Connect::connect_i: %p\n"),
                ACE_TEXT("setsockopt")),
               -1);
          }
      }
  
    if (local_sap != ACE_Addr::sap_any)
      {
        sockaddr * laddr = reinterpret_cast<sockaddr *> (local_sap.get_addr ());
        size_t size = local_sap.get_size ();
  
        if (ACE_OS::bind (handle, laddr, size) == -1)
          {
             result->set_error (errno);
             ACELIB_ERROR_RETURN
               ((LM_ERROR,
                 ACE_TEXT("ACE_POSIX_Asynch_Connect::connect_i: %p\n"),
                 ACE_TEXT("bind")),
                -1);
          }
      }
  
    // set non blocking mode
    if (ACE::set_flags (handle, ACE_NONBLOCK) != 0)
      {
        result->set_error (errno);
        ACELIB_ERROR_RETURN
          ((LM_ERROR,
            ACE_TEXT("ACE_POSIX_Asynch_Connect::connect_i: %p\n")
            ACE_TEXT("set_flags")),
           -1);
      }
  
    for (;;)
      {
        int rc = ACE_OS::connect
          (handle,
           reinterpret_cast<sockaddr *> (remote_sap.get_addr ()),
           remote_sap.get_size ());
        if (rc < 0)  // failure
          {
            if (errno == EWOULDBLOCK || errno == EINPROGRESS)
              return 0; // connect started
  
            if (errno == EINTR)
               continue;
  
            result->set_error (errno);
          }
  
        return 1 ;  // connect finished
      }
  
    ACE_NOTREACHED (return 0);
  }
  
  
  //@@ New method cancel_uncompleted
  // It performs cancellation of all pending requests
  //
  // Parameter flg_notify can be
  //     0  - don't send notifications about canceled accepts
  //    !0  - notify user about canceled accepts
  //          according POSIX standards we should receive notifications
  //          on canceled AIO requests
  //
  //  Return value : number of cancelled requests
  //
  
  int
  ACE_POSIX_Asynch_Connect::cancel_uncompleted (bool flg_notify,
                                                ACE_Handle_Set & set)
  {
    ACE_TRACE ("ACE_POSIX_Asynch_Connect::cancel_uncompleted");
  
    int retval = 0;
  
    MAP_MANAGER::ITERATOR  iter (result_map_);
    MAP_MANAGER::ENTRY *   me = 0;
  
    set.reset ();
  
    for (; iter.next (me) != 0;  retval++ , iter.advance ())
      {
         ACE_HANDLE handle = me->ext_id_;
         ACE_POSIX_Asynch_Connect_Result* result = me->int_id_ ;
  
         set.set_bit (handle);
  
         result->set_bytes_transferred (0);
         result->set_error (ECANCELED);
         this->post_result (result, flg_notify);
      }
  
    result_map_.unbind_all ();
  
    return retval;
  }
  
  int
  ACE_POSIX_Asynch_Connect::cancel (void)
  {
    ACE_TRACE ("ACE_POSIX_Asynch_Connect::cancel");
  
    // Since this is not a real asynch I/O operation, we can't just call
    // ::aiocancel () or ACE_POSIX_Asynch_Operation::cancel ().
    // Delegate real cancelation to cancel_uncompleted (1)
  
    int rc = -1 ;  // ERRORS
  
    ACE_Handle_Set set;
    int num_cancelled = 0;
    {
      ACE_MT (ACE_GUARD_RETURN (ACE_SYNCH_MUTEX, ace_mon, this->lock_, -1));
      num_cancelled = cancel_uncompleted (flg_open_, set);
    }
    if (num_cancelled == 0)
      rc = 1 ;        // AIO_ALLDONE
    else if (num_cancelled > 0)
      rc = 0 ;        // AIO_CANCELED
  
    if (!this->flg_open_)
      return rc ;
  
    ACE_Asynch_Pseudo_Task & task =
      this->posix_proactor ()->get_asynch_pseudo_task ();
  
    task.remove_io_handler (set);
    return rc;
  }
  
  int
  ACE_POSIX_Asynch_Connect::close (void)
  {
    ACE_TRACE ("ACE_POSIX_Asynch_Connect::close");
  
    ACE_Handle_Set set ;
    int num_cancelled = 0;
    {
      ACE_MT (ACE_GUARD_RETURN (ACE_SYNCH_MUTEX, ace_mon, this->lock_, -1));
      num_cancelled = cancel_uncompleted (flg_open_, set);
    }
  
    if (num_cancelled == 0 || !this->flg_open_)
      {
        this->flg_open_ = false;
        return 0;
      }
  
    ACE_Asynch_Pseudo_Task & task =
      this->posix_proactor ()->get_asynch_pseudo_task ();
  
    task.remove_io_handler (set);
    this->flg_open_ = false;
  
    return 0;
  }
  
  int
  ACE_POSIX_Asynch_Connect::handle_output (ACE_HANDLE fd)
  {
    ACE_TRACE ("ACE_POSIX_Asynch_Connect::handle_output");
  
    ACE_POSIX_Asynch_Connect_Result* result = 0;
  
    {
      ACE_MT (ACE_GUARD_RETURN (ACE_SYNCH_MUTEX, ace_mon, this->lock_, 0));
      if (this->result_map_.unbind (fd, result) != 0) // not found
        return -1;
    }
  
    int sockerror  = 0 ;
    int lsockerror = sizeof sockerror;
  
    ACE_OS::getsockopt (fd,
                        SOL_SOCKET,
                        SO_ERROR,
                        (char*) &sockerror,
                        &lsockerror);
  
    result->set_bytes_transferred (0);
    result->set_error (sockerror);
  
    // This previously just did a "return -1" and let handle_close() clean
    // things up. However, this entire object may be gone as a result of
    // the application's completion handler, so don't count on 'this' being
    // legitimate on return from post_result().
    // remove_io_handler() contains flag DONT_CALL
    this->posix_proactor ()->get_asynch_pseudo_task ().remove_io_handler (fd);
    this->post_result (result, this->flg_open_);
    return 0;
  }
  
  
  int
  ACE_POSIX_Asynch_Connect::handle_close (ACE_HANDLE fd, ACE_Reactor_Mask)
  {
    ACE_TRACE ("ACE_POSIX_Asynch_Connect::handle_close");
  
    ACE_Asynch_Pseudo_Task &task =
           this->posix_proactor ()->get_asynch_pseudo_task ();
  
    task.remove_io_handler (fd);
  
    ACE_POSIX_Asynch_Connect_Result* result = 0;
  
    {
      ACE_MT (ACE_GUARD_RETURN (ACE_SYNCH_MUTEX, ace_mon, this->lock_, 0));
      if (this->result_map_.unbind (fd, result) != 0) // not found
        return -1;
    }
  
    result->set_bytes_transferred (0);
    result->set_error (ECANCELED);
    this->post_result (result, this->flg_open_);
  
    return 0;
  }
  
  // *********************************************************************
  
  ACE_HANDLE
  ACE_POSIX_Asynch_Transmit_File_Result::socket (void) const
  {
    return this->socket_;
  }
  
  ACE_HANDLE
  ACE_POSIX_Asynch_Transmit_File_Result::file (void) const
  {
    return this->aio_fildes;
  }
  
  ACE_Asynch_Transmit_File::Header_And_Trailer *
  ACE_POSIX_Asynch_Transmit_File_Result::header_and_trailer (void) const
  {
    return this->header_and_trailer_;
  }
  
  size_t
  ACE_POSIX_Asynch_Transmit_File_Result::bytes_to_write (void) const
  {
    return this->aio_nbytes;
  }
  
  size_t
  ACE_POSIX_Asynch_Transmit_File_Result::bytes_per_send (void) const
  {
    return this->bytes_per_send_;
  }
  
  u_long
  ACE_POSIX_Asynch_Transmit_File_Result::flags (void) const
  {
    return this->flags_;
  }
  
  ACE_POSIX_Asynch_Transmit_File_Result::ACE_POSIX_Asynch_Transmit_File_Result
    (const ACE_Handler::Proxy_Ptr &handler_proxy,
     ACE_HANDLE socket,
     ACE_HANDLE file,
     ACE_Asynch_Transmit_File::Header_And_Trailer *header_and_trailer,
     size_t bytes_to_write,
     u_long offset,
     u_long offset_high,
     size_t bytes_per_send,
     u_long flags,
     const void *act,
     ACE_HANDLE event,
     int priority,
     int signal_number)
    : ACE_POSIX_Asynch_Result
       (handler_proxy, act, event, offset, offset_high, priority, signal_number),
      socket_ (socket),
      header_and_trailer_ (header_and_trailer),
      bytes_per_send_ (bytes_per_send),
      flags_ (flags)
  {
    this->aio_fildes = file;
    this->aio_nbytes = bytes_to_write;
  }
  
  void
  ACE_POSIX_Asynch_Transmit_File_Result::complete (size_t bytes_transferred,
                                                   int success,
                                                   const void *completion_key,
                                                   u_long error)
  {
    // Copy the data.
    this->bytes_transferred_ = bytes_transferred;
    this->success_ = success;
    this->completion_key_ = completion_key;
    this->error_ = error;
  
    // We will not do this because (a) the header and trailer blocks may
    // be the same message_blocks and (b) in cases of failures we have
    // no idea how much of what (header, data, trailer) was sent.
    /*
      if (this->success_ && this->header_and_trailer_ != 0)
      {
      ACE_Message_Block *header = this->header_and_trailer_->header ();
      if (header != 0)
      header->rd_ptr (this->header_and_trailer_->header_bytes ());
  
      ACE_Message_Block *trailer = this->header_and_trailer_->trailer ();
      if (trailer != 0)
      trailer->rd_ptr (this->header_and_trailer_->trailer_bytes ());
      }
    */
  
    // Create the interface result class.
    ACE_Asynch_Transmit_File::Result result (this);
  
    // Call the application handler.
    ACE_Handler *handler = this->handler_proxy_.get ()->handler ();
    if (handler != 0)
      handler->handle_transmit_file (result);
  }
  
  ACE_POSIX_Asynch_Transmit_File_Result::~ACE_POSIX_Asynch_Transmit_File_Result (void)
  {
  }
  
  
  // *********************************************************************
  
  /**
   * @class ACE_POSIX_Asynch_Transmit_Handler
   *
   * @brief Auxillary handler for doing <Asynch_Transmit_File> in
   * Unix. <ACE_POSIX_Asynch_Transmit_File> internally uses this.
   *
   * This is a helper class for implementing
   * <ACE_POSIX_Asynch_Transmit_File> in Unix systems.
   */
  class ACE_Export ACE_POSIX_Asynch_Transmit_Handler : public ACE_Handler
  {
  public:
    /// Constructor. Result pointer will have all the information to do
    /// the file transmission (socket, file, application handler, bytes
    /// to write).
    ACE_POSIX_Asynch_Transmit_Handler (ACE_POSIX_Proactor *posix_proactor,
                                       ACE_POSIX_Asynch_Transmit_File_Result *result);
  
    /// Destructor.
    virtual ~ACE_POSIX_Asynch_Transmit_Handler (void);
  
    /// Do the transmission. All the info to do the transmission is in
    /// the <result> member.
    int transmit (void);
  
  protected:
  
    /// The asynch result pointer made from the initial transmit file
    /// request.
    ACE_POSIX_Asynch_Transmit_File_Result *result_;
  
    /// Message bloack used to do the transmission.
    ACE_Message_Block *mb_;
  
    enum ACT
    {
      HEADER_ACT  = 1,
      DATA_ACT    = 2,
      TRAILER_ACT = 3
    };
  
    /// ACT to transmit header.
    ACT header_act_;
  
    /// ACT to transmit data.
    ACT data_act_;
  
    /// ACT to transmit trailer.
    ACT trailer_act_;
  
    /// Current offset of the file being transmitted.
    size_t file_offset_;
  
    /// Total size of the file.
    size_t file_size_;
  
    /// Number of bytes transferred on the stream.
    size_t bytes_transferred_;
  
    /// This is called when asynchronous writes from the socket complete.
    virtual void handle_write_stream (const ACE_Asynch_Write_Stream::Result &result);
  
    /// This is called when asynchronous reads from the file complete.
    virtual void handle_read_file (const ACE_Asynch_Read_File::Result &result);
  
    /// Issue asynch read from  the file.
    int initiate_read_file (void);
  
    /// To read from the file to be transmitted.
    ACE_POSIX_Asynch_Read_File rf_;
  
    /// Write stream to write the header, trailer and the data.
    ACE_POSIX_Asynch_Write_Stream ws_;
  };
  
  // ************************************************************
  
  // Constructor.
  ACE_POSIX_Asynch_Transmit_Handler::ACE_POSIX_Asynch_Transmit_Handler
        (ACE_POSIX_Proactor *posix_proactor,
         ACE_POSIX_Asynch_Transmit_File_Result *result)
    : result_ (result),
      mb_ (0),
      header_act_ (this->HEADER_ACT),
      data_act_ (this->DATA_ACT),
      trailer_act_ (this->TRAILER_ACT),
      file_offset_ (result->offset ()),
      file_size_ (0),
      bytes_transferred_ (0),
      rf_ (posix_proactor),
      ws_ (posix_proactor)
  {
    // Allocate memory for the message block.
    ACE_NEW (this->mb_,
             ACE_Message_Block (this->result_->bytes_per_send ()
                                + 1));
    // Init the file size.
    file_size_ = ACE_OS::filesize (this->result_->file ());
  }
  
  // Destructor.
  ACE_POSIX_Asynch_Transmit_Handler::~ACE_POSIX_Asynch_Transmit_Handler (void)
  {
    delete result_;
    mb_->release ();
  }
  
  
  // Do the transmission.
  // Initiate transmitting the header. When that completes
  // handle_write_stream will be called, there start transmitting the file.
  int
  ACE_POSIX_Asynch_Transmit_Handler::transmit (void)
  {
    // No proactor is given for the <open>'s. Because we are using the
    // concrete implementations of the  Asynch_Operations, and we have
    // already given them the specific proactor, so they wont need the
    // general <proactor> interface pointer.
  
    // Open Asynch_Read_File.
    if (this->rf_.open (this->proxy (),
                        this->result_->file (),
                        0,
                        0) == -1)
      ACELIB_ERROR_RETURN ((LM_ERROR,
                         "ACE_Asynch_Transmit_Handler:read_file open failed\n"),
                        -1);
  
    // Open Asynch_Write_Stream.
    if (this->ws_.open (this->proxy (),
                        this->result_->socket (),
                        0,
                        0) == -1)
      ACELIB_ERROR_RETURN ((LM_ERROR,
                         "ACE_Asynch_Transmit_Handler:write_stream open failed\n"),
                        -1);
  
    // Transmit the header.
    if (this->ws_.write (*this->result_->header_and_trailer ()->header (),
                         this->result_->header_and_trailer ()->header_bytes (),
                         reinterpret_cast<void *> (&this->header_act_),
                         0) == -1)
      ACELIB_ERROR_RETURN ((LM_ERROR,
                         "Asynch_Transmit_Handler:transmitting header:write_stream failed\n"),
                        -1);
    return 0;
  }
  
  void
  ACE_POSIX_Asynch_Transmit_Handler::handle_write_stream (const ACE_Asynch_Write_Stream::Result &result)
  {
    // Update bytes transferred so far.
    this->bytes_transferred_ += result.bytes_transferred ();
  
    // Check the success parameter.
    if (result.success () == 0)
      {
        // Failure.
  
        ACELIB_ERROR ((LM_ERROR,
                    "Asynch_Transmit_File failed.\n"));
  
        ACE_SEH_TRY
          {
            this->result_->complete (this->bytes_transferred_,
                                     0,      // Failure.
                                     0,      // @@ Completion key.
                                     0);     // @@ Error no.
          }
        ACE_SEH_FINALLY
          {
            // This is crucial to prevent memory leaks. This deletes
            // the result pointer also.
            delete this;
          }
      }
  
    // Write stream successful.
  
    // Partial write to socket.
    size_t unsent_data = result.bytes_to_write () - result.bytes_transferred ();
    if (unsent_data != 0)
      {
        ACELIB_DEBUG ((LM_DEBUG,
                    "%N:%l:Partial write to socket: Asynch_write called again\n"));
  
        // Duplicate the message block and retry remaining data
        if (this->ws_.write (*result.message_block ().duplicate (),
                             unsent_data,
                             result.act (),
                             this->result_->priority (),
                             this->result_->signal_number ()) == -1)
          {
            // @@ Handle this error.
            ACELIB_ERROR ((LM_ERROR,
                        "Asynch_Transmit_Handler:write_stream failed\n"));
            return;
          }
  
        // @@ Handling *partial write* to a socket.  Let us not continue
        // further before this write finishes. Because proceeding with
        // another read and then write might change the order of the
        // file transmission, because partial write to the stream is
        // always possible.
        return;
      }
  
    // Not a partial write. A full write.
  
    // Check ACT to see what was sent.
    ACT act = * (ACT *) result.act ();
  
    switch (act)
      {
      case TRAILER_ACT:
        // If it is the "trailer" that is just sent, then transmit file
        // is complete.
        // Call the application handler.
        ACE_SEH_TRY
          {
            this->result_->complete (this->bytes_transferred_,
                                     1,      // @@ Success.
                                     0,      // @@ Completion key.
                                     0);     // @@ Errno.
          }
        ACE_SEH_FINALLY
          {
            delete this;
          }
        break;
  
      case HEADER_ACT:
      case DATA_ACT:
        // If header/data was sent, initiate the file data transmission.
        if (this->initiate_read_file () == -1)
          // @@ Handle this error.
          ACELIB_ERROR ((LM_ERROR,
                      "Error:Asynch_Transmit_Handler:read_file couldnt be initiated\n"));
        break;
  
      default:
        // @@ Handle this error.
        ACELIB_ERROR ((LM_ERROR,
                    "Error:ACE_Asynch_Transmit_Handler::handle_write_stream::Unexpected act\n"));
      }
  }
  
  void
  ACE_POSIX_Asynch_Transmit_Handler::handle_read_file (const ACE_Asynch_Read_File::Result &result)
  {
    // Failure.
    if (result.success () == 0)
      {
        //
        ACE_SEH_TRY
          {
            this->result_->complete (this->bytes_transferred_,
                                     0,      // Failure.
                                     0,      // @@ Completion key.
                                     errno); // Error no.
          }
        ACE_SEH_FINALLY
          {
            delete this;
          }
        return;
      }
  
    // Read successful.
    if (result.bytes_transferred () == 0)
      return;
  
    // Increment offset.
    this->file_offset_ += result.bytes_transferred ();
  
    // Write data to network.
    if (this->ws_.write (result.message_block (),
                         result.bytes_transferred (),
                         (void *)&this->data_act_,
                         this->result_->priority (),
                         this->result_->signal_number ()) == -1)
      {
        // @@ Handle this error.
        ACELIB_ERROR ((LM_ERROR,
                    "Error:ACE_Asynch_Transmit_File : write to the stream failed\n"));
        return;
      }
  }
  
  int
  ACE_POSIX_Asynch_Transmit_Handler::initiate_read_file (void)
  {
    // Is there something to read.
    if (this->file_offset_ >= this->file_size_)
      {
        // File is sent. Send the trailer.
        if (this->ws_.write (*this->result_->header_and_trailer ()->trailer (),
                             this->result_->header_and_trailer ()->trailer_bytes (),
                             (void *)&this->trailer_act_,
                             this->result_->priority (),
                             this->result_->signal_number ()) == -1)
          ACELIB_ERROR_RETURN ((LM_ERROR,
                             "Error:Asynch_Transmit_Handler:write_stream writing trailer failed\n"),
                            -1);
        return 0;
      }
    else
      {
        // @@ Is this right??
        // Previous reads and writes are over. For the new read, adjust
        // the wr_ptr and the rd_ptr to the beginning.
        this->mb_->rd_ptr (this->mb_->base ());
        this->mb_->wr_ptr (this->mb_->base ());
  
        // Inititiate an asynchronous read from the file.
        if (this->rf_.read (*this->mb_,
                            this->mb_->size () - 1,
                            this->file_offset_,
                            0, // @@ offset_high !!! if aiocb64 is used.
                            0, // Act
                            this->result_->priority (),
                            this->result_->signal_number ()) == -1)
          ACELIB_ERROR_RETURN ((LM_ERROR,
                             "Error:Asynch_Transmit_Handler::read from file failed\n"),
                            -1);
        return 0;
      }
  }
  
  // *********************************************************************
  
  ACE_POSIX_Asynch_Transmit_File::ACE_POSIX_Asynch_Transmit_File (ACE_POSIX_Proactor *posix_proactor)
    : ACE_POSIX_Asynch_Operation (posix_proactor)
  {
  }
  
  int
  ACE_POSIX_Asynch_Transmit_File::transmit_file (ACE_HANDLE file,
                                                 ACE_Asynch_Transmit_File::Header_And_Trailer *header_and_trailer,
                                                 size_t bytes_to_write,
                                                 u_long offset,
                                                 u_long offset_high,
                                                 size_t bytes_per_send,
                                                 u_long flags,
                                                 const void *act,
                                                 int priority,
                                                 int signal_number)
  {
    // Adjust these parameters if there are default values specified.
    ssize_t file_size = ACE_OS::filesize (file);
  
    if (file_size == -1)
      ACELIB_ERROR_RETURN ((LM_ERROR,
                         ACE_TEXT("Error:%N:%l:%p\n"),
                         ACE_TEXT("POSIX_Asynch_Transmit_File:filesize failed")),
                        -1);
  
    if (bytes_to_write == 0)
      bytes_to_write = file_size;
  
    if (offset > (size_t) file_size)
      ACELIB_ERROR_RETURN ((LM_ERROR,
                         ACE_TEXT("Error:%p\n"),
                         ACE_TEXT("Asynch_Transmit_File:File size is less than offset")),
                        -1);
  
    if (offset != 0)
      bytes_to_write = file_size - offset + 1;
  
    if (bytes_per_send == 0)
      bytes_per_send = bytes_to_write;
  
    // Configure the result parameter.
    ACE_POSIX_Asynch_Transmit_File_Result *result = 0;
  
    ACE_NEW_RETURN (result,
                    ACE_POSIX_Asynch_Transmit_File_Result (this->handler_proxy_,
                                                           this->handle_,
                                                           file,
                                                           header_and_trailer,
                                                           bytes_to_write,
                                                           offset,
                                                           offset_high,
                                                           bytes_per_send,
                                                           flags,
                                                           act,
                                                           this->posix_proactor ()->get_handle (),
                                                           priority,
                                                           signal_number),
                    -1);
  
    // Make the auxillary handler and initiate transmit.
    ACE_POSIX_Asynch_Transmit_Handler *transmit_handler = 0;
  
    ACE_NEW_RETURN (transmit_handler,
                    ACE_POSIX_Asynch_Transmit_Handler (this->posix_proactor (),
                                                       result),
                    -1);
  
    ssize_t return_val = transmit_handler->transmit ();
  
    if (return_val == -1)
      // This deletes the <result> in it too.
      delete transmit_handler;
  
    return 0;
  }
  
  ACE_POSIX_Asynch_Transmit_File::~ACE_POSIX_Asynch_Transmit_File (void)
  {
  }
  
  // *********************************************************************
  size_t
  ACE_POSIX_Asynch_Read_Dgram_Result::bytes_to_read (void) const
  {
    return this->bytes_to_read_;
  }
  
  int
  ACE_POSIX_Asynch_Read_Dgram_Result::remote_address (ACE_Addr& addr) const
  {
    int retVal = -1;  // failure
  
    // make sure the addresses are of the same type
    if (addr.get_type () == this->remote_address_->get_type ())
    { // copy the remote_address_ into addr
      addr.set_addr (this->remote_address_->get_addr (),
                     this->remote_address_->get_size ());
      retVal = 0; // success
    }
  
    return retVal;
  }
  
  sockaddr *
  ACE_POSIX_Asynch_Read_Dgram_Result::saddr () const
  {
    return (sockaddr *) this->remote_address_->get_addr ();
  }
  
  
  int
  ACE_POSIX_Asynch_Read_Dgram_Result::flags (void) const
  {
    return this->flags_;
  }
  
  ACE_HANDLE
  ACE_POSIX_Asynch_Read_Dgram_Result::handle (void) const
  {
    return this->handle_;
  }
  
  ACE_Message_Block*
  ACE_POSIX_Asynch_Read_Dgram_Result::message_block () const
  {
    return this->message_block_;
  }
  
  ACE_POSIX_Asynch_Read_Dgram_Result::ACE_POSIX_Asynch_Read_Dgram_Result
    (const ACE_Handler::Proxy_Ptr &handler_proxy,
     ACE_HANDLE handle,
     ACE_Message_Block *message_block,
     size_t bytes_to_read,
     int flags,
     int protocol_family,
     const void* act,
     ACE_HANDLE event,
     int priority,
     int signal_number)
    : ACE_POSIX_Asynch_Result
        (handler_proxy, act, event, 0, 0, priority, signal_number),
      bytes_to_read_ (bytes_to_read),
      message_block_ (message_block),
      remote_address_ (0),
      addr_len_ (0),
      flags_ (flags),
      handle_ (handle)
  {
    ACE_UNUSED_ARG (protocol_family);
    this->aio_fildes = handle;
    this->aio_buf = message_block->wr_ptr ();
    this->aio_nbytes = bytes_to_read;
    ACE_NEW (this->remote_address_, ACE_INET_Addr);
  }
  
  void
  ACE_POSIX_Asynch_Read_Dgram_Result::complete (size_t bytes_transferred,
                                                int success,
                                                const void *completion_key,
                                                u_long error)
  {
    // Copy the data which was returned by GetQueuedCompletionStatus
    this->bytes_transferred_ = bytes_transferred;
    this->success_ = success;
    this->completion_key_ = completion_key;
    this->error_ = error;
  
    // Appropriately move the pointers in the message block.
    this->message_block_->wr_ptr (bytes_transferred);
  
    // <errno> is available in the aiocb.
    ACE_UNUSED_ARG (error);
  
   this->remote_address_->set_size(this->addr_len_);
  
    // Create the interface result class.
    ACE_Asynch_Read_Dgram::Result result (this);
  
    // Call the application handler.
    ACE_Handler *handler = this->handler_proxy_.get ()->handler ();
    if (handler != 0)
      handler->handle_read_dgram (result);
  }
  
  ACE_POSIX_Asynch_Read_Dgram_Result::~ACE_POSIX_Asynch_Read_Dgram_Result (void)
  {
    delete this->remote_address_;
  }
  
  //***************************************************************************
  size_t
  ACE_POSIX_Asynch_Write_Dgram_Result::bytes_to_write (void) const
  {
    return this->bytes_to_write_;
  }
  
  int
  ACE_POSIX_Asynch_Write_Dgram_Result::flags (void) const
  {
    return this->flags_;
  }
  
  ACE_HANDLE
  ACE_POSIX_Asynch_Write_Dgram_Result::handle (void) const
  {
    return this->handle_;
  }
  
  
  ACE_Message_Block*
  ACE_POSIX_Asynch_Write_Dgram_Result::message_block () const
  {
    return this->message_block_;
  }
  
  ACE_POSIX_Asynch_Write_Dgram_Result::ACE_POSIX_Asynch_Write_Dgram_Result
    (const ACE_Handler::Proxy_Ptr &handler_proxy,
     ACE_HANDLE handle,
     ACE_Message_Block *message_block,
     size_t bytes_to_write,
     int flags,
     const void* act,
     ACE_HANDLE event,
     int priority,
     int signal_number)
    : ACE_POSIX_Asynch_Result
       (handler_proxy, act, event, 0, 0, priority, signal_number),
      bytes_to_write_ (bytes_to_write),
      message_block_ (message_block),
      flags_ (flags),
      handle_ (handle)
  
  {
    this->aio_fildes = handle;
    this->aio_buf = message_block->rd_ptr ();
    this->aio_nbytes = bytes_to_write;
  }
  
  void
  ACE_POSIX_Asynch_Write_Dgram_Result::complete (size_t bytes_transferred,
                                                 int success,
                                                 const void *completion_key,
                                                 u_long error)
  {
    // Copy the data which was returned by GetQueuedCompletionStatus
    this->bytes_transferred_ = bytes_transferred;
    this->success_ = success;
    this->completion_key_ = completion_key;
    this->error_ = error;
  
    // <errno> is available in the aiocb.
    ACE_UNUSED_ARG (error);
  
    // Appropriately move the pointers in the message block.
    this->message_block_->rd_ptr (bytes_transferred);
  
    // Create the interface result class.
    ACE_Asynch_Write_Dgram::Result result (this);
  
    // Call the application handler.
    ACE_Handler *handler = this->handler_proxy_.get ()->handler ();
    if (handler != 0)
      handler->handle_write_dgram (result);
  }
  
  ACE_POSIX_Asynch_Write_Dgram_Result::~ACE_POSIX_Asynch_Write_Dgram_Result (void)
  {
  }
  
  /***************************************************************************/
  ACE_POSIX_Asynch_Read_Dgram::~ACE_POSIX_Asynch_Read_Dgram (void)
  {
  }
  
  ssize_t
  ACE_POSIX_Asynch_Read_Dgram::recv (ACE_Message_Block *message_block,
                                     size_t & /*number_of_bytes_recvd*/,
                                     int flags,
                                     int protocol_family,
                                     const void *act,
                                     int priority,
                                     int signal_number)
  {
    size_t space = message_block->space ();
    // Create the Asynch_Result.
    ACE_POSIX_Asynch_Read_Dgram_Result *result = 0;
    ACE_POSIX_Proactor *proactor = this->posix_proactor ();
    ACE_NEW_RETURN (result,
                    ACE_POSIX_Asynch_Read_Dgram_Result (this->handler_proxy_,
                                                        this->handle_,
                                                        message_block,
                                                        space,
                                                        flags,
                                                        protocol_family,
                                                        act,
                                                        proactor->get_handle (),
                                                        priority,
                                                        signal_number),
                    -1);
  
    int return_val = proactor->start_aio (result, ACE_POSIX_Proactor::ACE_OPCODE_READ);
    if (return_val == -1)
      delete result;
  
    return return_val;
  }
  
  ACE_POSIX_Asynch_Read_Dgram::ACE_POSIX_Asynch_Read_Dgram (ACE_POSIX_Proactor *posix_proactor)
    : ACE_POSIX_Asynch_Operation (posix_proactor)
  {
  }
  
  //***************************************************************************
  
  ACE_POSIX_Asynch_Write_Dgram::~ACE_POSIX_Asynch_Write_Dgram (void)
  {
  }
  
  ssize_t
  ACE_POSIX_Asynch_Write_Dgram::send (ACE_Message_Block *message_block,
                                      size_t &/*number_of_bytes_sent*/,
                                      int flags,
                                      const ACE_Addr &/*addr*/,
                                      const void *act,
                                      int priority,
                                      int signal_number)
  {
    size_t len = message_block->length ();
    if (len == 0)
      ACELIB_ERROR_RETURN
        ((LM_ERROR,
          ACE_TEXT ("ACE_POSIX_Asynch_Write_Stream::write:")
          ACE_TEXT ("Attempt to write 0 bytes\n")),
        -1);
  
    ACE_POSIX_Asynch_Write_Dgram_Result *result = 0;
    ACE_POSIX_Proactor *proactor = this->posix_proactor ();
    ACE_NEW_RETURN (result,
                    ACE_POSIX_Asynch_Write_Dgram_Result (this->handler_proxy_,
                                                         this->handle_,
                                                         message_block,
                                                         len,
                                                         flags,
                                                         act,
                                                         proactor->get_handle (),
                                                         priority,
                                                         signal_number),
                    -1);
  
    int return_val = proactor->start_aio (result, ACE_POSIX_Proactor::ACE_OPCODE_WRITE);
    if (return_val == -1)
      delete result;
  
    return return_val;
  }
  
  ACE_POSIX_Asynch_Write_Dgram::ACE_POSIX_Asynch_Write_Dgram
    (ACE_POSIX_Proactor *posix_proactor)
    : ACE_POSIX_Asynch_Operation (posix_proactor)
  {
  }
  
  ACE_END_VERSIONED_NAMESPACE_DECL
  
  #endif /* ACE_HAS_AIO_CALLS */
  