[Opensrf-commits] r1836 - trunk/src/router (scottmk)
svn at svn.open-ils.org
svn at svn.open-ils.org
Mon Nov 2 09:41:23 EST 2009
Author: scottmk
Date: 2009-11-02 09:41:22 -0500 (Mon, 02 Nov 2009)
New Revision: 1836
Modified:
trunk/src/router/osrf_router.c
trunk/src/router/osrf_router.h
trunk/src/router/osrf_router_main.c
Log:
Changed the signal handling.
There are very few things you can safely do within a signal handler, and
shutting down an osrfRouter is not among them.
Now the signal handler just sets a switch for the main loop to look at.
The select call looks for errno == EINTR and then looks at the switch
that the signal handler sets. If the switch is set, we exit the otherwise
infinite loop. Then we free the osrfRouter and re-raise the signal.
M src/router/osrf_router.h
M src/router/osrf_router.c
M src/router/osrf_router_main.c
Modified: trunk/src/router/osrf_router.c
===================================================================
--- trunk/src/router/osrf_router.c 2009-10-31 16:49:15 UTC (rev 1835)
+++ trunk/src/router/osrf_router.c 2009-11-02 14:41:22 UTC (rev 1836)
@@ -73,6 +73,18 @@
#define ROUTER_REQUEST_STATS_CLASS_SUMMARY "opensrf.router.info.stats.class.summary"
/**
+ @brief Stop the otherwise infinite main loop of the router.
+ @param router Pointer to the osrfRouter to be stopped.
+
+ To be called by a signal handler.
+*/
+void router_stop( osrfRouter* router )
+{
+ if( router )
+ router->stop = 1;
+}
+
+/**
@brief Allocate and initialize a new osrfRouter.
@param domain Domain name of Jabber server
@param name Router's username for the Jabber logon.
@@ -101,6 +113,7 @@
router->password = strdup(password);
router->resource = strdup(resource);
router->port = port;
+ router->stop = 0;
router->trustedClients = trustedClients;
router->trustedServers = trustedServers;
@@ -138,15 +151,25 @@
int routerfd = router->ROUTER_SOCKFD;
int selectret = 0;
- while(1) {
+ while( ! router->stop ) {
fd_set set;
int maxfd = _osrfRouterFillFDSet( router, &set );
int numhandled = 0;
if( (selectret = select(maxfd + 1, &set, NULL, NULL, NULL)) < 0 ) {
- osrfLogWarning( OSRF_LOG_MARK, "Top level select call failed with errno %d", errno);
- continue;
+ if( EINTR == errno ) {
+ if( router->stop ) {
+ osrfLogWarning( OSRF_LOG_MARK, "Top level select call interrupted by signal" );
+ break;
+ }
+ else
+ continue; // Irrelevant signal; ignore it
+ } else {
+ osrfLogWarning( OSRF_LOG_MARK,
+ "Top level select call failed with errno %d", errno);
+ continue;
+ }
}
/* see if there is a top level router message */
@@ -157,7 +180,6 @@
osrfRouterHandleIncoming( router );
}
-
/* now check each of the connected classes and see if they have data to route */
while( numhandled < selectret ) {
Modified: trunk/src/router/osrf_router.h
===================================================================
--- trunk/src/router/osrf_router.h 2009-10-31 16:49:15 UTC (rev 1835)
+++ trunk/src/router/osrf_router.h 2009-11-02 14:41:22 UTC (rev 1836)
@@ -23,12 +23,13 @@
/* a router maintains a list of server classes */
struct _osrfRouterStruct {
- osrfHash* classes; /* our list of server classes */
- char* domain; /* our login domain */
- char* name;
- char* resource;
- char* password;
- int port;
+ osrfHash* classes; /**< our list of server classes */
+ char* domain; /**< Domain name of Jabber server. */
+ char* name; /**< Router's username for the Jabber logon. */
+ char* resource; /**< Router's resource name for the Jabber logon. */
+ char* password; /**< Router's password for the Jabber logon. */
+ int port; /**< Jabber's port number. */
+ sig_atomic_t stop; /**< To be set by signal handler to interrupt main loop */
osrfStringArray* trustedClients;
osrfStringArray* trustedServers;
@@ -65,6 +66,7 @@
*/
void osrfRouterRun( osrfRouter* router );
+void router_stop( osrfRouter* router );
/**
Frees a router
Modified: trunk/src/router/osrf_router_main.c
===================================================================
--- trunk/src/router/osrf_router_main.c 2009-10-31 16:49:15 UTC (rev 1835)
+++ trunk/src/router/osrf_router_main.c 2009-11-02 14:41:22 UTC (rev 1836)
@@ -28,27 +28,24 @@
*/
static osrfRouter* router = NULL;
+static sig_atomic_t stop_signal = 0;
+
+static void setupRouter(jsonObject* configChunk);
+
/**
- @brief Respond to signal by cleaning up and exiting immediately.
+ @brief Respond to signal by setting a switch that will interrupt the main loop.
@param signo The signal number.
+
+ Signal handler. We not only interrupt the main loop but also remember the signal
+ number so that we can report it later and re-raise it.
*/
void routerSignalHandler( int signo ) {
- osrfLogWarning( OSRF_LOG_MARK, "Received signal [%d], cleaning up...", signo );
-
- osrfConfigCleanup();
- osrfRouterFree(router);
- osrfLogWarning( OSRF_LOG_MARK, "Cleanup successful. Re-raising signal" );
- router = NULL;
-
- // Re-raise the signal so that the parent process can detect it.
- signal( signo, SIG_DFL );
- raise( signo );
+ signal( signo, routerSignalHandler );
+ router_stop( router );
+ stop_signal = signo;
}
-static void setupRouter(jsonObject* configChunk);
-
-
/**
@brief The top-level function of the router program.
@param argc Number of items in command line.
@@ -98,12 +95,12 @@
jsonObject* configChunk = jsonObjectGetIndex(configInfo, i);
if( ! jsonObjectGetKey( configChunk, "transport" ) )
{
- // In searching the configuration file for a given context, we may have found a spurious
- // hit on an unrelated part of the configuration file that happened to use the same XML
- // tag. In fact this happens routinely in practice.
+ // In searching the configuration file for a given context, we may have found a
+ // spurious hit on an unrelated part of the configuration file that happened to use
+ // the same XML tag. In fact this happens routinely in practice.
- // If we don't see a member for "transport" then this is presumably such a spurious hit,
- // so we silently ignore it.
+ // If we don't see a member for "transport" then this is presumably such a spurious
+ // hit, so we silently ignore it.
// It is also possible that it's the right part of the configuration file but it has a
// typo or other such error, making it look spurious. In that case, well, too bad.
@@ -115,6 +112,13 @@
}
}
+ if( stop_signal ) {
+ // Interrupted by a signal? Re raise so the parent can see it.
+ osrfLogWarning( OSRF_LOG_MARK, "Interrupted by signal %d; re-raising",
+ (int) stop_signal );
+ raise( stop_signal );
+ }
+
return EXIT_SUCCESS;
}
@@ -224,6 +228,8 @@
osrfRouterFree(router);
router = NULL;
+
+ osrfLogInfo( OSRF_LOG_MARK, "Router freed" );
return;
}
More information about the opensrf-commits
mailing list