void worker_cleanup(void) { LPWORKER lpWorker = NULL; /* WARNING: we can have a race condition here, if while this code is executed another worker is waiting to access hWorkersMutex, he will never be able to get it... */ if (hWorkersMutex != INVALID_HANDLE_VALUE) { WaitForSingleObject(hWorkersMutex, INFINITE); DEBUG_PRINT("Freeing global resource of workers"); /* Empty the queue of worker worker */ while (lpWorkers != NULL) { ReleaseMutex(hWorkersMutex); lpWorker = worker_pop(); DEBUG_PRINT("Freeing worker %x", lpWorker); WaitForSingleObject(hWorkersMutex, INFINITE); worker_free(lpWorker); }; ReleaseMutex(hWorkersMutex); /* Destroy associated mutex */ CloseHandle(hWorkersMutex); hWorkersMutex = INVALID_HANDLE_VALUE; }; }
LPWORKER worker_job_submit (WORKERFUNC f, void *user_data) { LPWORKER lpWorker = worker_pop(); #ifdef DBUG dbug_print("Waiting for worker to be ready"); #endif enter_blocking_section(); WaitForSingleObject(lpWorker->hWorkerReady, INFINITE); ResetEvent(lpWorker->hWorkerReady); leave_blocking_section(); #ifdef DBUG dbug_print("Worker is ready"); #endif lpWorker->hJobFunc = f; lpWorker->lpJobUserData = user_data; lpWorker->ECommand = WORKER_CMD_EXEC; #ifdef DBUG dbug_print("Call worker (func: %x, worker: %x)", f, lpWorker); #endif SetEvent(lpWorker->hCommandReady); return (LPWORKER)lpWorker; }