Index: ext/standard/tests/general_functions/phpinfo.phpt
===================================================================
--- ext/standard/tests/general_functions/phpinfo.phpt	(.../PHP_5_3)	(revision 32)
+++ ext/standard/tests/general_functions/phpinfo.phpt	(.../PHP_5_3_signals)	(revision 32)
@@ -31,6 +31,7 @@
 Debug Build => %s
 Thread Safety => %s
 Zend Memory Manager => %s
+Zend Signal Handling => %s
 Zend Multibyte Support => %s
 IPv6 Support => %s
 Registered PHP Streams => %s
Index: ext/standard/info.c
===================================================================
--- ext/standard/info.c	(.../PHP_5_3)	(revision 32)
+++ ext/standard/info.c	(.../PHP_5_3_signals)	(revision 32)
@@ -514,6 +514,12 @@
 
 		php_info_print_table_row(2, "Zend Memory Manager", is_zend_mm(TSRMLS_C) ? "enabled" : "disabled" );
 
+#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
+
 #ifdef ZEND_MULTIBYTE
 		php_info_print_table_row(2, "Zend Multibyte Support", "enabled");
 #else
Index: ext/pcntl/php_signal.c
===================================================================
--- ext/pcntl/php_signal.c	(.../PHP_5_3)	(revision 32)
+++ ext/pcntl/php_signal.c	(.../PHP_5_3_signals)	(revision 32)
@@ -38,8 +38,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;
 }
Index: configure.in
===================================================================
--- configure.in	(.../PHP_5_3)	(revision 32)
+++ configure.in	(.../PHP_5_3_signals)	(revision 32)
@@ -1440,7 +1440,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_closures.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)
Index: TSRM/tsrm.m4
===================================================================
--- TSRM/tsrm.m4	(.../PHP_5_3)	(revision 32)
+++ TSRM/tsrm.m4	(.../PHP_5_3_signals)	(revision 32)
@@ -30,6 +30,8 @@
 
 AC_CHECK_HEADERS(stdarg.h)
 
+AC_CHECK_FUNCS(sigprocmask)
+
 ])
 
 
