From 805f5de8520375af7b7634c08e2bdc9c9fbe0bfe Mon Sep 17 00:00:00 2001 From: Krzosa Karol Date: Fri, 30 Jan 2026 21:44:28 +0100 Subject: [PATCH] Coroutine API rename --- src/basic/basic_alloc.cpp | 1 + src/basic/basic_head.h | 1 + src/basic/basic_os.cpp | 1 + src/external/minicoro.h | 1 + src/test/tests.cpp | 8 +-- src/text_editor/coroutines.cpp | 49 +++++++++++-------- src/text_editor/globals.cpp | 10 +++- src/text_editor/plugin_file_commands.cpp | 11 +++-- src/text_editor/plugin_load_vcvars.cpp | 8 +-- src/text_editor/plugin_project_management.cpp | 13 ++--- src/text_editor/plugin_remedybg.cpp | 7 +-- .../plugin_search_open_buffers.cpp | 13 ++--- src/text_editor/text_editor.cpp | 6 +-- src/text_editor/text_editor.h | 6 +-- src/text_editor/ui.cpp | 9 ++-- 15 files changed, 84 insertions(+), 60 deletions(-) diff --git a/src/basic/basic_alloc.cpp b/src/basic/basic_alloc.cpp index 744f2b5..c215496 100644 --- a/src/basic/basic_alloc.cpp +++ b/src/basic/basic_alloc.cpp @@ -20,6 +20,7 @@ #define WIN32_LEAN_AND_MEAN #endif #include +#undef Yield API void *VReserve(size_t size) { void *result = (uint8_t *)VirtualAlloc(0, size, MEM_RESERVE, PAGE_READWRITE); diff --git a/src/basic/basic_head.h b/src/basic/basic_head.h index 46d9a1c..19bec0d 100644 --- a/src/basic/basic_head.h +++ b/src/basic/basic_head.h @@ -93,6 +93,7 @@ #define WIN32_LEAN_AND_MEAN #endif #include +#undef Yield #define BREAK() if (IsDebuggerPresent()) {__debugbreak();} #elif OS_LINUX #define BREAK() raise(SIGTRAP) diff --git a/src/basic/basic_os.cpp b/src/basic/basic_os.cpp index f10e428..a031d9e 100644 --- a/src/basic/basic_os.cpp +++ b/src/basic/basic_os.cpp @@ -462,6 +462,7 @@ API void CloseStdin(Process *process) { #define WIN32_LEAN_AND_MEAN #endif #include +#undef Yield #include #include diff --git a/src/external/minicoro.h b/src/external/minicoro.h index f770943..bc8fd7e 100644 --- a/src/external/minicoro.h +++ b/src/external/minicoro.h @@ -476,6 +476,7 @@ MCO_API const char *mco_result_description(mco_result res); /* Get the descripti #define WIN32_LEAN_AND_MEAN #endif #include + #undef Yield #endif #ifndef MCO_NO_DEFAULT_ALLOCATOR diff --git a/src/test/tests.cpp b/src/test/tests.cpp index 99f3d5a..fc6aa06 100644 --- a/src/test/tests.cpp +++ b/src/test/tests.cpp @@ -21,7 +21,7 @@ void AddText(String string) { void Wait(mco_coro *co) { Add(&EventPlayback, {EVENT_KIND_INVALID}); - for (Event *event = CoYield(co); event->kind != EVENT_KIND_INVALID; event = CoYield(co)) { + for (Event *event = Yield(co); event->kind != EVENT_KIND_INVALID; event = Yield(co)) { } } @@ -153,8 +153,8 @@ void InitTests() { WaitForEvents = false; TestDir = Format(TestArena, "%S/test_env", GetExeDir(TestArena)); - CoRemove("Test"); - CoData *data = CoAdd(Test); + RemoveCoroutine("Test"); + CCtx *data = AddCoroutine(Test); data->dont_wait_until_resolved = true; - CoResume(data); + ResumeCoroutine(data); } diff --git a/src/text_editor/coroutines.cpp b/src/text_editor/coroutines.cpp index 7b81ace..172d87e 100644 --- a/src/text_editor/coroutines.cpp +++ b/src/text_editor/coroutines.cpp @@ -1,41 +1,47 @@ -typedef void CoroutineProc(mco_coro *co); -CoData *CoCurr = NULL; +typedef void CoroutineFunction(mco_coro *co); +CCtx *_CoroutineContext = NULL; -void CoDestroy(CoData *n) { +CCtx *GetCoroutineContext() { + Assert(_CoroutineContext); + return _CoroutineContext; +} + +void DestroyCoroutine(CCtx *n) { mco_destroy(n->co); Release(&n->arena); } -void CoRemove(String name) { +void RemoveCoroutine(String name) { IterRemove(ActiveCoroutines) { IterRemovePrepare(ActiveCoroutines); if (it.name == name) { - CoDestroy(&it); + DestroyCoroutine(&it); remove_item = true; } } } -#define CoAdd(x) CoAddEx(x, #x) -CoData *CoAddEx(CoroutineProc *proc, String name) { - mco_desc desc = mco_desc_init(proc, 0); +CCtx CreateCoroutine(CoroutineFunction *func, String name) { + mco_desc desc = mco_desc_init(func, 0); mco_coro *coro = NULL; mco_result ok = mco_create(&coro, &desc); - if (ok != MCO_SUCCESS) { - ReportWarningf("failed to create coroutine %d", ok); - return NULL; - } + assert(ok == MCO_SUCCESS); + return {coro, name}; +} - Add(&ActiveCoroutines, {coro, name}); +#define AddCoroutine(x) AddCoroutineEx(x, #x) +CCtx *AddCoroutineEx(CoroutineFunction *func, String name) { + CCtx coroutine = CreateCoroutine(func, name); + Add(&ActiveCoroutines, coroutine); return GetLast(ActiveCoroutines); } -void CoResume(CoData *dat) { - CoData *prev_curr = CoCurr; - CoCurr = dat; +void ResumeCoroutine(CCtx *dat) { + CCtx *prev_curr = _CoroutineContext; + _CoroutineContext = dat; mco_result ok = mco_resume(dat->co); Assert(ok == MCO_SUCCESS); - CoCurr = prev_curr; + _CoroutineContext = prev_curr; } void UpdateCoroutines(Event *event) { @@ -48,17 +54,18 @@ void UpdateCoroutines(Event *event) { mco_state status = mco_status(it.co); if (status == MCO_DEAD) { - CoDestroy(&it); + DestroyCoroutine(&it); remove_item = true; } else { mco_push(it.co, &event, sizeof(Event *)); - CoCurr = ⁢ + _CoroutineContext = ⁢ mco_result ok = mco_resume(it.co); if (ok != MCO_SUCCESS) { ReportWarningf("failed to resume coroutine %d", ok); - CoDestroy(&it); + DestroyCoroutine(&it); remove_item = true; } + _CoroutineContext = NULL; } } @@ -79,7 +86,7 @@ void UpdateCoroutines(Event *event) { } } -Event *CoYield(mco_coro *co) { +Event *Yield(mco_coro *co) { mco_result ok = mco_yield(co); Assert(ok == MCO_SUCCESS); diff --git a/src/text_editor/globals.cpp b/src/text_editor/globals.cpp index 2a06504..4ad3f33 100644 --- a/src/text_editor/globals.cpp +++ b/src/text_editor/globals.cpp @@ -110,8 +110,14 @@ Array Variables; Array ActiveProcesses = {}; Array ProcessEnviroment = {}; -struct CoData { mco_coro *co; String name; BlockArena arena; bool dont_wait_until_resolved; void *user_ctx; }; -Array ActiveCoroutines; +struct CCtx { + mco_coro *co; + String name; + BlockArena arena; + bool dont_wait_until_resolved; + void *user_ctx; +}; +Array ActiveCoroutines; Color GruvboxDark0Hard = {0x1d, 0x20, 0x21, 0xff}; Color GruvboxDark0 = {0x28, 0x28, 0x28, 0xff}; diff --git a/src/text_editor/plugin_file_commands.cpp b/src/text_editor/plugin_file_commands.cpp index 0f07522..cd2d1b0 100644 --- a/src/text_editor/plugin_file_commands.cpp +++ b/src/text_editor/plugin_file_commands.cpp @@ -38,6 +38,7 @@ void CMD_Reopen() { } RegisterCommand(CMD_Reopen, "", "Reads again from disk the current buffer"); void CO_Rename(mco_coro *co) { + CCtx *ctx = GetCoroutineContext(); BSet main = GetBSet(PrimaryWindowID); Buffer *original_buffer = main.buffer; JumpTempBuffer(&main); @@ -60,11 +61,12 @@ void CO_Rename(mco_coro *co) { return; } String16 string16 = GetString(main.buffer, {a.range.max + 1, b.range.max}); - String string = ToString(CoCurr->arena, string16); + String string = ToString(ctx->arena, string16); original_buffer->name = Intern(&GlobalInternTable, string); } RegisterCoroutineCommand(CO_Rename, "", "Opens a UI asking for a new name of a buffer open in the last active primary window"); void CO_Close(mco_coro *co) { + CCtx *ctx = GetCoroutineContext(); BSet main = GetBSet(PrimaryWindowID); if (main.buffer->special || main.buffer->temp) { Close(main.view->id); @@ -92,7 +94,7 @@ void CO_Close(mco_coro *co) { return; } - String question = Format(CoCurr->arena, "Do you want to save [%S] before closing?", main.buffer->name); + String question = Format(ctx->arena, "Do you want to save [%S] before closing?", main.buffer->name); UIAction ui_action = QueryUserYesNoCancel(co, main, question); if (ui_action == UIAction_Yes) { SaveBuffer(main.buffer); @@ -116,9 +118,10 @@ void CO_CloseAll(mco_coro *co) { } RegisterCoroutineCommand(CO_CloseAll, "", "Ask user which files to save and close all open normal views and buffers"); void CO_ReplaceAll(mco_coro *co) { + CCtx *ctx = GetCoroutineContext(); BSet main = GetBSet(PrimaryWindowID); String16 string = FetchLoadWord(main.view); - String string8 = ToString(CoCurr->arena, string); + String string8 = ToString(ctx->arena, string); String16 needle = {}; String16 replace = {}; @@ -144,7 +147,7 @@ void CO_ReplaceAll(mco_coro *co) { { JumpTempBuffer(&main); NextActiveWindowID = main.window->id; - RawAppendf(main.buffer, ":Submit (enter) :Cancel (escape)\nString to replace with::%S", ToString(CoCurr->arena, needle)); + RawAppendf(main.buffer, ":Submit (enter) :Cancel (escape)\nString to replace with::%S", ToString(ctx->arena, needle)); Caret field_seek = BaseFindNext(main.buffer, u"with::", MakeCaret(0), SeekFlag_None); main.view->carets[0] = MakeCaret(main.buffer->len, field_seek.range.max); diff --git a/src/text_editor/plugin_load_vcvars.cpp b/src/text_editor/plugin_load_vcvars.cpp index 3585bf4..0ed4211 100644 --- a/src/text_editor/plugin_load_vcvars.cpp +++ b/src/text_editor/plugin_load_vcvars.cpp @@ -11,7 +11,7 @@ void Windows_SetupVCVarsall(mco_coro *co) { if (!ProcessIsActive(view->id)) { break; } - CoYield(co); + Yield(co); } Scratch scratch; @@ -30,8 +30,8 @@ void Windows_SetupVCVarsall(mco_coro *co) { void LoadVCVars() { - CoRemove("Windows_SetupVCVarsall"); - CoData *co_data = CoAdd(Windows_SetupVCVarsall); + RemoveCoroutine("Windows_SetupVCVarsall"); + CCtx *co_data = AddCoroutine(Windows_SetupVCVarsall); co_data->dont_wait_until_resolved = true; - CoResume(co_data); + ResumeCoroutine(co_data); } \ No newline at end of file diff --git a/src/text_editor/plugin_project_management.cpp b/src/text_editor/plugin_project_management.cpp index 6b4a55e..5ad1457 100644 --- a/src/text_editor/plugin_project_management.cpp +++ b/src/text_editor/plugin_project_management.cpp @@ -10,12 +10,13 @@ void SetProjectDirectory(String dir) { } void CO_OpenCode(mco_coro *co) { - Array patterns = SplitWhitespace(CoCurr->arena, OpenCodePatterns); - Array exclude_patterns = SplitWhitespace(CoCurr->arena, OpenCodeExcludePatterns); - Array dirs = {CoCurr->arena}; - Add(&dirs, Copy(CoCurr->arena, ProjectDirectory)); + CCtx *ctx = GetCoroutineContext(); + Array patterns = SplitWhitespace(ctx->arena, OpenCodePatterns); + Array exclude_patterns = SplitWhitespace(ctx->arena, OpenCodeExcludePatterns); + Array dirs = {ctx->arena}; + Add(&dirs, Copy(ctx->arena, ProjectDirectory)); for (int diri = 0; diri < dirs.len; diri += 1) { - for (FileIter it = IterateFiles(CoCurr->arena, dirs[diri]); IsValid(it); Advance(&it)) { + for (FileIter it = IterateFiles(ctx->arena, dirs[diri]); IsValid(it); Advance(&it)) { bool should_open = true; if (!it.is_directory) { should_open = false; @@ -45,7 +46,7 @@ void CO_OpenCode(mco_coro *co) { BufferOpenFile(it.absolute_path); } - CoYield(co); + Yield(co); } } } RegisterCoroutineCommand( diff --git a/src/text_editor/plugin_remedybg.cpp b/src/text_editor/plugin_remedybg.cpp index 7062454..3df803a 100644 --- a/src/text_editor/plugin_remedybg.cpp +++ b/src/text_editor/plugin_remedybg.cpp @@ -2098,6 +2098,7 @@ uint8_t reply_buf[REPLY_BUF_SIZE]; ClientContext RDBG_Ctx; bool RDBG_InitConnection(mco_coro *co, bool create_session = true) { + CCtx *ctx = GetCoroutineContext(); ReportConsolef("Remedybg: InitConnection"); enum rdbg_CommandResult res; if (RDBG_Ctx.command_pipe_handle != NULL) { @@ -2112,7 +2113,7 @@ bool RDBG_InitConnection(mco_coro *co, bool create_session = true) { if (create_session) { if (BinaryUnderDebug.len) { Window *window = GetWindow(PrimaryWindowID); - ResolvedOpen res = ResolveOpen(CoCurr->arena, window, BinaryUnderDebug, ResolveOpenMeta_DontError | ResolveOpenMeta_DontExec); + ResolvedOpen res = ResolveOpen(ctx->arena, window, BinaryUnderDebug, ResolveOpenMeta_DontError | ResolveOpenMeta_DontExec); if (res.kind == OpenKind_Goto) { file = Intern(&GlobalInternTable, res.path); } @@ -2133,8 +2134,8 @@ bool RDBG_InitConnection(mco_coro *co, bool create_session = true) { } } - String session_name = Format(CoCurr->arena, "te%llu", GetTimeNanos()); - String remedy_string = Format(CoCurr->arena, "%S --servername %S", RemedyBGPath, session_name); + String session_name = Format(ctx->arena, "te%llu", GetTimeNanos()); + String remedy_string = Format(ctx->arena, "%S --servername %S", RemedyBGPath, session_name); ReportConsolef("Remedybg: %S", remedy_string); Exec(LogView->id, true, remedy_string, GetPrimaryDirectory()); MemoryZero(&RDBG_Ctx, sizeof(RDBG_Ctx)); diff --git a/src/text_editor/plugin_search_open_buffers.cpp b/src/text_editor/plugin_search_open_buffers.cpp index 89d661d..f2630c6 100644 --- a/src/text_editor/plugin_search_open_buffers.cpp +++ b/src/text_editor/plugin_search_open_buffers.cpp @@ -4,9 +4,10 @@ struct SearchOpenBuffersParams { }; void Coro_SearchOpenBuffers(mco_coro *co) { - SearchOpenBuffersParams *param = (SearchOpenBuffersParams *)CoCurr->user_ctx; + CCtx *ctx = GetCoroutineContext(); + SearchOpenBuffersParams *param = (SearchOpenBuffersParams *)ctx->user_ctx; - Array buffers = {CoCurr->arena}; + Array buffers = {ctx->arena}; For (Buffers) { Add(&buffers, it->id); } @@ -36,7 +37,7 @@ void Coro_SearchOpenBuffers(mco_coro *co) { Appendf(out_view, "%S ||> %S:%lld:%lld\n", line_string8, it->name, (long long)line + 1, (long long)column + 1); } } - CoYield(co); + Yield(co); } } @@ -55,14 +56,14 @@ void UpdateSearchOpenBuffersView() { Replace(active.view, line_string); Append(active.view, "\n", false); - CoRemove("Coro_SearchOpenBuffers"); - CoData *dat = CoAdd(Coro_SearchOpenBuffers); + RemoveCoroutine("Coro_SearchOpenBuffers"); + CCtx *dat = AddCoroutine(Coro_SearchOpenBuffers); SearchOpenBuffersParams *param = AllocType(dat->arena, SearchOpenBuffersParams); param->needle = Copy16(dat->arena, line_string); param->view = active.view->id; dat->user_ctx = param; dat->dont_wait_until_resolved = true; - CoResume(dat); + ResumeCoroutine(dat); active.view->carets[0] = caret; } diff --git a/src/text_editor/text_editor.cpp b/src/text_editor/text_editor.cpp index 2f604f0..1483b6a 100644 --- a/src/text_editor/text_editor.cpp +++ b/src/text_editor/text_editor.cpp @@ -175,9 +175,9 @@ void ShowQuitAppUI(mco_coro *co) { } void CMD_Quit() { - CoRemove("ShowQuitAppUI"); - CoData *data = CoAdd(ShowQuitAppUI); - CoResume(data); + RemoveCoroutine("ShowQuitAppUI"); + CCtx *data = AddCoroutine(ShowQuitAppUI); + ResumeCoroutine(data); } RegisterCommand(CMD_Quit, "", "Ask user which files he would like to save and exit"); void OnCommand(Event event) { diff --git a/src/text_editor/text_editor.h b/src/text_editor/text_editor.h index 2ee34ef..c95a1c5 100644 --- a/src/text_editor/text_editor.h +++ b/src/text_editor/text_editor.h @@ -293,10 +293,10 @@ struct Register_Command { }; #define RegisterCommand(name, binding, docs) Register_Command RC__##name(&GlobalCommands, name, #name, binding, docs) #define RegisterCoroutineCommand(name, binding, docs, ...) void CMD_##name() {\ - CoRemove(#name);\ - CoData *data = CoAdd(name);\ + RemoveCoroutine(#name);\ + CCtx *data = AddCoroutine(name);\ __VA_ARGS__\ - CoResume(data);\ + ResumeCoroutine(data);\ }\ Register_Command RC__##name(&GlobalCommands, CMD_##name, #name, binding, docs) diff --git a/src/text_editor/ui.cpp b/src/text_editor/ui.cpp index 222f082..eaa8bcc 100644 --- a/src/text_editor/ui.cpp +++ b/src/text_editor/ui.cpp @@ -35,7 +35,7 @@ UIAction WaitForUIAction(mco_coro *co, BSet main) { break; } - CoYield(co); + Yield(co); } Close(main.buffer->id); return result; @@ -118,8 +118,9 @@ String16 QueryUserString(mco_coro *co, String ask) { // 2. Are pointers and globals correct over time? Or might they get deleted etc. // 3. Imagine a scenario where the coroutine gets deleted before completion, will the memory leak? UIAction ShowCloseAllUI(mco_coro *co) { + CCtx *ctx = GetCoroutineContext(); BSet main = GetBSet(PrimaryWindowID); - Array buffers = {CoCurr->arena}; + Array buffers = {ctx->arena}; For (Buffers) Add(&buffers, it->id); ForItem (id, buffers) { Buffer *it = GetBuffer(id, NULL); @@ -130,7 +131,7 @@ UIAction ShowCloseAllUI(mco_coro *co) { continue; } - String question = Format(CoCurr->arena, "Do you want to save [%S] before closing?", it->name); + String question = Format(ctx->arena, "Do you want to save [%S] before closing?", it->name); UIAction ui_action = QueryUserYesNoCancel(co, main, question); it = GetBuffer(id, NULL); if (it && ui_action == UIAction_Yes) { @@ -167,7 +168,7 @@ String QueryUserFile(mco_coro *co) { break; } - CoYield(co); + Yield(co); } window->active_view = original_view; return window->ui_query_file;