On Linux (and probably other platforms), VLC media player has been plagued by thread-safety issues. First, the VLC code base was full of race conditions. We put a lot of efforts into fixing most of those issues in VLC 0.9, and kept going since then.
With VLC 1.1, we finally got rid of the Xlib-based rendering in favor of XCB, and also fixed the (still Xlib-based) skin engine. In Ubuntu alone, this should address several tens of bug reports.
Now, I have started looking at our underlying libraries as well...
...and it is not a pretty sight.
I could have used some powerful race conditions analysis tool such as valgrind's helgrind. But instead, I simply looked for a few well-known unsafe function calls. This is actually quite a trivial thing to do. The way link resolution works with the ELF executable file format, I simply needed to define those functions in the main program: in this case, the vlc binary. Using LD_PRELOAD would constitute a more involved but reusable approach. A simpler alternative is to run the program under a debugger and use break points, but it is not so convenient.
This far, I only took a limited set of functions as follows:
fork()
and before exec*()
.
If you need to retain a value process-wide,
global variables (and a mutex) are safer and faster.
<ctype.h>
)
and wide to multi-byte characters conversion functions.
newlocale()
, uselocale()
and freelocale()/
functions.
They are also found in <locale.h>,
except on MacOS/Darwin in <xlocale.h>.
As an example, this can be useful to parse or format floating point numbers
in american format regardless of the user-selected locale.
strerror_r()
must be used instead.
In some cases, perror()
is simpler.
Also note that syslog()
supports a special
specific '%m' that expands to strerror (errno) but is thread-safe.
With GNU/libc, all printf-like functions also support '%m'.
waitpid()
can be used in blocking mode.
In non-blocking mode, in an event loop,
a dedicated thread will need to call waitpid()
.
rand_r()
is the most direct thread-safe substitution,
but POSIX marked it as deprecated.
random()
(and srandom()
),
or nrand48
constiture better alternatives.
erand48()
, nrand48
and jrand48
can be used instead.
_r
getaddrinfo
and getnameinfo
instead.
*: not yet checked in VLC.
There were not many libraries that did not exhibit any obvious problem this far. This does not imply that there are no issues, only that I found none:
And there were quite a bunch of nasty surprises:
N.B.: Those lists are very incomplete.