Index: TSRM/TSRM.c
===================================================================
--- TSRM/TSRM.c	(.../PHP_5_3)	(revision 32)
+++ TSRM/TSRM.c	(.../PHP_5_3_signals)	(revision 32)
@@ -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;
Index: TSRM/TSRM.h
===================================================================
--- TSRM/TSRM.h	(.../PHP_5_3)	(revision 32)
+++ TSRM/TSRM.h	(.../PHP_5_3_signals)	(revision 32)
@@ -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);
Index: Zend/zend.c
===================================================================
--- Zend/zend.c	(.../PHP_5_3)	(revision 32)
+++ Zend/zend.c	(.../PHP_5_3_signals)	(revision 32)
@@ -91,6 +91,9 @@
 ZEND_INI_BEGIN()
 	ZEND_INI_ENTRY("error_reporting",				NULL,		ZEND_INI_ALL,		OnUpdateErrorReporting)
 	STD_ZEND_INI_BOOLEAN("zend.enable_gc",				"1",	ZEND_INI_ALL,		OnUpdateGCEnabled,      gc_enabled,     zend_gc_globals,        gc_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
 #ifdef ZEND_MULTIBYTE
  	STD_ZEND_INI_BOOLEAN("detect_unicode", "1", ZEND_INI_ALL, OnUpdateBool, detect_unicode, zend_compiler_globals, compiler_globals)
 #endif
@@ -634,8 +637,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;
@@ -763,6 +768,9 @@
 
 void zend_shutdown(TSRMLS_D) /* {{{ */
 {
+#ifdef ZEND_SIGNALS
+	zend_signal_shutdown(TSRMLS_C);
+#endif
 #ifdef ZEND_WIN32
 	zend_shutdown_timeout_thread();
 #endif
Index: Zend/zend_hash.c
===================================================================
--- Zend/zend_hash.c	(.../PHP_5_3)	(revision 32)
+++ Zend/zend_hash.c	(.../PHP_5_3_signals)	(revision 32)
@@ -202,6 +202,7 @@
 	ulong h;
 	uint nIndex;
 	Bucket *p;
+	TSRMLS_FETCH();
 
 	IS_CONSISTENT(ht);
 
@@ -271,6 +272,7 @@
 {
 	uint nIndex;
 	Bucket *p;
+	TSRMLS_FETCH();
 
 	IS_CONSISTENT(ht);
 
@@ -348,6 +350,7 @@
 {
 	uint nIndex;
 	Bucket *p;
+	TSRMLS_FETCH();
 
 	IS_CONSISTENT(ht);
 
@@ -415,6 +418,7 @@
 static int zend_hash_do_resize(HashTable *ht)
 {
 	Bucket **t;
+	TSRMLS_FETCH();
 
 	IS_CONSISTENT(ht);
 
@@ -456,6 +460,7 @@
 {
 	uint nIndex;
 	Bucket *p;
+	TSRMLS_FETCH();
 
 	IS_CONSISTENT(ht);
 
@@ -574,6 +579,7 @@
 static Bucket *zend_hash_apply_deleter(HashTable *ht, Bucket *p)
 {
 	Bucket *retval;
+	TSRMLS_FETCH();
 
 	HANDLE_BLOCK_INTERRUPTIONS();
 	if (p->pLast) {
@@ -1173,6 +1179,7 @@
 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;
+	TSRMLS_FETCH();
 
 	p = pos ? (*pos) : ht->pInternalPointer;
 
Index: Zend/zend.h
===================================================================
--- Zend/zend.h	(.../PHP_5_3)	(revision 32)
+++ Zend/zend.h	(.../PHP_5_3_signals)	(revision 32)
@@ -471,8 +471,10 @@
 	int (*write_function)(const char *str, uint str_length);
 	FILE *(*fopen_function)(const char *filename, char **opened_path);
 	void (*message_handler)(long message, void *data);
+#ifndef ZEND_SIGNALS
 	void (*block_interruptions)(void);
 	void (*unblock_interruptions)(void);
+#endif
 	int (*get_configuration_directive)(char *name, uint name_length, zval *contents);
 	void (*ticks_function)(int ticks);
 	void (*on_timeout)(int seconds TSRMLS_DC);
@@ -611,8 +613,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);
+#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);
@@ -635,9 +639,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);
 
Index: Zend/Zend.m4
===================================================================
--- Zend/Zend.m4	(.../PHP_5_3)	(revision 32)
+++ Zend/Zend.m4	(.../PHP_5_3_signals)	(revision 32)
@@ -384,9 +384,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],[
 
 ])
Index: Zend/zend_signal.c
===================================================================
--- Zend/zend_signal.c	(.../PHP_5_3)	(revision 0)
+++ Zend/zend_signal.c	(.../PHP_5_3_signals)	(revision 32)
@@ -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          |
+  | license@php.net so we can mail you a copy immediately.               |
+  +----------------------------------------------------------------------+
+  | Authors: Lucas Nealan <lucas@php.net>                                |
+  |          Arnaud Le Blanc <lbarnaud@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
+ */
Index: Zend/zend_signal.h
===================================================================
--- Zend/zend_signal.h	(.../PHP_5_3)	(revision 0)
+++ Zend/zend_signal.h	(.../PHP_5_3_signals)	(revision 32)
@@ -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          |
+  | license@php.net so we can mail you a copy immediately.               |
+  +----------------------------------------------------------------------+
+  | Authors: Lucas Nealan <lucas@php.net>                                |
+  |          Arnaud Le Blanc <lbarnaud@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:
+ */
Index: Zend/zend_alloc.c
===================================================================
--- Zend/zend_alloc.c	(.../PHP_5_3)	(revision 32)
+++ Zend/zend_alloc.c	(.../PHP_5_3_signals)	(revision 32)
@@ -1751,7 +1751,10 @@
 	size_t segment_size;
 	zend_mm_segment *segment;
 	int keep_rest = 0;
+	TSRMLS_FETCH();
 
+	HANDLE_BLOCK_INTERRUPTIONS();
+
 	if (EXPECTED(ZEND_MM_SMALL_SIZE(true_size))) {
 		size_t index = ZEND_MM_BUCKET_INDEX(true_size);
 		size_t bitmap;
@@ -1771,6 +1774,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
@@ -1824,8 +1828,6 @@
 			segment_size = heap->block_size;
 		}
 
-		HANDLE_BLOCK_INTERRUPTIONS();
-
 		if (segment_size < true_size ||
 		    heap->real_size + segment_size > heap->limit) {
 			/* Memory limit overflow */
@@ -1847,8 +1849,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
@@ -1876,7 +1878,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);
@@ -1924,11 +1925,14 @@
 	zend_mm_block *mm_block;
 	zend_mm_block *next_block;
 	size_t size;
+	TSRMLS_FETCH();
 
 	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);
@@ -1951,12 +1955,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);
@@ -1986,10 +1989,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);
@@ -2005,7 +2012,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);
@@ -2021,9 +2027,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;
 	}
 
@@ -2066,6 +2072,7 @@
 			}
 #endif
 
+			HANDLE_UNBLOCK_INTERRUPTIONS();
 			return ptr;
 		}
 	}
@@ -2080,7 +2087,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) {
@@ -2111,7 +2117,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;
 		}
@@ -2122,7 +2127,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)) {
@@ -2155,8 +2159,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
@@ -2220,6 +2224,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;
 }
 
@@ -2408,12 +2413,17 @@
 ZEND_API void *_ecalloc(size_t nmemb, size_t size ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC)
 {
 	void *p;
+	TSRMLS_FETCH();
 
+	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;
 }
 
