diff options
author | Emiel Bruijntjes <emiel.bruijntjes@copernica.com> | 2015-04-12 12:11:13 +0200 |
---|---|---|
committer | Emiel Bruijntjes <emiel.bruijntjes@copernica.com> | 2015-04-12 12:11:13 +0200 |
commit | a8f3d4c47b342ef1ce9c951239a1618a0912484c (patch) | |
tree | 893442596323e62762a11f22baae0fa0f3bc3165 /zend | |
parent | a860f85e80c48b821c8cb53fc1d98d5ac2f6f07a (diff) |
Php::dl() function now gets an extra "persistent" parameter to load extensions persistently
Diffstat (limited to 'zend')
-rw-r--r-- | zend/eval.cpp | 9 | ||||
-rw-r--r-- | zend/module.cpp | 30 | ||||
-rw-r--r-- | zend/module.h | 78 |
3 files changed, 113 insertions, 4 deletions
diff --git a/zend/eval.cpp b/zend/eval.cpp index 7ab4957..6d043b1 100644 --- a/zend/eval.cpp +++ b/zend/eval.cpp @@ -93,12 +93,17 @@ Value require_once(const char *filename) /** * Implementation of the dl() function - activate a different PHP extension + * + * If you open an extension persistently, the static variables inside it are + * kept open for as long as apache runs. + * * @param filename + * @param persistent */ -bool dl(const char *filename) +bool dl(const char *filename, bool persistent) { // create the module - Module module(filename); + Module module(filename, persistent); // start the module return module.start(); diff --git a/zend/module.cpp b/zend/module.cpp new file mode 100644 index 0000000..46d03d8 --- /dev/null +++ b/zend/module.cpp @@ -0,0 +1,30 @@ +/** + * Module.cpp + * + * Module implementation file + * + * @author Emiel Bruijntjes <emiel.bruijntjes@copernica.com> + * @copyright 2015 Copernica BV + */ + +/** + * Dependencies + */ +#include "includes.h" + +/** + * Set up namespace + */ +namespace Php { + +/** + * The persistent handles + * @var Module::Persistent + */ +Module::Persistent Module::_persistent; + +/** + * End of namespace + */ +} + diff --git a/zend/module.h b/zend/module.h index 4fa6bce..40cd6f7 100644 --- a/zend/module.h +++ b/zend/module.h @@ -43,7 +43,7 @@ private: * @var zend_module_entry */ zend_module_entry *_entry = nullptr; - + #ifdef ZTS /** * When in thread safety mode, we also keep track of the TSRM_LS var @@ -52,12 +52,82 @@ private: void ***tsrm_ls; #endif + /** + * Internal helper class with persistent modules + */ + class Persistent + { + private: + /** + * The set of handles + * @var std::set + */ + std::set<void*> _handles; + + public: + /** + * Constructor + */ + Persistent() {} + + /** + * Destructor + */ + virtual ~Persistent() + { + // remove all handles + while (!_handles.empty()) + { + // get first handle + auto iter = _handles.begin(); + + // remove the handle + DL_UNLOAD(*iter); + + // remove from set + _handles.erase(iter); + } + } + + /** + * Check whether a handle is already persistently opened + * @param handle + * @return bool + */ + bool contains(void *handle) const + { + return _handles.find(handle) != _handles.end(); + } + + /** + * Add a library persistently + * @param module + */ + void add(const char *module) + { + // insert the handle + _handles.insert(DL_LOAD(module)); + } + }; + + /** + * All persistent modules + * @var Persistent + */ + static Persistent _persistent; + public: /** * Constructor + * + * A module can be loaded persistently. This means that the variables in + * the module will keep in scope for as long as Apache runs, even though + * the extension is not active in other page views + * * @param module Name of the module + * @param persistent Should it be loaded persistently */ - Module(const char *module) + Module(const char *module, bool persistent) { #ifdef ZTS // fetch multi-threading thing @@ -76,6 +146,10 @@ public: // handle should be valid if (!_handle) return; + // if we have to open it persistently, we open it for a second time so that + // the refcounter always stays 1 or higher + if (persistent && !_persistent.contains(_handle)) _persistent.add(module); + // we have to call the get_module() function Symbol<zend_module_entry*()> get_module(_handle, "get_module"); |