Fixed libuv resource deallocation.

This commit is contained in:
genxium 2023-01-25 23:47:54 +08:00
parent 8536521136
commit 60bb74169e
7 changed files with 58 additions and 38 deletions

View File

@ -362,7 +362,7 @@
"array": [ "array": [
0, 0,
0, 0,
217.36746944238692, 209.6693197428241,
0, 0,
0, 0,
0, 0,

View File

@ -23,7 +23,8 @@ cc.Class({
// LIFE-CYCLE CALLBACKS: // LIFE-CYCLE CALLBACKS:
onLoad() {}, onLoad() {},
init() { init(mapIns) {
this.mapIns = mapIns;
if (null != this.firstPlayerInfoNode) { if (null != this.firstPlayerInfoNode) {
this.firstPlayerInfoNode.active = false; this.firstPlayerInfoNode.active = false;
} }
@ -53,9 +54,10 @@ cc.Class({
}, },
exitBtnOnClick(evt) { exitBtnOnClick(evt) {
window.clearBoundRoomIdInBothVolatileAndPersistentStorage(); this.mapIns.hideFindingPlayersGUI();
window.closeWSConnection(constants.RET_CODE.UNKNOWN_ERROR, ""); cc.log(`FindingPlayers.exitBtnOnClick`);
cc.director.loadScene('login'); window.closeWSConnection(constants.RET_CODE.BATTLE_STOPPED, "");
window.clearLocalStorageAndBackToLoginScene(false);
}, },
updatePlayersInfo(playerMetas) { updatePlayersInfo(playerMetas) {

View File

@ -360,10 +360,6 @@ cc.Class({
if (self.countdownLabel) { if (self.countdownLabel) {
self.countdownLabel.string = ""; self.countdownLabel.string = "";
} }
if (self.findingPlayerNode) {
const findingPlayerScriptIns = self.findingPlayerNode.getComponent("FindingPlayer");
findingPlayerScriptIns.init();
}
if (self.playersInfoNode) { if (self.playersInfoNode) {
safelyAddChild(self.widgetsAboveAllNode, self.playersInfoNode); safelyAddChild(self.widgetsAboveAllNode, self.playersInfoNode);
} }
@ -470,7 +466,7 @@ cc.Class({
self.findingPlayerNode.width = self.canvasNode.width; self.findingPlayerNode.width = self.canvasNode.width;
self.findingPlayerNode.height = self.canvasNode.height; self.findingPlayerNode.height = self.canvasNode.height;
const findingPlayerScriptIns = self.findingPlayerNode.getComponent("FindingPlayer"); const findingPlayerScriptIns = self.findingPlayerNode.getComponent("FindingPlayer");
findingPlayerScriptIns.init(); findingPlayerScriptIns.init(self);
self.playersInfoNode = cc.instantiate(self.playersInfoPrefab); self.playersInfoNode = cc.instantiate(self.playersInfoPrefab);
@ -1066,6 +1062,7 @@ othersForcedDownsyncRenderFrame=${JSON.stringify(othersForcedDownsyncRenderFrame
logout(byClick /* The case where this param is "true" will be triggered within `ConfirmLogout.js`.*/ , shouldRetainBoundRoomIdInBothVolatileAndPersistentStorage) { logout(byClick /* The case where this param is "true" will be triggered within `ConfirmLogout.js`.*/ , shouldRetainBoundRoomIdInBothVolatileAndPersistentStorage) {
const self = this; const self = this;
const localClearance = () => { const localClearance = () => {
window.closeWSConnection(constants.RET_CODE.BATTLE_STOPPED, "");
window.clearLocalStorageAndBackToLoginScene(shouldRetainBoundRoomIdInBothVolatileAndPersistentStorage); window.clearLocalStorageAndBackToLoginScene(shouldRetainBoundRoomIdInBothVolatileAndPersistentStorage);
} }

View File

@ -34,7 +34,7 @@ window.closeWSConnection = function(code, reason) {
console.log(`"window.clientSession" is already closed or destroyed.`); console.log(`"window.clientSession" is already closed or destroyed.`);
return; return;
} }
console.log(`Closing "window.clientSession" from the client-side.`); console.log(`Closing "window.clientSession" from the client-side with code=${code}.`);
window.clientSession.close(code, reason); window.clientSession.close(code, reason);
} }
@ -240,6 +240,12 @@ window.initPersistentSessionClient = function(onopenCb, expectedRoomId) {
clientSession.onclose = function(evt) { clientSession.onclose = function(evt) {
// [WARNING] The callback "onclose" might be called AFTER the webpage is refreshed with "1001 == evt.code". // [WARNING] The callback "onclose" might be called AFTER the webpage is refreshed with "1001 == evt.code".
console.warn(`The WS clientSession is closed: evt=${JSON.stringify(evt)}, evt.code=${evt.code}`); console.warn(`The WS clientSession is closed: evt=${JSON.stringify(evt)}, evt.code=${evt.code}`);
if (cc.sys.isNative) {
if (mapIns.frameDataLoggingEnabled) {
console.warn(`${mapIns._stringifyRdfIdToActuallyUsedInput()}`);
}
DelayNoMore.UdpSession.closeUdpSession();
}
switch (evt.code) { switch (evt.code) {
case constants.RET_CODE.CLIENT_MISMATCHED_RENDER_FRAME: case constants.RET_CODE.CLIENT_MISMATCHED_RENDER_FRAME:
break; break;
@ -261,7 +267,7 @@ window.initPersistentSessionClient = function(onopenCb, expectedRoomId) {
case constants.RET_CODE.MYSQL_ERROR: case constants.RET_CODE.MYSQL_ERROR:
case constants.RET_CODE.PLAYER_NOT_FOUND: case constants.RET_CODE.PLAYER_NOT_FOUND:
case constants.RET_CODE.PLAYER_CHEATING: case constants.RET_CODE.PLAYER_CHEATING:
case 1006: // Peer(i.e. the backend) gone unexpectedly case 1006: // Peer(i.e. the backend) gone unexpectedly, but not working for "cc.sys.isNative"
if (mapIns.frameDataLoggingEnabled) { if (mapIns.frameDataLoggingEnabled) {
console.warn(`${mapIns._stringifyRdfIdToActuallyUsedInput()}`); console.warn(`${mapIns._stringifyRdfIdToActuallyUsedInput()}`);
} }
@ -270,24 +276,20 @@ window.initPersistentSessionClient = function(onopenCb, expectedRoomId) {
default: default:
break; break;
} }
if (cc.sys.isNative) {
DelayNoMore.UdpSession.closeUdpSession();
}
}; };
}; };
window.clearLocalStorageAndBackToLoginScene = function(shouldRetainBoundRoomIdInBothVolatileAndPersistentStorage) { window.clearLocalStorageAndBackToLoginScene = function(shouldRetainBoundRoomIdInBothVolatileAndPersistentStorage) {
console.warn("+++++++ Calling `clearLocalStorageAndBackToLoginScene`"); console.warn("+++++++ Calling `clearLocalStorageAndBackToLoginScene`");
window.clearSelfPlayer();
if (true != shouldRetainBoundRoomIdInBothVolatileAndPersistentStorage) {
window.clearBoundRoomIdInBothVolatileAndPersistentStorage();
}
if (window.mapIns && window.mapIns.musicEffectManagerScriptIns) { if (window.mapIns && window.mapIns.musicEffectManagerScriptIns) {
window.mapIns.musicEffectManagerScriptIns.stopAllMusic(); window.mapIns.musicEffectManagerScriptIns.stopAllMusic();
} }
window.closeWSConnection(constants.RET_CODE.UNKNOWN_ERROR, "");
window.clearSelfPlayer();
if (true != shouldRetainBoundRoomIdInBothVolatileAndPersistentStorage) {
window.clearBoundRoomIdInBothVolatileAndPersistentStorage();
}
cc.director.loadScene('login'); cc.director.loadScene('login');
}; };

View File

@ -0,0 +1,8 @@
{
"engine_version": "2.2.1",
"has_native": true,
"project_type": "js",
"projectName": "DelayNoMore",
"packageName": "org.genxium.delaynomore"
}

View File

@ -6,7 +6,8 @@
#include "uv/uv.h" #include "uv/uv.h"
uv_udp_t* udpSocket = NULL; uv_udp_t* udpSocket = NULL;
uv_thread_t recvTid;
uv_async_t uvLoopStopSig;
uv_loop_t* loop = NULL; // Only this loop is used for this simple PoC uv_loop_t* loop = NULL; // Only this loop is used for this simple PoC
int const maxPeerCnt = 10; int const maxPeerCnt = 10;
@ -76,11 +77,25 @@ typedef struct client {
short port; short port;
}; };
void _onUvStopSig(uv_async_t* handle) {
uv_stop(loop);
CCLOG("UDP recv loop is signaled to stop in UvThread");
}
void _onWalkCleanup(uv_handle_t* handle, void* data) {
(void)data;
uv_close(handle, NULL);
}
void startRecvLoop(void* arg) { void startRecvLoop(void* arg) {
uv_loop_t* l = (uv_loop_t*)arg; uv_loop_t* l = (uv_loop_t*)arg;
uv_run(l, UV_RUN_DEFAULT); int uvRunRet1 = uv_run(l, UV_RUN_DEFAULT);
CCLOG("UDP recv loop is ended in UvThread, uvRunRet1=%d", uvRunRet1);
uv_walk(l, _onWalkCleanup, NULL);
int uvRunRet2 = uv_run(l, UV_RUN_DEFAULT);
CCLOG("UDP recv loop is ended!"); int uvCloseRet = uv_loop_close(l);
CCLOG("UDP recv loop is closed in UvThread, uvRunRet2=%d, uvCloseRet=%d", uvRunRet2, uvCloseRet);
} }
bool DelayNoMore::UdpSession::openUdpSession(int port) { bool DelayNoMore::UdpSession::openUdpSession(int port) {
@ -96,9 +111,9 @@ bool DelayNoMore::UdpSession::openUdpSession(int port) {
CCLOG("About to open UDP session at port=%d...", port); CCLOG("About to open UDP session at port=%d...", port);
loop = uv_loop_new(); loop = uv_loop_new();
uv_udp_init(loop, udpSocket); uv_udp_init(loop, udpSocket);
uv_async_init(loop, &uvLoopStopSig, _onUvStopSig);
uv_udp_recv_start(udpSocket, _allocBuffer, _onRead); uv_udp_recv_start(udpSocket, _allocBuffer, _onRead);
uv_thread_t recvTid;
uv_thread_create(&recvTid, startRecvLoop, loop); uv_thread_create(&recvTid, startRecvLoop, loop);
CCLOG("Finished opening UDP session at port=%d", port); CCLOG("Finished opening UDP session at port=%d", port);
@ -106,11 +121,6 @@ bool DelayNoMore::UdpSession::openUdpSession(int port) {
return true; return true;
} }
static void _onWalkCleanup(uv_handle_t* handle, void* data) {
(void)data;
uv_close(handle, NULL);
}
bool DelayNoMore::UdpSession::closeUdpSession() { bool DelayNoMore::UdpSession::closeUdpSession() {
CCLOG("About to close udp session and dealloc all resources..."); CCLOG("About to close udp session and dealloc all resources...");
@ -118,17 +128,18 @@ bool DelayNoMore::UdpSession::closeUdpSession() {
peerAddrList[i].authKey = -1; // hardcoded for now peerAddrList[i].authKey = -1; // hardcoded for now
memset((char*)&peerAddrList[i].sockAddrIn, 0, sizeof(peerAddrList[i].sockAddrIn)); memset((char*)&peerAddrList[i].sockAddrIn, 0, sizeof(peerAddrList[i].sockAddrIn));
} }
uv_async_send(&uvLoopStopSig); // The few if not only guaranteed thread safe utility of libuv :) See http://docs.libuv.org/en/v1.x/async.html#c.uv_async_send
CCLOG("Signaling UvThread to end in GameThread...");
uv_thread_join(&recvTid);
uv_stop(loop);
uv_walk(loop, _onWalkCleanup, NULL);
uv_loop_close(loop);
free(udpSocket); free(udpSocket);
free(loop); free(loop);
uv_mutex_destroy(&sendLock); uv_mutex_destroy(&sendLock);
uv_mutex_destroy(&recvLock); uv_mutex_destroy(&recvLock);
CCLOG("Closed udp session and dealloc all resources..."); CCLOG("Closed udp session and dealloc all resources in GameThread...");
return true; return true;
} }
@ -141,7 +152,7 @@ void _onSend(uv_udp_send_t* req, int status) {
} }
bool DelayNoMore::UdpSession::upsertPeerUdpAddr(int joinIndex, CHARC* const ip, int port, uint32_t authKey, int roomCapacity, int selfJoinIndex) { bool DelayNoMore::UdpSession::upsertPeerUdpAddr(int joinIndex, CHARC* const ip, int port, uint32_t authKey, int roomCapacity, int selfJoinIndex) {
CCLOG("Called by js for joinIndex=%d, ip=%s, port=%d, authKey=%lu; roomCapacity=%d, selfJoinIndex=%d.", joinIndex, ip, port, authKey, roomCapacity, selfJoinIndex); CCLOG("upsertPeerUdpAddr called by js for joinIndex=%d, ip=%s, port=%d, authKey=%lu; roomCapacity=%d, selfJoinIndex=%d.", joinIndex, ip, port, authKey, roomCapacity, selfJoinIndex);
uv_ip4_addr(ip, port, &(peerAddrList[joinIndex - 1].sockAddrIn)); uv_ip4_addr(ip, port, &(peerAddrList[joinIndex - 1].sockAddrIn));
peerAddrList[joinIndex - 1].authKey = authKey; peerAddrList[joinIndex - 1].authKey = authKey;

View File

@ -1,7 +1,7 @@
{ {
"excludeScenes": [], "excludeScenes": [],
"packageName": "org.cocos2d.helloworld", "packageName": "org.genxium.delaynomore",
"platform": "web-mobile", "platform": "android",
"startScene": "2d2f792f-a40c-49bb-a189-ed176a246e49", "startScene": "2d2f792f-a40c-49bb-a189-ed176a246e49",
"title": "HelloWorld" "title": "DelayNoMore"
} }