Reputation: 731
Is there a way I can exit a blocking connect()
call in Windows?
Note that I do not want to switch to non-blocking sockets.
Upvotes: 4
Views: 935
Reputation: 9619
According to MSDN connect page:
Note When issuing a blocking Winsock call such as connect, Winsock may need to wait for a network event before the call can complete. Winsock performs an alertable wait in this situation, which can be interrupted by an asynchronous procedure call (APC) scheduled on the same thread. Issuing another blocking Winsock call inside an APC that interrupted an ongoing blocking Winsock call on the same thread will lead to undefined behavior, and must never be attempted by Winsock clients.
So if you want to cancel connect
call, you must do it from another thread:
/* apc callback */
VOID CALLBACK apc( _In_ ULONG_PTR data)
{
/* warning, some synchronization should be added here*/
printf("connect canceled by APC\n");
}
/* second thread code */
DWORD WINAPI cancel_thread_function(void* main_thread_handle)
{
/* wait 500 ms*/
Sleep(500);
if (test_if_connect_is_still_pending())
{
/* cancel connect */
QueueUserAPC(apc, (HANDLE)main_thread_handle, (ULONG_PTR) NULL);
}
return 0;
}
/* The thread in which is executed the connect call */
HANDLE mainThread;
DuplicateHandle(GetCurrentProcess(), GetCurrentThread(), GetCurrentProcess(), &mainThread, 0, TRUE, DUPLICATE_SAME_ACCESS);
/* create cancelation thread */
CreateThread(NULL, 0, cancel_thread_function, , 0, NULL);
/* Warning: I should close the handles... */
connect(...);
IMO, the EJP solution is the best (non-blocking connect
and test with select
).
Upvotes: 3