Issue #28387: Fixed possible crash in _io.TextIOWrapper deallocator when
the garbage collector is invoked in other thread.
Based on patch by Sebastian Cufre.
diff --git a/Modules/_io/textio.c b/Modules/_io/textio.c
index a95edce..b4007c2 100644
--- a/Modules/_io/textio.c
+++ b/Modules/_io/textio.c
@@ -1071,11 +1071,9 @@
     return -1;
 }
 
-static int
+static void
 _textiowrapper_clear(textio *self)
 {
-    if (self->ok && _PyIOBase_finalize((PyObject *) self) < 0)
-        return -1;
     self->ok = 0;
     Py_CLEAR(self->buffer);
     Py_CLEAR(self->encoding);
@@ -1087,18 +1085,19 @@
     Py_CLEAR(self->snapshot);
     Py_CLEAR(self->errors);
     Py_CLEAR(self->raw);
-    return 0;
+
+    Py_CLEAR(self->dict);
 }
 
 static void
 textiowrapper_dealloc(textio *self)
 {
-    if (_textiowrapper_clear(self) < 0)
+    if (self->ok && _PyIOBase_finalize((PyObject *) self) < 0)
         return;
     _PyObject_GC_UNTRACK(self);
     if (self->weakreflist != NULL)
         PyObject_ClearWeakRefs((PyObject *)self);
-    Py_CLEAR(self->dict);
+    _textiowrapper_clear(self);
     Py_TYPE(self)->tp_free((PyObject *)self);
 }
 
@@ -1123,9 +1122,9 @@
 static int
 textiowrapper_clear(textio *self)
 {
-    if (_textiowrapper_clear(self) < 0)
+    if (self->ok && _PyIOBase_finalize((PyObject *) self) < 0)
         return -1;
-    Py_CLEAR(self->dict);
+    _textiowrapper_clear(self);
     return 0;
 }