Add a bit of bulletproofing.
authorscottmk <scottmk@9efc2488-bf62-4759-914b-345cdb29e865>
Tue, 22 Jun 2010 15:35:03 +0000 (15:35 +0000)
committerscottmk <scottmk@9efc2488-bf62-4759-914b-345cdb29e865>
Tue, 22 Jun 2010 15:35:03 +0000 (15:35 +0000)
When a drone finishes servicing a request, it writes a brief message
to a pipe, to notify the listener that it's available for another request.

Change: if the write to the pipe is not successful, log an error message
and terminate.  Otherwise the drone would become undead and unreachable.

M    src/libopensrf/osrf_prefork.c

git-svn-id: svn://svn.open-ils.org/OpenSRF/trunk@1968 9efc2488-bf62-4759-914b-345cdb29e865

src/libopensrf/osrf_prefork.c

index 319c33d..560142f 100644 (file)
@@ -23,6 +23,7 @@
        to the parent.  Then the parent knows that it can send that child another request.
 */
 
+#include <errno.h>
 #include <signal.h>
 #include <sys/types.h>
 #include <sys/time.h>
@@ -919,8 +920,18 @@ static void prefork_child_wait( prefork_child* child ) {
                        buffer_reset( gbuf );
                }
 
-               if( i < child->max_requests - 1 )
-                       write( child->write_status_fd, "available" /*less than 64 bytes*/, 9 );
+               if( i < child->max_requests - 1 ) {
+                       size_t msg_len = 9;
+                       ssize_t len = write(
+                               child->write_status_fd, "available" /*less than 64 bytes*/, msg_len );
+                       if( len != msg_len ) {
+                               osrfLogError( OSRF_LOG_MARK, 
+                                       "Drone terminating: unable to notify listener of availability: %s",
+                                       strerror( errno ));
+                               buffer_free(gbuf);
+                               osrf_prefork_child_exit(child);
+                       }
+               }
        }
 
        buffer_free(gbuf);
@@ -955,66 +966,6 @@ static void add_prefork_child( prefork_simple* forker, prefork_child* child ) {
        }
 }
 
-/**
-       @brief Remove a prefork_child, representing a terminated child, from the list it's on.
-       @param forker Pointer to the prefork_simple that owns the child.
-       @param pid Process ID of the child to be removed.
-
-       Look for the node in the active list, and, failing that, in the idle list.  If you
-       find it, close its file descriptors and put it in the free list for potential reuse.
-*/
-static void old_del_prefork_child( prefork_simple* forker, pid_t pid ) {
-
-       if( forker->first_child == NULL )
-               return;  // Empty list; bail out.
-
-       osrfLogDebug( OSRF_LOG_MARK, "Deleting Child: %d", pid );
-
-       // Find the node in question
-       prefork_child* cur_child = forker->first_child; /* current pointer */
-       while( cur_child->pid != pid && cur_child->next != forker->first_child )
-               cur_child = cur_child->next;
-
-       if( cur_child->pid == pid ) {
-               // We found the right node.  Remove it from the list.
-               if( cur_child->next == cur_child )
-                       forker->first_child = NULL;    // only child in the list
-               else {
-                       if( forker->first_child == cur_child )
-                               forker->first_child = cur_child->next;  // Reseat forker->first_child
-
-                       // Stitch the nodes on either side together
-                       cur_child->prev->next = cur_child->next;
-                       cur_child->next->prev = cur_child->prev;
-               }
-
-               //Destroy the node
-               prefork_child_free( forker, cur_child );
-
-       } else {
-               // Maybe it's in the idle list.  This can happen if, for example,
-               // a child is killed by a signal while it's between requests.
-
-               prefork_child* prev = NULL;
-               cur_child = forker->idle_list;
-               while( cur_child && cur_child->pid != pid ) {
-                       prev = cur_child;
-                       cur_child = cur_child->next;
-               }
-
-               if( cur_child ) {
-                       // Detach from the list
-                       if( prev )
-                               prev->next = cur_child->next;
-                       else
-                               forker->idle_list = cur_child->next;
-
-                       //Destroy the node
-                       prefork_child_free( forker, cur_child );
-               } // else we can't find it, so do nothing.
-       }
-}
-
 static void del_prefork_child( prefork_simple* forker, pid_t pid ) {
 
        osrfLogDebug( OSRF_LOG_MARK, "Deleting Child: %d", pid );