Windows Sockets guarantees synchronization to a WSH DLL on a per-socket basis. That is, two threads cannot be executing concurrently in WSHXxx functions for the same socket. Consequently, a WSH DLL that maintains its state information on a per-socket basis need not do any synchronization on its own.
If a WSH DLL maintains global state or per-process state, it must synchronize access to such state information internally. Windows NT provides several user-mode synchronization mechanisms such a WSH DLL might use, including semaphores, events, and critical sections. Which type of synchronization mechanism to use is up to the WSH DLL developer.