
Scripting Engine Threading
Because a Windows Script engine can be used in many environments, it is important to keep its execution model as flexible as possible. For example, a server-based host may need to preserve a multithreaded design while using Windows Script in an efficient manner. At the same time, a host that does not use threading, such as a typical application, should not be burdened with threading management. Windows Script achieves this balance by restricting the ways a free-threaded scripting engine can call back to the host, freeing hosts from this burden.
Scripting engines used on servers are typically implemented as free-threading COM objects. This means that methods on the IActiveScript interface and its associated interfaces can be called from any thread in the process, without marshaling. (Unfortunately, this also means that the scripting engine must be implemented as an in-process server, because OLE does not currently support interprocess marshaling of free-threaded objects.) Synchronization is the responsibility of the scripting engine. For scripting engines that are not internally reentrant, or for language models that are not multithreaded, synchronization could be as simple as serializing access to the scripting engine with a mutex. Of course certain methods, such as IActiveScript::InterruptScriptThread, should not be serialized in this way so that a stuck script can be terminated from another thread.
The fact that IActiveScript is typically free-threaded generally implies that the IActiveScriptSite interface and the host's object model should be free-threaded as well. This would make implementation of the host quite difficult, particularly in the common case where the host is a single-threaded Microsoft Windows®-based application with single-threaded or apartment-model ActiveX Controls in its object model. For this reason, the following constraints are placed on the scripting engine's use of IActiveScriptSite:
The script site is always called in the context of a host thread. That is, the scripting engine never calls the script site in the context of a thread that the scripting engine created, but only from within a scripting engine method that was called from the host through IActiveScript and its derivatives, through the exposed scripting engine's dispatch object, through a Windows message, or from an event source in the host's object model.
The script site is never called from within the context of a simple thread state control method (for example, the IActiveScript::InterruptScriptThread method) or from the IActiveScript::Clone method.