Skip to content

Commit a276fd8

Browse files
committed
Add safety checks in request handler to possibly fix crash on exit (cztomczak#455)
1 parent 66107b2 commit a276fd8

File tree

2 files changed

+74
-3
lines changed

2 files changed

+74
-3
lines changed

src/browser.pyx

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,20 @@ cdef PyBrowser GetPyBrowserById(int browserId):
3333
return g_pyBrowsers[browserId]
3434
return None
3535

36+
cdef py_bool IsBrowserClosed(CefRefPtr[CefBrowser] cefBrowser):
37+
"""Possibly fix Issue #455 by using this helper function to detect
38+
if browser is closing/closed."""
39+
# CefBrowser may sometimes be NULL e.g. Issue #429, Issue #454.
40+
if not cefBrowser.get():
41+
return True
42+
if not cefBrowser.get().GetHost().get():
43+
return True
44+
cdef int browserId = cefBrowser.get().GetIdentifier()
45+
if browserId in g_unreferenced_browsers \
46+
or browserId in g_closed_browsers:
47+
return True
48+
return False
49+
3650
cdef PyBrowser GetPyBrowser(CefRefPtr[CefBrowser] cefBrowser,
3751
callerIdStr="GetPyBrowser"):
3852
"""The second argument 'callerIdStr' is so that a debug

src/handlers/request_handler.pyx

Lines changed: 60 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,11 @@ cdef public cpp_bool RequestHandler_OnBeforeBrowse(
6868
cdef object clientCallback
6969
cdef py_bool returnValue
7070
try:
71+
# Issue #455: CefRequestHandler callbacks still executed after
72+
# browser was closed.
73+
if IsBrowserClosed(cefBrowser):
74+
return False
75+
7176
pyBrowser = GetPyBrowser(cefBrowser, "OnBeforeBrowse")
7277
pyFrame = GetPyFrame(cefFrame)
7378
pyRequest = CreatePyRequest(cefRequest)
@@ -98,6 +103,11 @@ cdef public cpp_bool RequestHandler_OnBeforeResourceLoad(
98103
cdef object clientCallback
99104
cdef py_bool returnValue
100105
try:
106+
# Issue #455: CefRequestHandler callbacks still executed after
107+
# browser was closed.
108+
if IsBrowserClosed(cefBrowser):
109+
return False
110+
101111
pyBrowser = GetPyBrowser(cefBrowser, "OnBeforeResourceLoad")
102112
pyFrame = GetPyFrame(cefFrame)
103113
pyRequest = CreatePyRequest(cefRequest)
@@ -126,6 +136,11 @@ cdef public CefRefPtr[CefResourceHandler] RequestHandler_GetResourceHandler(
126136
cdef object clientCallback
127137
cdef object returnValue
128138
try:
139+
# Issue #455: CefRequestHandler callbacks still executed after
140+
# browser was closed.
141+
if IsBrowserClosed(cefBrowser):
142+
return <CefRefPtr[CefResourceHandler]>NULL
143+
129144
pyBrowser = GetPyBrowser(cefBrowser, "GetResourceHandler")
130145
pyFrame = GetPyFrame(cefFrame)
131146
pyRequest = CreatePyRequest(cefRequest)
@@ -162,6 +177,11 @@ cdef public void RequestHandler_OnResourceRedirect(
162177
cdef PyResponse pyResponse
163178
cdef object clientCallback
164179
try:
180+
# Issue #455: CefRequestHandler callbacks still executed after
181+
# browser was closed.
182+
if IsBrowserClosed(cefBrowser):
183+
return
184+
165185
pyBrowser = GetPyBrowser(cefBrowser, "OnResourceRedirect")
166186
pyFrame = GetPyFrame(cefFrame)
167187
pyOldUrl = CefToPyString(cefOldUrl)
@@ -207,6 +227,11 @@ cdef public cpp_bool RequestHandler_GetAuthCredentials(
207227
cdef list pyPasswordOut
208228
cdef object clientCallback
209229
try:
230+
# Issue #455: CefRequestHandler callbacks still executed after
231+
# browser was closed.
232+
if IsBrowserClosed(cefBrowser):
233+
return False
234+
210235
pyBrowser = GetPyBrowser(cefBrowser, "GetAuthCredentials")
211236
pyFrame = GetPyFrame(cefFrame)
212237
pyIsProxy = bool(cefIsProxy)
@@ -261,6 +286,11 @@ cdef public cpp_bool RequestHandler_OnQuotaRequest(
261286
cdef py_bool returnValue
262287
cdef object clientCallback
263288
try:
289+
# Issue #455: CefRequestHandler callbacks still executed after
290+
# browser was closed.
291+
if IsBrowserClosed(cefBrowser):
292+
return False
293+
264294
pyBrowser = GetPyBrowser(cefBrowser, "OnQuotaRequest")
265295
pyOriginUrl = CefToPyString(cefOriginUrl)
266296
clientCallback = pyBrowser.GetClientCallback("OnQuotaRequest")
@@ -291,10 +321,16 @@ cdef public CefRefPtr[CefCookieManager] RequestHandler_GetCookieManager(
291321
cdef object clientCallback
292322
cdef PyCookieManager returnValue
293323
try:
324+
# Issue #429: in some cases due to a race condition the browser
325+
# may be NULL.
294326
if not cefBrowser.get():
295-
# Bug: In some cases due to a race condition the browser
296-
# may be NULL. Issue #429.
297327
return <CefRefPtr[CefCookieManager]>NULL
328+
329+
# Issue #455: CefRequestHandler callbacks still executed after
330+
# browser was closed.
331+
if IsBrowserClosed(cefBrowser):
332+
return <CefRefPtr[CefCookieManager]>NULL
333+
298334
pyBrowser = GetPyBrowser(cefBrowser, "GetCookieManager")
299335
pyMainUrl = CefToPyString(cefMainUrl)
300336
clientCallback = pyBrowser.GetClientCallback("GetCookieManager")
@@ -325,6 +361,11 @@ cdef public void RequestHandler_OnProtocolExecution(
325361
cdef list pyAllowOSExecutionOut
326362
cdef object clientCallback
327363
try:
364+
# Issue #455: CefRequestHandler callbacks still executed after
365+
# browser was closed.
366+
if IsBrowserClosed(cefBrowser):
367+
return
368+
328369
pyBrowser = GetPyBrowser(cefBrowser, "OnProtocolExecution")
329370
pyUrl = CefToPyString(cefUrl)
330371
pyAllowOSExecutionOut = [bool(cefAllowOSExecution)]
@@ -369,6 +410,12 @@ cdef public cpp_bool RequestHandler_OnBeforePluginLoad(
369410
Debug("WARNING: RequestHandler_OnBeforePluginLoad() failed,"
370411
" Browser object is not available")
371412
return False
413+
414+
# Issue #455: CefRequestHandler callbacks still executed after
415+
# browser was closed.
416+
if IsBrowserClosed(browser):
417+
return False
418+
372419
py_browser = GetPyBrowser(browser, "OnBeforePluginLoad")
373420
py_plugin_info = CreatePyWebPluginInfo(plugin_info)
374421
clientCallback = GetGlobalClientCallback("OnBeforePluginLoad")
@@ -424,6 +471,11 @@ cdef public void RequestHandler_OnRendererProcessTerminated(
424471
cdef PyBrowser pyBrowser
425472
cdef object clientCallback
426473
try:
474+
# Issue #455: CefRequestHandler callbacks still executed after
475+
# browser was closed.
476+
if IsBrowserClosed(cefBrowser):
477+
return
478+
427479
pyBrowser = GetPyBrowser(cefBrowser, "OnRendererProcessTerminated")
428480
clientCallback = pyBrowser.GetClientCallback(
429481
"OnRendererProcessTerminated")
@@ -439,13 +491,18 @@ cdef public void RequestHandler_OnPluginCrashed(
439491
const CefString& cefPluginPath
440492
) except * with gil:
441493
# TODO: plugin may crash during browser creation. Let this callback
442-
# to be set either through cefpython.SetGlobalClientCallback()
494+
# to be set either through cefpython.SetGlobalClientCallback()
443495
# or PyBrowser.SetClientCallback(). Modify the
444496
# PyBrowser.GetClientCallback() implementation to return a global
445497
# callback first if set.
446498
cdef PyBrowser pyBrowser
447499
cdef object clientCallback
448500
try:
501+
# Issue #455: CefRequestHandler callbacks still executed after
502+
# browser was closed.
503+
if IsBrowserClosed(cefBrowser):
504+
return
505+
449506
pyBrowser = GetPyBrowser(cefBrowser, "OnPluginCrashed")
450507
clientCallback = pyBrowser.GetClientCallback("OnPluginCrashed")
451508
if clientCallback:

0 commit comments

Comments
 (0)