I've noticed some behavior I don't quite understand. If I attempt to hold a pointer to CefRefPtr<CefProcessMessage> or a CefRefPtr<CefDictionaryValue> etc. it contains, then access the pointer later, the message or value seems to be invalid.
Some code probably makes it clearer, simplified for brevity. See code comments below:
- Code: Select all
bool MyClient::OnProcessMessageReceived(CefRefPtr<CefBrowser> browser, CefRefPtr<CefFrame> frame, CefProcessId source_process, CefRefPtr<CefProcessMessage> message)
{
CEF_REQUIRE_UI_THREAD();
CEF_ML_SCOPED_LOCK(_mutex);
Q_ASSERT(browser);
auto* h = getMyProcHandler();
Q_ASSERT(message->IsValid());
Q_ASSERT(frame->IsValid());
// TODO: For some reason, if we pass the original message CefRefPtr<CefProcessMessage> we get a crash
// when calling GetString() on the message.
// The message becomes invalid on my main thread even though all ref-counting is correctly applied
// during closure capture. Manually calling AddRef() made no difference. Suspect a bug in CEF, since
// CefProcessMessage claims to be thread-safe.
auto msgCopy = message->Copy(); // *** NOTE: Copy() ***
my::utils::dispatchToMyMainThread([=]() {
REQUIRE_MY_MAIN_THREAD();
Q_ASSERT(msgCopy->IsValid()); // This is false if we pass original message instead of a copy.
Q_ASSERT(frame->IsValid());
h->onProcessMessageReceived(browser, frame, source_process, msgCopy);
});
return true;
}
Since CefProcessMessage is thread safe and both threads are in the browser process, I would expect to not have to make a copy.
Why does the Copy() work and not the original CefProcessMessage?