@@ -3832,36 +3832,43 @@ SimpleExtendsException(PyExc_Exception, ReferenceError,
38323832
38333833#define MEMERRORS_SAVE 16
38343834
3835+ #ifdef Py_GIL_DISABLED
3836+ # define MEMERRORS_LOCK (state ) PyMutex_LockFlags(&state->memerrors_lock, _Py_LOCK_DONT_DETACH)
3837+ # define MEMERRORS_UNLOCK (state ) PyMutex_Unlock(&state->memerrors_lock)
3838+ #else
3839+ # define MEMERRORS_LOCK (state ) ((void)0)
3840+ # define MEMERRORS_UNLOCK (state ) ((void)0)
3841+ #endif
3842+
38353843static PyObject *
38363844get_memory_error (int allow_allocation , PyObject * args , PyObject * kwds )
38373845{
3838- PyBaseExceptionObject * self ;
3846+ PyBaseExceptionObject * self = NULL ;
38393847 struct _Py_exc_state * state = get_exc_state ();
3840- if (state -> memerrors_freelist == NULL ) {
3841- if (!allow_allocation ) {
3842- PyInterpreterState * interp = _PyInterpreterState_GET ();
3843- return Py_NewRef (
3844- & _Py_INTERP_SINGLETON (interp , last_resort_memory_error ));
3845- }
3846- PyObject * result = BaseException_new ((PyTypeObject * )PyExc_MemoryError , args , kwds );
3847- return result ;
3848- }
38493848
3850- /* Fetch object from freelist and revive it */
3851- self = state -> memerrors_freelist ;
3852- self -> args = PyTuple_New (0 );
3853- /* This shouldn't happen since the empty tuple is persistent */
3849+ MEMERRORS_LOCK (state );
3850+ if (state -> memerrors_freelist != NULL ) {
3851+ /* Fetch MemoryError from freelist and initialize it */
3852+ self = state -> memerrors_freelist ;
3853+ state -> memerrors_freelist = (PyBaseExceptionObject * ) self -> dict ;
3854+ state -> memerrors_numfree -- ;
3855+ self -> dict = NULL ;
3856+ self -> args = (PyObject * )& _Py_SINGLETON (tuple_empty );
3857+ _Py_NewReference ((PyObject * )self );
3858+ _PyObject_GC_TRACK (self );
3859+ }
3860+ MEMERRORS_UNLOCK (state );
38543861
3855- if (self -> args = = NULL ) {
3856- return NULL ;
3862+ if (self ! = NULL ) {
3863+ return ( PyObject * ) self ;
38573864 }
38583865
3859- state -> memerrors_freelist = ( PyBaseExceptionObject * ) self -> dict ;
3860- state -> memerrors_numfree -- ;
3861- self -> dict = NULL ;
3862- _Py_NewReference (( PyObject * ) self );
3863- _PyObject_GC_TRACK ( self );
3864- return ( PyObject * )self ;
3866+ if (! allow_allocation ) {
3867+ PyInterpreterState * interp = _PyInterpreterState_GET () ;
3868+ return Py_NewRef (
3869+ & _Py_INTERP_SINGLETON ( interp , last_resort_memory_error ) );
3870+ }
3871+ return BaseException_new (( PyTypeObject * )PyExc_MemoryError , args , kwds ) ;
38653872}
38663873
38673874static PyObject *
@@ -3907,14 +3914,17 @@ MemoryError_dealloc(PyObject *obj)
39073914 }
39083915
39093916 struct _Py_exc_state * state = get_exc_state ();
3910- if (state -> memerrors_numfree >= MEMERRORS_SAVE ) {
3911- Py_TYPE (self )-> tp_free ((PyObject * )self );
3912- }
3913- else {
3917+ MEMERRORS_LOCK (state );
3918+ if (state -> memerrors_numfree < MEMERRORS_SAVE ) {
39143919 self -> dict = (PyObject * ) state -> memerrors_freelist ;
39153920 state -> memerrors_freelist = self ;
39163921 state -> memerrors_numfree ++ ;
3922+ MEMERRORS_UNLOCK (state );
3923+ return ;
39173924 }
3925+ MEMERRORS_UNLOCK (state );
3926+
3927+ Py_TYPE (self )-> tp_free ((PyObject * )self );
39183928}
39193929
39203930static int
0 commit comments