facebook/hhvm — pull request #2063 by tstarling (2014-03-13 23:01:01+00:00)
Title: Implement TSRM

Only the last commit (1952111) is new. Its commit message is copied below:

* Implement TSRM globals properly, i.e. have different globals for different threads.
* Enable the ZTS macro. This is generally used by Zend extensions to know if they need to be thread-safe, so for HHVM best answer is yes, please do be thread-safe.
* Move ZendExtension to a separate header file, plus another for inline functions, to allow circular declarations. Having it in zend_modules.h didn't fit the recommended coding style in README.md.
* Implement functions in zend_virtual_cwd.cpp which are now used due to ZTS being defined. This is necessary to link the new version, and fixes some bugs due to HHVM's virtual CWD system not previously being used.
* Move zend_wrap_func() to the .cpp file so that TSRM.h can be included without giving duplicate macro definitions throughout the non-EZC codebase.
* Tested VCWD_REALPATH() by adding a wrapper ezc_realpath(), which has exactly the implementation of realpath() from PHP PHP. Copied in the realpath() tests, replacing realpath() with ezc_realpath().
* expand_filepath_with_mode() was naively copied from Zend and had a few problems with it. Reimplemented.

The major implementation difficulty is ensuring that the existing macros can transmit relevant data to the implementation, and ensuring that the extern macro does actually give access to the globals. I would have liked to put each module's globals in its own __thread variable, but there was no way to supply the name of it to the constructor's caller. Obviously you can't take the address of a __thread variable in the zend_module_entry static initializer.

The implementation here is quite close to the Zend implementation, except with an HPHP::ThreadLocal used for underlying storage. TSRMLS_CC etc. is used as it is in Zend ZTS mode, and should provide a slight speedup over TLS, especially with dynamic linking.