.. note::
+ The :meth:`acquire` and :meth:`wait` methods of each of these types
+ treat negative timeouts as zero timeouts. This differs from
+ :mod:`threading` where, since version 3.2, the equivalent
+ :meth:`acquire` methods treat negative timeouts as infinite
+ timeouts.
+
On Mac OS X, ``sem_timedwait`` is unsupported, so calling ``acquire()`` with
a timeout will emulate that function's behavior using a sleeping loop.
those objects in *object_list* which are ready. If *timeout* is a
float then the call blocks for at most that many seconds. If
*timeout* is ``None`` then it will block for an unlimited period.
+ A negative timeout is equivalent to a zero timeout.
For both Unix and Windows, an object can appear in *object_list* if
it is
import _multiprocessing
from multiprocessing import current_process, AuthenticationError, BufferTooShort
-from multiprocessing.util import (
- get_temp_dir, Finalize, sub_debug, debug, _eintr_retry)
+from multiprocessing.util import get_temp_dir, Finalize, sub_debug, debug
from multiprocessing.forking import ForkingPickler
try:
import _winapi
if (self._got_empty_message or
_winapi.PeekNamedPipe(self._handle)[0] != 0):
return True
- if timeout < 0:
- timeout = None
return bool(wait([self], timeout))
def _get_more_data(self, ov, maxsize):
return self._recv(size)
def _poll(self, timeout):
- if timeout < 0.0:
- timeout = None
r = wait([self._handle], timeout)
return bool(r)
#
if sys.platform != 'win32':
- import select
-
exit = os._exit
duplicate = os.dup
close = os.close
- _select = util._eintr_retry(select.select)
#
# We define a Popen class similar to the one from subprocess, but
def wait(self, timeout=None):
if self.returncode is None:
if timeout is not None:
- r = _select([self.sentinel], [], [], timeout)[0]
- if not r:
+ from .connection import wait
+ if not wait([self.sentinel], timeout):
return None
- # This shouldn't block if select() returned successfully.
+ # This shouldn't block if wait() returned successfully.
return self.poll(os.WNOHANG if timeout == 0.0 else 0)
return self.returncode
'HAVE_BROKEN_SEM_GETVALUE', False)
WIN32 = (sys.platform == "win32")
-if WIN32:
- from _winapi import WaitForSingleObject, INFINITE, WAIT_OBJECT_0
- def wait_for_handle(handle, timeout):
- if timeout is None or timeout < 0.0:
- timeout = INFINITE
- else:
- timeout = int(1000 * timeout)
- return WaitForSingleObject(handle, timeout) == WAIT_OBJECT_0
-else:
- from select import select
- _select = util._eintr_retry(select)
+from multiprocessing.connection import wait
- def wait_for_handle(handle, timeout):
- if timeout is not None and timeout < 0.0:
- timeout = None
- return handle in _select([handle], [], [], timeout)[0]
+def wait_for_handle(handle, timeout):
+ if timeout is not None and timeout < 0.0:
+ timeout = None
+ return wait([handle], timeout)
try:
MAXFD = os.sysconf("SC_OPEN_MAX")
self.assertIn(p, self.active_children())
self.assertEqual(p.exitcode, None)
+ join = TimingWrapper(p.join)
+
+ self.assertEqual(join(0), None)
+ self.assertTimingAlmostEqual(join.elapsed, 0.0)
+ self.assertEqual(p.is_alive(), True)
+
+ self.assertEqual(join(-1), None)
+ self.assertTimingAlmostEqual(join.elapsed, 0.0)
+ self.assertEqual(p.is_alive(), True)
+
p.terminate()
- join = TimingWrapper(p.join)
self.assertEqual(join(), None)
self.assertTimingAlmostEqual(join.elapsed, 0.0)
self.assertEqual(poll(), False)
self.assertTimingAlmostEqual(poll.elapsed, 0)
+ self.assertEqual(poll(-1), False)
+ self.assertTimingAlmostEqual(poll.elapsed, 0)
+
self.assertEqual(poll(TIMEOUT1), False)
self.assertTimingAlmostEqual(poll.elapsed, TIMEOUT1)
p.terminate()
p.join()
+ def test_neg_timeout(self):
+ from multiprocessing.connection import wait
+ a, b = multiprocessing.Pipe()
+ t = time.time()
+ res = wait([a], timeout=-1)
+ t = time.time() - t
+ self.assertEqual(res, [])
+ self.assertLess(t, 1)
+ a.close()
+ b.close()
#
# Issue 14151: Test invalid family on invalid environment