OSDN Git Service

Reduce application startup time by reducing the number of open-close of HKEY
authorTakashi Sawanaka <sdottaka@users.sourceforge.net>
Fri, 1 Feb 2019 15:32:14 +0000 (00:32 +0900)
committerTakashi Sawanaka <sdottaka@users.sourceforge.net>
Fri, 1 Feb 2019 15:32:14 +0000 (00:32 +0900)
(Anti-virus software makes creating the handle of registry key slow)

Src/Common/RegOptionsMgr.cpp
Src/Common/RegOptionsMgr.h
Src/Merge.cpp
Src/Merge.h

index 6c02156..5b89901 100644 (file)
@@ -199,13 +199,22 @@ int CRegOptionsMgr::InitOption(const String& name, const varprop::VariantValue&
 
        // Open key. Create new key if it does not exist.
        HKEY hKey = nullptr;
-       DWORD action = 0;
-       LONG retValReg = RegCreateKeyEx(HKEY_CURRENT_USER, strRegPath.c_str(),
-               0, nullptr, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, nullptr,
-               &hKey, &action);
+       if (m_hKeys.find(strPath) == m_hKeys.end())
+       {
+               DWORD action = 0;
+               LONG retValReg = RegCreateKeyEx(HKEY_CURRENT_USER, strRegPath.c_str(),
+                       0, nullptr, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, nullptr,
+                       &hKey, &action);
 
-       if (retValReg != ERROR_SUCCESS)
-               return COption::OPT_ERR;
+               if (retValReg != ERROR_SUCCESS)
+                       return COption::OPT_ERR;
+
+               m_hKeys[strPath] = hKey;
+       }
+       else
+       {
+               hKey = m_hKeys[strPath];
+       }
 
        // Check previous value
        // This just checks if the value exists, LoadValueFromReg() below actually
@@ -213,7 +222,7 @@ int CRegOptionsMgr::InitOption(const String& name, const varprop::VariantValue&
        DWORD type = 0;
        BYTE dataBuf[MAX_PATH_FULL] = {0};
        DWORD size = MAX_PATH_FULL;
-       retValReg = RegQueryValueEx(hKey, strValueName.c_str(),
+       LONG retValReg = RegQueryValueEx(hKey, strValueName.c_str(),
                0, &type, dataBuf, &size);
 
        // Actually save value into our in-memory options table
@@ -236,7 +245,12 @@ int CRegOptionsMgr::InitOption(const String& name, const varprop::VariantValue&
                                retVal = Set(name, value);
                }
        }
-       RegCloseKey(hKey);
+
+       if (m_bCloseHandle)
+       {
+               RegCloseKey(hKey);
+               m_hKeys.erase(strPath);
+       }
        return retVal;
 }
 
@@ -313,13 +327,28 @@ int CRegOptionsMgr::LoadOption(const String& name)
        
        if (retVal == COption::OPT_OK)
        {
-               LONG retValReg = RegOpenKeyEx(HKEY_CURRENT_USER, strRegPath.c_str(),
-                       0, KEY_READ, &hKey);
+               LONG retValReg;
+               if (m_hKeys.find(strPath) == m_hKeys.end())
+               {
+                       retValReg = RegOpenKeyEx(HKEY_CURRENT_USER, strRegPath.c_str(),
+                               0, KEY_ALL_ACCESS, &hKey);
+                       if (retValReg == ERROR_SUCCESS)
+                               m_hKeys[strPath] = hKey;
+               }
+               else
+               {
+                       hKey = m_hKeys[strPath];
+                       retValReg = ERROR_SUCCESS;
+               }
 
                if (retValReg == ERROR_SUCCESS)
                {
                        retVal = LoadValueFromReg(hKey, name, value);
-                       RegCloseKey(hKey);
+                       if (m_bCloseHandle)
+                       {
+                               RegCloseKey(hKey);
+                               m_hKeys.erase(strPath);
+                       }
                }
                else
                        retVal = COption::OPT_ERR;
@@ -352,13 +381,28 @@ int CRegOptionsMgr::SaveOption(const String& name)
        
        if (retVal == COption::OPT_OK)
        {
-               LONG retValReg = RegOpenKeyEx(HKEY_CURRENT_USER, strRegPath.c_str(),
-                       0, KEY_WRITE, &hKey);
+               LONG retValReg;
+               if (m_hKeys.find(strPath) == m_hKeys.end())
+               {
+                       retValReg = RegOpenKeyEx(HKEY_CURRENT_USER, strRegPath.c_str(),
+                               0, KEY_ALL_ACCESS, &hKey);
+                       if (retValReg == ERROR_SUCCESS)
+                               m_hKeys[strPath] = hKey;
+               }
+               else
+               {
+                       retValReg = ERROR_SUCCESS;
+                       hKey = m_hKeys[strPath];
+               }
 
                if (retValReg == ERROR_SUCCESS)
                {
                        retVal = SaveValueToReg(hKey, strValueName, value);
-                       RegCloseKey(hKey);
+                       if (m_bCloseHandle)
+                       {
+                               RegCloseKey(hKey);
+                               m_hKeys.erase(strPath);
+                       }
                }
                else
                        retVal = COption::OPT_ERR;
@@ -431,11 +475,23 @@ int CRegOptionsMgr::RemoveOption(const String& name)
        String strRegPath(m_registryRoot);
        String strPath;
        String strValueName;
+       LONG retValReg;
 
        SplitName(name, strPath, strValueName);
        strRegPath += strPath;
 
-       LONG retValReg = RegOpenKey(HKEY_CURRENT_USER, strRegPath.c_str(), &hKey);
+       if (m_hKeys.find(strPath) == m_hKeys.end())
+       {
+               retValReg = RegOpenKeyEx(HKEY_CURRENT_USER, strRegPath.c_str(),
+                       0, KEY_ALL_ACCESS, &hKey);
+               if (retValReg == ERROR_SUCCESS)
+                       m_hKeys[strPath] = hKey;
+       }
+       else
+       {
+               hKey = m_hKeys[strPath];
+               retValReg = ERROR_SUCCESS;
+       }
        if (retValReg == ERROR_SUCCESS)
        {
                retValReg = RegDeleteValue(hKey, strValueName.c_str());
@@ -443,7 +499,11 @@ int CRegOptionsMgr::RemoveOption(const String& name)
                {
                        retVal = COption::OPT_ERR;
                }
-               RegCloseKey(hKey);
+               if (m_bCloseHandle)
+               {
+                       RegCloseKey(hKey);
+                       m_hKeys.erase(strPath);
+               }
        }
        else
                retVal = COption::OPT_ERR;
@@ -595,3 +655,10 @@ int CRegOptionsMgr::ImportOptions(const String& filename)
        }
        return retVal;
 }
+
+void CRegOptionsMgr::CloseHandles()
+{
+       for (auto& pair : m_hKeys)
+               RegCloseKey(pair.second);
+       m_hKeys.clear();
+}
index 370e175..63df713 100644 (file)
@@ -17,10 +17,11 @@ class COptionsMgr;
 class CRegOptionsMgr: public COptionsMgr
 {
 public:
-       CRegOptionsMgr() : m_serializing(true) { }
+       CRegOptionsMgr() : m_serializing(true), m_bCloseHandle(true) { }
        virtual ~CRegOptionsMgr() { }
        int LoadOption(const String& name);
        int SetRegRootKey(const String& path);
+       void CloseHandles();
 
        virtual int InitOption(const String& name, const varprop::VariantValue& defaultValue);
        virtual int InitOption(const String& name, const String& defaultValue);
@@ -52,4 +53,6 @@ protected:
 private:
        String m_registryRoot; /**< Registry path where to store options. */
        bool m_serializing;
+       std::map<String, HKEY> m_hKeys;
+       bool m_bCloseHandle;
 };
index 559f48c..759c43c 100644 (file)
@@ -202,7 +202,10 @@ BOOL CMergeApp::InitInstance()
        if (cmdInfo.m_bNoPrefs)
                m_pOptions->SetSerializing(false); // Turn off serializing to registry.
 
-       Options::Init(m_pOptions.get()); // Implementation in OptionsInit.cpp
+       {
+               WMPROFILE(L"Init");
+               Options::Init(m_pOptions.get()); // Implementation in OptionsInit.cpp
+       }
        ApplyCommandLineConfigOptions(cmdInfo);
        if (cmdInfo.m_sErrorMessages.size() > 0)
        {
@@ -548,6 +551,8 @@ BOOL CMergeApp::OnIdle(LONG lCount)
        if (m_bNonInteractive && IsReallyIdle())
                m_pMainWnd->PostMessage(WM_CLOSE, 0, 0);
 
+       static_cast<CRegOptionsMgr *>(GetOptionsMgr())->CloseHandles();
+
        return FALSE;
 }
 
@@ -1291,3 +1296,43 @@ void CMergeApp::OnUpdateMergingStatus(CCmdUI *pCmdUI)
        pCmdUI->SetText(text.c_str());
        pCmdUI->Enable(GetMergingMode());
 }
