Permalink
Browse files

- Move timeout code to Zend

- Implement timeouts in Win32
  • Loading branch information...
1 parent f29eae1 commit ef0bd3d102aef4909b5107a327d37c549fd879b0 @zsuraski zsuraski committed Jun 16, 2000
Showing with 141 additions and 0 deletions.
  1. +10 −0 Zend/zend.c
  2. +8 −0 Zend/zend_execute.c
  3. +8 −0 Zend/zend_execute.h
  4. +109 −0 Zend/zend_execute_API.c
  5. +6 −0 Zend/zend_globals.h
View
10 Zend/zend.c
@@ -292,13 +292,19 @@ 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
}
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
8 Zend/zend_execute.c
@@ -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
@@ -993,6 +996,11 @@ void execute(zend_op_array *op_array ELS_DC)
#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:
EG(binary_op) = add_function;
View
8 Zend/zend_execute.h
@@ -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
109 Zend/zend_execute_API.c
@@ -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
6 Zend/zend_globals.h
@@ -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];

0 comments on commit ef0bd3d

Please sign in to comment.