mirror of
https://github.com/php/php-src.git
synced 2025-08-15 21:48:51 +02:00
Merge branch 'PHP-8.2'
* PHP-8.2: [ci skip] NEWS [ci skip] NEWS fix: support for timeouts with ZTS on Linux (#10141)
This commit is contained in:
commit
0c7fc351ea
11 changed files with 253 additions and 1 deletions
22
Zend/Zend.m4
22
Zend/Zend.m4
|
@ -302,6 +302,28 @@ fi
|
||||||
AC_MSG_CHECKING(whether to enable zend signal handling)
|
AC_MSG_CHECKING(whether to enable zend signal handling)
|
||||||
AC_MSG_RESULT($ZEND_SIGNALS)
|
AC_MSG_RESULT($ZEND_SIGNALS)
|
||||||
|
|
||||||
|
dnl Don't enable Zend Max Execution Timers by default until PHP 8.3 to not break the ABI
|
||||||
|
AC_ARG_ENABLE([zend-max-execution-timers],
|
||||||
|
[AS_HELP_STRING([--enable-zend-max-execution-timers],
|
||||||
|
[whether to enable zend max execution timers])],
|
||||||
|
[ZEND_MAX_EXECUTION_TIMERS=$enableval],
|
||||||
|
[ZEND_MAX_EXECUTION_TIMERS='no'])
|
||||||
|
|
||||||
|
AS_CASE(["$host_alias"], [*linux*], [], [ZEND_MAX_EXECUTION_TIMERS='no'])
|
||||||
|
|
||||||
|
PHP_CHECK_FUNC(timer_create, rt)
|
||||||
|
if test "$ac_cv_func_timer_create" != "yes"; then
|
||||||
|
ZEND_MAX_EXECUTION_TIMERS='no'
|
||||||
|
fi
|
||||||
|
|
||||||
|
if test "$ZEND_MAX_EXECUTION_TIMERS" = "yes"; then
|
||||||
|
AC_DEFINE(ZEND_MAX_EXECUTION_TIMERS, 1, [Use zend max execution timers])
|
||||||
|
CFLAGS="$CFLAGS -DZEND_MAX_EXECUTION_TIMERS"
|
||||||
|
fi
|
||||||
|
|
||||||
|
AC_MSG_CHECKING(whether to enable zend max execution timers)
|
||||||
|
AC_MSG_RESULT($ZEND_MAX_EXECUTION_TIMERS)
|
||||||
|
|
||||||
])
|
])
|
||||||
|
|
||||||
AC_ARG_ENABLE([gcc-global-regs],
|
AC_ARG_ENABLE([gcc-global-regs],
|
||||||
|
|
18
Zend/zend.c
18
Zend/zend.c
|
@ -36,6 +36,7 @@
|
||||||
#include "zend_observer.h"
|
#include "zend_observer.h"
|
||||||
#include "zend_fibers.h"
|
#include "zend_fibers.h"
|
||||||
#include "zend_call_stack.h"
|
#include "zend_call_stack.h"
|
||||||
|
#include "zend_max_execution_timer.h"
|
||||||
#include "Optimizer/zend_optimizer.h"
|
#include "Optimizer/zend_optimizer.h"
|
||||||
|
|
||||||
static size_t global_map_ptr_last = 0;
|
static size_t global_map_ptr_last = 0;
|
||||||
|
@ -802,6 +803,10 @@ static void executor_globals_ctor(zend_executor_globals *executor_globals) /* {{
|
||||||
executor_globals->stack_limit = (void*)0;
|
executor_globals->stack_limit = (void*)0;
|
||||||
executor_globals->stack_base = (void*)0;
|
executor_globals->stack_base = (void*)0;
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef ZEND_MAX_EXECUTION_TIMERS
|
||||||
|
executor_globals->pid = 0;
|
||||||
|
executor_globals->oldact = (struct sigaction){0};
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
/* }}} */
|
/* }}} */
|
||||||
|
|
||||||
|
@ -826,6 +831,7 @@ static void zend_new_thread_end_handler(THREAD_T thread_id) /* {{{ */
|
||||||
#ifdef ZEND_CHECK_STACK_LIMIT
|
#ifdef ZEND_CHECK_STACK_LIMIT
|
||||||
zend_call_stack_init();
|
zend_call_stack_init();
|
||||||
#endif
|
#endif
|
||||||
|
zend_max_execution_timer_init();
|
||||||
}
|
}
|
||||||
/* }}} */
|
/* }}} */
|
||||||
#endif
|
#endif
|
||||||
|
@ -1607,6 +1613,18 @@ ZEND_API ZEND_COLD ZEND_NORETURN void zend_error_noreturn(int type, const char *
|
||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ZEND_API ZEND_COLD ZEND_NORETURN void zend_strerror_noreturn(int type, int errn, const char *message)
|
||||||
|
{
|
||||||
|
#ifdef HAVE_STR_ERROR_R
|
||||||
|
char buf[1024];
|
||||||
|
strerror_r(errn, buf, sizeof(buf));
|
||||||
|
#else
|
||||||
|
char *buf = strerror(errn);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
zend_error_noreturn(type, "%s: %s (%d)", message, buf, errn);
|
||||||
|
}
|
||||||
|
|
||||||
ZEND_API ZEND_COLD void zend_error_zstr(int type, zend_string *message) {
|
ZEND_API ZEND_COLD void zend_error_zstr(int type, zend_string *message) {
|
||||||
zend_string *filename;
|
zend_string *filename;
|
||||||
uint32_t lineno;
|
uint32_t lineno;
|
||||||
|
|
|
@ -40,6 +40,7 @@
|
||||||
#include "zend_smart_string_public.h"
|
#include "zend_smart_string_public.h"
|
||||||
#include "zend_signal.h"
|
#include "zend_signal.h"
|
||||||
#include "zend_type_code.h"
|
#include "zend_type_code.h"
|
||||||
|
#include "zend_max_execution_timer.h"
|
||||||
|
|
||||||
#define zend_sprintf sprintf
|
#define zend_sprintf sprintf
|
||||||
|
|
||||||
|
@ -360,6 +361,9 @@ ZEND_API ZEND_COLD void zend_value_error(const char *format, ...) ZEND_ATTRIBUTE
|
||||||
|
|
||||||
ZEND_COLD void zenderror(const char *error);
|
ZEND_COLD void zenderror(const char *error);
|
||||||
|
|
||||||
|
/* For internal C errors */
|
||||||
|
ZEND_API ZEND_COLD ZEND_NORETURN void zend_strerror_noreturn(int type, int errn, const char *message);
|
||||||
|
|
||||||
/* The following #define is used for code duality in PHP for Engine 1 & 2 */
|
/* The following #define is used for code duality in PHP for Engine 1 & 2 */
|
||||||
#define ZEND_STANDARD_CLASS_DEF_PTR zend_standard_class_def
|
#define ZEND_STANDARD_CLASS_DEF_PTR zend_standard_class_def
|
||||||
extern ZEND_API zend_class_entry *zend_standard_class_def;
|
extern ZEND_API zend_class_entry *zend_standard_class_def;
|
||||||
|
|
|
@ -44,6 +44,9 @@
|
||||||
#ifdef HAVE_UNISTD_H
|
#ifdef HAVE_UNISTD_H
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef ZEND_MAX_EXECUTION_TIMERS
|
||||||
|
#include <sys/syscall.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
ZEND_API void (*zend_execute_ex)(zend_execute_data *execute_data);
|
ZEND_API void (*zend_execute_ex)(zend_execute_data *execute_data);
|
||||||
ZEND_API void (*zend_execute_internal)(zend_execute_data *execute_data, zval *return_value);
|
ZEND_API void (*zend_execute_internal)(zend_execute_data *execute_data, zval *return_value);
|
||||||
|
@ -196,6 +199,7 @@ void init_executor(void) /* {{{ */
|
||||||
EG(filename_override) = NULL;
|
EG(filename_override) = NULL;
|
||||||
EG(lineno_override) = -1;
|
EG(lineno_override) = -1;
|
||||||
|
|
||||||
|
zend_max_execution_timer_init();
|
||||||
zend_fiber_init();
|
zend_fiber_init();
|
||||||
zend_weakrefs_init();
|
zend_weakrefs_init();
|
||||||
|
|
||||||
|
@ -413,6 +417,7 @@ void shutdown_executor(void) /* {{{ */
|
||||||
zend_shutdown_executor_values(fast_shutdown);
|
zend_shutdown_executor_values(fast_shutdown);
|
||||||
|
|
||||||
zend_weakrefs_shutdown();
|
zend_weakrefs_shutdown();
|
||||||
|
zend_max_execution_timer_shutdown();
|
||||||
zend_fiber_shutdown();
|
zend_fiber_shutdown();
|
||||||
|
|
||||||
zend_try {
|
zend_try {
|
||||||
|
@ -1367,8 +1372,35 @@ ZEND_API ZEND_NORETURN void ZEND_FASTCALL zend_timeout(void) /* {{{ */
|
||||||
/* }}} */
|
/* }}} */
|
||||||
|
|
||||||
#ifndef ZEND_WIN32
|
#ifndef ZEND_WIN32
|
||||||
|
# ifdef ZEND_MAX_EXECUTION_TIMERS
|
||||||
|
static void zend_timeout_handler(int dummy, siginfo_t *si, void *uc) /* {{{ */
|
||||||
|
{
|
||||||
|
#ifdef ZTS
|
||||||
|
if (!tsrm_is_managed_thread()) {
|
||||||
|
fprintf(stderr, "zend_timeout_handler() called in a thread not managed by PHP. The expected signal handler will not be called. This is probably a bug.\n");
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (si->si_value.sival_ptr != &EG(max_execution_timer_timer)) {
|
||||||
|
#ifdef MAX_EXECUTION_TIMERS_DEBUG
|
||||||
|
fprintf(stderr, "Executing previous handler (if set) for unexpected signal SIGRTMIN received on thread %d\n", (pid_t) syscall(SYS_gettid));
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (EG(oldact).sa_sigaction) {
|
||||||
|
EG(oldact).sa_sigaction(dummy, si, uc);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (EG(oldact).sa_handler) EG(oldact).sa_handler(dummy);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
# else
|
||||||
static void zend_timeout_handler(int dummy) /* {{{ */
|
static void zend_timeout_handler(int dummy) /* {{{ */
|
||||||
{
|
{
|
||||||
|
# endif
|
||||||
#ifdef ZTS
|
#ifdef ZTS
|
||||||
if (!tsrm_is_managed_thread()) {
|
if (!tsrm_is_managed_thread()) {
|
||||||
fprintf(stderr, "zend_timeout_handler() called in a thread not managed by PHP. The expected signal handler will not be called. This is probably a bug.\n");
|
fprintf(stderr, "zend_timeout_handler() called in a thread not managed by PHP. The expected signal handler will not be called. This is probably a bug.\n");
|
||||||
|
@ -1474,6 +1506,21 @@ static void zend_set_timeout_ex(zend_long seconds, bool reset_signals) /* {{{ */
|
||||||
zend_error_noreturn(E_ERROR, "Could not queue new timer");
|
zend_error_noreturn(E_ERROR, "Could not queue new timer");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
#elif defined(ZEND_MAX_EXECUTION_TIMERS)
|
||||||
|
zend_max_execution_timer_settime(seconds);
|
||||||
|
|
||||||
|
if (reset_signals) {
|
||||||
|
sigset_t sigset;
|
||||||
|
struct sigaction act;
|
||||||
|
|
||||||
|
act.sa_sigaction = zend_timeout_handler;
|
||||||
|
sigemptyset(&act.sa_mask);
|
||||||
|
act.sa_flags = SA_ONSTACK | SA_SIGINFO;
|
||||||
|
sigaction(SIGRTMIN, &act, NULL);
|
||||||
|
sigemptyset(&sigset);
|
||||||
|
sigaddset(&sigset, SIGRTMIN);
|
||||||
|
sigprocmask(SIG_UNBLOCK, &sigset, NULL);
|
||||||
|
}
|
||||||
#elif defined(HAVE_SETITIMER)
|
#elif defined(HAVE_SETITIMER)
|
||||||
{
|
{
|
||||||
struct itimerval t_r; /* timeout requested */
|
struct itimerval t_r; /* timeout requested */
|
||||||
|
@ -1539,6 +1586,8 @@ void zend_unset_timeout(void) /* {{{ */
|
||||||
}
|
}
|
||||||
tq_timer = NULL;
|
tq_timer = NULL;
|
||||||
}
|
}
|
||||||
|
#elif ZEND_MAX_EXECUTION_TIMERS
|
||||||
|
zend_max_execution_timer_settime(0);
|
||||||
#elif defined(HAVE_SETITIMER)
|
#elif defined(HAVE_SETITIMER)
|
||||||
if (EG(timeout_seconds)) {
|
if (EG(timeout_seconds)) {
|
||||||
struct itimerval no_timeout;
|
struct itimerval no_timeout;
|
||||||
|
|
|
@ -23,6 +23,7 @@
|
||||||
|
|
||||||
#include <setjmp.h>
|
#include <setjmp.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
|
||||||
#include "zend_globals_macros.h"
|
#include "zend_globals_macros.h"
|
||||||
|
|
||||||
|
@ -39,6 +40,7 @@
|
||||||
#include "zend_multiply.h"
|
#include "zend_multiply.h"
|
||||||
#include "zend_arena.h"
|
#include "zend_arena.h"
|
||||||
#include "zend_call_stack.h"
|
#include "zend_call_stack.h"
|
||||||
|
#include "zend_max_execution_timer.h"
|
||||||
|
|
||||||
/* Define ZTS if you want a thread-safe Zend */
|
/* Define ZTS if you want a thread-safe Zend */
|
||||||
/*#undef ZTS*/
|
/*#undef ZTS*/
|
||||||
|
@ -294,6 +296,12 @@ struct _zend_executor_globals {
|
||||||
zend_ulong reserved_stack_size;
|
zend_ulong reserved_stack_size;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef ZEND_MAX_EXECUTION_TIMERS
|
||||||
|
timer_t max_execution_timer_timer;
|
||||||
|
pid_t pid;
|
||||||
|
struct sigaction oldact;
|
||||||
|
#endif
|
||||||
|
|
||||||
void *reserved[ZEND_MAX_RESERVED_RESOURCES];
|
void *reserved[ZEND_MAX_RESERVED_RESOURCES];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
103
Zend/zend_max_execution_timer.c
Normal file
103
Zend/zend_max_execution_timer.c
Normal file
|
@ -0,0 +1,103 @@
|
||||||
|
/*
|
||||||
|
+----------------------------------------------------------------------+
|
||||||
|
| Copyright (c) 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: |
|
||||||
|
| https://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. |
|
||||||
|
+----------------------------------------------------------------------+
|
||||||
|
| Author: Kévin Dunglas <kevin@dunglas.dev> |
|
||||||
|
+----------------------------------------------------------------------+
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef ZEND_MAX_EXECUTION_TIMERS
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <signal.h>
|
||||||
|
#include <time.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <sys/syscall.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
|
||||||
|
#include "zend.h"
|
||||||
|
#include "zend_globals.h"
|
||||||
|
|
||||||
|
// Musl Libc defines this macro, glibc does not
|
||||||
|
// According to "man 2 timer_create" this field should always be available, but it's not: https://sourceware.org/bugzilla/show_bug.cgi?id=27417
|
||||||
|
# ifndef sigev_notify_thread_id
|
||||||
|
# define sigev_notify_thread_id _sigev_un._tid
|
||||||
|
# endif
|
||||||
|
|
||||||
|
ZEND_API void zend_max_execution_timer_init(void) /* {{{ */
|
||||||
|
{
|
||||||
|
struct sigevent sev;
|
||||||
|
sev.sigev_notify = SIGEV_THREAD_ID;
|
||||||
|
sev.sigev_value.sival_ptr = &EG(max_execution_timer_timer);
|
||||||
|
sev.sigev_signo = SIGRTMIN;
|
||||||
|
sev.sigev_notify_thread_id = (pid_t) syscall(SYS_gettid);
|
||||||
|
|
||||||
|
EG(pid) = getpid();
|
||||||
|
// Measure wall time instead of CPU time as originally planned now that it is possible https://github.com/php/php-src/pull/6504#issuecomment-1370303727
|
||||||
|
if (timer_create(CLOCK_BOOTTIME, &sev, &EG(max_execution_timer_timer)) != 0) {
|
||||||
|
zend_strerror_noreturn(E_ERROR, errno, "Could not create timer");
|
||||||
|
}
|
||||||
|
|
||||||
|
# ifdef MAX_EXECUTION_TIMERS_DEBUG
|
||||||
|
fprintf(stderr, "Timer %#jx created on thread %d\n", (uintmax_t) EG(max_execution_timer_timer), sev.sigev_notify_thread_id);
|
||||||
|
# endif
|
||||||
|
|
||||||
|
sigaction(sev.sigev_signo, NULL, &EG(oldact));
|
||||||
|
}
|
||||||
|
/* }}} */
|
||||||
|
|
||||||
|
void zend_max_execution_timer_settime(zend_long seconds) /* {{{ }*/
|
||||||
|
{
|
||||||
|
/* Timer not initialized or shutdown. */
|
||||||
|
if (!EG(pid)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
timer_t timer = EG(max_execution_timer_timer);
|
||||||
|
|
||||||
|
struct itimerspec its;
|
||||||
|
its.it_value.tv_sec = seconds;
|
||||||
|
its.it_value.tv_nsec = its.it_interval.tv_sec = its.it_interval.tv_nsec = 0;
|
||||||
|
|
||||||
|
# ifdef MAX_EXECUTION_TIMERS_DEBUG
|
||||||
|
fprintf(stderr, "Setting timer %#jx on thread %d (%ld seconds)...\n", (uintmax_t) timer, (pid_t) syscall(SYS_gettid), seconds);
|
||||||
|
# endif
|
||||||
|
|
||||||
|
if (timer_settime(timer, 0, &its, NULL) != 0) {
|
||||||
|
zend_strerror_noreturn(E_ERROR, errno, "Could not set timer");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* }}} */
|
||||||
|
|
||||||
|
void zend_max_execution_timer_shutdown(void) /* {{{ */
|
||||||
|
{
|
||||||
|
/* Don't try to delete a timer created before a call to fork() */
|
||||||
|
if (EG(pid) != getpid()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
EG(pid) = 0;
|
||||||
|
|
||||||
|
timer_t timer = EG(max_execution_timer_timer);
|
||||||
|
|
||||||
|
# ifdef MAX_EXECUTION_TIMERS_DEBUG
|
||||||
|
fprintf(stderr, "Deleting timer %#jx on thread %d...\n", (uintmax_t) timer, (pid_t) syscall(SYS_gettid));
|
||||||
|
# endif
|
||||||
|
|
||||||
|
int err = timer_delete(timer);
|
||||||
|
if (err != 0) {
|
||||||
|
zend_strerror_noreturn(E_ERROR, errno, "Could not delete timer");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* }}}} */
|
||||||
|
|
||||||
|
#endif
|
36
Zend/zend_max_execution_timer.h
Normal file
36
Zend/zend_max_execution_timer.h
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
/*
|
||||||
|
+----------------------------------------------------------------------+
|
||||||
|
| Copyright (c) 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: |
|
||||||
|
| https://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. |
|
||||||
|
+----------------------------------------------------------------------+
|
||||||
|
| Author: Kévin Dunglas <kevin@dunglas.dev> |
|
||||||
|
+----------------------------------------------------------------------+
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef ZEND_MAX_EXECUTION_TIMER_H
|
||||||
|
#define ZEND_MAX_EXECUTION_TIMER_H
|
||||||
|
|
||||||
|
# ifdef ZEND_MAX_EXECUTION_TIMERS
|
||||||
|
|
||||||
|
#include "zend_long.h"
|
||||||
|
|
||||||
|
/* Must be called after calls to fork() */
|
||||||
|
ZEND_API void zend_max_execution_timer_init(void);
|
||||||
|
void zend_max_execution_timer_settime(zend_long seconds);
|
||||||
|
void zend_max_execution_timer_shutdown(void);
|
||||||
|
|
||||||
|
# else
|
||||||
|
|
||||||
|
#define zend_max_execution_timer_init()
|
||||||
|
#define zend_max_execution_timer_settime(seconds)
|
||||||
|
#define zend_max_execution_timer_shutdown()
|
||||||
|
|
||||||
|
# endif
|
||||||
|
#endif
|
|
@ -636,6 +636,7 @@ asprintf \
|
||||||
nanosleep \
|
nanosleep \
|
||||||
memmem \
|
memmem \
|
||||||
memrchr \
|
memrchr \
|
||||||
|
strerror_r \
|
||||||
)
|
)
|
||||||
|
|
||||||
AX_FUNC_WHICH_GETHOSTBYNAME_R
|
AX_FUNC_WHICH_GETHOSTBYNAME_R
|
||||||
|
@ -1722,7 +1723,7 @@ PHP_ADD_SOURCES(Zend, \
|
||||||
zend_virtual_cwd.c zend_ast.c zend_objects.c zend_object_handlers.c zend_objects_API.c \
|
zend_virtual_cwd.c zend_ast.c zend_objects.c zend_object_handlers.c zend_objects_API.c \
|
||||||
zend_default_classes.c zend_inheritance.c zend_smart_str.c zend_cpuinfo.c zend_gdb.c \
|
zend_default_classes.c zend_inheritance.c zend_smart_str.c zend_cpuinfo.c zend_gdb.c \
|
||||||
zend_observer.c zend_system_id.c zend_enum.c zend_fibers.c zend_atomic.c \
|
zend_observer.c zend_system_id.c zend_enum.c zend_fibers.c zend_atomic.c \
|
||||||
zend_rc_debug.c \
|
zend_rc_debug.c zend_max_execution_timer.c \
|
||||||
Optimizer/zend_optimizer.c \
|
Optimizer/zend_optimizer.c \
|
||||||
Optimizer/pass1.c \
|
Optimizer/pass1.c \
|
||||||
Optimizer/pass3.c \
|
Optimizer/pass3.c \
|
||||||
|
|
|
@ -58,6 +58,8 @@
|
||||||
|
|
||||||
#include "pcntl_arginfo.h"
|
#include "pcntl_arginfo.h"
|
||||||
|
|
||||||
|
#include "Zend/zend_max_execution_timer.h"
|
||||||
|
|
||||||
ZEND_DECLARE_MODULE_GLOBALS(pcntl)
|
ZEND_DECLARE_MODULE_GLOBALS(pcntl)
|
||||||
static PHP_GINIT_FUNCTION(pcntl);
|
static PHP_GINIT_FUNCTION(pcntl);
|
||||||
|
|
||||||
|
@ -184,6 +186,8 @@ PHP_FUNCTION(pcntl_fork)
|
||||||
if (id == -1) {
|
if (id == -1) {
|
||||||
PCNTL_G(last_error) = errno;
|
PCNTL_G(last_error) = errno;
|
||||||
php_error_docref(NULL, E_WARNING, "Error %d", errno);
|
php_error_docref(NULL, E_WARNING, "Error %d", errno);
|
||||||
|
} else if (id == 0) {
|
||||||
|
zend_max_execution_timer_init();
|
||||||
}
|
}
|
||||||
|
|
||||||
RETURN_LONG((zend_long) id);
|
RETURN_LONG((zend_long) id);
|
||||||
|
|
|
@ -898,6 +898,12 @@ PHPAPI ZEND_COLD void php_print_info(int flag)
|
||||||
efree(descr);
|
efree(descr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef ZEND_MAX_EXECUTION_TIMERS
|
||||||
|
php_info_print_table_row(2, "Zend Max Execution Timers", "enabled" );
|
||||||
|
#else
|
||||||
|
php_info_print_table_row(2, "Zend Max Execution Timers", "disabled" );
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef HAVE_IPV6
|
#ifdef HAVE_IPV6
|
||||||
php_info_print_table_row(2, "IPv6 Support", "enabled" );
|
php_info_print_table_row(2, "IPv6 Support", "enabled" );
|
||||||
#else
|
#else
|
||||||
|
|
|
@ -34,6 +34,7 @@ Thread Safety => %s%A
|
||||||
Zend Signal Handling => %s
|
Zend Signal Handling => %s
|
||||||
Zend Memory Manager => %s
|
Zend Memory Manager => %s
|
||||||
Zend Multibyte Support => %s
|
Zend Multibyte Support => %s
|
||||||
|
Zend Max Execution Timers => %s
|
||||||
IPv6 Support => %s
|
IPv6 Support => %s
|
||||||
DTrace Support => %s
|
DTrace Support => %s
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue