From 0cf3d031692c1a413cfe909243f21a9e01ebe1c2 Mon Sep 17 00:00:00 2001 From: scottmk Date: Tue, 22 Jun 2010 15:35:03 +0000 Subject: [PATCH] Add a bit of bulletproofing. 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 | 75 ++++++----------------------------- 1 file changed, 13 insertions(+), 62 deletions(-) diff --git a/src/libopensrf/osrf_prefork.c b/src/libopensrf/osrf_prefork.c index 319c33d..560142f 100644 --- a/src/libopensrf/osrf_prefork.c +++ b/src/libopensrf/osrf_prefork.c @@ -23,6 +23,7 @@ to the parent. Then the parent knows that it can send that child another request. */ +#include #include #include #include @@ -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 ); -- 2.43.2