From 6771e8b7c92c5904a48ee921ee1055fa228d742b Mon Sep 17 00:00:00 2001 From: Wim Taymans Date: Mon, 10 Oct 2005 12:29:22 +0000 Subject: [PATCH] gst/tcp/gsttcpserversrc.c: Don't block in accept while doing the state change, move to poll and make cancellable. Original commit message from CVS: * gst/tcp/gsttcpserversrc.c: (gst_tcpserversrc_create), (gst_tcpserversrc_start): Don't block in accept while doing the state change, move to poll and make cancellable. --- ChangeLog | 7 ++++ gst/tcp/gsttcpserversrc.c | 85 +++++++++++++++++++++++++++++++-------- 2 files changed, 75 insertions(+), 17 deletions(-) diff --git a/ChangeLog b/ChangeLog index b04a5b6a4a..ed3fc12218 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2005-10-10 Wim Taymans + + * gst/tcp/gsttcpserversrc.c: (gst_tcpserversrc_create), + (gst_tcpserversrc_start): + Don't block in accept while doing the state change, move + to poll and make cancellable. + 2005-10-09 Philippe Khalaf * gst-libs/gst/rtp/rtpbasedepayload.c: diff --git a/gst/tcp/gsttcpserversrc.c b/gst/tcp/gsttcpserversrc.c index b460f85e94..5bfab2f205 100644 --- a/gst/tcp/gsttcpserversrc.c +++ b/gst/tcp/gsttcpserversrc.c @@ -170,12 +170,50 @@ gst_tcpserversrc_create (GstPushSrc * psrc, GstBuffer ** outbuf) { GstTCPServerSrc *src; GstFlowReturn ret = GST_FLOW_OK; + fd_set testfds; + int maxfdp1; src = GST_TCPSERVERSRC (psrc); if (!GST_FLAG_IS_SET (src, GST_TCPSERVERSRC_OPEN)) goto wrong_state; +restart: + /* do a blocking select on the socket */ + FD_ZERO (&testfds); + + /* always select on cancel socket */ + FD_SET (READ_SOCKET (src), &testfds); + + if (src->client_sock_fd >= 0) { + /* if we have a client, wait for read */ + FD_SET (src->client_sock_fd, &testfds); + maxfdp1 = MAX (src->client_sock_fd, READ_SOCKET (src)) + 1; + } else { + /* else wait on server socket for connections */ + FD_SET (src->server_sock_fd, &testfds); + maxfdp1 = MAX (src->server_sock_fd, READ_SOCKET (src)) + 1; + } + + /* no action (0) is an error too in our case */ + if (select (maxfdp1, &testfds, NULL, NULL, 0) <= 0) + goto select_error; + + if (FD_ISSET (READ_SOCKET (src), &testfds)) + goto select_cancelled; + + /* if we have no client socket we can accept one now */ + if (src->client_sock_fd < 0) { + if (FD_ISSET (src->server_sock_fd, &testfds)) { + if ((src->client_sock_fd = + accept (src->server_sock_fd, (struct sockaddr *) &src->client_sin, + &src->client_sin_len)) == -1) + goto accept_error; + } + /* and restart now to poll the socket. */ + goto restart; + } + GST_LOG_OBJECT (src, "asked for a buffer"); switch (src->protocol) { @@ -192,6 +230,9 @@ gst_tcpserversrc_create (GstPushSrc * psrc, GstBuffer ** outbuf) ret = gst_tcp_gdp_read_caps (GST_ELEMENT (src), src->client_sock_fd, READ_SOCKET (src), &caps); + if (ret == GST_FLOW_WRONG_STATE) + goto gdp_cancelled; + if (ret != GST_FLOW_OK) goto gdp_caps_read_error; @@ -235,10 +276,35 @@ wrong_state: GST_DEBUG_OBJECT (src, "connection to closed, cannot read data"); return GST_FLOW_WRONG_STATE; } -gdp_caps_read_error: +select_error: { GST_ELEMENT_ERROR (src, RESOURCE, READ, (NULL), - ("Could not read caps through GDP")); + ("Select error: %s", g_strerror (errno))); + return GST_FLOW_ERROR; + } +select_cancelled: + { + GST_DEBUG_OBJECT (src, "select canceled"); + return GST_FLOW_WRONG_STATE; + } +accept_error: + { + GST_ELEMENT_ERROR (src, RESOURCE, OPEN_READ, (NULL), + ("Could not accept client on server socket: %s", g_strerror (errno))); + return GST_FLOW_ERROR; + } +gdp_cancelled: + { + GST_DEBUG_OBJECT (src, "reading gdp canceled"); + return GST_FLOW_WRONG_STATE; + } +gdp_caps_read_error: + { + /* if we did not get canceled, report an error */ + if (ret != GST_FLOW_WRONG_STATE) { + GST_ELEMENT_ERROR (src, RESOURCE, READ, (NULL), + ("Could not read caps through GDP")); + } return ret; } } @@ -350,14 +416,6 @@ gst_tcpserversrc_start (GstBaseSrc * bsrc) if (listen (src->server_sock_fd, TCP_BACKLOG) == -1) goto listen_error; - /* FIXME: maybe we should think about moving actual client accepting - somewhere else */ - GST_DEBUG_OBJECT (src, "waiting for client"); - if ((src->client_sock_fd = - accept (src->server_sock_fd, (struct sockaddr *) &src->client_sin, - &src->client_sin_len)) == -1) - goto accept_error; - GST_DEBUG_OBJECT (src, "received client"); GST_FLAG_SET (src, GST_TCPSERVERSRC_OPEN); @@ -405,13 +463,6 @@ listen_error: ("Could not listen on server socket: %s", g_strerror (errno))); return FALSE; } -accept_error: - { - gst_tcp_socket_close (&src->server_sock_fd); - GST_ELEMENT_ERROR (src, RESOURCE, OPEN_READ, (NULL), - ("Could not accept client on server socket: %s", g_strerror (errno))); - return FALSE; - } } static gboolean