iliaa                                    Thu, 02 Jun 2011 21:16:50 +0000

Revision: http://svn.php.net/viewvc?view=revision&revision=311740

Log:
Zend Signal Handling (see RFC: https://wiki.php.net/rfc/zendsignals)
This needs to go into 5.4 as well, but will wait for Pierre to review win32 
situation

# Patch by Lucas Nealan, Arnaud Le Blanc, Brian Shire & Ilia Alshanetsky

Changed paths:
    U   php/php-src/trunk/TSRM/TSRM.c
    U   php/php-src/trunk/TSRM/TSRM.h
    U   php/php-src/trunk/TSRM/tsrm.m4
    U   php/php-src/trunk/Zend/Makefile.am
    U   php/php-src/trunk/Zend/Zend.m4
    U   php/php-src/trunk/Zend/zend.c
    U   php/php-src/trunk/Zend/zend.h
    U   php/php-src/trunk/Zend/zend_alloc.c
    U   php/php-src/trunk/Zend/zend_execute_API.c
    U   php/php-src/trunk/Zend/zend_hash.c
    A   php/php-src/trunk/Zend/zend_signal.c
    A   php/php-src/trunk/Zend/zend_signal.h
    U   php/php-src/trunk/configure.in
    U   php/php-src/trunk/ext/pcntl/php_signal.c
    U   php/php-src/trunk/ext/standard/info.c
    U   php/php-src/trunk/ext/standard/tests/general_functions/phpinfo.phpt
    U   php/php-src/trunk/main/SAPI.c
    U   php/php-src/trunk/main/main.c

Modified: php/php-src/trunk/TSRM/TSRM.c
===================================================================
--- php/php-src/trunk/TSRM/TSRM.c	2011-06-02 20:01:40 UTC (rev 311739)
+++ php/php-src/trunk/TSRM/TSRM.c	2011-06-02 21:16:50 UTC (rev 311740)
@@ -710,7 +710,23 @@
 #endif
 }

+/*
+  Changes the signal mask of the calling thread
+*/
+#ifdef HAVE_SIGPROCMASK
+TSRM_API int tsrm_sigmask(int how, const sigset_t *set, sigset_t *oldset)
+{
+	TSRM_ERROR((TSRM_ERROR_LEVEL_INFO, "Changed sigmask in thread: %ld", tsrm_thread_id()));
+	/* TODO: add support for other APIs */
+#ifdef PTHREADS
+	return pthread_sigmask(how, set, oldset);
+#else
+	return sigprocmask(how, set, oldset);
+#endif
+}
+#endif

+
 TSRM_API void *tsrm_set_new_thread_begin_handler(tsrm_thread_begin_func_t new_thread_begin_handler)
 {
 	void *retval = (void *) tsrm_new_thread_begin_handler;

Modified: php/php-src/trunk/TSRM/TSRM.h
===================================================================
--- php/php-src/trunk/TSRM/TSRM.h	2011-06-02 20:01:40 UTC (rev 311739)
+++ php/php-src/trunk/TSRM/TSRM.h	2011-06-02 21:16:50 UTC (rev 311740)
@@ -90,6 +90,10 @@
 # define MUTEX_T beos_ben *
 #endif

+#ifdef HAVE_SIGNAL_H
+#include <signal.h>
+#endif
+
 typedef void (*ts_allocate_ctor)(void *, void ***);
 typedef void (*ts_allocate_dtor)(void *, void ***);

@@ -138,6 +142,9 @@
 TSRM_API void tsrm_mutex_free(MUTEX_T mutexp);
 TSRM_API int tsrm_mutex_lock(MUTEX_T mutexp);
 TSRM_API int tsrm_mutex_unlock(MUTEX_T mutexp);
+#ifdef HAVE_SIGPROCMASK
+TSRM_API int tsrm_sigmask(int how, const sigset_t *set, sigset_t *oldset);
+#endif

 TSRM_API void *tsrm_set_new_thread_begin_handler(tsrm_thread_begin_func_t new_thread_begin_handler);
 TSRM_API void *tsrm_set_new_thread_end_handler(tsrm_thread_end_func_t new_thread_end_handler);

Modified: php/php-src/trunk/TSRM/tsrm.m4
===================================================================
--- php/php-src/trunk/TSRM/tsrm.m4	2011-06-02 20:01:40 UTC (rev 311739)
+++ php/php-src/trunk/TSRM/tsrm.m4	2011-06-02 21:16:50 UTC (rev 311740)
@@ -30,6 +30,8 @@

 AC_CHECK_HEADERS(stdarg.h)

+AC_CHECK_FUNCS(sigprocmask)
+
 ])



Modified: php/php-src/trunk/Zend/Makefile.am
===================================================================
--- php/php-src/trunk/Zend/Makefile.am	2011-06-02 20:01:40 UTC (rev 311739)
+++ php/php-src/trunk/Zend/Makefile.am	2011-06-02 21:16:50 UTC (rev 311740)
@@ -17,7 +17,7 @@
 	zend_objects_API.c zend_ts_hash.c zend_stream.c \
 	zend_default_classes.c \
 	zend_iterators.c zend_interfaces.c zend_exceptions.c \
-	zend_strtod.c zend_closures.c zend_float.c zend_string.c
+	zend_strtod.c zend_closures.c zend_float.c zend_string.c zend_signal.c

 libZend_la_LDFLAGS =
 libZend_la_LIBADD = @ZEND_EXTRA_LIBS@

Modified: php/php-src/trunk/Zend/Zend.m4
===================================================================
--- php/php-src/trunk/Zend/Zend.m4	2011-06-02 20:01:40 UTC (rev 311739)
+++ php/php-src/trunk/Zend/Zend.m4	2011-06-02 21:16:50 UTC (rev 311740)
@@ -392,9 +392,23 @@

 AC_CHECK_FUNCS(mremap)

+
+AC_CHECK_FUNC(sigaction, [
+	ZEND_SIGNALS=yes
+	AC_DEFINE(ZEND_SIGNALS, 1, [Use zend signal handling])
+	AC_DEFINE(HAVE_SIGACTION, 1, [Whether sigaction() is available])
+], [
+	ZEND_SIGNALS=no
 ])
+if test "$ZEND_SIGNALS" = "yes"; then
+	CFLAGS="$CFLAGS -DZEND_SIGNALS"
+fi

+AC_MSG_CHECKING(whether to enable zend signal handling)
+AC_MSG_RESULT($ZEND_SIGNALS)

+])
+
 AC_DEFUN([LIBZEND_CPLUSPLUS_CHECKS],[

 ])

