wininet: Remove the custom thread pool implementation and use QueueUserWorkItem instead.

Robert Shearman rob at codeweavers.com
Thu Jan 4 12:26:31 CST 2007


---
  dlls/wininet/internet.c |  184 
+++++------------------------------------------
  dlls/wininet/internet.h |    3 -
  2 files changed, 19 insertions(+), 168 deletions(-)

This also fixes a bug in the old code where starting a new asynchronous 
operation with more than 10 asynchronous operations in progress would fail.
-------------- next part --------------
diff --git a/dlls/wininet/internet.c b/dlls/wininet/internet.c
index aadac29..afbff3d 100644
--- a/dlls/wininet/internet.c
+++ b/dlls/wininet/internet.c
@@ -70,8 +70,6 @@ #include "wincrypt.h"
 
 WINE_DEFAULT_DEBUG_CHANNEL(wininet);
 
-#define MAX_IDLE_WORKER 1000*60*1
-#define MAX_WORKER_THREADS 10
 #define RESPONSE_TIMEOUT        30
 
 typedef struct
@@ -83,18 +81,8 @@ typedef struct
 static VOID INTERNET_CloseHandle(LPWININETHANDLEHEADER hdr);
 HINTERNET WINAPI INTERNET_InternetOpenUrlW(LPWININETAPPINFOW hIC, LPCWSTR lpszUrl,
               LPCWSTR lpszHeaders, DWORD dwHeadersLength, DWORD dwFlags, DWORD dwContext);
-static VOID INTERNET_ExecuteWork(void);
 
 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;
 
 #define HANDLE_CHUNK_SIZE 0x10
@@ -246,16 +234,8 @@ BOOL WINAPI DllMain (HINSTANCE hinstDLL,
 	    if (g_dwTlsErrIndex == TLS_OUT_OF_INDEXES)
 		return FALSE;
 
-	    hQuitEvent = CreateEventW(0, TRUE, FALSE, NULL);
-	    hWorkEvent = CreateEventW(0, FALSE, FALSE, NULL);
-	    InitializeCriticalSection(&csQueue);
-
             URLCacheContainers_CreateDefaults();
 
-            dwNumThreads = 0;
-            dwNumIdleThreads = 0;
-	    dwNumJobs = 0;
-
             WININET_hModule = (HMODULE)hinstDLL;
 
         case DLL_THREAD_ATTACH:
@@ -278,12 +258,6 @@ BOOL WINAPI DllMain (HINSTANCE hinstDLL,
 	        HeapFree(GetProcessHeap(), 0, TlsGetValue(g_dwTlsErrIndex));
 	        TlsFree(g_dwTlsErrIndex);
 	    }
-
-	    SetEvent(hQuitEvent);
-
-	    CloseHandle(hQuitEvent);
-	    CloseHandle(hWorkEvent);
-	    DeleteCriticalSection(&csQueue);
             break;
     }
 
@@ -3105,107 +3079,18 @@ DWORD INTERNET_GetLastError(void)
  */
 static DWORD CALLBACK INTERNET_WorkerThreadFunc(LPVOID lpvParam)
 {
-    DWORD dwWaitRes;
-
-    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");
-
-    lpNewRequest = HeapAlloc(GetProcessHeap(), 0, 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;
+    LPWORKREQUEST lpRequest = lpvParam;
+    WORKREQUEST workRequest;
 
     TRACE("\n");
 
-    EnterCriticalSection(&csQueue);
+    memcpy(&workRequest, lpRequest, sizeof(WORKREQUEST));
+    HeapFree(GetProcessHeap(), 0, lpRequest);
 
-    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);
-	bSuccess = TRUE;
-	InterlockedDecrement(&dwNumJobs);
-    }
+    workRequest.asyncproc(&workRequest);
 
-    return bSuccess;
+    WININET_Release( workRequest.hdr );
+    return TRUE;
 }
 
 
@@ -3219,60 +3104,29 @@ static BOOL INTERNET_GetWorkRequest(LPWO
  */
 BOOL INTERNET_AsyncCall(LPWORKREQUEST lpWorkRequest)
 {
-    HANDLE hThread;
-    DWORD dwTID;
-    BOOL bSuccess = FALSE;
+    BOOL bSuccess;
+    LPWORKREQUEST lpNewRequest;
 
     TRACE("\n");
+    
+    lpNewRequest = HeapAlloc(GetProcessHeap(), 0, sizeof(WORKREQUEST));
+    if (!lpNewRequest)
+        return FALSE;
 
-    if (InterlockedDecrement(&dwNumIdleThreads) < 0)
-    {
-        InterlockedIncrement(&dwNumIdleThreads);
+    memcpy(lpNewRequest, lpWorkRequest, sizeof(WORKREQUEST));
 
-	if (InterlockedIncrement(&dwNumThreads) > MAX_WORKER_THREADS ||
-	    !(hThread = CreateThread(NULL, 0,
-            INTERNET_WorkerThreadFunc, NULL, 0, &dwTID)))
-	{
-            InterlockedDecrement(&dwNumThreads);
-            INTERNET_SetLastError(ERROR_INTERNET_ASYNC_THREAD_FAILED);
-	    goto lerror;
-	}
-
-	TRACE("Created new thread\n");
+    bSuccess = QueueUserWorkItem(INTERNET_WorkerThreadFunc, lpNewRequest, WT_EXECUTELONGFUNCTION);
+    if (!bSuccess)
+    {
+        HeapFree(GetProcessHeap(), 0, lpNewRequest);
+        INTERNET_SetLastError(ERROR_INTERNET_ASYNC_THREAD_FAILED);
     }
 
-    bSuccess = TRUE;
-    INTERNET_InsertWorkRequest(lpWorkRequest);
-    SetEvent(hWorkEvent);
-
-lerror:
-
     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)
  *
  * RETURNS
diff --git a/dlls/wininet/internet.h b/dlls/wininet/internet.h
index 06de851..438654b 100644
--- a/dlls/wininet/internet.h
+++ b/dlls/wininet/internet.h
@@ -376,9 +376,6 @@ typedef struct WORKREQ
         struct WORKREQ_INTERNETREADFILEEXA      InternetReadFileExA;
     } u;
 
-    struct WORKREQ *next;
-    struct WORKREQ *prev;
-
 } WORKREQUEST, *LPWORKREQUEST;
 
 HINTERNET WININET_AllocHandle( LPWININETHANDLEHEADER info );


More information about the wine-patches mailing list