wininet: Remove the custom thread pool implementation and use QueueUserWorkItem instead.
This commit is contained in:
parent
98c87d0e70
commit
02c89e5c6f
|
@ -70,8 +70,6 @@
|
||||||
|
|
||||||
WINE_DEFAULT_DEBUG_CHANNEL(wininet);
|
WINE_DEFAULT_DEBUG_CHANNEL(wininet);
|
||||||
|
|
||||||
#define MAX_IDLE_WORKER 1000*60*1
|
|
||||||
#define MAX_WORKER_THREADS 10
|
|
||||||
#define RESPONSE_TIMEOUT 30
|
#define RESPONSE_TIMEOUT 30
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
|
@ -83,18 +81,8 @@ typedef struct
|
||||||
static VOID INTERNET_CloseHandle(LPWININETHANDLEHEADER hdr);
|
static VOID INTERNET_CloseHandle(LPWININETHANDLEHEADER hdr);
|
||||||
HINTERNET WINAPI INTERNET_InternetOpenUrlW(LPWININETAPPINFOW hIC, LPCWSTR lpszUrl,
|
HINTERNET WINAPI INTERNET_InternetOpenUrlW(LPWININETAPPINFOW hIC, LPCWSTR lpszUrl,
|
||||||
LPCWSTR lpszHeaders, DWORD dwHeadersLength, DWORD dwFlags, DWORD dwContext);
|
LPCWSTR lpszHeaders, DWORD dwHeadersLength, DWORD dwFlags, DWORD dwContext);
|
||||||
static VOID INTERNET_ExecuteWork(void);
|
|
||||||
|
|
||||||
static DWORD g_dwTlsErrIndex = TLS_OUT_OF_INDEXES;
|
static DWORD g_dwTlsErrIndex = TLS_OUT_OF_INDEXES;
|
||||||
static LONG dwNumThreads;
|
|
||||||
static LONG dwNumIdleThreads;
|
|
||||||
static LONG dwNumJobs;
|
|
||||||
static HANDLE hEventArray[2];
|
|
||||||
#define hQuitEvent hEventArray[0]
|
|
||||||
#define hWorkEvent hEventArray[1]
|
|
||||||
static CRITICAL_SECTION csQueue;
|
|
||||||
static LPWORKREQUEST lpHeadWorkQueue;
|
|
||||||
static LPWORKREQUEST lpWorkQueueTail;
|
|
||||||
static HMODULE WININET_hModule;
|
static HMODULE WININET_hModule;
|
||||||
|
|
||||||
#define HANDLE_CHUNK_SIZE 0x10
|
#define HANDLE_CHUNK_SIZE 0x10
|
||||||
|
@ -246,16 +234,8 @@ BOOL WINAPI DllMain (HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
|
||||||
if (g_dwTlsErrIndex == TLS_OUT_OF_INDEXES)
|
if (g_dwTlsErrIndex == TLS_OUT_OF_INDEXES)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
hQuitEvent = CreateEventW(0, TRUE, FALSE, NULL);
|
|
||||||
hWorkEvent = CreateEventW(0, FALSE, FALSE, NULL);
|
|
||||||
InitializeCriticalSection(&csQueue);
|
|
||||||
|
|
||||||
URLCacheContainers_CreateDefaults();
|
URLCacheContainers_CreateDefaults();
|
||||||
|
|
||||||
dwNumThreads = 0;
|
|
||||||
dwNumIdleThreads = 0;
|
|
||||||
dwNumJobs = 0;
|
|
||||||
|
|
||||||
WININET_hModule = (HMODULE)hinstDLL;
|
WININET_hModule = (HMODULE)hinstDLL;
|
||||||
|
|
||||||
case DLL_THREAD_ATTACH:
|
case DLL_THREAD_ATTACH:
|
||||||
|
@ -278,12 +258,6 @@ BOOL WINAPI DllMain (HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
|
||||||
HeapFree(GetProcessHeap(), 0, TlsGetValue(g_dwTlsErrIndex));
|
HeapFree(GetProcessHeap(), 0, TlsGetValue(g_dwTlsErrIndex));
|
||||||
TlsFree(g_dwTlsErrIndex);
|
TlsFree(g_dwTlsErrIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
SetEvent(hQuitEvent);
|
|
||||||
|
|
||||||
CloseHandle(hQuitEvent);
|
|
||||||
CloseHandle(hWorkEvent);
|
|
||||||
DeleteCriticalSection(&csQueue);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3084,107 +3058,18 @@ DWORD INTERNET_GetLastError(void)
|
||||||
*/
|
*/
|
||||||
static DWORD CALLBACK INTERNET_WorkerThreadFunc(LPVOID lpvParam)
|
static DWORD CALLBACK INTERNET_WorkerThreadFunc(LPVOID lpvParam)
|
||||||
{
|
{
|
||||||
DWORD dwWaitRes;
|
LPWORKREQUEST lpRequest = lpvParam;
|
||||||
|
WORKREQUEST workRequest;
|
||||||
while (1)
|
|
||||||
{
|
|
||||||
if(dwNumJobs > 0) {
|
|
||||||
INTERNET_ExecuteWork();
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
dwWaitRes = WaitForMultipleObjects(2, hEventArray, FALSE, MAX_IDLE_WORKER);
|
|
||||||
|
|
||||||
if (dwWaitRes == WAIT_OBJECT_0 + 1)
|
|
||||||
INTERNET_ExecuteWork();
|
|
||||||
else
|
|
||||||
break;
|
|
||||||
|
|
||||||
InterlockedIncrement(&dwNumIdleThreads);
|
|
||||||
}
|
|
||||||
|
|
||||||
InterlockedDecrement(&dwNumIdleThreads);
|
|
||||||
InterlockedDecrement(&dwNumThreads);
|
|
||||||
TRACE("Worker thread exiting\n");
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/***********************************************************************
|
|
||||||
* INTERNET_InsertWorkRequest (internal)
|
|
||||||
*
|
|
||||||
* Insert work request into queue
|
|
||||||
*
|
|
||||||
* RETURNS
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
static BOOL INTERNET_InsertWorkRequest(LPWORKREQUEST lpWorkRequest)
|
|
||||||
{
|
|
||||||
BOOL bSuccess = FALSE;
|
|
||||||
LPWORKREQUEST lpNewRequest;
|
|
||||||
|
|
||||||
TRACE("\n");
|
TRACE("\n");
|
||||||
|
|
||||||
lpNewRequest = HeapAlloc(GetProcessHeap(), 0, sizeof(WORKREQUEST));
|
memcpy(&workRequest, lpRequest, sizeof(WORKREQUEST));
|
||||||
if (lpNewRequest)
|
|
||||||
{
|
|
||||||
memcpy(lpNewRequest, lpWorkRequest, sizeof(WORKREQUEST));
|
|
||||||
lpNewRequest->prev = NULL;
|
|
||||||
|
|
||||||
EnterCriticalSection(&csQueue);
|
|
||||||
|
|
||||||
lpNewRequest->next = lpWorkQueueTail;
|
|
||||||
if (lpWorkQueueTail)
|
|
||||||
lpWorkQueueTail->prev = lpNewRequest;
|
|
||||||
lpWorkQueueTail = lpNewRequest;
|
|
||||||
if (!lpHeadWorkQueue)
|
|
||||||
lpHeadWorkQueue = lpWorkQueueTail;
|
|
||||||
|
|
||||||
LeaveCriticalSection(&csQueue);
|
|
||||||
|
|
||||||
bSuccess = TRUE;
|
|
||||||
InterlockedIncrement(&dwNumJobs);
|
|
||||||
}
|
|
||||||
|
|
||||||
return bSuccess;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/***********************************************************************
|
|
||||||
* INTERNET_GetWorkRequest (internal)
|
|
||||||
*
|
|
||||||
* Retrieves work request from queue
|
|
||||||
*
|
|
||||||
* RETURNS
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
static BOOL INTERNET_GetWorkRequest(LPWORKREQUEST lpWorkRequest)
|
|
||||||
{
|
|
||||||
BOOL bSuccess = FALSE;
|
|
||||||
LPWORKREQUEST lpRequest = NULL;
|
|
||||||
|
|
||||||
TRACE("\n");
|
|
||||||
|
|
||||||
EnterCriticalSection(&csQueue);
|
|
||||||
|
|
||||||
if (lpHeadWorkQueue)
|
|
||||||
{
|
|
||||||
lpRequest = lpHeadWorkQueue;
|
|
||||||
lpHeadWorkQueue = lpHeadWorkQueue->prev;
|
|
||||||
if (lpRequest == lpWorkQueueTail)
|
|
||||||
lpWorkQueueTail = lpHeadWorkQueue;
|
|
||||||
}
|
|
||||||
|
|
||||||
LeaveCriticalSection(&csQueue);
|
|
||||||
|
|
||||||
if (lpRequest)
|
|
||||||
{
|
|
||||||
memcpy(lpWorkRequest, lpRequest, sizeof(WORKREQUEST));
|
|
||||||
HeapFree(GetProcessHeap(), 0, lpRequest);
|
HeapFree(GetProcessHeap(), 0, lpRequest);
|
||||||
bSuccess = TRUE;
|
|
||||||
InterlockedDecrement(&dwNumJobs);
|
|
||||||
}
|
|
||||||
|
|
||||||
return bSuccess;
|
workRequest.asyncproc(&workRequest);
|
||||||
|
|
||||||
|
WININET_Release( workRequest.hdr );
|
||||||
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -3198,59 +3083,28 @@ static BOOL INTERNET_GetWorkRequest(LPWORKREQUEST lpWorkRequest)
|
||||||
*/
|
*/
|
||||||
BOOL INTERNET_AsyncCall(LPWORKREQUEST lpWorkRequest)
|
BOOL INTERNET_AsyncCall(LPWORKREQUEST lpWorkRequest)
|
||||||
{
|
{
|
||||||
HANDLE hThread;
|
BOOL bSuccess;
|
||||||
DWORD dwTID;
|
LPWORKREQUEST lpNewRequest;
|
||||||
BOOL bSuccess = FALSE;
|
|
||||||
|
|
||||||
TRACE("\n");
|
TRACE("\n");
|
||||||
|
|
||||||
if (InterlockedDecrement(&dwNumIdleThreads) < 0)
|
lpNewRequest = HeapAlloc(GetProcessHeap(), 0, sizeof(WORKREQUEST));
|
||||||
{
|
if (!lpNewRequest)
|
||||||
InterlockedIncrement(&dwNumIdleThreads);
|
return FALSE;
|
||||||
|
|
||||||
if (InterlockedIncrement(&dwNumThreads) > MAX_WORKER_THREADS ||
|
memcpy(lpNewRequest, lpWorkRequest, sizeof(WORKREQUEST));
|
||||||
!(hThread = CreateThread(NULL, 0,
|
|
||||||
INTERNET_WorkerThreadFunc, NULL, 0, &dwTID)))
|
bSuccess = QueueUserWorkItem(INTERNET_WorkerThreadFunc, lpNewRequest, WT_EXECUTELONGFUNCTION);
|
||||||
|
if (!bSuccess)
|
||||||
{
|
{
|
||||||
InterlockedDecrement(&dwNumThreads);
|
HeapFree(GetProcessHeap(), 0, lpNewRequest);
|
||||||
INTERNET_SetLastError(ERROR_INTERNET_ASYNC_THREAD_FAILED);
|
INTERNET_SetLastError(ERROR_INTERNET_ASYNC_THREAD_FAILED);
|
||||||
goto lerror;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TRACE("Created new thread\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
bSuccess = TRUE;
|
|
||||||
INTERNET_InsertWorkRequest(lpWorkRequest);
|
|
||||||
SetEvent(hWorkEvent);
|
|
||||||
|
|
||||||
lerror:
|
|
||||||
|
|
||||||
return bSuccess;
|
return bSuccess;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/***********************************************************************
|
|
||||||
* INTERNET_ExecuteWork (internal)
|
|
||||||
*
|
|
||||||
* RETURNS
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
static VOID INTERNET_ExecuteWork(void)
|
|
||||||
{
|
|
||||||
WORKREQUEST workRequest;
|
|
||||||
|
|
||||||
TRACE("\n");
|
|
||||||
|
|
||||||
if (!INTERNET_GetWorkRequest(&workRequest))
|
|
||||||
return;
|
|
||||||
|
|
||||||
workRequest.asyncproc(&workRequest);
|
|
||||||
|
|
||||||
WININET_Release( workRequest.hdr );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
* INTERNET_GetResponseBuffer (internal)
|
* INTERNET_GetResponseBuffer (internal)
|
||||||
*
|
*
|
||||||
|
|
|
@ -374,9 +374,6 @@ typedef struct WORKREQ
|
||||||
struct WORKREQ_INTERNETREADFILEEXA InternetReadFileExA;
|
struct WORKREQ_INTERNETREADFILEEXA InternetReadFileExA;
|
||||||
} u;
|
} u;
|
||||||
|
|
||||||
struct WORKREQ *next;
|
|
||||||
struct WORKREQ *prev;
|
|
||||||
|
|
||||||
} WORKREQUEST, *LPWORKREQUEST;
|
} WORKREQUEST, *LPWORKREQUEST;
|
||||||
|
|
||||||
HINTERNET WININET_AllocHandle( LPWININETHANDLEHEADER info );
|
HINTERNET WININET_AllocHandle( LPWININETHANDLEHEADER info );
|
||||||
|
|
Loading…
Reference in New Issue