1
0
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:
Zeev Suraski
2000-06-16 01:54:56 +00:00
parent f29eae1302
commit ef0bd3d102
5 changed files with 141 additions and 0 deletions

View File

@@ -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);

View File

@@ -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:

View File

@@ -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))

View File

@@ -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
}

View File

@@ -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];