summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEmiel Bruijntjes <emiel.bruijntjes@copernica.com>2015-02-05 22:59:15 +0100
committerEmiel Bruijntjes <emiel.bruijntjes@copernica.com>2015-02-05 22:59:15 +0100
commit7c7121e92b3ebd2763b4b03227eeec09461d8ea9 (patch)
treed4de14152798da46907795e773feac742d27a769
parentba32a85db3f1130d01ccf228e253d2e717c53c70 (diff)
refactored the initialization and shutdown of extension objects (code is moved from a static method to a real member method), and more importantly: fixed initialization of the PhpCpp::Functor class, previously, we created the class an runtime whenever we needed it, but that turned out to be a cause for crashes when php stopped, this has also been solved
-rw-r--r--include/class.h6
-rw-r--r--zend/extensionimpl.cpp119
-rw-r--r--zend/extensionimpl.h11
-rw-r--r--zend/function.cpp24
-rw-r--r--zend/functor.cpp56
-rw-r--r--zend/functor.h29
6 files changed, 168 insertions, 77 deletions
diff --git a/include/class.h b/include/class.h
index 45bc236..c7ae32a 100644
--- a/include/class.h
+++ b/include/class.h
@@ -585,11 +585,11 @@ private:
/**
* Namespaces and the function have access to the private base class,
- * so that the classes can be registered (the function object needs
- * this to register the Functor class).
+ * so that the classes can be registered, and the Functor object needs
+ * this to register the PhpCpp::Functor class.
*/
friend class Namespace;
- friend class Function;
+ friend class Functor;
/**
* All Php::Class<AnyThing> also need access to the base class to
diff --git a/zend/extensionimpl.cpp b/zend/extensionimpl.cpp
index 47b4419..d313498 100644
--- a/zend/extensionimpl.cpp
+++ b/zend/extensionimpl.cpp
@@ -114,43 +114,8 @@ int ExtensionImpl::processStartup(int type, int module_number TSRMLS_DC)
// get the extension
auto *extension = find(module_number TSRMLS_CC);
- // array contains ini settings
- auto *entries = extension->_ini = new zend_ini_entry[extension->_data->iniVariables()+1];
-
- // the entry that we're filling
- int i=0;
-
- // Fill the php.ini entries
- extension->_data->iniVariables([entries, &i, module_number](Ini &ini) {
-
- // initialize the function
- zend_ini_entry *entry = &entries[i];
-
- // fill the property
- ini.fill(entry, module_number);
-
- // move on to the next iteration
- i++;
- });
-
- // last entry should be set to all zero's
- memset(&entries[i], 0, sizeof(zend_ini_entry));
-
- // register ini entries in Zend core
- zend_register_ini_entries(entries, module_number TSRMLS_CC);
-
// initialize the extension
- extension->initialize(module_number TSRMLS_CC);
-
- // remember that we're initialized (when you use "apache reload" it is
- // possible that the processStartup() method is called more than once)
- extension->_locked = true;
-
- // is the callback registered?
- if (extension->_onStartup) extension->_onStartup();
-
- // done
- return BOOL2SUCCESS(true);
+ return BOOL2SUCCESS(extension->initialize(module_number TSRMLS_CC));
}
/**
@@ -165,20 +130,8 @@ int ExtensionImpl::processShutdown(int type, int module_number TSRMLS_DC)
// get the extension
auto *extension = find(module_number TSRMLS_CC);
- // unregister the ini entries
- zend_unregister_ini_entries(module_number TSRMLS_CC);
-
- // destruct the ini entries
- if (extension->_ini) delete[] extension->_ini;
-
- // forget the ini entries
- extension->_ini = nullptr;
-
- // is the callback registered?
- if (extension->_onShutdown) extension->_onShutdown();
-
// done
- return BOOL2SUCCESS(true);
+ return BOOL2SUCCESS(extension->shutdown(module_number TSRMLS_CC));
}
/**
@@ -381,9 +334,35 @@ zend_module_entry *ExtensionImpl::module()
* Initialize the extension after it was started
* @param module_number
* @param tsrm_ls
+ * @return bool
*/
-void ExtensionImpl::initialize(int module_number TSRMLS_DC)
+bool ExtensionImpl::initialize(int module_number TSRMLS_DC)
{
+ // array contains ini settings
+ _ini = new zend_ini_entry[_data->iniVariables()+1];
+
+ // the entry that we're filling
+ int i = 0;
+
+ // Fill the php.ini entries
+ _data->iniVariables([this, &i, module_number](Ini &ini) {
+
+ // initialize the function
+ zend_ini_entry *entry = &_ini[i];
+
+ // fill the property
+ ini.fill(entry, module_number);
+
+ // move on to the next iteration
+ i++;
+ });
+
+ // last entry should be set to all zero's
+ memset(&_ini[i], 0, sizeof(zend_ini_entry));
+
+ // register ini entries in Zend core
+ zend_register_ini_entries(_ini, module_number TSRMLS_CC);
+
// the constants are registered after the module is ready
_data->constants([module_number TSRMLS_CC](const std::string &prefix, Constant &c) {
@@ -397,6 +376,46 @@ void ExtensionImpl::initialize(int module_number TSRMLS_DC)
// forward to implementation class
c.implementation()->initialize(&c, prefix TSRMLS_CC);
});
+
+ // initialize the PhpCpp::Functor class
+ Functor::initialize(TSRMLS_C);
+
+ // remember that we're initialized (when you use "apache reload" it is
+ // possible that the processStartup() method is called more than once)
+ _locked = true;
+
+ // is the callback registered?
+ if (_onStartup) _onStartup();
+
+ // done
+ return true;
+}
+
+/**
+ * Function that is called when the extension shuts down
+ * @param module_number
+ * @param tsrmls
+ * @return bool
+ */
+bool ExtensionImpl::shutdown(int module_number TSRMLS_DC)
+{
+ // unregister the ini entries
+ zend_unregister_ini_entries(module_number TSRMLS_CC);
+
+ // destruct the ini entries
+ if (_ini) delete[] _ini;
+
+ // forget the ini entries
+ _ini = nullptr;
+
+ // shutdown the functor class
+ Functor::shutdown(TSRMLS_C);
+
+ // is the callback registered?
+ if (_onShutdown) _onShutdown();
+
+ // done
+ return true;
}
/**
diff --git a/zend/extensionimpl.h b/zend/extensionimpl.h
index 83deb36..3a0fc63 100644
--- a/zend/extensionimpl.h
+++ b/zend/extensionimpl.h
@@ -106,8 +106,17 @@ private:
* Initialize the namespace after it was registered
* @param module_number
* @param tsrm_ls
+ * @return bool
+ */
+ bool initialize(int module_number TSRMLS_DC);
+
+ /**
+ * Shutdown the extension
+ * @param module_number
+ * @param tsrm_ls
+ * @return bool
*/
- void initialize(int module_number TSRMLS_DC);
+ bool shutdown(int module_number TSRMLS_DC);
/**
* Function that is called when the extension initializes
diff --git a/zend/function.cpp b/zend/function.cpp
index 01267c0..dddc489 100644
--- a/zend/function.cpp
+++ b/zend/function.cpp
@@ -18,32 +18,10 @@
namespace Php {
/**
- * Function returns a pointer to the class-entry of the Functor class
- * @return zend_class_entry
- */
-zend_class_entry *Function::entry()
-{
- // and the actual class entry
- static zend_class_entry *entry = nullptr;
-
- // is the class entry already valid?
- if (entry) return entry;
-
- // construct functor object
- static std::unique_ptr<ClassBase> functor(new Class<Functor>("Functor"));
-
- // we need the TSRMLS variable
- TSRMLS_FETCH();
-
- // initialize the functor class
- return entry = functor->implementation()->initialize(functor.get(), "" TSRMLS_CC);
-}
-
-/**
* Constructor
* @param function The function to be wrapped
*/
-Function::Function(const std::function<Php::Value(Php::Parameters&)> &function) : Value(Object(entry(), new Functor(function))) {}
+Function::Function(const std::function<Php::Value(Php::Parameters&)> &function) : Value(Object(Functor::entry(), new Functor(function))) {}
/**
* End of namespace
diff --git a/zend/functor.cpp b/zend/functor.cpp
new file mode 100644
index 0000000..7d0404b
--- /dev/null
+++ b/zend/functor.cpp
@@ -0,0 +1,56 @@
+/**
+ * Functor.cpp
+ *
+ * Implementation file for the functor class
+ *
+ * @author Emiel Bruijntjes <emiel.bruijntjes@copernica.com>
+ * @copyright 2015 Copernica BV
+ */
+
+/**
+ * Dependencies
+ */
+#include "includes.h"
+
+/**
+ * Set up namespace
+ */
+namespace Php {
+
+/**
+ * The classentry
+ * @var zend_class_entry
+ */
+zend_class_entry *Functor::_entry = nullptr;
+
+/**
+ * Initialize the class
+ * @param tsrmls
+ */
+void Functor::initialize(TSRMLS_D)
+{
+ // leap out if the class entry is already set
+ if (_entry) return;
+
+ // construct functor object
+ static std::unique_ptr<ClassBase> functor(new Class<Functor>("PhpCpp::Functor"));
+
+ // initialize the functor class
+ _entry = functor->implementation()->initialize(functor.get(), "" TSRMLS_CC);
+}
+
+/**
+ * Shutdown the class
+ * @param tsrmls
+ */
+void Functor::shutdown(TSRMLS_D)
+{
+ // we forget the entry
+ _entry = nullptr;
+}
+
+/**
+ * End of namespace
+ */
+}
+
diff --git a/zend/functor.h b/zend/functor.h
index 7d5bef5..503a05c 100644
--- a/zend/functor.h
+++ b/zend/functor.h
@@ -46,12 +46,41 @@ public:
return _function(params);
}
+ /**
+ * Get the functor class entry
+ * @return zend_class_entry
+ */
+ static zend_class_entry *entry()
+ {
+ // get the "member"
+ return _entry;
+ }
+
+ /**
+ * Initialize the class
+ * @param tsrmls
+ */
+ static void initialize(TSRMLS_D);
+
+ /**
+ * Shutdown the class
+ * @param tsrmls
+ */
+ static void shutdown(TSRMLS_D);
+
private:
/**
* The std::function that is wrapped in PHP code
* @var std::function
*/
const std::function<Value(Parameters &params)> _function;
+
+ /**
+ * The classentry
+ * @var zend_class_entry
+ */
+ static zend_class_entry *_entry;
+
};
/**