diff options
author | Igor Pashev <pashev.igor@gmail.com> | 2015-02-20 22:25:42 +0300 |
---|---|---|
committer | Igor Pashev <pashev.igor@gmail.com> | 2015-02-20 22:25:42 +0300 |
commit | 71d41ca6bb3a9d888b39f34a30f994ac1cf88873 (patch) | |
tree | 3a11365b77b332c078440204fb82549d34237a35 /Zend/zend_execute_API.c | |
parent | 2d50280dd013556e51b6f275ca965fe7b530029b (diff) | |
parent | 1ceec3a053647865493ab417d3ce401b9bc42450 (diff) | |
download | php-71d41ca6bb3a9d888b39f34a30f994ac1cf88873.tar.gz |
Merge branch 'master-5.6' of git://anonscm.debian.org/pkg-php/php
Conflicts:
debian/changelog
debian/patches/series
Diffstat (limited to 'Zend/zend_execute_API.c')
-rw-r--r-- | Zend/zend_execute_API.c | 168 |
1 files changed, 44 insertions, 124 deletions
diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c index af32e91f2..aeced8fb4 100644 --- a/Zend/zend_execute_API.c +++ b/Zend/zend_execute_API.c @@ -2,7 +2,7 @@ +----------------------------------------------------------------------+ | Zend Engine | +----------------------------------------------------------------------+ - | Copyright (c) 1998-2014 Zend Technologies Ltd. (http://www.zend.com) | + | Copyright (c) 1998-2015 Zend Technologies Ltd. (http://www.zend.com) | +----------------------------------------------------------------------+ | This source file is subject to version 2.00 of the Zend license, | | that is bundled with this package in the file LICENSE, and is | @@ -46,13 +46,10 @@ ZEND_API const zend_fcall_info empty_fcall_info = { 0, NULL, NULL, NULL, NULL, 0 ZEND_API const zend_fcall_info_cache empty_fcall_info_cache = { 0, NULL, NULL, NULL, NULL }; #ifdef ZEND_WIN32 -#include <process.h> -static WNDCLASS wc; -static HWND timeout_window; -static HANDLE timeout_thread_event; -static HANDLE timeout_thread_handle; -static DWORD timeout_thread_id; -static int timeout_thread_initialized=0; +#ifdef ZTS +__declspec(thread) +#endif +HANDLE tq_timer = NULL; #endif #if 0&&ZEND_DEBUG @@ -109,7 +106,7 @@ static int clean_non_persistent_function(zend_function *function TSRMLS_DC) /* { } /* }}} */ -static int clean_non_persistent_function_full(zend_function *function TSRMLS_DC) /* {{{ */ +ZEND_API int clean_non_persistent_function_full(zend_function *function TSRMLS_DC) /* {{{ */ { return (function->type == ZEND_INTERNAL_FUNCTION) ? ZEND_HASH_APPLY_KEEP : ZEND_HASH_APPLY_REMOVE; } @@ -121,7 +118,7 @@ static int clean_non_persistent_class(zend_class_entry **ce TSRMLS_DC) /* {{{ */ } /* }}} */ -static int clean_non_persistent_class_full(zend_class_entry **ce TSRMLS_DC) /* {{{ */ +ZEND_API int clean_non_persistent_class_full(zend_class_entry **ce TSRMLS_DC) /* {{{ */ { return ((*ce)->type == ZEND_INTERNAL_CLASS) ? ZEND_HASH_APPLY_KEEP : ZEND_HASH_APPLY_REMOVE; } @@ -1234,111 +1231,19 @@ ZEND_API void zend_timeout(int dummy) /* {{{ */ /* }}} */ #ifdef ZEND_WIN32 -static LRESULT CALLBACK zend_timeout_WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) /* {{{ */ -{ - switch (message) { - case WM_DESTROY: - PostQuitMessage(0); - break; - case WM_REGISTER_ZEND_TIMEOUT: - /* wParam is the thread id pointer, lParam is the timeout amount in seconds */ - if (lParam == 0) { - KillTimer(timeout_window, wParam); - } else { -#ifdef ZTS - void ***tsrm_ls; -#endif - SetTimer(timeout_window, wParam, lParam*1000, NULL); -#ifdef ZTS - tsrm_ls = ts_resource_ex(0, &wParam); - if (!tsrm_ls) { - /* shouldn't normally happen */ - break; - } -#endif - EG(timed_out) = 0; - } - break; - case WM_UNREGISTER_ZEND_TIMEOUT: - /* wParam is the thread id pointer */ - KillTimer(timeout_window, wParam); - break; - case WM_TIMER: { -#ifdef ZTS - void ***tsrm_ls; - - tsrm_ls = ts_resource_ex(0, &wParam); - if (!tsrm_ls) { - /* Thread died before receiving its timeout? */ - break; - } -#endif - KillTimer(timeout_window, wParam); - EG(timed_out) = 1; - } - break; - default: - return DefWindowProc(hWnd, message, wParam, lParam); - } - return 0; -} -/* }}} */ - -static unsigned __stdcall timeout_thread_proc(void *pArgs) /* {{{ */ +VOID CALLBACK tq_timer_cb(PVOID arg, BOOLEAN timed_out) { - MSG message; - - 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 -1; - } - timeout_window = CreateWindow(wc.lpszClassName, wc.lpszClassName, 0, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, NULL, NULL); - SetEvent(timeout_thread_event); - while (GetMessage(&message, NULL, 0, 0)) { - SendMessage(timeout_window, message.message, message.wParam, message.lParam); - if (message.message == WM_QUIT) { - break; - } - } - DestroyWindow(timeout_window); - UnregisterClass(wc.lpszClassName, NULL); - SetEvent(timeout_thread_handle); - return 0; -} -/* }}} */ + zend_bool *php_timed_out; -void zend_init_timeout_thread(void) /* {{{ */ -{ - timeout_thread_event = CreateEvent(NULL, FALSE, FALSE, NULL); - timeout_thread_handle = CreateEvent(NULL, FALSE, FALSE, NULL); - _beginthreadex(NULL, 0, timeout_thread_proc, NULL, 0, &timeout_thread_id); - WaitForSingleObject(timeout_thread_event, INFINITE); -} -/* }}} */ - -void zend_shutdown_timeout_thread(void) /* {{{ */ -{ - if (!timeout_thread_initialized) { + /* The doc states it'll be always true, however it theoretically + could be FALSE when the thread was signaled. */ + if (!timed_out) { return; } - PostThreadMessage(timeout_thread_id, WM_QUIT, 0, 0); - /* Wait for thread termination */ - WaitForSingleObject(timeout_thread_handle, 5000); - CloseHandle(timeout_thread_handle); - timeout_thread_initialized = 0; + php_timed_out = (zend_bool *)arg; + *php_timed_out = 1; } -/* }}} */ - #endif /* This one doesn't exists on QNX */ @@ -1356,13 +1261,28 @@ void zend_set_timeout(long seconds, int reset_signals) /* {{{ */ if(!seconds) { return; } - if (timeout_thread_initialized == 0 && InterlockedIncrement(&timeout_thread_initialized) == 1) { - /* We start up this process-wide thread here and not in zend_startup(), because if Zend - * is initialized inside a DllMain(), you're not supposed to start threads from it. - */ - zend_init_timeout_thread(); + + /* Don't use ChangeTimerQueueTimer() as it will not restart an expired + timer, so we could end up with just an ignored timeout. Instead + delete and recreate. */ + if (NULL != tq_timer) { + if (!DeleteTimerQueueTimer(NULL, tq_timer, NULL)) { + EG(timed_out) = 0; + tq_timer = NULL; + zend_error(E_ERROR, "Could not delete queued timer"); + return; + } + tq_timer = NULL; + } + + /* XXX passing NULL means the default timer queue provided by the system is used */ + if (!CreateTimerQueueTimer(&tq_timer, NULL, (WAITORTIMERCALLBACK)tq_timer_cb, (VOID*)&EG(timed_out), seconds*1000, 0, WT_EXECUTEONLYONCE)) { + EG(timed_out) = 0; + tq_timer = NULL; + zend_error(E_ERROR, "Could not queue new timer"); + return; } - PostThreadMessage(timeout_thread_id, WM_REGISTER_ZEND_TIMEOUT, (WPARAM) GetCurrentThreadId(), (LPARAM) seconds); + EG(timed_out) = 0; #else # ifdef HAVE_SETITIMER { @@ -1404,9 +1324,16 @@ void zend_set_timeout(long seconds, int reset_signals) /* {{{ */ void zend_unset_timeout(TSRMLS_D) /* {{{ */ { #ifdef ZEND_WIN32 - if(timeout_thread_initialized) { - PostThreadMessage(timeout_thread_id, WM_UNREGISTER_ZEND_TIMEOUT, (WPARAM) GetCurrentThreadId(), (LPARAM) 0); + if (NULL != tq_timer) { + if (!DeleteTimerQueueTimer(NULL, tq_timer, NULL)) { + EG(timed_out) = 0; + tq_timer = NULL; + zend_error(E_ERROR, "Could not delete queued timer"); + return; + } + tq_timer = NULL; } + EG(timed_out) = 0; #else # ifdef HAVE_SETITIMER if (EG(timeout_seconds)) { @@ -1656,13 +1583,6 @@ ZEND_API void zend_rebuild_symbol_table(TSRMLS_D) /* {{{ */ /*printf("Cache miss! Initialized %x\n", EG(active_symbol_table));*/ } ex->symbol_table = EG(active_symbol_table); - - if (ex->op_array->this_var != -1 && - !*EX_CV_NUM(ex, ex->op_array->this_var) && - EG(This)) { - *EX_CV_NUM(ex, ex->op_array->this_var) = (zval**)EX_CV_NUM(ex, ex->op_array->last_var + ex->op_array->this_var); - **EX_CV_NUM(ex, ex->op_array->this_var) = EG(This); - } for (i = 0; i < ex->op_array->last_var; i++) { if (*EX_CV_NUM(ex, i)) { zend_hash_quick_update(EG(active_symbol_table), |