@@ -6314,6 +6314,32 @@ type_update_dict(PyTypeObject *type, PyDictObject *dict, PyObject *name,
6314
6314
return 0 ;
6315
6315
}
6316
6316
6317
+ static int
6318
+ update_slot_after_setattr (PyTypeObject * type , PyObject * name )
6319
+ {
6320
+ #ifdef Py_GIL_DISABLED
6321
+ // stack allocate one chunk since that's all we need
6322
+ assert (SLOT_UPDATE_CHUNK_SIZE >= MAX_EQUIV );
6323
+ slot_update_chunk_t chunk = {0 };
6324
+ slot_update_t queued_updates = {& chunk };
6325
+
6326
+ if (update_slot (type , name , & queued_updates ) < 0 ) {
6327
+ return -1 ;
6328
+ }
6329
+ if (queued_updates .head != NULL ) {
6330
+ types_stop_world ();
6331
+ apply_slot_updates (& queued_updates );
6332
+ types_start_world ();
6333
+ ASSERT_TYPE_LOCK_HELD ();
6334
+ // should never allocate another chunk
6335
+ assert (chunk .prev == NULL );
6336
+ }
6337
+ #else
6338
+ update_slot (type , name , NULL );
6339
+ #endif
6340
+ return 0 ;
6341
+ }
6342
+
6317
6343
static int
6318
6344
type_setattro (PyObject * self , PyObject * name , PyObject * value )
6319
6345
{
@@ -6389,10 +6415,7 @@ type_setattro(PyObject *self, PyObject *name, PyObject *value)
6389
6415
if (res == 0 ) {
6390
6416
if (is_dunder_name (name ) && has_slotdef (name )) {
6391
6417
// The name corresponds to a type slot.
6392
- types_stop_world ();
6393
- res = update_slot (type , name , NULL );
6394
- types_start_world ();
6395
- ASSERT_TYPE_LOCK_HELD ();
6418
+ res = update_slot_after_setattr (type , name );
6396
6419
}
6397
6420
}
6398
6421
END_TYPE_DICT_LOCK ();
0 commit comments