in win32/src/async_socket_win32.c [337:411]
int async_socket_open_async(ASYNC_SOCKET_HANDLE async_socket, SOCKET_HANDLE socket_handle, ON_ASYNC_SOCKET_OPEN_COMPLETE on_open_complete, void* on_open_complete_context)
{
int result;
/* Codes_SRS_ASYNC_SOCKET_WIN32_01_009: [ on_open_complete_context shall be allowed to be NULL. ]*/
if (
/* Codes_SRS_ASYNC_SOCKET_WIN32_01_007: [ If async_socket is NULL, async_socket_open_async shall fail and return a non-zero value. ]*/
(async_socket == NULL) ||
/* Codes_SRS_ASYNC_SOCKET_WIN32_01_008: [ If on_open_complete is NULL, async_socket_open_async shall fail and return a non-zero value. ]*/
(on_open_complete == NULL) ||
/* Codes_SRS_ASYNC_SOCKET_WIN32_01_034: [ If socket_handle is INVALID_SOCKET, async_socket_create shall fail and return NULL. ]*/
(SOCKET)socket_handle == INVALID_SOCKET
)
{
/* Codes_SRS_ASYNC_SOCKET_WIN32_01_039: [ If any error occurs, async_socket_open_async shall fail and return a non-zero value. ]*/
LogError("ASYNC_SOCKET_HANDLE async_socket=%p, ON_ASYNC_SOCKET_OPEN_COMPLETE on_open_complete=%p, void* on_open_complete_context=%p",
async_socket, on_open_complete, on_open_complete_context);
result = MU_FAILURE;
}
else
{
/* Codes_SRS_ASYNC_SOCKET_WIN32_01_023: [ Otherwise, async_socket_open_async shall switch the state to OPENING. ]*/
LONG current_state = InterlockedCompareExchange(&async_socket->state, (LONG)ASYNC_SOCKET_WIN32_STATE_OPENING, (LONG)ASYNC_SOCKET_WIN32_STATE_CLOSED);
if (current_state != (LONG)ASYNC_SOCKET_WIN32_STATE_CLOSED)
{
/* Codes_SRS_ASYNC_SOCKET_WIN32_01_015: [ If async_socket is already OPEN or OPENING, async_socket_open_async shall fail and return a non-zero value. ]*/
LogError("Open called in state %" PRI_MU_ENUM "", MU_ENUM_VALUE(ASYNC_SOCKET_WIN32_STATE, current_state));
result = MU_FAILURE;
}
else
{
async_socket->socket_handle = socket_handle;
/* Codes_SRS_ASYNC_SOCKET_WIN32_01_016: [ Otherwise async_socket_open_async shall initialize a thread pool environment by calling InitializeThreadpoolEnvironment. ]*/
InitializeThreadpoolEnvironment(&async_socket->tp_environment);
/* Codes_SRS_ASYNC_SOCKET_WIN32_01_036: [ async_socket_open_async shall set the thread pool for the environment to the pool obtained from the execution engine by calling SetThreadpoolCallbackPool. ]*/
SetThreadpoolCallbackPool(&async_socket->tp_environment, async_socket->pool);
/* Codes_SRS_ASYNC_SOCKET_WIN32_01_058: [ async_socket_open_async shall create a threadpool IO by calling CreateThreadpoolIo and passing socket_handle, the callback environment to it and on_io_complete as callback. ]*/
async_socket->tp_io = CreateThreadpoolIo(async_socket->socket_handle, on_io_complete, NULL, &async_socket->tp_environment);
if (async_socket->tp_io == NULL)
{
/* Codes_SRS_ASYNC_SOCKET_WIN32_01_039: [ If any error occurs, async_socket_open_async shall fail and return a non-zero value. ]*/
LogLastError("CreateThreadpoolIo failed");
result = MU_FAILURE;
}
else
{
/* Codes_SRS_ASYNC_SOCKET_WIN32_01_094: [ async_socket_open_async shall set the state to OPEN. ]*/
(void)InterlockedExchange(&async_socket->state, (LONG)ASYNC_SOCKET_WIN32_STATE_OPEN);
WakeByAddressSingle((PVOID)&async_socket->state);
/* Codes_SRS_ASYNC_SOCKET_WIN32_01_017: [ On success async_socket_open_async shall call on_open_complete_context with ASYNC_SOCKET_OPEN_OK. ]*/
on_open_complete(on_open_complete_context, ASYNC_SOCKET_OPEN_OK);
/* Codes_SRS_ASYNC_SOCKET_WIN32_01_014: [ On success, async_socket_open_async shall return 0. ]*/
result = 0;
goto all_ok;
}
async_socket->socket_handle = (SOCKET_HANDLE)INVALID_SOCKET;
DestroyThreadpoolEnvironment(&async_socket->tp_environment);
(void)InterlockedExchange(&async_socket->state, (LONG)ASYNC_SOCKET_WIN32_STATE_CLOSED);
WakeByAddressSingle((PVOID)&async_socket->state);
}
}
all_ok:
return result;
}