Skip to content
This repository was archived by the owner on Aug 31, 2021. It is now read-only.

Commit aee9230

Browse files
committed
[[ Bug 15671 ]] Ensure 'unload extension' returns a result.
The 'unload extension' command will now report "module in use" in the result if the specified module is in use (i.e. referred to by another loaded module, or a widget). It will also return "module not loaded" if the specified module is not in memory.
1 parent 00f5fee commit aee9230

File tree

7 files changed

+46
-3
lines changed

7 files changed

+46
-3
lines changed

docs/dictionary/command/unload-extension.lcdoc

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,11 @@ Use the <unload extension> <command> to unload a <LiveCode Builder extension>. T
2929
If the extension is a library, its public handlers will no longer be in the message path.
3030
If it is a widget, it will no longer be available as a control to add to a stack.
3131

32-
>*Note:* If there is an instance of a widget still present on a stack in memory, the <unload extension> <command> will fail.
32+
If a module with the given identifier has already been loaded into memory, the result will be set to "module already loaded".
33+
34+
If there is no module with the given identifier loaded into memory, the result will be set to "module not loaded".
35+
36+
If the module is currently in use by another module or a widget, the result will be set to "module in use".
3337

3438
References: load extension (command), loadedExtensions (function), LiveCode Builder extension (glossary)
3539

docs/notes/bugfix-15671.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
# Ensure unload extension reports appropriate status in 'the result'
2+
3+
If 'unload extension' is called on a module which has not been loaded,
4+
the result will be set to "module not loaded".
5+
6+
If 'unload extension' is called on a module which is currently in use,
7+
the result will be set to "module in use".

engine/src/exec-extension.cpp

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -251,6 +251,14 @@ void MCEngineExecUnloadExtension(MCExecContext& ctxt, MCStringRef p_module_name)
251251
for(MCLoadedExtension *t_previous = nil, *t_ext = MCextensions; t_ext != nil; t_previous = t_ext, t_ext = t_ext -> next)
252252
if (MCNameIsEqualTo(t_ext -> module_name, *t_name))
253253
{
254+
// If the retain count of the module is not 1, then it can't be
255+
// unloaded.
256+
if (MCScriptGetRetainCountOfModule(t_ext -> module) != 1)
257+
{
258+
ctxt . SetTheResultToCString("module in use");
259+
return;
260+
}
261+
254262
if (t_ext -> instance != nil)
255263
MCScriptReleaseInstance(t_ext -> instance);
256264
MCScriptReleaseModule(t_ext -> module);
@@ -264,8 +272,11 @@ void MCEngineExecUnloadExtension(MCExecContext& ctxt, MCStringRef p_module_name)
264272

265273
MCextensionschanged = true;
266274

267-
break;
275+
return;
268276
}
277+
278+
// If we get here the module was not found.
279+
ctxt . SetTheResultToCString("module not loaded");
269280
}
270281

271282
void MCEngineGetLoadedExtensions(MCExecContext& ctxt, MCProperListRef& r_list)

libscript/include/libscript/script.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -211,6 +211,9 @@ MCScriptModuleRef MCScriptRetainModule(MCScriptModuleRef module);
211211
// Release a module.
212212
void MCScriptReleaseModule(MCScriptModuleRef module);
213213

214+
// Return the reference count of the given module.
215+
uint32_t MCScriptGetRetainCountOfModule(MCScriptModuleRef module);
216+
214217
// Gets the module ptr for the most recent LCB stack frame on the current thread's stack.
215218
MCScriptModuleRef MCScriptGetCurrentModule(void);
216219

libscript/src/script-module.cpp

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -459,6 +459,16 @@ void MCScriptReleaseModule(MCScriptModuleRef self)
459459
MCScriptReleaseObject(self);
460460
}
461461

462+
uint32_t MCScriptGetRetainCountOfModule(MCScriptModuleRef self)
463+
{
464+
if (nil == self)
465+
return 0;
466+
467+
__MCScriptValidateObjectAndKind__(self, kMCScriptObjectKindModule);
468+
469+
return MCScriptGetRetainCountOfObject(self);
470+
}
471+
462472
////////////////////////////////////////////////////////////////////////////////
463473

464474
bool MCScriptCreateModuleFromStream(MCStreamRef stream, MCScriptModuleRef& r_module)
@@ -501,7 +511,7 @@ bool MCScriptCreateModuleFromStream(MCStreamRef stream, MCScriptModuleRef& r_mod
501511
if (MCNameIsEqualTo(t_other_module -> name, t_module -> name))
502512
{
503513
MCScriptDestroyObject(t_module);
504-
return MCErrorThrowGeneric(MCSTR("module with that name already loaded"));
514+
return MCErrorThrowGeneric(MCSTR("module already loaded"));
505515
}
506516

507517
// Link our module into the global module list.

libscript/src/script-object.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -375,6 +375,13 @@ void MCScriptReleaseObject(MCScriptObject *self)
375375
MCScriptDestroyObject(self);
376376
}
377377

378+
uint32_t MCScriptGetRetainCountOfObject(MCScriptObject *self)
379+
{
380+
__MCScriptValidateObject__(self);
381+
382+
return self -> references;
383+
}
384+
378385
////////////////////////////////////////////////////////////////////////////////
379386

380387
void MCScriptReleaseObjectArray(MCScriptObject **p_elements, uindex_t p_count)

libscript/src/script-private.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@ void MCScriptDestroyObject(MCScriptObject *object);
6969

7070
MCScriptObject *MCScriptRetainObject(MCScriptObject *object);
7171
void MCScriptReleaseObject(MCScriptObject *object);
72+
uint32_t MCScriptGetRetainCountOfObject(MCScriptObject *object);
7273

7374
void MCScriptReleaseObjectArray(MCScriptObject **elements, uindex_t count);
7475

0 commit comments

Comments
 (0)