[Ace-users] [ace-users] ACE_Select_Reactor not calling handle_output( )

p_j_r_m p_j_r_m at yahoo.com
Mon Nov 26 10:42:42 CST 2007


ACE VERSION: 5.5
      HOST MACHINE and OPERATING SYSTEM:
          Linux 2.6.9 Kernel.CentOS4.2 (32bit)
      COMPILER NAME AND VERSION (AND PATCHLEVEL):
         gcc version 3.4.4 20050721 (Red Hat 3.4.4-2)
      THE $ACE_ROOT/ace/config.h FILE: #include "ace/config-linux.h"
      THE $ACE_ROOT/include/makeinclude/platform_macros.GNU FILE:platform_linux.GNU
  
      CONTENTS OF $ACE_ROOT/bin/MakeProjectCreator/config/default.rel
      // This is the default relative definitions.  Wildcards are acceptable.
  //
  // The first column is the name for which we create a relative definition.
  // The second (optional) column is the value to build up if it isn't defined
  // as an environmenment variable.
   *_ROOT
  TAO_ROOT,  $ACE_ROOT/TAO
  CIAO_ROOT, $TAO_ROOT/CIAO
  
      AREA/CLASS/EXAMPLE AFFECTED:ACE_Select_Reactor
      DOES THE PROBLEM AFFECT:
          COMPILATION? NO
          LINKING? NO
          EXECUTION? YES
          OTHER (please specify)? 
      SYNOPSIS:
     A simple, syncronous ACE::recv_n in hadle_input( ) followed by a simple ACE::send_n( ) sendng data does not work for me
      DESCRIPTION:
      I'm  building a simple echo test program.
      I have an ACE_Select_Reactor listening in a port waiting data to be sent by telnet, for example. The reactor is registered for READ events. When telnet client connects, I write eight bytes in terminal. ACE_Reactors calls handle_input() , who tries to read the 8 bytes, and then (still inside handle_input() ) it does a schedule_cancel( ) on read events, and a schedule_wakeup for WRITE events. I think ACE_Reactor should call handle_ouput( ) , but it is never called, so I can send the answer to the client.  Only handle_input( ) gets called.
  The idea is to control when I want to be notified for read or write in my Event Handler, because my protocol needs to exchange some packets syncronously in the right order. Is there any kind of read priorization over send outpur in the way ACE_reactor manage events? 
  
      REPEAT BY:
      See test program
  
      SAMPLE FIX/WORKAROUND: ?
  
  My program is:
  
  #include "ace/ACE.h"
  #include "ace/INET_Addr.h"
  #include "ace/SOCK_Acceptor.h"
  #include "ace/Reactor.h"
  #include "ace/Acceptor.h"
  #include "ace/Select_Reactor.h"
  #include "ace/Svc_Handler.h"
   #include "ace/SOCK_Stream.h"
  
  // Test program to read 8 bytes, then echo them to the client
  // To test, compila the program,boot it,and do a telnet to 127.0.0.1 7020 port and send exactly 8 bytes
  // I have tryed also writng a simple sockets program that sends exactly 8 bytes
  // 
  
  class MyEH : public ACE_Svc_Handler<ACE_SOCK_STREAM, ACE_NULL_SYNCH>
  {
  public:
      // Will wait 8 bytes,then answer to the client with them
      MyEH (): m_iLenData(8),m_iReceived(0){}
      
      int open(void *p);
      int handle_input (ACE_HANDLE fd = ACE_INVALID_HANDLE);
      int handle_output (ACE_HANDLE fd = ACE_INVALID_HANDLE);
      int handle_close (ACE_HANDLE handle,
                     ACE_Reactor_Mask close_mask);
  
       char m_pBuffer[256];
      int m_iLenData;
      int m_iReceived;
  };
  
  int MyEH::open (void *p)
  {
    ACE_TCHAR peer_name[MAXHOSTNAMELEN];
    ACE_INET_Addr peer_addr;
      
    if (this->peer().get_remote_addr (peer_addr) == 0 &&
        peer_addr.addr_to_string (peer_name, MAXHOSTNAMELEN) == 0)
              printf("New incoming connection from %s\n",peer_name);
    
    if (reactor ()->register_handler (this, ACE_Event_Handler::READ_MASK ) == -1)
      printf("Read_Handler::open, cannot register handler\n");
  
    //peer().enable(ACE_NONBLOCK);
    
    return 0;
  }
  int MyEH::handle_input (ACE_HANDLE h)
  {
      size_t result;
      
      printf("\nrecv(%d) HEADER  waiting %d bytes\n",h,m_iLenData - m_iReceived);
      result = ACE::recv_n (h,&m_pBuffer[m_iReceived],m_iLenData - m_iReceived);
      if(result<=0)
      {    
          if(errno == EWOULDBLOCK)
          {
                  printf("WOULDBLOCK\n");
                  return 0;
          }
          return -1;
      }
          
      m_iReceived+= result;
          
      if(m_iReceived == m_iLenData)
      {
          m_pBuffer[m_iReceived] = 0;
  
           printf("recv(%d) DATA %d %s\n",h,m_iReceived,m_pBuffer);
          
          m_iLenData = 8; // nest time,receive 8 again
          m_iReceived = 0;
      }
      else 
          return result;
              
      printf("Received %d bytes.Setting IO\n",m_iReceived);
      
      if (ACE_Reactor::instance ()->cancel_wakeup (this, ACE_Event_Handler::READ_MASK) == -1)
          return -1;
      printf("Input for %d disabled\n",h);
      if (ACE_Reactor::instance ()->schedule_wakeup (this, ACE_Event_Handler::WRITE_MASK) == -1)
          return -1;    
      printf("Output for %d  enabled\n",h);
      
      return result;
  }
  
  int MyEH::handle_output (ACE_HANDLE h)
  {
      printf("\nhandle_output(%d) called\n",h);
      
      int rc = ACE::send_n(h,m_pBuffer,strlen(m_pBuffer));
      if (rc <= 0)
          printf("Error header send\n");
      else        
          printf("HEADER %s sent %d\n",m_pBuffer,rc);
      
      printf("handle_output() %d\n",rc);
      
     if (ACE_Reactor::instance ()->cancel_wakeup  (this, ACE_Event_Handler::WRITE_MASK) != -1)    
              printf("Ouput for %d disabled\n",get_handle());
      if (ACE_Reactor::instance  ()->schedule_wakeup  (this, ACE_Event_Handler::READ_MASK) == -1)
          return -1;    
      printf("Input for %d enabled\n",get_handle());
      
      return rc;
  }
  
  int MyEH::handle_close (ACE_HANDLE,ACE_Reactor_Mask)
  {
      printf("Close\n");
      this->reactor ()->end_reactor_event_loop ();
      delete this;
      
      return 0;
  }
  
  typedef ACE_Acceptor<MyEH, ACE_SOCK_ACCEPTOR> MyAcceptor;
  
  int main (int, ACE_TCHAR *[])
  {
      ACE_Select_Reactor select_reactor;
      ACE_Reactor reactor ((ACE_Reactor_Impl *)&select_reactor);
      
      ACE_INET_Addr listenAddress("127.0.0.1:7020");
      MyAcceptor acceptor;
       
      acceptor.reactor (ACE_Reactor::instance (&reactor));
      if (acceptor.open (listenAddress) == -1)
      {
          printf("Listen error\n");
          exit(0);    
      }
      else
      {
          printf("Working...\n");
      }
      
      reactor.run_reactor_event_loop ();
  
      return 0;
  }
       
---------------------------------
Be a better sports nut! Let your teams follow you with Yahoo Mobile. Try it now.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://list.isis.vanderbilt.edu/pipermail/ace-users/attachments/20071126/ed7ee019/attachment.html 


More information about the Ace-users mailing list