Commit f1e12596 authored by Kirill Smelkov's avatar Kirill Smelkov

.

parent e73e22ea
...@@ -51,6 +51,9 @@ typedef struct _frame PyFrameObject; ...@@ -51,6 +51,9 @@ typedef struct _frame PyFrameObject;
// waiting for numpy to start accept it on python2 // waiting for numpy to start accept it on python2
#define BIGFILE_USE_OLD_BUFFER (PY_VERSION_HEX < 0x03000000) #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 * python representation of VMA - exposes vma memory as python buffer
...@@ -544,9 +547,19 @@ out: ...@@ -544,9 +547,19 @@ out:
PySys_SetObject("exc_traceback", Py_None); 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 */ /* verify pybuf is not held - its memory will go away right after return */
if (pybuf) if (pybuf)
BUG_ON(pybuf->ob_refcnt != 1); BUG_ON(pybuf->ob_refcnt != 1);
#endif
/* drop pybuf /* drop pybuf
* *
...@@ -633,22 +646,28 @@ static int pybigfile_storeblk(BigFile *file, blk_t blk, const void *buf) ...@@ -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 */ /* we need to know only whether storeret != NULL, decref it now */
Py_XDECREF(storeret); 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 * 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 * vma), but we need pybuf to stay not corrupt - for printing full
* traceback in case of storeblk() error. */ * traceback in case of storeblk() error. */
#if BIGFILE_USE_OLD_BUFFER #if BIGFILE_USE_OLD_BUFFER
PyBufferObject *pybufo = (PyBufferObject *)pybuf; PyBufferObject *pybufo = (PyBufferObject *)pybuf;
PyBufferObject_Unpin(pybufo);
/*
pybufo->b_ptr = NULL; pybufo->b_ptr = NULL;
pybufo->b_size = 0; pybufo->b_size = 0;
pybufo->b_offset = 0; pybufo->b_offset = 0;
pybufo->b_hash = -1; pybufo->b_hash = -1;
Py_CLEAR(pybufo->b_base); Py_CLEAR(pybufo->b_base);
*/
#else #else
PyMemoryViewObject *pybufm = (PyMemoryViewObject *)pybuf; PyMemoryViewObject *pybufm = (PyMemoryViewObject *)pybuf;
PyBuffer_Unpin(&pybufm->view);
/*
pybufm->view.buf = NULL; pybufm->view.buf = NULL;
pybufm->view.len = 0; pybufm->view.len = 0;
Py_CLEAR(pybufm->view.obj); Py_CLEAR(pybufm->view.obj);
*/
#endif #endif
/* verify that we actually tweaked pybuf ok */ /* verify that we actually tweaked pybuf ok */
...@@ -775,6 +794,23 @@ static /*const*/ PyMethodDef pybigfile_modulemeths[] = { ...@@ -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 */ /* GIL hooks for virtmem big lock */
static void *py_gil_ensure_unlocked(void) static void *py_gil_ensure_unlocked(void)
......
...@@ -151,16 +151,20 @@ def test_pagefault_savestate(): ...@@ -151,16 +151,20 @@ def test_pagefault_savestate():
# v .f_localsplus # v .f_localsplus
# frame # frame
# #
# Since upon returning we can't hold a reference to buf, let's
# break the loop explicitly. # # 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. # # 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 # # 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_run = 1
self.loadblk_buf = buf
f = BadFile(PS) f = BadFile(PS)
...@@ -184,6 +188,11 @@ def test_pagefault_savestate(): ...@@ -184,6 +188,11 @@ def test_pagefault_savestate():
assert exc_value is exc_value2 assert exc_value is exc_value2
assert exc_tb is exc_tb2 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 # TODO close f
......
...@@ -58,6 +58,7 @@ static inline PyThreadState * _PyThreadState_UncheckedGet(void) ...@@ -58,6 +58,7 @@ static inline PyThreadState * _PyThreadState_UncheckedGet(void)
{ {
return _PyThreadState_Current; return _PyThreadState_Current;
} }
/* _PyThreadState_UncheckedGet() was added in CPython 3.5.2rc1 /* _PyThreadState_UncheckedGet() was added in CPython 3.5.2rc1
* https://github.com/python/cpython/commit/df858591 * 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