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_0,
PROP_HOST, PROP_HOST,
PROP_PORT, PROP_PORT,
PROP_CURRENT_PORT
}; };
static void gst_tcp_server_sink_finalize (GObject * gobject); 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", g_param_spec_int ("port", "port", "The port to send the packets to",
0, TCP_HIGHEST_PORT, TCP_DEFAULT_PORT, 0, TCP_HIGHEST_PORT, TCP_DEFAULT_PORT,
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); 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, gst_element_class_set_static_metadata (gstelement_class,
"TCP server sink", "Sink/Network", "TCP server sink", "Sink/Network",
@ -256,6 +261,9 @@ gst_tcp_server_sink_get_property (GObject * object, guint prop_id,
case PROP_PORT: case PROP_PORT:
g_value_set_int (value, sink->server_port); g_value_set_int (value, sink->server_port);
break; break;
case PROP_CURRENT_PORT:
g_value_set_int (value, g_atomic_int_get (&sink->current_port));
break;
default: default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break; break;
@ -272,6 +280,7 @@ gst_tcp_server_sink_init_send (GstMultiHandleSink * parent)
GInetAddress *addr; GInetAddress *addr;
GSocketAddress *saddr; GSocketAddress *saddr;
GResolver *resolver; GResolver *resolver;
gint bound_port;
/* look up name if we need to */ /* look up name if we need to */
addr = g_inet_address_new_from_string (this->host); 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", "listened on server socket %p, returning from connection setup",
this->server_socket); 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 = this->server_source =
g_socket_create_source (this->server_socket, g_socket_create_source (this->server_socket,
G_IO_IN | G_IO_OUT | G_IO_PRI | G_IO_ERR | G_IO_HUP, 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); g_object_unref (this->server_socket);
this->server_socket = NULL; this->server_socket = NULL;
g_atomic_int_set (&this->current_port, 0);
g_object_notify (G_OBJECT (this), "current-port");
} }
return TRUE; return TRUE;

View File

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

View File

@ -60,7 +60,8 @@ enum
{ {
PROP_0, PROP_0,
PROP_HOST, PROP_HOST,
PROP_PORT PROP_PORT,
PROP_CURRENT_PORT
}; };
#define gst_tcp_server_src_parent_class parent_class #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", g_param_spec_int ("port", "Port", "The port to listen to",
0, TCP_HIGHEST_PORT, TCP_DEFAULT_PORT, 0, TCP_HIGHEST_PORT, TCP_DEFAULT_PORT,
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); 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_element_class_add_pad_template (gstelement_class,
gst_static_pad_template_get (&srctemplate)); gst_static_pad_template_get (&srctemplate));
@ -338,6 +343,9 @@ gst_tcp_server_src_get_property (GObject * object, guint prop_id,
case PROP_PORT: case PROP_PORT:
g_value_set_int (value, tcpserversrc->server_port); g_value_set_int (value, tcpserversrc->server_port);
break; break;
case PROP_CURRENT_PORT:
g_value_set_int (value, g_atomic_int_get (&tcpserversrc->current_port));
break;
default: default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break; break;
@ -353,6 +361,7 @@ gst_tcp_server_src_start (GstBaseSrc * bsrc)
GInetAddress *addr; GInetAddress *addr;
GSocketAddress *saddr; GSocketAddress *saddr;
GResolver *resolver; GResolver *resolver;
gint bound_port = 0;
/* look up name if we need to */ /* look up name if we need to */
addr = g_inet_address_new_from_string (src->host); 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); 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; return TRUE;
/* ERRORS */ /* ERRORS */
@ -485,6 +507,9 @@ gst_tcp_server_src_stop (GstBaseSrc * bsrc)
} }
g_object_unref (src->server_socket); g_object_unref (src->server_socket);
src->server_socket = NULL; 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); GST_OBJECT_FLAG_UNSET (src, GST_TCP_SERVER_SRC_OPEN);

View File

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