bpo-30860: Consolidate stateful runtime globals. (#2594) · python/cpython@76d5abc (original) (raw)

``

1

`+

#ifndef CONDVAR_H

`

``

2

`+

#define CONDVAR_H

`

``

3

+

``

4

`+

#ifndef _POSIX_THREADS

`

``

5

`+

/* This means pthreads are not implemented in libc headers, hence the macro

`

``

6

`+

not present in unistd.h. But they still can be implemented as an external

`

``

7

`+

library (e.g. gnu pth in pthread emulation) */

`

``

8

`+

ifdef HAVE_PTHREAD_H

`

``

9

`+

include <pthread.h> /* _POSIX_THREADS */

`

``

10

`+

endif

`

``

11

`+

#endif

`

``

12

+

``

13

`+

#ifdef _POSIX_THREADS

`

``

14

`+

/*

`

``

15

`+

`

``

16

`+

*/

`

``

17

`+

#define Py_HAVE_CONDVAR

`

``

18

+

``

19

`+

#include <pthread.h>

`

``

20

+

``

21

`+

#define PyMUTEX_T pthread_mutex_t

`

``

22

`+

#define PyCOND_T pthread_cond_t

`

``

23

+

``

24

`+

#elif defined(NT_THREADS)

`

``

25

`+

/*

`

``

26

`+

`

``

27

`+

`

``

28

`+

`

``

29

`+

`

``

30

`+

*/

`

``

31

`+

#define Py_HAVE_CONDVAR

`

``

32

+

``

33

`+

/* include windows if it hasn't been done before */

`

``

34

`+

#define WIN32_LEAN_AND_MEAN

`

``

35

`+

#include <windows.h>

`

``

36

+

``

37

`+

/* options */

`

``

38

`+

/* non-emulated condition variables are provided for those that want

`

``

39

`+

`

``

40

`+

*/

`

``

41

`+

#ifndef _PY_EMULATED_WIN_CV

`

``

42

`+

#define _PY_EMULATED_WIN_CV 1 /* use emulated condition variables */

`

``

43

`+

#endif

`

``

44

+

``

45

`+

/* fall back to emulation if not targeting Vista */

`

``

46

`+

#if !defined NTDDI_VISTA || NTDDI_VERSION < NTDDI_VISTA

`

``

47

`+

#undef _PY_EMULATED_WIN_CV

`

``

48

`+

#define _PY_EMULATED_WIN_CV 1

`

``

49

`+

#endif

`

``

50

+

``

51

`+

#if _PY_EMULATED_WIN_CV

`

``

52

+

``

53

`+

typedef CRITICAL_SECTION PyMUTEX_T;

`

``

54

+

``

55

`+

/* The ConditionVariable object. From XP onwards it is easily emulated

`

``

56

`+

with a Semaphore.

`

``

57

`+

Semaphores are available on Windows XP (2003 server) and later.

`

``

58

`+

We use a Semaphore rather than an auto-reset event, because although

`

``

59

`+

an auto-resent event might appear to solve the lost-wakeup bug (race

`

``

60

`+

condition between releasing the outer lock and waiting) because it

`

``

61

`+

maintains state even though a wait hasn't happened, there is still

`

``

62

`+

a lost wakeup problem if more than one thread are interrupted in the

`

``

63

`+

critical place. A semaphore solves that, because its state is

`

``

64

`+

counted, not Boolean.

`

``

65

`+

Because it is ok to signal a condition variable with no one

`

``

66

`+

waiting, we need to keep track of the number of

`

``

67

`+

waiting threads. Otherwise, the semaphore's state could rise

`

``

68

`+

without bound. This also helps reduce the number of "spurious wakeups"

`

``

69

`+

that would otherwise happen.

`

``

70

`+

*/

`

``

71

+

``

72

`+

typedef struct _PyCOND_T

`

``

73

`+

{

`

``

74

`+

HANDLE sem;

`

``

75

`+

int waiting; /* to allow PyCOND_SIGNAL to be a no-op */

`

``

76

`+

} PyCOND_T;

`

``

77

+

``

78

`+

#else /* !_PY_EMULATED_WIN_CV */

`

``

79

+

``

80

`+

/* Use native Win7 primitives if build target is Win7 or higher */

`

``

81

+

``

82

`+

/* SRWLOCK is faster and better than CriticalSection */

`

``

83

`+

typedef SRWLOCK PyMUTEX_T;

`

``

84

+

``

85

`+

typedef CONDITION_VARIABLE PyCOND_T;

`

``

86

+

``

87

`+

#endif /* _PY_EMULATED_WIN_CV */

`

``

88

+

``

89

`+

#endif /* _POSIX_THREADS, NT_THREADS */

`

``

90

+

``

91

`+

#endif /* CONDVAR_H */

`