Make fatal signals cause an exit more promptly in special cases.
authorBen Pfaff <blp@nicira.com>
Tue, 13 Apr 2010 16:28:13 +0000 (09:28 -0700)
committerBen Pfaff <blp@nicira.com>
Tue, 13 Apr 2010 16:30:32 +0000 (09:30 -0700)
The fatal-signal library notices and records fatal signals (e.g. SIGTERM)
and terminates the process on the next trip through poll_block().  But
some special utilities do not always invoke poll_block() promptly, e.g.
"ovs-ofctl monitor" does not call poll_block() as long as OpenFlow messages
are available.  But these special cases seem like they are all likely to
call into functions that themselves block (those with "_block" in their
names).  So make a new rule that such functions should always call
fatal_signal_run(), either directly or through poll_block().  This commit
implements and documents that rule.

Bug #2625.

lib/fatal-signal.c
lib/jsonrpc.c
lib/ovsdb-idl.c
lib/stream.c
lib/vconn.c

index f6f913ebc0b1d2aa19923240344f40c88df37384..2e38fc51aca1fc8b0e2c5d71f3fc8deff36a6abc 100644 (file)
@@ -134,6 +134,17 @@ fatal_signal_handler(int sig_nr)
     stored_sig_nr = sig_nr;
 }
 
+/* Check whether a fatal signal has occurred and, if so, call the fatal signal
+ * hooks and exit.
+ *
+ * This function is called automatically by poll_block(), but specialized
+ * programs that may not always call poll_block() on a regular basis should
+ * also call it periodically.  (Therefore, any function with "block" in its
+ * name should call fatal_signal_run() each time it is called, either directly
+ * or through poll_block(), because such functions can only used by specialized
+ * programs that can afford to block outside their main loop around
+ * poll_block().)
+ */
 void
 fatal_signal_run(void)
 {
index 72590a2f41da2d73c1b1c35da361e89a54cc8590..828bdac21a90e6eebe8b9ac62c3fb72fd42ca1f4 100644 (file)
@@ -23,6 +23,7 @@
 
 #include "byteq.h"
 #include "dynamic-string.h"
+#include "fatal-signal.h"
 #include "json.h"
 #include "list.h"
 #include "ofpbuf.h"
@@ -293,6 +294,8 @@ jsonrpc_send_block(struct jsonrpc *rpc, struct jsonrpc_msg *msg)
 {
     int error;
 
+    fatal_signal_run();
+
     error = jsonrpc_send(rpc, msg);
     if (error) {
         return error;
@@ -314,6 +317,7 @@ jsonrpc_recv_block(struct jsonrpc *rpc, struct jsonrpc_msg **msgp)
     for (;;) {
         int error = jsonrpc_recv(rpc, msgp);
         if (error != EAGAIN) {
+            fatal_signal_run();
             return error;
         }
 
index 42c53b831c60e9044731af6dd4cdedb69ba46b38..3f3ce555ac3f4ec413352107ef65e40730ade696 100644 (file)
@@ -25,6 +25,7 @@
 
 #include "bitmap.h"
 #include "dynamic-string.h"
+#include "fatal-signal.h"
 #include "json.h"
 #include "jsonrpc.h"
 #include "ovsdb-data.h"
@@ -1281,6 +1282,7 @@ ovsdb_idl_txn_commit_block(struct ovsdb_idl_txn *txn)
 {
     enum ovsdb_idl_txn_status status;
 
+    fatal_signal_run();
     while ((status = ovsdb_idl_txn_commit(txn)) == TXN_INCOMPLETE) {
         ovsdb_idl_run(txn->idl);
         ovsdb_idl_wait(txn->idl);
index 2349b0c116be300ce1cb7953bbf5bde50c111628..43b73af0adf9f7f542019a031e57b3515a799298 100644 (file)
@@ -25,6 +25,7 @@
 #include <string.h>
 #include "coverage.h"
 #include "dynamic-string.h"
+#include "fatal-signal.h"
 #include "flow.h"
 #include "ofp-print.h"
 #include "ofpbuf.h"
@@ -237,6 +238,8 @@ stream_open_block(int error, struct stream **streamp)
 {
     struct stream *stream = *streamp;
 
+    fatal_signal_run();
+
     while (error == EAGAIN) {
         stream_run(stream);
         stream_run_wait(stream);
@@ -570,6 +573,7 @@ pstream_accept_block(struct pstream *pstream, struct stream **new_stream)
 {
     int error;
 
+    fatal_signal_run();
     while ((error = pstream_accept(pstream, new_stream)) == EAGAIN) {
         pstream_wait(pstream);
         poll_block();
index d8807fda3e521b46d9a975138f3c408ba6724661..99d5a54d4e8f572293d3f88a70e25365d49f87fa 100644 (file)
@@ -25,6 +25,7 @@
 #include <string.h>
 #include "coverage.h"
 #include "dynamic-string.h"
+#include "fatal-signal.h"
 #include "flow.h"
 #include "ofp-print.h"
 #include "ofpbuf.h"
@@ -273,6 +274,8 @@ vconn_open_block(const char *name, int min_version, struct vconn **vconnp)
     struct vconn *vconn;
     int error;
 
+    fatal_signal_run();
+
     error = vconn_open(name, min_version, &vconn);
     while (error == EAGAIN) {
         vconn_run(vconn);
@@ -607,6 +610,9 @@ int
 vconn_send_block(struct vconn *vconn, struct ofpbuf *msg)
 {
     int retval;
+
+    fatal_signal_run();
+
     while ((retval = vconn_send(vconn, msg)) == EAGAIN) {
         vconn_run(vconn);
         vconn_run_wait(vconn);
@@ -621,6 +627,9 @@ int
 vconn_recv_block(struct vconn *vconn, struct ofpbuf **msgp)
 {
     int retval;
+
+    fatal_signal_run();
+
     while ((retval = vconn_recv(vconn, msgp)) == EAGAIN) {
         vconn_run(vconn);
         vconn_run_wait(vconn);