[Opensrf-commits] r1994 - trunk/src/libopensrf (scottmk)

svn at svn.open-ils.org svn at svn.open-ils.org
Tue Aug 10 22:58:27 EDT 2010


Author: scottmk
Date: 2010-08-10 22:58:25 -0400 (Tue, 10 Aug 2010)
New Revision: 1994

Modified:
   trunk/src/libopensrf/osrf_prefork.c
Log:
Adding comments and tinkering with white space.
No substantive changes.

M    src/libopensrf/osrf_prefork.c


Modified: trunk/src/libopensrf/osrf_prefork.c
===================================================================
--- trunk/src/libopensrf/osrf_prefork.c	2010-08-10 02:13:39 UTC (rev 1993)
+++ trunk/src/libopensrf/osrf_prefork.c	2010-08-11 02:58:25 UTC (rev 1994)
@@ -88,16 +88,16 @@
 	int max_requests, int min_children, int max_children );
 static prefork_child* launch_child( prefork_simple* forker );
 static void prefork_launch_children( prefork_simple* forker );
-static void prefork_run(prefork_simple* forker);
+static void prefork_run( prefork_simple* forker );
 static void add_prefork_child( prefork_simple* forker, prefork_child* child );
 
 static void del_prefork_child( prefork_simple* forker, pid_t pid );
 static void check_children( prefork_simple* forker, int forever );
-static int  prefork_child_process_request(prefork_child*, char* data);
-static int prefork_child_init_hook(prefork_child*);
+static int  prefork_child_process_request( prefork_child*, char* data );
+static int prefork_child_init_hook( prefork_child* );
 static prefork_child* prefork_child_init( prefork_simple* forker,
-		int read_data_fd, int write_data_fd,
-		int read_status_fd, int write_status_fd );
+	int read_data_fd, int write_data_fd,
+	int read_status_fd, int write_status_fd );
 
 /* listens on the 'data_to_child' fd and wait for incoming data */
 static void prefork_child_wait( prefork_child* child );