Modified: php/php-src/trunk/Zend/zend.c
===================================================================
--- php/php-src/trunk/Zend/zend.c	2011-06-02 20:01:40 UTC (rev 311739)
+++ php/php-src/trunk/Zend/zend.c	2011-06-02 21:16:50 UTC (rev 311740)
@@ -108,6 +108,9 @@
  	STD_ZEND_INI_BOOLEAN("zend.multibyte", "0", ZEND_INI_PERDIR, OnUpdateBool, multibyte,      zend_compiler_globals, compiler_globals)
  	ZEND_INI_ENTRY("zend.script_encoding",			NULL,		ZEND_INI_ALL,		OnUpdateScriptEncoding)
  	STD_ZEND_INI_BOOLEAN("zend.detect_unicode",			"1",	ZEND_INI_ALL,		OnUpdateBool, detect_unicode, zend_compiler_globals, compiler_globals)
+#ifdef ZEND_SIGNALS
+	STD_ZEND_INI_BOOLEAN("zend.signal_check", "0", ZEND_INI_SYSTEM, OnUpdateBool, check, zend_signal_globals_t, zend_signal_globals)
+#endif
 ZEND_INI_END()


@@ -659,8 +662,10 @@
 	}
 	zend_stream_open_function = utility_functions->stream_open_function;
 	zend_message_dispatcher_p = utility_functions->message_handler;
+#ifndef ZEND_SIGNALS
 	zend_block_interruptions = utility_functions->block_interruptions;
 	zend_unblock_interruptions = utility_functions->unblock_interruptions;
+#endif
 	zend_get_configuration_directive_p = utility_functions->get_configuration_directive;
 	zend_ticks_function = utility_functions->ticks_function;
 	zend_on_timeout = utility_functions->on_timeout;
@@ -791,6 +796,9 @@

 void zend_shutdown(TSRMLS_D) /* {{{ */
 {
+#ifdef ZEND_SIGNALS
+	zend_signal_shutdown(TSRMLS_C);
+#endif
 #ifdef ZEND_WIN32
 	zend_shutdown_timeout_thread();
 #endif

Modified: php/php-src/trunk/Zend/zend.h
===================================================================
--- php/php-src/trunk/Zend/zend.h	2011-06-02 20:01:40 UTC (rev 311739)
+++ php/php-src/trunk/Zend/zend.h	2011-06-02 21:16:50 UTC (rev 311740)
@@ -531,8 +531,10 @@
 	int (*write_function)(const char *str, uint str_length);
 	FILE *(*fopen_function)(const char *filename, char **opened_path TSRMLS_DC);
 	void (*message_handler)(long message, void *data TSRMLS_DC);
+#ifndef ZEND_SIGNALS
 	void (*block_interruptions)(void);
 	void (*unblock_interruptions)(void);
+#endif
 	int (*get_configuration_directive)(const char *name, uint name_length, zval *contents);
 	void (*ticks_function)(int ticks);
 	void (*on_timeout)(int seconds TSRMLS_DC);
@@ -678,8 +680,10 @@
 extern ZEND_API int (*zend_printf)(const char *format, ...) ZEND_ATTRIBUTE_PTR_FORMAT(printf, 1, 2);
 extern ZEND_API zend_write_func_t zend_write;
 extern ZEND_API FILE *(*zend_fopen)(const char *filename, char **opened_path TSRMLS_DC);
+#ifndef ZEND_SIGNALS
 extern ZEND_API void (*zend_block_interruptions)(void);
 extern ZEND_API void (*zend_unblock_interruptions)(void);
+#endif
 extern ZEND_API void (*zend_ticks_function)(int ticks);
 extern ZEND_API void (*zend_error_cb)(int type, const char *error_filename, const uint error_lineno, const char *format, va_list args) ZEND_ATTRIBUTE_PTR_FORMAT(printf, 4, 0);
 extern void (*zend_on_timeout)(int seconds TSRMLS_DC);
@@ -702,9 +706,16 @@

 #define ZEND_UV(name) (zend_uv.name)

+#ifndef ZEND_SIGNALS
 #define HANDLE_BLOCK_INTERRUPTIONS()		if (zend_block_interruptions) { zend_block_interruptions(); }
 #define HANDLE_UNBLOCK_INTERRUPTIONS()		if (zend_unblock_interruptions) { zend_unblock_interruptions(); }
+#else
+#include "zend_signal.h"

+#define HANDLE_BLOCK_INTERRUPTIONS()		SIGG(depth)++;
+#define HANDLE_UNBLOCK_INTERRUPTIONS()		if (UNEXPECTED((--SIGG(depth))==SIGG(blocked))) { zend_signal_handler_unblock(TSRMLS_C); }
+#endif
+
 BEGIN_EXTERN_C()
 ZEND_API void zend_message_dispatcher(long message, void *data TSRMLS_DC);


Modified: php/php-src/trunk/Zend/zend_alloc.c
===================================================================
--- php/php-src/trunk/Zend/zend_alloc.c	2011-06-02 20:01:40 UTC (rev 311739)
+++ php/php-src/trunk/Zend/zend_alloc.c	2011-06-02 21:16:50 UTC (rev 311740)
@@ -1882,7 +1882,12 @@
 	size_t segment_size;
 	zend_mm_segment *segment;
 	int keep_rest = 0;
+#ifdef ZEND_SIGNALS
+	TSRMLS_FETCH();
+#endif

+	HANDLE_BLOCK_INTERRUPTIONS();
+
 	if (EXPECTED(ZEND_MM_SMALL_SIZE(true_size))) {
 		size_t index = ZEND_MM_BUCKET_INDEX(true_size);
 		size_t bitmap;
@@ -1902,6 +1907,7 @@
 			heap->cached -= true_size;
 			ZEND_MM_CHECK_MAGIC(best_fit, MEM_BLOCK_CACHED);
 			ZEND_MM_SET_DEBUG_INFO(best_fit, size, 1, 0);
+			HANDLE_UNBLOCK_INTERRUPTIONS();
 			return ZEND_MM_DATA_OF(best_fit);
  		}
 #if ZEND_MM_CACHE_STAT
@@ -1955,8 +1961,6 @@
 			segment_size = heap->block_size;
 		}

