diff --git a/microscript/ILibDuktape_ChildProcess.c b/microscript/ILibDuktape_ChildProcess.c index 02112c9..c3a2e7d 100644 --- a/microscript/ILibDuktape_ChildProcess.c +++ b/microscript/ILibDuktape_ChildProcess.c @@ -147,10 +147,20 @@ duk_ret_t ILibDuktape_ChildProcess_Kill(duk_context *ctx) duk_ret_t ILibDuktape_ChildProcess_waitExit(duk_context *ctx) { void *chain = Duktape_GetChain(ctx); + if (ILibIsChainBeingDestroyed(chain)) + { + return(ILibDuktape_Error(ctx, "Cannot waitExit() because current thread is exiting")); + } + duk_push_this(ctx); // [spawnedProcess] duk_push_int(ctx, 1); // [spawnedProcess][flag] duk_put_prop_string(ctx, -2, "\xFF_WaitExit"); // [spawnedProcess] + if (!ILibChain_IsLinkAlive(Duktape_GetPointerProperty(ctx, -1, ILibDuktape_ChildProcess_Manager))) + { + return(ILibDuktape_Error(ctx, "Cannot waitExit() because JS Engine is exiting")); + } + void *mods[] = { ILibGetBaseTimer(Duktape_GetChain(ctx)), Duktape_GetPointerProperty(ctx, -1, ILibDuktape_ChildProcess_Manager) }; ILibChain_Continue(chain, (ILibChain_Link**)mods, 2, -1); @@ -231,7 +241,6 @@ duk_ret_t ILibDuktape_ChildProcess_Manager_Finalizer(duk_context *ctx) { duk_get_prop_string(ctx, 0, ILibDuktape_ChildProcess_Manager); ILibProcessPipe_Manager manager = (ILibProcessPipe_Manager)duk_get_pointer(ctx, -1); - ILibChain_SafeRemove(((ILibChain_Link*)manager)->ParentChain, manager); return(0); } diff --git a/microstack/ILibParsers.c b/microstack/ILibParsers.c index e8ef0a7..0eac15a 100644 --- a/microstack/ILibParsers.c +++ b/microstack/ILibParsers.c @@ -1724,7 +1724,7 @@ void ILibChain_SafeAdd(void *chain, void *object) memset(data, 0, sizeof(struct ILibBaseChain_SafeData)); data->Chain = chain; data->Object = object; - + ((ILibChain_Link*)object)->RESERVED = ILibMemory_Canary; ILibLifeTime_Add(baseChain->Timer, data, 0, &ILibChain_SafeAddSink, &ILibChain_Safe_Destroy); } void ILibChain_SafeRemoveEx(void *chain, void *object) @@ -1736,7 +1736,7 @@ void ILibChain_SafeRemoveEx(void *chain, void *object) if (link != NULL) { if (link->DestroyHandler != NULL) { link->DestroyHandler(link); } - free(link); + ILibChain_FreeLink(link); ILibLinkedList_Remove(node); } } @@ -1747,6 +1747,7 @@ void ILibChain_SafeRemoveEx(void *chain, void *object) */ void ILibChain_SafeRemove(void *chain, void *object) { + ((ILibChain_Link*)object)->RESERVED = 0xFFFFFFFF; if (ILibIsChainBeingDestroyed(chain) == 0) { // @@ -1826,6 +1827,7 @@ void ILibAddToChain(void *Chain, void *object) // // Add link to the end of the chain (Linked List) // + ((ILibChain_Link*)object)->RESERVED = ILibMemory_Canary; ILibLinkedList_AddTail(((ILibBaseChain*)Chain)->Links, object); ((ILibChain_Link*)object)->ParentChain = Chain; } @@ -1902,7 +1904,7 @@ void ILibChain_DestroyEx(void *subChain) while (node != NULL && (module = (ILibChain_Link*)ILibLinkedList_GetDataFromNode(node)) != NULL) { if (module->DestroyHandler != NULL) { module->DestroyHandler((void*)module); } - free(module); + ILibChain_FreeLink(module); node = ILibLinkedList_GetNextNode(node); } ILibLinkedList_Destroy(((ILibBaseChain*)subChain)->Links); @@ -2039,7 +2041,7 @@ ILibExportMethod void ILibChain_Continue(void *Chain, ILibChain_Link **modules, if (module != NULL) { if (module->DestroyHandler != NULL) { module->DestroyHandler((void*)module); } - free(module); + ILibChain_FreeLink(module); } } sem_post(&ILibChainLock); @@ -2860,7 +2862,7 @@ ILibExportMethod void ILibStartChain(void *Chain) if (module != NULL) { if (module->DestroyHandler != NULL) { module->DestroyHandler((void*)module); } - free(module); + ILibChain_FreeLink(module); } } sem_post(&ILibChainLock); @@ -2997,7 +2999,7 @@ ILibExportMethod void ILibStartChain(void *Chain) // // After calling the Destroy, we free the module and move to the next // - free(module); + ILibChain_FreeLink(module); chain->node = ILibLinkedList_Remove(chain->node); } @@ -3010,7 +3012,7 @@ ILibExportMethod void ILibStartChain(void *Chain) if (chain->node!=NULL && (module=(ILibChain_Link*)ILibLinkedList_GetDataFromNode(chain->node))!=NULL) { module->DestroyHandler((void*)module); - free(module); + ILibChain_FreeLink(module); ((ILibBaseChain*)Chain)->Timer = NULL; } @@ -3020,7 +3022,7 @@ ILibExportMethod void ILibStartChain(void *Chain) while(chain->node != NULL && (module = (ILibChain_Link*)ILibLinkedList_GetDataFromNode(chain->node)) != NULL) { if(module->DestroyHandler != NULL) {module->DestroyHandler((void*)module);} - free(module); + ILibChain_FreeLink(module); chain->node = ILibLinkedList_GetNextNode(chain->node); } ILibLinkedList_Destroy(((ILibBaseChain*)Chain)->LinksPendingDelete); diff --git a/microstack/ILibParsers.h b/microstack/ILibParsers.h index a1f6175..4a28e40 100644 --- a/microstack/ILibParsers.h +++ b/microstack/ILibParsers.h @@ -328,6 +328,7 @@ int ILibIsRunningOnChainThread(void* chain); void* ParentChain; void* ExtraMemoryPtr; char* MetaData; + int RESERVED; }ILibChain_Link; ILibChain_Link* ILibChain_Link_Allocate(int structSize, int extraMemorySize); int ILibChain_Link_GetExtraMemorySize(ILibChain_Link* link); @@ -932,6 +933,8 @@ int ILibIsRunningOnChainThread(void* chain); ILibExportMethod void ILibStopChain(void *chain); ILibExportMethod void ILibChain_Continue(void *chain, ILibChain_Link **modules, int moduleCount, int maxTimeout); ILibExportMethod void ILibChain_EndContinue(void *chain); + #define ILibChain_FreeLink(link) ((ILibChain_Link*)link)->RESERVED = 0xFFFFFFFF;free(link); + #define ILibChain_IsLinkAlive(link) (((ILibChain_Link*)link)->RESERVED == ILibMemory_Canary) void ILibForceUnBlockChain(void *Chain); void* ILibChain_RunOnMicrostackThreadEx3(void *chain, ILibChain_StartEvent handler, ILibChain_StartEvent abortHandler, void *user); diff --git a/microstack/ILibWrapperWebRTC.c b/microstack/ILibWrapperWebRTC.c index 45b81f0..e23c3b2 100644 --- a/microstack/ILibWrapperWebRTC.c +++ b/microstack/ILibWrapperWebRTC.c @@ -833,7 +833,7 @@ void ILibWrapper_WebRTC_ConnectionFactory_RemoveFromChainSink(void *chain, void if (obj == turnClient) { finished = 1; } if (obj->DestroyHandler != NULL) { obj->DestroyHandler(obj); } - free(obj); + ILibChain_FreeLink(obj); node = ILibLinkedList_Remove(node); } } diff --git a/modules/message-box.js b/modules/message-box.js index 893af1a..76e69a4 100644 --- a/modules/message-box.js +++ b/modules/message-box.js @@ -226,7 +226,19 @@ function macos_messageBox() this._ObjectID = 'message-box'; this._initMessageServer = function _initMessageServer() { - var ipcpath = '/var/tmp/' + process.execPath.split('/').pop() + '_ev'; + var ret = new promise(function (res, rej) { this._res = res; this._rej = rej; }); + + try + { + ret.uid = require('user-sessions').consoleUid(); + } + catch(e) + { + ret._rej(e); + return (ret); + } + + ret.ipcpath = '/var/tmp/' + process.execPath.split('/').pop() + '_ev'; var n; try @@ -237,7 +249,7 @@ function macos_messageBox() { n = 0; } - while (require('fs').existsSync(ipcPath + n)) + while (require('fs').existsSync(ret.ipcpath + n)) { try { @@ -248,17 +260,16 @@ function macos_messageBox() ++n; } } - ipcpath = ipcpath + n; - - var tmpServiceName = 'meshNotificationServer' + n; - + ret.ipcpath = ret.ipcpath + n; + ret.tmpServiceName = 'meshNotificationServer' + n; require('service-manager').manager.installLaunchAgent( { name: tmpServiceName, servicePath: process.execPath, startType: 'AUTO_START', - sessionTypes: ['Aqua'], parameters: ['-exec', "require('message-box').startServer({path: '" + ipcpath + "}).on('close', function(){process.exit();});"] + sessionTypes: ['Aqua'], parameters: ['-exec', "require('message-box').startServer({path: '" + ret.ipcpath + ", service: '" + ret.tmpServiceName + "'}).on('close', function(){process.exit();});"] }); + require('service-manager').getLaunchAgent(ret.tmpServiceName).load(ret.uid); - return (ipcpath); + return (ret); }; @@ -312,7 +323,7 @@ function macos_messageBox() { this.promise._rej('Message Server abruptly disconnected'); }); - + ret.finally(function () { console.log('finally'); }); return (ret); }; this.notify = function notify(title, caption) @@ -364,6 +375,7 @@ function macos_messageBox() if (require('fs').existsSync(options.path)) { require('fs').unlinkSync(options.path); } this._messageServer = require('net').createServer(); + this._messageServer.uid = require('user-sessions').consoleUid(); this._messageServer._options = options; this._messageServer.timer = setTimeout(function (obj) { @@ -434,12 +446,40 @@ function macos_messageBox() this._messageServer.on('~', function () { - try { + //attachDebugger({ webport: 9998, wait: 1 }).then(console.log); + try + { require('fs').unlinkSync(this._options.path); } catch (e) { } + + // Need to uninstall ourselves + var osVersion = require('service-manager').getOSVersion(); + var s; + + try + { + s = require('service-manager').manager.getLaunchAgent(this._options.service); + } + catch(ee) + { + return; // Nothing to do if the service doesn't exist + } + + var child = require('child_process').execFile('/bin/sh', ['sh'], { detached: true }); + if (osVersion.compareTo('10.10') < 0) + { + // Just unload + child.stdin.write('launchctl unload ' + s.plist + '\nrm ' + s.plist + '\nexit\n'); + } + else + { + // Use bootout + child.stdin.write('launchctl bootout gui/' + this.uid + ' ' + s.plist + '\nrm ' + s.plist + '\nexit\n'); + } + child.waitExit(); }); return (this._messageServer);