Changeset 592

Show
Ignore:
Timestamp:
11/27/07 09:29:34 (1 year ago)
Author:
blackhedd
Message:

Added a hack to return subprocess exit-status from EM#popen.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • version_0/ChangeLog

    r581 r592  
    939319Nov07: Fixed bug with EM::Connection#start_tls. Was not working with server 
    9494        connections. Reported by Michael S. Fischer. 
     9526Nov07: Supported a hack for EventMachine#popen so it can return an exit 
     96        status from subprocesses. Requested by Michael S. Fischer. 
  • version_0/ext/cmain.cpp

    r591 r592  
    284284        if (!EventMachine) 
    285285                throw std::runtime_error ("not initialized"); 
    286         EventableDescriptor *ed = dynamic_cast <EventableDescriptor*> (Bindable_t::GetObject (binding)); 
    287         if (ed) { 
    288                 return ed->GetSubprocessStatus (status) ? 1 : 0
     286        if (status) { 
     287               *status = EventMachine->SubprocessExitStatus; 
     288                return 1
    289289        } 
    290290        else 
  • version_0/ext/ed.h

    r591 r592  
    6464                virtual bool GetPeername (struct sockaddr*) {return false;} 
    6565                virtual bool GetSubprocessPid (pid_t*) {return false;} 
    66                 virtual bool GetSubprocessStatus (int*) {return false;} 
    6766 
    6867                virtual void StartTls() {} 
     
    291290 
    292291                virtual bool GetSubprocessPid (pid_t*); 
    293                 virtual bool GetSubprocessStatus (int*); 
    294292 
    295293        protected: 
     
    311309 
    312310                pid_t SubprocessPid; 
    313                 int SubprocessStatus; 
    314311 
    315312        private: 
  • version_0/ext/em.h

    r580 r592  
    8585                static int SetRlimitNofile (int); 
    8686 
     87                int SubprocessExitStatus; 
     88 
    8789                // Temporary: 
    8890                void _UseEpoll(); 
    89  
    90                 /* 
    91         public: 
    92                 enum { // Event names 
    93                         TIMER_FIRED = 100, 
    94                         CONNECTION_READ = 101, 
    95                         CONNECTION_UNBOUND = 102, 
    96                         CONNECTION_ACCEPTED = 103, 
    97                         CONNECTION_COMPLETED = 104, 
    98                         LOOPBREAK_SIGNAL = 105 
    99                 }; 
    100                 */ 
    10191 
    10292 
  • version_0/ext/pipe.cpp

    r591 r592  
    3434        InactivityTimeout (0), 
    3535        OutboundDataSize (0), 
    36         SubprocessPid (subpid), 
    37         SubprocessStatus (0) 
     36        SubprocessPid (subpid) 
    3837{ 
    3938        #ifdef HAVE_EPOLL 
     
    7372         * client-visible API, let's wait until that is done before cleaning 
    7473         * this up. 
     74         * 
     75         * Added a very ugly hack to support passing the subprocess's exit 
     76         * status to the user. It only makes logical sense for user code to access 
     77         * the subprocess exit status in the unbind callback. But unbind is called 
     78         * back during the EventableDescriptor destructor. So by that time there's 
     79         * no way to call back this object through an object binding, because it's 
     80         * already been cleaned up. We might have added a parameter to the unbind 
     81         * callback, but that would probably break a huge amount of existing code. 
     82         * So the hack-solution is to define an instance variable in the EventMachine 
     83         * object and stick the exit status in there, where it can easily be accessed 
     84         * with an accessor visible to user code. 
     85         * User code should ONLY access the exit status from within the unbind callback. 
     86         * Otherwise there's no guarantee it'll be valid. 
     87         * This hack won't make it impossible to run multiple EventMachines in a single 
     88         * process, but it will make it impossible to reliably nest unbind calls 
     89         * within other unbind calls. (Not sure if that's even possible.) 
    7590         */ 
    7691 
     
    7893        kill (SubprocessPid, SIGTERM); 
    7994        nanosleep (&req, NULL); 
    80         if (waitpid (SubprocessPid, &SubprocessStatus, WNOHANG) == 0) { 
     95        assert (MyEventMachine); 
     96        if (waitpid (SubprocessPid, &(MyEventMachine->SubprocessExitStatus), WNOHANG) == 0) { 
    8197                kill (SubprocessPid, SIGKILL); 
    8298                nanosleep (&req, NULL); 
    83                 if (waitpid (SubprocessPid, &SubprocessStatus, WNOHANG) == 0) 
     99                if (waitpid (SubprocessPid, &(MyEventMachine->SubprocessExitStatus), WNOHANG) == 0) 
    84100                        throw std::runtime_error ("unable to reap subprocess"); 
    85101        } 
     
    304320} 
    305321 
    306 /*********************************** 
    307 PipeDescriptor::GetSubprocessStatus 
    308 ***********************************/ 
    309  
    310 bool PipeDescriptor::GetSubprocessStatus (int *status) 
    311 { 
    312         bool ok = false; 
    313         if (status) { 
    314                 *status = SubprocessStatus; 
    315                 ok = true; 
    316         } 
    317         return ok; 
    318 } 
    319322 
    320323#endif // OS_UNIX