+
+UINT CMergeApp::GetProfileInt(LPCTSTR lpszSection, LPCTSTR lpszEntry, int nDefault)
+{
+       COptionsMgr *pOptions = GetOptionsMgr();
+       String name = strutils::format(_T("%s/%s"), lpszSection, lpszEntry);
+       if (!pOptions->Get(name).IsInt())
+               pOptions->InitOption(name, nDefault);
+       return pOptions->GetInt(name);
+}
+
+BOOL CMergeApp::WriteProfileInt(LPCTSTR lpszSection, LPCTSTR lpszEntry, int nValue)
+{
+       COptionsMgr *pOptions = GetOptionsMgr();
+       String name = strutils::format(_T("%s/%s"), lpszSection, lpszEntry);
+       if (!pOptions->Get(name).IsInt())
+               pOptions->InitOption(name, nValue);
+       return pOptions->SaveOption(name, nValue) == COption::OPT_OK;
+}
+
+CString CMergeApp::GetProfileString(LPCTSTR lpszSection, LPCTSTR lpszEntry, LPCTSTR lpszDefault)
+{
+       COptionsMgr *pOptions = GetOptionsMgr();
+       String name = strutils::format(_T("%s/%s"), lpszSection, lpszEntry);
+       if (!pOptions->Get(name).IsString())
+               pOptions->InitOption(name, lpszDefault ? lpszDefault : _T(""));
+       return pOptions->GetString(name).c_str();
+}
+
+BOOL CMergeApp::WriteProfileString(LPCTSTR lpszSection, LPCTSTR lpszEntry, LPCTSTR lpszValue)
+{
+       COptionsMgr *pOptions = GetOptionsMgr();
+       if (lpszEntry != nullptr)
+       {
+               String name = strutils::format(_T("%s/%s"), lpszSection, lpszEntry);
+               if (!pOptions->Get(name).IsString())
+                       pOptions->InitOption(name, lpszValue ? lpszValue : _T(""));
+               return pOptions->SaveOption(name, lpszValue ? lpszValue : _T("")) == COption::OPT_OK;
+       }
+       return TRUE;
+}
index 86975f5..9aee56f 100644 (file)
@@ -104,6 +104,11 @@ public:
        void SetupTempPath();
        bool IsReallyIdle() const;
 
+       virtual UINT GetProfileInt(LPCTSTR lpszSection, LPCTSTR lpszEntry, int nDefault) override;
+       virtual BOOL WriteProfileInt(LPCTSTR lpszSection, LPCTSTR lpszEntry, int nValue) override;
+       virtual CString GetProfileString(LPCTSTR lpszSection, LPCTSTR lpszEntry, LPCTSTR lpszDefault = NULL) override;
+       virtual BOOL WriteProfileString(LPCTSTR lpszSection, LPCTSTR lpszEntry, LPCTSTR lpszValue) override;
+
 // Implementation
 protected:
 
@@ -172,6 +177,8 @@ private:
        LONG m_nActiveOperations; /**< Active operations count. */
        bool m_bMergingMode; /**< Merging or Edit mode */
        CFont m_fontGUI;
+       std::map<String, HKEY> m_hKeys;
+       std::map<String, HKEY> m_hWriteKeys;
 };
 
 extern CMergeApp theApp;