gh-110014: Fix _POSIX_THREADS and _POSIX_SEMAPHORES usage (#110139)

* pycore_pythread.h is now the central place to make sure that
  _POSIX_THREADS and _POSIX_SEMAPHORES macros are defined if
  available.
* Make sure that pycore_pythread.h is included when _POSIX_THREADS
  and _POSIX_SEMAPHORES macros are tested.
* PY_TIMEOUT_MAX is now defined as a constant, since its value
  depends on _POSIX_THREADS, instead of being defined as a macro.
* Prevent integer overflow in the preprocessor when computing
  PY_TIMEOUT_MAX_VALUE on Windows:
  replace "0xFFFFFFFELL * 1000 < LLONG_MAX"
  with "0xFFFFFFFELL < LLONG_MAX / 1000".
* Document the change and give hints how to fix affected code.
* Add an exception for PY_TIMEOUT_MAX  name to smelly.py
* Add PY_TIMEOUT_MAX to the stable ABI
This commit is contained in:
Victor Stinner 2023-09-30 19:25:54 +02:00 committed by GitHub
parent f3bb00ea12
commit 74e425ec18
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
13 changed files with 72 additions and 57 deletions

View file

@ -8,7 +8,7 @@
#include "Python.h"
#include "pycore_pystate.h" // _PyInterpreterState_GET()
#include "pycore_structseq.h" // _PyStructSequence_FiniBuiltin()
#include "pycore_pythread.h"
#include "pycore_pythread.h" // _POSIX_THREADS
#ifndef DONT_HAVE_STDIO_H
# include <stdio.h>
@ -17,6 +17,26 @@
#include <stdlib.h>
// Define PY_TIMEOUT_MAX constant.
#ifdef _POSIX_THREADS
// PyThread_acquire_lock_timed() uses _PyTime_FromNanoseconds(us * 1000),
// convert microseconds to nanoseconds.
# define PY_TIMEOUT_MAX_VALUE (LLONG_MAX / 1000)
#elif defined (NT_THREADS)
// WaitForSingleObject() accepts timeout in milliseconds in the range
// [0; 0xFFFFFFFE] (DWORD type). INFINITE value (0xFFFFFFFF) means no
// timeout. 0xFFFFFFFE milliseconds is around 49.7 days.
# if 0xFFFFFFFELL < LLONG_MAX / 1000
# define PY_TIMEOUT_MAX_VALUE (0xFFFFFFFELL * 1000)
# else
# define PY_TIMEOUT_MAX_VALUE LLONG_MAX
# endif
#else
# define PY_TIMEOUT_MAX_VALUE LLONG_MAX
#endif
const long long PY_TIMEOUT_MAX = PY_TIMEOUT_MAX_VALUE;
static void PyThread__init_thread(void); /* Forward */
#define initialized _PyRuntime.threads.initialized