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