[vlc-commits] rc: add lock for output (fixes #25200)
Rémi Denis-Courmont
git at videolan.org
Sun Oct 18 20:26:05 CEST 2020
vlc | branch: master | Rémi Denis-Courmont <remi at remlab.net> | Sun Oct 18 21:19:59 2020 +0300| [47f1b7b645076b495deacbab76392d2ba2fec3ca] | committer: Rémi Denis-Courmont
rc: add lock for output (fixes #25200)
This fixes the (mostly harmless but nevertheless undefined behaviour)
data race on the output file descriptor.
> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=47f1b7b645076b495deacbab76392d2ba2fec3ca
---
modules/control/cli/cli.c | 33 ++++++++++++++++++++++++---------
modules/control/cli/cli.h | 1 +
2 files changed, 25 insertions(+), 9 deletions(-)
diff --git a/modules/control/cli/cli.c b/modules/control/cli/cli.c
index ed7df6b83f..5ec2d4d359 100644
--- a/modules/control/cli/cli.c
+++ b/modules/control/cli/cli.c
@@ -69,17 +69,25 @@ static void msg_vprint(intf_thread_t *p_intf, const char *psz_fmt, va_list args)
{
#ifndef _WIN32
intf_sys_t *sys = p_intf->p_sys;
- char fmt_eol[strlen (psz_fmt) + 3], *msg;
- int len;
+ int fd;
- snprintf (fmt_eol, sizeof (fmt_eol), "%s\r\n", psz_fmt);
- len = vasprintf( &msg, fmt_eol, args );
+ vlc_mutex_lock(&sys->output_lock);
+ fd = sys->fd;
+ if (fd != -1)
+ {
+ char fmt_eol[strlen (psz_fmt) + 3], *msg;
+ int len;
- if( len < 0 )
- return;
+ snprintf(fmt_eol, sizeof (fmt_eol), "%s\r\n", psz_fmt);
+ len = vasprintf(&msg, fmt_eol, args);
- vlc_write(sys->fd, msg, len);
- free( msg );
+ if (len < 0)
+ return;
+
+ vlc_write(sys->fd, msg, len);
+ free(msg);
+ }
+ vlc_mutex_unlock(&sys->output_lock);
#else
char fmt_eol[strlen (psz_fmt) + 3], *msg;
int len;
@@ -221,9 +229,11 @@ static void LogOut(intf_thread_t *intf, const char *const *args, size_t count)
#ifndef _WIN32
if (sys->pi_socket_listen != NULL)
{
+ vlc_mutex_lock(&sys->output_lock);
+ sys->fd = -1;
+ vlc_mutex_unlock(&sys->output_lock);
fclose(sys->stream);
sys->stream = NULL;
- sys->fd = -1;
}
else
{ /* Force end-of-file on the standard input. */
@@ -363,7 +373,11 @@ static void *Run(void *data)
fcntl(fd, F_SETFL, fcntl(fd, F_GETFL) & ~O_NONBLOCK);
sys->stream = fdopen(fd, "r");
if (sys->stream != NULL)
+ {
+ vlc_mutex_lock(&sys->output_lock);
sys->fd = fd;
+ vlc_mutex_unlock(&sys->output_lock);
+ }
else
vlc_close(fd);
vlc_restorecancel(canc);
@@ -721,6 +735,7 @@ static int Activate( vlc_object_t *p_this )
p_intf->p_sys = p_sys;
p_sys->commands = NULL;
+ vlc_mutex_init(&p_sys->output_lock);
p_sys->pi_socket_listen = pi_socket;
p_sys->playlist = vlc_intf_GetMainPlaylist(p_intf);;
diff --git a/modules/control/cli/cli.h b/modules/control/cli/cli.h
index 7eaedafd87..ae2dedc5c1 100644
--- a/modules/control/cli/cli.h
+++ b/modules/control/cli/cli.h
@@ -34,6 +34,7 @@ struct intf_sys_t
/* playlist */
vlc_playlist_t *playlist;
+ vlc_mutex_t output_lock;
#ifndef _WIN32
FILE *stream;
int fd;
More information about the vlc-commits
mailing list