@@ -19,8 +19,13 @@ PyObject *PyExc_IOError = NULL;
19
19
PyObject * PyExc_WindowsError = NULL ;
20
20
#endif
21
21
22
- /* The dict map from errno codes to OSError subclasses */
23
- static PyObject * errnomap = NULL ;
22
+
23
+ static struct _Py_exc_state *
24
+ get_exc_state (void )
25
+ {
26
+ PyInterpreterState * interp = _PyInterpreterState_GET ();
27
+ return & interp -> exc_state ;
28
+ }
24
29
25
30
26
31
/* NOTE: If the exception class hierarchy changes, don't forget to update
@@ -985,10 +990,11 @@ OSError_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
985
990
))
986
991
goto error ;
987
992
993
+ struct _Py_exc_state * state = get_exc_state ();
988
994
if (myerrno && PyLong_Check (myerrno ) &&
989
- errnomap && (PyObject * ) type == PyExc_OSError ) {
995
+ state -> errnomap && (PyObject * ) type == PyExc_OSError ) {
990
996
PyObject * newtype ;
991
- newtype = PyDict_GetItemWithError (errnomap , myerrno );
997
+ newtype = PyDict_GetItemWithError (state -> errnomap , myerrno );
992
998
if (newtype ) {
993
999
assert (PyType_Check (newtype ));
994
1000
type = (PyTypeObject * ) newtype ;
@@ -2274,8 +2280,6 @@ SimpleExtendsException(PyExc_Exception, ReferenceError,
2274
2280
*/
2275
2281
2276
2282
#define MEMERRORS_SAVE 16
2277
- static PyBaseExceptionObject * memerrors_freelist = NULL ;
2278
- static int memerrors_numfree = 0 ;
2279
2283
2280
2284
static PyObject *
2281
2285
MemoryError_new (PyTypeObject * type , PyObject * args , PyObject * kwds )
@@ -2284,16 +2288,22 @@ MemoryError_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
2284
2288
2285
2289
if (type != (PyTypeObject * ) PyExc_MemoryError )
2286
2290
return BaseException_new (type , args , kwds );
2287
- if (memerrors_freelist == NULL )
2291
+
2292
+ struct _Py_exc_state * state = get_exc_state ();
2293
+ if (state -> memerrors_freelist == NULL ) {
2288
2294
return BaseException_new (type , args , kwds );
2295
+ }
2296
+
2289
2297
/* Fetch object from freelist and revive it */
2290
- self = memerrors_freelist ;
2298
+ self = state -> memerrors_freelist ;
2291
2299
self -> args = PyTuple_New (0 );
2292
2300
/* This shouldn't happen since the empty tuple is persistent */
2293
- if (self -> args == NULL )
2301
+ if (self -> args == NULL ) {
2294
2302
return NULL ;
2295
- memerrors_freelist = (PyBaseExceptionObject * ) self -> dict ;
2296
- memerrors_numfree -- ;
2303
+ }
2304
+
2305
+ state -> memerrors_freelist = (PyBaseExceptionObject * ) self -> dict ;
2306
+ state -> memerrors_numfree -- ;
2297
2307
self -> dict = NULL ;
2298
2308
_Py_NewReference ((PyObject * )self );
2299
2309
_PyObject_GC_TRACK (self );
@@ -2305,12 +2315,15 @@ MemoryError_dealloc(PyBaseExceptionObject *self)
2305
2315
{
2306
2316
_PyObject_GC_UNTRACK (self );
2307
2317
BaseException_clear (self );
2308
- if (memerrors_numfree >= MEMERRORS_SAVE )
2318
+
2319
+ struct _Py_exc_state * state = get_exc_state ();
2320
+ if (state -> memerrors_numfree >= MEMERRORS_SAVE ) {
2309
2321
Py_TYPE (self )-> tp_free ((PyObject * )self );
2322
+ }
2310
2323
else {
2311
- self -> dict = (PyObject * ) memerrors_freelist ;
2312
- memerrors_freelist = self ;
2313
- memerrors_numfree ++ ;
2324
+ self -> dict = (PyObject * ) state -> memerrors_freelist ;
2325
+ state -> memerrors_freelist = self ;
2326
+ state -> memerrors_numfree ++ ;
2314
2327
}
2315
2328
}
2316
2329
@@ -2335,11 +2348,11 @@ preallocate_memerrors(void)
2335
2348
}
2336
2349
2337
2350
static void
2338
- free_preallocated_memerrors (void )
2351
+ free_preallocated_memerrors (struct _Py_exc_state * state )
2339
2352
{
2340
- while (memerrors_freelist != NULL ) {
2341
- PyObject * self = (PyObject * ) memerrors_freelist ;
2342
- memerrors_freelist = (PyBaseExceptionObject * ) memerrors_freelist -> dict ;
2353
+ while (state -> memerrors_freelist != NULL ) {
2354
+ PyObject * self = (PyObject * ) state -> memerrors_freelist ;
2355
+ state -> memerrors_freelist = (PyBaseExceptionObject * )state -> memerrors_freelist -> dict ;
2343
2356
Py_TYPE (self )-> tp_free ((PyObject * )self );
2344
2357
}
2345
2358
}
@@ -2507,8 +2520,10 @@ SimpleExtendsException(PyExc_Warning, ResourceWarning,
2507
2520
#endif /* MS_WINDOWS */
2508
2521
2509
2522
PyStatus
2510
- _PyExc_Init (void )
2523
+ _PyExc_Init (PyThreadState * tstate )
2511
2524
{
2525
+ struct _Py_exc_state * state = & tstate -> interp -> exc_state ;
2526
+
2512
2527
#define PRE_INIT (TYPE ) \
2513
2528
if (!(_PyExc_ ## TYPE.tp_flags & Py_TPFLAGS_READY)) { \
2514
2529
if (PyType_Ready(&_PyExc_ ## TYPE) < 0) { \
@@ -2521,7 +2536,7 @@ _PyExc_Init(void)
2521
2536
do { \
2522
2537
PyObject *_code = PyLong_FromLong(CODE); \
2523
2538
assert(_PyObject_RealIsSubclass(PyExc_ ## TYPE, PyExc_OSError)); \
2524
- if (!_code || PyDict_SetItem(errnomap, _code, PyExc_ ## TYPE)) \
2539
+ if (!_code || PyDict_SetItem(state-> errnomap, _code, PyExc_ ## TYPE)) \
2525
2540
return _PyStatus_ERR("errmap insertion problem."); \
2526
2541
Py_DECREF(_code); \
2527
2542
} while (0)
@@ -2595,15 +2610,14 @@ _PyExc_Init(void)
2595
2610
PRE_INIT (TimeoutError );
2596
2611
2597
2612
if (preallocate_memerrors () < 0 ) {
2598
- return _PyStatus_ERR ( "Could not preallocate MemoryError object" );
2613
+ return _PyStatus_NO_MEMORY ( );
2599
2614
}
2600
2615
2601
2616
/* Add exceptions to errnomap */
2602
- if (!errnomap ) {
2603
- errnomap = PyDict_New ();
2604
- if (!errnomap ) {
2605
- return _PyStatus_ERR ("Cannot allocate map from errnos to OSError subclasses" );
2606
- }
2617
+ assert (state -> errnomap == NULL );
2618
+ state -> errnomap = PyDict_New ();
2619
+ if (!state -> errnomap ) {
2620
+ return _PyStatus_NO_MEMORY ();
2607
2621
}
2608
2622
2609
2623
ADD_ERRNO (BlockingIOError , EAGAIN );
@@ -2741,10 +2755,11 @@ _PyBuiltins_AddExceptions(PyObject *bltinmod)
2741
2755
}
2742
2756
2743
2757
void
2744
- _PyExc_Fini (void )
2758
+ _PyExc_Fini (PyThreadState * tstate )
2745
2759
{
2746
- free_preallocated_memerrors ();
2747
- Py_CLEAR (errnomap );
2760
+ struct _Py_exc_state * state = & tstate -> interp -> exc_state ;
2761
+ free_preallocated_memerrors (state );
2762
+ Py_CLEAR (state -> errnomap );
2748
2763
}
2749
2764
2750
2765
/* Helper to do the equivalent of "raise X from Y" in C, but always using
0 commit comments