-		HANDLE_BLOCK_INTERRUPTIONS();
-
 		if (segment_size < true_size ||
 		    heap->real_size + segment_size > heap->limit) {
 			/* Memory limit overflow */
@@ -1978,8 +1982,8 @@
 #if ZEND_MM_CACHE
 			zend_mm_free_cache(heap);
 #endif
+out_of_memory:
 			HANDLE_UNBLOCK_INTERRUPTIONS();
-out_of_memory:
 #if ZEND_DEBUG
 			zend_mm_safe_error(heap, "Out of memory (allocated %ld) at %s:%d (tried to allocate %lu bytes)", heap->real_size, __zend_filename, __zend_lineno, size);
 #else
@@ -2007,7 +2011,6 @@
 	} else {
 zend_mm_finished_searching_for_block:
 		/* remove from free list */
-		HANDLE_BLOCK_INTERRUPTIONS();
 		ZEND_MM_CHECK_MAGIC(best_fit, MEM_BLOCK_FREED);
 		ZEND_MM_CHECK_COOKIE(best_fit);
 		ZEND_MM_CHECK_BLOCK_LINKAGE(best_fit);
@@ -2055,11 +2058,15 @@
 	zend_mm_block *mm_block;
 	zend_mm_block *next_block;
 	size_t size;
-
+#ifdef ZEND_SIGNALS
+	TSRMLS_FETCH();
+#endif
 	if (!ZEND_MM_VALID_PTR(p)) {
 		return;
 	}

+	HANDLE_BLOCK_INTERRUPTIONS();
+
 	mm_block = ZEND_MM_HEADER_OF(p);
 	size = ZEND_MM_BLOCK_SIZE(mm_block);
 	ZEND_MM_CHECK_PROTECTION(mm_block);
@@ -2082,12 +2089,11 @@
 			heap->cache_stat[index].max_count = heap->cache_stat[index].count;
 		}
 #endif
+		HANDLE_UNBLOCK_INTERRUPTIONS();
 		return;
 	}
 #endif

-	HANDLE_BLOCK_INTERRUPTIONS();
-
 	heap->size -= size;

 	next_block = ZEND_MM_BLOCK_AT(mm_block, size);
@@ -2117,10 +2123,14 @@
 	size_t true_size;
 	size_t orig_size;
 	void *ptr;
+	TSRMLS_FETCH();

 	if (UNEXPECTED(!p) || !ZEND_MM_VALID_PTR(p)) {
 		return _zend_mm_alloc_int(heap, size ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC);
 	}
+
+	HANDLE_BLOCK_INTERRUPTIONS();
+
 	mm_block = ZEND_MM_HEADER_OF(p);
 	true_size = ZEND_MM_TRUE_SIZE(size);
 	orig_size = ZEND_MM_BLOCK_SIZE(mm_block);
@@ -2136,7 +2146,6 @@
 		if (remaining_size >= ZEND_MM_ALIGNED_MIN_HEADER_SIZE) {
 			zend_mm_free_block *new_free_block;

-			HANDLE_BLOCK_INTERRUPTIONS();
 			next_block = ZEND_MM_BLOCK_AT(mm_block, orig_size);
 			if (ZEND_MM_IS_FREE_BLOCK(next_block)) {
 				remaining_size += ZEND_MM_FREE_BLOCK_SIZE(next_block);
@@ -2152,9 +2161,9 @@
 			/* add the new free block to the free list */
 			zend_mm_add_to_free_list(heap, new_free_block);
 			heap->size += (true_size - orig_size);
-			HANDLE_UNBLOCK_INTERRUPTIONS();
 		}
 		ZEND_MM_SET_DEBUG_INFO(mm_block, size, 0, 0);
+		HANDLE_UNBLOCK_INTERRUPTIONS();
 		return p;
 	}

@@ -2197,6 +2206,7 @@
 			}
 #endif

+			HANDLE_UNBLOCK_INTERRUPTIONS();
 			return ptr;
 		}
 	}
@@ -2211,7 +2221,6 @@
 			size_t block_size = orig_size + ZEND_MM_FREE_BLOCK_SIZE(next_block);
 			size_t remaining_size = block_size - true_size;

-			HANDLE_BLOCK_INTERRUPTIONS();
 			zend_mm_remove_from_free_list(heap, (zend_mm_free_block *) next_block);

 			if (remaining_size < ZEND_MM_ALIGNED_MIN_HEADER_SIZE) {
@@ -2242,7 +2251,6 @@
 			return p;
 		} else if (ZEND_MM_IS_FIRST_BLOCK(mm_block) &&
 				   ZEND_MM_IS_GUARD_BLOCK(ZEND_MM_BLOCK_AT(next_block, ZEND_MM_FREE_BLOCK_SIZE(next_block)))) {
-			HANDLE_BLOCK_INTERRUPTIONS();
 			zend_mm_remove_from_free_list(heap, (zend_mm_free_block *) next_block);
 			goto realloc_segment;
 		}
@@ -2253,7 +2261,6 @@
 		size_t block_size;
 		size_t remaining_size;

-		HANDLE_BLOCK_INTERRUPTIONS();
 realloc_segment:
 		/* segment size, size of block and size of guard block */
 		if (true_size > heap->block_size - (ZEND_MM_ALIGNED_SEGMENT_SIZE + ZEND_MM_ALIGNED_HEADER_SIZE)) {
@@ -2286,8 +2293,8 @@
 #if ZEND_MM_CACHE
 			zend_mm_free_cache(heap);
 #endif
+out_of_memory:
 			HANDLE_UNBLOCK_INTERRUPTIONS();
-out_of_memory:
 #if ZEND_DEBUG
 			zend_mm_safe_error(heap, "Out of memory (allocated %ld) at %s:%d (tried to allocate %ld bytes)", heap->real_size, __zend_filename, __zend_lineno, size);
 #else
@@ -2351,6 +2358,7 @@
 	memcpy(ptr, p, orig_size - ZEND_MM_ALIGNED_HEADER_SIZE);
 #endif
 	_zend_mm_free_int(heap, p ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC);
+	HANDLE_UNBLOCK_INTERRUPTIONS();
 	return ptr;
 }

@@ -2539,12 +2547,18 @@
 ZEND_API void *_ecalloc(size_t nmemb, size_t size ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC)
 {
 	void *p;
+#ifdef ZEND_SIGNALS
+	TSRMLS_FETCH();
+#endif
+	HANDLE_BLOCK_INTERRUPTIONS();

 	p = _safe_emalloc(nmemb, size, 0 ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC);
 	if (UNEXPECTED(p == NULL)) {
+		HANDLE_UNBLOCK_INTERRUPTIONS();
 		return p;
 	}
 	memset(p, 0, size * nmemb);
+	HANDLE_UNBLOCK_INTERRUPTIONS();
 	return p;
 }

@@ -2552,26 +2566,40 @@
 {
 	int length;
 	char *p;
+#ifdef ZEND_SIGNALS
+	TSRMLS_FETCH();
+#endif

+	HANDLE_BLOCK_INTERRUPTIONS();
+
 	length = strlen(s)+1;
 	p = (char *) _emalloc(length ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC);
 	if (UNEXPECTED(p == NULL)) {
+		HANDLE_UNBLOCK_INTERRUPTIONS();
 		return p;
 	}
 	memcpy(p, s, length);
+	HANDLE_UNBLOCK_INTERRUPTIONS();
 	return p;
 }

 ZEND_API char *_estrndup(const char *s, uint length ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC)
 {
 	char *p;
+#ifdef ZEND_SIGNALS
+	TSRMLS_FETCH();
+#endif

+	HANDLE_BLOCK_INTERRUPTIONS();
+
 	p = (char *) _emalloc(length+1 ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC);
 	if (UNEXPECTED(p == NULL)) {
+		HANDLE_UNBLOCK_INTERRUPTIONS();
 		return p;
 	}
 	memcpy(p, s, length);
 	p[length] = 0;
+	HANDLE_UNBLOCK_INTERRUPTIONS();
 	return p;
 }

@@ -2579,15 +2607,22 @@
 ZEND_API char *zend_strndup(const char *s, uint length)
 {
 	char *p;
+#ifdef ZEND_SIGNALS
+	TSRMLS_FETCH();
+#endif

+	HANDLE_BLOCK_INTERRUPTIONS();
+
 	p = (char *) malloc(length+1);
 	if (UNEXPECTED(p == NULL)) {
+		HANDLE_UNBLOCK_INTERRUPTIONS();
 		return p;
 	}
 	if (length) {
 		memcpy(p, s, length);
 	}
 	p[length] = 0;
+	HANDLE_UNBLOCK_INTERRUPTIONS();
 	return p;
 }


Modified: php/php-src/trunk/Zend/zend_execute_API.c
===================================================================
--- php/php-src/trunk/Zend/zend_execute_API.c	2011-06-02 20:01:40 UTC (rev 311739)
+++ php/php-src/trunk/Zend/zend_execute_API.c	2011-06-02 21:16:50 UTC (rev 311740)
@@ -1469,7 +1469,7 @@
 #	ifdef HAVE_SETITIMER
 	{
 		struct itimerval t_r;		/* timeout requested */
-		sigset_t sigset;
+		int signo;

 		if(seconds) {
 			t_r.it_value.tv_sec = seconds;
@@ -1478,25 +1478,27 @@
 #	ifdef __CYGWIN__
 			setitimer(ITIMER_REAL, &t_r, NULL);
 		}
-		if(reset_signals) {
-			signal(SIGALRM, zend_timeout);
-			sigemptyset(&sigset);
-			sigaddset(&sigset, SIGALRM);
-		}
+		signo = SIGALRM;
 #	else
 			setitimer(ITIMER_PROF, &t_r, NULL);
 		}
-		if(reset_signals) {
-			signal(SIGPROF, zend_timeout);
+		signo = SIGPROF;
+#	endif
+
+		if (reset_signals) {
+#	ifdef ZEND_SIGNALS
+			zend_signal(signo, zend_timeout TSRMLS_CC);
+#	else
+			sigset_t sigset;
+
+			signal(signo, zend_timeout);
 			sigemptyset(&sigset);
-			sigaddset(&sigset, SIGPROF);
-		}
+			sigaddset(&sigset, signo);
+			sigprocmask(SIG_UNBLOCK, &sigset, NULL);
 #	endif
-		if(reset_signals) {
-			sigprocmask(SIG_UNBLOCK, &sigset, NULL);
 		}
 	}
-#	endif
+#	endif /* HAVE_SETITIMER */
 #endif
 }
 /* }}} */

Modified: php/php-src/trunk/Zend/zend_hash.c
===================================================================
--- php/php-src/trunk/Zend/zend_hash.c	2011-06-02 20:01:40 UTC (rev 311739)
+++ php/php-src/trunk/Zend/zend_hash.c	2011-06-02 21:16:50 UTC (rev 311740)
@@ -197,6 +197,9 @@
 	ulong h;
 	uint nIndex;
 	Bucket *p;
+#ifdef ZEND_SIGNALS
+	TSRMLS_FETCH();
+#endif

 	IS_CONSISTENT(ht);

