@@ -68,8 +68,8 @@ typedef struct {
6868
6969#include "clinic/_dbmmodule.c.h"
7070
71- /* NOTE: Must be used within a critical section! */
7271#define check_dbmobject_open (v , err ) \
72+ _Py_CRITICAL_SECTION_ASSERT_OBJECT_LOCKED((v)) \
7373 if ((v)->di_dbm == NULL) { \
7474 PyErr_SetString(err, "DBM object has already been closed"); \
7575 return NULL; \
@@ -117,17 +117,14 @@ dbm_dealloc(PyObject *self)
117117}
118118
119119static Py_ssize_t
120- dbm_length (PyObject * self )
120+ dbm_length_lock_held (PyObject * self )
121121{
122- Py_ssize_t result = -1 ;
123122 dbmobject * dp = dbmobject_CAST (self );
124123 _dbm_state * state = PyType_GetModuleState (Py_TYPE (dp ));
125124 assert (state != NULL );
126-
127- Py_BEGIN_CRITICAL_SECTION (self );
128125 if (dp -> di_dbm == NULL ) {
129126 PyErr_SetString (state -> dbm_error , "DBM object has already been closed" );
130- goto done ;
127+ return -1 ;
131128 }
132129 if ( dp -> di_size < 0 ) {
133130 datum key ;
@@ -139,95 +136,103 @@ dbm_length(PyObject *self)
139136 size ++ ;
140137 dp -> di_size = size ;
141138 }
142- result = dp -> di_size ;
143- done :;
139+ return dp -> di_size ;
140+ }
141+
142+ static Py_ssize_t
143+ dbm_length (PyObject * self )
144+ {
145+ Py_ssize_t result ;
146+ Py_BEGIN_CRITICAL_SECTION (self );
147+ result = dbm_length_lock_held (self );
144148 Py_END_CRITICAL_SECTION ();
145149 return result ;
146150}
147151
148152static int
149- dbm_bool (PyObject * self )
153+ dbm_bool_lock_held (PyObject * self )
150154{
151- int result ;
152155 dbmobject * dp = dbmobject_CAST (self );
153156 _dbm_state * state = PyType_GetModuleState (Py_TYPE (dp ));
154157 assert (state != NULL );
155158
156- Py_BEGIN_CRITICAL_SECTION (self );
157159 if (dp -> di_dbm == NULL ) {
158160 PyErr_SetString (state -> dbm_error , "DBM object has already been closed" );
159- result = -1 ;
160- goto done ;
161+ return -1 ;
161162 }
162163
163164 if (dp -> di_size > 0 ) {
164165 /* Known non-zero size. */
165- result = 1 ;
166- goto done ;
166+ return 1 ;
167167 }
168168 if (dp -> di_size == 0 ) {
169169 /* Known zero size. */
170- result = 0 ;
171- goto done ;
170+ return 0 ;
172171 }
173172
174173 /* Unknown size. Ensure DBM object has an entry. */
175174 datum key = dbm_firstkey (dp -> di_dbm );
176175 if (key .dptr == NULL ) {
177176 /* Empty. Cache this fact. */
178- result = dp -> di_size = 0 ;
179- goto done ;
177+ dp -> di_size = 0 ;
178+ return 0 ;
180179 }
181-
182180 /* Non-empty. Don't cache the length since we don't know. */
183- result = 1 ;
184- done :;
181+ return 1 ;
182+ }
183+
184+ static int
185+ dbm_bool (PyObject * self )
186+ {
187+ int result ;
188+ Py_BEGIN_CRITICAL_SECTION (self );
189+ result = dbm_bool_lock_held (self );
185190 Py_END_CRITICAL_SECTION ();
186191 return result ;
187192}
188193
189194static PyObject *
190- dbm_subscript (PyObject * self , PyObject * key )
195+ dbm_subscript_lock_held (PyObject * self , PyObject * key )
191196{
192197 datum drec , krec ;
193198 Py_ssize_t tmp_size ;
194- PyObject * result = NULL ;
195199 dbmobject * dp = dbmobject_CAST (self );
196200 _dbm_state * state = PyType_GetModuleState (Py_TYPE (dp ));
197201 assert (state != NULL );
198202 if (!PyArg_Parse (key , "s#" , & krec .dptr , & tmp_size )) {
199203 return NULL ;
200204 }
201- krec .dsize = tmp_size ;
202205
203- Py_BEGIN_CRITICAL_SECTION (self );
204- /* Can't use the macro here as it returns. */
205- if (dp -> di_dbm == NULL ) {
206- PyErr_SetString (state -> dbm_error , "DBM object has already been closed" );
207- goto done ;
208- }
206+ krec .dsize = tmp_size ;
207+ check_dbmobject_open (dp , state -> dbm_error );
209208 drec = dbm_fetch (dp -> di_dbm , krec );
210209 if ( drec .dptr == 0 ) {
211210 PyErr_SetObject (PyExc_KeyError , key );
212- goto done ;
211+ return NULL ;
213212 }
214213 if ( dbm_error (dp -> di_dbm ) ) {
215214 dbm_clearerr (dp -> di_dbm );
216215 PyErr_SetString (state -> dbm_error , "" );
217- goto done ;
216+ return NULL ;
218217 }
219- result = PyBytes_FromStringAndSize (drec .dptr , drec .dsize );
220- done :;
218+ return PyBytes_FromStringAndSize (drec .dptr , drec .dsize );
219+ }
220+
221+ static PyObject *
222+ dbm_subscript (PyObject * self , PyObject * key )
223+ {
224+ PyObject * result ;
225+ Py_BEGIN_CRITICAL_SECTION (self );
226+ result = dbm_subscript_lock_held (self , key );
221227 Py_END_CRITICAL_SECTION ();
222228 return result ;
223229}
224230
225231static int
226- dbm_ass_sub (PyObject * self , PyObject * v , PyObject * w )
232+ dbm_ass_sub_lock_held (PyObject * self , PyObject * v , PyObject * w )
227233{
228234 datum krec , drec ;
229235 Py_ssize_t tmp_size ;
230- int result = -1 ;
231236 dbmobject * dp = dbmobject_CAST (self );
232237
233238 if ( !PyArg_Parse (v , "s#" , & krec .dptr , & tmp_size ) ) {
@@ -238,13 +243,10 @@ dbm_ass_sub(PyObject *self, PyObject *v, PyObject *w)
238243 _dbm_state * state = PyType_GetModuleState (Py_TYPE (dp ));
239244 assert (state != NULL );
240245 krec .dsize = tmp_size ;
241-
242- Py_BEGIN_CRITICAL_SECTION (self );
243246 if (dp -> di_dbm == NULL ) {
244- PyErr_SetString (state -> dbm_error , "DBM object has already been closed" );
245- goto done ;
247+ PyErr_SetString (state -> dbm_error , "DBM object has already been closed" );
248+ return -1 ;
246249 }
247-
248250 dp -> di_size = -1 ;
249251 if (w == NULL ) {
250252 if ( dbm_delete (dp -> di_dbm , krec ) < 0 ) {
@@ -257,30 +259,36 @@ dbm_ass_sub(PyObject *self, PyObject *v, PyObject *w)
257259 else {
258260 PyErr_SetString (state -> dbm_error , "cannot delete item from database" );
259261 }
260- goto done ;
262+ return -1 ;
261263 }
262264 } else {
263265 if ( !PyArg_Parse (w , "s#" , & drec .dptr , & tmp_size ) ) {
264266 PyErr_SetString (PyExc_TypeError ,
265267 "dbm mappings have bytes or string elements only" );
266- goto done ;
268+ return -1 ;
267269 }
268270 drec .dsize = tmp_size ;
269271 if ( dbm_store (dp -> di_dbm , krec , drec , DBM_REPLACE ) < 0 ) {
270272 dbm_clearerr (dp -> di_dbm );
271273 PyErr_SetString (state -> dbm_error ,
272274 "cannot add item to database" );
273- goto done ;
275+ return -1 ;
274276 }
275277 }
276278 if ( dbm_error (dp -> di_dbm ) ) {
277279 dbm_clearerr (dp -> di_dbm );
278280 PyErr_SetString (state -> dbm_error , "" );
279- goto done ;
281+ return -1 ;
280282 }
283+ return 0 ;
284+ }
281285
282- result = 0 ;
283- done :;
286+ static int
287+ dbm_ass_sub (PyObject * self , PyObject * v , PyObject * w )
288+ {
289+ int result ;
290+ Py_BEGIN_CRITICAL_SECTION (self );
291+ result = dbm_ass_sub_lock_held (self , v , w );
284292 Py_END_CRITICAL_SECTION ();
285293 return result ;
286294}
@@ -345,41 +353,45 @@ _dbm_dbm_keys_impl(dbmobject *self, PyTypeObject *cls)
345353}
346354
347355static int
348- dbm_contains (PyObject * self , PyObject * arg )
356+ dbm_contains_lock_held (PyObject * self , PyObject * arg )
349357{
350358 dbmobject * dp = dbmobject_CAST (self );
351359 datum key , val ;
352360 Py_ssize_t size ;
353- int result = -1 ;
354361
355362 _dbm_state * state = PyType_GetModuleState (Py_TYPE (dp ));
356363 assert (state != NULL );
357-
358- Py_BEGIN_CRITICAL_SECTION (self );
359364 if ((dp )-> di_dbm == NULL ) {
360365 PyErr_SetString (state -> dbm_error ,
361366 "DBM object has already been closed" );
362- goto done ;
367+ return -1 ;
363368 }
364369 if (PyUnicode_Check (arg )) {
365370 key .dptr = (char * )PyUnicode_AsUTF8AndSize (arg , & size );
366371 key .dsize = size ;
367372 if (key .dptr == NULL )
368- goto done ;
373+ return -1 ;
369374 }
370375 else if (!PyBytes_Check (arg )) {
371376 PyErr_Format (PyExc_TypeError ,
372377 "dbm key must be bytes or string, not %.100s" ,
373378 Py_TYPE (arg )-> tp_name );
374- goto done ;
379+ return -1 ;
375380 }
376381 else {
377382 key .dptr = PyBytes_AS_STRING (arg );
378383 key .dsize = PyBytes_GET_SIZE (arg );
379384 }
380385 val = dbm_fetch (dp -> di_dbm , key );
381- result = val .dptr != NULL ;
382- done :;
386+ return val .dptr != NULL ;
387+ }
388+
389+ static int
390+ dbm_contains (PyObject * self , PyObject * arg )
391+ {
392+ int result ;
393+ Py_BEGIN_CRITICAL_SECTION (self );
394+ result = dbm_contains_lock_held (self , arg );
383395 Py_END_CRITICAL_SECTION ();
384396 return result ;
385397}
0 commit comments