Now, when no children are available to pass a request to, the parent
authorerickson <erickson@dcc99617-32d9-48b4-a31d-7c20da2025e4>
Tue, 12 Sep 2006 02:03:52 +0000 (02:03 +0000)
committererickson <erickson@dcc99617-32d9-48b4-a31d-7c20da2025e4>
Tue, 12 Sep 2006 02:03:52 +0000 (02:03 +0000)
process blocks on a select() call until any child is available.

previously, the parent would sleep 50ms, do a select() poll, sleep again, etc.

The new approach has the potential to be up to almost 50ms faster at finding
an available child when the parent is forced to wait.  plus, polling is just dumb

git-svn-id: svn://svn.open-ils.org/ILS/trunk@6071 dcc99617-32d9-48b4-a31d-7c20da2025e4

OpenSRF/src/libstack/osrf_prefork.c
OpenSRF/src/libstack/osrf_prefork.h

index 988215c..5b7d1f5 100644 (file)
@@ -367,10 +367,12 @@ void prefork_run(prefork_simple* forker) {
                if( cur_msg == NULL ) continue;
 
                int honored = 0;        /* true if we've serviced the request */
+               int no_recheck = 0;
 
                while( ! honored ) {
 
-                       check_children( forker ); 
+                       if(!no_recheck) check_children( forker, 0 ); 
+                       no_recheck = 0;
 
                        osrfLogDebug( OSRF_LOG_MARK,  "Server received inbound data" );
                        int k;
@@ -430,8 +432,12 @@ void prefork_run(prefork_simple* forker) {
                        }
 
                        if( !honored ) {
-                               osrfLogWarning( OSRF_LOG_MARK,  "No children available, sleeping and looping..." );
-                               usleep( 50000 ); /* 50 milliseconds */
+                               osrfLogWarning( OSRF_LOG_MARK,  "No children available, waiting...");
+
+                               check_children( forker, 1 );  /* non-poll version */
+                               /* tell the loop no to call check_children again, since we're calling it now */
+                               no_recheck = 1;
+                               //usleep(50000);
                        }
 
                        if( child_dead )
@@ -449,7 +455,12 @@ void prefork_run(prefork_simple* forker) {
 }
 
 
-void check_children( prefork_simple* forker ) {
+/** XXX Add a flag which tells select() to wait forever on children
+ * in the best case, this will be faster than calling usleep(x), and
+ * in the worst case it won't be slower and will do less logging...
+ */
+
+void check_children( prefork_simple* forker, int forever ) {
 
        //check_begin:
 
@@ -459,9 +470,6 @@ void check_children( prefork_simple* forker ) {
        int max_fd = 0;
        int n;
 
-       struct timeval tv;
-       tv.tv_sec       = 0;
-       tv.tv_usec      = 0;
 
        if( child_dead )
                reap_children(forker);
@@ -479,8 +487,23 @@ void check_children( prefork_simple* forker ) {
 
        FD_CLR(0,&read_set);/* just to be sure */
 
-       if( (select_ret=select( max_fd + 1 , &read_set, NULL, NULL, &tv)) == -1 ) {
-               osrfLogWarning( OSRF_LOG_MARK,  "Select returned error %d on check_children", errno );
+       if( forever ) {
+               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 ) {
+                       osrfLogWarning( OSRF_LOG_MARK,  "Select returned error %d on check_children", errno );
+               }
+               osrfLogInfo(OSRF_LOG_MARK, "select() completed after waiting on children to become available");
+
+       } else {
+
+               struct timeval tv;
+               tv.tv_sec       = 0;
+               tv.tv_usec      = 0;
+       
+               if( (select_ret=select( max_fd + 1 , &read_set, NULL, NULL, &tv)) == -1 ) {
+                       osrfLogWarning( OSRF_LOG_MARK,  "Select returned error %d on check_children", errno );
+               }
        }
 
        if( select_ret == 0 )
index 98b334f..28df9df 100644 (file)
@@ -75,7 +75,7 @@ void add_prefork_child( prefork_simple* forker, prefork_child* child );
 prefork_child* find_prefork_child( prefork_simple* forker, pid_t pid );
 void del_prefork_child( prefork_simple* forker, pid_t pid );
 
-void check_children( prefork_simple* forker );
+void check_children( prefork_simple* forker, int forever );
 
 void prefork_child_process_request(prefork_child*, char* data);
 int prefork_child_init_hook(prefork_child*);