mirror of
https://github.com/capnproto/pycapnp.git
synced 2025-03-04 08:24:43 +01:00
fix for unreleased buffers under mmap (issue 280)
This commit is contained in:
parent
d1bd4cb256
commit
4b75fe3b5e
1 changed files with 30 additions and 8 deletions
|
@ -22,6 +22,7 @@ from libc.string cimport memcpy
|
||||||
import array
|
import array
|
||||||
import asyncio
|
import asyncio
|
||||||
import collections as _collections
|
import collections as _collections
|
||||||
|
import contextlib
|
||||||
import enum as _enum
|
import enum as _enum
|
||||||
import inspect as _inspect
|
import inspect as _inspect
|
||||||
import os as _os
|
import os as _os
|
||||||
|
@ -3320,6 +3321,7 @@ class _StructModule(object):
|
||||||
reader = _MultipleBytesPackedMessageReader(buf, self.schema, traversal_limit_in_words, nesting_limit)
|
reader = _MultipleBytesPackedMessageReader(buf, self.schema, traversal_limit_in_words, nesting_limit)
|
||||||
return reader
|
return reader
|
||||||
|
|
||||||
|
@contextlib.contextmanager
|
||||||
def from_bytes(self, buf, traversal_limit_in_words=None, nesting_limit=None, builder=False):
|
def from_bytes(self, buf, traversal_limit_in_words=None, nesting_limit=None, builder=False):
|
||||||
"""Returns a Reader for the unpacked object in buf.
|
"""Returns a Reader for the unpacked object in buf.
|
||||||
|
|
||||||
|
@ -3340,13 +3342,18 @@ class _StructModule(object):
|
||||||
|
|
||||||
:rtype: :class:`_DynamicStructReader` or :class:`_DynamicStructBuilder`
|
:rtype: :class:`_DynamicStructReader` or :class:`_DynamicStructBuilder`
|
||||||
"""
|
"""
|
||||||
if builder:
|
message = None
|
||||||
# message = _FlatMessageBuilder(buf)
|
try:
|
||||||
message = _FlatArrayMessageReader(buf, traversal_limit_in_words, nesting_limit)
|
if builder:
|
||||||
return message.get_root(self.schema).as_builder()
|
# message = _FlatMessageBuilder(buf)
|
||||||
else:
|
message = _FlatArrayMessageReader(buf, traversal_limit_in_words, nesting_limit)
|
||||||
message = _FlatArrayMessageReader(buf, traversal_limit_in_words, nesting_limit)
|
yield message.get_root(self.schema).as_builder()
|
||||||
return message.get_root(self.schema)
|
else:
|
||||||
|
message = _FlatArrayMessageReader(buf, traversal_limit_in_words, nesting_limit)
|
||||||
|
yield message.get_root(self.schema)
|
||||||
|
finally:
|
||||||
|
if message:
|
||||||
|
message.close()
|
||||||
|
|
||||||
def from_segments(self, segments, traversal_limit_in_words=None, nesting_limit=None):
|
def from_segments(self, segments, traversal_limit_in_words=None, nesting_limit=None):
|
||||||
"""Returns a Reader for a list of segment bytes.
|
"""Returns a Reader for a list of segment bytes.
|
||||||
|
@ -4088,15 +4095,22 @@ cdef class _AlignedBuffer:
|
||||||
cdef class _BufferView:
|
cdef class _BufferView:
|
||||||
cdef Py_buffer view
|
cdef Py_buffer view
|
||||||
cdef char * buf
|
cdef char * buf
|
||||||
|
cdef int closed
|
||||||
|
|
||||||
def __init__(self, other):
|
def __init__(self, other):
|
||||||
cdef int ret = PyObject_GetBuffer(other, &self.view, PyBUF_SIMPLE)
|
cdef int ret = PyObject_GetBuffer(other, &self.view, PyBUF_SIMPLE)
|
||||||
if ret < 0:
|
if ret < 0:
|
||||||
raise ValueError("Invalid buffer passed to BufferView")
|
raise ValueError("Invalid buffer passed to BufferView")
|
||||||
self.buf = <char*>self.view.buf
|
self.buf = <char*>self.view.buf
|
||||||
|
self.closed = False
|
||||||
|
|
||||||
|
def close(self):
|
||||||
|
if not self.closed:
|
||||||
|
PyBuffer_Release(&self.view)
|
||||||
|
self.closed = True
|
||||||
|
|
||||||
def __dealloc__(self):
|
def __dealloc__(self):
|
||||||
PyBuffer_Release(&self.view)
|
self.close()
|
||||||
|
|
||||||
|
|
||||||
@cython.internal
|
@cython.internal
|
||||||
|
@ -4133,6 +4147,7 @@ cdef class _FlatArrayMessageReaderAligned(_MessageReader):
|
||||||
@cython.internal
|
@cython.internal
|
||||||
cdef class _FlatArrayMessageReader(_MessageReader):
|
cdef class _FlatArrayMessageReader(_MessageReader):
|
||||||
cdef object _object_to_pin
|
cdef object _object_to_pin
|
||||||
|
cdef _BufferView _buffer_view
|
||||||
|
|
||||||
def __init__(self, buf, traversal_limit_in_words=None, nesting_limit=None):
|
def __init__(self, buf, traversal_limit_in_words=None, nesting_limit=None):
|
||||||
cdef schema_cpp.ReaderOptions opts = make_reader_opts(traversal_limit_in_words, nesting_limit)
|
cdef schema_cpp.ReaderOptions opts = make_reader_opts(traversal_limit_in_words, nesting_limit)
|
||||||
|
@ -4151,10 +4166,12 @@ cdef class _FlatArrayMessageReader(_MessageReader):
|
||||||
self._object_to_pin = aligned
|
self._object_to_pin = aligned
|
||||||
else:
|
else:
|
||||||
self._object_to_pin = buf
|
self._object_to_pin = buf
|
||||||
|
self._buffer_view = None
|
||||||
elif PyObject_CheckBuffer(buf):
|
elif PyObject_CheckBuffer(buf):
|
||||||
view = _BufferView(buf)
|
view = _BufferView(buf)
|
||||||
ptr = view.buf
|
ptr = view.buf
|
||||||
self._object_to_pin = view
|
self._object_to_pin = view
|
||||||
|
self._buffer_view = view
|
||||||
else:
|
else:
|
||||||
raise TypeError('expected buffer-like object in FlatArrayMessageReader')
|
raise TypeError('expected buffer-like object in FlatArrayMessageReader')
|
||||||
|
|
||||||
|
@ -4162,7 +4179,12 @@ cdef class _FlatArrayMessageReader(_MessageReader):
|
||||||
schema_cpp.WordArrayPtr(<schema_cpp.word*>ptr, sz//8),
|
schema_cpp.WordArrayPtr(<schema_cpp.word*>ptr, sz//8),
|
||||||
opts)
|
opts)
|
||||||
|
|
||||||
|
def close(self):
|
||||||
|
if self._buffer_view:
|
||||||
|
self._buffer_view.close()
|
||||||
|
|
||||||
def __dealloc__(self):
|
def __dealloc__(self):
|
||||||
|
self.close()
|
||||||
del self.thisptr
|
del self.thisptr
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue