mirror of
https://github.com/genxium/DelayNoMore
synced 2024-12-26 19:58:56 +00:00
Fixed libuv resource deallocation.
This commit is contained in:
parent
8536521136
commit
60bb74169e
@ -362,7 +362,7 @@
|
|||||||
"array": [
|
"array": [
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
217.36746944238692,
|
209.6693197428241,
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
|
@ -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) {
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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');
|
||||||
};
|
};
|
||||||
|
|
||||||
|
8
frontend/build-templates/.cocos-project.json
Normal file
8
frontend/build-templates/.cocos-project.json
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
{
|
||||||
|
"engine_version": "2.2.1",
|
||||||
|
"has_native": true,
|
||||||
|
"project_type": "js",
|
||||||
|
"projectName": "DelayNoMore",
|
||||||
|
"packageName": "org.genxium.delaynomore"
|
||||||
|
}
|
||||||
|
|
@ -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;
|
||||||
|
|
||||||
|
@ -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"
|
||||||
}
|
}
|
Loading…
Reference in New Issue
Block a user