X-Git-Url: https://git.lttng.org/?p=lttng-tools.git;a=blobdiff_plain;f=src%2Fbin%2Flttng-relayd%2Fconnection.c;h=d657efb4f97eb5ec8fc75260505b6f40ae8f2eec;hp=fce6c84d58c922f5d26491c62160ba49ab2577ef;hb=3a5328d20432d9782b24ddeaaa093ac6219d6e29;hpb=7591bab11eceedc6a0d1e02fd6f85592267a63b5 diff --git a/src/bin/lttng-relayd/connection.c b/src/bin/lttng-relayd/connection.c index fce6c84d5..d657efb4f 100644 --- a/src/bin/lttng-relayd/connection.c +++ b/src/bin/lttng-relayd/connection.c @@ -1,23 +1,12 @@ /* - * Copyright (C) 2013 - Julien Desfossez - * David Goulet - * 2015 - Mathieu Desnoyers + * Copyright (C) 2013 Julien Desfossez + * Copyright (C) 2013 David Goulet + * Copyright (C) 2015 Mathieu Desnoyers * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License, version 2 only, as - * published by the Free Software Foundation. + * SPDX-License-Identifier: GPL-2.0-only * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., 51 - * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ -#define _GNU_SOURCE #define _LGPL_SOURCE #include #include @@ -28,16 +17,7 @@ bool connection_get(struct relay_connection *conn) { - bool has_ref = false; - - pthread_mutex_lock(&conn->reflock); - if (conn->ref.refcount != 0) { - has_ref = true; - urcu_ref_get(&conn->ref); - } - pthread_mutex_unlock(&conn->reflock); - - return has_ref; + return urcu_ref_get_unless_zero(&conn->ref); } struct relay_connection *connection_get_by_sock(struct lttng_ht *relay_connections_ht, @@ -66,6 +46,45 @@ end: return conn; } +int connection_reset_protocol_state(struct relay_connection *connection) +{ + int ret = 0; + + switch (connection->type) { + case RELAY_DATA: + connection->protocol.data.state_id = + DATA_CONNECTION_STATE_RECEIVE_HEADER; + memset(&connection->protocol.data.state.receive_header, + 0, + sizeof(connection->protocol.data.state.receive_header)); + connection->protocol.data.state.receive_header.left_to_receive = + sizeof(struct lttcomm_relayd_data_hdr); + break; + case RELAY_CONTROL: + connection->protocol.ctrl.state_id = + CTRL_CONNECTION_STATE_RECEIVE_HEADER; + memset(&connection->protocol.ctrl.state.receive_header, + 0, + sizeof(connection->protocol.ctrl.state.receive_header)); + connection->protocol.data.state.receive_header.left_to_receive = + sizeof(struct lttcomm_relayd_hdr); + ret = lttng_dynamic_buffer_set_size( + &connection->protocol.ctrl.reception_buffer, + sizeof(struct lttcomm_relayd_hdr)); + if (ret) { + ERR("Failed to reinitialize control connection reception buffer size to %zu bytes.", sizeof(struct lttcomm_relayd_hdr)); + goto end; + } + break; + default: + goto end; + } + DBG("Reset communication state of relay connection (fd = %i)", + connection->sock->fd); +end: + return ret; +} + struct relay_connection *connection_create(struct lttcomm_sock *sock, enum connection_type type) { @@ -76,11 +95,14 @@ struct relay_connection *connection_create(struct lttcomm_sock *sock, PERROR("zmalloc relay connection"); goto end; } - pthread_mutex_init(&conn->reflock, NULL); urcu_ref_init(&conn->ref); conn->type = type; conn->sock = sock; lttng_ht_node_init_ulong(&conn->sock_n, (unsigned long) conn->sock->fd); + if (conn->type == RELAY_CONTROL) { + lttng_dynamic_buffer_init(&conn->protocol.ctrl.reception_buffer); + } + connection_reset_protocol_state(conn); end: return conn; } @@ -95,6 +117,10 @@ static void rcu_free_connection(struct rcu_head *head) viewer_session_destroy(conn->viewer_session); conn->viewer_session = NULL; } + if (conn->type == RELAY_CONTROL) { + lttng_dynamic_buffer_reset( + &conn->protocol.ctrl.reception_buffer); + } free(conn); } @@ -132,9 +158,7 @@ static void connection_release(struct urcu_ref *ref) void connection_put(struct relay_connection *conn) { rcu_read_lock(); - pthread_mutex_lock(&conn->reflock); urcu_ref_put(&conn->ref, connection_release); - pthread_mutex_unlock(&conn->reflock); rcu_read_unlock(); } @@ -146,3 +170,27 @@ void connection_ht_add(struct lttng_ht *relay_connections_ht, conn->in_socket_ht = 1; conn->socket_ht = relay_connections_ht; } + +int connection_set_session(struct relay_connection *conn, + struct relay_session *session) +{ + int ret = 0; + + assert(conn); + assert(session); + assert(!conn->session); + + if (connection_get(conn)) { + if (session_get(session)) { + conn->session = session; + } else { + ERR("Failed to get session reference in connection_set_session()"); + ret = -1; + } + connection_put(conn); + } else { + ERR("Failed to get connection reference in connection_set_session()"); + ret = -1; + } + return ret; +}