[RAPPS] Protect database update with a mutex (#7006)
authorWhindmar Saksit <whindsaks@proton.me>
Sat, 11 Jan 2025 18:52:07 +0000 (19:52 +0100)
committerGitHub <noreply@github.com>
Sat, 11 Jan 2025 18:52:07 +0000 (19:52 +0100)
base/applications/rapps/gui.cpp
base/applications/rapps/include/misc.h
base/applications/rapps/include/rapps.h
base/applications/rapps/unattended.cpp
base/applications/rapps/winmain.cpp

index 70cedb2..5e8dc85 100644 (file)
@@ -304,6 +304,7 @@ CMainWindow::CheckAvailable()
 {
     if (m_Db->GetAvailableCount() == 0)
     {
+        CUpdateDatabaseMutex lock;
         m_Db->RemoveCached();
         m_Db->UpdateAvailable();
     }
@@ -591,9 +592,12 @@ CMainWindow::OnCommand(WPARAM wParam, LPARAM lParam)
                 break;
 
             case ID_RESETDB:
+            {
+                CUpdateDatabaseMutex lock;
                 m_Db->RemoveCached();
                 UpdateApplicationsList(SelectedEnumType, bReload);
                 break;
+            }
 
             case ID_HELP:
                 MessageBoxW(L"Help not implemented yet", NULL, MB_OK);
index 4617050..f2f3ea7 100644 (file)
@@ -117,3 +117,32 @@ GetProgramFilesPath(CStringW &Path, BOOL PerUser, HWND hwnd = NULL);
 template <class T> class CLocalPtr : public CHeapPtr<T, CLocalAllocator>
 {
 };
+
+struct CScopedMutex
+{
+    HANDLE m_hMutex;
+
+    CScopedMutex(LPCWSTR Name, UINT Timeout = INFINITE, BOOL InitialOwner = FALSE)
+    {
+        m_hMutex = CreateMutexW(NULL, InitialOwner, Name);
+        if (m_hMutex && !InitialOwner)
+        {
+            DWORD wait = WaitForSingleObject(m_hMutex, Timeout);
+            if (wait != WAIT_OBJECT_0 && wait != WAIT_ABANDONED)
+            {
+                CloseHandle(m_hMutex);
+                m_hMutex = NULL;
+            }
+        }
+    }
+    ~CScopedMutex()
+    {
+        if (m_hMutex)
+        {
+            ReleaseMutex(m_hMutex);
+            CloseHandle(m_hMutex);
+        }
+    }
+
+    bool Acquired() const { return m_hMutex != NULL; }
+};
index 49bb469..c03a06d 100644 (file)
@@ -17,4 +17,13 @@ extern LONG g_Busy;
 
 #define WM_NOTIFY_OPERATIONCOMPLETED (WM_APP + 0)
 
+#define MAINWINDOWCLASSNAME L"ROSAPPMGR2"
+#define MAINWINDOWMUTEX szWindowClass
+#define UPDATEDBMUTEX ( MAINWINDOWCLASSNAME L":UpDB" )
+
+struct CUpdateDatabaseMutex : public CScopedMutex
+{
+    CUpdateDatabaseMutex() : CScopedMutex(UPDATEDBMUTEX, 1000 * 60 * 10, FALSE) { };
+};
+
 #endif /* _RAPPS_H */
index 12ffe79..4967f25 100644 (file)
@@ -338,6 +338,7 @@ ParseCmdAndExecute(LPWSTR lpCmdLine, BOOL bIsFirstLaunch, int nCmdShow)
     BOOL bAppwizMode = (argc > 1 && MatchCmdOption(argv[1], CMD_KEY_APPWIZ));
     if (!bAppwizMode)
     {
+        CUpdateDatabaseMutex lock;
         if (SettingsInfo.bUpdateAtStart || bIsFirstLaunch)
             db.RemoveCached();
 
@@ -350,7 +351,7 @@ ParseCmdAndExecute(LPWSTR lpCmdLine, BOOL bIsFirstLaunch, int nCmdShow)
     {
         // Check whether the RAPPS MainWindow is already launched in another process
         CStringW szWindowText(MAKEINTRESOURCEW(bAppwizMode ? IDS_APPWIZ_TITLE : IDS_APPTITLE));
-        LPCWSTR pszMutex = bAppwizMode ? L"RAPPWIZ" : szWindowClass;
+        LPCWSTR pszMutex = bAppwizMode ? L"RAPPWIZ" : MAINWINDOWMUTEX;
 
         HANDLE hMutex = CreateMutexW(NULL, FALSE, pszMutex);
         if ((!hMutex) || (GetLastError() == ERROR_ALREADY_EXISTS))
index 2c5c06a..70ce317 100644 (file)
@@ -13,7 +13,7 @@
 #include <gdiplus.h>
 #include <conutils.h>
 
-LPCWSTR szWindowClass = L"ROSAPPMGR2";
+LPCWSTR szWindowClass = MAINWINDOWCLASSNAME;
 LONG g_Busy = 0;
 
 HWND hMainWnd;