Mercurial > hg > vampy
diff PyExtensionManager.h @ 37:27bab3a16c9a vampy2final
new branch Vampy2final
author | fazekasgy |
---|---|
date | Mon, 05 Oct 2009 11:28:00 +0000 |
parents | |
children | 5664fe298af2 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/PyExtensionManager.h Mon Oct 05 11:28:00 2009 +0000 @@ -0,0 +1,86 @@ +/* + + * Vampy : This plugin is a wrapper around the Vamp plugin API. + * It allows for writing Vamp plugins in Python. + + * Centre for Digital Music, Queen Mary University of London. + * Copyright (C) 2008-2009 Gyorgy Fazekas, QMUL. (See Vamp sources + * for licence information.) + +*/ + +/* +PyExtensionManager: This class is responsible for initialisation +and cleanup of the extension module, as well as the loaded plugin +module namespaces. + +NOTES: Why do we need to clean up the module? + +The module exposed by Vampy to the embedded interpreter contains +callback functions. These functions are accessed via function +pointers stored in the extension module's namespace dictionary. + +Unfortunately, when the shared library is unloaded and reloaded +during a host session, these addresses might change. +Therefore, we reinitialise the module dict before each use. +However, this will cause garbage collection errors or segmentation +faults, when elements of the dict of the previous session are +attempted to free. Therefore, we clear the dictinary describing +the module namespace and replace all fuction pointers with Py_None +objects in individual plugin module namespaces. The reference +count on these can be safely decremented next time vampy is loaded +and the namespaces are reinitialised. + +Why doesn't the GC clean this up correctly? + +In a normal Python session the GC would deallocate the module +dict at the end. In embedded python, although the GC appears +to be called when the shared lib is unloaded, the interpreter +is reused. Since there is no C/API call to unload modules, +and at the time of unloading vampy the wrapped function pointers +are still valid, the GC doesn't collect them, nor are they freed +by the interpreter. When vampy is reloaded however, the module +dict will contain invalid addresses. The above procedure solves +this problem. + + +*/ + + +#ifndef _PYEXTENSIONMANAGER_H_ +#define _PYEXTENSIONMANAGER_H_ + +using std::cerr; +using std::endl; +using std::string; +using std::vector; + +class PyExtensionManager +{ +public: + PyExtensionManager(); + ~PyExtensionManager(); + bool initExtension(); + void setPlugModuleNames(vector<string> pyPlugs); + void deleteModuleName(string plugKey); + +private: + static char* m_exposedNames[]; + + vector<string> m_plugModuleNames; + PyObject* m_pyGlobalNamespace; + PyObject* m_pyVampyNamespace; + + void cleanAllLocals() const; + void cleanLocalNamespace(const char* plugModuleName) const; + void updateAllLocals() const; + void updateLocalNamespace(const char* plugModuleName) const; + + void printDict(PyObject* inDict) const; + bool cleanModule() const; + +}; + +#endif + +