Mercurial > hg > vampy
comparison PyExtensionManager.h @ 37:27bab3a16c9a vampy2final
new branch Vampy2final
author | fazekasgy |
---|---|
date | Mon, 05 Oct 2009 11:28:00 +0000 |
parents | |
children | 5664fe298af2 |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 37:27bab3a16c9a |
---|---|
1 /* | |
2 | |
3 * Vampy : This plugin is a wrapper around the Vamp plugin API. | |
4 * It allows for writing Vamp plugins in Python. | |
5 | |
6 * Centre for Digital Music, Queen Mary University of London. | |
7 * Copyright (C) 2008-2009 Gyorgy Fazekas, QMUL. (See Vamp sources | |
8 * for licence information.) | |
9 | |
10 */ | |
11 | |
12 /* | |
13 PyExtensionManager: This class is responsible for initialisation | |
14 and cleanup of the extension module, as well as the loaded plugin | |
15 module namespaces. | |
16 | |
17 NOTES: Why do we need to clean up the module? | |
18 | |
19 The module exposed by Vampy to the embedded interpreter contains | |
20 callback functions. These functions are accessed via function | |
21 pointers stored in the extension module's namespace dictionary. | |
22 | |
23 Unfortunately, when the shared library is unloaded and reloaded | |
24 during a host session, these addresses might change. | |
25 Therefore, we reinitialise the module dict before each use. | |
26 However, this will cause garbage collection errors or segmentation | |
27 faults, when elements of the dict of the previous session are | |
28 attempted to free. Therefore, we clear the dictinary describing | |
29 the module namespace and replace all fuction pointers with Py_None | |
30 objects in individual plugin module namespaces. The reference | |
31 count on these can be safely decremented next time vampy is loaded | |
32 and the namespaces are reinitialised. | |
33 | |
34 Why doesn't the GC clean this up correctly? | |
35 | |
36 In a normal Python session the GC would deallocate the module | |
37 dict at the end. In embedded python, although the GC appears | |
38 to be called when the shared lib is unloaded, the interpreter | |
39 is reused. Since there is no C/API call to unload modules, | |
40 and at the time of unloading vampy the wrapped function pointers | |
41 are still valid, the GC doesn't collect them, nor are they freed | |
42 by the interpreter. When vampy is reloaded however, the module | |
43 dict will contain invalid addresses. The above procedure solves | |
44 this problem. | |
45 | |
46 | |
47 */ | |
48 | |
49 | |
50 #ifndef _PYEXTENSIONMANAGER_H_ | |
51 #define _PYEXTENSIONMANAGER_H_ | |
52 | |
53 using std::cerr; | |
54 using std::endl; | |
55 using std::string; | |
56 using std::vector; | |
57 | |
58 class PyExtensionManager | |
59 { | |
60 public: | |
61 PyExtensionManager(); | |
62 ~PyExtensionManager(); | |
63 bool initExtension(); | |
64 void setPlugModuleNames(vector<string> pyPlugs); | |
65 void deleteModuleName(string plugKey); | |
66 | |
67 private: | |
68 static char* m_exposedNames[]; | |
69 | |
70 vector<string> m_plugModuleNames; | |
71 PyObject* m_pyGlobalNamespace; | |
72 PyObject* m_pyVampyNamespace; | |
73 | |
74 void cleanAllLocals() const; | |
75 void cleanLocalNamespace(const char* plugModuleName) const; | |
76 void updateAllLocals() const; | |
77 void updateLocalNamespace(const char* plugModuleName) const; | |
78 | |
79 void printDict(PyObject* inDict) const; | |
80 bool cleanModule() const; | |
81 | |
82 }; | |
83 | |
84 #endif | |
85 | |
86 |