From: Wim Taymans Date: Mon, 19 Jan 2009 18:36:23 +0000 (+0100) Subject: Make more properties configurable in the server. X-Git-Tag: 1.19.3~495^2~1626 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=491b20bedd6f7989a29830d09c7906164e58483c;p=platform%2Fupstream%2Fgstreamer.git Make more properties configurable in the server. Expose the GIOChannel and GSource better to allow for more customisations. --- diff --git a/gst/rtsp-server/rtsp-server.c b/gst/rtsp-server/rtsp-server.c index 1c6d3ea..ad1fdc7 100644 --- a/gst/rtsp-server/rtsp-server.c +++ b/gst/rtsp-server/rtsp-server.c @@ -22,12 +22,16 @@ #include "rtsp-server.h" #include "rtsp-client.h" -#define TCP_BACKLOG 5 +#define DEFAULT_BACKLOG 5 #define DEFAULT_PORT 1554 + enum { - ARG_0, - PROP_PORT + PROP_0, + PROP_BACKLOG, + PROP_PORT, + PROP_POOL, + PROP_LAST }; G_DEFINE_TYPE (GstRTSPServer, gst_rtsp_server, G_TYPE_OBJECT); @@ -47,16 +51,45 @@ gst_rtsp_server_class_init (GstRTSPServerClass * klass) gobject_class->get_property = gst_rtsp_server_get_property; gobject_class->set_property = gst_rtsp_server_set_property; + /** + * GstRTSPServer::backlog + * + * The backlog argument defines the maximum length to which the queue of + * pending connections for the server may grow. If a connection request arrives + * when the queue is full, the client may receive an error with an indication of + * ECONNREFUSED or, if the underlying protocol supports retransmission, the + * request may be ignored so that a later reattempt at connection succeeds. + */ + g_object_class_install_property (gobject_class, PROP_BACKLOG, + g_param_spec_int ("backlog", "Backlog", "The maximum length to which the queue " + "of pending connections may grow", + 0, G_MAXINT, DEFAULT_BACKLOG, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + /** + * GstRTSPServer::port + * + * The session port of the server. This is the port where the server will + * listen on. + */ g_object_class_install_property (gobject_class, PROP_PORT, - g_param_spec_int ("port", "Port", "The port the server uses", - 1, 65535, DEFAULT_PORT, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + g_param_spec_int ("port", "Port", "The port the server uses to listen on", + 1, 65535, DEFAULT_PORT, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + /** + * GstRTSPServer::pool + * + * The session pool of the server. By default each server has a separate + * session pool but sessions can be shared between servers by setting the same + * session pool on multiple servers. + */ + g_object_class_install_property (gobject_class, PROP_POOL, + g_param_spec_object ("pool", "Pool", "The session pool to use for client session", + GST_TYPE_RTSP_SESSION_POOL, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); } static void gst_rtsp_server_init (GstRTSPServer * server) { server->server_port = DEFAULT_PORT; + server->backlog = DEFAULT_BACKLOG; server->pool = gst_rtsp_session_pool_new (); } @@ -75,6 +108,117 @@ gst_rtsp_server_new (void) return result; } +/** + * gst_rtsp_server_set_port: + * @server: a #GstRTSPServer + * @port: the port + * + * Configure @server to accept connections on the given port. + * @port should be a port number between 1 and 65535. + * + * This function must be called before the server is bound. + */ +void +gst_rtsp_server_set_port (GstRTSPServer *server, gint port) +{ + g_return_if_fail (GST_IS_RTSP_SERVER (server)); + g_return_if_fail (port >= 1 && port <= 65535); + + server->server_port = port; +} + +/** + * gst_rtsp_server_get_port: + * @server: a #GstRTSPServer + * + * Get the port number on which the server will accept connections. + * + * Returns: the server port. + */ +gint +gst_rtsp_server_get_port (GstRTSPServer *server) +{ + g_return_val_if_fail (GST_IS_RTSP_SERVER (server), -1); + + return server->server_port; +} + +/** + * gst_rtsp_server_set_backlog: + * @server: a #GstRTSPServer + * @backlog: the backlog + * + * configure the maximum amount of requests that may be queued for the + * server. + * + * This function must be called before the server is bound. + */ +void +gst_rtsp_server_set_backlog (GstRTSPServer *server, gint backlog) +{ + g_return_if_fail (GST_IS_RTSP_SERVER (server)); + + server->backlog = backlog; +} + +/** + * gst_rtsp_server_get_backlog: + * @server: a #GstRTSPServer + * + * The maximum amount of queued requests for the server. + * + * Returns: the server backlog. + */ +gint +gst_rtsp_server_get_backlog (GstRTSPServer *server) +{ + g_return_val_if_fail (GST_IS_RTSP_SERVER (server), -1); + + return server->backlog; +} + +/** + * gst_rtsp_server_set_session_pool: + * @server: a #GstRTSPServer + * @pool: a #GstRTSPSessionPool + * + * configure @pool to be used as the session pool of @server. + */ +void +gst_rtsp_server_set_session_pool (GstRTSPServer *server, GstRTSPSessionPool *pool) +{ + g_return_if_fail (GST_IS_RTSP_SERVER (server)); + + if (server->pool) + g_object_unref (server->pool); + if (pool) + pool = g_object_ref (pool); + server->pool = pool; +} + + +/** + * gst_rtsp_server_get_session_pool: + * @server: a #GstRTSPServer + * + * Get the #GstRTSPSessionPool used as the session pool of @server. + * + * Returns: the #GstRTSPSessionPool used for sessions. g_object_unref() after + * usage. + */ +GstRTSPSessionPool * +gst_rtsp_server_get_session_pool (GstRTSPServer *server) +{ + GstRTSPSessionPool *result; + + g_return_val_if_fail (GST_IS_RTSP_SERVER (server), NULL); + + if ((result = server->pool)) + g_object_ref (result); + + return result; +} + static void gst_rtsp_server_get_property (GObject *object, guint propid, GValue *value, GParamSpec *pspec) @@ -83,7 +227,13 @@ gst_rtsp_server_get_property (GObject *object, guint propid, switch (propid) { case PROP_PORT: - g_value_set_int (value, server->server_port); + g_value_set_int (value, gst_rtsp_server_get_port (server)); + break; + case PROP_BACKLOG: + g_value_set_int (value, gst_rtsp_server_get_backlog (server)); + break; + case PROP_POOL: + g_value_take_object (value, gst_rtsp_server_get_session_pool (server)); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, propid, pspec); @@ -98,13 +248,20 @@ gst_rtsp_server_set_property (GObject *object, guint propid, switch (propid) { case PROP_PORT: - server->server_port = g_value_get_int (value); + gst_rtsp_server_set_port (server, g_value_get_int (value)); + break; + case PROP_BACKLOG: + gst_rtsp_server_set_backlog (server, g_value_get_int (value)); + break; + case PROP_POOL: + gst_rtsp_server_set_session_pool (server, g_value_get_object (value)); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, propid, pspec); } } +/* Prepare a server socket for @server and make it listen on the configured port */ static gboolean gst_rtsp_server_sink_init_send (GstRTSPServer * server) { @@ -146,8 +303,8 @@ gst_rtsp_server_sink_init_send (GstRTSPServer * server) fcntl (server->server_sock.fd, F_SETFL, O_NONBLOCK); GST_DEBUG_OBJECT (server, "listening on server socket %d with queue of %d", - server->server_sock.fd, TCP_BACKLOG); - if (listen (server->server_sock.fd, TCP_BACKLOG) == -1) + server->server_sock.fd, server->backlog); + if (listen (server->server_sock.fd, server->backlog) == -1) goto listen_failed; GST_DEBUG_OBJECT (server, @@ -200,13 +357,22 @@ bind_failed: } } -/* called when an event is available on our server socket */ -static gboolean -server_dispatch (GIOChannel *source, GIOCondition condition, GstRTSPServer *server) +/** + * gst_rtsp_server_io_func: + * @channel: a #GIOChannel + * @condition: the condition on @source + * + * A default #GIOFunc that creates a new #GstRTSPClient to accept and handle a + * new connection on @channel or @server. + * + * Returns: TRUE if the source could be connected, FALSE if an error occured. + */ +gboolean +gst_rtsp_server_io_func (GIOChannel *channel, GIOCondition condition, GstRTSPServer *server) { - if (condition & G_IO_IN) { - GstRTSPClient *client; + GstRTSPClient *client; + if (condition & G_IO_IN) { /* a new client connected, create a session to handle the client. */ client = gst_rtsp_client_new (); @@ -216,7 +382,7 @@ server_dispatch (GIOChannel *source, GIOCondition condition, GstRTSPServer *serv /* accept connections for that client, this function returns after accepting * the connection and will run the remainder of the communication with the * client asyncronously. */ - if (!gst_rtsp_client_accept (client, source)) + if (!gst_rtsp_client_accept (client, channel)) goto accept_failed; /* can unref the client now, when the request is finished, it will be @@ -233,11 +399,76 @@ accept_failed: { g_error ("Could not accept client on server socket %d: %s (%d)", server->server_sock.fd, g_strerror (errno), errno); + gst_object_unref (client); return FALSE; } } /** + * gst_rtsp_server_get_io_channel: + * @server: a #GstRTSPServer + * + * Create a #GIOChannel for @server. + * + * Returns: the GIOChannel for @server or NULL when an error occured. + */ +GIOChannel * +gst_rtsp_server_get_io_channel (GstRTSPServer *server) +{ + g_return_val_if_fail (GST_IS_RTSP_SERVER (server), NULL); + + if (server->io_channel == NULL) { + if (!gst_rtsp_server_sink_init_send (server)) + goto init_failed; + + /* create IO channel for the socket */ + server->io_channel = g_io_channel_unix_new (server->server_sock.fd); + } + return server->io_channel; + +init_failed: + { + return NULL; + } +} + +/** + * gst_rtsp_server_create_watch: + * @server: a #GstRTSPServer + * + * Create a #GSource for @server. The new source will have a default + * #GIOFunc of gst_rtsp_server_io_func(). + * + * Returns: the #GSource for @server or NULL when an error occured. + */ +GSource * +gst_rtsp_server_create_watch (GstRTSPServer *server) +{ + g_return_val_if_fail (GST_IS_RTSP_SERVER (server), NULL); + + if (server->io_watch == NULL) { + GIOChannel *channel; + + channel = gst_rtsp_server_get_io_channel (server); + if (channel == NULL) + goto no_channel; + + /* create a watch for reads (new connections) and possible errors */ + server->io_watch = g_io_create_watch (channel, G_IO_IN | + G_IO_ERR | G_IO_HUP | G_IO_NVAL); + + /* configure the callback */ + g_source_set_callback (server->io_watch, (GSourceFunc) gst_rtsp_server_io_func, server, NULL); + } + return server->io_watch; + +no_channel: + { + return NULL; + } +} + +/** * gst_rtsp_server_attach: * @server: a #GstRTSPServer * @context: a #GMainContext @@ -254,26 +485,20 @@ guint gst_rtsp_server_attach (GstRTSPServer *server, GMainContext *context) { guint res; + GSource *source; - if (!gst_rtsp_server_sink_init_send (server)) - goto init_failed; - - /* create IO channel for the socket */ - server->io_channel = g_io_channel_unix_new (server->server_sock.fd); + g_return_val_if_fail (GST_IS_RTSP_SERVER (server), 0); - /* create a watch for reads (new connections) and possible errors */ - server->io_watch = g_io_create_watch (server->io_channel, G_IO_IN | - G_IO_ERR | G_IO_HUP | G_IO_NVAL); - - /* configure the callback */ - g_source_set_callback (server->io_watch, (GSourceFunc) server_dispatch, server, NULL); + source = gst_rtsp_server_create_watch (server); + if (source == NULL) + goto no_source; - res = g_source_attach (server->io_watch, context); + res = g_source_attach (source, context); return res; /* ERRORS */ -init_failed: +no_source: { return 0; } diff --git a/gst/rtsp-server/rtsp-server.h b/gst/rtsp-server/rtsp-server.h index 93bc820..d23bdd0 100644 --- a/gst/rtsp-server/rtsp-server.h +++ b/gst/rtsp-server/rtsp-server.h @@ -56,7 +56,8 @@ struct _GstRTSPServer { GObject parent; /* server information */ - int server_port; + gint server_port; + gint backlog; gchar *host; struct sockaddr_in server_sin; @@ -74,12 +75,26 @@ struct _GstRTSPServerClass { GObjectClass parent_class; }; -GType gst_rtsp_server_get_type (void); +GType gst_rtsp_server_get_type (void); -GstRTSPServer * gst_rtsp_server_new (void); +GstRTSPServer * gst_rtsp_server_new (void); -guint gst_rtsp_server_attach (GstRTSPServer *server, - GMainContext *context); +void gst_rtsp_server_set_port (GstRTSPServer *server, gint port); +gint gst_rtsp_server_get_port (GstRTSPServer *server); + +void gst_rtsp_server_set_backlog (GstRTSPServer *server, gint backlog); +gint gst_rtsp_server_get_backlog (GstRTSPServer *server); + +void gst_rtsp_server_set_session_pool (GstRTSPServer *server, GstRTSPSessionPool *pool); +GstRTSPSessionPool * gst_rtsp_server_get_session_pool (GstRTSPServer *server); + +gboolean gst_rtsp_server_io_func (GIOChannel *channel, GIOCondition condition, + GstRTSPServer *server); + +GIOChannel * gst_rtsp_server_get_io_channel (GstRTSPServer *server); +GSource * gst_rtsp_server_create_watch (GstRTSPServer *server); +guint gst_rtsp_server_attach (GstRTSPServer *server, + GMainContext *context); G_END_DECLS