@@ -115,7 +115,7 @@
 */
 int osrf_prefork_run( const char* appname ) {
 
-	if(!appname) {
+	if( !appname ) {
 		osrfLogError( OSRF_LOG_MARK, "osrf_prefork_run requires an appname to run!");
 		return -1;
 	}
@@ -127,67 +127,74 @@
 	int minc = 3;
 	int kalive = 5;
 
-	osrfLogInfo( OSRF_LOG_MARK, "Loading config in osrf_forker for app %s", appname);
+	// Get configuration settings
+	osrfLogInfo( OSRF_LOG_MARK, "Loading config in osrf_forker for app %s", appname );
 
-	char* max_req      = osrf_settings_host_value("/apps/%s/unix_config/max_requests", appname);
-	char* min_children = osrf_settings_host_value("/apps/%s/unix_config/min_children", appname);
-	char* max_children = osrf_settings_host_value("/apps/%s/unix_config/max_children", appname);
-	char* keepalive    = osrf_settings_host_value("/apps/%s/keepalive", appname);
+	char* max_req      = osrf_settings_host_value( "/apps/%s/unix_config/max_requests", appname );
+	char* min_children = osrf_settings_host_value( "/apps/%s/unix_config/min_children", appname );
+	char* max_children = osrf_settings_host_value( "/apps/%s/unix_config/max_children", appname );
+	char* keepalive    = osrf_settings_host_value( "/apps/%s/keepalive", appname );
 
-	if(!keepalive) osrfLogWarning( OSRF_LOG_MARK, "Keepalive is not defined, assuming %d", kalive);
-	else kalive = atoi(keepalive);
+	if( !keepalive )
+		osrfLogWarning( OSRF_LOG_MARK, "Keepalive is not defined, assuming %d", kalive );
+	else
+		kalive = atoi( keepalive );
 
-	if(!max_req) osrfLogWarning( OSRF_LOG_MARK, "Max requests not defined, assuming %d", maxr);
-	else maxr = atoi(max_req);
+	if( !max_req )
+		osrfLogWarning( OSRF_LOG_MARK, "Max requests not defined, assuming %d", maxr );
+	else
+		maxr = atoi( max_req );
 
-	if(!min_children) osrfLogWarning( OSRF_LOG_MARK,
-			"Min children not defined, assuming %d", minc);
-	else minc = atoi(min_children);
+	if( !min_children )
+		osrfLogWarning( OSRF_LOG_MARK, "Min children not defined, assuming %d", minc );
+	else
+		minc = atoi( min_children );
 
-	if(!max_children) osrfLogWarning( OSRF_LOG_MARK,
-			"Max children not defined, assuming %d", maxc);
-	else maxc = atoi(max_children);
+	if( !max_children )
+		osrfLogWarning( OSRF_LOG_MARK, "Max children not defined, assuming %d", maxc );
+	else
+		maxc = atoi( max_children );
 
-	free(keepalive);
-	free(max_req);
-	free(min_children);
-	free(max_children);
+	free( keepalive );
+	free( max_req );
+	free( min_children );
+	free( max_children );
 	/* --------------------------------------------------- */
 
-	char* resc = va_list_to_string("%s_listener", appname);
+	char* resc = va_list_to_string( "%s_listener", appname );
 
 	// Make sure that we haven't already booted
-	if(!osrfSystemBootstrapClientResc( NULL, NULL, resc )) {
-		osrfLogError( OSRF_LOG_MARK, "Unable to bootstrap client for osrf_prefork_run()");
-		free(resc);
+	if( !osrfSystemBootstrapClientResc( NULL, NULL, resc )) {
+		osrfLogError( OSRF_LOG_MARK, "Unable to bootstrap client for osrf_prefork_run()" );
+		free( resc );
 		return -1;
 	}
 
-	free(resc);
+	free( resc );
 
 	prefork_simple forker;
 
-	if( prefork_simple_init( &forker, osrfSystemGetTransportClient(), maxr, minc, maxc ) ) {
+	if( prefork_simple_init( &forker, osrfSystemGetTransportClient(), maxr, minc, maxc )) {
 		osrfLogError( OSRF_LOG_MARK,
-				"osrf_prefork_run() failed to create prefork_simple object" );
+			"osrf_prefork_run() failed to create prefork_simple object" );
 		return -1;
 	}
 
 	// Finish initializing the prefork_simple.
-	forker.appname   = strdup(appname);
+	forker.appname   = strdup( appname );
 	forker.keepalive = kalive;
 
 	// Spawn the children; put them in the idle list.
 	prefork_launch_children( &forker );
 
 	// Tell the router that you're open for business.
-	osrf_prefork_register_routers(appname);
+	osrf_prefork_register_routers( appname );
 
 	// Sit back and let the requests roll in
-	osrfLogInfo( OSRF_LOG_MARK, "Launching osrf_forker for app %s", appname);
+	osrfLogInfo( OSRF_LOG_MARK, "Launching osrf_forker for app %s", appname );
 	prefork_run( &forker );
 
-	osrfLogWarning( OSRF_LOG_MARK, "prefork_run() returned - how??");
+	osrfLogWarning( OSRF_LOG_MARK, "prefork_run() returned - how??" );
 	prefork_clear( &forker );
 	return 0;
 }
@@ -218,38 +225,55 @@
 
 	// Clean up
 	message_free( msg );
-	free(jid);
+	free( jid );
 }
 
-/* parses a single "complex" router configuration chunk */
-// Called only by the parent process
-static void osrf_prefork_parse_router_chunk(const char* appname, const jsonObject* routerChunk) {
+/**
+	@brief Register with a router, or not, according to some config settings.
+	@param appname Name of the application
+	@param RouterChunk A representation of part of the config file.
 
-	const char* routerName = jsonObjectGetString(jsonObjectGetKeyConst(routerChunk, "name"));
-	const char* domain = jsonObjectGetString(jsonObjectGetKeyConst(routerChunk, "domain"));
-	const jsonObject* services = jsonObjectGetKeyConst(routerChunk, "services");
-	osrfLogDebug(OSRF_LOG_MARK, "found router config with domain %s and name %s",
-			routerName, domain);
+	Parse a "complex" router configuration chunk.
 
+	Examine the services listed for a given router (normally in opensrf_core.xml).  If
+	there is an entry for this service, or if there are @em no services listed, then
+	register with this router.  Otherwise don't.
+
+	Called only by the parent process.
+*/
+static void osrf_prefork_parse_router_chunk( const char* appname, const jsonObject* routerChunk ) {
+
+	const char* routerName = jsonObjectGetString( jsonObjectGetKeyConst( routerChunk, "name" ));
+	const char* domain = jsonObjectGetString( jsonObjectGetKeyConst( routerChunk, "domain" ));
+	const jsonObject* services = jsonObjectGetKeyConst( routerChunk, "services" );
+	osrfLogDebug( OSRF_LOG_MARK, "found router config with domain %s and name %s",
+		routerName, domain );
+
 	if( services && services->type == JSON_HASH ) {
-		osrfLogDebug(OSRF_LOG_MARK, "investigating router information...");
-		const jsonObject* service_obj = jsonObjectGetKeyConst(services, "service");
+		osrfLogDebug( OSRF_LOG_MARK, "investigating router information..." );
+		const jsonObject* service_obj = jsonObjectGetKeyConst( services, "service" );
 		if( !service_obj )
 			;    // do nothing (shouldn't happen)
 		else if( JSON_ARRAY == service_obj->type ) {
+			// There are multiple services listed.  Register with this router
+			// if and only if this service is on the list.
 			int j;
-			for(j = 0; j < service_obj->size; j++ ) {
-				const char* service = jsonObjectGetString(jsonObjectGetIndex(service_obj, j));
+			for( j = 0; j < service_obj->size; j++ ) {
+				const char* service = jsonObjectGetString( jsonObjectGetIndex( service_obj, j ));
 				if( service && !strcmp( appname, service ))
-					osrf_prefork_send_router_registration(appname, routerName, domain);
+					osrf_prefork_send_router_registration( appname, routerName, domain );
 			}
 		}
 		else if( JSON_STRING == service_obj->type ) {
-			if( !strcmp(appname, jsonObjectGetString( service_obj )) )
-				osrf_prefork_send_router_registration(appname, routerName, domain);
+			// There's only one service listed.  Register with this router
+			// if and only if this service is the one listed.
+			if( !strcmp( appname, jsonObjectGetString( service_obj )) )
+				osrf_prefork_send_router_registration( appname, routerName, domain );
 		}
 	} else {
-		osrf_prefork_send_router_registration(appname, routerName, domain);
+		// This router is not restricted to any set of services,
+		// so go ahead and register with it.
+		osrf_prefork_send_router_registration( appname, routerName, domain );
 	}
 }
 
@@ -261,24 +285,24 @@
 */
 static void osrf_prefork_register_routers( const char* appname ) {
 
-	jsonObject* routerInfo = osrfConfigGetValueObject(NULL, "/routers/router");
+	jsonObject* routerInfo = osrfConfigGetValueObject( NULL, "/routers/router" );
 
 	int i;
-	for(i = 0; i < routerInfo->size; i++) {
-		const jsonObject* routerChunk = jsonObjectGetIndex(routerInfo, i);
+	for( i = 0; i < routerInfo->size; i++ ) {
+		const jsonObject* routerChunk = jsonObjectGetIndex( routerInfo, i );
 
-		if(routerChunk->type == JSON_STRING) {
+		if( routerChunk->type == JSON_STRING ) {
 			/* this accomodates simple router configs */
 			char* routerName = osrfConfigGetValue( NULL, "/router_name" );
-			char* domain = osrfConfigGetValue(NULL, "/routers/router");
-			osrfLogDebug(OSRF_LOG_MARK, "found simple router settings with router name %s",
-					routerName);
-			osrf_prefork_send_router_registration(appname, routerName, domain);
+			char* domain = osrfConfigGetValue( NULL, "/routers/router" );
+			osrfLogDebug( OSRF_LOG_MARK, "found simple router settings with router name %s",
+				routerName );
+			osrf_prefork_send_router_registration( appname, routerName, domain );
 
 			free( routerName );
 			free( domain );
 		} else {
-			osrf_prefork_parse_router_chunk(appname, routerChunk);
+			osrf_prefork_parse_router_chunk( appname, routerChunk );
 		}
 	}
 
@@ -297,39 +321,39 @@
 	- Dynamically call an application-specific initialization routine
 	- Change the command line as reported by ps
 */
-static int prefork_child_init_hook(prefork_child* child) {
+static int prefork_child_init_hook( prefork_child* child ) {
 
-	if(!child) return -1;
-	osrfLogDebug( OSRF_LOG_MARK, "Child init hook for child %d", child->pid);
+	if( !child ) return -1;
+	osrfLogDebug( OSRF_LOG_MARK, "Child init hook for child %d", child->pid );
 
 	// Connect to cache server(s).
 	osrfSystemInitCache();
-	char* resc = va_list_to_string("%s_drone", child->appname);
+	char* resc = va_list_to_string( "%s_drone", child->appname );
 
 	// If we're a source-client, tell the logger now that we're a new process.
-	char* isclient = osrfConfigGetValue(NULL, "/client");
-	if( isclient && !strcasecmp(isclient,"true") )
-		osrfLogSetIsClient(1);
-	free(isclient);
+	char* isclient = osrfConfigGetValue( NULL, "/client" );
+	if( isclient && !strcasecmp( isclient,"true" ))
+		osrfLogSetIsClient( 1 );
+	free( isclient );
 
 	// Remove traces of our parent's socket connection so we can have our own.
 	osrfSystemIgnoreTransportClient();
 
 	// Connect to Jabber
-	if(!osrfSystemBootstrapClientResc( NULL, NULL, resc )) {
-		osrfLogError( OSRF_LOG_MARK, "Unable to bootstrap client for osrf_prefork_run()");
-		free(resc);
+	if( !osrfSystemBootstrapClientResc( NULL, NULL, resc )) {
+		osrfLogError( OSRF_LOG_MARK, "Unable to bootstrap client for osrf_prefork_run()" );
+		free( resc );
 		return -1;
 	}
 
-	free(resc);
+	free( resc );
 
 	// Dynamically call the application-specific initialization function
 	// from a previously loaded shared library.
-	if( ! osrfAppRunChildInit(child->appname) ) {
-		osrfLogDebug(OSRF_LOG_MARK, "Prefork child_init succeeded\n");
+	if( ! osrfAppRunChildInit( child->appname )) {
+		osrfLogDebug( OSRF_LOG_MARK, "Prefork child_init succeeded\n" );
 	} else {
-		osrfLogError(OSRF_LOG_MARK, "Prefork child_init failed\n");
+		osrfLogError( OSRF_LOG_MARK, "Prefork child_init failed\n" );
 		return -1;
 	}
 
@@ -338,30 +362,39 @@
 	return 0;
 }
 
-// Called only by a child process
-// Non-zero return code means that the child process has decided to terminate immediately,
-// without waiting for a DISCONNECT or max_requests.
-static int prefork_child_process_request(prefork_child* child, char* data) {
+/**
+	@brief Respond to a client request forwarded by the parent.
+	@param child Pointer to the state of the child process.
+	@param data Pointer to the raw XMPP message received from the parent.
+	@return 0 on success; non-zero means that the child process should clean itself up
+		and terminate immediately, presumably due to a fatal error condition.
+
+	Called only by a child process.
+*/
+static int prefork_child_process_request( prefork_child* child, char* data ) {
 	if( !child ) return 0;
 
 	transport_client* client = osrfSystemGetTransportClient();
 
-	if(!client_connected(client)) {
+	// Make sure that we're still connected to Jabber; reconnect if necessary.
+	if( !client_connected( client )) {
 		osrfSystemIgnoreTransportClient();
-		osrfLogWarning(OSRF_LOG_MARK, "Reconnecting child to opensrf after disconnect...");
-		if(!osrf_system_bootstrap_client(NULL, NULL)) {
+		osrfLogWarning( OSRF_LOG_MARK, "Reconnecting child to opensrf after disconnect..." );
+		if( !osrf_system_bootstrap_client( NULL, NULL )) {
 			osrfLogError( OSRF_LOG_MARK,
-				"Unable to bootstrap client in prefork_child_process_request()");
-			sleep(1);
-			osrf_prefork_child_exit(child);
+				"Unable to bootstrap client in prefork_child_process_request()" );
+			sleep( 1 );
+			osrf_prefork_child_exit( child );
 		}
 	}
 
-	/* construct the message from the xml */
+	// Construct the message from the xml.
 	transport_message* msg = new_message_from_xml( data );
 
-	osrfAppSession* session = osrf_stack_transport_handler(msg, child->appname);
-	if(!session) return 0;
+	// Respond to the transport message.  This is where method calls are buried.
+	osrfAppSession* session = osrf_stack_transport_handler( msg, child->appname );
+	if( !session )
+		return 0;
 
 	int rc = session->panic;
 
@@ -373,10 +406,20 @@
 	}
 
 	if( session->stateless && session->state != OSRF_SESSION_CONNECTED ) {
+		// We're no longer connected to the client, which presumably means that
+		// we're done with this request.  Bail out.
 		osrfAppSessionFree( session );
 		return rc;
 	}
 
+	// If we get this far, then the client has opened an application connection so that it
+	// can send multiple requests directly to the same server drone, bypassing the router
+	// and the listener.  For example, it may need to do a database transaction, requiring
+	// multiple method calls within the same database session.
+
+	// Hence we go into a loop, responding to successive requests from the same client, until
+	// either the client disconnects or an error occurs.
+
 	osrfLogDebug( OSRF_LOG_MARK, "Entering keepalive loop for session %s", session->session_id );
 	int keepalive = child->keepalive;
 	int retval;
@@ -384,42 +427,48 @@
 	time_t start;
 	time_t end;
 
-	while(1) {
+	while( 1 ) {
 
-		osrfLogDebug(OSRF_LOG_MARK,
-				"osrf_prefork calling queue_wait [%d] in keepalive loop", keepalive);
-		start   = time(NULL);
-		retval  = osrf_app_session_queue_wait(session, keepalive, &recvd);
-		end     = time(NULL);
+		// Respond to any input messages.  This is where the method calls are buried.
+		osrfLogDebug( OSRF_LOG_MARK,
+			"osrf_prefork calling queue_wait [%d] in keepalive loop", keepalive );
+		start   = time( NULL );
+		retval  = osrf_app_session_queue_wait( session, keepalive, &recvd );
+		end     = time( NULL );
 
-		osrfLogDebug(OSRF_LOG_MARK, "Data received == %d", recvd);
+		osrfLogDebug( OSRF_LOG_MARK, "Data received == %d", recvd );
 
+		// Now we check a number of possible reasons to exit the loop.
+
+		// If the method call decided to terminate immediately,
+		// note that for future reference.
 		if( session->panic )
 			rc = 1;
 
-		if(retval) {
-			osrfLogError(OSRF_LOG_MARK, "queue-wait returned non-success %d", retval);
+		// If an error occurred when we tried to service the request, exit the loop.
+		if( retval ) {
+			osrfLogError( OSRF_LOG_MARK, "queue-wait returned non-success %d", retval );
 			break;
 		}
 
-		/* see if the client disconnected from us */
-		if(session->state != OSRF_SESSION_CONNECTED)
+		// If the client disconnected, exit the loop.
+		if( session->state != OSRF_SESSION_CONNECTED )
 			break;
 
-		/* if no data was reveived within the timeout interval */
+		// If we timed out while waiting for a request, exit the loop.
 		if( !recvd && (end - start) >= keepalive ) {
-			osrfLogInfo(OSRF_LOG_MARK,
-					"No request was received in %d seconds, exiting stateful session", keepalive);
+			osrfLogInfo( OSRF_LOG_MARK,
+				"No request was received in %d seconds, exiting stateful session", keepalive );
 			osrfAppSessionStatus(
-					session,
-					OSRF_STATUS_TIMEOUT,
-					"osrfConnectStatus",
-					0, "Disconnected on timeout" );
+				session,
+				OSRF_STATUS_TIMEOUT,
+				"osrfConnectStatus",
+				0, "Disconnected on timeout" );
 
 			break;
 		}
 
-		// If the child process has decided to terminate immediately
+		// If the child process has decided to terminate immediately, exit the loop.
 		if( rc )
 			break;
 	}
@@ -444,17 +493,17 @@
 
 	if( min_children > max_children ) {
 		osrfLogError( OSRF_LOG_MARK,  "min_children (%d) is greater "
-				"than max_children (%d)", min_children, max_children );
+			"than max_children (%d)", min_children, max_children );
 		return 1;
 	}
 
 	if( max_children > ABS_MAX_CHILDREN ) {
 		osrfLogError( OSRF_LOG_MARK,  "max_children (%d) is greater than ABS_MAX_CHILDREN (%d)",
-				max_children, ABS_MAX_CHILDREN );
+			max_children, ABS_MAX_CHILDREN );
 		return 1;
 	}
 
-	osrfLogInfo(OSRF_LOG_MARK, "Prefork launching child with max_request=%d,"
+	osrfLogInfo( OSRF_LOG_MARK, "Prefork launching child with max_request=%d,"
 		"min_children=%d, max_children=%d", max_requests, min_children, max_children );
 
 	/* flesh out the struct */
@@ -492,12 +541,12 @@
 	int status_fd[2];
 
 	// Set up the data and status pipes
-	if( pipe(data_fd) < 0 ) { /* build the data pipe*/
+	if( pipe( data_fd ) < 0 ) { /* build the data pipe*/
 		osrfLogError( OSRF_LOG_MARK,  "Pipe making error" );
 		return NULL;
 	}
 
-	if( pipe(status_fd) < 0 ) {/* build the status pipe */
+	if( pipe( status_fd ) < 0 ) {/* build the status pipe */
 		osrfLogError( OSRF_LOG_MARK,  "Pipe making error" );
 		close( data_fd[1] );
 		close( data_fd[0] );
@@ -505,11 +554,11 @@
 	}
 
 	osrfLogInternal( OSRF_LOG_MARK, "Pipes: %d %d %d %d",
-			data_fd[0], data_fd[1], status_fd[0], status_fd[1] );
+		data_fd[0], data_fd[1], status_fd[0], status_fd[1] );
 
 	// Create and initialize a prefork_child for the new process
 	prefork_child* child = prefork_child_init( forker, data_fd[0],
-			data_fd[1], status_fd[0], status_fd[1] );
+		data_fd[1], status_fd[0], status_fd[1] );
 
 	if( (pid=fork()) < 0 ) {
 		osrfLogError( OSRF_LOG_MARK, "Forking Error" );
@@ -523,8 +572,8 @@
 
 	if( pid > 0 ) {  /* parent */
 
-		signal(SIGCHLD, sigchld_handler);
-		(forker->current_num_children)++;
+		signal( SIGCHLD, sigchld_handler );
+		( forker->current_num_children )++;
 		child->pid = pid;
 
 		osrfLogDebug( OSRF_LOG_MARK, "Parent launched %d", pid );
@@ -536,18 +585,18 @@
 	else { /* child */
 
 		osrfLogInternal( OSRF_LOG_MARK,
-				"I am new child with read_data_fd = %d and write_status_fd = %d",
-				child->read_data_fd, child->write_status_fd );
+			"I am new child with read_data_fd = %d and write_status_fd = %d",
+			child->read_data_fd, child->write_status_fd );
 
 		child->pid = getpid();
 		close( child->write_data_fd );
 		close( child->read_status_fd );
 
 		/* do the initing */
-		if( prefork_child_init_hook(child) == -1 ) {
-			osrfLogError(OSRF_LOG_MARK,
-				"Forker child going away because we could not connect to OpenSRF...");
-			osrf_prefork_child_exit(child);
+		if( prefork_child_init_hook( child ) == -1 ) {
+			osrfLogError( OSRF_LOG_MARK,
+				"Forker child going away because we could not connect to OpenSRF..." );
+			osrf_prefork_child_exit( child );
 		}
 
 		prefork_child_wait( child );      // Should exit without returning
@@ -558,14 +607,14 @@
 
 /**
 	@brief Terminate a child process.
-	@param child Pointer to the prefork_child representing the child process.
+	@param child Pointer to the prefork_child representing the child process (not used).
 
 	Called only by child processes.  Dynamically call an application-specific shutdown
 	function from a previously loaded shared library; then exit.
 */
-static void osrf_prefork_child_exit(prefork_child* child) {
+static void osrf_prefork_child_exit( prefork_child* child ) {
 	osrfAppRunExitCode();
-	exit(0);
+	exit( 0 );
 }
 
 /**
@@ -575,7 +624,7 @@
 	Called only by the parent process (in order to become a parent).
 */
 static void prefork_launch_children( prefork_simple* forker ) {
-	if(!forker) return;
+	if( !forker ) return;
 	int c = 0;
 	while( c++ < forker->min_children )
 		launch_child( forker );
@@ -588,7 +637,7 @@
 	Set a boolean to be checked later.
 */
 static void sigchld_handler( int sig ) {
-	signal(SIGCHLD, sigchld_handler);
+	signal( SIGCHLD, sigchld_handler );
 	child_dead = 1;
 }
 
@@ -612,7 +661,7 @@
 	// Bury the children so that they won't be zombies.  WNOHANG means that waitpid() returns
 	// immediately if there are no waitable children, instead of waiting for more to die.
 	// Ignore the return code of the child.  We don't do an autopsy.
-	while( (child_pid = waitpid(-1, NULL, WNOHANG)) > 0) {
+	while( (child_pid = waitpid( -1, NULL, WNOHANG )) > 0 ) {
 		--forker->current_num_children;
 		del_prefork_child( forker, child_pid );
 	}
@@ -641,7 +690,7 @@
 
 	transport_message* cur_msg = NULL;
 
-	while(1) {
+	while( 1 ) {
 
 		if( forker->first_child == NULL && forker->idle_list == NULL ) {/* no more children */
 			osrfLogWarning( OSRF_LOG_MARK, "No more children..." );
@@ -649,7 +698,7 @@
 		}
 
 		// Wait indefinitely for an input message
-		osrfLogDebug( OSRF_LOG_MARK, "Forker going into wait for data...");
+		osrfLogDebug( OSRF_LOG_MARK, "Forker going into wait for data..." );
 		cur_msg = client_recv( forker->connection, -1 );
 
 		if( cur_msg == NULL )
@@ -659,7 +708,7 @@
 		const char* msg_data = cur_msg->msg_xml;
 		if( ! msg_data || ! *msg_data ) {
 			osrfLogWarning( OSRF_LOG_MARK, "Received % message from %s, thread %",
-					(msg_data ? "empty" : "NULL"), cur_msg->sender, cur_msg->thread );
+				(msg_data ? "empty" : "NULL"), cur_msg->sender, cur_msg->thread );
 			message_free( cur_msg );
 			continue;       // Message not usable; go on to the next one.
 		}
@@ -669,7 +718,7 @@
 
 		while( ! honored ) {
 
-			if(!no_recheck)
+			if( !no_recheck )
 				check_children( forker, 0 );
 			no_recheck = 0;
 
@@ -690,19 +739,19 @@
 				cur_child->next = NULL;
 
 				osrfLogInternal( OSRF_LOG_MARK,
-						"Searching for available child. cur_child->pid = %d", cur_child->pid );
+					"Searching for available child. cur_child->pid = %d", cur_child->pid );
 				osrfLogInternal( OSRF_LOG_MARK, "Current num children %d",
-						forker->current_num_children );
+					forker->current_num_children );
 
 				osrfLogDebug( OSRF_LOG_MARK, "forker sending data to %d", cur_child->pid );
 				osrfLogInternal( OSRF_LOG_MARK, "Writing to child fd %d",
-						cur_child->write_data_fd );
+					cur_child->write_data_fd );
 
-				int written = write(cur_child->write_data_fd, msg_data, strlen(msg_data) + 1);
+				int written = write( cur_child->write_data_fd, msg_data, strlen( msg_data ) + 1 );
 				if( written < 0 ) {
 					// This child appears to be dead or unusable.  Discard it.
 					osrfLogWarning( OSRF_LOG_MARK, "Write returned error %d: %s",
-							errno, strerror( errno ) );
+						errno, strerror( errno ));
 					kill( cur_child->pid, SIGKILL );
 					del_prefork_child( forker, cur_child->pid );
 					continue;
@@ -715,11 +764,11 @@
 
 			/* if none available, add a new child if we can */
 			if( ! honored ) {
-				osrfLogDebug( OSRF_LOG_MARK, "Not enough children, attempting to add...");
+				osrfLogDebug( OSRF_LOG_MARK, "Not enough children, attempting to add..." );
 
 				if( forker->current_num_children < forker->max_children ) {
 					osrfLogDebug( OSRF_LOG_MARK,  "Launching new child with current_num = %d",
-							forker->current_num_children );
+						forker->current_num_children );
 
 					launch_child( forker );  // Put a new child into the idle list
 					if( forker->idle_list ) {
@@ -730,14 +779,14 @@
 						new_child->next = NULL;
 
 						osrfLogDebug( OSRF_LOG_MARK, "Writing to new child fd %d : pid %d",
-								new_child->write_data_fd, new_child->pid );
+							new_child->write_data_fd, new_child->pid );
 
 						int written = write(
-								new_child->write_data_fd, msg_data, strlen(msg_data) + 1);
+							new_child->write_data_fd, msg_data, strlen( msg_data ) + 1 );
 						if( written < 0 ) {
 							// This child appears to be dead or unusable.  Discard it.
 							osrfLogWarning( OSRF_LOG_MARK, "Write returned error %d: %s",
-											errno, strerror( errno ) );
+								errno, strerror( errno ));
 							kill( cur_child->pid, SIGKILL );
 							del_prefork_child( forker, cur_child->pid );
 						} else {
@@ -750,14 +799,14 @@
 			}
 
 			if( !honored ) {
-				osrfLogWarning( OSRF_LOG_MARK, "No children available, waiting...");
+				osrfLogWarning( OSRF_LOG_MARK, "No children available, waiting..." );
 				check_children( forker, 1 );
 				// Tell the loop not to call check_children again, since we're calling it now
 				no_recheck = 1;
 			}
 
 			if( child_dead )
-				reap_children(forker);
+				reap_children( forker );
 
 		} // end while( ! honored )
 
@@ -775,7 +824,6 @@
 	@brief See if any children have become available.
 	@param forker Pointer to the prefork_simple that owns the children.
 	@param forever Boolean: true if we should wait indefinitely.
-	@return 
 
 	Call select() for all the children in the active list.  Read each active file
 	descriptor and move the corresponding child to the idle list.
@@ -793,13 +841,13 @@
 		// processes, so there should be some active ones around.
 		// If forever is false, then the children may all be idle, and that's okay.
 		if( forever )
- 			osrfLogError( OSRF_LOG_MARK, "No active child processes to check" );
+			osrfLogError( OSRF_LOG_MARK, "No active child processes to check" );
 		return;
 	}
 
 	int select_ret;
 	fd_set read_set;
-	FD_ZERO(&read_set);
+	FD_ZERO( &read_set );
 	int max_fd = 0;
 	int n;
 
@@ -812,18 +860,18 @@
 		cur_child = cur_child->next;
 	} while( cur_child != forker->first_child );
 
-	FD_CLR(0,&read_set); /* just to be sure */
+	FD_CLR( 0, &read_set ); /* just to be sure */
 
 	if( forever ) {
-		osrfLogWarning(OSRF_LOG_MARK,
-				"We have no children available - waiting for one to show up...");
+		osrfLogWarning( OSRF_LOG_MARK,
+			"We have no children available - waiting for one to show up..." );
 
-		if( (select_ret=select( max_fd + 1, &read_set, NULL, NULL, NULL)) == -1 ) {
+		if( (select_ret=select( max_fd + 1, &read_set, NULL, NULL, NULL )) == -1 ) {
 			osrfLogWarning( OSRF_LOG_MARK, "Select returned error %d on check_children: %s",
-					errno, strerror( errno ) );
+				errno, strerror( errno ));
 		}
-		osrfLogInfo(OSRF_LOG_MARK,
-				"select() completed after waiting on children to become available");
+		osrfLogInfo( OSRF_LOG_MARK,
+			"select() completed after waiting on children to become available" );
 
 	} else {
 
@@ -831,9 +879,9 @@
 		tv.tv_sec   = 0;
 		tv.tv_usec  = 0;
 
-		if( (select_ret=select( max_fd + 1, &read_set, NULL, NULL, &tv)) == -1 ) {
+		if( (select_ret=select( max_fd + 1, &read_set, NULL, NULL, &tv )) == -1 ) {
 			osrfLogWarning( OSRF_LOG_MARK, "Select returned error %d on check_children: %s",
-					errno, strerror( errno ) );
+				errno, strerror( errno ));
 		}
 	}
 
@@ -847,18 +895,18 @@
 	int num_handled = 0;
 	do {
 		next_child = cur_child->next;
-		if( FD_ISSET( cur_child->read_status_fd, &read_set ) ) {
+		if( FD_ISSET( cur_child->read_status_fd, &read_set )) {
 			osrfLogDebug( OSRF_LOG_MARK,
-					"Server received status from a child %d", cur_child->pid );
+				"Server received status from a child %d", cur_child->pid );
 
 			num_handled++;
 
 			/* now suck off the data */
 			char buf[64];
-			if( (n=read(cur_child->read_status_fd, buf, sizeof(buf) - 1)) < 0 ) {
+			if( (n=read( cur_child->read_status_fd, buf, sizeof( buf ) - 1 )) < 0 ) {
 				osrfLogWarning( OSRF_LOG_MARK,
-						"Read error after select in child status read with errno %d: %s",
-						errno, strerror( errno ) );
+					"Read error after select in child status read with errno %d: %s",
+					errno, strerror( errno ));
 			}
 			else {
 				buf[n] = '\0';
@@ -908,22 +956,24 @@
 
 		n = -1;
 		int gotdata = 0;    // boolean; set to true if we get data
-		clr_fl(child->read_data_fd, O_NONBLOCK );
+		clr_fl( child->read_data_fd, O_NONBLOCK );
 
-		while( (n=read(child->read_data_fd, buf, READ_BUFSIZE-1)) > 0 ) {
+		// Read a request from the parent, via a pipe, into a growing_buffer.
+		while( (n = read( child->read_data_fd, buf, READ_BUFSIZE-1 )) > 0 ) {
 			buf[n] = '\0';
-			osrfLogDebug(OSRF_LOG_MARK, "Prefork child read %d bytes of data", n);
-			if(!gotdata) {
-				set_fl(child->read_data_fd, O_NONBLOCK );
+			osrfLogDebug( OSRF_LOG_MARK, "Prefork child read %d bytes of data", n );
+			if( !gotdata ) {
+				set_fl( child->read_data_fd, O_NONBLOCK );
 				gotdata = 1;
 			}
 			buffer_add( gbuf, buf );
 		}
 
-		if( errno == EAGAIN ) n = 0;
+		if( errno == EAGAIN )
+			n = 0;
 
 		if( errno == EPIPE ) {
-			osrfLogDebug(OSRF_LOG_MARK, "C child attempted read on broken pipe, exiting...");
+			osrfLogDebug( OSRF_LOG_MARK, "C child attempted read on broken pipe, exiting..." );
 			break;
 		}
 
@@ -931,40 +981,43 @@
 
 		if( n < 0 ) {
 			osrfLogWarning( OSRF_LOG_MARK,
-					"Prefork child read returned error with errno %d", errno );
+				"Prefork child read returned error with errno %d", errno );
 			break;
 
 		} else if( gotdata ) {
+			// Process the request
 			osrfLogDebug( OSRF_LOG_MARK, "Prefork child got a request.. processing.." );
 			terminate_now = prefork_child_process_request( child, gbuf->buf );
 			buffer_reset( gbuf );
 		}
 
 		if( terminate_now ) {
+			// We're terminating prematurely -- presumably due to a fatal error condition.
 			osrfLogWarning( OSRF_LOG_MARK, "Prefork child terminating abruptly" );
 			break;
 		}
 
 		if( i < child->max_requests - 1 ) {
+			// Report back to the parent for another request.
 			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, 
+				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 );
+				osrf_prefork_child_exit( child );
 			}
 		}
 	}
 
-	buffer_free(gbuf);
+	buffer_free( gbuf );
 
 	osrfLogDebug( OSRF_LOG_MARK, "Child with max-requests=%d, num-served=%d exiting...[%ld]",
-			child->max_requests, i, (long) getpid() );
+		child->max_requests, i, (long) getpid());
 
-	osrf_prefork_child_exit(child);
+	osrf_prefork_child_exit( child );
 }
 
 /**
@@ -991,12 +1044,21 @@
 	}
 }
 
+/**
+	@brief Delete and destroy a dead child from our list.
+	@param forker Pointer to the prefork_simple that owns the dead child.
+	@param pid Process ID of the dead child.
+
+	Look for the dead child first in the list of active children.  If you don't find it
+	there, look in the list of idle children.  If you find it, remove it from whichever
+	list it's on, and destroy it.
+*/
 static void del_prefork_child( prefork_simple* forker, pid_t pid ) {
 
 	osrfLogDebug( OSRF_LOG_MARK, "Deleting Child: %d", pid );
 
 	prefork_child* cur_child = NULL;
-	
+
 	// Look first in the active list
 	if( forker->first_child ) {
 		cur_child = forker->first_child; /* current pointer */
@@ -1067,7 +1129,7 @@
 		child = forker->free_list;
 		forker->free_list = child->next;
 	} else
-		child = safe_malloc(sizeof(prefork_child));
+		child = safe_malloc( sizeof( prefork_child ));
 
 	child->pid              = 0;
 	child->read_data_fd     = read_data_fd;
@@ -1126,11 +1188,11 @@
 	// don't become zombies.  We don't wait indefinitely, so it's possible that some
 	// children will survive a bit longer.
 	sleep( 1 );
-	while( (waitpid(-1, NULL, WNOHANG)) > 0) {
+	while( (waitpid( -1, NULL, WNOHANG )) > 0 ) {
 		--prefork->current_num_children;
 	}
 
-	free(prefork->appname);
+	free( prefork->appname );
 	prefork->appname = NULL;
 }
 



More information about the opensrf-commits mailing list