windows-nt/Source/XPSP1/NT/net/tapi/skywalker/h323/tsp/io.cpp
2020-09-26 16:20:57 +08:00

170 lines
4.4 KiB
C++

#include "globals.h"
#if H323_USE_PRIVATE_IO_THREAD
#define FINITE_WAIT_TIME 3000
static HANDLE H323IoCompletionPort = NULL;
static HANDLE H323IoThread = NULL;
static DWORD H323IoThreadID = 0;
static DWORD WINAPI H323IoThreadProc (
IN PVOID ThreadParameter)
{
LPOVERLAPPED Overlapped;
ULONG_PTR CompletionKey;
DWORD Status;
DWORD BytesTransferred;
for (;;)
{
if( GetQueuedCompletionStatus( H323IoCompletionPort,
&BytesTransferred,
&CompletionKey,
&Overlapped,
INFINITE) == TRUE )
{
Status = ERROR_SUCCESS;
}
else
{
if( Overlapped )
{
Status = GetLastError();
}
else
{
H323DBG((DEBUG_LEVEL_ERROR, "failed to dequeue i/o completion "
"packet: %d, quitting...", GetLastError() ));
ExitThread (GetLastError());
}
}
_ASSERTE( CompletionKey);
((LPOVERLAPPED_COMPLETION_ROUTINE) CompletionKey)( Status,
BytesTransferred,
Overlapped );
}
// never reached
return EXIT_SUCCESS;
}
static void CALLBACK H323IoThreadExitCallback (
IN DWORD Status,
IN DWORD BytesTransferred,
IN LPOVERLAPPED Overlapped)
{
H323DBG ((DEBUG_LEVEL_TRACE, "i/o completion thread is stopping"));
ExitThread (EXIT_SUCCESS);
}
HRESULT H323IoThreadStart (void)
{
if( H323IoCompletionPort == NULL )
{
H323IoCompletionPort =
CreateIoCompletionPort( INVALID_HANDLE_VALUE,
NULL,
0,
0 );
if( H323IoCompletionPort == NULL )
{
H323DBG(( DEBUG_LEVEL_ERROR,
"failed to create i/o completion port: %d", GetLastError() ));
return GetLastResult();
}
}
H323IoThread = CreateThread(NULL,
0,
H323IoThreadProc,
NULL,
0,
&H323IoThreadID );
if( H323IoThread == NULL )
{
H323DBG(( DEBUG_LEVEL_ERROR,
"failed to create i/o completion worker thread: %d",
GetLastError() ));
CloseHandle (H323IoCompletionPort);
H323IoCompletionPort = NULL;
return GetLastResult();
}
return S_OK;
}
void H323IoThreadStop (void)
{
DWORD dwWaitTime = INFINITE;
H323DBG ((DEBUG_LEVEL_WARNING, "H323IoThreadStop entered."));
if( H323IoThread != NULL )
{
_ASSERTE( H323IoCompletionPort != NULL );
if( !PostQueuedCompletionStatus( H323IoCompletionPort, 0,
(ULONG_PTR) H323IoThreadExitCallback, (LPOVERLAPPED) -1) )
{
H323DBG(( DEBUG_LEVEL_WARNING, "PostQueuedCompletionStatus failed" ));
dwWaitTime = FINITE_WAIT_TIME;
}
H323DBG(( DEBUG_LEVEL_WARNING,
"waiting for i/o completion port thread to finish..." ));
WaitForSingleObject( H323IoThread, dwWaitTime );
H323DBG(( DEBUG_LEVEL_WARNING,
"i/o completion port thread is finished." ));
CloseHandle (H323IoThread);
H323IoThread = NULL;
}
if( H323IoCompletionPort != NULL )
{
CloseHandle( H323IoCompletionPort );
H323IoCompletionPort = NULL;
}
H323DBG ((DEBUG_LEVEL_WARNING, "H323IoThreadStop exited"));
}
BOOL H323BindIoCompletionCallback (
IN HANDLE ObjectHandle,
IN LPOVERLAPPED_COMPLETION_ROUTINE CompletionRoutine,
IN ULONG Flags)
{
if( H323IoCompletionPort != NULL )
{
if (!CompletionRoutine)
{
SetLastError (ERROR_INVALID_PARAMETER);
return FALSE;
}
return CreateIoCompletionPort( ObjectHandle,
H323IoCompletionPort,
(ULONG_PTR) CompletionRoutine,
0 ) != NULL;
}
else
{
H323DBG(( DEBUG_LEVEL_ERROR, "i/o completion port is not yet created" ));
SetLastError( ERROR_GEN_FAILURE );
return FALSE;
}
}
#endif