Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

gh-110014: Remove PY_TIMEOUT_MAX from limited C API #110217

Merged
merged 2 commits into from
Oct 2, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
gh-110014: Remove PY_TIMEOUT_MAX from limited C API
If the timeout is greater than PY_TIMEOUT_MAX,
PyThread_acquire_lock_timed() uses a timeout of PY_TIMEOUT_MAX
microseconds, which is around 280.6 years. This case is unlikely and
limiting a timeout to 280.6 years sounds like a reasonable trade-off.

The constant PY_TIMEOUT_MAX is not used in PyPI top 5,000 projects.
  • Loading branch information
vstinner committed Oct 2, 2023
commit f590f2c908249bd09b53426483295464c2df70c9
1 change: 0 additions & 1 deletion Doc/data/stable_abi.dat

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions Doc/whatsnew/3.13.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1290,3 +1290,6 @@ removed, although there is currently no date scheduled for their removal.
* :c:func:`PyThread_get_key_value`: use :c:func:`PyThread_tss_get`.
* :c:func:`PyThread_delete_key_value`: use :c:func:`PyThread_tss_delete`.
* :c:func:`PyThread_ReInitTLS`: no longer needed.

* Remove undocumented ``PY_TIMEOUT_MAX`` constant from the limited C API.
(Contributed by Victor Stinner in :gh:`110014`.)
8 changes: 8 additions & 0 deletions Include/cpython/pythread.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,14 @@
# error "this header file must not be included directly"
#endif

// PY_TIMEOUT_MAX is the highest usable value (in microseconds) of PY_TIMEOUT_T
// type, and depends on the system threading API.
//
// NOTE: this isn't the same value as `_thread.TIMEOUT_MAX`. The _thread module
// exposes a higher-level API, with timeouts expressed in seconds and
// floating-point numbers allowed.
PyAPI_DATA(const long long) PY_TIMEOUT_MAX;

#define PYTHREAD_INVALID_THREAD_ID ((unsigned long)-1)

#ifdef HAVE_PTHREAD_H
Expand Down
17 changes: 4 additions & 13 deletions Include/pythread.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,27 +33,18 @@ PyAPI_FUNC(int) PyThread_acquire_lock(PyThread_type_lock, int);
#define WAIT_LOCK 1
#define NOWAIT_LOCK 0

/* PY_TIMEOUT_T is the integral type used to specify timeouts when waiting
on a lock (see PyThread_acquire_lock_timed() below).
PY_TIMEOUT_MAX is the highest usable value (in microseconds) of that
type, and depends on the system threading API.

NOTE: this isn't the same value as `_thread.TIMEOUT_MAX`. The _thread
module exposes a higher-level API, with timeouts expressed in seconds
and floating-point numbers allowed.
*/
// PY_TIMEOUT_T is the integral type used to specify timeouts when waiting
// on a lock (see PyThread_acquire_lock_timed() below).
#define PY_TIMEOUT_T long long

PyAPI_DATA(const long long) PY_TIMEOUT_MAX;


/* If microseconds == 0, the call is non-blocking: it returns immediately
even when the lock can't be acquired.
If microseconds > 0, the call waits up to the specified duration.
If microseconds < 0, the call waits until success (or abnormal failure)

microseconds must be less than PY_TIMEOUT_MAX. Behaviour otherwise is
undefined.
If *microseconds* is greater than PY_TIMEOUT_MAX, clamp the timeout to
PY_TIMEOUT_MAX microseconds.

If intr_flag is true and the acquire is interrupted by a signal, then the
call will return PY_LOCK_INTR. The caller may reattempt to acquire the
Expand Down
1 change: 0 additions & 1 deletion Lib/test/test_stable_abi_ctypes.py

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Remove undocumented ``PY_TIMEOUT_MAX`` constant from the limited C API.
Patch by Victor Stinner.
4 changes: 0 additions & 4 deletions Misc/stable_abi.toml
Original file line number Diff line number Diff line change
Expand Up @@ -1843,10 +1843,6 @@
[function.PyThread_start_new_thread]
added = '3.2'

# Not mentioned in PEP 384, was implemented as a macro in Python <= 3.12
[data.PY_TIMEOUT_MAX]
added = '3.2'

# The following were added in PC/python3.def in Python 3.3:
# 7800f75827b1be557be16f3b18f5170fbf9fae08
# 9c56409d3353b8cd4cfc19e0467bbe23fd34fc92
Expand Down
1 change: 0 additions & 1 deletion PC/python3dll.c

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 1 addition & 6 deletions Tools/build/smelly.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,6 @@
if sys.platform == 'darwin':
ALLOWED_PREFIXES += ('__Py',)

# "Legacy": some old symbols are prefixed by "PY_".
EXCEPTIONS = frozenset({
'PY_TIMEOUT_MAX',
})

IGNORED_EXTENSION = "_ctypes_test"
# Ignore constructor and destructor functions
IGNORED_SYMBOLS = {'_init', '_fini'}
Expand Down Expand Up @@ -77,7 +72,7 @@ def get_smelly_symbols(stdout):
symbol = parts[-1]
result = '%s (type: %s)' % (symbol, symtype)

if symbol.startswith(ALLOWED_PREFIXES) or symbol in EXCEPTIONS:
if symbol.startswith(ALLOWED_PREFIXES):
python_symbols.append(result)
continue

Expand Down