phpdbg_sigio_win32.c 2.9 KB

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