diff options
Diffstat (limited to 'sapi/phpdbg/phpdbg_sigio_win32.c')
| -rw-r--r-- | sapi/phpdbg/phpdbg_sigio_win32.c | 120 | 
1 files changed, 120 insertions, 0 deletions
diff --git a/sapi/phpdbg/phpdbg_sigio_win32.c b/sapi/phpdbg/phpdbg_sigio_win32.c new file mode 100644 index 0000000000..24e9ac0e0a --- /dev/null +++ b/sapi/phpdbg/phpdbg_sigio_win32.c @@ -0,0 +1,120 @@ +/* +   +----------------------------------------------------------------------+ +   | PHP Version 5                                                        | +   +----------------------------------------------------------------------+ +   | Copyright (c) 7-4 The PHP Group                                      | +   +----------------------------------------------------------------------+ +   | This source file is subject to version 3.01 of the PHP license,      | +   | that is bundled with this package in the file LICENSE, and is        | +   | available through the world-wide-web at the following url:           | +   | http://www.php.net/license/3_01.txt                                  | +   | If you did not receive a copy of the PHP license and are unable to   | +   | obtain it through the world-wide-web, please send a note to          | +   | license@php.net so we can mail you a copy immediately.               | +   +----------------------------------------------------------------------+ +   | Authors: Anatol Belski <ab@php.net>                                  | +   +----------------------------------------------------------------------+ +*/ + + +#include <signal.h> + +#include "phpdbg.h" +#include "phpdbg_sigio_win32.h" + + +ZEND_EXTERN_MODULE_GLOBALS(phpdbg); + + +VOID +SigIoWatcherThread(VOID *p) +{ +	zend_uchar sig; +	struct win32_sigio_watcher_data *swd = (struct win32_sigio_watcher_data *)p; +#ifdef ZTS +	void ***tsrm_ls = swd->tsrm_ls; +top: +	(void)phpdbg_consume_bytes(swd->fd, &sig, 1, -1, tsrm_ls); +#else +top: +	(void)phpdbg_consume_bytes(swd->fd, &sig, 1, -1); +#endif + + +	if (3 == sig) { +		printf("signaled, got %d", sig); +		/* XXX completely not sure it is done right here */ +		if (swd->flags & PHPDBG_IS_INTERACTIVE) { +			if (raise(sig)) { +				/* just out*/ +				exit(0); +			} +		} +		if (swd->flags & PHPDBG_IS_SIGNALED) { +			phpdbg_set_sigsafe_mem(&sig TSRMLS_CC); +			zend_try { +				phpdbg_force_interruption(TSRMLS_C); +			} zend_end_try(); +			phpdbg_clear_sigsafe_mem(TSRMLS_C); +		} +		/* XXX set signaled flag to the caller thread, question is - whether it's needed */ +		ExitThread(sig); +	} else { +		goto top; +	} +} + + +/* Start this only for the time of the run or eval command, +for so long that the main thread is busy serving some debug +session. */ +void +sigio_watcher_start(void) +{ +	TSRMLS_FETCH(); + +	PHPDBG_G(swd).fd = PHPDBG_G(io)[PHPDBG_STDIN].fd; +	PHPDBG_G(swd).running = 1; +	PHPDBG_G(swd).flags = PHPDBG_G(flags); +#ifdef ZTS +	PHPDBG_G(swd).tsrm_ls = tsrm_ls; +#endif + +	PHPDBG_G(sigio_watcher_thread) = CreateThread( +		NULL, +		0, +		(LPTHREAD_START_ROUTINE)SigIoWatcherThread, +		&PHPDBG_G(swd), +		0, +		NULL); +} + +void +sigio_watcher_stop(void) +{ +	DWORD waited; +	TSRMLS_FETCH(); + +	if (INVALID_HANDLE_VALUE == PHPDBG_G(sigio_watcher_thread)) { +		/* it probably did bail out already */ +		return; +	} + +	waited = WaitForSingleObject(PHPDBG_G(sigio_watcher_thread), 300); + +	if (WAIT_OBJECT_0 != waited) { +		if (!CancelSynchronousIo(PHPDBG_G(sigio_watcher_thread))) { +			/* error out */ +		} + +		if (!TerminateThread(PHPDBG_G(sigio_watcher_thread), 0)) { +			/* error out */ +		} +	} + +	PHPDBG_G(swd).fd = -1; +	PHPDBG_G(swd).running = 0; +	PHPDBG_G(swd).flags = 0; +	PHPDBG_G(sigio_watcher_thread) = INVALID_HANDLE_VALUE; +} +  | 
