X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=plugins%2Fctf%2Flttng-live%2Fviewer-connection.c;h=79d2c31ef926962f7f709e763829af59e36ec01c;hb=da91b29ad2964b85601e25843f1dca92f6c97406;hp=e66bd1e8aa9c0929b80b97476956af02ebf5a909;hpb=50842bdc4c21f3de2b63e29cdac730af8b6dcca6;p=babeltrace.git diff --git a/plugins/ctf/lttng-live/viewer-connection.c b/plugins/ctf/lttng-live/viewer-connection.c index e66bd1e8..79d2c31e 100644 --- a/plugins/ctf/lttng-live/viewer-connection.c +++ b/plugins/ctf/lttng-live/viewer-connection.c @@ -57,7 +57,7 @@ static ssize_t lttng_live_recv(struct bt_live_viewer_connection *viewer_connecti do { ret = bt_socket_recv(sock, buf + copied, to_copy, 0); if (ret > 0) { - assert(ret <= to_copy); + BT_ASSERT(ret <= to_copy); copied += ret; to_copy -= ret; } @@ -157,6 +157,8 @@ static int lttng_live_handshake(struct bt_live_viewer_connection *viewer_connect { struct lttng_viewer_cmd cmd; struct lttng_viewer_connect connect; + const size_t cmd_buf_len = sizeof(cmd) + sizeof(connect); + char cmd_buf[cmd_buf_len]; int ret; ssize_t ret_len; @@ -169,19 +171,20 @@ static int lttng_live_handshake(struct bt_live_viewer_connection *viewer_connect connect.minor = htobe32(LTTNG_LIVE_MINOR); connect.type = htobe32(LTTNG_VIEWER_CLIENT_COMMAND); - ret_len = lttng_live_send(viewer_connection, &cmd, sizeof(cmd)); - if (ret_len == BT_SOCKET_ERROR) { - BT_LOGE("Error sending cmd: %s", bt_socket_errormsg()); - goto error; - } - assert(ret_len == sizeof(cmd)); - - ret_len = lttng_live_send(viewer_connection, &connect, sizeof(connect)); + /* + * Merge the cmd and connection request to prevent a write-write + * sequence on the TCP socket. Otherwise, a delayed ACK will prevent the + * second write to be performed quickly in presence of Nagle's algorithm + */ + memcpy(cmd_buf, &cmd, sizeof(cmd)); + memcpy(cmd_buf + sizeof(cmd), &connect, sizeof(connect)); + ret_len = lttng_live_send(viewer_connection, &cmd_buf, cmd_buf_len); if (ret_len == BT_SOCKET_ERROR) { BT_LOGE("Error sending version: %s", bt_socket_errormsg()); goto error; } - assert(ret_len == sizeof(connect)); + + BT_ASSERT(ret_len == cmd_buf_len); ret_len = lttng_live_recv(viewer_connection, &connect, sizeof(connect)); if (ret_len == 0) { @@ -192,7 +195,7 @@ static int lttng_live_handshake(struct bt_live_viewer_connection *viewer_connect BT_LOGE("Error receiving version: %s", bt_socket_errormsg()); goto error; } - assert(ret_len == sizeof(connect)); + BT_ASSERT(ret_len == sizeof(connect)); BT_LOGD("Received viewer session ID : %" PRIu64, (uint64_t) be64toh(connect.viewer_session_id)); @@ -300,7 +303,7 @@ enum bt_value_status list_update_session(struct bt_value *results, int i, len; bool found = false; - len = bt_value_array_size(results); + len = bt_value_array_get_size(results); if (len < 0) { ret = BT_VALUE_STATUS_ERROR; goto end; @@ -353,11 +356,11 @@ enum bt_value_status list_update_session(struct bt_value *results, } /* sum */ val += streams; - ret = bt_value_integer_set(btval, val); + ret = bt_private_integer_bool_set(btval, val); if (ret != BT_VALUE_STATUS_OK) { goto end; } - BT_PUT(btval); + BT_OBJECT_PUT_REF_AND_RESET(btval); btval = bt_value_map_get(map, "client-count"); if (!btval) { @@ -370,26 +373,26 @@ enum bt_value_status list_update_session(struct bt_value *results, } /* max */ val = max_t(int64_t, clients, val); - ret = bt_value_integer_set(btval, val); + ret = bt_private_integer_bool_set(btval, val); if (ret != BT_VALUE_STATUS_OK) { goto end; } - BT_PUT(btval); + BT_OBJECT_PUT_REF_AND_RESET(btval); } - BT_PUT(hostname); - BT_PUT(session_name); - BT_PUT(map); + BT_OBJECT_PUT_REF_AND_RESET(hostname); + BT_OBJECT_PUT_REF_AND_RESET(session_name); + BT_OBJECT_PUT_REF_AND_RESET(map); if (found) { break; } } end: - BT_PUT(btval); - BT_PUT(hostname); - BT_PUT(session_name); - BT_PUT(map); + BT_OBJECT_PUT_REF_AND_RESET(btval); + BT_OBJECT_PUT_REF_AND_RESET(hostname); + BT_OBJECT_PUT_REF_AND_RESET(session_name); + BT_OBJECT_PUT_REF_AND_RESET(map); *_found = found; return ret; } @@ -413,7 +416,7 @@ enum bt_value_status list_append_session(struct bt_value *results, goto end; } - map = bt_value_map_create(); + map = bt_private_value_map_create(); if (!map) { ret = BT_VALUE_STATUS_ERROR; goto end; @@ -433,7 +436,7 @@ enum bt_value_status list_append_session(struct bt_value *results, g_string_append_c(url, '/'); g_string_append(url, session->session_name); - ret = bt_value_map_insert_string(map, "url", url->str); + ret = bt_private_value_map_insert_string_entry(map, "url", url->str); if (ret != BT_VALUE_STATUS_OK) { goto end; } @@ -442,7 +445,7 @@ enum bt_value_status list_append_session(struct bt_value *results, * key = "target-hostname", * value = , */ - ret = bt_value_map_insert_string(map, "target-hostname", + ret = bt_private_value_map_insert_string_entry(map, "target-hostname", session->hostname); if (ret != BT_VALUE_STATUS_OK) { goto end; @@ -452,7 +455,7 @@ enum bt_value_status list_append_session(struct bt_value *results, * key = "session-name", * value = , */ - ret = bt_value_map_insert_string(map, "session-name", + ret = bt_private_value_map_insert_string_entry(map, "session-name", session->session_name); if (ret != BT_VALUE_STATUS_OK) { goto end; @@ -465,7 +468,7 @@ enum bt_value_status list_append_session(struct bt_value *results, { uint32_t live_timer = be32toh(session->live_timer); - ret = bt_value_map_insert_integer(map, "timer-us", + ret = bt_private_value_map_insert_integer_entry(map, "timer-us", live_timer); if (ret != BT_VALUE_STATUS_OK) { goto end; @@ -479,7 +482,7 @@ enum bt_value_status list_append_session(struct bt_value *results, { uint32_t streams = be32toh(session->streams); - ret = bt_value_map_insert_integer(map, "stream-count", + ret = bt_private_value_map_insert_integer_entry(map, "stream-count", streams); if (ret != BT_VALUE_STATUS_OK) { goto end; @@ -494,19 +497,19 @@ enum bt_value_status list_append_session(struct bt_value *results, { uint32_t clients = be32toh(session->clients); - ret = bt_value_map_insert_integer(map, "client-count", + ret = bt_private_value_map_insert_integer_entry(map, "client-count", clients); if (ret != BT_VALUE_STATUS_OK) { goto end; } } - ret = bt_value_array_append(results, map); + ret = bt_private_value_array_append_element(results, map); end: if (url) { g_string_free(url, TRUE); } - BT_PUT(map); + BT_OBJECT_PUT_REF_AND_RESET(map); return ret; } @@ -559,7 +562,7 @@ struct bt_value *bt_live_viewer_connection_list_sessions(struct bt_live_viewer_c goto error; } - results = bt_value_array_create(); + results = bt_private_value_array_create(); if (!results) { BT_LOGE("Error creating array"); goto error; @@ -574,7 +577,7 @@ struct bt_value *bt_live_viewer_connection_list_sessions(struct bt_live_viewer_c BT_LOGE("Error sending cmd: %s", bt_socket_errormsg()); goto error; } - assert(ret_len == sizeof(cmd)); + BT_ASSERT(ret_len == sizeof(cmd)); ret_len = lttng_live_recv(viewer_connection, &list, sizeof(list)); if (ret_len == 0) { @@ -585,7 +588,7 @@ struct bt_value *bt_live_viewer_connection_list_sessions(struct bt_live_viewer_c BT_LOGE("Error receiving session list: %s", bt_socket_errormsg()); goto error; } - assert(ret_len == sizeof(list)); + BT_ASSERT(ret_len == sizeof(list)); sessions_count = be32toh(list.sessions_count); for (i = 0; i < sessions_count; i++) { @@ -601,7 +604,7 @@ struct bt_value *bt_live_viewer_connection_list_sessions(struct bt_live_viewer_c BT_LOGE("Error receiving session: %s", bt_socket_errormsg()); goto error; } - assert(ret_len == sizeof(lsession)); + BT_ASSERT(ret_len == sizeof(lsession)); lsession.hostname[LTTNG_VIEWER_HOST_NAME_MAX - 1] = '\0'; lsession.session_name[LTTNG_VIEWER_NAME_MAX - 1] = '\0'; if (list_append_session(results, @@ -612,7 +615,7 @@ struct bt_value *bt_live_viewer_connection_list_sessions(struct bt_live_viewer_c } goto end; error: - BT_PUT(results); + BT_OBJECT_PUT_REF_AND_RESET(results); end: return results; } @@ -638,7 +641,7 @@ int lttng_live_query_session_ids(struct lttng_live_component *lttng_live) BT_LOGE("Error sending cmd: %s", bt_socket_errormsg()); goto error; } - assert(ret_len == sizeof(cmd)); + BT_ASSERT(ret_len == sizeof(cmd)); ret_len = lttng_live_recv(viewer_connection, &list, sizeof(list)); if (ret_len == 0) { @@ -649,7 +652,7 @@ int lttng_live_query_session_ids(struct lttng_live_component *lttng_live) BT_LOGE("Error receiving session list: %s", bt_socket_errormsg()); goto error; } - assert(ret_len == sizeof(list)); + BT_ASSERT(ret_len == sizeof(list)); sessions_count = be32toh(list.sessions_count); for (i = 0; i < sessions_count; i++) { @@ -663,7 +666,7 @@ int lttng_live_query_session_ids(struct lttng_live_component *lttng_live) BT_LOGE("Error receiving session: %s", bt_socket_errormsg()); goto error; } - assert(ret_len == sizeof(lsession)); + BT_ASSERT(ret_len == sizeof(lsession)); lsession.hostname[LTTNG_VIEWER_HOST_NAME_MAX - 1] = '\0'; lsession.session_name[LTTNG_VIEWER_NAME_MAX - 1] = '\0'; session_id = be64toh(lsession.id); @@ -709,7 +712,7 @@ int lttng_live_create_viewer_session(struct lttng_live_component *lttng_live) BT_LOGE("Error sending cmd: %s", bt_socket_errormsg()); goto error; } - assert(ret_len == sizeof(cmd)); + BT_ASSERT(ret_len == sizeof(cmd)); ret_len = lttng_live_recv(viewer_connection, &resp, sizeof(resp)); if (ret_len == 0) { @@ -720,7 +723,7 @@ int lttng_live_create_viewer_session(struct lttng_live_component *lttng_live) BT_LOGE("Error receiving create session reply: %s", bt_socket_errormsg()); goto error; } - assert(ret_len == sizeof(resp)); + BT_ASSERT(ret_len == sizeof(resp)); if (be32toh(resp.status) != LTTNG_VIEWER_CREATE_SESSION_OK) { BT_LOGE("Error creating viewer session"); @@ -762,7 +765,7 @@ int receive_streams(struct lttng_live_session *session, BT_LOGE("Error receiving stream"); goto error; } - assert(ret_len == sizeof(stream)); + BT_ASSERT(ret_len == sizeof(stream)); stream.path_name[LTTNG_VIEWER_PATH_MAX - 1] = '\0'; stream.channel_name[LTTNG_VIEWER_NAME_MAX - 1] = '\0'; stream_id = be64toh(stream.id); @@ -810,6 +813,8 @@ int lttng_live_attach_session(struct lttng_live_session *session) lttng_live->viewer_connection; uint64_t session_id = session->id; uint32_t streams_count; + const size_t cmd_buf_len = sizeof(cmd) + sizeof(rq); + char cmd_buf[cmd_buf_len]; if (session->attached) { return 0; @@ -825,20 +830,20 @@ int lttng_live_attach_session(struct lttng_live_session *session) // rq.seek = htobe32(LTTNG_VIEWER_SEEK_BEGINNING); rq.seek = htobe32(LTTNG_VIEWER_SEEK_LAST); - ret_len = lttng_live_send(viewer_connection, &cmd, sizeof(cmd)); - if (ret_len == BT_SOCKET_ERROR) { - BT_LOGE("Error sending cmd: %s", bt_socket_errormsg()); - goto error; - } - assert(ret_len == sizeof(cmd)); - - ret_len = lttng_live_send(viewer_connection, &rq, sizeof(rq)); + /* + * Merge the cmd and connection request to prevent a write-write + * sequence on the TCP socket. Otherwise, a delayed ACK will prevent the + * second write to be performed quickly in presence of Nagle's algorithm. + */ + memcpy(cmd_buf, &cmd, sizeof(cmd)); + memcpy(cmd_buf + sizeof(cmd), &rq, sizeof(rq)); + ret_len = lttng_live_send(viewer_connection, &cmd_buf, cmd_buf_len); if (ret_len == BT_SOCKET_ERROR) { BT_LOGE("Error sending attach request: %s", bt_socket_errormsg()); goto error; } - assert(ret_len == sizeof(rq)); + BT_ASSERT(ret_len == cmd_buf_len); ret_len = lttng_live_recv(viewer_connection, &rp, sizeof(rp)); if (ret_len == 0) { BT_LOGI("Remote side has closed connection"); @@ -848,7 +853,7 @@ int lttng_live_attach_session(struct lttng_live_session *session) BT_LOGE("Error receiving attach response: %s", bt_socket_errormsg()); goto error; } - assert(ret_len == sizeof(rp)); + BT_ASSERT(ret_len == sizeof(rp)); streams_count = be32toh(rp.streams_count); switch(be32toh(rp.status)) { @@ -896,6 +901,8 @@ int lttng_live_detach_session(struct lttng_live_session *session) struct bt_live_viewer_connection *viewer_connection = lttng_live->viewer_connection; uint64_t session_id = session->id; + const size_t cmd_buf_len = sizeof(cmd) + sizeof(rq); + char cmd_buf[cmd_buf_len]; if (!session->attached) { return 0; @@ -908,20 +915,20 @@ int lttng_live_detach_session(struct lttng_live_session *session) memset(&rq, 0, sizeof(rq)); rq.session_id = htobe64(session_id); - ret_len = lttng_live_send(viewer_connection, &cmd, sizeof(cmd)); - if (ret_len == BT_SOCKET_ERROR) { - BT_LOGE("Error sending cmd: %s", bt_socket_errormsg()); - goto error; - } - assert(ret_len == sizeof(cmd)); - - ret_len = lttng_live_send(viewer_connection, &rq, sizeof(rq)); + /* + * Merge the cmd and connection request to prevent a write-write + * sequence on the TCP socket. Otherwise, a delayed ACK will prevent the + * second write to be performed quickly in presence of Nagle's algorithm. + */ + memcpy(cmd_buf, &cmd, sizeof(cmd)); + memcpy(cmd_buf + sizeof(cmd), &rq, sizeof(rq)); + ret_len = lttng_live_send(viewer_connection, &cmd_buf, cmd_buf_len); if (ret_len == BT_SOCKET_ERROR) { BT_LOGE("Error sending detach request: %s", bt_socket_errormsg()); goto error; } - assert(ret_len == sizeof(rq)); + BT_ASSERT(ret_len == cmd_buf_len); ret_len = lttng_live_recv(viewer_connection, &rp, sizeof(rp)); if (ret_len == 0) { BT_LOGI("Remote side has closed connection"); @@ -931,7 +938,7 @@ int lttng_live_detach_session(struct lttng_live_session *session) BT_LOGE("Error receiving detach response: %s", bt_socket_errormsg()); goto error; } - assert(ret_len == sizeof(rp)); + BT_ASSERT(ret_len == sizeof(rp)); switch(be32toh(rp.status)) { case LTTNG_VIEWER_DETACH_SESSION_OK: @@ -971,26 +978,28 @@ ssize_t lttng_live_get_one_metadata_packet(struct lttng_live_trace *trace, struct lttng_live_metadata *metadata = trace->metadata; struct bt_live_viewer_connection *viewer_connection = lttng_live->viewer_connection; + const size_t cmd_buf_len = sizeof(cmd) + sizeof(rq); + char cmd_buf[cmd_buf_len]; rq.stream_id = htobe64(metadata->stream_id); cmd.cmd = htobe32(LTTNG_VIEWER_GET_METADATA); cmd.data_size = htobe64((uint64_t) sizeof(rq)); cmd.cmd_version = htobe32(0); - ret_len = lttng_live_send(viewer_connection, &cmd, sizeof(cmd)); - if (ret_len == BT_SOCKET_ERROR) { - BT_LOGE("Error sending cmd: %s", bt_socket_errormsg()); - goto error; - } - assert(ret_len == sizeof(cmd)); - - ret_len = lttng_live_send(viewer_connection, &rq, sizeof(rq)); + /* + * Merge the cmd and connection request to prevent a write-write + * sequence on the TCP socket. Otherwise, a delayed ACK will prevent the + * second write to be performed quickly in presence of Nagle's algorithm. + */ + memcpy(cmd_buf, &cmd, sizeof(cmd)); + memcpy(cmd_buf + sizeof(cmd), &rq, sizeof(rq)); + ret_len = lttng_live_send(viewer_connection, &cmd_buf, cmd_buf_len); if (ret_len == BT_SOCKET_ERROR) { BT_LOGE("Error sending get_metadata request: %s", bt_socket_errormsg()); goto error; } - assert(ret_len == sizeof(rq)); + BT_ASSERT(ret_len == cmd_buf_len); ret_len = lttng_live_recv(viewer_connection, &rp, sizeof(rp)); if (ret_len == 0) { BT_LOGI("Remote side has closed connection"); @@ -1000,7 +1009,7 @@ ssize_t lttng_live_get_one_metadata_packet(struct lttng_live_trace *trace, BT_LOGE("Error receiving get_metadata response: %s", bt_socket_errormsg()); goto error; } - assert(ret_len == sizeof(rp)); + BT_ASSERT(ret_len == sizeof(rp)); switch (be32toh(rp.status)) { case LTTNG_VIEWER_METADATA_OK: @@ -1038,7 +1047,7 @@ ssize_t lttng_live_get_one_metadata_packet(struct lttng_live_trace *trace, BT_LOGE("Error receiving trace packet: %s", bt_socket_errormsg()); goto error_free_data; } - assert(ret_len == len); + BT_ASSERT(ret_len == len); do { ret_len = fwrite(data, 1, len, fp); @@ -1047,7 +1056,7 @@ ssize_t lttng_live_get_one_metadata_packet(struct lttng_live_trace *trace, BT_LOGE("Writing in the metadata fp"); goto error_free_data; } - assert(ret_len == len); + BT_ASSERT(ret_len == len); free(data); ret = len; end: @@ -1066,8 +1075,8 @@ static void lttng_index_to_packet_index(struct lttng_viewer_index *lindex, struct packet_index *pindex) { - assert(lindex); - assert(pindex); + BT_ASSERT(lindex); + BT_ASSERT(pindex); pindex->offset = be64toh(lindex->offset); pindex->packet_size = be64toh(lindex->packet_size); @@ -1092,28 +1101,31 @@ enum bt_lttng_live_iterator_status lttng_live_get_next_index(struct lttng_live_c struct bt_live_viewer_connection *viewer_connection = lttng_live->viewer_connection; struct lttng_live_trace *trace = stream->trace; + const size_t cmd_buf_len = sizeof(cmd) + sizeof(rq); + char cmd_buf[cmd_buf_len]; cmd.cmd = htobe32(LTTNG_VIEWER_GET_NEXT_INDEX); cmd.data_size = htobe64((uint64_t) sizeof(rq)); cmd.cmd_version = htobe32(0); + memset(&rq, 0, sizeof(rq)); rq.stream_id = htobe64(stream->viewer_stream_id); - ret_len = lttng_live_send(viewer_connection, &cmd, sizeof(cmd)); - if (ret_len == BT_SOCKET_ERROR) { - BT_LOGE("Error sending cmd: %s", bt_socket_errormsg()); - goto error; - } - assert(ret_len == sizeof(cmd)); - - ret_len = lttng_live_send(viewer_connection, &rq, sizeof(rq)); + /* + * Merge the cmd and connection request to prevent a write-write + * sequence on the TCP socket. Otherwise, a delayed ACK will prevent the + * second write to be performed quickly in presence of Nagle's algorithm. + */ + memcpy(cmd_buf, &cmd, sizeof(cmd)); + memcpy(cmd_buf + sizeof(cmd), &rq, sizeof(rq)); + ret_len = lttng_live_send(viewer_connection, &cmd_buf, cmd_buf_len); if (ret_len == BT_SOCKET_ERROR) { BT_LOGE("Error sending get_next_index request: %s", bt_socket_errormsg()); goto error; } - assert(ret_len == sizeof(rq)); + BT_ASSERT(ret_len == cmd_buf_len); ret_len = lttng_live_recv(viewer_connection, &rp, sizeof(rp)); if (ret_len == 0) { BT_LOGI("Remote side has closed connection"); @@ -1123,7 +1135,7 @@ enum bt_lttng_live_iterator_status lttng_live_get_next_index(struct lttng_live_c BT_LOGE("Error receiving get_next_index response: %s", bt_socket_errormsg()); goto error; } - assert(ret_len == sizeof(rp)); + BT_ASSERT(ret_len == sizeof(rp)); flags = be32toh(rp.flags); status = be32toh(rp.status); @@ -1139,7 +1151,7 @@ enum bt_lttng_live_iterator_status lttng_live_get_next_index(struct lttng_live_c stream->current_inactivity_timestamp = index->ts_cycles.timestamp_end; ctf_stream_class_id = be64toh(rp.stream_id); if (stream->ctf_stream_class_id != -1ULL) { - assert(stream->ctf_stream_class_id == + BT_ASSERT(stream->ctf_stream_class_id == ctf_stream_class_id); } else { stream->ctf_stream_class_id = ctf_stream_class_id; @@ -1155,7 +1167,7 @@ enum bt_lttng_live_iterator_status lttng_live_get_next_index(struct lttng_live_c lttng_index_to_packet_index(&rp, index); ctf_stream_class_id = be64toh(rp.stream_id); if (stream->ctf_stream_class_id != -1ULL) { - assert(stream->ctf_stream_class_id == + BT_ASSERT(stream->ctf_stream_class_id == ctf_stream_class_id); } else { stream->ctf_stream_class_id = ctf_stream_class_id; @@ -1225,6 +1237,8 @@ enum bt_notif_iter_medium_status lttng_live_get_stream_bytes(struct lttng_live_c struct bt_live_viewer_connection *viewer_connection = lttng_live->viewer_connection; struct lttng_live_trace *trace = stream->trace; + const size_t cmd_buf_len = sizeof(cmd) + sizeof(rq); + char cmd_buf[cmd_buf_len]; BT_LOGD("lttng_live_get_stream_bytes: offset=%" PRIu64 ", req_len=%" PRIu64, offset, req_len); @@ -1237,20 +1251,20 @@ enum bt_notif_iter_medium_status lttng_live_get_stream_bytes(struct lttng_live_c rq.offset = htobe64(offset); rq.len = htobe32(req_len); - ret_len = lttng_live_send(viewer_connection, &cmd, sizeof(cmd)); - if (ret_len == BT_SOCKET_ERROR) { - BT_LOGE("Error sending cmd: %s", bt_socket_errormsg()); - goto error; - } - assert(ret_len == sizeof(cmd)); - - ret_len = lttng_live_send(viewer_connection, &rq, sizeof(rq)); + /* + * Merge the cmd and connection request to prevent a write-write + * sequence on the TCP socket. Otherwise, a delayed ACK will prevent the + * second write to be performed quickly in presence of Nagle's algorithm. + */ + memcpy(cmd_buf, &cmd, sizeof(cmd)); + memcpy(cmd_buf + sizeof(cmd), &rq, sizeof(rq)); + ret_len = lttng_live_send(viewer_connection, &cmd_buf, cmd_buf_len); if (ret_len == BT_SOCKET_ERROR) { BT_LOGE("Error sending get_data request: %s", bt_socket_errormsg()); goto error; } - assert(ret_len == sizeof(rq)); + BT_ASSERT(ret_len == cmd_buf_len); ret_len = lttng_live_recv(viewer_connection, &rp, sizeof(rp)); if (ret_len == 0) { BT_LOGI("Remote side has closed connection"); @@ -1317,7 +1331,7 @@ enum bt_notif_iter_medium_status lttng_live_get_stream_bytes(struct lttng_live_c BT_LOGE("Error receiving trace packet: %s", bt_socket_errormsg()); goto error; } - assert(ret_len == req_len); + BT_ASSERT(ret_len == req_len); *recv_len = ret_len; end: return retstatus; @@ -1348,6 +1362,8 @@ enum bt_lttng_live_iterator_status lttng_live_get_new_streams( struct bt_live_viewer_connection *viewer_connection = lttng_live->viewer_connection; uint32_t streams_count; + const size_t cmd_buf_len = sizeof(cmd) + sizeof(rq); + char cmd_buf[cmd_buf_len]; if (!session->new_streams_needed) { return BT_LTTNG_LIVE_ITERATOR_STATUS_OK; @@ -1360,20 +1376,20 @@ enum bt_lttng_live_iterator_status lttng_live_get_new_streams( memset(&rq, 0, sizeof(rq)); rq.session_id = htobe64(session->id); - ret_len = lttng_live_send(viewer_connection, &cmd, sizeof(cmd)); - if (ret_len == BT_SOCKET_ERROR) { - BT_LOGE("Error sending cmd: %s", bt_socket_errormsg()); - goto error; - } - assert(ret_len == sizeof(cmd)); - - ret_len = lttng_live_send(viewer_connection, &rq, sizeof(rq)); + /* + * Merge the cmd and connection request to prevent a write-write + * sequence on the TCP socket. Otherwise, a delayed ACK will prevent the + * second write to be performed quickly in presence of Nagle's algorithm. + */ + memcpy(cmd_buf, &cmd, sizeof(cmd)); + memcpy(cmd_buf + sizeof(cmd), &rq, sizeof(rq)); + ret_len = lttng_live_send(viewer_connection, &cmd_buf, cmd_buf_len); if (ret_len == BT_SOCKET_ERROR) { BT_LOGE("Error sending get_new_streams request: %s", bt_socket_errormsg()); goto error; } - assert(ret_len == sizeof(rq)); + BT_ASSERT(ret_len == cmd_buf_len); ret_len = lttng_live_recv(viewer_connection, &rp, sizeof(rp)); if (ret_len == 0) { BT_LOGI("Remote side has closed connection"); @@ -1383,7 +1399,7 @@ enum bt_lttng_live_iterator_status lttng_live_get_new_streams( BT_LOGE("Error receiving get_new_streams response"); goto error; } - assert(ret_len == sizeof(rp)); + BT_ASSERT(ret_len == sizeof(rp)); streams_count = be32toh(rp.streams_count);