mirror of
https://github.com/php/php-src.git
synced 2026-04-11 10:03:18 +02:00
- Move timeout code to Zend
- Implement timeouts in Win32
This commit is contained in:
10
Zend/zend.c
10
Zend/zend.c
@@ -292,6 +292,9 @@ static void executor_globals_ctor(zend_executor_globals *executor_globals)
|
||||
}
|
||||
zend_init_rsrc_plist(ELS_C);
|
||||
EG(lambda_count)=0;
|
||||
#ifdef ZEND_WIN32
|
||||
zend_create_timeout_window(ELS_C);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -299,6 +302,9 @@ static void executor_globals_dtor(zend_executor_globals *executor_globals)
|
||||
{
|
||||
zend_shutdown_constants(ELS_C);
|
||||
zend_destroy_rsrc_plist(ELS_C);
|
||||
#ifdef ZEND_WIN32
|
||||
zend_destroy_timeout_window(ELS_C);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -366,6 +372,10 @@ int zend_startup(zend_utility_functions *utility_functions, char **extensions, i
|
||||
zval_used_for_init.refcount = 1;
|
||||
zval_used_for_init.type = IS_NULL;
|
||||
|
||||
#ifdef ZEND_WIN32
|
||||
zend_register_timeout_wndclass();
|
||||
#endif
|
||||
|
||||
#ifdef ZTS
|
||||
global_constants_table = NULL;
|
||||
compiler_globals_id = ts_allocate_id(sizeof(zend_compiler_globals), (void (*)(void *)) compiler_globals_ctor, (void (*)(void *)) compiler_globals_dtor);
|
||||
|
||||
@@ -955,6 +955,9 @@ void execute(zend_op_array *op_array ELS_DC)
|
||||
temp_variable Ts[op_array->T];
|
||||
#endif
|
||||
zend_bool original_in_execution=EG(in_execution);
|
||||
#ifdef ZEND_WIN32
|
||||
MSG timeout_message;
|
||||
#endif
|
||||
|
||||
EG(in_execution) = 1;
|
||||
#if SUPPORT_INTERACTIVE
|
||||
@@ -992,6 +995,11 @@ void execute(zend_op_array *op_array ELS_DC)
|
||||
while (opline<end) {
|
||||
#else
|
||||
while (1) {
|
||||
#endif
|
||||
#ifdef ZEND_WIN32
|
||||
while (PeekMessage(&timeout_message, EG(timeout_window), 0, 0, PM_REMOVE)) {
|
||||
DispatchMessage(&timeout_message);
|
||||
}
|
||||
#endif
|
||||
switch(opline->opcode) {
|
||||
case ZEND_ADD:
|
||||
|
||||
@@ -155,6 +155,14 @@ ZEND_API char *zend_get_executed_filename(ELS_D);
|
||||
ZEND_API uint zend_get_executed_lineno(ELS_D);
|
||||
ZEND_API zend_bool zend_is_executing(void);
|
||||
|
||||
void zend_set_timeout(long seconds);
|
||||
void zend_unset_timeout(void);
|
||||
#ifdef ZEND_WIN32
|
||||
void zend_register_timeout_wndclass(void);
|
||||
void zend_create_timeout_window(ELS_D);
|
||||
void zend_destroy_timeout_window(ELS_D);
|
||||
#endif
|
||||
|
||||
#define zendi_zval_copy_ctor(p) zval_copy_ctor(&(p))
|
||||
#define zendi_zval_dtor(p) zval_dtor(&(p))
|
||||
|
||||
|
||||
@@ -33,6 +33,11 @@
|
||||
|
||||
ZEND_API void (*zend_execute)(zend_op_array *op_array ELS_DC);
|
||||
|
||||
#ifdef ZEND_WIN32
|
||||
/* true global */
|
||||
static WNDCLASS wc;
|
||||
#endif
|
||||
|
||||
|
||||
#if ZEND_DEBUG
|
||||
static void (*original_sigsegv_handler)(int);
|
||||
@@ -523,3 +528,107 @@ void execute_new_code(CLS_D)
|
||||
#endif
|
||||
|
||||
|
||||
#if defined(HAVE_SETITIMER) || defined(ZEND_WIN32)
|
||||
static void zend_timeout(int dummy)
|
||||
{
|
||||
ELS_FETCH();
|
||||
|
||||
/* is there any point in this? we're terminating the request anyway...
|
||||
PLS_FETCH();
|
||||
|
||||
PG(connection_status) |= PHP_CONNECTION_TIMEOUT;
|
||||
*/
|
||||
zend_error(E_ERROR, "Maximum execution time of %d second%s exceeded",
|
||||
EG(timeout_seconds), EG(timeout_seconds) == 1 ? "" : "s");
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
static LRESULT CALLBACK zend_timeout_WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
switch (message) {
|
||||
case WM_DESTROY:
|
||||
PostQuitMessage(0);
|
||||
return 0;
|
||||
case WM_TIMER:
|
||||
zend_timeout(0);
|
||||
return 0;
|
||||
default:
|
||||
return DefWindowProc(hWnd,message,wParam,lParam);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#ifdef ZEND_WIN32
|
||||
void zend_register_timeout_wndclass()
|
||||
{
|
||||
wc.style=0;
|
||||
wc.lpfnWndProc = zend_timeout_WndProc;
|
||||
wc.cbClsExtra=0;
|
||||
wc.cbWndExtra=0;
|
||||
wc.hInstance=NULL;
|
||||
wc.hIcon=NULL;
|
||||
wc.hCursor=NULL;
|
||||
wc.hbrBackground=(HBRUSH)(COLOR_BACKGROUND + 5);
|
||||
wc.lpszMenuName=NULL;
|
||||
wc.lpszClassName = "Zend Timeout Window";
|
||||
if(!RegisterClass(&wc)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void zend_create_timeout_window(ELS_D)
|
||||
{
|
||||
EG(timeout_window) = CreateWindow(wc.lpszClassName, wc.lpszClassName, 0, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, NULL, NULL);
|
||||
}
|
||||
|
||||
|
||||
void zend_destroy_timeout_window(ELS_D)
|
||||
{
|
||||
DestroyWindow(EG(timeout_window));
|
||||
}
|
||||
#endif
|
||||
|
||||
/* This one doesn't exists on QNX */
|
||||
#ifndef SIGPROF
|
||||
#define SIGPROF 27
|
||||
#endif
|
||||
|
||||
void zend_set_timeout(long seconds)
|
||||
{
|
||||
ELS_FETCH();
|
||||
|
||||
EG(timeout_seconds) = seconds;
|
||||
#ifdef ZEND_WIN32
|
||||
SetTimer(EG(timeout_window), 1, seconds*1000, NULL);
|
||||
#else
|
||||
# ifdef HAVE_SETITIMER
|
||||
struct itimerval t_r; /* timeout requested */
|
||||
|
||||
t_r.it_value.tv_sec = seconds;
|
||||
t_r.it_value.tv_usec = t_r.it_interval.tv_sec = t_r.it_interval.tv_usec = 0;
|
||||
|
||||
setitimer(ITIMER_PROF, &t_r, NULL);
|
||||
signal(SIGPROF, zend_timeout);
|
||||
# endif
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
void zend_unset_timeout(void)
|
||||
{
|
||||
ELS_FETCH();
|
||||
|
||||
#ifdef ZEND_WIN32
|
||||
KillTimer(EG(timeout_window), 1);
|
||||
#else
|
||||
# ifdef HAVE_SETITIMER
|
||||
struct itimerval no_timeout;
|
||||
|
||||
no_timeout.it_value.tv_sec = no_timeout.it_value.tv_usec = no_timeout.it_interval.tv_sec = no_timeout.it_interval.tv_usec = 0;
|
||||
|
||||
setitimer(ITIMER_PROF, &no_timeout, NULL);
|
||||
# endif
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -180,6 +180,12 @@ struct _zend_executor_globals {
|
||||
|
||||
zval *user_error_handler;
|
||||
|
||||
/* timeout support */
|
||||
int timeout_seconds;
|
||||
#ifdef ZEND_WIN32
|
||||
HWND timeout_window;
|
||||
#endif
|
||||
|
||||
int lambda_count;
|
||||
|
||||
void *reserved[ZEND_MAX_RESERVED_RESOURCES];
|
||||
|
||||
Reference in New Issue
Block a user