mirror of https://gitlab.com/nakst/essence
drain work queue before exit
This commit is contained in:
parent
069eb7754f
commit
a60f0cea09
|
@ -548,7 +548,7 @@ void ThumbnailResize(uint32_t *bits, uint32_t originalWidth, uint32_t originalHe
|
|||
void ThumbnailGenerateTask(Instance *, Task *task) {
|
||||
EsMessageMutexAcquire();
|
||||
Thumbnail *thumbnail = thumbnailCache.Get(&task->id);
|
||||
bool cancelTask = !thumbnail || thumbnail->referenceCount == 0;
|
||||
bool cancelTask = !thumbnail || thumbnail->referenceCount == 0 || EsWorkIsExiting();
|
||||
EsMessageMutexRelease();
|
||||
|
||||
if (cancelTask) {
|
||||
|
@ -593,13 +593,6 @@ void ThumbnailGenerateTask(Instance *, Task *task) {
|
|||
if (targetWidth == originalWidth && targetHeight == originalHeight) {
|
||||
targetBits = originalBits;
|
||||
} else {
|
||||
targetBits = (uint32_t *) EsHeapAllocate(targetWidth * targetHeight * 4, false);
|
||||
|
||||
if (!targetBits) {
|
||||
EsHeapFree(originalBits);
|
||||
return; // Allocation failure; could not resize the image.
|
||||
}
|
||||
|
||||
ThumbnailResize(originalBits, originalWidth, originalHeight, targetWidth, targetHeight);
|
||||
targetBits = (uint32_t *) EsHeapReallocate(originalBits, targetWidth * targetHeight * 4, false);
|
||||
}
|
||||
|
|
|
@ -145,6 +145,8 @@ struct {
|
|||
EsHandle workAvailable;
|
||||
EsMutex workMutex;
|
||||
Array<Work> workQueue;
|
||||
Array<EsHandle> workThreads;
|
||||
volatile bool workFinish;
|
||||
} api;
|
||||
|
||||
ptrdiff_t tlsStorageOffset;
|
||||
|
@ -862,7 +864,17 @@ EsMessage *EsMessageReceive() {
|
|||
// Desktop tracks the number of instances it owns, so it needs to know when it exits.
|
||||
ApplicationProcessTerminated(EsProcessGetID(ES_CURRENT_PROCESS));
|
||||
} else {
|
||||
api.workFinish = true;
|
||||
if (api.workAvailable) EsEventSet(api.workAvailable);
|
||||
EsMessageMutexRelease();
|
||||
|
||||
for (uintptr_t i = 0; i < api.workThreads.Length(); i++) {
|
||||
EsWaitSingle(api.workThreads[i]);
|
||||
EsHandleClose(api.workThreads[i]);
|
||||
}
|
||||
|
||||
#ifdef DEBUG_BUILD
|
||||
EsMessageMutexAcquire();
|
||||
FontDatabaseFree();
|
||||
FreeUnusedStyles(true /* include permanent styles */);
|
||||
theming.loadedStyles.Free();
|
||||
|
@ -875,8 +887,9 @@ EsMessage *EsMessageReceive() {
|
|||
gui.allWindows.Free();
|
||||
calculator.Free();
|
||||
HashTableFree(&gui.keyboardShortcutNames, false);
|
||||
EsHandleClose(api.workAvailable); // TODO Waiting for all work to finish.
|
||||
if (api.workAvailable) EsHandleClose(api.workAvailable);
|
||||
EsAssert(!api.workQueue.Length());
|
||||
api.workThreads.Free();
|
||||
api.workQueue.Free();
|
||||
MemoryLeakDetectorCheckpoint(&heap);
|
||||
EsPrint("ES_MSG_APPLICATION_EXIT - Heap allocation count: %d (%d from malloc).\n", heap.allocationsCount, mallocCount);
|
||||
|
@ -1893,6 +1906,10 @@ void EsTimerCancel(EsTimer id) {
|
|||
EsMutexRelease(&api.timersMutex);
|
||||
}
|
||||
|
||||
bool EsWorkIsExiting() {
|
||||
return api.workFinish;
|
||||
}
|
||||
|
||||
void WorkThread(EsGeneric) {
|
||||
while (true) {
|
||||
EsWait(&api.workAvailable, 1, ES_WAIT_NO_TIMEOUT);
|
||||
|
@ -1907,28 +1924,38 @@ void WorkThread(EsGeneric) {
|
|||
work.callback(work.context);
|
||||
} else {
|
||||
EsMutexRelease(&api.workMutex);
|
||||
|
||||
if (api.workFinish) {
|
||||
EsEventSet(api.workAvailable); // Wake up another thread.
|
||||
return;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void EsWorkQueue(EsWorkCallback callback, EsGeneric context) {
|
||||
EsError EsWorkQueue(EsWorkCallback callback, EsGeneric context) {
|
||||
EsMutexAcquire(&api.workMutex);
|
||||
|
||||
if (!api.workAvailable) {
|
||||
api.workAvailable = EsEventCreate(true /* autoReset */);
|
||||
EsThreadInformation thread = {};
|
||||
}
|
||||
|
||||
for (uintptr_t i = 0; i < EsSystemGetOptimalWorkQueueThreadCount(); i++) {
|
||||
EsThreadCreate(WorkThread, &thread, nullptr);
|
||||
EsHandleClose(thread.handle);
|
||||
}
|
||||
EsThreadInformation thread = {};
|
||||
|
||||
while (api.workThreads.Length() < EsSystemGetOptimalWorkQueueThreadCount()) {
|
||||
EsError error = EsThreadCreate(WorkThread, &thread, nullptr);
|
||||
if (error != ES_SUCCESS) return error;
|
||||
api.workThreads.Add(thread.handle);
|
||||
}
|
||||
|
||||
Work work = { callback, context };
|
||||
api.workQueue.Add(work);
|
||||
bool success = api.workQueue.Add(work);
|
||||
EsMutexRelease(&api.workMutex);
|
||||
EsEventSet(api.workAvailable);
|
||||
return success ? ES_SUCCESS : ES_ERROR_INSUFFICIENT_RESOURCES;
|
||||
}
|
||||
|
||||
#ifndef ENABLE_POSIX_SUBSYSTEM
|
||||
|
|
|
@ -1997,7 +1997,8 @@ function EsError EsThreadCreate(EsThreadEntryCallback entryFunction, EsThreadInf
|
|||
function EsObjectID EsThreadGetID(EsHandle thread);
|
||||
function void EsThreadTerminate(EsHandle thread);
|
||||
|
||||
function void EsWorkQueue(EsWorkCallback callback, EsGeneric context);
|
||||
function EsError EsWorkQueue(EsWorkCallback callback, EsGeneric context);
|
||||
function bool EsWorkIsExiting();
|
||||
|
||||
// Memory.
|
||||
|
||||
|
|
|
@ -996,6 +996,7 @@ extern "C" void InterruptHandler(InterruptContext *context) {
|
|||
|
||||
while (rbp && traceDepth < 32) {
|
||||
uint64_t value;
|
||||
if (!MMArchIsBufferInUserRange(rbp, 16)) break;
|
||||
if (!MMArchSafeCopy((uintptr_t) &value, rbp + 8, sizeof(uint64_t))) break;
|
||||
EsPrint("\t%d: %x\n", ++traceDepth, value);
|
||||
if (!value) break;
|
||||
|
|
|
@ -454,3 +454,4 @@ EsFontDatabaseLookupByName=452
|
|||
_EsWindowGetHandle=453
|
||||
_EsUISetFont=454
|
||||
EsWorkQueue=455
|
||||
EsWorkIsExiting=456
|
||||
|
|
Loading…
Reference in New Issue