This is an automated email from Gerrit. "Anatoly P <anatoly.parshint...@syntacore.com>" just uploaded a new patch set to Gerrit, which you can find at https://review.openocd.org/c/openocd/+/8932
-- gerrit commit 3f880b317973a9a41bed02f4ccb41ae38ed70ac6 Author: Parshintsev Anatoly <anatoly.parshint...@syntacore.com> Date: Thu May 22 18:30:23 2025 +0300 server: track asynchronous and synchronous shutdown requests separately (NFC) Change-Id: Ic34d6e90919d18616207fe38528ca4d190e9d12a Signed-off-by: Parshintsev Anatoly <anatoly.parshint...@syntacore.com> diff --git a/src/openocd.c b/src/openocd.c index 3fbece3955..4e0b678c96 100644 --- a/src/openocd.c +++ b/src/openocd.c @@ -312,9 +312,12 @@ static int openocd_thread(int argc, char *argv[], struct command_context *cmd_ct ret = server_loop(cmd_ctx); int last_signal = server_quit(); - if (last_signal != ERROR_OK) - return last_signal; + /* warning: here we return either a signal number of ERROR_OK / ERROR_FAIL + * status. This works, because ERROR_OK is zero an ERROR_FAIL is negative */ + assert(ERROR_FAIL < 0); + if (last_signal != 0) + return last_signal; if (ret != ERROR_OK) return ERROR_FAIL; return ERROR_OK; diff --git a/src/server/server.c b/src/server/server.c index c9499f9395..5bd122090b 100644 --- a/src/server/server.c +++ b/src/server/server.c @@ -37,17 +37,16 @@ static struct service *services; -enum shutdown_reason { - CONTINUE_MAIN_LOOP, /* stay in main event loop */ - SHUTDOWN_REQUESTED, /* set by shutdown command; exit the event loop and quit the debugger */ - SHUTDOWN_WITH_ERROR_CODE, /* set by shutdown command; quit with non-zero return code */ - SHUTDOWN_WITH_SIGNAL_CODE /* set by sig_handler; exec shutdown then exit with signal as return code */ -}; - -static volatile sig_atomic_t shutdown_openocd = CONTINUE_MAIN_LOOP; +/* this *flag* indicates that we have a pending shutdown request because of an + * asynchronous event such as signal or WM_QUIT in the message queue for + * windows */ +static volatile sig_atomic_t async_shutdown_requested; /* store received signal to exit application by killing ourselves */ static volatile sig_atomic_t last_signal; +bool sync_shutdown_requested; +bool sync_shutdown_reports_error; + /* set the polling period to 100ms */ static int polling_period = 100; @@ -439,7 +438,7 @@ int server_loop(struct command_context *command_context) LOG_ERROR("couldn't set SIGPIPE to SIG_IGN"); #endif - while (shutdown_openocd == CONTINUE_MAIN_LOOP) { + while (!openocd_is_shutdown_pending()) { /* monitor sockets for activity */ fd_max = 0; FD_ZERO(&read_fds); @@ -569,7 +568,7 @@ int server_loop(struct command_context *command_context) service->type == CONNECTION_STDINOUT) { /* if connection uses a pipe then * shutdown openocd on error */ - shutdown_openocd = SHUTDOWN_REQUESTED; + sync_shutdown_requested = true; } remove_connection(service, c); LOG_INFO("dropped '%s' connection", @@ -587,23 +586,24 @@ int server_loop(struct command_context *command_context) MSG msg; while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) { if (msg.message == WM_QUIT) - shutdown_openocd = SHUTDOWN_WITH_SIGNAL_CODE; + async_shutdown_requested = true; } #endif } /* when quit for signal or CTRL-C, run (eventually user implemented) "shutdown" */ - if (shutdown_openocd == SHUTDOWN_WITH_SIGNAL_CODE) + if (async_shutdown_requested) command_run_line(command_context, "shutdown"); - return shutdown_openocd == SHUTDOWN_WITH_ERROR_CODE ? ERROR_FAIL : ERROR_OK; + return sync_shutdown_reports_error ? ERROR_FAIL : ERROR_OK; } static void sig_handler(int sig) { /* store only first signal that hits us */ - if (shutdown_openocd == CONTINUE_MAIN_LOOP) { - shutdown_openocd = SHUTDOWN_WITH_SIGNAL_CODE; + if (!async_shutdown_requested) { + assert(sig >= SIG_ATOMIC_MIN && sig <= SIG_ATOMIC_MAX); + async_shutdown_requested = true; last_signal = sig; LOG_DEBUG("Terminating on Signal %d", sig); } else @@ -614,7 +614,7 @@ static void sig_handler(int sig) #ifdef _WIN32 BOOL WINAPI control_handler(DWORD ctrl_type) { - shutdown_openocd = SHUTDOWN_WITH_SIGNAL_CODE; + async_shutdown_requested = true; return TRUE; } #else @@ -703,7 +703,7 @@ int server_quit(void) #ifdef _WIN32 SetConsoleCtrlHandler(control_handler, FALSE); - return ERROR_OK; + return 0; #endif /* return signal number so we can kill ourselves */ @@ -751,7 +751,7 @@ int connection_read(struct connection *connection, void *data, int len) bool openocd_is_shutdown_pending(void) { - return shutdown_openocd != CONTINUE_MAIN_LOOP; + return sync_shutdown_requested || async_shutdown_requested; } /* tell the server we want to shut down */ @@ -759,13 +759,13 @@ COMMAND_HANDLER(handle_shutdown_command) { LOG_USER("shutdown command invoked"); - shutdown_openocd = SHUTDOWN_REQUESTED; + sync_shutdown_requested = true; command_run_line(CMD_CTX, "_run_pre_shutdown_commands"); if (CMD_ARGC == 1) { if (!strcmp(CMD_ARGV[0], "error")) { - shutdown_openocd = SHUTDOWN_WITH_ERROR_CODE; + sync_shutdown_reports_error = true; return ERROR_FAIL; } } --