Skip to content

Commit 3634413

Browse files
Synchronize changes from 1.6 branch [ci skip]
bb98fb6 1.6: Addendum to ea33335 (C++ 17 constraints) ea33335 Crash handler: Minor improvements f09ede6 Better crash handling of disastrous exception types, including STATUS_FATAL_USER_CALLBACK_EXCEPTION (0xC000041D) 4bc0334 1.6: CEF reworks #2: Miscelanneous + compile fix
2 parents ee8f610 + bb98fb6 commit 3634413

File tree

14 files changed

+784
-201
lines changed

14 files changed

+784
-201
lines changed

Client/ceflauncher/Main.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ int __stdcall WinMain(HINSTANCE, HINSTANCE, LPSTR, int)
3838
{
3939
try
4040
{
41-
return std::invoke_r<int>(init);
41+
return std::invoke(init);
4242
}
4343
catch (...)
4444
{

Client/cefweb/CAjaxResourceHandler.cpp

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -84,13 +84,16 @@ bool CAjaxResourceHandler::ReadResponse(void* data_out, int bytes_to_read, int&
8484
}
8585

8686
// Are we done?
87-
if (m_strResponse.length() - m_DataOffset <= 0)
87+
if (m_strResponse.length() - m_DataOffset <= 0) [[unlikely]]
8888
return false;
8989

90-
int copyBytes = std::min((uint)bytes_to_read, m_strResponse.length() - m_DataOffset);
90+
if (bytes_to_read <= 0) [[unlikely]]
91+
return false;
92+
93+
const size_t copyBytes = std::min(static_cast<size_t>(bytes_to_read), m_strResponse.length() - m_DataOffset);
9194

9295
memcpy(data_out, m_strResponse.c_str() + m_DataOffset, copyBytes);
93-
bytes_read = copyBytes;
96+
bytes_read = static_cast<int>(copyBytes);
9497

9598
m_DataOffset += copyBytes;
9699

Client/cefweb/CWebApp.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,9 @@ void CWebApp::OnBeforeCommandLineProcessing(const CefString& process_type, CefRe
2929
if (!command_line)
3030
return;
3131

32+
if (!g_pCore) [[unlikely]]
33+
return;
34+
3235
const auto pWebCore = static_cast<CWebCore*>(g_pCore->GetWebCore());
3336
if (!pWebCore)
3437
return;
@@ -65,6 +68,9 @@ CefRefPtr<CefResourceHandler> CWebApp::Create(CefRefPtr<CefBrowser> browser, Cef
6568
if (!browser || !frame || !request)
6669
return nullptr;
6770

71+
if (!g_pCore) [[unlikely]]
72+
return nullptr;
73+
6874
const auto pWebCore = static_cast<CWebCore*>(g_pCore->GetWebCore());
6975
if (!pWebCore)
7076
return nullptr;

Client/cefweb/CWebCore.cpp

Lines changed: 50 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,9 @@ CWebCore::CWebCore()
3131
m_bTestmodeEnabled = false;
3232
m_pXmlConfig = nullptr;
3333
m_pFocusedWebView = nullptr;
34+
m_bGPUEnabled = false;
35+
m_iWhitelistRevision = 0;
36+
m_iBlacklistRevision = 0;
3437

3538
MakeSureXMLNodesExist();
3639
InitialiseWhiteAndBlacklist();
@@ -92,12 +95,14 @@ bool CWebCore::Initialise(bool gpuEnabled)
9295
settings.multi_threaded_message_loop = true;
9396
settings.windowless_rendering_enabled = true;
9497

95-
bool state = CefInitialize(mainArgs, settings, app, sandboxInfo);
96-
97-
// Register custom scheme handler factory
98-
CefRegisterSchemeHandlerFactory("http", "mta", app);
98+
if (const bool state = CefInitialize(mainArgs, settings, app, sandboxInfo); state) [[likely]]
99+
{
100+
// Register custom scheme handler factory only if initialization succeeded
101+
CefRegisterSchemeHandlerFactory("http", "mta", app);
102+
return true;
103+
}
99104

100-
return state;
105+
return false;
101106
}
102107

103108
CWebViewInterface* CWebCore::CreateWebView(unsigned int uiWidth, unsigned int uiHeight, bool bIsLocal, CWebBrowserItem* pWebBrowserRenderItem,
@@ -243,19 +248,17 @@ void CWebCore::WaitForTask(std::function<void(bool)> task, CWebView* webView)
243248
{
244249
std::scoped_lock lock(m_TaskQueueMutex);
245250

246-
// Prevent unbounded queue growth - if queue is too large, oldest tasks will be dropped during pulse
247-
if (m_TaskQueue.size() >= MAX_TASK_QUEUE_SIZE)
251+
// Prevent unbounded queue growth - abort new task if queue is too large
252+
if (m_TaskQueue.size() >= MAX_TASK_QUEUE_SIZE) [[unlikely]]
248253
{
249254
#ifdef MTA_DEBUG
250-
g_pCore->GetConsole()->Printf("Warning: Task queue size limit reached (%d), task will be aborted", MAX_TASK_QUEUE_SIZE);
255+
static constexpr auto WARNING_MSG = "Warning: Task queue size limit reached (%d), aborting new task";
256+
g_pCore->GetConsole()->Printf(WARNING_MSG, MAX_TASK_QUEUE_SIZE);
251257
#endif
252-
// Must still queue the task to fulfill the future, but it will be aborted during processing
253-
// Removing oldest task to make room
254-
if (!m_TaskQueue.empty())
255-
{
256-
m_TaskQueue.front().task(true); // Abort oldest task
257-
m_TaskQueue.pop_front();
258-
}
258+
// Abort the new task immediately to prevent deadlock
259+
// Don't add it to the queue
260+
task(true);
261+
return;
259262
}
260263

261264
m_TaskQueue.emplace_back(TaskEntry{task, webView});
@@ -269,14 +272,19 @@ void CWebCore::RemoveWebViewTasks(CWebView* webView)
269272
{
270273
std::scoped_lock lock(m_TaskQueueMutex);
271274

272-
for (auto iter = m_TaskQueue.begin(); iter != m_TaskQueue.end(); ++iter)
273-
{
274-
if (iter->webView != webView)
275-
continue;
276-
277-
iter->task(true);
278-
iter = m_TaskQueue.erase(iter);
279-
}
275+
// C++17-compatible erase-remove idiom (std::erase_if is C++20)
276+
m_TaskQueue.erase(
277+
std::remove_if(m_TaskQueue.begin(), m_TaskQueue.end(),
278+
[webView](TaskEntry& entry) {
279+
if (entry.webView == webView)
280+
{
281+
entry.task(true);
282+
return true;
283+
}
284+
return false;
285+
}),
286+
m_TaskQueue.end()
287+
);
280288
}
281289

282290
void CWebCore::DoTaskQueuePulse()
@@ -298,12 +306,12 @@ eURLState CWebCore::GetDomainState(const SString& strURL, bool bOutputDebug)
298306
std::lock_guard<std::recursive_mutex> lock(m_FilterMutex);
299307

300308
// Initialize wildcard whitelist (be careful with modifying) | Todo: Think about the following
301-
static SString wildcardWhitelist[] = {"*.googlevideo.com", "*.google.com", "*.youtube.com", "*.ytimg.com",
302-
"*.vimeocdn.com", "*.gstatic.com", "*.googleapis.com", "*.ggpht.com"};
309+
static constexpr const char* wildcardWhitelist[] = {"*.googlevideo.com", "*.google.com", "*.youtube.com", "*.ytimg.com",
310+
"*.vimeocdn.com", "*.gstatic.com", "*.googleapis.com", "*.ggpht.com"};
303311

304-
for (int i = 0; i < sizeof(wildcardWhitelist) / sizeof(SString); ++i)
312+
for (const auto& pattern : wildcardWhitelist)
305313
{
306-
if (WildcardMatch(wildcardWhitelist[i], strURL))
314+
if (WildcardMatch(pattern, strURL))
307315
return eURLState::WEBPAGE_ALLOWED;
308316
}
309317

@@ -602,6 +610,11 @@ bool CWebCore::SetGlobalAudioVolume(float fVolume)
602610
return true;
603611
}
604612

613+
CWebViewInterface* CWebCore::GetFocusedWebView()
614+
{
615+
return m_pFocusedWebView;
616+
}
617+
605618
bool CWebCore::UpdateListsFromMaster()
606619
{
607620
if (!m_pXmlConfig)
@@ -813,7 +826,7 @@ void CWebCore::GetFilterEntriesByType(std::vector<std::pair<SString, bool>>& out
813826
outEntries.push_back(std::pair<SString, bool>(iter->first, iter->second.first));
814827
else if (state == eWebFilterState::WEBFILTER_ALLOWED && iter->second.first == true)
815828
outEntries.push_back(std::pair<SString, bool>(iter->first, iter->second.first));
816-
else
829+
else if (state == eWebFilterState::WEBFILTER_DISALLOWED && iter->second.first == false)
817830
outEntries.push_back(std::pair<SString, bool>(iter->first, iter->second.first));
818831
}
819832
}
@@ -822,6 +835,9 @@ void CWebCore::GetFilterEntriesByType(std::vector<std::pair<SString, bool>>& out
822835
void CWebCore::StaticFetchRevisionFinished(const SHttpDownloadResult& result)
823836
{
824837
CWebCore* pWebCore = static_cast<CWebCore*>(result.pObj);
838+
if (!pWebCore) [[unlikely]]
839+
return;
840+
825841
if (result.bSuccess)
826842
{
827843
SString strData = result.pData;
@@ -862,6 +878,9 @@ void CWebCore::StaticFetchWhitelistFinished(const SHttpDownloadResult& result)
862878
return;
863879

864880
CWebCore* pWebCore = static_cast<CWebCore*>(result.pObj);
881+
if (!pWebCore) [[unlikely]]
882+
return;
883+
865884
if (!pWebCore->m_pXmlConfig)
866885
return;
867886

@@ -905,6 +924,9 @@ void CWebCore::StaticFetchBlacklistFinished(const SHttpDownloadResult& result)
905924
return;
906925

907926
CWebCore* pWebCore = static_cast<CWebCore*>(result.pObj);
927+
if (!pWebCore) [[unlikely]]
928+
return;
929+
908930
if (!pWebCore->m_pXmlConfig)
909931
return;
910932

Client/cefweb/CWebCore.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
class CWebBrowserItem;
3030
class CWebsiteRequests;
3131
class CWebView;
32+
class CWebViewInterface;
3233

3334
class CWebCore : public CWebCoreInterface
3435
{
@@ -88,7 +89,7 @@ class CWebCore : public CWebCoreInterface
8889
void SetTestModeEnabled(bool bEnabled) { m_bTestmodeEnabled = bEnabled; };
8990
void DebugOutputThreadsafe(const SString& message, unsigned char R, unsigned char G, unsigned char B);
9091

91-
CWebViewInterface* GetFocusedWebView() { return (CWebViewInterface*)m_pFocusedWebView; };
92+
CWebViewInterface* GetFocusedWebView();
9293
void SetFocusedWebView(CWebView* pWebView) { m_pFocusedWebView = pWebView; };
9394
void ProcessInputMessage(UINT uMsg, WPARAM wParam, LPARAM lParam);
9495
void ClearTextures();

Client/cefweb/CWebView.cpp

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,11 @@ CWebView::~CWebView()
3737
{
3838
if (IsMainThread())
3939
{
40-
if (g_pCore->GetWebCore()->GetFocusedWebView() == this)
41-
g_pCore->GetWebCore()->SetFocusedWebView(nullptr);
40+
if (auto pWebCore = g_pCore->GetWebCore(); pWebCore) [[likely]]
41+
{
42+
if (pWebCore->GetFocusedWebView() == this)
43+
pWebCore->SetFocusedWebView(nullptr);
44+
}
4245
}
4346

4447
// Make sure we don't dead lock the CEF render thread
@@ -936,13 +939,16 @@ CefResourceRequestHandler::ReturnValue CWebView::OnBeforeResourceLoad(CefRefPtr<
936939
void CWebView::OnBeforeClose(CefRefPtr<CefBrowser> browser)
937940
{
938941
// Remove events owned by this webview and invoke left callbacks
939-
g_pCore->GetWebCore()->RemoveWebViewEvents(this);
942+
if (auto pWebCore = g_pCore->GetWebCore(); pWebCore) [[likely]]
943+
{
944+
pWebCore->RemoveWebViewEvents(this);
940945

941-
m_pWebView = nullptr;
946+
// Remove focused web view reference
947+
if (pWebCore->GetFocusedWebView() == this)
948+
pWebCore->SetFocusedWebView(nullptr);
949+
}
942950

943-
// Remove focused web view reference
944-
if (g_pCore->GetWebCore()->GetFocusedWebView() == this)
945-
g_pCore->GetWebCore()->SetFocusedWebView(nullptr);
951+
m_pWebView = nullptr;
946952
}
947953

948954
////////////////////////////////////////////////////////////////////

Client/cefweb/CefWeb.cpp

Lines changed: 49 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,27 +3,66 @@
33
* PROJECT: Multi Theft Auto v1.0
44
* LICENSE: See LICENSE in the top level directory
55
* FILE: CefWeb.cpp
6+
* PURPOSE: CEF web browser module initialization entry point
67
*
78
* Multi Theft Auto is available from https://www.multitheftauto.com/
89
*
910
*****************************************************************************/
1011

1112
#include "StdInc.h"
12-
#include "SharedUtil.hpp"
13+
#include <memory>
14+
#include <SharedUtil.Memory.h>
1315

14-
CCoreInterface* g_pCore = NULL;
16+
CCoreInterface* g_pCore = nullptr;
1517
CLocalizationInterface* g_pLocalization = nullptr;
1618

17-
extern "C" _declspec(dllexport) CWebCoreInterface* InitWebCoreInterface(CCoreInterface* pCore)
19+
namespace
1820
{
19-
g_pCore = pCore;
20-
g_pLocalization = pCore->GetLocalization();
21+
[[nodiscard]] inline bool InitializeGlobalInterfaces(CCoreInterface* pCore) noexcept
22+
{
23+
if (!pCore) [[unlikely]]
24+
return false;
2125

22-
// Ensure main thread identification is consistent
23-
IsMainThread();
26+
g_pCore = pCore;
27+
g_pLocalization = pCore->GetLocalization();
2428

25-
SetMemoryAllocationFailureHandler();
29+
// Localization is critical for browser GUI (request dialogs, etc.)
30+
if (!g_pLocalization) [[unlikely]]
31+
return false;
2632

27-
CWebCore* pWebCore = new CWebCore;
28-
return pWebCore;
33+
return true;
34+
}
35+
36+
//
37+
// Performs required runtime initialization
38+
// Must be called on the main thread before creating CWebCore
39+
//
40+
inline void PerformRuntimeInitialization() noexcept
41+
{
42+
// Ensure main thread identification is consistent
43+
IsMainThread();
44+
45+
// Set up memory allocation failure handler for CEF processes
46+
SharedUtil::SetMemoryAllocationFailureHandler();
47+
}
48+
} // namespace
49+
50+
//
51+
// DLL export: Initialize the web browser subsystem
52+
// Called by CCore::GetWebCore() during initialization
53+
// Returns CWebCoreInterface pointer on success, nullptr on failure
54+
// Thread safety: Must be called from the main thread only
55+
//
56+
extern "C" _declspec(dllexport) CWebCoreInterface* InitWebCoreInterface(CCoreInterface* pCore) noexcept
57+
{
58+
// Validate and initialize global interfaces
59+
if (!InitializeGlobalInterfaces(pCore)) [[unlikely]]
60+
return nullptr;
61+
62+
// Perform runtime initialization
63+
PerformRuntimeInitialization();
64+
65+
// Create and return the web core instance
66+
// Using make_unique for exception safety, then releasing ownership to caller
67+
return std::make_unique<CWebCore>().release();
2968
}

Client/cefweb/StdInc.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
// StdInc.h
22
#include "StdInc.h"
3+
#include "SharedUtil.hpp"

Client/cefweb/premake5.lua

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
project "Client Webbrowser"
22
language "C++"
3-
cppdialect "C++23"
3+
cppdialect "C++20"
44
kind "SharedLib"
55
targetname "cefweb"
66
targetdir(buildpath("mta"))
@@ -39,6 +39,8 @@ project "Client Webbrowser"
3939
"**.cpp"
4040
}
4141

42+
filter {}
43+
4244
links {
4345
"libcef", "CEF", "Psapi.lib", "version.lib", "Winmm.lib", "Ws2_32.lib", "DbgHelp.lib"
4446
}

Client/core/CCore.cpp

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1157,7 +1157,14 @@ CWebCoreInterface* CCore::GetWebCore()
11571157
cvars->Get("browser_enable_gpu", gpuEnabled);
11581158

11591159
m_pWebCore = CreateModule<CWebCoreInterface>(m_WebCoreModule, "CefWeb", "cefweb", "InitWebCoreInterface", this);
1160-
m_pWebCore->Initialise(gpuEnabled);
1160+
if (!m_pWebCore) [[unlikely]]
1161+
return nullptr;
1162+
1163+
if (!m_pWebCore->Initialise(gpuEnabled)) [[unlikely]]
1164+
{
1165+
SAFE_DELETE(m_pWebCore);
1166+
return nullptr;
1167+
}
11611168
}
11621169
return m_pWebCore;
11631170
}

0 commit comments

Comments
 (0)