stream: New functions stream_verify_name() and pstream_verify_name().
[openvswitch] / lib / jsonrpc.c
index aeb1dd8245fa77b14562b986472ab55fc1d1ea4a..5e054802f785b2af53a61c31e8da0c32bdfac996 100644 (file)
@@ -152,19 +152,19 @@ jsonrpc_log_msg(const struct jsonrpc *rpc, const char *title,
         }
         if (msg->params) {
             ds_put_cstr(&s, ", params=");
-            ds_put_and_free_cstr(&s, json_to_string(msg->params, 0));
+            json_to_ds(msg->params, 0, &s);
         }
         if (msg->result) {
             ds_put_cstr(&s, ", result=");
-            ds_put_and_free_cstr(&s, json_to_string(msg->result, 0));
+            json_to_ds(msg->result, 0, &s);
         }
         if (msg->error) {
             ds_put_cstr(&s, ", error=");
-            ds_put_and_free_cstr(&s, json_to_string(msg->error, 0));
+            json_to_ds(msg->error, 0, &s);
         }
         if (msg->id) {
             ds_put_cstr(&s, ", id=");
-            ds_put_and_free_cstr(&s, json_to_string(msg->id, 0));
+            json_to_ds(msg->id, 0, &s);
         }
         VLOG_DBG("%s: %s %s%s", rpc->name, title,
                  jsonrpc_msg_type_to_string(msg->type), ds_cstr(&s));
@@ -172,6 +172,7 @@ jsonrpc_log_msg(const struct jsonrpc *rpc, const char *title,
     }
 }
 
+/* Always takes ownership of 'msg', regardless of success. */
 int
 jsonrpc_send(struct jsonrpc *rpc, struct jsonrpc_msg *msg)
 {
@@ -268,6 +269,7 @@ jsonrpc_recv_wait(struct jsonrpc *rpc)
     }
 }
 
+/* Always takes ownership of 'msg', regardless of success. */
 int
 jsonrpc_send_block(struct jsonrpc *rpc, struct jsonrpc_msg *msg)
 {
@@ -278,12 +280,14 @@ jsonrpc_send_block(struct jsonrpc *rpc, struct jsonrpc_msg *msg)
         return error;
     }
 
-    while (!queue_is_empty(&rpc->output) && !rpc->status) {
+    for (;;) {
         jsonrpc_run(rpc);
+        if (queue_is_empty(&rpc->output) || rpc->status) {
+            return rpc->status;
+        }
         jsonrpc_wait(rpc);
         poll_block();
     }
-    return rpc->status;
 }
 
 int
@@ -302,6 +306,7 @@ jsonrpc_recv_block(struct jsonrpc *rpc, struct jsonrpc_msg **msgp)
     }
 }
 
+/* Always takes ownership of 'request', regardless of success. */
 int
 jsonrpc_transact_block(struct jsonrpc *rpc, struct jsonrpc_msg *request,
                        struct jsonrpc_msg **replyp)
@@ -679,6 +684,7 @@ jsonrpc_session_close(struct jsonrpc_session *s)
     if (s) {
         jsonrpc_close(s->rpc);
         reconnect_destroy(s->reconnect);
+        stream_close(s->stream);
         free(s);
     }
 }
@@ -790,10 +796,16 @@ jsonrpc_session_get_name(const struct jsonrpc_session *s)
     return reconnect_get_name(s->reconnect);
 }
 
+/* Always takes ownership of 'msg', regardless of success. */
 int
 jsonrpc_session_send(struct jsonrpc_session *s, struct jsonrpc_msg *msg)
 {
-    return s->rpc ? jsonrpc_send(s->rpc, msg) : ENOTCONN;
+    if (s->rpc) {
+        return jsonrpc_send(s->rpc, msg);
+    } else {
+        jsonrpc_msg_destroy(msg);
+        return ENOTCONN;
+    }
 }
 
 struct jsonrpc_msg *