Consider this code.
- Code: Select all
#include "examples/shared/app_factory.h"
namespace shared {
CefRefPtr<CefBrowser> g_browser;
void ExecuteJavascript(const std::string &str)
{
if (g_browser)
{
CefRefPtr<CefFrame> frame = g_browser->GetMainFrame();
frame->ExecuteJavaScript(str, frame->GetURL(), 0);
}
}
class My8Handler : public CefV8Handler {
public:
My8Handler() {
ExecuteJavascript("console.log('constructed callback handler')");
}
~My8Handler() {
ExecuteJavascript("console.log('destroyed callback handler')");
}
virtual bool Execute(const CefString& name,
CefRefPtr<CefV8Value> object,
const CefV8ValueList& arguments,
CefRefPtr<CefV8Value>& retval,
CefString& exception) OVERRIDE {
// Function does not exist.
return false;
}
IMPLEMENT_REFCOUNTING(My8Handler);
};
class WindowHandler : public CefV8Handler {
public:
WindowHandler() {}
virtual bool Execute(const CefString& name,
CefRefPtr<CefV8Value> object,
const CefV8ValueList& arguments,
CefRefPtr<CefV8Value>& retval,
CefString& exception) OVERRIDE {
if (name == "createHandle") {
CefRefPtr<CefV8Handler> handler = new My8Handler();
CefRefPtr<CefV8Value> func = CefV8Value::CreateFunction("somefunction", handler);
retval = func;
return true;
}
return false;
}
IMPLEMENT_REFCOUNTING(WindowHandler);
};
class RendererApp :
public CefApp,
public CefRenderProcessHandler {
public:
RendererApp() {
}
CefRefPtr<CefRenderProcessHandler> GetRenderProcessHandler() OVERRIDE {
return this;
}
void OnContextCreated(CefRefPtr<CefBrowser> browser,
CefRefPtr<CefFrame> frame,
CefRefPtr<CefV8Context> context) OVERRIDE {
g_browser = browser;
CefRefPtr<CefV8Value> object = context->GetGlobal();
CefRefPtr<CefV8Handler> handler = new WindowHandler();
CefRefPtr<CefV8Value> func = CefV8Value::CreateFunction("createHandle", handler);
object->SetValue("createHandle", func, V8_PROPERTY_ATTRIBUTE_NONE);
}
void OnContextReleased(CefRefPtr<CefBrowser> browser,
CefRefPtr<CefFrame> frame,
CefRefPtr<CefV8Context> context) OVERRIDE {
g_browser = nullptr;
}
private:
IMPLEMENT_REFCOUNTING(RendererApp);
DISALLOW_COPY_AND_ASSIGN(RendererApp);
};
CefRefPtr<CefApp> CreateRendererProcessApp() {
return new RendererApp();
}
} // namespace shared
And let's say I create 2000 My8Handler handlers.
I ran this in the remote debugger.
- Code: Select all
var i;
for (i = 0; i < 2000; i++) {
window.createHandle();
}
2000(index):1 constructed callback handler
ƒ somefunction() { [native code] }
I would expect that some(if not all) of these handlers would be deleted when "somefunction" is garbage collected.
I'm using Cef 3.3497.1827.ga4f7e36_windows32.
If I reload the page CefV8Handlers are indeed deleted, although if I allocate 2000 I get a stack overflow while they are deleting themselves. 200 or so seems to work just fine.
Am I missing something?