@@ -2421,26 +2431,36 @@
 {
 	int length;
 	char *p;
+	TSRMLS_FETCH();
 
+	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;
+	TSRMLS_FETCH();
 
+	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;
 }
 
@@ -2448,15 +2468,20 @@
 ZEND_API char *zend_strndup(const char *s, uint length)
 {
 	char *p;
+	TSRMLS_FETCH();
 
+	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;
 }
 
Index: Zend/zend_execute_API.c
===================================================================
--- Zend/zend_execute_API.c	(.../PHP_5_3)	(revision 32)
+++ Zend/zend_execute_API.c	(.../PHP_5_3_signals)	(revision 32)
@@ -1364,7 +1364,7 @@
 #	ifdef HAVE_SETITIMER
 	{
 		struct itimerval t_r;		/* timeout requested */
-		sigset_t sigset;
+		int signo;
 
 		if(seconds) {
 			t_r.it_value.tv_sec = seconds;
@@ -1373,25 +1373,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
 }
 /* }}} */
Index: Zend/Makefile.am
===================================================================
--- Zend/Makefile.am	(.../PHP_5_3)	(revision 32)
+++ Zend/Makefile.am	(.../PHP_5_3_signals)	(revision 32)
@@ -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_strtod.c zend_closures.c zend_signal.c
 
 libZend_la_LDFLAGS =
 libZend_la_LIBADD = @ZEND_EXTRA_LIBS@
Index: main/SAPI.c
===================================================================
--- main/SAPI.c	(.../PHP_5_3)	(revision 32)
+++ main/SAPI.c	(.../PHP_5_3_signals)	(revision 32)
@@ -76,6 +76,10 @@
 
 SAPI_API void sapi_startup(sapi_module_struct *sf)
 {
+#ifdef ZEND_SIGNALS
+	zend_signal_startup();
+#endif
+
 	sf->ini_entries = NULL;
 	sapi_module = *sf;
 
Index: main/main.c
===================================================================
--- main/main.c	(.../PHP_5_3)	(revision 32)
+++ main/main.c	(.../PHP_5_3_signals)	(revision 32)
@@ -1245,8 +1245,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
@@ -1310,6 +1314,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 {
@@ -1433,6 +1441,10 @@
 	}
 
 	zend_try {
+		zend_unset_timeout(TSRMLS_C);
+	} zend_end_try();
+
+	zend_try {
 		int i;
 
 		for (i = 0; i < NUM_TRACK_VARS; i++) {
@@ -1456,9 +1468,11 @@
 		shutdown_memory_manager(CG(unclean_shutdown), 0 TSRMLS_CC);
 	} zend_end_try();
 
+#ifdef ZEND_SIGNALS
 	zend_try {
-		zend_unset_timeout(TSRMLS_C);
+		zend_signal_deactivate(TSRMLS_C);
 	} zend_end_try();
+#endif
 }
 
 /* }}} */
@@ -1500,13 +1514,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;
 
@@ -1517,7 +1536,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;
@@ -1527,33 +1546,35 @@
 		PG(last_error_file) = NULL;
 	}
 
-	/* 7. Shutdown scanner/executor/compiler and restore ini entries */
+	/* 8. Shutdown scanner/executor/compiler and restore ini entries */
 	zend_deactivate(TSRMLS_C);
 
-	/* 8. Call all extensions post-RSHUTDOWN functions */
+	/* 9. Call all extensions post-RSHUTDOWN functions */
 	zend_try {
 		zend_post_deactivate_modules(TSRMLS_C);
 	} zend_end_try();
 
-	/* 9. SAPI related shutdown (free stuff) */
+	/* 10. SAPI related shutdown (free stuff) */
 	zend_try {
 		sapi_deactivate(TSRMLS_C);
 	} zend_end_try();
 
-	/* 10. Destroy stream hashes */
+	/* 11. Destroy stream hashes */
 	zend_try {
 		php_shutdown_stream_hashes(TSRMLS_C);
 	} zend_end_try();
 
-	/* 11. Free Willy (here be crashes) */
+	/* 12. Free Willy (here be crashes) */
 	zend_try {
 		shutdown_memory_manager(CG(unclean_shutdown) || !report_memleaks, 0 TSRMLS_CC);
 	} zend_end_try();
 
-	/* 12. Reset max_execution_time */
+    /* 13. Reset zend signals */
+#ifdef ZEND_SIGNALS
 	zend_try {
-		zend_unset_timeout(TSRMLS_C);
+		zend_signal_deactivate(TSRMLS_C);
 	} zend_end_try();
+#endif
 
 #ifdef PHP_WIN32
 	if (PG(com_initialized)) {
@@ -1729,8 +1750,10 @@
 	zuf.write_function = php_body_write_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;
