Skip to content

Commit

Permalink
bpo-17852: Revert incorrect fix based on misunderstanding of _Py_PyAt…
Browse files Browse the repository at this point in the history
…Exit() semantics (python#4826)
  • Loading branch information
pitrou authored and vstinner committed Dec 13, 2017
1 parent d233796 commit 317def9
Show file tree
Hide file tree
Showing 5 changed files with 2 additions and 78 deletions.
24 changes: 0 additions & 24 deletions Lib/_pyio.py
Original file line number Diff line number Diff line change
Expand Up @@ -1182,7 +1182,6 @@ def __init__(self, raw, buffer_size=DEFAULT_BUFFER_SIZE):
self.buffer_size = buffer_size
self._write_buf = bytearray()
self._write_lock = Lock()
_register_writer(self)

def writable(self):
return self.raw.writable()
Expand Down Expand Up @@ -2587,26 +2586,3 @@ def encoding(self):
def detach(self):
# This doesn't make sense on StringIO.
self._unsupported("detach")


# ____________________________________________________________

import atexit, weakref

_all_writers = weakref.WeakSet()

def _register_writer(w):
# keep weak-ref to buffered writer
_all_writers.add(w)

def _flush_all_writers():
# Ensure all buffered writers are flushed before proceeding with
# normal shutdown. Otherwise, if the underlying file objects get
# finalized before the buffered writer wrapping it then any buffered
# data will be lost.
for w in _all_writers:
try:
w.flush()
except:
pass
atexit.register(_flush_all_writers)
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Revert incorrect fix based on misunderstanding of _Py_PyAtExit() semantics.
2 changes: 0 additions & 2 deletions Modules/_io/_iomodule.c
Original file line number Diff line number Diff line change
Expand Up @@ -766,8 +766,6 @@ PyInit__io(void)
!(_PyIO_empty_bytes = PyBytes_FromStringAndSize(NULL, 0)))
goto fail;

_Py_PyAtExit(_PyIO_atexit_flush);

state->initialized = 1;

return m;
Expand Down
2 changes: 0 additions & 2 deletions Modules/_io/_iomodule.h
Original file line number Diff line number Diff line change
Expand Up @@ -183,5 +183,3 @@ extern PyObject *_PyIO_empty_str;
extern PyObject *_PyIO_empty_bytes;

extern PyTypeObject _PyBytesIOBuffer_Type;

extern void _PyIO_atexit_flush(void);
51 changes: 1 addition & 50 deletions Modules/_io/bufferedio.c
Original file line number Diff line number Diff line change
Expand Up @@ -197,7 +197,7 @@ bufferediobase_write(PyObject *self, PyObject *args)
}


typedef struct _buffered {
typedef struct {
PyObject_HEAD

PyObject *raw;
Expand Down Expand Up @@ -239,18 +239,8 @@ typedef struct _buffered {

PyObject *dict;
PyObject *weakreflist;

/* a doubly-linked chained list of "buffered" objects that need to
be flushed when the process exits */
struct _buffered *next, *prev;
} buffered;

/* the actual list of buffered objects */
static buffered buffer_list_end = {
.next = &buffer_list_end,
.prev = &buffer_list_end
};

/*
Implementation notes:
Expand Down Expand Up @@ -389,21 +379,10 @@ _enter_buffered_busy(buffered *self)
(self->buffer_size * (size / self->buffer_size)))


static void
remove_from_linked_list(buffered *self)
{
self->next->prev = self->prev;
self->prev->next = self->next;
self->prev = NULL;
self->next = NULL;
}

static void
buffered_dealloc(buffered *self)
{
self->finalizing = 1;
if (self->next != NULL)
remove_from_linked_list(self);
if (_PyIOBase_finalize((PyObject *) self) < 0)
return;
_PyObject_GC_UNTRACK(self);
Expand Down Expand Up @@ -1827,38 +1806,10 @@ _io_BufferedWriter___init___impl(buffered *self, PyObject *raw,
self->fast_closed_checks = (Py_TYPE(self) == &PyBufferedWriter_Type &&
Py_TYPE(raw) == &PyFileIO_Type);

if (self->next == NULL) {
self->prev = &buffer_list_end;
self->next = buffer_list_end.next;
buffer_list_end.next->prev = self;
buffer_list_end.next = self;
}

self->ok = 1;
return 0;
}

/*
* Ensure all buffered writers are flushed before proceeding with
* normal shutdown. Otherwise, if the underlying file objects get
* finalized before the buffered writer wrapping it then any buffered
* data will be lost.
*/
void _PyIO_atexit_flush(void)
{
while (buffer_list_end.next != &buffer_list_end) {
buffered *buf = buffer_list_end.next;
remove_from_linked_list(buf);
if (buf->ok && !buf->finalizing) {
/* good state and not finalizing */
Py_INCREF(buf);
buffered_flush(buf, NULL);
Py_DECREF(buf);
PyErr_Clear();
}
}
}

static Py_ssize_t
_bufferedwriter_raw_write(buffered *self, char *start, Py_ssize_t len)
{
Expand Down

0 comments on commit 317def9

Please sign in to comment.