Patch Patch_for_PhpCrashInFCGIModeDuringCoUnintialzie.diff for COM related Bug #32099
Patch version 2011-04-22 23:17 UTC
Return to Bug #32099 |
Download this patch
Patch Revisions:
Developer: thangaraj@gmail.com
Index: php-src-5.3/sapi/cgi/cgi_main.c
===================================================================
--- php-src-5.3/sapi/cgi/cgi_main.c (revision 310436)
+++ php-src-5.3/sapi/cgi/cgi_main.c (working copy)
@@ -2156,7 +2156,16 @@
{
STR_FREE(SG(request_info).path_translated);
- php_request_shutdown((void *) 0);
+ /* Thanga/LTAC: For Win32 non-Thread safe builds using FastCGI
+ * mode invoke PHP request shutdown funtion with '1' in order
+ * to avoid CoUninit - i.e., cache already made CoInit call
+ * for future request processing
+ */
+#if defined(PHP_WIN32) && !defined(ZTS)
+ php_request_shutdown((void *) 1);
+#else
+ php_request_shutdown((void *) 0);
+#endif
if (exit_status == 0) {
exit_status = EG(exit_status);
Index: php-src-5.3/main/main.c
===================================================================
--- php-src-5.3/main/main.c (revision 310436)
+++ php-src-5.3/main/main.c (working copy)
@@ -24,6 +24,8 @@
*/
#define ZEND_INCLUDE_FULL_WINDOWS_HEADERS
+/* Thanga/LTAC: For COM debugging */
+#define ZEND_COM_DEBUG
#include "php.h"
#include <stdio.h>
@@ -1388,9 +1390,25 @@
{
int retval = SUCCESS;
-#ifdef PHP_WIN32
- PG(com_initialized) = 0;
-#endif
+/* Thanga/LTAC:
+ * For Win32 Thread safe builds(ZTS): com_initialized state is thread
+ * specific and it is ok to reset the state during every PHP request
+ * processing startup, since during request cleanup stage we do
+ * CoUninitialize()
+ *
+ * For Win32 non-Thread safe builds: com_initialized state is not reset
+ * in order to avoid possibility of CoInit() done for each request processing
+ * stage and thereby avoiding multiple CoUninit calls on the same thread, such
+ * design resolves crashes induced by PHP scripts using COM objects
+ * intemperately. Note that MSDN recommends using CoUnint API during
+ * application shutdown.
+ */
+#if defined(PHP_WIN32) && defined(ZTS)
+ PG(com_initialized) = 0;
+#ifdef ZEND_COM_DEBUG
+ OutputDebugString("phprequest_startup() com_initialized=0");
+#endif /*ZEND_COM_DEBUG*/
+#endif
#if PHP_SIGCHILD
signal(SIGCHLD, sigchld_handler);
@@ -1566,7 +1584,7 @@
/* {{{ php_request_shutdown
*/
-void php_request_shutdown(void *dummy)
+void php_request_shutdown(void *operatingMode)
{
zend_bool report_memleaks;
TSRMLS_FETCH();
@@ -1661,11 +1679,47 @@
zend_unset_timeout(TSRMLS_C);
} zend_end_try();
-#ifdef PHP_WIN32
- if (PG(com_initialized)) {
- CoUninitialize();
+/* Thanga/LTAC:
+ * For Win32 Thread safe builds(ZTS): allow CoUninit call on each
+ * request shutdown sequence (thread processing the request)
+ *
+ */
+#if defined(PHP_WIN32) && defined(ZTS)
+
+ if (PG(com_initialized)) {
+ CoUninitialize();
PG(com_initialized) = 0;
+#ifdef ZEND_COM_DEBUG
+ {
+ char dbgMsg[1024];
+ sprintf(dbgMsg, "[%d:%d] php_request_Shutdown() ZTS CoUnint() "
+ "com_initialized=0", GetCurrentProcessId(), GetCurrentThreadId());
+ OutputDebugString(dbgMsg);
+ }
+#endif /*ZEND_COM_DEBUG*/
}
+/* Thanga/LTAC:
+ * For Win32 non-Thread safe builds:
+ *
+ * FastCGI mode (operatingMode == 1): Do not uninitialize COM subsystem in order to
+ * avoid php crashes induced by PHP scripts using
+ * COM objects intemperately.
+ *
+ * CGI mode (operatingMode != 1): COM uninitialize can be called.
+ */
+#elif defined(PHP_WIN32) && !defined(ZTS)
+ if (PG(com_initialized) && operatingMode != 1) {
+ CoUninitialize();
+ PG(com_initialized) = 0;
+#ifdef ZEND_COM_DEBUG
+ {
+ char dbgMsg[1024];
+ sprintf(dbgMsg, "[%d:%d] php_request_shutdown() nonTS CoUninit() "
+ "com_initialized=0", GetCurrentProcessId(), GetCurrentThreadId());
+ OutputDebugString(dbgMsg);
+ }
+#endif /*ZEND_COM_DEBUG*/
+ }
#endif
}
/* }}} */
@@ -1678,6 +1732,14 @@
if (!PG(com_initialized)) {
if (CoInitialize(NULL) == S_OK) {
PG(com_initialized) = 1;
+#ifdef ZEND_COM_DEBUG
+ {
+ char dbgMsg[1024];
+ sprintf(dbgMsg, "[%d:%d] CoInit() com_initialized=1",
+ GetCurrentProcessId(), GetCurrentThreadId());
+ OutputDebugString(dbgMsg);
+ }
+#endif /*ZEND_COM_DEBUG*/
}
}
#endif
@@ -1915,6 +1977,21 @@
}
#endif
+/* Thanga/LTAC:
+ * For non-Thread safe Win32 builds: Set/reset com_initilazed flag only during
+ * module/process startup phase. By this method we can call CoUninit call only
+ * during fastcgi process shutdown phase, and thereby adhere to MSDN's
+ * recommended way of calling CoUnint during process shutdown. Note that this
+ * approach resolves crashes induced by PHP scripts using COM objects
+ * intemperately
+ */
+#if defined(PHP_WIN32) && (!defined(ZTS))
+ PG(com_initialized) = 0;
+#ifdef ZEND_COM_DEBUG
+ OutputDebugString("php_module_startup() com_initialized=0");
+#endif /*ZEND_COM_DEBUG*/
+#endif
+
le_index_ptr = zend_register_list_destructors_ex(NULL, NULL, "index pointer", 0);
/* Register constants */
@@ -2178,6 +2255,26 @@
_set_invalid_parameter_handler(old_invalid_parameter_handler);
}
#endif
+
+
+/* Thanga/LTAC:
+ * For Win32 non-Thread safe builds: Cleanup COM subsystem only during process
+ * shutdown.
+ */
+#if defined(PHP_WIN32) && !defined(ZTS)
+ if (PG(com_initialized)) {
+ CoUninitialize();
+ PG(com_initialized) = 0;
+#ifdef ZEND_COM_DEBUG
+ {
+ char dbgMsg[1024];
+ sprintf(dbgMsg, "[%d:%d] php_module_shutdown() CoUninit() "
+ "com_initialized=0", GetCurrentProcessId(), GetCurrentThreadId());
+ OutputDebugString(dbgMsg);
+ }
+#endif /*ZEND_COM_DEBUG*/
+ }
+#endif
}
/* }}} */
|