bool CUpgradrRootImpl::CheckThreadOwnership(ESharedResourceId rid) { #ifdef _DEBUG DWORD tid = GetCurrentThreadId(); m_MainCS.Enter(); TOwnership::iterator i = m_Ownership.find(rid); if (i==m_Ownership.end()) { TRACE_E(FS(_T("Resource %s owned by no thread used by thread %08X !!!"), g_acResourceNames[rid], tid)); DebugBreak(); m_MainCS.Leave(); return false; } if (i->second.first!=tid) { TRACE_E(FS(_T("Resource %s owned by thread %08X used by thread %08X !!!"), g_acResourceNames[rid], i->second.first, tid)); DebugBreak(); m_MainCS.Leave(); return false; } m_MainCS.Leave(); #endif return true; }
void CConnectionManager::RegistryWatchDogThread() { HKEY hKey; if (RegOpenKeyEx(HKEY_CURRENT_USER, REGISTRY_ROOT_KEY_SITES_PARENT, 0, KEY_NOTIFY, &hKey) != ERROR_SUCCESS) { TRACE_E(FS(_T("Registry watchdog thread unable to open registry key: %s"), REGISTRY_ROOT_KEY_SITES_PARENT)); _endthreadex(2); return; } while (true) { if (RegNotifyChangeKeyValue(hKey, TRUE, REG_NOTIFY_CHANGE_NAME|REG_NOTIFY_CHANGE_LAST_SET, NULL, FALSE)!=ERROR_SUCCESS) { TRACE_E(_T("Registry watchdog thread unable to setup next waiting operation")); _endthreadex(1); return; } TRACE_W(_T("Registry watchdog triggered")); m_CS.Enter(); m_SitesModel.Load(REGISTRY_ROOT_KEY_SITES); m_CS.Leave(); TRACE_W(_T("Sites model reloaded!")); } RegCloseKey(hKey); _endthread(); }
bool CServices::OpenSettingsDialog() { CHECK_THREAD_OWNERSHIP; Mortimer::COptionSheetLayoutImpl<Mortimer::COptionSelectionLayoutTreeBanner, CCSNOptionSheet> Sheet(_T("Upgradr Settings")); // retrieve root key for registry HKEY hKey = NULL; LONG lRes = RegOpenKeyEx(HKEY_CURRENT_USER, REGISTRY_ROOT_KEY, 0, KEY_ALL_ACCESS, &hKey); if (lRes != ERROR_SUCCESS) { if (RegCreateKey(HKEY_CURRENT_USER, REGISTRY_ROOT_KEY, &hKey)) { TRACE_E(_T("Cannot create registry key: HKCU\\") REGISTRY_ROOT_KEY); return false; } } // create storage Mortimer::CSettingsStorageRegistry storage(hKey, REGISTRY_OPTIONS_KEY); // load settings from storage m_Settings.Load(storage); // fire options dialog Sheet.SetManagedSettings(&m_Settings, &storage); if (IDOK!=Sheet.DoModal()) return true; // if OK pressed, save options into storage m_Settings.Save(storage); return true; }
STDMETHODIMP CUpgradrToolbar::SetSite(IUnknown *pUnknownSite) { DT(TRACE_I(FS(_T("Toolbar[%08X]: SetSite(%08X)"), this, pUnknownSite))); try { if (!!pUnknownSite) { // attach the window HWND hMyWindow; CComPtr<IUnknown> site(pUnknownSite); CComQIPtr<IOleWindow> window(site); window->GetWindow(&hMyWindow); if (!hMyWindow) { TRACE_E(FS(_T("Toolbar[%08X]: Cannot retrieve toolbar base window"), this)); return E_FAIL; } SubclassWindow(hMyWindow); // get a WebBrowser reference CComQIPtr<IServiceProvider> serviceProvider(site); serviceProvider->QueryService(IID_IWebBrowserApp, IID_IWebBrowser2, (void**)&m_spWebBrowser); site->QueryInterface(IID_IInputObjectSite, (void**)&m_spSite); // create main window CreateMainWindow(); } } catch (CUpgradrRuntimeError &ex) { HandleError(ex.ErrorMessage()); return E_FAIL; } return S_OK; }
void CConnectionManager::Send(Json::Value& msg) { if (!m_Connection.IsOpen()) return; Json::FastWriter writer; string data = writer.write(msg)+"\n"; if (!m_Connection.WriteComm((LPBYTE)data.c_str(), data.size(), 1000)) { TRACE_E(_T("unable to send message")); } }
void CFrameTable::SetFrameId(CComPtr<IHTMLDocument2> document, TFrameId frameId, bool bImportant) { // retrieve document's window object CComPtr<IHTMLWindow2> window; CHECK_COM(document->get_parentWindow(&window), _T("Cannot retrieve parent window")); if (!window) { TRACE_E(_T("Cannot retrieve parent window for document")); ATLASSERT(0); return; } // cast window object to IDispatchEx CComQIPtr<IDispatchEx> windowDispEx = window; if (!windowDispEx) { TRACE_E(_T("Cannot retrieve IDispatchEx on parent window of document")); ATLASSERT(0); return; } // add FrameId property to window object DISPID dispid; DISPPARAMS dispparams; HRESULT hr = windowDispEx->GetDispID(CComBSTR(JAVASCRIPT_FRAMEID_VARIABLE), fdexNameEnsure|fdexNameCaseSensitive, &dispid); if (!bImportant && hr==E_ACCESSDENIED) return; CHECK_COM(hr, FS(_T("GetDispID for window.%s has failed"), JAVASCRIPT_FRAMEID_VARIABLE)); DISPID putid = DISPATCH_PROPERTYPUT; CComVariant var(frameId); dispparams.rgvarg = &var; dispparams.rgdispidNamedArgs = &putid; dispparams.cArgs = 1; dispparams.cNamedArgs = 1; VARIANT temp; CHECK_COM(windowDispEx->Invoke(dispid, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_PROPERTYPUT, &dispparams, &temp, NULL, NULL), _T("Failed to add property to window object")); ATLASSERT(GetFrameId(document)==frameId); DT(TRACE_I(FS(_T("CFrameTable::SetFrameId(doc=%08X, id=%d) OK"), document, frameId))); }
STDMETHODIMP CXRefreshToolbar::SetSite(IUnknown *pUnknownSite) { DT(TRACE_I(FS(_T("Toolbar[%08X]: SetSite(%08X)"), this, pUnknownSite))); try { if (!!pUnknownSite) { // attach the window HWND hWnd; CComPtr<IUnknown> site(pUnknownSite); CComQIPtr<IOleWindow> window(site); window->GetWindow(&hWnd); if (!hWnd) { TRACE_E(FS(_T("Toolbar[%08X]: Cannot retrieve toolbar base window"), this)); return E_FAIL; } SubclassWindow(hWnd); // get a WebBrowser reference CComQIPtr<IServiceProvider> serviceProvider(site); serviceProvider->QueryService(IID_IWebBrowserApp, IID_IWebBrowser2, (void**)&m_Browser); site->QueryInterface(IID_IInputObjectSite, (void**)&m_Site); // retrive browser id { BrowserManagerLock browserManager; m_BrowserId = browserManager->AllocBrowserId(m_Browser, this); ATLASSERT(m_BrowserId!=NULL_BROWSER); } // create main window CreateMainWindow(); } else { BrowserManagerLock browserManager; CBrowserMessageWindow* bw = browserManager->FindBrowserMessageWindow(m_BrowserId); ATLASSERT(bw); bw->SetToolbar(NULL); browserManager->ReleaseBrowserId(m_BrowserId); m_BrowserId = NULL_BROWSER; } } catch (CXRefreshRuntimeError &ex) { HandleError(ex.ErrorMessage()); return E_FAIL; } return S_OK; }
TFrameId CFrameTable::GetFrameId(CComPtr<IHTMLDocument2> document, bool bImportant) { // get frame id from window.<JAVASCRIPT_FRAMEID_VARIABLE> // retrieve document's window object CComPtr<IHTMLWindow2> window; CHECK_COM(document->get_parentWindow(&window), _T("Cannot retrieve parent window")); if (!window) { TRACE_E(_T("Cannot retrieve parent window for document")); ATLASSERT(0); return NULL_FRAME; } // cast window object to IDispatchEx CComQIPtr<IDispatchEx> windowDispEx = window; if (!windowDispEx) { TRACE_E(_T("Cannot retrieve IDispatchEx on parent window of document")); ATLASSERT(0); return NULL_FRAME; } // read FrameId property to window object DISPID dispid; DISPPARAMS dispparams = { NULL, NULL, 0, 0 }; HRESULT hr = windowDispEx->GetDispID(CComBSTR(JAVASCRIPT_FRAMEID_VARIABLE), fdexNameCaseSensitive, &dispid); if (hr==DISP_E_UNKNOWNNAME) return NULL_FRAME; if (!bImportant && hr==E_ACCESSDENIED) return NULL_FRAME; CHECK_COM(hr, FS(_T("GetDispID for window.%s has failed"), JAVASCRIPT_FRAMEID_VARIABLE)); CComVariant res; CHECK_COM(windowDispEx->Invoke(dispid, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_PROPERTYGET, &dispparams, &res, NULL, NULL), _T("Failed to read property from window object")); ATLASSERT(res.vt==VT_UI4); return res.ulVal; }
STDMETHODIMP CUpgradrHelperbar::SetSite(IUnknown *pUnknownSite) { DT(TRACE_I(FS(_T("Helperbar[%08X]: SetSite(%08X)"), this, pUnknownSite))); if (!!pUnknownSite) { // get a WebBrowser reference CComPtr<IUnknown> site(pUnknownSite); CComQIPtr<IServiceProvider> serviceProvider(site); serviceProvider->QueryService(IID_IWebBrowserApp, IID_IWebBrowser2, (void**)&m_Browser); site->QueryInterface(IID_IInputObjectSite, (void**)&m_Site); // retrive browser id { BrowserManagerLock browserManager; m_BrowserId = browserManager->AllocBrowserId(m_Browser, this); ATLASSERT(m_BrowserId!=NULL_BROWSER); } // attach the window HWND hHelperbarWindow; CComQIPtr<IOleWindow> window(site); window->GetWindow(&hHelperbarWindow); if (!hHelperbarWindow) { TRACE_E(FS(_T("Helperbar[%08X]: Cannot retrieve helpbar base window"), this)); return E_FAIL; } SubclassWindow(hHelperbarWindow); // create main window CreateMainWindow(); } else { BrowserManagerLock browserManager; browserManager->ReleaseBrowserId(m_BrowserId); m_BrowserId = NULL_BROWSER; } return S_OK; }
// pri beznem provozu se nesmi TRACOVAT v Acquire a Release // to vede k zmateni Loggeru, protoze Acquire a Release nejsou reentrantni void* CUpgradrRootImpl::Acquire(ESharedResourceId rid) { static bool inAcquire = false; // try to enter CS m_MainCS.Enter(); if (inAcquire) DebugBreak(); // this function is NOT reentrant inAcquire = true; DWORD myThread = GetCurrentThreadId(); pair<TResourcesMap::iterator, TResourcesMap::iterator> range = m_Resources.equal_range(myThread); TResourcesMap::iterator test = range.first; ESharedResourceId max = (ESharedResourceId)-1; if (test!=range.second) { if (max>test->second) max = test->second; ++test; } if (rid<max) { TRACE_E(FS(_T("Thread %0X tried to alloc resource %s(%d) after %s(%d)"), myThread, g_acResourceNames[rid], (int)rid, g_acResourceNames[max], (int)max)); ATLASSERT(0); } void* res = NULL; switch (rid) { case SR_DATABASE: res = &m_Database; break; case SR_SCRIPTMANAGER: res = &m_ScriptManager; break; case SR_HANDLEMANAGER: res = &m_HandleManager; break; case SR_LOGGER: res = &m_Logger; break; case SR_SERVICES: res = &m_Services; break; case SR_SCRIPTDEBUGGER: res = &m_ScriptDebugger; break; case SR_SCRIPTINSTANCEMANAGER: res = &m_ScriptInstanceManager; break; case SR_FRAMEMANAGER: res = &m_FrameManager; break; case SR_WINDOWMANAGER: res = &m_WindowManager; break; case SR_BROWSERMANAGER: res = &m_BrowserManager; break; case SR_DIALOGMANAGER: res = &m_DialogManager; break; case SR_SERVER: res = &m_Server; break; case SR_FILESYSTEM: res = &m_FileSystem; break; } ATLASSERT(res); // test if someone owns that resource already TOwnership::iterator owner = m_Ownership.find(rid); if (owner==m_Ownership.end()) { // well, nobody owns that resource, it is safe to enter DT(OutputDebugString(FS(_T("Module[%08X]: Acquire %s"), myThread, g_acResourceNames[rid]))); // register as an owner m_Ownership.insert(make_pair(rid, make_pair(myThread, 1))); m_Resources.insert(make_pair(myThread, rid)); owner = m_Ownership.find(rid); // enter critical section ATLASSERT(m_CS[rid].CanEnter()); m_CS[rid].Enter(); // it must proceed !!! } else { // someone owns that resource if (owner->second.first==myThread) { // already have it DT(OutputDebugString(FS(_T("Module[%08X]: Multiple enter into %s (%dx)"), myThread, g_acResourceNames[rid], owner->second.second+1))); // increase enter counter owner->second.second++; // and leave inAcquire = false; m_MainCS.Leave(); return res; } // i'm going to fall asleep DT(OutputDebugString(FS(_T("Module[%08X]: Hibernate %s"), myThread, g_acResourceNames[rid]))); m_StarveMap.insert(make_pair(myThread, 0)); while (true) // wait until out resource is free { // leave main CS inAcquire = false; m_MainCS.Leave(); // wait for signal, zzZZ SleepEx(100, TRUE); // thread is alertable m_MainCS.Enter(); if (inAcquire) DebugBreak(); // this function is NOT reentrant inAcquire = true; DT(OutputDebugString(FS(_T("Module[%08X]: Reborn %s"), myThread, g_acResourceNames[rid]))); // is requested resource free ? owner = m_Ownership.find(rid); if (owner==m_Ownership.end()) { break; } m_StarveMap[myThread]+=100; } m_StarveMap.erase(myThread); DT(OutputDebugString(FS(_T("Module[%08X]: Thread is alive %s"), myThread, g_acResourceNames[rid]))); // register as an owner m_Ownership.insert(make_pair(rid, make_pair(myThread, 1))); m_Resources.insert(make_pair(myThread, rid)); // enter critical section ATLASSERT(m_CS[rid].CanEnter()); m_CS[rid].Enter(); // it must proceed !!! } inAcquire = false; m_MainCS.Leave(); return res; }