diff options
author | Anatol Belski <ab@php.net> | 2014-12-12 14:25:59 +0100 |
---|---|---|
committer | Anatol Belski <ab@php.net> | 2014-12-12 14:25:59 +0100 |
commit | dfb18b1188492efa48ade07029172c5535f65f93 (patch) | |
tree | 5da6d50a4918a06299162a22aa5cb98e5c76a26a /Zend/zend_execute_API.c | |
parent | de99a94c384fdb6a71c20692df33dc24a2b81a4b (diff) | |
parent | f4311686cc2c7d07abce2b752b4e8597771c5b25 (diff) | |
download | php-git-dfb18b1188492efa48ade07029172c5535f65f93.tar.gz |
Merge remote-tracking branch 'origin/master' into native-tls
* origin/master:
updated NEWS
PowerPC64 support for add and sub with overflow check
PowerPC64 support for operators with overflow check
Fixed bug #68583 Crash in timeout thread
Reduced size of zend_op on 64-bit systems.
Make ZEND_INIT_FCALL keep predcalculted size of necessary stack space in opline->op1.num to avoid its recalculation on each execution.
Removed unused variables
Improved array_merge() and array_replace() (1-st array may be added using simple procedure).
Replaced zendi_convert_to_long() with _zval_get_long_func()
Moved zend_is_true() from zend_execute.h/zend_execute_API.c into zend_operators.h/zend_operators.c. Splited the most expensive part of inline i_zend_is_true() into a separate zend_object_is_true(). Replaced zendi_convert_to_long() with cals to zend_is_true().
Revert "Save one xor instr"
Save one xor instr
Conflicts:
Zend/zend_execute_API.c
Diffstat (limited to 'Zend/zend_execute_API.c')
-rw-r--r-- | Zend/zend_execute_API.c | 170 |
1 files changed, 41 insertions, 129 deletions
diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c index 60ffb93ddc..760747affa 100644 --- a/Zend/zend_execute_API.c +++ b/Zend/zend_execute_API.c @@ -46,13 +46,10 @@ ZEND_API const zend_fcall_info empty_fcall_info = { 0, NULL, {{0}, {{0}}, {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 unsigned timeout_thread_id; -static volatile long timeout_thread_initialized=0; +#ifdef ZTS +__declspec(thread) +#endif +HANDLE tq_timer = NULL; #endif #if 0&&ZEND_DEBUG @@ -501,12 +498,6 @@ ZEND_API void _zval_internal_ptr_dtor(zval *zval_ptr ZEND_FILE_LINE_DC) /* {{{ * } /* }}} */ -ZEND_API int zend_is_true(zval *op TSRMLS_DC) /* {{{ */ -{ - return i_zend_is_true(op TSRMLS_CC); -} -/* }}} */ - #define IS_VISITED_CONSTANT 0x80 #define IS_CONSTANT_VISITED(p) (Z_TYPE_P(p) & IS_VISITED_CONSTANT) #define MARK_CONSTANT_VISITED(p) Z_TYPE_INFO_P(p) |= IS_VISITED_CONSTANT @@ -1163,120 +1154,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) /* {{{ */ +VOID CALLBACK tq_timer_cb(PVOID arg, BOOLEAN timed_out) { -#ifdef ZTS - THREAD_T thread_id = (THREAD_T)wParam; -#endif + zend_bool *php_timed_out; - 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, &thread_id); - if (!tsrm_ls) { - /* shouldn't normally happen */ - break; - } -#endif - /* XXX this won't work with TLS enabled, EG is on a different thread. - But nothing happened anyway, no timeout here. */ - /* 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, &thread_id); - if (!tsrm_ls) { - /* Thread died before receiving its timeout? */ - break; - } -#endif - KillTimer(timeout_window, wParam); - - /* XXX this won't work with TLS enabled, EG is on a different thread. - Maybe an ide were to throw the timeout window right from here. */ - /*EG(timed_out) = 1; */ - } - break; - default: - return DefWindowProc(hWnd, message, wParam, lParam); - } - return 0; -} -/* }}} */ - -static unsigned __stdcall timeout_thread_proc(void *pArgs) /* {{{ */ -{ - 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; -} -/* }}} */ - -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 */ @@ -1294,13 +1184,28 @@ void zend_set_timeout(zend_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 { @@ -1342,9 +1247,16 @@ void zend_set_timeout(zend_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)) { |