_win_wait.py 1.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758
  1. ###############################################################################
  2. # Compat for wait function on Windows system
  3. #
  4. # author: Thomas Moreau and Olivier Grisel
  5. #
  6. # adapted from multiprocessing/connection.py (17/02/2017)
  7. # * Backport wait function to python2.7
  8. #
  9. import ctypes
  10. import sys
  11. from time import sleep
  12. if sys.platform == 'win32' and sys.version_info[:2] < (3, 3):
  13. from _subprocess import WaitForSingleObject, WAIT_OBJECT_0
  14. try:
  15. from time import monotonic
  16. except ImportError:
  17. # Backward old for crappy old Python that did not have cross-platform
  18. # monotonic clock by default.
  19. # TODO: do we want to add support for cygwin at some point? See:
  20. # https://github.com/atdt/monotonic/blob/master/monotonic.py
  21. GetTickCount64 = ctypes.windll.kernel32.GetTickCount64
  22. GetTickCount64.restype = ctypes.c_ulonglong
  23. def monotonic():
  24. """Monotonic clock, cannot go backward."""
  25. return GetTickCount64() / 1000.0
  26. def wait(handles, timeout=None):
  27. """Backward compat for python2.7
  28. This function wait for either:
  29. * one connection is ready for read,
  30. * one process handle has exited or got killed,
  31. * timeout is reached. Note that this function has a precision of 2
  32. msec.
  33. """
  34. if timeout is not None:
  35. deadline = monotonic() + timeout
  36. while True:
  37. # We cannot use select as in windows it only support sockets
  38. ready = []
  39. for h in handles:
  40. if type(h) in [int, long]:
  41. if WaitForSingleObject(h, 0) == WAIT_OBJECT_0:
  42. ready += [h]
  43. elif h.poll(0):
  44. ready.append(h)
  45. if len(ready) > 0:
  46. return ready
  47. sleep(.001)
  48. if timeout is not None and deadline - monotonic() <= 0:
  49. return []