tags:

views:

77

answers:

3

I'm developing an app that has one TCP server and several UDP servers/listeners. Each server is a separate thread, same as the worker threads for established TCP connections. I'm calling WSAStartup() in each of the threads.

Sometimes, calling WSAStartup() hangs (it looks like a deadlock to me). Here is the stack trace:

  ntdll.dll!_KiFastSystemCallRet@0()  
  ntdll.dll!_ZwWaitForSingleObject@12()  + 0xc bytes 
  ntdll.dll!_RtlpWaitForCriticalSection@4()  + 0x8c bytes 
  ntdll.dll!_RtlEnterCriticalSection@4()  + 0x46 bytes 
  ntdll.dll!_LdrpGetProcedureAddress@20()  + 0x17d bytes 
  ntdll.dll!_LdrGetProcedureAddress@16()  + 0x18 bytes 
  kernel32.dll!_GetProcAddress@8()  + 0x3e bytes 
  vld.dll!03203723()  
  [Frames below may be incorrect and/or missing, no symbols loaded for vld.dll] 
  ws2_32.dll!CheckForHookersOrChainers()  + 0x22 bytes 
  ws2_32.dll!_WSAStartup@8()  + 0xa7 bytes 

This deadlock happens during the initialization faze. I see that the TCP server is started and that one TCP connection is established, while only one of UDP servers is started. The stack trace is from the function that should initiate the rest of UDP servers. My guess is that while I'm trying to init UDP sever and calling WSACStartup(), another tread is handling another socket operation, for example a new TCP connection and it's also calling WSAStartup()?

My question is whether calling WSAStartup() from several threads can cause this deadlock? Also I checked is the WSACleanup() called before the deadlock, and it isn't. The execution never reaches any of WSACleanup().

I'm aware that only one call to WSAStartup should be enough, yet calling WSAStartup() several times should not be a problem (MSDN]1): "An application can call WSAStartup more than once if it needs to obtain the WSADATA structure information more than once." Hence, I would like to establish whether this deadlock is caused by WSAStartup() or something else.

+1  A: 

You don't have to call WSAStartup() multiple times at all. Once per program is fine.

Warren Young
Imho, question states clearly that topic starter has read this part of MSDN and instead of solution to "avoid" the problem (which is definitely a good solution) - he is trying to find the root cause.
Andrey
It's like the old joke: "Doctor, it hurts when I do this." "So don't do that, then."
Warren Young
A: 

I think that Luke is right. You cannot call WSAStartup() in DllMain() or in initializers of global/static variables. Change your code so that it does not happen.

wilx
I'm working on a standalone application and I'm using system DLLs, hence I don't have a DLLMain(). All my calls to WSAStartup() are in the thread functions:http://msdn.microsoft.com/en-us/library/ms686736(VS.85).aspx PS. here is the list of additional libraries:- ws2_32.lib - strsafe.lib - shell32.lib
Misko Mare
Take a closer look at the list of DLLs loaded into "release" version of your application (w/o profilers, leak detectors, etc). Chances are that one of those DLLs is trapping windows functions. SysInternals' Process Explorer will help you a lot.
Andrey
A: 

WSAStartup doesn't actually lead to LoadLibrary of any kind, so I don't feel like it is a loader lock case.

Instead, it is obvious that windows API is being trapped in your case (term trap is better here, because hook has other meaning in Windows).

Thus, I believe that the problem is not in concurrent use of WSAStartup, but in side effects of third party traps over original Windows API functions in your process. I think, you need to clean up your environment from any external influence (api traps from your side or from anti-virus software, whatever).

By the way, make sure that each thread of yours provides WSAStartup with its own separate copy of WSADATA output parameter

Andrey