1 /*
2 +----------------------------------------------------------------------+
3 | Copyright (c) The PHP Group |
4 +----------------------------------------------------------------------+
5 | This source file is subject to version 3.01 of the PHP license, |
6 | that is bundled with this package in the file LICENSE, and is |
7 | available through the world-wide-web at the following url: |
8 | http://www.php.net/license/3_01.txt |
9 | If you did not receive a copy of the PHP license and are unable to |
10 | obtain it through the world-wide-web, please send a note to |
11 | license@php.net so we can mail you a copy immediately. |
12 +----------------------------------------------------------------------+
13 | Authors: Anatol Belski <ab@php.net> |
14 +----------------------------------------------------------------------+
15 */
16
17
18 #include <signal.h>
19
20 #include "phpdbg.h"
21 #include "phpdbg_sigio_win32.h"
22
23
ZEND_EXTERN_MODULE_GLOBALS(phpdbg)24 ZEND_EXTERN_MODULE_GLOBALS(phpdbg)
25
26
27 VOID
28 SigIoWatcherThread(VOID *p)
29 {
30 zend_uchar sig;
31 struct win32_sigio_watcher_data *swd = (struct win32_sigio_watcher_data *)p;
32
33 top:
34 (void)phpdbg_consume_bytes(swd->fd, &sig, 1, -1);
35
36
37 if (3 == sig) {
38 /* XXX completely not sure it is done right here */
39 if (*swd->flags & PHPDBG_IS_INTERACTIVE) {
40 if (raise(sig)) {
41 goto top;
42 }
43 }
44 if (*swd->flags & PHPDBG_IS_SIGNALED) {
45 phpdbg_set_sigsafe_mem(&sig);
46 zend_try {
47 phpdbg_force_interruption();
48 } zend_end_try();
49 phpdbg_clear_sigsafe_mem();
50 goto end;
51 }
52 if (!(*swd->flags & PHPDBG_IS_INTERACTIVE)) {
53 *swd->flags |= PHPDBG_IS_SIGNALED;
54 }
55 end:
56 /* XXX set signaled flag to the caller thread, question is - whether it's needed */
57 ExitThread(sig);
58 } else {
59 goto top;
60 }
61 }
62
63
64 /* Start this only for the time of the run or eval command,
65 for so long that the main thread is busy serving some debug
66 session. */
67 void
sigio_watcher_start(void)68 sigio_watcher_start(void)
69 {
70
71 PHPDBG_G(swd).fd = PHPDBG_G(io)[PHPDBG_STDIN].fd;
72 #ifdef ZTS
73 PHPDBG_G(swd).flags = &PHPDBG_G(flags);
74 #endif
75
76 PHPDBG_G(sigio_watcher_thread) = CreateThread(
77 NULL,
78 0,
79 (LPTHREAD_START_ROUTINE)SigIoWatcherThread,
80 &PHPDBG_G(swd),
81 0,
82 NULL);
83 }
84
85 void
sigio_watcher_stop(void)86 sigio_watcher_stop(void)
87 {
88 DWORD waited;
89
90 if (INVALID_HANDLE_VALUE == PHPDBG_G(sigio_watcher_thread)) {
91 /* it probably did bail out already */
92 return;
93 }
94
95 waited = WaitForSingleObject(PHPDBG_G(sigio_watcher_thread), 300);
96
97 if (WAIT_OBJECT_0 != waited) {
98 if (!CancelSynchronousIo(PHPDBG_G(sigio_watcher_thread))) {
99 /* error out */
100 }
101
102 if (!TerminateThread(PHPDBG_G(sigio_watcher_thread), 0)) {
103 /* error out */
104 }
105 }
106
107 PHPDBG_G(swd).fd = -1;
108 PHPDBG_G(sigio_watcher_thread) = INVALID_HANDLE_VALUE;
109 }
110