From 805638ddd82fb40d8c3ce50afdfe68f57b94ffc3 Mon Sep 17 00:00:00 2001 From: ts-korhonen Date: Fri, 17 Dec 2021 22:15:21 +0200 Subject: [PATCH 1/2] Fix window resize not always working Change doresize to atomic_flag to prevent race condition --- src/86box.c | 8 ++++---- src/include/86box/plat.h | 6 +++++- src/unix/unix.c | 4 ++-- src/win/win.c | 6 +++--- src/win/win_specify_dim.c | 2 +- src/win/win_ui.c | 14 +++++++------- 6 files changed, 22 insertions(+), 18 deletions(-) diff --git a/src/86box.c b/src/86box.c index 045b3bd0a..adc60130d 100644 --- a/src/86box.c +++ b/src/86box.c @@ -28,6 +28,8 @@ #include #include #include +#include + #ifndef _WIN32 #include #endif @@ -97,7 +99,7 @@ /* Stuff that used to be globally declared in plat.h but is now extern there and declared here instead. */ int dopause; /* system is paused */ -int doresize; /* screen resize requested */ +atomic_flag doresize; /* screen resize requested */ volatile int is_quit; /* system exit requested */ uint64_t timer_freq; char emu_version[200]; /* version ID string */ @@ -1286,9 +1288,7 @@ set_screen_size(int x, int y) /* If the resolution has changed, let the main thread handle it. */ if ((owsx != scrnsz_x) || (owsy != scrnsz_y)) - doresize = 1; - else - doresize = 0; + atomic_flag_clear(&doresize); } diff --git a/src/include/86box/plat.h b/src/include/86box/plat.h index ca116a684..ecf8cb063 100644 --- a/src/include/86box/plat.h +++ b/src/include/86box/plat.h @@ -63,13 +63,17 @@ extern int strnicmp(const char* s1, const char* s2, size_t n); #ifdef __cplusplus +#include +#define atomic_flag std::atomic_flag extern "C" { +#else +#include #endif /* Global variables residing in the platform module. */ extern int dopause, /* system is paused */ - doresize, /* screen resize requested */ mouse_capture; /* mouse is captured in app */ +extern atomic_flag doresize; /* screen resize requested */ extern volatile int is_quit; /* system exit requested */ #ifdef MTR_ENABLED diff --git a/src/unix/unix.c b/src/unix/unix.c index 47a65944d..c583f7f50 100644 --- a/src/unix/unix.c +++ b/src/unix/unix.c @@ -18,6 +18,7 @@ #include #include #include +#include #include <86box/86box.h> #include <86box/keyboard.h> @@ -531,12 +532,11 @@ main_thread(void *param) SDL_Delay(1); /* If needed, handle a screen resize. */ - if (doresize && !video_fullscreen && !is_quit) { + if (!atomic_flag_test_and_set(&doresize) && !video_fullscreen && !is_quit) { if (vid_resize & 2) plat_resize(fixed_size_x, fixed_size_y); else plat_resize(scrnsz_x, scrnsz_y); - doresize = 0; } } diff --git a/src/win/win.c b/src/win/win.c index d2a5003ec..0f8b1f7f2 100644 --- a/src/win/win.c +++ b/src/win/win.c @@ -35,6 +35,7 @@ #include #include #include +#include #define HAVE_STDARG_H #include <86box/86box.h> #include <86box/config.h> @@ -550,12 +551,11 @@ main_thread(void *param) // Sleep(1); /* If needed, handle a screen resize. */ - if (doresize && !video_fullscreen && !is_quit) { + if (!atomic_flag_test_and_set(&doresize) && !video_fullscreen && !is_quit) { if (vid_resize & 2) plat_resize(fixed_size_x, fixed_size_y); else plat_resize(scrnsz_x, scrnsz_y); - doresize = 0; } } @@ -1162,7 +1162,7 @@ plat_setfullscreen(int on) video_fullscreen &= 1; video_force_resize_set(1); if (!(on & 1)) - doresize = 1; + atomic_flag_clear(&doresize); win_mouse_init(); diff --git a/src/win/win_specify_dim.c b/src/win/win_specify_dim.c index d4727c68b..96ae0403c 100644 --- a/src/win/win_specify_dim.c +++ b/src/win/win_specify_dim.c @@ -133,7 +133,7 @@ SpecifyDimensionsDialogProcedure(HWND hdlg, UINT message, WPARAM wParam, LPARAM scrnsz_x = fixed_size_x; scrnsz_y = fixed_size_y; - doresize = 1; + atomic_flag_clear(&doresize); GetWindowRect(hwndMain, &r); diff --git a/src/win/win_ui.c b/src/win/win_ui.c index b6a22fe50..42060377f 100644 --- a/src/win/win_ui.c +++ b/src/win/win_ui.c @@ -672,7 +672,7 @@ MainWindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) scrnsz_x = unscaled_size_x; scrnsz_y = unscaled_size_y; - doresize = 1; + atomic_flag_clear(&doresize); config_save(); break; @@ -771,7 +771,7 @@ MainWindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) reset_screen_size(); device_force_redraw(); video_force_resize_set(1); - doresize = 1; + atomic_flag_clear(&doresize); config_save(); break; @@ -786,7 +786,7 @@ MainWindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) case IDM_VID_HIDPI: dpi_scale = !dpi_scale; CheckMenuItem(hmenu, IDM_VID_HIDPI, dpi_scale ? MF_CHECKED : MF_UNCHECKED); - doresize = 1; + atomic_flag_clear(&doresize); config_save(); break; @@ -947,7 +947,7 @@ MainWindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) else ResizeWindowByClientArea(hwndMain, temp_x, temp_y + sbar_height); } else if (!user_resize) - doresize = 1; + atomic_flag_clear(&doresize); break; case WM_WINDOWPOSCHANGED: @@ -992,13 +992,13 @@ MainWindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) if (temp_x != scrnsz_x || temp_y != scrnsz_y) { scrnsz_x = temp_x; scrnsz_y = temp_y; - doresize = 1; + atomic_flag_clear(&doresize); } } else { if (rect.right != scrnsz_x || rect.bottom != scrnsz_y) { scrnsz_x = rect.right; scrnsz_y = rect.bottom; - doresize = 1; + atomic_flag_clear(&doresize); } } @@ -1160,7 +1160,7 @@ MainWindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) /* If window is not resizable, then tell the main thread to resize it, as sometimes, moves can mess up the window size. */ if (!vid_resize) - doresize = 1; + atomic_flag_clear(&doresize); break; } From 766f15d858756e25df456c421076faf02dfa7d0a Mon Sep 17 00:00:00 2001 From: ts-korhonen Date: Fri, 17 Dec 2021 22:26:21 +0200 Subject: [PATCH 2/2] Better c++ compatibility to the doresize change --- src/include/86box/plat.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/include/86box/plat.h b/src/include/86box/plat.h index ecf8cb063..75c32d087 100644 --- a/src/include/86box/plat.h +++ b/src/include/86box/plat.h @@ -64,16 +64,17 @@ extern int strnicmp(const char* s1, const char* s2, size_t n); #ifdef __cplusplus #include -#define atomic_flag std::atomic_flag +#define atomic_flag_t std::atomic_flag extern "C" { #else #include +#define atomic_flag_t atomic_flag #endif /* Global variables residing in the platform module. */ extern int dopause, /* system is paused */ mouse_capture; /* mouse is captured in app */ -extern atomic_flag doresize; /* screen resize requested */ +extern atomic_flag_t doresize; /* screen resize requested */ extern volatile int is_quit; /* system exit requested */ #ifdef MTR_ENABLED