jsonrpc: Keep jsonrpc_recv() from taking over the CPU.
authorBen Pfaff <blp@nicira.com>
Tue, 24 Apr 2012 17:57:41 +0000 (10:57 -0700)
committerBen Pfaff <blp@nicira.com>
Wed, 25 Apr 2012 22:17:31 +0000 (15:17 -0700)
jsonrpc_recv() could take an unbounded amount of CPU time as long as data
kept arriving, preventing other work from taking place.  This limits the
amount of work to processing at most 25 kB of received data and then
yielding to the caller.

Signed-off-by: Ben Pfaff <blp@nicira.com>
lib/jsonrpc.c

index fc8a75b08af1fbfe6694e36e2d4ecb514c515763..4ebff104a96180136b4c31b214b5eb2b7c8ec04e 100644 (file)
@@ -277,13 +277,19 @@ jsonrpc_send(struct jsonrpc *rpc, struct jsonrpc_msg *msg)
 int
 jsonrpc_recv(struct jsonrpc *rpc, struct jsonrpc_msg **msgp)
 {
+    int i;
+
     *msgp = NULL;
     if (rpc->status) {
         return rpc->status;
     }
 
-    while (!rpc->received) {
-        if (byteq_is_empty(&rpc->input)) {
+    for (i = 0; i < 50; i++) {
+        if (rpc->received) {
+            *msgp = rpc->received;
+            rpc->received = NULL;
+            return 0;
+        } else if (byteq_is_empty(&rpc->input)) {
             size_t chunk;
             int retval;
 
@@ -328,9 +334,7 @@ jsonrpc_recv(struct jsonrpc *rpc, struct jsonrpc_msg **msgp)
         }
     }
 
-    *msgp = rpc->received;
-    rpc->received = NULL;
-    return 0;
+    return EAGAIN;
 }
 
 /* Causes the poll loop to wake up when jsonrpc_recv() may return a value other