tcpserver{sink,src}: add 'current-port' property and signal actually used port

Useful when port=0 (use random available port) was requested.

https://bugzilla.gnome.org/show_bug.cgi?id=580093
This commit is contained in:
Alexandre Relange 2012-10-17 12:19:56 +02:00 committed by Tim-Philipp Müller
parent a66ff00908
commit d2f1d82778
4 changed files with 59 additions and 5 deletions

View file

@ -53,6 +53,7 @@ enum
PROP_0,
PROP_HOST,
PROP_PORT,
PROP_CURRENT_PORT
};
static void gst_tcp_server_sink_finalize (GObject * gobject);
@ -93,6 +94,10 @@ gst_tcp_server_sink_class_init (GstTCPServerSinkClass * klass)
g_param_spec_int ("port", "port", "The port to send the packets to",
0, TCP_HIGHEST_PORT, TCP_DEFAULT_PORT,
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
g_object_class_install_property (gobject_class, PROP_CURRENT_PORT,
g_param_spec_int ("current-port", "current-port",
"The port number the socket is currently bound to", 0,
TCP_HIGHEST_PORT, 0, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
gst_element_class_set_static_metadata (gstelement_class,
"TCP server sink", "Sink/Network",
@ -256,6 +261,9 @@ gst_tcp_server_sink_get_property (GObject * object, guint prop_id,
case PROP_PORT:
g_value_set_int (value, sink->server_port);
break;
case PROP_CURRENT_PORT:
g_value_set_int (value, g_atomic_int_get (&sink->current_port));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
@ -272,6 +280,7 @@ gst_tcp_server_sink_init_send (GstMultiHandleSink * parent)
GInetAddress *addr;
GSocketAddress *saddr;
GResolver *resolver;
gint bound_port;
/* look up name if we need to */
addr = g_inet_address_new_from_string (this->host);
@ -330,6 +339,20 @@ gst_tcp_server_sink_init_send (GstMultiHandleSink * parent)
"listened on server socket %p, returning from connection setup",
this->server_socket);
if (this->server_port == 0) {
saddr = g_socket_get_local_address (this->server_socket, NULL);
bound_port = g_inet_socket_address_get_port ((GInetSocketAddress *) saddr);
g_object_unref (saddr);
} else {
bound_port = this->server_port;
}
GST_DEBUG_OBJECT (this, "listening on port %d", bound_port);
g_atomic_int_set (&this->current_port, bound_port);
g_object_notify (G_OBJECT (this), "current-port");
this->server_source =
g_socket_create_source (this->server_socket,
G_IO_IN | G_IO_OUT | G_IO_PRI | G_IO_ERR | G_IO_HUP,
@ -413,6 +436,9 @@ gst_tcp_server_sink_close (GstMultiHandleSink * parent)
}
g_object_unref (this->server_socket);
this->server_socket = NULL;
g_atomic_int_set (&this->current_port, 0);
g_object_notify (G_OBJECT (this), "current-port");
}
return TRUE;

View file

@ -59,8 +59,10 @@ struct _GstTCPServerSink {
GstMultiSocketSink element;
/* server information */
gint server_port;
gchar *host;
int current_port; /* currently bound-to port, or 0 */ /* ATOMIC */
int server_port; /* port property */
gchar *host; /* host property */
GSocket *server_socket;
GSource *server_source;
};

View file

@ -60,7 +60,8 @@ enum
{
PROP_0,
PROP_HOST,
PROP_PORT
PROP_PORT,
PROP_CURRENT_PORT
};
#define gst_tcp_server_src_parent_class parent_class
@ -104,6 +105,10 @@ gst_tcp_server_src_class_init (GstTCPServerSrcClass * klass)
g_param_spec_int ("port", "Port", "The port to listen to",
0, TCP_HIGHEST_PORT, TCP_DEFAULT_PORT,
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
g_object_class_install_property (gobject_class, PROP_CURRENT_PORT,
g_param_spec_int ("current-port", "current-port",
"The port number the socket is currently bound to", 0,
TCP_HIGHEST_PORT, 0, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
gst_element_class_add_pad_template (gstelement_class,
gst_static_pad_template_get (&srctemplate));
@ -338,6 +343,9 @@ gst_tcp_server_src_get_property (GObject * object, guint prop_id,
case PROP_PORT:
g_value_set_int (value, tcpserversrc->server_port);
break;
case PROP_CURRENT_PORT:
g_value_set_int (value, g_atomic_int_get (&tcpserversrc->current_port));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
@ -353,6 +361,7 @@ gst_tcp_server_src_start (GstBaseSrc * bsrc)
GInetAddress *addr;
GSocketAddress *saddr;
GResolver *resolver;
gint bound_port = 0;
/* look up name if we need to */
addr = g_inet_address_new_from_string (src->host);
@ -407,6 +416,19 @@ gst_tcp_server_src_start (GstBaseSrc * bsrc)
GST_OBJECT_FLAG_SET (src, GST_TCP_SERVER_SRC_OPEN);
if (src->server_port == 0) {
saddr = g_socket_get_local_address (src->server_socket, NULL);
bound_port = g_inet_socket_address_get_port ((GInetSocketAddress *) saddr);
g_object_unref (saddr);
} else {
bound_port = src->server_port;
}
GST_DEBUG_OBJECT (src, "listening on port %d", bound_port);
g_atomic_int_set (&src->current_port, bound_port);
g_object_notify (G_OBJECT (src), "current-port");
return TRUE;
/* ERRORS */
@ -485,6 +507,9 @@ gst_tcp_server_src_stop (GstBaseSrc * bsrc)
}
g_object_unref (src->server_socket);
src->server_socket = NULL;
g_atomic_int_set (&src->current_port, 0);
g_object_notify (G_OBJECT (src), "current-port");
}
GST_OBJECT_FLAG_UNSET (src, GST_TCP_SERVER_SRC_OPEN);

View file

@ -54,8 +54,9 @@ struct _GstTCPServerSrc {
GstPushSrc element;
/* server information */
int server_port;
gchar *host;
int current_port; /* currently bound-to port, or 0 */ /* ATOMIC */
int server_port; /* port property */
gchar *host; /* host property */
GCancellable *cancellable;
GSocket *server_socket;