@@ -3313,36 +3313,43 @@ SimpleExtendsException(PyExc_Exception, ReferenceError,
3313
3313
3314
3314
#define MEMERRORS_SAVE 16
3315
3315
3316
+ #ifdef Py_GIL_DISABLED
3317
+ # define MEMERRORS_LOCK (state ) PyMutex_LockFlags(&state->memerrors_lock, _Py_LOCK_DONT_DETACH)
3318
+ # define MEMERRORS_UNLOCK (state ) PyMutex_Unlock(&state->memerrors_lock)
3319
+ #else
3320
+ # define MEMERRORS_LOCK (state ) ((void)0)
3321
+ # define MEMERRORS_UNLOCK (state ) ((void)0)
3322
+ #endif
3323
+
3316
3324
static PyObject *
3317
3325
get_memory_error (int allow_allocation , PyObject * args , PyObject * kwds )
3318
3326
{
3319
- PyBaseExceptionObject * self ;
3327
+ PyBaseExceptionObject * self = NULL ;
3320
3328
struct _Py_exc_state * state = get_exc_state ();
3321
- if (state -> memerrors_freelist == NULL ) {
3322
- if (!allow_allocation ) {
3323
- PyInterpreterState * interp = _PyInterpreterState_GET ();
3324
- return Py_NewRef (
3325
- & _Py_INTERP_SINGLETON (interp , last_resort_memory_error ));
3326
- }
3327
- PyObject * result = BaseException_new ((PyTypeObject * )PyExc_MemoryError , args , kwds );
3328
- return result ;
3329
- }
3330
3329
3331
- /* Fetch object from freelist and revive it */
3332
- self = state -> memerrors_freelist ;
3333
- self -> args = PyTuple_New (0 );
3334
- /* This shouldn't happen since the empty tuple is persistent */
3330
+ MEMERRORS_LOCK (state );
3331
+ if (state -> memerrors_freelist != NULL ) {
3332
+ /* Fetch MemoryError from freelist and initialize it */
3333
+ self = state -> memerrors_freelist ;
3334
+ state -> memerrors_freelist = (PyBaseExceptionObject * ) self -> dict ;
3335
+ state -> memerrors_numfree -- ;
3336
+ self -> dict = NULL ;
3337
+ self -> args = (PyObject * )& _Py_SINGLETON (tuple_empty );
3338
+ _Py_NewReference ((PyObject * )self );
3339
+ _PyObject_GC_TRACK (self );
3340
+ }
3341
+ MEMERRORS_UNLOCK (state );
3335
3342
3336
- if (self -> args = = NULL ) {
3337
- return NULL ;
3343
+ if (self ! = NULL ) {
3344
+ return ( PyObject * ) self ;
3338
3345
}
3339
3346
3340
- state -> memerrors_freelist = ( PyBaseExceptionObject * ) self -> dict ;
3341
- state -> memerrors_numfree -- ;
3342
- self -> dict = NULL ;
3343
- _Py_NewReference (( PyObject * ) self );
3344
- _PyObject_GC_TRACK ( self );
3345
- return ( PyObject * )self ;
3347
+ if (! allow_allocation ) {
3348
+ PyInterpreterState * interp = _PyInterpreterState_GET () ;
3349
+ return Py_NewRef (
3350
+ & _Py_INTERP_SINGLETON ( interp , last_resort_memory_error ) );
3351
+ }
3352
+ return BaseException_new (( PyTypeObject * )PyExc_MemoryError , args , kwds ) ;
3346
3353
}
3347
3354
3348
3355
static PyObject *
@@ -3387,14 +3394,17 @@ MemoryError_dealloc(PyBaseExceptionObject *self)
3387
3394
}
3388
3395
3389
3396
struct _Py_exc_state * state = get_exc_state ();
3390
- if (state -> memerrors_numfree >= MEMERRORS_SAVE ) {
3391
- Py_TYPE (self )-> tp_free ((PyObject * )self );
3392
- }
3393
- else {
3397
+ MEMERRORS_LOCK (state );
3398
+ if (state -> memerrors_numfree < MEMERRORS_SAVE ) {
3394
3399
self -> dict = (PyObject * ) state -> memerrors_freelist ;
3395
3400
state -> memerrors_freelist = self ;
3396
3401
state -> memerrors_numfree ++ ;
3402
+ MEMERRORS_UNLOCK (state );
3403
+ return ;
3397
3404
}
3405
+ MEMERRORS_UNLOCK (state );
3406
+
3407
+ Py_TYPE (self )-> tp_free ((PyObject * )self );
3398
3408
}
3399
3409
3400
3410
static int
0 commit comments