QUERY · ISSUE
_thread: timeout parameter is not implemented in Lock.acquire()
py-core
https://github.com/micropython/micropython/blob/62849b7010abffb7b0a9c9875930efe7cb77519c/py/modthread.c#L69
Background:
I'm looking for a way to implement a cancelable timeout on Linux, e.g something like threading.Timer from the standard library.
Being on Linux, I'm thinking of trying a timerfd with uasyncio instead. But if implementing the timeout parameter here is not too hard, I could give it a try. It looks to be platform dependent though, so it might be beyond my capabilities.
CANDIDATE · PULL REQUEST
py/_thread: Add support for lock.acquire timeout.
py-core
Fixes #3332. Based on previous work in #5599 and #8932.
Differences to previous PR's:
- Uses a per-port resolution
- This prevents us from always converting to microseconds and back on ports that don't have that level of precision, no longer limiting the maximum timeout.
- Also used to implement
_thread.TIMEOUT_MAX(see CPython docs), which in turn is used to raise an OverflowError if a too large timeout is given.
- Maintains the
MICROPY_PY_THREAD_LOCK_TIMEOUTfeature flag from @mcdeoliveira, since some ports do not support timeouts yet.- Adds POSIX feature flags check since apparently my MacOS system doesn't support
pthread_mutex_timedlock(see here). - This flag also controls the availability of
_thread.TIMEOUT_MAX, which is used in the tests to determine whether timeouts are supported or the test should be skipped.
- Adds POSIX feature flags check since apparently my MacOS system doesn't support
- Takes into account comments from @dpgeorge in https://github.com/micropython/micropython/issues/3332#issuecomment-971109197
- Modifies the existing
mp_thread_mutex_lockto add full timeout support instead of adding an extra function. - Uses
int64_tfor the timeout value (see note below).
- Modifies the existing
It still has some open issues / questions:
- The code for adding an constant float/int to the
_threadclass is wrong. Looking at other examples likemath.PIandsys.maxsize, it looks like currently all these are defined in the globalobj.h/objint.hso they can have separate implementations for each supported storage format?- Even nicer would be if we had some helpers / defines to make it easier to define large integer / float constants, without having to put them into the global int/float implemenation files. But that's probably out of scope for this PR.
- I've switched to
int64_tbecause on the Unix port the max timeout would otherwise be a mere 35 minutes. However on many other ports the resolution method (see above) already allows for longer timeouts. We could add another per-port define for the type so we could use a smaller type on some ports? I'm not sure if that would be a meaningful improvement for the smaller microcontrollers. - The TIMEOUT_MAX value is not entirely accurate; it does for example not take into account the
mp_int_tsize limit, or on the Unix port the fact that we cannot use the full uint32 range because the current time should be subtracted.
And it needs testing on all the platforms; I've don't have hardware for all of them.
Feedback is welcomed!