@@ -276,6 +279,9 @@
 {
 	uint nIndex;
 	Bucket *p;
+#ifdef ZEND_SIGNALS
+	TSRMLS_FETCH();
+#endif

 	IS_CONSISTENT(ht);

@@ -431,6 +437,9 @@
 static int zend_hash_do_resize(HashTable *ht)
 {
 	Bucket **t;
+#ifdef ZEND_SIGNALS
+	TSRMLS_FETCH();
+#endif

 	IS_CONSISTENT(ht);

@@ -475,6 +484,9 @@
 {
 	uint nIndex;
 	Bucket *p;
+#ifdef ZEND_SIGNALS
+	TSRMLS_FETCH();
+#endif

 	IS_CONSISTENT(ht);

@@ -595,6 +607,9 @@
 static Bucket *zend_hash_apply_deleter(HashTable *ht, Bucket *p)
 {
 	Bucket *retval;
+#ifdef ZEND_SIGNALS
+	TSRMLS_FETCH();
+#endif

 	HANDLE_BLOCK_INTERRUPTIONS();
 	if (p->pLast) {
@@ -1194,6 +1209,9 @@
 ZEND_API int zend_hash_update_current_key_ex(HashTable *ht, int key_type, const char *str_index, uint str_length, ulong num_index, int mode, HashPosition *pos)
 {
 	Bucket *p;
+#ifdef ZEND_SIGNALS
+	TSRMLS_FETCH();
+#endif

 	p = pos ? (*pos) : ht->pInternalPointer;


Added: php/php-src/trunk/Zend/zend_signal.c
===================================================================
--- php/php-src/trunk/Zend/zend_signal.c	                        (rev 0)
+++ php/php-src/trunk/Zend/zend_signal.c	2011-06-02 21:16:50 UTC (rev 311740)
@@ -0,0 +1,414 @@
+/*
+  +----------------------------------------------------------------------+
+  | Zend Signal Handling                                                 |
+  +----------------------------------------------------------------------+
+  | Copyright (c) 2008 The PHP Group                                     |
+  +----------------------------------------------------------------------+
+  | This source file is subject to version 3.01 of the PHP license,      |
+  | that is bundled with this package in the file LICENSE, and is        |
+  | available through the world-wide-web at the following url:           |
+  | http://www.php.net/license/3_01.txt                                  |
+  | If you did not receive a copy of the PHP license and are unable to   |
+  | obtain it through the world-wide-web, please send a note to          |
+  | lice...@php.net so we can mail you a copy immediately.               |
+  +----------------------------------------------------------------------+
+  | Authors: Lucas Nealan <lu...@php.net>                                |
+  |          Arnaud Le Blanc <lbarn...@php.net>                          |
+  +----------------------------------------------------------------------+
+
+   This software was contributed to PHP by Facebook Inc. in 2008.
+
+   Future revisions and derivatives of this source code must acknowledge
+   Facebook Inc. as the original contributor of this module by leaving
+   this note intact in the source code.
+
+   All other licensing and usage conditions are those of the PHP Group.
+*/
+
+ /* $Id$ */
+
+#define _GNU_SOURCE
+#include <string.h>
+
+#include "zend.h"
+#include "zend_globals.h"
+
+#ifdef HAVE_SIGNAL_H
+#include <signal.h>
+#endif
+
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+#ifdef ZEND_SIGNALS
+
+#include "zend_signal.h"
+
+#ifdef ZTS
+ZEND_API int zend_signal_globals_id;
+#else
+zend_signal_globals_t zend_signal_globals;
+#endif
+
+static void zend_signal_handler(int signo, siginfo_t *siginfo, void *context TSRMLS_DC);
+static int zend_signal_register(int signo, void (*handler)(int, siginfo_t*, void*) TSRMLS_DC);
+
+#ifdef __CYGWIN__
+#define TIMEOUT_SIG SIGALRM
+#else
+#define TIMEOUT_SIG SIGPROF
+#endif
+
+static int zend_sigs[] = { TIMEOUT_SIG, SIGHUP, SIGINT, SIGQUIT, SIGTERM, SIGUSR1, SIGUSR2 };
+
+#define SA_FLAGS_MASK ~(SA_NODEFER | SA_RESETHAND)
+
+/* True globals, written only at process startup */
+static zend_signal_entry_t global_orig_handlers[NSIG];
+static sigset_t            global_sigmask;
+
+/* {{{ zend_signal_handler_defer
+ *  Blocks signals if in critical section */
+void zend_signal_handler_defer(int signo, siginfo_t *siginfo, void *context)
+{
+	int errno_save = errno;
+	zend_signal_queue_t *queue, *qtmp;
+	TSRMLS_FETCH();
+
+	if (SIGG(active)) {
+		if (SIGG(depth) == 0) { /* try to handle signal */
+			if (SIGG(blocked) != -1) { /* inverse */
+				SIGG(blocked) = -1; /* signal is not blocked */
+			}
+			if (SIGG(running) == 0) {
+				SIGG(running) = 1;
+				zend_signal_handler(signo, siginfo, context TSRMLS_CC);
+
+				queue = SIGG(phead);
+				SIGG(phead) = NULL;
+
+				while (queue) {
+					zend_signal_handler(queue->zend_signal.signo, queue->zend_signal.siginfo, queue->zend_signal.context TSRMLS_CC);
+					qtmp = queue->next;
+					queue->next = SIGG(pavail);
+					queue->zend_signal.signo = 0;
+					SIGG(pavail) = queue;
+					queue = qtmp;
+				}
+				SIGG(running) = 0;
+			}
+		} else { /* delay signal handling */
+			SIGG(blocked) = 0; /* signal is blocked */
+
+			if ((queue = SIGG(pavail))) { /* if none available it's simply forgotton */
+				SIGG(pavail) = queue->next;
+				queue->zend_signal.signo = signo;
+				queue->zend_signal.siginfo = siginfo;
+				queue->zend_signal.context = context;
+				queue->next = NULL;
+
+				if (SIGG(phead) && SIGG(ptail)) {
+					SIGG(ptail)->next = queue;
+				} else {
+					SIGG(phead) = queue;
+				}
+				SIGG(ptail) = queue;
+			}
+#if ZEND_DEBUG
+			else { /* this may not be safe to do, but could work and be useful */
+				zend_output_debug_string(0, "zend_signal: not enough queue storage, lost signal (%d)", signo);
+			}
+#endif
+		}
+	} else {
+		/* need to just run handler if we're inactive and getting a signal */
+		zend_signal_handler(signo, siginfo, context TSRMLS_CC);
+	}
+
+	errno = errno_save;
+} /* }}} */
+
+/* {{{ zend_signal_handler_unblock
+ * Handle deferred signal from HANDLE_UNBLOCK_ALARMS */
+void zend_signal_handler_unblock(TSRMLS_D)
+{
+	zend_signal_queue_t *queue;
+	zend_signal_t zend_signal;
+
+	if (SIGG(active)) {
+		SIGNAL_BEGIN_CRITICAL(); /* procmask to protect handler_defer as if it were called by the kernel */
+		queue = SIGG(phead);
+		SIGG(phead) = queue->next;
+		zend_signal = queue->zend_signal;
+		queue->next = SIGG(pavail);
+		queue->zend_signal.signo = 0;
+		SIGG(pavail) = queue;
+
+		zend_signal_handler_defer(zend_signal.signo, zend_signal.siginfo, zend_signal.context);
+		SIGNAL_END_CRITICAL();
+	}
+}
+/* }}} */
+
+/* {{{ zend_signal_handler
+ *  Call the previously registered handler for a signal
+ */
+static void zend_signal_handler(int signo, siginfo_t *siginfo, void *context TSRMLS_DC)
+{
+	int errno_save = errno;
+	struct sigaction sa = {{0}};
+	sigset_t sigset;
+	zend_signal_entry_t p_sig = SIGG(handlers)[signo-1];
+
+	if (p_sig.handler == SIG_DFL) { /* raise default handler */
+		if (sigaction(signo, NULL, &sa) == 0) {
+			sa.sa_handler = SIG_DFL;
+			sigemptyset(&sa.sa_mask);
+
+			sigemptyset(&sigset);
+			sigaddset(&sigset, signo);
+
+			if (sigaction(signo, &sa, NULL) == 0) {
+				/* throw away any blocked signals */
+				sigprocmask(SIG_UNBLOCK, &sigset, NULL);
+				raise(signo);
+			}
+		}
+	} else if (p_sig.handler != SIG_IGN) { /* ignore SIG_IGN */
+		if (p_sig.flags & SA_SIGINFO) {
+			if (p_sig.flags & SA_RESETHAND) {
+				SIGG(handlers)[signo-1].flags   = 0;
+				SIGG(handlers)[signo-1].handler = SIG_DFL;
+			}
+			(*(void (*)(int, siginfo_t*, void*))p_sig.handler)(signo, siginfo, context);
+		} else {
+			(*(void (*)(int))p_sig.handler)(signo);
+		}
+	}
+
+	errno = errno_save;
+} /* }}} */
+
+/* {{{ zend_sigaction
+ *  Register a signal handler that will be deferred in critical sections */
+ZEND_API int zend_sigaction(int signo, const struct sigaction *act, struct sigaction *oldact TSRMLS_DC)
+{
+	struct sigaction sa = {{0}};
+	sigset_t sigset;
+
+	if (oldact != NULL) {
+		oldact->sa_flags   = SIGG(handlers)[signo-1].flags;
+		oldact->sa_handler = (void *) SIGG(handlers)[signo-1].handler;
+		oldact->sa_mask    = global_sigmask;
+	}
+	if (act != NULL) {
+		SIGG(handlers)[signo-1].flags = act->sa_flags;
+		if (act->sa_flags & SA_SIGINFO) {
+			SIGG(handlers)[signo-1].handler = (void *) act->sa_sigaction;
+		} else {
+			SIGG(handlers)[signo-1].handler = (void *) act->sa_handler;
+		}
+
+		sa.sa_flags     = SA_SIGINFO | (act->sa_flags & SA_FLAGS_MASK);
+		sa.sa_sigaction = zend_signal_handler_defer;
+		sa.sa_mask      = global_sigmask;
+
+		if (sigaction(signo, &sa, NULL) < 0) {
+			zend_error(E_ERROR, "Error installing signal handler for %d", signo);
+		}
+
+		/* unsure this signal is not blocked */
+		sigemptyset(&sigset);
+		sigaddset(&sigset, signo);
+		zend_sigprocmask(SIG_UNBLOCK, &sigset, NULL);
+	}
+
+	return SUCCESS;
+}
+/* }}} */
+
+/* {{{ zend_signal
+ *  Register a signal handler that will be deferred in critical sections */
+ZEND_API int zend_signal(int signo, void (*handler)(int) TSRMLS_DC)
+{
+	struct sigaction sa = {{0}};
+
+	sa.sa_flags   = 0;
+	sa.sa_handler = handler;
+	sa.sa_mask    = global_sigmask;
+
+	return zend_sigaction(signo, &sa, NULL TSRMLS_CC);
+}
+/* }}} */
+
+/* {{{ zend_signal_register
+ *  Set a handler for a signal we want to defer.
+ *  Previously set handler must have been saved before.
+ */
+static int zend_signal_register(int signo, void (*handler)(int, siginfo_t*, void*) TSRMLS_DC)
+{
+	struct sigaction sa = {{0}};
+
+	if (sigaction(signo, NULL, &sa) == 0) {
+		if ((sa.sa_flags & SA_SIGINFO) && sa.sa_sigaction == handler) {
+			return FAILURE;
+		}
+
+		SIGG(handlers)[signo-1].flags = sa.sa_flags;
+		if (sa.sa_flags & SA_SIGINFO) {
+			SIGG(handlers)[signo-1].handler = (void *)sa.sa_sigaction;
+		} else {
+			SIGG(handlers)[signo-1].handler = (void *)sa.sa_handler;
+		}
+
+		sa.sa_flags     = SA_SIGINFO; /* we'll use a siginfo handler */
+		sa.sa_sigaction = handler;
+		sa.sa_mask      = global_sigmask;
+
+		if (sigaction(signo, &sa, NULL) < 0) {
+			zend_error(E_ERROR, "Error installing signal handler for %d", signo);
+		}
+
+		return SUCCESS;
+	}
+	return FAILURE;
+} /* }}} */
+
+/* {{{ zend_signal_activate
+ *  Install our signal handlers, per request */
+void zend_signal_activate(TSRMLS_D)
+{
+	int x;
+
+	memcpy(&SIGG(handlers), &global_orig_handlers, sizeof(global_orig_handlers));
+
+	for (x=0; x < sizeof(zend_sigs) / sizeof(*zend_sigs); x++) {
+		zend_signal_register(zend_sigs[x], zend_signal_handler_defer TSRMLS_CC);
+	}
+
+	SIGG(active) = 1;
+	SIGG(depth)  = 0;
+} /* }}} */
+
+/* {{{ zend_signal_deactivate
+ * */
+void zend_signal_deactivate(TSRMLS_D)
+{
+	int x;
+	struct sigaction sa = {{0}};
+
+	if (SIGG(check)) {
+		if (SIGG(depth) != 0) {
+			zend_error(E_CORE_WARNING, "zend_signal: shutdown with non-zero blocking depth (%d)", SIGG(depth));
+		}
+		/* did anyone steal our installed handler */
+		for (x=0; x < sizeof(zend_sigs) / sizeof(*zend_sigs); x++) {
+			sigaction(zend_sigs[x], NULL, &sa);
+			if (sa.sa_sigaction != zend_signal_handler_defer) {
+				zend_error(E_CORE_WARNING, "zend_signal: handler was replaced for signal (%d) after startup", zend_sigs[x]);
+			}
+		}
+	}
+
+	SIGNAL_BEGIN_CRITICAL();
+	SIGG(active) = 0;
+	SIGG(running) = 0;
+	SIGG(blocked) = -1;
+	SIGG(depth) = 0;
+	SIGNAL_END_CRITICAL();
+}
+/* }}} */
+
+static void zend_signal_globals_ctor(zend_signal_globals_t *zend_signal_globals TSRMLS_DC)
+{
+	size_t x;
+
+	memset(zend_signal_globals, 0, sizeof(*zend_signal_globals));
+	zend_signal_globals->blocked = -1;
+
+	for (x = 0; x < sizeof(zend_signal_globals->pstorage) / sizeof(*zend_signal_globals->pstorage); ++x) {
+		zend_signal_queue_t *queue = &zend_signal_globals->pstorage[x];
+		queue->zend_signal.signo = 0;
+		queue->next = zend_signal_globals->pavail;
+		zend_signal_globals->pavail = queue;
+	}
+}
+
+static void zend_signal_globals_dtor(zend_signal_globals_t *zend_signal_globals TSRMLS_DC)
+{
+	zend_signal_globals->blocked = -1;
+}
+
+/* {{{ zend_signal_startup
+ * alloc zend signal globals */
+void zend_signal_startup()
+{
+	int signo;
+	struct sigaction sa = {{0}};
+
+#ifdef ZTS
+	ts_allocate_id(&zend_signal_globals_id, sizeof(zend_signal_globals_t), (ts_allocate_ctor) zend_signal_globals_ctor, (ts_allocate_dtor) zend_signal_globals_dtor);
+#else
+	zend_signal_globals_ctor(&zend_signal_globals);
+#endif
+
+	/* Used to block signals during execution of signal handlers */
+	sigfillset(&global_sigmask);
+	sigdelset(&global_sigmask, SIGILL);
+	sigdelset(&global_sigmask, SIGABRT);
+	sigdelset(&global_sigmask, SIGFPE);
+	sigdelset(&global_sigmask, SIGKILL);
+	sigdelset(&global_sigmask, SIGSEGV);
+	sigdelset(&global_sigmask, SIGCONT);
+	sigdelset(&global_sigmask, SIGSTOP);
+	sigdelset(&global_sigmask, SIGTSTP);
+	sigdelset(&global_sigmask, SIGTTIN);
+	sigdelset(&global_sigmask, SIGTTOU);
+#ifdef SIGBUS
+	sigdelset(&global_sigmask, SIGBUS);
+#endif
+#ifdef SIGSYS
+	sigdelset(&global_sigmask, SIGSYS);
+#endif
+#ifdef SIGTRAP
+	sigdelset(&global_sigmask, SIGTRAP);
+#endif
+
+	/* Save previously registered signal handlers into orig_handlers */
+	memset(&global_orig_handlers, 0, sizeof(global_orig_handlers));
+	for (signo = 1; signo <= NSIG; ++signo) {
+		if (sigaction(signo, NULL, &sa) == 0) {
+			global_orig_handlers[signo-1].flags = sa.sa_flags;
+			if (sa.sa_flags & SA_SIGINFO) {
+				global_orig_handlers[signo-1].handler = (void *) sa.sa_sigaction;
+			} else {
+				global_orig_handlers[signo-1].handler = (void *) sa.sa_handler;
+			}
+		}
+	}
+}
+/* }}} */
+
+/* {{{ zend_signal_shutdown
+ * called by zend_shutdown */
+void zend_signal_shutdown(TSRMLS_D)
+{
+#ifndef ZTS
+	zend_signal_globals_dtor(&zend_signal_globals);
+#endif
+}
+/* }}} */
+
+
+#endif /* ZEND_SIGNALS */
+
+/*
+ * Local variables:
+ * tab-width: 4
+ * c-basic-offset: 4
+ * indent-tabs-mode: t
+ * End:
+ * vim600: fdm=marker
+ * vim: noet sw=4 ts=4
+ */


Property changes on: php/php-src/trunk/Zend/zend_signal.c
___________________________________________________________________
Added: svn:keywords
   + Id Rev Revision
Added: svn:eol-style
   + native

Added: php/php-src/trunk/Zend/zend_signal.h
===================================================================
--- php/php-src/trunk/Zend/zend_signal.h	                        (rev 0)
+++ php/php-src/trunk/Zend/zend_signal.h	2011-06-02 21:16:50 UTC (rev 311740)
@@ -0,0 +1,104 @@
+/*
+  +----------------------------------------------------------------------+
+  | Zend Signal Handling                                                 |
+  +----------------------------------------------------------------------+
+  | Copyright (c) 2008 The PHP Group                                     |
+  +----------------------------------------------------------------------+
+  | This source file is subject to version 3.01 of the PHP license,      |
+  | that is bundled with this package in the file LICENSE, and is        |
+  | available through the world-wide-web at the following url:           |
+  | http://www.php.net/license/3_01.txt                                  |
+  | If you did not receive a copy of the PHP license and are unable to   |
+  | obtain it through the world-wide-web, please send a note to          |
+  | lice...@php.net so we can mail you a copy immediately.               |
+  +----------------------------------------------------------------------+
+  | Authors: Lucas Nealan <lu...@php.net>                                |
+  |          Arnaud Le Blanc <lbarn...@php.net>                          |
+  +----------------------------------------------------------------------+
+
+ */
+
+/* $Id$ */
+
+#ifndef ZEND_SIGNAL_H
+#define ZEND_SIGNAL_H
+
+#ifdef HAVE_SIGNAL_H
+#include <signal.h>
+#endif
+
+#ifndef NSIG
+#define NSIG 65
+#endif
+
+#ifndef ZEND_SIGNAL_QUEUE_SIZE
+#define ZEND_SIGNAL_QUEUE_SIZE 32
+#endif
+
+/* Signal structs */
+typedef struct _zend_signal_entry_t {
+	int   flags;          /* sigaction style flags */
+	void* handler;      /* signal handler or context */
+} zend_signal_entry_t;
+
+typedef struct _zend_signal_t {
+	int signo;
+	siginfo_t *siginfo;
+	void* context;
+} zend_signal_t;
+
+typedef struct _zend_signal_queue_t {
+	zend_signal_t zend_signal;
+	struct _zend_signal_queue_t *next;
+} zend_signal_queue_t;
+
+/* Signal Globals */
+typedef struct _zend_signal_globals_t {
+	int depth;
+	int blocked;            /* 0==TRUE, -1==FALSE */
+	int running;            /* in signal handler execution */
+	int active;             /* internal signal handling is enabled */
+	int initialized;        /* memory initialized */
+	zend_bool check;        /* check for replaced handlers on shutdown */
+	zend_signal_entry_t handlers[NSIG];
+	zend_signal_queue_t pstorage[ZEND_SIGNAL_QUEUE_SIZE], *phead, *ptail, *pavail; /* pending queue */
+} zend_signal_globals_t;
+
+#ifdef ZTS
+# define SIGG(v) TSRMG(zend_signal_globals_id, zend_signal_globals_t *, v)
+BEGIN_EXTERN_C()
+ZEND_API extern int zend_signal_globals_id;
+END_EXTERN_C()
+#else /* ZTS */
+# define SIGG(v) (zend_signal_globals.v)
+extern ZEND_API zend_signal_globals_t zend_signal_globals;
+#endif /* not ZTS */
+
+# define SIGNAL_BEGIN_CRITICAL() 	sigset_t oldmask; \
+	zend_sigprocmask(SIG_BLOCK, &global_sigmask, &oldmask);
+# define SIGNAL_END_CRITICAL()		zend_sigprocmask(SIG_SETMASK, &oldmask, NULL);
+
+void zend_signal_handler_defer(int signo, siginfo_t *siginfo, void *context);
+void zend_signal_handler_unblock();
+void zend_signal_activate(TSRMLS_D);
+void zend_signal_deactivate(TSRMLS_D);
+void zend_signal_startup();
+void zend_signal_shutdown(TSRMLS_D);
+ZEND_API int zend_signal(int signo, void (*handler)(int) TSRMLS_DC);
+ZEND_API int zend_sigaction(int signo, const struct sigaction *act, struct sigaction *oldact TSRMLS_DC);
+
+#ifdef ZTS
+#define zend_sigprocmask(signo, set, oldset) tsrm_sigmask((signo), (set), (oldset))
+#else
+#define zend_sigprocmask(signo, set, oldset) sigprocmask((signo), (set), (oldset))
+#endif
+
+#endif /* ZEND_SIGNAL_H */
+
+/*
+ * Local variables:
+ * tab-width: 4
+ * c-basic-offset: 4
+ * indent-tabs-mode: t
+ * End:
+ */


Property changes on: php/php-src/trunk/Zend/zend_signal.h
___________________________________________________________________
Added: svn:keywords
   + Id Rev Revision
Added: svn:eol-style
   + native

Modified: php/php-src/trunk/configure.in
===================================================================
--- php/php-src/trunk/configure.in	2011-06-02 20:01:40 UTC (rev 311739)
+++ php/php-src/trunk/configure.in	2011-06-02 21:16:50 UTC (rev 311740)
@@ -1473,7 +1473,7 @@
     zend_list.c zend_indent.c zend_builtin_functions.c zend_sprintf.c \
     zend_ini.c zend_qsort.c zend_multibyte.c zend_ts_hash.c zend_stream.c \
     zend_iterators.c zend_interfaces.c zend_exceptions.c zend_strtod.c zend_gc.c \
-    zend_closures.c zend_float.c zend_string.c)
+    zend_closures.c zend_float.c zend_string.c zend_signal.c)

 if test -r "$abs_srcdir/Zend/zend_objects.c"; then
   PHP_ADD_SOURCES(Zend, zend_objects.c zend_object_handlers.c zend_objects_API.c zend_default_classes.c)

Modified: php/php-src/trunk/ext/pcntl/php_signal.c
===================================================================
--- php/php-src/trunk/ext/pcntl/php_signal.c	2011-06-02 20:01:40 UTC (rev 311739)
+++ php/php-src/trunk/ext/pcntl/php_signal.c	2011-06-02 21:16:50 UTC (rev 311740)
@@ -41,8 +41,14 @@
 		act.sa_flags |= SA_RESTART; /* SVR4, 4.3+BSD */
 #endif
 	}
+#ifdef ZEND_SIGNALS
+	if (zend_sigaction(signo, &act, &oact) < 0)
+#else
 	if (sigaction(signo, &act, &oact) < 0)
+#endif
+	{
 		return SIG_ERR;
+	}

 	return oact.sa_handler;
 }

Modified: php/php-src/trunk/ext/standard/info.c
===================================================================
--- php/php-src/trunk/ext/standard/info.c	2011-06-02 20:01:40 UTC (rev 311739)
+++ php/php-src/trunk/ext/standard/info.c	2011-06-02 21:16:50 UTC (rev 311740)
@@ -747,6 +747,12 @@
 		php_info_print_table_row(2, "Thread Safety", "disabled" );
 #endif

+#ifdef ZEND_SIGNALS
+		php_info_print_table_row(2, "Zend Signal Handling", "enabled" );
+#else
+		php_info_print_table_row(2, "Zend Signal Handling", "disabled" );
+#endif
+
 		php_info_print_table_row(2, "Zend Memory Manager", is_zend_mm(TSRMLS_C) ? "enabled" : "disabled" );

 		{

Modified: php/php-src/trunk/ext/standard/tests/general_functions/phpinfo.phpt
===================================================================
--- php/php-src/trunk/ext/standard/tests/general_functions/phpinfo.phpt	2011-06-02 20:01:40 UTC (rev 311739)
+++ php/php-src/trunk/ext/standard/tests/general_functions/phpinfo.phpt	2011-06-02 21:16:50 UTC (rev 311740)
@@ -35,6 +35,7 @@
 Debug Build => %s
 Thread Safety => %s
 Zend Memory Manager => %s
+Zend Signal Handling => %s
 Zend Multibyte Support => %s
 IPv6 Support => %s
 DTrace Support => %s

Modified: php/php-src/trunk/main/SAPI.c
===================================================================
--- php/php-src/trunk/main/SAPI.c	2011-06-02 20:01:40 UTC (rev 311739)
+++ php/php-src/trunk/main/SAPI.c	2011-06-02 21:16:50 UTC (rev 311740)
@@ -75,6 +75,10 @@

 SAPI_API void sapi_startup(sapi_module_struct *sf)
 {
+#ifdef ZEND_SIGNALS
+	zend_signal_startup();
+#endif
+
 	sf->ini_entries = NULL;
 	sapi_module = *sf;


Modified: php/php-src/trunk/main/main.c
===================================================================
--- php/php-src/trunk/main/main.c	2011-06-02 20:01:40 UTC (rev 311739)
+++ php/php-src/trunk/main/main.c	2011-06-02 21:16:50 UTC (rev 311740)
@@ -1371,8 +1371,12 @@
  */
 static void sigchld_handler(int apar)
 {
+	int errno_save = errno;
+
 	while (waitpid(-1, NULL, WNOHANG) > 0);
 	signal(SIGCHLD, sigchld_handler);
+
+	errno = errno_save;
 }
 /* }}} */
 #endif
@@ -1441,6 +1445,10 @@
 		zend_activate(TSRMLS_C);
 		sapi_activate(TSRMLS_C);

+#ifdef ZEND_SIGNALS
+		zend_signal_activate(TSRMLS_C);
+#endif
+
 		if (PG(max_input_time) == -1) {
 			zend_set_timeout(EG(timeout_seconds), 1);
 		} else {
@@ -1565,6 +1573,10 @@
 	}

 	zend_try {
+		zend_unset_timeout(TSRMLS_C);
+	} zend_end_try();
+
+	zend_try {
 		int i;

 		for (i = 0; i < NUM_TRACK_VARS; i++) {
@@ -1590,9 +1602,11 @@

 	zend_interned_strings_restore(TSRMLS_C);

+#ifdef ZEND_SIGNALS
 	zend_try {
-		zend_unset_timeout(TSRMLS_C);
+		zend_signal_deactivate(TSRMLS_C);
 	} zend_end_try();
+#endif
 }

 /* }}} */
@@ -1647,13 +1661,18 @@
 		sapi_send_headers(TSRMLS_C);
 	} zend_end_try();

-	/* 5. Call all extensions RSHUTDOWN functions */
+	/* 5. Reset max_execution_time (no longer executing php code after response sent) */
+	zend_try {
+		zend_unset_timeout(TSRMLS_C);
+	} zend_end_try();
+
+	/* 6. Call all extensions RSHUTDOWN functions */
 	if (PG(modules_activated)) {
 		zend_deactivate_modules(TSRMLS_C);
 		php_free_shutdown_functions(TSRMLS_C);
 	}

-	/* 6. Destroy super-globals */
+	/* 7. Destroy super-globals */
 	zend_try {
 		int i;

@@ -1664,7 +1683,7 @@
 		}
 	} zend_end_try();

-	/* 6.5 free last error information */
+	/* 7.5 free last error information */
 	if (PG(last_error_message)) {
 		free(PG(last_error_message));
 		PG(last_error_message) = NULL;
@@ -1889,8 +1908,10 @@
 	zuf.write_function = php_output_wrapper;
 	zuf.fopen_function = php_fopen_wrapper_for_zend;
 	zuf.message_handler = php_message_handler_for_zend;
+#ifndef ZEND_SIGNALS
 	zuf.block_interruptions = sapi_module.block_interruptions;
 	zuf.unblock_interruptions = sapi_module.unblock_interruptions;
+#endif
 	zuf.get_configuration_directive = php_get_configuration_directive_for_zend;
 	zuf.ticks_function = php_run_ticks;
 	zuf.on_timeout = php_on_timeout;
-- 
PHP CVS Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to