@@ -3313,36 +3313,43 @@ SimpleExtendsException(PyExc_Exception, ReferenceError,
33133313
33143314#define MEMERRORS_SAVE 16
33153315
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+
33163324static PyObject *
33173325get_memory_error (int allow_allocation , PyObject * args , PyObject * kwds )
33183326{
3319- PyBaseExceptionObject * self ;
3327+ PyBaseExceptionObject * self = NULL ;
33203328 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- }
33303329
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 );
33353342
3336- if (self -> args = = NULL ) {
3337- return NULL ;
3343+ if (self ! = NULL ) {
3344+ return ( PyObject * ) self ;
33383345 }
33393346
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 ) ;
33463353}
33473354
33483355static PyObject *
@@ -3387,14 +3394,17 @@ MemoryError_dealloc(PyBaseExceptionObject *self)
33873394 }
33883395
33893396 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 ) {
33943399 self -> dict = (PyObject * ) state -> memerrors_freelist ;
33953400 state -> memerrors_freelist = self ;
33963401 state -> memerrors_numfree ++ ;
3402+ MEMERRORS_UNLOCK (state );
3403+ return ;
33973404 }
3405+ MEMERRORS_UNLOCK (state );
3406+
3407+ Py_TYPE (self )-> tp_free ((PyObject * )self );
33983408}
33993409
34003410static int
0 commit comments