diff options
Diffstat (limited to 'documentation')
-rw-r--r-- | documentation/extension-callbacks.html | 81 | ||||
-rw-r--r-- | documentation/install.html | 33 |
2 files changed, 80 insertions, 34 deletions
diff --git a/documentation/extension-callbacks.html b/documentation/extension-callbacks.html index 5c93736..defa550 100644 --- a/documentation/extension-callbacks.html +++ b/documentation/extension-callbacks.html @@ -130,4 +130,83 @@ extern "C" { right before PHP shuts down. If there is anything to clean up, you can install such a callback and run the cleanup code from it. </p> -
\ No newline at end of file +<h2 id="multi-threading">Watch out for multi-threading</h2> +<p> + If your extension runs on a multi-threaded PHP installation, you need to take + extra care. Most PHP installations (Apache, CLI scripts, etc) serve one + request at a time, sequentially. There are however PHP installations that use + multi-threading and that can serve multiple requests in parallel. If your + extension runs on such an environment, you should be aware that your global + (and static!) variables can also be accessed by multiple threads at the same + time. It is your own responsibility to use technologies like std::mutex or + std::atomic to prevent race conditions and conflicts. +</p> +<p> + If your extension is compiled for a multi-threaded environment, the PHP-CPP + header files defines the macro ZTS. You can use this macro to check if you + do have to create special code to deal with threads. +</p> +<p> +<pre class="language-c++"><code>#include <phpcpp.h> + +/** + * Global variable that store the number of times + * the function updateCounters() has been called in total + * @var int + */ +int invokeTotalCount = 0; + +#ifdef ZTS + +/** + * Mutex so that the 'invokeTotalCount' variable is only accessed + * by one process at a time + * @var std::mutex + */ +std::mutex invokeTotalMutex; + +#endif + +/** + * Native function that is callable from PHP + * + * This function updates a number of global variables that count + * the number of times a function was called + */ +void updateCounters() +{ +#ifdef ZTS + + // lock the mutex + std::unique_lock<std::mutex> lock(invokeTotalMutex); + +#endif + + // increment counters + invokeTotalCount++; +} +</code></pre> +</p> +<p> + Another important thing to realize is that PHP also does this locking + internally. If you call a PHP function from you C++ code (like Php::Value("myFunction")()), + or when you access a PHP variable in the Php::GLOBALS array (or one of the + other super-globals), PHP has to lock something to ensure that no + other thread is accessing the same information at the same time. These operations + can be expensive. +</p> +<p> + Good rules of thumb for writing native extensions with PHP-CPP therefore + are: + <ol type="1"> + <li>Do not use global variables</li> + <li>Only call other <i>native</i> functions, and don't call back to PHP</li> + </ol> +</p> +<p> + In our opinion, these rules should not not be limiting for you. The use of global + variables is not considered a very good software design, so you were probably + not even using them, and the reason why you are writing a native extension is + because you want to get away from PHP. Calling back to (slow) PHP is the last + thing you want to do when your application has finally reached native code. +</p> diff --git a/documentation/install.html b/documentation/install.html index d1d1cb0..a498acb 100644 --- a/documentation/install.html +++ b/documentation/install.html @@ -15,39 +15,6 @@ installation instructions and include other platforms as well. </p> -<h2 id="limitations">Limitations</h2> -<p> - At this moment, PHP-CPP only supports single-threaded PHP installations. - Web servers come in a number forms: there are the ones that handle each - page request in different process, and the ones that handle each page request - in the same process, but in a different thread. If you're using such a - multi-threaded PHP installation, you can not use the PHP-CPP library. Most - installations are single-threaded however, so this should not be a show stopper. -</p> -<p> - Are you not sure whether you have a single-threaded or multi-threaded PHP - environment? Just try to compile the PHP-CPP library, if you see a zillion - errors, you can be pretty sure that this is because of your installation - is multi-threaded. -</p> -<p> - The reason why we've chosen not to support multi-threaded PHP installations - lies in the fact that internally the Zend engine uses a very odd system - to ensure thread safety. Essentially, they pass an additional parameter to - each and every function call that holds a pointer-to-a-pointer with thread - information that you can access with specific C macro's, and that you have - to pass on to every other function call that you make. This makes life for - extension writers much harder than is necessary - and is in total conflict - with the core principle of the PHP-CPP library: to make life easy. -</p> -<p> - However, if there is demand for, we will add support for multi-threaded PHP - installations, and hopefully we can even keep the same simple C++ API as we - have now. -</p> - - - <h2 id="download">Download</h2> <p> Installation begins with downloading the source code. You can either |