[vlc-commits] cli: (de)allocate client dynamically
Rémi Denis-Courmont
git at videolan.org
Sun Nov 29 14:55:59 CET 2020
vlc | branch: master | Rémi Denis-Courmont <remi at remlab.net> | Sun Nov 29 12:18:27 2020 +0200| [ccf0ba539b3f1ea7e1e2735edd73fe0003abfdff] | committer: Rémi Denis-Courmont
cli: (de)allocate client dynamically
> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=ccf0ba539b3f1ea7e1e2735edd73fe0003abfdff
---
modules/control/cli/cli.c | 102 +++++++++++++++++++++++++++++++++-------------
1 file changed, 74 insertions(+), 28 deletions(-)
diff --git a/modules/control/cli/cli.c b/modules/control/cli/cli.c
index f2c4a982c3..6ed8df0ce3 100644
--- a/modules/control/cli/cli.c
+++ b/modules/control/cli/cli.c
@@ -72,7 +72,6 @@ struct intf_sys_t
#ifndef _WIN32
vlc_mutex_t clients_lock;
struct vlc_list clients;
- struct cli_client client;
char *psz_unix_path;
#else
HANDLE hConsoleIn;
@@ -446,6 +445,57 @@ static void *cli_client_thread(void *data)
return NULL;
}
+static struct cli_client *cli_client_new(intf_thread_t *intf, int fd,
+ FILE *stream)
+{
+ struct cli_client *cl = malloc(sizeof (*cl));
+ if (unlikely(cl == NULL))
+ return NULL;
+
+ cl->stream = stream;
+ cl->fd = fd;
+ cl->intf = intf;
+ vlc_mutex_init(&cl->output_lock);
+ return cl;
+}
+
+/**
+ * Creates a client from a file descriptor.
+ *
+ * This works with (pseudo-)terminals, stream sockets, serial ports, etc.
+ */
+static struct cli_client *cli_client_new_fd(intf_thread_t *intf, int fd)
+{
+ fcntl(fd, F_SETFL, fcntl(fd, F_GETFL) & ~O_NONBLOCK);
+
+ FILE *stream = fdopen(fd, "r");
+ if (stream == NULL)
+ {
+ vlc_close(fd);
+ return NULL;
+ }
+
+ struct cli_client *cl = cli_client_new(intf, fd, stream);
+ if (unlikely(cl == NULL))
+ fclose(stream);
+ return cl;
+}
+
+/**
+ * Creates a client from the standard input and output.
+ */
+static struct cli_client *cli_client_new_std(intf_thread_t *intf)
+{
+ return cli_client_new(intf, 1, stdin);
+}
+
+static void cli_client_delete(struct cli_client *cl)
+{
+ if (cl->stream != stdin)
+ fclose(cl->stream);
+ free(cl);
+}
+
static void *Run(void *data)
{
intf_thread_t *intf = data;
@@ -453,8 +503,6 @@ static void *Run(void *data)
for (;;)
{
- struct cli_client *cl = &sys->client;
-
while (vlc_list_is_empty(&sys->clients))
{
assert(sys->pi_socket_listen != NULL);
@@ -464,27 +512,26 @@ static void *Run(void *data)
continue;
int canc = vlc_savecancel();
+ struct cli_client *cl = cli_client_new_fd(intf, fd);
+ vlc_restorecancel(canc);
- fcntl(fd, F_SETFL, fcntl(fd, F_GETFL) & ~O_NONBLOCK);
- cl->stream = fdopen(fd, "r");
- if (cl->stream != NULL)
+ if (cl != NULL)
{
- cl->fd = fd;
- cl->intf = intf;
- vlc_mutex_init(&cl->output_lock);
vlc_mutex_lock(&sys->clients_lock);
vlc_list_append(&cl->node, &sys->clients);
vlc_mutex_unlock(&sys->clients_lock);
}
- else
- vlc_close(fd);
- vlc_restorecancel(canc);
}
+ struct cli_client *cl = vlc_list_first_entry_or_null(&sys->clients,
+ struct cli_client,
+ node);
+
cli_client_thread(cl);
vlc_mutex_lock(&sys->clients_lock);
vlc_list_remove(&cl->node);
vlc_mutex_unlock(&sys->clients_lock);
+ cli_client_delete(cl);
if (sys->pi_socket_listen == NULL)
break;
@@ -738,6 +785,7 @@ static void *Run( void *data )
static int Activate( vlc_object_t *p_this )
{
intf_thread_t *p_intf = (intf_thread_t*)p_this;
+ struct cli_client *cl;
char *psz_host, *psz_unix_path = NULL;
int *pi_socket = NULL;
@@ -896,21 +944,13 @@ static int Activate( vlc_object_t *p_this )
RegisterPlaylist(p_intf);
#ifndef _WIN32
- struct cli_client *cl = &p_sys->client;
-
if (pi_socket == NULL)
{
- cl->stream = stdin;
- cl->fd = 1;
- cl->intf = p_intf;
- vlc_mutex_init(&cl->output_lock);
+ cl = cli_client_new_std(p_intf);
+ if (cl == NULL)
+ goto error;
vlc_list_append(&cl->node, &p_sys->clients);
}
- else
- {
- cl->stream = NULL;
- cl->fd = -1;
- }
#endif
if( vlc_clone( &p_sys->thread, Run, p_intf, VLC_THREAD_PRIORITY_LOW ) )
@@ -924,6 +964,10 @@ static int Activate( vlc_object_t *p_this )
error:
if (p_sys->player_cli != NULL)
DeregisterPlayer(p_intf, p_sys->player_cli);
+#ifndef _WIN32
+ vlc_list_foreach (cl, &p_sys->clients, node)
+ cli_client_delete(cl);
+#endif
tdestroy(p_sys->commands, free);
net_ListenClose( pi_socket );
free( psz_unix_path );
@@ -941,18 +985,20 @@ static void Deactivate( vlc_object_t *p_this )
vlc_cancel( p_sys->thread );
vlc_join( p_sys->thread, NULL );
-
DeregisterPlayer(p_intf, p_sys->player_cli);
+
+#ifndef _WIN32
+ struct cli_client *cl;
+
+ vlc_list_foreach (cl, &p_sys->clients, node)
+ cli_client_delete(cl);
+#endif
tdestroy(p_sys->commands, free);
if (p_sys->pi_socket_listen != NULL)
{
net_ListenClose(p_sys->pi_socket_listen);
#ifndef _WIN32
- struct cli_client *cl = &p_sys->client;
-
- if (cl->stream != NULL)
- fclose(cl->stream);
if (p_sys->psz_unix_path != NULL)
{
unlink(p_sys->psz_unix_path);
More information about the vlc-commits
mailing list