diff --git a/engines/tony/mpal/mpal.cpp b/engines/tony/mpal/mpal.cpp index 3757cdddcf7d..78111753ce96 100644 --- a/engines/tony/mpal/mpal.cpp +++ b/engines/tony/mpal/mpal.cpp @@ -996,11 +996,12 @@ void ShutUpActionThread(CORO_PARAM, const void *param) { CORO_BEGIN_CONTEXT; CORO_END_CONTEXT(_ctx); - HANDLE hThread = *(const HANDLE *)param; + int pid = *(const int *)param; CORO_BEGIN_CODE(_ctx); - WaitForSingleObject(hThread, INFINITE); + CORO_INVOKE_2(_vm->_scheduler.waitForSingleObject, pid, INFINITE); + bExecutingAction = false; CORO_KILL_SELF(); @@ -1554,7 +1555,7 @@ static HANDLE DoAction(uint32 nAction, uint32 ordItem, uint32 dwParam) { if ((h = g_scheduler->createProcess(ActionThread, newitem)) == NULL) return INVALID_HANDLE_VALUE; - if ((h = g_scheduler->createProcess(0, ShutUpActionThread, &h, sizeof(PROCESS *))) == NULL) + if ((h = g_scheduler->createProcess(ShutUpActionThread, &h->pid, sizeof(int))) == NULL) return INVALID_HANDLE_VALUE; /* diff --git a/engines/tony/sched.cpp b/engines/tony/sched.cpp index 7f259b7a5b84..0f397316f6d4 100644 --- a/engines/tony/sched.cpp +++ b/engines/tony/sched.cpp @@ -21,6 +21,7 @@ * Process scheduler. */ +#include "common/system.h" #include "common/textconsole.h" #include "common/util.h" #include "tony/sched.h" @@ -42,7 +43,8 @@ Scheduler::Scheduler() { maxProcs = 0; #endif - pRCfunction = 0; + pRCfunction = NULL; + pidCounter = 0; active = new PROCESS; active->pPrevious = NULL; @@ -289,6 +291,40 @@ void Scheduler::giveWay(PPROCESS pReSchedProc) { pReSchedProc->pNext = NULL; } +/** + * Continously makes a given process wait for another process to finish + * + * @param pid Process identifier + * @param duration Duration in milliseconds + */ +void Scheduler::waitForSingleObject(CORO_PARAM, int pid, int duration) { + CORO_BEGIN_CONTEXT; + uint32 endTime; + PROCESS *pProc; + CORO_END_CONTEXT(_ctx); + + CORO_BEGIN_CODE(_ctx); + + _ctx->endTime = (duration == INFINITE) ? INFINITE : g_system->getMillis() + duration; + + // Outer loop for doing checks until expiry + while (g_system->getMillis() < _ctx->endTime) { + // Check to see if a process with the given Id exists + _ctx->pProc = active->pNext; + while ((_ctx->pProc != NULL) && (_ctx->pProc->pid == pid)) + _ctx->pProc = _ctx->pProc->pNext; + + if (_ctx->pProc == NULL) + // No match process found, so it's okay to break out of loop + break; + + // Sleep until the next cycle + CORO_SLEEP(1); + } + + CORO_END_CODE; +} + /** * Creates a new process. * @@ -297,7 +333,7 @@ void Scheduler::giveWay(PPROCESS pReSchedProc) { * @param pParam process specific info * @param sizeParam size of process specific info */ -PROCESS *Scheduler::createProcess(int pid, CORO_ADDR coroAddr, const void *pParam, int sizeParam) { +PROCESS *Scheduler::createProcess(CORO_ADDR coroAddr, const void *pParam, int sizeParam) { PROCESS *pProc; // get a free process @@ -347,7 +383,7 @@ PROCESS *Scheduler::createProcess(int pid, CORO_ADDR coroAddr, const void *pPara pProc->sleepTime = 1; // set new process id - pProc->pid = pid; + pProc->pid = ++pidCounter; // set new process specific info if (sizeParam) { diff --git a/engines/tony/sched.h b/engines/tony/sched.h index 9bc6d052da29..cffa0f932862 100644 --- a/engines/tony/sched.h +++ b/engines/tony/sched.h @@ -35,6 +35,8 @@ namespace Tony { #define NUM_PROCESS 100 #define MAX_PROCESSES 100 +#define INFINITE 0xffffffff + typedef void (*CORO_ADDR)(CoroContext &, const void *); /** process structure */ @@ -75,6 +77,10 @@ class Scheduler { /** the currently active process */ PROCESS *pCurrent; + /** Auto-incrementing process Id */ + int pidCounter; + + #ifdef DEBUG // diagnostic process counters int numProcs; @@ -105,10 +111,11 @@ class Scheduler { void rescheduleAll(); void reschedule(PPROCESS pReSchedProc = NULL); void giveWay(PPROCESS pReSchedProc = NULL); + void waitForSingleObject(CORO_PARAM, int pid, int duration); - PROCESS *createProcess(int pid, CORO_ADDR coroAddr, const void *pParam, int sizeParam); + PROCESS *createProcess(CORO_ADDR coroAddr, const void *pParam, int sizeParam); PROCESS *createProcess(CORO_ADDR coroAddr, const void *pParam) { - return createProcess(0, coroAddr, &pParam, sizeof(void *)); + return createProcess(coroAddr, &pParam, sizeof(void *)); } void killProcess(PROCESS *pKillProc);