/** * Reads a block of data from the buffer. * * @param data The read data will be written here. * @param length Number of bytes to read. If there aren't this many * bytes currently available, reads all the available * data instead. * * @return Actual number of bytes read. */ int read(void* data, int length) { Sys_Lock(_mutex); // We'll read as much as we have. int avail = availableForReading(); length = MIN_OF(length, avail); const int remainder = _end - _readPos; if(length <= remainder) { memcpy(data, _readPos, length); _readPos += length; if(_readPos == _end) _readPos = _buf; // May wrap around. } else { memcpy(data, _readPos, remainder); memcpy((byte*)data + remainder, _buf, length - remainder); _readPos = _buf + length - remainder; } Sys_Unlock(_mutex); // This is how much we were able to read. return length; }
void BusyMode_WorkerEnd(void) { if(!busyInited) return; Sys_Lock(busy_Mutex); busyDone = true; Sys_Unlock(busy_Mutex); }
/** * Acquire or release ownership of the message queue mutex. * * @return @c true, if successful. */ boolean N_LockQueue(boolean doAcquire) { if(doAcquire) Sys_Lock(msgMutex); else Sys_Unlock(msgMutex); return true; }
static void lock(CBuffer* cb, boolean yes) { assert(cb); if(yes) { Sys_Lock(cb->mutex); return; } Sys_Unlock(cb->mutex); }
dd_bool BusyMode_IsWorkerThread(uint threadId) { dd_bool result; if(!BusyMode_Active() || !busyThread) return false; /// @todo Is locking necessary? Sys_Lock(busy_Mutex); result = (Sys_ThreadId(busyThread) == threadId); Sys_Unlock(busy_Mutex); return result; }
static void lockProgress(boolean lock) { if(lock) { Sys_Lock(progressMutex); } else { Sys_Unlock(progressMutex); } }
void FileHandleBuilder::shutdown(void) { #if 0 if(inited) { Sys_Lock(mutex); BlockSet_Delete(handleBlockSet); handleBlockSet = 0; usedHandles = 0; Sys_Unlock(mutex); Sys_DestroyMutex(mutex); mutex = 0; inited = false; return; } #if _DEBUG Con_Error("FileHandleBuilder::shutdown: Not presently initialized."); #endif #endif }
int availableForReading() const { Sys_Lock(_mutex); int avail; if(_writePos >= _readPos) { avail = _writePos - _readPos; } else { // Write position was wrapped around. avail = (_end - _readPos) + (_writePos - _buf); } Sys_Unlock(_mutex); return avail; }
/** * The busy loop callback function. Called periodically in the main (UI) thread * while the busy worker is running. */ void BusyMode_Loop(void) { if(!busyTask || !BusyMode_Active()) return; dd_bool canUpload = !(busyTask->mode & BUSYF_NO_UPLOADS); timespan_t oldTime; // Post and discard all input events. DD_ProcessEvents(0); DD_ProcessSharpEvents(0); if(canUpload) { ClientWindowSystem::main().glActivate(); // Any deferred content needs to get uploaded. GL_ProcessDeferredTasks(15); } // We accumulate time in the busy loop so that the animation of a task // sequence doesn't jump around but remains continuous. oldTime = busyTime; busyTime = Timer_RealSeconds() - busyTask->_startTime; if(busyTime > oldTime) { accumulatedBusyTime += busyTime - oldTime; } Sys_Lock(busy_Mutex); busyDoneCopy = busyDone; Sys_Unlock(busy_Mutex); if(!busyDoneCopy || (canUpload && GL_DeferredTaskCount() > 0) || !Con_IsProgressAnimationCompleted()) { // Let's keep running the busy loop. ClientWindowSystem::main().draw(); return; } // Stop the loop. BusyMode_Exit(); }
FileHandle::~FileHandle() { close(); // Free any cached data. if(d->data) { M_Free(d->data); d->data = 0; } #if 0 // Copy this file to the used object pool for recycling. Sys_Lock(mutex); d->file = 0; d->list = usedHandles; usedHandles = this; Sys_Unlock(mutex); #endif delete d; }
FileHandle::FileHandle(void) { #if 0 Sys_Lock(mutex); de::FileHandle* file; if(usedHandles) { file = usedHandles; usedHandles = (de::FileHandle*) file->list; } else { if(!handleBlockSet) { handleBlockSet = BlockSet_New(sizeof(de::FileHandle), 64); } file = (de::FileHandle*) BlockSet_Allocate(handleBlockSet); } Sys_Unlock(mutex); #endif d = new Instance(); }
/** * Sets up module state for running a busy task. After this the busy mode event * loop is started. The loop will run until the worker thread exits. */ static void beginTask(BusyTask* task) { DENG_ASSERT(task); if(!busyInited) { busy_Mutex = Sys_CreateMutex("BUSY_MUTEX"); } if(busyInited) { App_Error("Con_Busy: Already busy.\n"); } BusyVisual_PrepareResources(); Sys_Lock(busy_Mutex); busyDone = false; busyTaskEndedWithError = false; // This is now the current task. busyTask = task; Sys_Unlock(busy_Mutex); busyInited = true; de::ProgressWidget &prog = ClientWindow::main().busy().progress(); prog.show(); prog.setText(task->name); prog.setMode(task->mode & BUSYF_ACTIVITY? de::ProgressWidget::Indefinite : de::ProgressWidget::Ranged); // Start the busy worker thread, which will process the task in the // background while we keep the user occupied with nice animations. busyThread = Sys_StartThread(busyTask->worker, busyTask->workerData); Thread_SetCallback(busyThread, busyWorkerTerminated); busyTask->_startTime = Timer_RealSeconds(); }
void write(const void* data, int length) { Sys_Lock(_mutex); DENG_ASSERT(_writePos < _end); // No need to split? const int remainder = _end - _writePos; if(length <= remainder) { memcpy(_writePos, data, length); _writePos += length; if(_writePos == _end) _writePos = _buf; // May wrap around. } else { // Do the write in two parts. memcpy(_writePos, data, remainder); memcpy(_buf, (byte*)data + remainder, length - remainder); _writePos = _buf + length - remainder; } Sys_Unlock(_mutex); }
static __inline void unlockZone(void) { Sys_Unlock(zoneMutex); }
void clear() { Sys_Lock(_mutex); _writePos = _readPos = _buf; Sys_Unlock(_mutex); }