Commit f1e12596 authored by Kirill Smelkov's avatar Kirill Smelkov

.

parent e73e22ea
......@@ -51,6 +51,9 @@ typedef struct _frame PyFrameObject;
// waiting for numpy to start accept it on python2
#define BIGFILE_USE_OLD_BUFFER (PY_VERSION_HEX < 0x03000000)
void PyBufferObject_Unpin(PyBufferObject *bufo);
void PyBuffer_Unpin(Py_buffer *view);
/*
* python representation of VMA - exposes vma memory as python buffer
......@@ -544,9 +547,19 @@ out:
PySys_SetObject("exc_traceback", Py_None);
#if BIGFILE_USE_OLD_BUFFER
PyBufferObject *pybufo = (PyBufferObject *)pybuf;
PyBufferObject_Unpin(pybufo);
#else
PyMemoryViewObject *pybufm = (PyMemoryViewObject *)pybuf;
PyBuffer_Unpin(&pybufm->view);
#endif
#if 0
/* verify pybuf is not held - its memory will go away right after return */
if (pybuf)
BUG_ON(pybuf->ob_refcnt != 1);
#endif
/* drop pybuf
*
......@@ -633,22 +646,28 @@ static int pybigfile_storeblk(BigFile *file, blk_t blk, const void *buf)
/* we need to know only whether storeret != NULL, decref it now */
Py_XDECREF(storeret);
/* repoint pybuf to empty region - the original memory attached to it can
/* repoint pybuf to empty region - the original memory attached to it can XXX do the same for loadblk()
* go away right after we return (if e.g. dirty page was not mapped in any
* vma), but we need pybuf to stay not corrupt - for printing full
* traceback in case of storeblk() error. */
#if BIGFILE_USE_OLD_BUFFER
PyBufferObject *pybufo = (PyBufferObject *)pybuf;
PyBufferObject_Unpin(pybufo);
/*
pybufo->b_ptr = NULL;
pybufo->b_size = 0;
pybufo->b_offset = 0;
pybufo->b_hash = -1;
Py_CLEAR(pybufo->b_base);
*/
#else
PyMemoryViewObject *pybufm = (PyMemoryViewObject *)pybuf;
PyBuffer_Unpin(&pybufm->view);
/*
pybufm->view.buf = NULL;
pybufm->view.len = 0;
Py_CLEAR(pybufm->view.obj);
*/
#endif
/* verify that we actually tweaked pybuf ok */
......@@ -775,6 +794,23 @@ static /*const*/ PyMethodDef pybigfile_modulemeths[] = {
};
/* buffer utilities: unpin buffer from its buffer - make it zero-length
* pointing to NULL but staying a vailid python object */
void PyBufferObject_Unpin(PyBufferObject *bufo)
{
bufo->b_ptr = NULL;
bufo->b_size = 0;
bufo->b_offset = 0;
bufo->b_hash = -1;
Py_CLEAR(bufo->b_base);
}
void PyBuffer_Unpin(Py_buffer *view)
{
view->buf = NULL;
view->len = 0;
Py_CLEAR(view->obj);
}
/* GIL hooks for virtmem big lock */
static void *py_gil_ensure_unlocked(void)
......
......@@ -151,16 +151,20 @@ def test_pagefault_savestate():
# v .f_localsplus
# frame
#
# Since upon returning we can't hold a reference to buf, let's
# break the loop explicitly.
#
# Otherwise both exc_traceback and frame will be alive until next
# gc.collect() which cannot be perform in pagefault handler.
#
# Not breaking this loop will BUG with `buf.refcnt != 1` on return
del exc_traceback
# # Since upon returning we can't hold a reference to buf, let's
# # break the loop explicitly.
# #
# # Otherwise both exc_traceback and frame will be alive until next
# # gc.collect() which cannot be perform in pagefault handler.
# #
# # Not breaking this loop will BUG with `buf.refcnt != 1` on return
# del exc_traceback
assert len(buf) > 0
self.loadblk_run = 1
self.loadblk_buf = buf
f = BadFile(PS)
......@@ -184,6 +188,11 @@ def test_pagefault_savestate():
assert exc_value is exc_value2
assert exc_tb is exc_tb2
# TODO check f.loadblk_buf for access -- len=0, read/write - index error
assert len(f.loadblk_buf) == 0
raises(IndexError, "f.loadblk_buf[0]")
raises(IndexError, "f.loadblk_buf[0] = b'1'")
# TODO close f
......
......@@ -58,6 +58,7 @@ static inline PyThreadState * _PyThreadState_UncheckedGet(void)
{
return _PyThreadState_Current;
}
/* _PyThreadState_UncheckedGet() was added in CPython 3.5.2rc1
* https://github.com/python/cpython/commit/df858591
*
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment