Changeset 384
- Timestamp:
- 06/12/07 21:05:56 (2 years ago)
- Files:
-
- version_0/ext/cmain.cpp (modified) (1 diff)
- version_0/ext/ed.h (modified) (1 diff)
- version_0/ext/em.h (modified) (1 diff)
- version_0/ext/eventmachine.h (modified) (1 diff)
- version_0/ext/pipe.cpp (modified) (2 diffs)
- version_0/ext/project.h (modified) (1 diff)
- version_0/ext/rubymain.cpp (modified) (2 diffs)
- version_0/lib/eventmachine.rb (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
version_0/ext/cmain.cpp
r383 r384 214 214 } 215 215 216 /*********************** 217 evma_get_subprocess_pid 218 ***********************/ 219 220 extern "C" int evma_get_subprocess_pid (const char *binding, pid_t *pid) 221 { 222 if (!EventMachine) 223 throw std::runtime_error ("not initialized"); 224 EventableDescriptor *ed = dynamic_cast <EventableDescriptor*> (Bindable_t::GetObject (binding)); 225 if (ed) { 226 return ed->GetSubprocessPid (pid) ? 1 : 0; 227 } 228 else 229 return 0; 230 } 231 216 232 217 233 /********************* version_0/ext/ed.h
r381 r384 293 293 time_t LastIo; 294 294 int InactivityTimeout; 295 FILE *MyStream;295 //FILE *MyStream; 296 296 297 297 deque<OutboundPage> OutboundPages; version_0/ext/em.h
r383 r384 71 71 const char *CreateUnixDomainServer (const char*); 72 72 const char *_OpenFileForWriting (const char*); 73 const char *Popen (const char*, const char*);73 //const char *Popen (const char*, const char*); 74 74 const char *Socketpair (char* const*); 75 75 version_0/ext/eventmachine.h
r383 r384 45 45 void evma_start_tls (const char *binding); 46 46 int evma_get_peername (const char *binding, struct sockaddr*); 47 int evma_get_subprocess_pid (const char *binding, pid_t*); 47 48 int evma_send_data_to_connection (const char *binding, const char *data, int data_length); 48 49 int evma_send_datagram (const char *binding, const char *data, int data_length, const char *address, int port); version_0/ext/pipe.cpp
r381 r384 30 30 LastIo (gCurrentLoopTime), 31 31 InactivityTimeout (0), 32 MyStream (fp),32 //MyStream (fp), 33 33 OutboundDataSize (0), 34 34 SubprocessPid (subpid) … … 51 51 52 52 /* As a virtual destructor, we come here before the base-class 53 * destructor that closes our file-descriptor. Calling pclose 54 * doesn't seem to bother the base-class destructor any, and it's 55 * required for cleaning up the subprocess zombie. 56 * Eventually we may need to refactor some of this stuff if there 57 * are undesirable interactions. 58 * Note that calling pclose on a still-running subprocess called 59 * with mode "r" will often cause the subprocess to catch SIGPIPE. 60 * This is part of the behavior of popen and not something EM is doing. 53 * destructor that closes our file-descriptor. 54 * We have to make sure the subprocess goes down (if it's not 55 * already down) and we have to reap the zombie. 61 56 * 62 * Something weirder and worse happens with mode "w" - 63 * pclose WILL HANG irretrievably if the subprocess doesn't 64 * close when we tell it to. It will see a close on its end 65 * of the pipe (the read end), but that doesn't mean it will 66 * be written so as to exit when that happens. 67 * pclose waits for the subprocess to terminate. 68 * (Is there a flavor of popen that has a timeout or a no-hang 69 * option?) 57 * This implementation is PROVISIONAL and will surely be improved. 58 * The intention here is that we never block, hence the highly 59 * undesirable sleeps. But if we can't reap the subprocess even 60 * after sending it SIGKILL, then something is wrong and we 61 * throw a fatal exception, which is also not something we should 62 * be doing. 70 63 * 71 * pclose returns the termination status of the subprocess. 72 * Someday we may need to make that available to the caller, 73 * possibly as an argument to the UNBOUND event. 64 * Eventually the right thing to do will be to have the reactor 65 * core respond to SIGCHLD by chaining a handler on top of the 66 * one Ruby may have installed, and dealing with a list of dead 67 * children that are pending cleanup. 68 * 69 * Since we want to have a signal processor integrated into the 70 * client-visible API, let's wait until that is done before cleaning 71 * this up. 74 72 */ 75 pclose (MyStream); 73 74 struct timespec req = {0, 10000000}; 75 kill (SubprocessPid, SIGTERM); 76 nanosleep (&req, NULL); 77 if (waitpid (SubprocessPid, NULL, WNOHANG) == 0) { 78 kill (SubprocessPid, SIGKILL); 79 nanosleep (&req, NULL); 80 if (waitpid (SubprocessPid, NULL, WNOHANG) == 0) 81 throw std::runtime_error ("unable to reap subprocess"); 82 } 76 83 } 77 84 version_0/ext/project.h
r373 r384 44 44 #include <sys/un.h> 45 45 #include <sys/resource.h> 46 #include <sys/wait.h> 46 47 #include <assert.h> 47 48 #include <unistd.h> version_0/ext/rubymain.cpp
r383 r384 138 138 if (evma_get_peername (StringValuePtr (signature), &s)) { 139 139 return rb_str_new ((const char*)&s, sizeof(s)); 140 } 141 142 return Qnil; 143 } 144 145 /******************** 146 t_get_subprocess_pid 147 ********************/ 148 149 static VALUE t_get_subprocess_pid (VALUE self, VALUE signature) 150 { 151 pid_t pid; 152 if (evma_get_subprocess_pid (StringValuePtr (signature), &pid)) { 153 return INT2NUM (pid); 140 154 } 141 155 … … 416 430 417 431 rb_define_module_function (EmModule, "get_peername", (VALUE(*)(...))t_get_peername, 1); 432 rb_define_module_function (EmModule, "get_subprocess_pid", (VALUE(*)(...))t_get_subprocess_pid, 1); 418 433 rb_define_module_function (EmModule, "get_comm_inactivity_timeout", (VALUE(*)(...))t_get_comm_inactivity_timeout, 1); 419 434 rb_define_module_function (EmModule, "set_comm_inactivity_timeout", (VALUE(*)(...))t_set_comm_inactivity_timeout, 2); version_0/lib/eventmachine.rb
r383 r384 1179 1179 end 1180 1180 1181 # Returns the PID (kernel process identifier) of a subprocess 1182 # associated with this Connection object. For use with EventMachine#popen 1183 # and similar methods. Returns nil when there is no meaningful subprocess. 1184 #-- 1185 # 1186 def get_pid 1187 EventMachine::get_subprocess_pid @signature 1188 end 1189 1181 1190 # comm_inactivity_timeout returns the current value (in seconds) of the inactivity-timeout 1182 1191 # property of network-connection and datagram-socket objects. A nonzero value