With the help of Scotts last suggestion, I made some changes. It seems
to work, but then I don't really know how to test it properly. I can
verify that A) it allows userland code the grace period of 1 second
for shutting down and B) shuts down regardless of the userland error
handler returning or not. I have tested by running the following:

    php -r 'function err() { echo "Shutting down"; while (true) {}};
set_error_handler("err"); set_time_limit(2); while (true) {}'

New patch is attached.

-- 
troels
Index: Zend/zend.c
===================================================================
--- Zend/zend.c	(revision 296628)
+++ Zend/zend.c	(working copy)
@@ -551,6 +551,7 @@
 	EG(exit_status) = 0;
 	EG(saved_fpu_cw) = NULL;
 	EG(active) = 0;
+	EG(zend_timeout_softswitch) = 0;
 }
 /* }}} */
 
Index: Zend/zend_globals.h
===================================================================
--- Zend/zend_globals.h	(revision 296628)
+++ Zend/zend_globals.h	(working copy)
@@ -235,6 +235,7 @@
 
 	/* timeout support */
 	int timeout_seconds;
+        int zend_timeout_softswitch;
 
 	int lambda_count;
 
Index: Zend/zend_execute_API.c
===================================================================
--- Zend/zend_execute_API.c	(revision 296628)
+++ Zend/zend_execute_API.c	(working copy)
@@ -1306,16 +1306,22 @@
 
 ZEND_API void zend_timeout(int dummy) /* {{{ */
 {
-	TSRMLS_FETCH();
-
-	if (zend_on_timeout) {
-		zend_on_timeout(EG(timeout_seconds) TSRMLS_CC);
+	if (EG(zend_timeout_softswitch) == 0) {
+		EG(zend_timeout_softswitch) = 1;
+		zend_unset_timeout(TSRMLS_C);
+		zend_set_timeout(1, 1);
+		zend_error(E_WARNING, "Maximum execution time of %d second%s exceeded", EG(timeout_seconds), EG(timeout_seconds) == 1 ? "" : "s");
+	} else {
+		TSRMLS_FETCH();
+ 
+		if (zend_on_timeout) {
+			zend_on_timeout(EG(timeout_seconds) TSRMLS_CC);
+		}
+ 
+		zend_error(E_ERROR, "Maximum execution time of %d second%s exceeded", EG(timeout_seconds), EG(timeout_seconds) == 1 ? "" : "s");
 	}
-
-	zend_error(E_ERROR, "Maximum execution time of %d second%s exceeded", EG(timeout_seconds), EG(timeout_seconds) == 1 ? "" : "s");
 }
-/* }}} */
-
+ /* }}} */
 #ifdef ZEND_WIN32
 static LRESULT CALLBACK zend_timeout_WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) /* {{{ */
 {
-- 
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to