Help with WINE and POSIX threading
efrias at syncad.com
Thu Oct 27 13:40:49 CDT 2005
Marcus Meissner wrote:
> On Wed, Oct 26, 2005 at 11:01:51AM -0700, ssawai wrote:
>>On several places we use third-party components that use native pthreads
>>from which we receive callbacks in different pthreads.
>>Is it possible to use Wine/pthread mix? What would be the preferred way
>>of doing things?
It's possible, and for us it worked pretty well. Our winelib
application links against several native unix DLLs which create their
own threads with the pthreads APIs. My knowledge is based on the state
of wine about a year ago, so this stuff could have changed. I'm
definitely not an expert on this stuff, but I've seen a lot of the
threading code when trying to debug my own code.
Wine has two threading models on linux, the old kernel threads and the
newer pthread interface. In the pthread model, windows threads
and threading primitives are built on top of their pthread counterparts.
In the kthread model, the pthread functions are built on top of wine's
own implementation, which is built on top of clone.
I don't think we ever had problems with one native library using
pthreads inside itself, or in combination with another native shared
library. The tricky bit is allowing threads that aren't created by wine
to call Windows API functions. Most of the Windows API functions rely
on being able to get the Thread Environment Block for the current
thread, and that's a windows-specific thing that won't exist if you just
create the thread with a call to the native pthread_create function.
In the wine-kthread model (which I'm more familiar with), wine overrides
most (all?) of the native pthreads functions, causing calls to
pthread_mutex_init(), for example, to internally create a
CriticalSection object. pthread_create() is also one of the functions
that is overridden, and in that wine calls clone() to make the new
thread, then creates a TEB for new thread before handing control off
back to your native shared library. If you use a lot of the
less-often-used parts of the pthread library, you might run into
limitations in wine's emulation of the pthread functions.
On other platforms where the wine-kthread model isn't supported
(Solaris, HP-UX, and possibly newer linux systems where wine-pthread is
chosen?), this wouldn't work. On those systems, the pthread_create
function goes directly to the system's pthread library, so wine doesn't
have a chance to intercept it and create a TEB. To get around this, our
main thread creates a helper thread that is wine-aware via CreateThread.
This helper thread creates a pthread mutex/condition variable pair and
uses the pthread functions to listen for requests from any threads
created in native shared libraries. When it gets a request, it executes
the windows API calls in its own wine-aware thread and then returns
control to the calling native thread. It's a bit cumbersome, but there
are not many places we need to make windows calls from native threads;
usually it's just a call to PostMessage to notify the GUI that something
>>On many places we use dynamic library loading (LoadLibrary() on Win32).
>>Possibly we will need to load native libraries also. Is it possible to
>>load shared libraries (.so) linked with Wine, with native dlopen(),
>>since we don't need the Win32 DllMain mechanism. What would be the
>>preferred/best way of doing things?
Using dlopen to load native shared libraries into a winelib application
has always worked fine for me. If you're loading shared libraries that
are linked with wine (winelib .dll.so) I think you must use LoadLibrary
to do it. I think there was a time when you could dlopen a .dll.so
directly, but I believe it stopped working a year or two ago, but I
can't think of any good reason not to use LoadLibrary for those cases.
More information about the wine-devel