Skip to content

Commit 2f3a7df

Browse files
DavidDeSimoneminggo
authored andcommitted
Fixing serious XMLHTTP leak when CC_ENABLE_GC_FOR_NATIVE_OBJECTS enabled (#17844)
* Fixing issue where XMLHttpRequests would not have their destructor fire if CC_ENABLE_GC_FOR_NATIVE_OBJECTS was set. This was due to mismanagement of JSHeap object tracing. * Removing unused variables in js_add_object_root.
1 parent 474491a commit 2f3a7df

File tree

3 files changed

+28
-50
lines changed

3 files changed

+28
-50
lines changed

cocos/scripting/js-bindings/manual/cocos2d_specifics.cpp

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -667,7 +667,7 @@ void js_add_object_root(JS::HandleValue target)
667667
}
668668

669669
JS::RootedObject root(cx);
670-
get_or_create_js_obj(cx, jsbObj, "jsb._root", &root);
670+
get_or_create_js_obj(cx, jsbObj, "_root", &root);
671671
JS::RootedValue valRoot(cx, OBJECT_TO_JSVAL(root));
672672

673673
JS::RootedValue retval(cx);
@@ -688,12 +688,6 @@ void js_remove_object_root(JS::HandleValue target)
688688
JSContext *cx = engine->getGlobalContext();
689689
JS::RootedObject global(cx, engine->getGlobalObject());
690690
JSAutoCompartment(cx, global);
691-
JS::RootedObject targetObj(cx, target.toObjectOrNull());
692-
js_proxy_t *pTarget = jsb_get_js_proxy(targetObj);
693-
if (!pTarget)
694-
{
695-
return;
696-
}
697691

698692
JS::RootedObject jsbObj(cx);
699693
get_or_create_js_obj(cx, global, "jsb", &jsbObj);

cocos/scripting/js-bindings/manual/network/XMLHTTPRequest.cpp

Lines changed: 26 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -248,6 +248,7 @@ void MinXmlHttpRequest::handle_requestResponse(cocos2d::network::HttpClient *sen
248248
callback.set(_onloadendCallback);
249249
_notify(callback, JS::HandleValueArray::empty());
250250
}
251+
_clearCallbacks();
251252
return;
252253
}
253254
}
@@ -291,6 +292,7 @@ void MinXmlHttpRequest::handle_requestResponse(cocos2d::network::HttpClient *sen
291292
callback.set(_onloadendCallback);
292293
_notify(callback, JS::HandleValueArray::empty());
293294
}
295+
_clearCallbacks();
294296
}
295297
/**
296298
* @brief Send out request and fire callback when done.
@@ -303,6 +305,27 @@ void MinXmlHttpRequest::_sendRequest(JSContext *cx)
303305
_httpRequest->release();
304306
}
305307

308+
#define REMOVE_CALLBACK(x) \
309+
if (x)\
310+
{ \
311+
JS::RootedValue callback(_cx); \
312+
callback.set(OBJECT_TO_JSVAL(x)); \
313+
js_remove_object_root(callback); \
314+
x = nullptr; \
315+
} \
316+
317+
void MinXmlHttpRequest::_clearCallbacks()
318+
{
319+
JSB_AUTOCOMPARTMENT_WITH_GLOBAL_OBJCET
320+
REMOVE_CALLBACK(_onreadystateCallback)
321+
REMOVE_CALLBACK(_onloadstartCallback)
322+
REMOVE_CALLBACK(_onabortCallback)
323+
REMOVE_CALLBACK(_onerrorCallback)
324+
REMOVE_CALLBACK(_onloadCallback)
325+
REMOVE_CALLBACK(_onloadendCallback)
326+
REMOVE_CALLBACK(_ontimeoutCallback)
327+
}
328+
306329
MinXmlHttpRequest::MinXmlHttpRequest()
307330
: _url()
308331
{
@@ -352,49 +375,7 @@ MinXmlHttpRequest::MinXmlHttpRequest(JSContext *cx)
352375
*/
353376
MinXmlHttpRequest::~MinXmlHttpRequest()
354377
{
355-
JS::RootedValue callback(_cx);
356-
if (_onreadystateCallback)
357-
{
358-
callback.set(OBJECT_TO_JSVAL(_onreadystateCallback));
359-
js_remove_object_root(callback);
360-
}
361-
if (_onloadstartCallback)
362-
{
363-
callback.set(OBJECT_TO_JSVAL(_onloadstartCallback));
364-
js_remove_object_root(callback);
365-
}
366-
if (_onabortCallback)
367-
{
368-
callback.set(OBJECT_TO_JSVAL(_onabortCallback));
369-
js_remove_object_root(callback);
370-
}
371-
if (_onerrorCallback)
372-
{
373-
callback.set(OBJECT_TO_JSVAL(_onerrorCallback));
374-
js_remove_object_root(callback);
375-
}
376-
if (_onloadCallback)
377-
{
378-
callback.set(OBJECT_TO_JSVAL(_onloadCallback));
379-
js_remove_object_root(callback);
380-
}
381-
if (_onloadendCallback)
382-
{
383-
callback.set(OBJECT_TO_JSVAL(_onloadendCallback));
384-
js_remove_object_root(callback);
385-
}
386-
if (_ontimeoutCallback)
387-
{
388-
callback.set(OBJECT_TO_JSVAL(_ontimeoutCallback));
389-
js_remove_object_root(callback);
390-
}
391-
392-
if (_httpRequest)
393-
{
394-
// We don't need to release _httpRequest here since it will be released in the http callback.
395-
// _httpRequest->release();
396-
}
397-
378+
_clearCallbacks();
398379
CC_SAFE_FREE(_data);
399380
CC_SAFE_RELEASE_NULL(_scheduler);
400381
}
@@ -890,6 +871,7 @@ void MinXmlHttpRequest::update(float dt)
890871
{
891872
JS::RootedObject callback(_cx, _ontimeoutCallback);
892873
_notify(callback, JS::HandleValueArray::empty());
874+
_clearCallbacks();
893875
}
894876
_elapsedTime = 0;
895877
_readyState = UNSENT;
@@ -916,6 +898,7 @@ JS_BINDED_FUNC_IMPL(MinXmlHttpRequest, abort)
916898
{
917899
JS::RootedObject callback(cx, _onabortCallback);
918900
_notify(callback, JS::HandleValueArray::empty());
901+
_clearCallbacks();
919902
}
920903

921904
return true;

cocos/scripting/js-bindings/manual/network/XMLHTTPRequest.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,7 @@ class MinXmlHttpRequest : public cocos2d::Ref
9696
void _setHttpRequestData(const char *data, size_t len);
9797
void _sendRequest(JSContext *cx);
9898
void _notify(JS::HandleObject callback, JS::HandleValueArray args);
99+
void _clearCallbacks();
99100

100101
std::string _url;
101102
JSContext* _cx;

0 commit comments

Comments
 (0)