On Tue,  6 Oct 2015 12:41:13 +0200
Hendrik Leppkes <[email protected]> wrote:

> The emulation uses native InitOnce* APIs on Windows Vista+, and a
> lock-free/allocation-free approach using atomics and spinning for Windows XP.
> ---
> This is in preparation to use pthread_once for global static init functions,
> and eventually removing the global lock in avcodec_open2
> 
> compat/w32pthreads.h | 68 ++++++++++++++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 68 insertions(+)

Somewhat related to this patch, we were discussing ways to deal with
w32thread_init().

Personally, I think we should not have to litter the code with
w32thread_init() calls. Nor should the user somehow have to make
sure that this function is somehow called implicitly, when calling
API functions which use threads.

There are a few ways to handle this:

1. Don't handle it, but put it e.g. in avcodec_register_all(), and hope
   the user calls it before calling other APIs which might require it.
2. Call it from DllMain() only. This breaks static linking, or requires
   special care if an application uses a statically linked libav.
3. Make w32thread_init() thread-safe, and call it from all entrypoints
   that need it, like pthread_cond_init() and pthread_once().

Choice 1. is pretty simple, but I think avcodec_register_all() should
eventually go away. And a lib should not require a global init function
in general. And there might be API in other sub-libs which require this
function to be called. It's also hard to guarantee that the API user
calls it in a safe way when no concurrent calls are possible. I think
this solution sucks. It's fragile and error-prone.

Using a DllMain() is probably most elegant. It still needs to be put in
all the sub-libs. It breaks static linking, but nev says static linking
on Windows is insanity. Maybe that's true, but personally I think it's
not a good idea to silently break static linking. (Assuming it works
currently.)

Choice 3. is my favorite. It could work like the XP-compatibility path
in pthread_once(). (In fact, pthread_once() can be reused for this
purpose.) Spinning is not a huge problem, because the protected code
only runs a bunch of GetProcAddress() call, and likely finishes very
quickly. Performance won't be affected much - it's only an additional
atomic operation in relatively rare calls like pthread_cond_init()
(pthread_once() will have to be avoided in performance-critical code
paths). This code would run on modern Windows releases too, but could
be disabled completely if compiling for Vista+ targets.

Which way should we go? Suggestions and discussion welcome.
_______________________________________________
libav-devel mailing list
[email protected]
https://lists.libav.org/mailman/listinfo/libav-devel

Reply via email to