@@ -3832,36 +3832,43 @@ SimpleExtendsException(PyExc_Exception, ReferenceError,
3832
3832
3833
3833
#define MEMERRORS_SAVE 16
3834
3834
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
+
3835
3843
static PyObject *
3836
3844
get_memory_error (int allow_allocation , PyObject * args , PyObject * kwds )
3837
3845
{
3838
- PyBaseExceptionObject * self ;
3846
+ PyBaseExceptionObject * self = NULL ;
3839
3847
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
- }
3849
3848
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 );
3854
3861
3855
- if (self -> args = = NULL ) {
3856
- return NULL ;
3862
+ if (self ! = NULL ) {
3863
+ return ( PyObject * ) self ;
3857
3864
}
3858
3865
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 ) ;
3865
3872
}
3866
3873
3867
3874
static PyObject *
@@ -3907,14 +3914,17 @@ MemoryError_dealloc(PyObject *obj)
3907
3914
}
3908
3915
3909
3916
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 ) {
3914
3919
self -> dict = (PyObject * ) state -> memerrors_freelist ;
3915
3920
state -> memerrors_freelist = self ;
3916
3921
state -> memerrors_numfree ++ ;
3922
+ MEMERRORS_UNLOCK (state );
3923
+ return ;
3917
3924
}
3925
+ MEMERRORS_UNLOCK (state );
3926
+
3927
+ Py_TYPE (self )-> tp_free ((PyObject * )self );
3918
3928
}
3919
3929
3920
3930
static int
0 commit comments