[Ace-users] [ace-users] ACE_Select_Reactor_Handler_Repository Bug

Paul Daugherty paul at nextalk.com
Thu Mar 6 15:47:18 CST 2008


    ACE VERSION: 

        5.5 (Not an issue with 5.6.3 - see below)

    HOST MACHINE and OPERATING SYSTEM:

        Windows

    TARGET MACHINE and OPERATING SYSTEM, if different from HOST:
    COMPILER NAME AND VERSION (AND PATCHLEVEL):

        N/A

    THE $ACE_ROOT/ace/config.h FILE [if you use a link to a platform-
    specific file, simply state which one]:
    
        #if defined (WIN32)
        #  define ACE_HAS_MFC 1
        #  if defined (NXI_USE_SSL)
        #    define ACE_SSL_HAS_DLL 1
        #    define ACE_SSL_BUILD_DLL
        #  endif // NXI_USE_SSL
        #  include "ace/config-win32.h"
        #  if defined (ACE_HAS_WCHAR)
        #    undef ACE_HAS_WCHAR
        #  endif // ACE_HAS_WCHAR
        #elif defined(linux) // WIN32
        #  define ACE_HAS_LINUX_EPOLL
        #  include "config-linux.h"
        #endif // WIN32

    AREA/CLASS/EXAMPLE AFFECTED:

        N/A

    DOES THE PROBLEM AFFECT:

        The problem affects the WIN32 proactor when the notification
pipe fails to open.

        The ACE_Select_Reactor_Handler_Repository has been refactored
since version 5.5; however, I am still submitting this bug in case
anybody is still using and/or supporting version 5.5.

        If this is a well-known issue, then I apologize in advance.

    SYNOPSIS:

        ACE_Select_Reactor_Handler_Repository::bind will cause a crash
if the notification pipe's listen call fails during ACE_Proactor
construction.

    DESCRIPTION:        

        When constructing an ACE_Proactor, The ACE_Asynch_Pseudo_Task
constructor will construct an ACE_Select_Reactor which in turn opens an
ACE_Select_Reactor_Handler_Repository and an ACE_Pipe for notifications.
On a heavily loaded system, ACE_Pipe::open fails with ENOBUFS and the
ACE_Select_Reactor will close the ACE_Select_Reactor_Handler_Repository.

        This failure goes undetected since it occurs in the ACE_Proactor
constructor.

        Next, when an asynch operation is issued like
ACE_Asynch_Connector::connect that does not complete immediately, the
ACE_Select_Reactor_Handler_Repository::event_handlers_ member is
eventually accessed via ACE_Select_Reactor_Handler_Repository::bind and
a crash occurs.

    REPEAT BY:

        This is a quick test that I wrote to ensure this is not a
problem with the 5.6.3 code (it is not):

        class Bogus_Handler : public ACE_Event_Handler
        {
        public:
          Bogus_Handler () {}
          virtual ~Bogus_Handler () {}
        };

        int
        run_main (int, ACE_TCHAR *[])
        {
          ACE_START_TEST (ACE_TEXT ("Paul_Daugherty_Test"));

          Bogus_Handler event_handler;
          ACE_Pipe notification_pipe;
          ACE_Select_Reactor select_reactor;
          ACE_Select_Reactor_Handler_Repository rep (select_reactor);

          int ret = notification_pipe.open ();
          if (0 == ret)
            {      
              ret = rep.open (1024);
            }
          if (0 == ret)
            {
              rep.close ();

              // The following causes a crash on 5.5.  bind is called if
an
              // asynch connect is issued and it does not complete
immediately,
              // i.e. connect_i returns 0 instead of 1.
 
              rep.bind (notification_pipe.read_handle(),
                &event_handler,
                ACE_Event_Handler::READ_MASK);
            }

          ACE_END_TEST;

          return ret;
        }

    SAMPLE FIX/WORKAROUND:

        In file Select_Reactor_Base.cpp,
ACE_Select_Reactor_Handler_Repository::bind, replace the conditional on
line 258:

          else if (this->max_handlep1_ < this->max_size_)

        with:
        
          else if (this->event_handlers_ && this->max_handlep1_ <
this->max_size_)

        Of course the better workaround is to upgrade to 5.6.3 which we
plan to do soon ;-)



More information about the Ace-users mailing list