From 65042a9551a9cf4586d6e3fa49e6a10f25873553 Mon Sep 17 00:00:00 2001 From: Alessandro Decina Date: Sat, 17 Nov 2012 14:51:52 +0100 Subject: [PATCH] client: wait until the TEARDOWN response is sent to close the connection Responses can be sent async so we need to wait until the TEARDOWN response has been written before we close the connection to the client. This avoids the risk of writing/polling closed sockets. Fixes https://bugzilla.gnome.org/show_bug.cgi?id=688535 --- gst/rtsp-server/rtsp-client.c | 40 ++++++++++++++++++++++------------------ gst/rtsp-server/rtsp-client.h | 2 ++ 2 files changed, 24 insertions(+), 18 deletions(-) diff --git a/gst/rtsp-server/rtsp-client.c b/gst/rtsp-server/rtsp-client.c index 9389160..799b42e 100644 --- a/gst/rtsp-server/rtsp-client.c +++ b/gst/rtsp-server/rtsp-client.c @@ -174,6 +174,7 @@ static void gst_rtsp_client_init (GstRTSPClient * client) { client->use_client_settings = DEFAULT_USE_CLIENT_SETTINGS; + client->teardown_response_seq = 0; } static void @@ -300,7 +301,7 @@ gst_rtsp_client_new (void) static void send_response (GstRTSPClient * client, GstRTSPSession * session, - GstRTSPMessage * response) + GstRTSPMessage * response, guint * id) { gst_rtsp_message_add_header (response, GST_RTSP_HDR_SERVER, "GStreamer RTSP server"); @@ -318,7 +319,7 @@ send_response (GstRTSPClient * client, GstRTSPSession * session, gst_rtsp_message_dump (response); } - gst_rtsp_watch_send_message (client->watch, response, NULL); + gst_rtsp_watch_send_message (client->watch, response, id); gst_rtsp_message_unset (response); } @@ -329,7 +330,7 @@ send_generic_response (GstRTSPClient * client, GstRTSPStatusCode code, gst_rtsp_message_init_response (state->response, code, gst_rtsp_status_as_text (code), state->request); - send_response (client, NULL, state->response); + send_response (client, NULL, state->response, NULL); } static void @@ -344,7 +345,7 @@ handle_unauthorized_request (GstRTSPClient * client, GstRTSPAuth * auth, gst_rtsp_auth_setup_auth (auth, client, 0, state); } - send_response (client, state->session, state->response); + send_response (client, state->session, state->response, NULL); } @@ -603,14 +604,15 @@ handle_teardown_request (GstRTSPClient * client, GstRTSPClientState * state) gst_rtsp_message_add_header (state->response, GST_RTSP_HDR_CONNECTION, "close"); - send_response (client, session, state->response); + /* send the response and store the seq number so we can wait until it's + * written to the client to close the connection */ + send_response (client, session, state->response, + &client->teardown_response_seq); /* we emit the signal before closing the connection */ g_signal_emit (client, gst_rtsp_client_signals[SIGNAL_TEARDOWN_REQUEST], 0, state); - close_connection (client); - return TRUE; /* ERRORS */ @@ -646,7 +648,7 @@ handle_get_param_request (GstRTSPClient * client, GstRTSPClientState * state) if (res != GST_RTSP_OK) goto bad_request; - send_response (client, state->session, state->response); + send_response (client, state->session, state->response, NULL); } g_signal_emit (client, gst_rtsp_client_signals[SIGNAL_GET_PARAMETER_REQUEST], @@ -682,7 +684,7 @@ handle_set_param_request (GstRTSPClient * client, GstRTSPClientState * state) if (res != GST_RTSP_OK) goto bad_request; - send_response (client, state->session, state->response); + send_response (client, state->session, state->response, NULL); } g_signal_emit (client, gst_rtsp_client_signals[SIGNAL_SET_PARAMETER_REQUEST], @@ -731,7 +733,7 @@ handle_pause_request (GstRTSPClient * client, GstRTSPClientState * state) gst_rtsp_message_init_response (state->response, code, gst_rtsp_status_as_text (code), state->request); - send_response (client, session, state->response); + send_response (client, session, state->response, NULL); /* the state is now READY */ media->state = GST_RTSP_STATE_READY; @@ -853,7 +855,7 @@ handle_play_request (GstRTSPClient * client, GstRTSPClientState * state) str = gst_rtsp_media_get_range_string (media->media, TRUE); gst_rtsp_message_take_header (state->response, GST_RTSP_HDR_RANGE, str); - send_response (client, session, state->response); + send_response (client, session, state->response, NULL); /* start playing after sending the request */ gst_rtsp_session_media_set_state (media, GST_STATE_PLAYING); @@ -1179,7 +1181,7 @@ handle_setup_request (GstRTSPClient * client, GstRTSPClientState * state) trans_str); g_free (trans_str); - send_response (client, session, state->response); + send_response (client, session, state->response, NULL); /* update the state */ switch (sessmedia->state) { @@ -1368,7 +1370,7 @@ handle_describe_request (GstRTSPClient * client, GstRTSPClientState * state) gst_rtsp_message_take_body (state->response, (guint8 *) str, strlen (str)); gst_sdp_message_free (sdp); - send_response (client, state->session, state->response); + send_response (client, state->session, state->response, NULL); g_signal_emit (client, gst_rtsp_client_signals[SIGNAL_DESCRIBE_REQUEST], 0, state); @@ -1410,7 +1412,7 @@ handle_options_request (GstRTSPClient * client, GstRTSPClientState * state) gst_rtsp_message_add_header (state->response, GST_RTSP_HDR_PUBLIC, str); g_free (str); - send_response (client, state->session, state->response); + send_response (client, state->session, state->response, NULL); g_signal_emit (client, gst_rtsp_client_signals[SIGNAL_OPTIONS_REQUEST], 0, state); @@ -1891,11 +1893,13 @@ message_received (GstRTSPWatch * watch, GstRTSPMessage * message, static GstRTSPResult message_sent (GstRTSPWatch * watch, guint cseq, gpointer user_data) { - /* GstRTSPClient *client; */ - - /* client = GST_RTSP_CLIENT (user_data); */ + GstRTSPClient *client; - /* GST_INFO ("client %p: sent a message with cseq %d", client, cseq); */ + client = GST_RTSP_CLIENT (user_data); + if (client->teardown_response_seq && client->teardown_response_seq == cseq) { + client->teardown_response_seq = 0; + close_connection (client); + } return GST_RTSP_OK; } diff --git a/gst/rtsp-server/rtsp-client.h b/gst/rtsp-server/rtsp-client.h index 71a28ad..dd4e712 100644 --- a/gst/rtsp-server/rtsp-client.h +++ b/gst/rtsp-server/rtsp-client.h @@ -107,6 +107,8 @@ struct _GstRTSPClient { GList *transports; GList *sessions; + + guint teardown_response_seq; }; struct _GstRTSPClientClass { -- 2.7.4