This section will assume you understand the basics of multithreading. If not there are plenty of good tutorials available on the net to get you started.
Threading in Wine is somewhat complex due to several factors. The first is the advanced level of multithreading support provided by Windows - there are far more threading related constructs available in Win32 than the Linux equivalent (pthreads). The second is the need to be able to map Win32 threads to native Linux threads which provides us with benefits like having the kernel schedule them without our intervention. While it's possible to implement threading entirely without kernel support, doing so is not desirable on most platforms that Wine runs on.
Win32 is an unusually thread friendly API. Not only is it entirely thread safe, but it provides many different facilities for working with threads. These range from the basics such as starting and stopping threads, to the extremely complex such as injecting threads into other processes and COM inter-thread marshalling.
One of the primary challenges of writing Wine code therefore is ensuring that all our DLLs are thread safe, free of race conditions and so on. This isn't simple - don't be afraid to ask if you aren't sure whether a piece of code is thread safe or not!
Win32 provides many different ways you can make your code thread safe however the most common are critical section and the interlocked functions. Critical sections are a type of mutex designed to protect a geographic area of code. If you don't want multiple threads running in a piece of code at once, you can protect them with calls to EnterCriticalSection and LeaveCriticalSection. The first call to EnterCriticalSection by a thread will lock the section and continue without stopping. If another thread calls it then it will block until the original thread calls LeaveCriticalSection again.
It is therefore vitally important that if you use critical sections to make some code thread-safe, that you check every possible codepath out of the code to ensure that any held sections are left. Code like this:
if (res != ERROR_SUCCESS) return res;
is extremely suspect in a function that also contains a call to EnterCriticalSection. Be careful.
If a thread blocks while waiting for another thread to leave a critical section, you will see an error from the RtlpWaitForCriticalSection function, along with a note of which thread is holding the lock. This only appears after a certain timeout, normally a few seconds. It's possible the thread holding the lock is just being really slow which is why Wine won't terminate the app like a non-checked build of Windows would, but the most common cause is that for some reason a thread forgot to call LeaveCriticalSection, or died while holding the lock (perhaps because it was in turn waiting for another lock). This doesn't just happen in Wine code: a deadlock while waiting for a critical section could be due to a bug in the app triggered by a slight difference in the emulation.
Another popular mechanism available is the use of functions like InterlockedIncrement and InterlockedExchange. These make use of native CPU abilities to execute a single instruction while ensuring any other processors on the system cannot access memory, and allow you to do common operations like add/remove/check a variable in thread-safe code without holding a mutex. These are useful for reference counting especially in free-threaded (thread safe) COM objects.
Finally, the usage of TLS slots are also popular. TLS stands for thread-local storage, and is a set of slots scoped local to a thread which you can store pointers in. Look on MSDN for the TlsAlloc function to learn more about the Win32 implementation of this. Essentially, the contents of a given slot will be different in each thread, so you can use this to store data that is only meaningful in the context of a single thread. On recent versions of Linux the __thread keyword provides a convenient interface to this functionality - a more portable API is exposed in the pthread library. However, these facilities is not used by Wine, rather, we implement Win32 TLS entirely ourselves.