/* ZazouMiniWebServer Copyright (C) 2003-2008 Xavier Garreau This file is part of ZazouMiniWebServer. ZazouMiniWebServer is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. ZazouMiniWebServer is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with ZazouMiniWebServer; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "stdafx.h" #include "threadpool.h" /* *** ZReqProvider class *** */ ZReqProvider::ZReqProvider() { queue_mutex = CreateMutex(NULL, FALSE, NULL); if (!queue_mutex) { zprintf("ERROR: ZReqProvider: Could not create queue mutex"); _exit(1); } request_semaphore = CreateSemaphore (NULL, 1, 0xffff, NULL); DWORD err = GetLastError(); if (!request_semaphore) { zprintf("ERROR: ZReqProvider: Could not create requests semaphore"); _exit(1); } switch (WaitForSingleSemaphore(request_semaphore, 30000)) { case WAIT_ABANDONED: case WAIT_TIMEOUT: case WAIT_FAILED: zprintf("ERROR: ZReqProvider: Could not get semaphore\n"); _exit(1); break; case WAIT_OBJECT_0: break; } } ZReqProvider::~ZReqProvider() { } void ZReqProvider::CloseSyncObjects() { switch (WaitForSingleMutex(queue_mutex, 60000)) { case WAIT_ABANDONED: case WAIT_TIMEOUT: case WAIT_FAILED: break; case WAIT_OBJECT_0: while (!requests.empty()) { delete requests.front(); requests.pop(); } ReleaseMutex(queue_mutex); break; } CloseMutex (queue_mutex); LONG pc; if (!ReleaseSemaphore(request_semaphore, 0xffff, &pc)) { while (pc--) { ReleaseSemaphore(request_semaphore, 1, NULL); } } CloseSemaphore (request_semaphore); } BYTE ZReqProvider::request_add (ZRequest* r) { BYTE retval=1; switch (WaitForSingleMutex(queue_mutex, INFINITE)) { case WAIT_ABANDONED: case WAIT_TIMEOUT: case WAIT_FAILED: retval = 0; break; case WAIT_OBJECT_0: retval = 1; requests.push(r); LONG prev_count; ReleaseSemaphore(request_semaphore, 1, &prev_count); ReleaseMutex(queue_mutex); break; } return retval; } ZRequest* ZReqProvider::request_get() { ZRequest* r = NULL; switch (WaitForSingleSemaphore(request_semaphore, INFINITE)) { case WAIT_ABANDONED: case WAIT_TIMEOUT: case WAIT_FAILED: break; case WAIT_OBJECT_0: switch (WaitForSingleMutex(queue_mutex, INFINITE)) { case WAIT_ABANDONED: case WAIT_TIMEOUT: case WAIT_FAILED: break; case WAIT_OBJECT_0: if (!requests.empty()) { r = requests.front(); requests.pop(); } ReleaseMutex(queue_mutex); break; } break; } return r; } /* *** End ZReqProvider class *** */ /* *** ZThread class *** */ void __cdecl ZThread::start(void* data) { ZThread* a_thread = static_cast(data); a_thread->run(); } ZThread::ZThread() : stop_thread(FALSE) { stop_mutex = CreateMutex (NULL, FALSE, NULL); if (!stop_mutex) stop_thread = TRUE; } ZThread::~ZThread() { if (stop_mutex) CloseMutex(stop_mutex); } BYTE ZThread::stop() { BYTE retval; switch (WaitForSingleMutex(stop_mutex, INFINITE)) { case WAIT_ABANDONED: case WAIT_TIMEOUT: case WAIT_FAILED: retval = 0; break; case WAIT_OBJECT_0: stop_thread=1; retval = 1; ReleaseMutex(stop_mutex); break; } return retval; } BOOL ZThread::should_stop() { BOOL retval; switch (WaitForSingleMutex(stop_mutex, 60000)) { case WAIT_ABANDONED: case WAIT_TIMEOUT: case WAIT_FAILED: retval = TRUE; break; case WAIT_OBJECT_0: retval = stop_thread; ReleaseMutex(stop_mutex); break; } return retval; } void ZThread::run() { ZRequest* r; while (!should_stop()) { r = request_provider->request_get(); if (r) { handle_request(r); } } delete this; } /* *** End ZThread class *** */