Skip to content

Hotfix for #2831(revert conditional variable) #2844

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Dec 22, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 28 additions & 2 deletions Client/cefweb/CWebView.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,11 @@ CWebView::~CWebView()
g_pCore->GetWebCore()->SetFocusedWebView(nullptr);
}

// Make sure we don't dead lock the CEF render thread
ResumeCefThread();

// Ensure that CefRefPtr::~CefRefPtr doesn't try to release it twice (it has already been released in CWebView::OnBeforeClose)
m_pWebView = nullptr;
m_pWebView = nullptr;

OutputDebugLine("CWebView::~CWebView");
}
Expand Down Expand Up @@ -77,6 +80,9 @@ void CWebView::CloseBrowser()
// CefBrowserHost::CloseBrowser calls the destructor after the browser has been destroyed
m_bBeingDestroyed = true;

// Make sure we don't dead lock the CEF render thread
ResumeCefThread();

if (m_pWebView)
m_pWebView->GetHost()->CloseBrowser(true);
}
Expand Down Expand Up @@ -200,7 +206,7 @@ void CWebView::UpdateTexture()

auto pSurface = m_pWebBrowserRenderItem->m_pD3DRenderTargetSurface;
if (m_bBeingDestroyed || !pSurface)
return;
m_RenderData.changed = m_RenderData.popupShown = false;

// Discard current buffer if size doesn't match
// This happens when resizing the browser as OnPaint is called asynchronously
Expand Down Expand Up @@ -281,6 +287,9 @@ void CWebView::UpdateTexture()
pSurface->UnlockRect();
}
}

m_RenderData.cefThreadState = ECefThreadState::Running;
m_RenderData.cefThreadCv.notify_all();
}

void CWebView::ExecuteJavascript(const SString& strJavascriptCode)
Expand Down Expand Up @@ -447,6 +456,8 @@ void CWebView::Resize(const CVector2D& size)
// Send resize event to CEF
if (m_pWebView)
m_pWebView->GetHost()->WasResized();

ResumeCefThread();
}

CVector2D CWebView::GetSize()
Expand Down Expand Up @@ -709,6 +720,10 @@ void CWebView::OnPaint(CefRefPtr<CefBrowser> browser, CefRenderHandler::PaintEle
m_RenderData.height = height;
m_RenderData.dirtyRects = dirtyRects;
m_RenderData.changed = true;

// Wait for the main thread to handle drawing the texture
m_RenderData.cefThreadState = ECefThreadState::Wait;
m_RenderData.cefThreadCv.wait(lock, [&](){ return m_RenderData.cefThreadState == ECefThreadState::Running; });
}

////////////////////////////////////////////////////////////////////
Expand Down Expand Up @@ -1069,3 +1084,14 @@ void CWebView::OnBeforeContextMenu(CefRefPtr<CefBrowser> browser, CefRefPtr<CefF
// Show no context menu
model->Clear();
}

void CWebView::ResumeCefThread()
{
{
// It's recommended to unlock a mutex before the cv notifying to avoid a possible pessimization
std::unique_lock<std::mutex> lock(m_RenderData.dataMutex);
m_RenderData.cefThreadState = ECefThreadState::Running;
}

m_RenderData.cefThreadCv.notify_all();
}
10 changes: 10 additions & 0 deletions Client/cefweb/CWebView.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,12 @@

#define MTA_CEF_USERAGENT "Multi Theft Auto: San Andreas Client " MTA_DM_BUILDTAG_LONG

enum class ECefThreadState
{
Running = 0, // CEF thread is currently running
Wait // CEF thread is waiting for the main thread
};

class CWebView : public CWebViewInterface,
private CefClient,
private CefRenderHandler,
Expand Down Expand Up @@ -173,6 +179,8 @@ class CWebView : public CWebViewInterface,
CefRefPtr<CefMenuModel> model) override;

private:
void ResumeCefThread();

CefRefPtr<CefBrowser> m_pWebView;
CWebBrowserItem* m_pWebBrowserRenderItem;

Expand All @@ -192,6 +200,8 @@ class CWebView : public CWebViewInterface,
{
bool changed = false;
std::mutex dataMutex;
ECefThreadState cefThreadState = ECefThreadState::Running;
std::condition_variable cefThreadCv;

const void* buffer;
int width, height;
Expand Down