[PATCH v5 02/10] msscript.ocx: Release the script engine only when the last module is detached.
Gabriel Ivăncescu
gabrielopcode at gmail.com
Fri Jun 19 07:53:31 CDT 2020
Signed-off-by: Gabriel Ivăncescu <gabrielopcode at gmail.com>
---
dlls/msscript.ocx/msscript.c | 88 +++++++++++++++++++++---------------
1 file changed, 51 insertions(+), 37 deletions(-)
diff --git a/dlls/msscript.ocx/msscript.c b/dlls/msscript.ocx/msscript.c
index 7385ce1..3d65067 100644
--- a/dlls/msscript.ocx/msscript.c
+++ b/dlls/msscript.ocx/msscript.c
@@ -51,6 +51,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(msscript);
struct ScriptControl;
typedef struct ConnectionPoint ConnectionPoint;
+typedef struct ScriptHost ScriptHost;
struct ConnectionPoint {
IConnectionPoint IConnectionPoint_iface;
@@ -68,9 +69,11 @@ struct named_item {
typedef struct {
IScriptModule IScriptModule_iface;
LONG ref;
+
+ ScriptHost *host;
} ScriptModule;
-typedef struct ScriptHost {
+struct ScriptHost {
IActiveScriptSite IActiveScriptSite_iface;
IActiveScriptSiteWindow IActiveScriptSiteWindow_iface;
IServiceProvider IServiceProvider_iface;
@@ -86,7 +89,7 @@ typedef struct ScriptHost {
ScriptModule **modules;
struct list named_items;
-} ScriptHost;
+};
struct ScriptControl {
IScriptControl IScriptControl_iface;
@@ -353,25 +356,6 @@ static ULONG WINAPI ActiveScriptSite_AddRef(IActiveScriptSite *iface)
return ref;
}
-static void release_script_engine(ScriptHost *host)
-{
- if (host->script) {
- IActiveScript_Close(host->script);
- IActiveScript_Release(host->script);
- }
-
- if (host->parse)
- IActiveScriptParse_Release(host->parse);
- if (host->script_dispatch)
- IDispatch_Release(host->script_dispatch);
-
- host->script_dispatch = NULL;
- host->parse = NULL;
- host->script = NULL;
-
- IActiveScriptSite_Release(&host->IActiveScriptSite_iface);
-}
-
static ULONG WINAPI ActiveScriptSite_Release(IActiveScriptSite *iface)
{
ScriptHost *This = impl_from_IActiveScriptSite(iface);
@@ -570,6 +554,32 @@ static const IServiceProviderVtbl ServiceProviderVtbl = {
ServiceProvider_QueryService
};
+static void detach_module(ScriptModule *module)
+{
+ ScriptHost *host = module->host;
+
+ module->host = NULL;
+
+ if (--host->module_count)
+ return;
+
+ if (host->script) {
+ IActiveScript_Close(host->script);
+ IActiveScript_Release(host->script);
+ }
+
+ if (host->parse)
+ IActiveScriptParse_Release(host->parse);
+ if (host->script_dispatch)
+ IDispatch_Release(host->script_dispatch);
+
+ host->script_dispatch = NULL;
+ host->parse = NULL;
+ host->script = NULL;
+
+ IActiveScriptSite_Release(&host->IActiveScriptSite_iface);
+}
+
static HRESULT WINAPI ScriptModule_QueryInterface(IScriptModule *iface, REFIID riid, void **ppv)
{
ScriptModule *This = impl_from_IScriptModule(iface);
@@ -608,7 +618,11 @@ static ULONG WINAPI ScriptModule_Release(IScriptModule *iface)
TRACE("(%p) ref=%d\n", This, ref);
if (!ref)
+ {
+ if (This->host)
+ detach_module(This);
heap_free(This);
+ }
return ref;
}
@@ -754,7 +768,7 @@ static const IScriptModuleVtbl ScriptModuleVtbl = {
ScriptModule_Run
};
-static ScriptModule *create_module(void)
+static ScriptModule *create_module(ScriptHost *host)
{
ScriptModule *module;
@@ -762,18 +776,23 @@ static ScriptModule *create_module(void)
module->IScriptModule_iface.lpVtbl = &ScriptModuleVtbl;
module->ref = 1;
+ module->host = host;
return module;
}
-static void release_modules(ScriptHost *host)
+static void release_modules(ScriptHost *host, BOOL force_detach)
{
- unsigned int i;
+ /* Releasing the modules might destroy the host, so keep copies */
+ unsigned int i, module_count = host->module_count;
+ ScriptModule **modules = host->modules;
- for (i = 0; i < host->module_count; i++)
- IScriptModule_Release(&host->modules[i]->IScriptModule_iface);
+ for (i = 0; i < module_count; i++)
+ {
+ if (force_detach) detach_module(modules[i]);
+ IScriptModule_Release(&modules[i]->IScriptModule_iface);
+ }
- host->module_count = 0;
- heap_free(host->modules);
+ heap_free(modules);
}
static HRESULT WINAPI ScriptModuleCollection_QueryInterface(IScriptModuleCollection *iface, REFIID riid, void **ppv)
@@ -951,7 +970,7 @@ static HRESULT init_script_host(const CLSID *clsid, ScriptHost **ret)
host->modules = heap_alloc_zero(sizeof(*host->modules));
if (!host->modules) return E_OUTOFMEMORY;
- host->modules[0] = create_module();
+ host->modules[0] = create_module(host);
if (!host->modules[0]) {
heap_free(host->modules);
heap_free(host);
@@ -1002,8 +1021,7 @@ static HRESULT init_script_host(const CLSID *clsid, ScriptHost **ret)
return S_OK;
failed:
- release_modules(host);
- release_script_engine(host);
+ release_modules(host, FALSE);
return hr;
}
@@ -1081,10 +1099,7 @@ static ULONG WINAPI ScriptControl_Release(IScriptControl *iface)
if (This->site)
IOleClientSite_Release(This->site);
if (This->host)
- {
- release_modules(This->host);
- release_script_engine(This->host);
- }
+ release_modules(This->host, FALSE);
heap_free(This);
}
@@ -1182,8 +1197,7 @@ static HRESULT WINAPI ScriptControl_put_Language(IScriptControl *iface, BSTR lan
return CTL_E_INVALIDPROPERTYVALUE;
if (This->host) {
- release_modules(This->host);
- release_script_engine(This->host);
+ release_modules(This->host, TRUE);
This->host = NULL;
}
--
2.21.0
More information about the wine-devel
mailing list