2008-08-20 Wim Taymans <wim.taymans@collabora.co.uk>
+ Patch by: Peter Kjellerstedt <pkj at axis com>
+
+ * gst/udp/gstdynudpsink.c: (gst_dynudpsink_init),
+ (gst_dynudpsink_finalize), (gst_dynudpsink_set_property),
+ (gst_dynudpsink_init_send), (gst_dynudpsink_close):
+ * gst/udp/gstmultiudpsink.c: (gst_multiudpsink_init),
+ (gst_multiudpsink_finalize), (gst_multiudpsink_set_property):
+ * gst/udp/gstudpsrc.c: (gst_udpsrc_finalize),
+ (gst_udpsrc_set_property):
+ Avoid leaking internally allocated file descriptors when setting
+ custom file descriptors. Fixes #543101.
+
+2008-08-20 Wim Taymans <wim.taymans@collabora.co.uk>
+
* gst/rtsp/gstrtspsrc.c: (gst_rtspsrc_stream_configure_udp_sink):
Don't try to configure RTCP back to the server when the server did not
give us a valid port number.
GST_DEBUG_CATEGORY_STATIC (dynudpsink_debug);
#define GST_CAT_DEFAULT (dynudpsink_debug)
-#define CLOSE_IF_REQUESTED(udpctx) \
- if ((!udpctx->externalfd) || (udpctx->externalfd && udpctx->closefd)) \
- CLOSE_SOCKET(udpctx->sock); \
- udpctx->sock = -1;
-
static GstStaticPadTemplate sink_template = GST_STATIC_PAD_TEMPLATE ("sink",
GST_PAD_SINK,
GST_PAD_ALWAYS,
PROP_CLOSEFD
};
+#define CLOSE_IF_REQUESTED(udpctx) \
+G_STMT_START { \
+ if ((!udpctx->externalfd) || (udpctx->externalfd && udpctx->closefd)) { \
+ CLOSE_SOCKET(udpctx->sock); \
+ if (udpctx->sock == udpctx->sockfd) \
+ udpctx->sockfd = UDP_DEFAULT_SOCKFD; \
+ } \
+ udpctx->sock = -1; \
+} G_STMT_END
+
static void gst_dynudpsink_base_init (gpointer g_class);
static void gst_dynudpsink_class_init (GstDynUDPSink * klass);
static void gst_dynudpsink_init (GstDynUDPSink * udpsink);
static void
gst_dynudpsink_init (GstDynUDPSink * sink)
{
- GstDynUDPSink *udpsink;
-
WSA_STARTUP (sink);
- udpsink = GST_DYNUDPSINK (sink);
-
sink->sockfd = UDP_DEFAULT_SOCKFD;
sink->closefd = UDP_DEFAULT_CLOSEFD;
sink->externalfd = FALSE;
static void
gst_dynudpsink_finalize (GObject * object)
{
+ GstDynUDPSink *udpsink;
+
+ udpsink = GST_DYNUDPSINK (object);
+
+ if (udpsink->sockfd >= 0 && udpsink->closefd)
+ CLOSE_SOCKET (udpsink->sockfd);
+
G_OBJECT_CLASS (parent_class)->finalize (object);
WSA_CLEANUP (object);
switch (prop_id) {
case PROP_SOCKFD:
+ if (udpsink->sockfd >= 0 && udpsink->sockfd != udpsink->sock &&
+ udpsink->closefd)
+ CLOSE_SOCKET (udpsink->sockfd);
udpsink->sockfd = g_value_get_int (value);
GST_DEBUG ("setting SOCKFD to %d", udpsink->sockfd);
break;
if (sink->sockfd == -1) {
/* create sender socket if none available */
- if ((sink->sock = socket (AF_INET, SOCK_DGRAM, 0)) == -1)
+ if ((sink->sock = socket (AF_INET, SOCK_DGRAM, 0)) < 0)
goto no_socket;
bc_val = 1;
static void
gst_dynudpsink_close (GstDynUDPSink * sink)
{
- if (sink->sock != -1)
- CLOSE_IF_REQUESTED (sink);
+ CLOSE_IF_REQUESTED (sink);
}
static GstStateChangeReturn
};
#define CLOSE_IF_REQUESTED(udpctx) \
- if ((!udpctx->externalfd) || (udpctx->externalfd && udpctx->closefd)) \
+G_STMT_START { \
+ if ((!udpctx->externalfd) || (udpctx->externalfd && udpctx->closefd)) { \
CLOSE_SOCKET(udpctx->sock); \
- udpctx->sock = -1;
+ if (udpctx->sock == udpctx->sockfd) \
+ udpctx->sockfd = DEFAULT_SOCKFD; \
+ } \
+ udpctx->sock = DEFAULT_SOCK; \
+} G_STMT_END
static void gst_multiudpsink_base_init (gpointer g_class);
static void gst_multiudpsink_class_init (GstMultiUDPSinkClass * klass);
WSA_STARTUP (sink);
sink->client_lock = g_mutex_new ();
- sink->sock = -1;
+ sink->sock = DEFAULT_SOCK;
sink->sockfd = DEFAULT_SOCKFD;
sink->closefd = DEFAULT_CLOSEFD;
sink->externalfd = (sink->sockfd != -1);
g_list_foreach (sink->clients, (GFunc) free_client, NULL);
g_list_free (sink->clients);
+ if (sink->sockfd >= 0 && sink->closefd)
+ CLOSE_SOCKET (sink->sockfd);
+
g_mutex_free (sink->client_lock);
WSA_CLEANUP (object);
switch (prop_id) {
case PROP_SOCKFD:
+ if (udpsink->sockfd >= 0 && udpsink->sockfd != udpsink->sock &&
+ udpsink->closefd)
+ CLOSE_SOCKET (udpsink->sockfd);
udpsink->sockfd = g_value_get_int (value);
GST_DEBUG_OBJECT (udpsink, "setting SOCKFD to %d", udpsink->sockfd);
break;
GST_DEBUG_CATEGORY_STATIC (udpsrc_debug);
#define GST_CAT_DEFAULT (udpsrc_debug)
-#define CLOSE_IF_REQUESTED(udpctx) \
-G_STMT_START { \
- if ((!udpctx->externalfd) || (udpctx->externalfd && udpctx->closefd)) \
- CLOSE_SOCKET(udpctx->sock.fd); \
- udpctx->sock.fd = -1; \
-} G_STMT_END
-
static GstStaticPadTemplate src_template = GST_STATIC_PAD_TEMPLATE ("src",
GST_PAD_SRC,
GST_PAD_ALWAYS,
PROP_LAST
};
+#define CLOSE_IF_REQUESTED(udpctx) \
+G_STMT_START { \
+ if ((!udpctx->externalfd) || (udpctx->externalfd && udpctx->closefd)) { \
+ CLOSE_SOCKET(udpctx->sock.fd); \
+ if (udpctx->sock.fd == udpctx->sockfd) \
+ udpctx->sockfd = UDP_DEFAULT_SOCKFD; \
+ } \
+ udpctx->sock.fd = UDP_DEFAULT_SOCK; \
+} G_STMT_END
+
static void gst_udpsrc_uri_handler_init (gpointer g_iface, gpointer iface_data);
static GstCaps *gst_udpsrc_getcaps (GstBaseSrc * src);
g_free (udpsrc->multi_group);
g_free (udpsrc->uri);
- WSA_CLEANUP (src);
+ if (udpsrc->sockfd >= 0 && udpsrc->closefd)
+ CLOSE_SOCKET (udpsrc->sockfd);
+
+ WSA_CLEANUP (object);
G_OBJECT_CLASS (parent_class)->finalize (object);
}
break;
}
case PROP_SOCKFD:
+ if (udpsrc->sockfd >= 0 && udpsrc->sockfd != udpsrc->sock.fd &&
+ udpsrc->closefd)
+ CLOSE_SOCKET (udpsrc->sockfd);
udpsrc->sockfd = g_value_get_int (value);
GST_DEBUG ("setting SOCKFD to %d", udpsrc->sockfd);
break;