diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 53f5c29..8a92754 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,6 +1,7 @@ add_library(src_lib STATIC gameresource.c hankaku.c + msgqueue.c utfsjis.c ) target_compile_options(src_lib PRIVATE -Wno-pointer-sign -Wall) @@ -108,9 +109,11 @@ if (EMSCRIPTEN) elseif (ANDROID) + target_link_libraries(src_lib PRIVATE SDL2) target_link_libraries(xsystem35 PRIVATE SDL2 SDL2_ttf SDL2_mixer ${ndk_zlib} ${ndk_log}) else() # non-emscripten, non-android + target_link_libraries(src_lib PRIVATE PkgConfig::SDL2) target_link_libraries(xsystem35 PRIVATE m ZLIB::ZLIB) target_link_libraries(xsystem35 PRIVATE PkgConfig::SDL2) target_link_libraries(xsystem35 PRIVATE PkgConfig::SDL2TTF) diff --git a/src/debugger_dap.c b/src/debugger_dap.c index c2c14c5..4cb03e3 100644 --- a/src/debugger_dap.c +++ b/src/debugger_dap.c @@ -20,7 +20,6 @@ #include #include #include -#include #include #ifdef _WIN32 #include @@ -31,6 +30,7 @@ #include "debugger.h" #include "debugger_private.h" #include "debug_symbol.h" +#include "msgqueue.h" #include "system.h" #include "nact.h" #include "variable.h" @@ -49,6 +49,7 @@ static enum { } init_state = WAITING_LAUNCH; static char *src_dir; +static struct msgq *queue; cJSON *create_source(const char *name) { cJSON *source = cJSON_CreateObject(); @@ -516,55 +517,6 @@ static boolean handle_message(char *msg) { return continue_repl; } -struct cmdq_elem { - char *cmd; - struct cmdq_elem *next; -}; - -struct { - SDL_mutex *mutex; - SDL_cond *cond_nonempty; - struct cmdq_elem *head; - struct cmdq_elem *last; -} cmd_queue; - -static boolean cmdq_isempty(void) { - return !cmd_queue.head; -} - -static void cmdq_enqueue(char *cmd) { - struct cmdq_elem *e = malloc(sizeof(struct cmdq_elem)); - e->cmd = cmd; - e->next = NULL; - - SDL_LockMutex(cmd_queue.mutex); - if (!cmd_queue.head) { - cmd_queue.head = cmd_queue.last = e; - } else { - cmd_queue.last->next = e; - cmd_queue.last = e; - } - SDL_UnlockMutex(cmd_queue.mutex); - SDL_CondSignal(cmd_queue.cond_nonempty); -} - -static char *cmdq_dequeue(void) { - SDL_LockMutex(cmd_queue.mutex); - while (!cmd_queue.head) - SDL_CondWait(cmd_queue.cond_nonempty, cmd_queue.mutex); - - struct cmdq_elem *e = cmd_queue.head; - cmd_queue.head = e->next; - if (!e->next) - cmd_queue.last = NULL; - - SDL_UnlockMutex(cmd_queue.mutex); - - char *cmd = e->cmd; - free(e); - return cmd; -} - static int read_command_thread(void *data) { int content_length = -1; char header[512]; @@ -578,19 +530,18 @@ static int read_command_thread(void *data) { } char *buf = malloc(content_length); fread(buf, content_length, 1, stdin); - cmdq_enqueue(buf); + msgq_enqueue(queue, buf); content_length = -1; } else { fprintf(stderr, "Unknown Debug Adapter Protocol header: %s", header); } } - cmdq_enqueue(NULL); // EOF + msgq_enqueue(queue, NULL); // EOF return 0; } static void dbg_dap_init(const char *symbols_path) { - cmd_queue.mutex = SDL_CreateMutex(); - cmd_queue.cond_nonempty = SDL_CreateCond(); + queue = msgq_new(); #ifdef _WIN32 _setmode(_fileno(stdin), _O_BINARY); @@ -602,7 +553,7 @@ static void dbg_dap_init(const char *symbols_path) { symbols = dsym_load(symbols_path); while (init_state != INITIALIZED) { - char *msg = cmdq_dequeue(); + char *msg = msgq_dequeue(queue); if (!msg) break; handle_message(msg); @@ -619,7 +570,7 @@ static void dbg_dap_repl(void) { boolean continue_repl = true; while (continue_repl) { - char *msg = cmdq_dequeue(); + char *msg = msgq_dequeue(queue); if (!msg) break; continue_repl = handle_message(msg); @@ -627,8 +578,8 @@ static void dbg_dap_repl(void) { } static void dbg_dap_onsleep(void) { - while (!cmdq_isempty()) { - char *msg = cmdq_dequeue(); + while (!msgq_isempty(queue)) { + char *msg = msgq_dequeue(queue); if (!msg) break; handle_message(msg); diff --git a/src/msgqueue.c b/src/msgqueue.c new file mode 100644 index 0000000..f6ad846 --- /dev/null +++ b/src/msgqueue.c @@ -0,0 +1,72 @@ +/* + * Copyright (C) 2021 kichikuou + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#include +#include "msgqueue.h" + +struct msgq_elem { + void *msg; + struct msgq_elem *next; +}; + +struct msgq *msgq_new(void) { + struct msgq *q = calloc(1, sizeof(struct msgq)); + q->mutex = SDL_CreateMutex(); + q->cond_nonempty = SDL_CreateCond(); + return q; +} + +void msgq_free(struct msgq *q) { + SDL_DestroyMutex(q->mutex); + SDL_DestroyCond(q->cond_nonempty); + free(q); +} + +void msgq_enqueue(struct msgq *q, void *msg) { + struct msgq_elem *e = malloc(sizeof(struct msgq_elem)); + e->msg = msg; + e->next = NULL; + + SDL_LockMutex(q->mutex); + if (!q->head) { + q->head = q->last = e; + } else { + q->last->next = e; + q->last = e; + } + SDL_UnlockMutex(q->mutex); + SDL_CondSignal(q->cond_nonempty); +} + +void *msgq_dequeue(struct msgq *q) { + SDL_LockMutex(q->mutex); + while (!q->head) + SDL_CondWait(q->cond_nonempty, q->mutex); + + struct msgq_elem *e = q->head; + q->head = e->next; + if (!e->next) + q->last = NULL; + + SDL_UnlockMutex(q->mutex); + + void *msg = e->msg; + free(e); + return msg; +} diff --git a/src/msgqueue.h b/src/msgqueue.h new file mode 100644 index 0000000..2f121e3 --- /dev/null +++ b/src/msgqueue.h @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2021 kichikuou + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#ifndef __MSGQUEUE_H__ +#define __MSGQUEUE_H__ + +#include +#include + +struct msgq_elem; + +struct msgq { + SDL_mutex *mutex; + SDL_cond *cond_nonempty; + struct msgq_elem *head; + struct msgq_elem *last; +}; + +static inline bool msgq_isempty(struct msgq *q) { + return !q->head; +} + +struct msgq *msgq_new(void); +void msgq_free(struct msgq *q); +void msgq_enqueue(struct msgq *q, void *msg); +void *msgq_dequeue(struct msgq *q); + +#endif // __MSGQUEUE_H__