Skip to content

Commit 49bafea

Browse files
Call BasicIo munmap when memoryview is deleted
This uses weakref's callback and a new '_release' method in BasicIo
1 parent d6fe79a commit 49bafea

11 files changed

Lines changed: 145 additions & 22 deletions

File tree

src/interface/basicio.i

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ UNIQUE_PTR(Exiv2::BasicIo);
5757
%thread Exiv2::BasicIo::seek;
5858
%thread Exiv2::BasicIo::transfer;
5959
%thread Exiv2::BasicIo::write;
60+
%thread Exiv2::BasicIo::_release;
6061

6162
// Some calls don't raise exceptions
6263
%noexception Exiv2::BasicIo::eof;
@@ -132,10 +133,25 @@ OUTPUT_BUFFER_RW(Exiv2::byte* buf, size_t rcount)
132133
%ignore Exiv2::BasicIo::mmap();
133134

134135
// Convert mmap() result to a Python memoryview, assumes arg2 = isWriteable
135-
RETURN_VIEW(Exiv2::byte* mmap, $1 ? arg1->size() : 0,
136-
arg2 ? PyBUF_WRITE : PyBUF_READ,)
136+
// The callback is used to call munmap when the memoryview is deleted
137+
RETURN_VIEW_CB(Exiv2::byte* mmap, $1 ? arg1->size() : 0,
138+
arg2 ? PyBUF_WRITE : PyBUF_READ, self,)
137139

138-
// Release memoryviews when some functions are called
140+
// Make Exiv2::BasicIo callable (for callback)
141+
%feature("python:slot", "tp_call", functype="ternaryfunc")
142+
Exiv2::BasicIo::_release;
143+
%extend Exiv2::BasicIo {
144+
void _release(PyObject* args, PyObject* kw) {
145+
self->munmap();
146+
};
147+
}
148+
149+
// Release memoryviews when mmap is called
150+
%typemap(check, fragment="memoryview_funcs") bool isWriteable {
151+
release_views(self);
152+
}
153+
154+
// Release memoryviews when some other functions are called
139155
%typemap(ret, fragment="memoryview_funcs")
140156
(int close), (int munmap), (long write), (size_t write) %{
141157
release_views(self);

src/interface/shared/buffers.i

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -113,14 +113,14 @@ static int release_views(PyObject* py_self) {
113113

114114
// Macro to convert byte* return value to memoryview
115115
// WARNING: return value does not keep a reference to the data it points to
116-
%define RETURN_VIEW(signature, size_func, flags, doc_method)
116+
%define RETURN_VIEW_CB(signature, size_func, flags, callback, doc_method)
117117
%typemap(doctype) signature "memoryview";
118118
%typemap(out, fragment="memoryview_funcs") (signature) %{
119119
$result = PyMemoryView_FromMemory((char*)$1, size_func, flags);
120120
if (!$result)
121121
SWIG_fail;
122122
// Store a weak ref to the new memoryview
123-
if (store_view(self, $result))
123+
if (store_view(self, $result, callback))
124124
SWIG_fail;
125125
%}
126126
#if #doc_method != ""
@@ -131,6 +131,9 @@ WARNING: do not resize or delete the object while using the view.
131131
132132
:rtype: memoryview"
133133
#endif
134+
%enddef // RETURN_VIEW_CB
135+
%define RETURN_VIEW(signature, size_func, flags, doc_method)
136+
RETURN_VIEW_CB(signature, size_func, flags, NULL, doc_method)
134137
%enddef // RETURN_VIEW
135138

136139

src/swig-0_27_7/basicio_wrap.cxx

Lines changed: 53 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4901,6 +4901,9 @@ SWIGINTERN char const *Exiv2_BasicIo_ioType(Exiv2::BasicIo *self){
49014901
}
49024902
return "unknown";
49034903
}
4904+
SWIGINTERN void Exiv2_BasicIo__release(Exiv2::BasicIo *self,PyObject *args,PyObject *kw){
4905+
self->munmap();
4906+
}
49044907
SWIGINTERN DataContext *Exiv2_BasicIo_data(Exiv2::BasicIo *self,bool isWriteable){
49054908
return new DataContext(self, isWriteable);
49064909
}
@@ -5611,6 +5614,9 @@ SWIGINTERN PyObject *_wrap_BasicIo_mmap(PyObject *self, PyObject *args) {
56115614
}
56125615
arg2 = static_cast< bool >(val2);
56135616
}
5617+
{
5618+
release_views(self);
5619+
}
56145620
{
56155621
try {
56165622
{
@@ -5629,7 +5635,7 @@ SWIGINTERN PyObject *_wrap_BasicIo_mmap(PyObject *self, PyObject *args) {
56295635
if (!resultobj)
56305636
SWIG_fail;
56315637
// Store a weak ref to the new memoryview
5632-
if (store_view(self, resultobj))
5638+
if (store_view(self, resultobj, self))
56335639
SWIG_fail;
56345640

56355641
return resultobj;
@@ -5846,6 +5852,44 @@ SWIGINTERN PyObject *_wrap_BasicIo_ioType(PyObject *self, PyObject *args) {
58465852
}
58475853

58485854

5855+
SWIGINTERN PyObject *_wrap_BasicIo__release(PyObject *self, PyObject *args) {
5856+
PyObject *resultobj = 0;
5857+
Exiv2::BasicIo *arg1 = (Exiv2::BasicIo *) 0 ;
5858+
PyObject *arg2 = (PyObject *) 0 ;
5859+
PyObject *arg3 = (PyObject *) 0 ;
5860+
void *argp1 = 0 ;
5861+
int res1 = 0 ;
5862+
PyObject * obj1 = 0 ;
5863+
PyObject * obj2 = 0 ;
5864+
5865+
if (!PyArg_UnpackTuple(args, "BasicIo__release", 2, 2, &obj1, &obj2)) SWIG_fail;
5866+
res1 = SWIG_ConvertPtr(self, &argp1,SWIGTYPE_p_Exiv2__BasicIo, 0 | 0 );
5867+
if (!SWIG_IsOK(res1)) {
5868+
SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "BasicIo__release" "', argument " "1"" of type '" "Exiv2::BasicIo *""'");
5869+
}
5870+
arg1 = reinterpret_cast< Exiv2::BasicIo * >(argp1);
5871+
arg2 = obj1;
5872+
arg3 = obj2;
5873+
{
5874+
try {
5875+
{
5876+
SWIG_PYTHON_THREAD_BEGIN_ALLOW;
5877+
Exiv2_BasicIo__release(arg1,arg2,arg3);
5878+
SWIG_PYTHON_THREAD_END_ALLOW;
5879+
}
5880+
}
5881+
catch(std::exception const& e) {
5882+
_set_python_exception();
5883+
SWIG_fail;
5884+
}
5885+
}
5886+
resultobj = SWIG_Py_Void();
5887+
return resultobj;
5888+
fail:
5889+
return NULL;
5890+
}
5891+
5892+
58495893
SWIGINTERN PyObject *_wrap_BasicIo_data(PyObject *self, PyObject *args) {
58505894
PyObject *resultobj = 0;
58515895
Exiv2::BasicIo *arg1 = (Exiv2::BasicIo *) 0 ;
@@ -5873,6 +5917,9 @@ SWIGINTERN PyObject *_wrap_BasicIo_data(PyObject *self, PyObject *args) {
58735917
}
58745918
arg2 = static_cast< bool >(val2);
58755919
}
5920+
{
5921+
release_views(self);
5922+
}
58765923
{
58775924
try {
58785925
{
@@ -5903,6 +5950,8 @@ SWIGPY_DESTRUCTOR_CLOSURE(_wrap_delete_BasicIo) /* defines _wrap_delete_BasicIo_
59035950

59045951
SWIGPY_LENFUNC_CLOSURE(_wrap_BasicIo_size) /* defines _wrap_BasicIo_size_lenfunc_closure */
59055952

5953+
SWIGPY_TERNARYFUNC_CLOSURE(_wrap_BasicIo__release) /* defines _wrap_BasicIo__release_ternaryfunc_closure */
5954+
59065955
static PyMethodDef SwigMethods[] = {
59075956
{ "_enum_list_Position", _wrap__enum_list_Position, METH_VARARGS, NULL},
59085957
{ NULL, NULL, 0, NULL }
@@ -6480,6 +6529,7 @@ SWIGINTERN PyMethodDef SwigPyBuiltin__Exiv2__BasicIo_methods[] = {
64806529
":rtype: str\n"
64816530
":return: A class name such as \"FileIo\".\n"
64826531
"" },
6532+
{ "_release", _wrap_BasicIo__release, METH_VARARGS, "" },
64836533
{ "data", _wrap_BasicIo_data, METH_VARARGS, "\n"
64846534
"Return a data context manager.\n"
64856535
"\n"
@@ -6525,7 +6575,7 @@ static PyHeapTypeObject SwigPyBuiltin__Exiv2__BasicIo_type = {
65256575
&SwigPyBuiltin__Exiv2__BasicIo_type.as_sequence, /* tp_as_sequence */
65266576
&SwigPyBuiltin__Exiv2__BasicIo_type.as_mapping, /* tp_as_mapping */
65276577
SwigPyObject_hash, /* tp_hash */
6528-
(ternaryfunc) 0, /* tp_call */
6578+
_wrap_BasicIo__release_ternaryfunc_closure, /* tp_call */
65296579
(reprfunc) 0, /* tp_str */
65306580
(getattrofunc) 0, /* tp_getattro */
65316581
(setattrofunc) 0, /* tp_setattro */
@@ -6761,7 +6811,7 @@ static PyTypeObject *SwigPyBuiltin__Exiv2__BasicIo_type_create(PyTypeObject *typ
67616811
{ Py_tp_methods, (void *)SwigPyBuiltin__Exiv2__BasicIo_methods },
67626812
{ Py_tp_getset, (void *)SwigPyBuiltin__Exiv2__BasicIo_getset },
67636813
{ Py_tp_hash, (void *)SwigPyObject_hash },
6764-
{ Py_tp_call, (void *)(ternaryfunc) 0 },
6814+
{ Py_tp_call, (void *)_wrap_BasicIo__release_ternaryfunc_closure },
67656815
{ Py_tp_getattro, (void *)(getattrofunc) 0 },
67666816
{ Py_tp_setattro, (void *)(setattrofunc) 0 },
67676817
{ Py_tp_descr_get, (void *)(descrgetfunc) 0 },

src/swig-0_27_7/preview_wrap.cxx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6632,7 +6632,7 @@ SWIGINTERN PyObject *_wrap_PreviewImage_data(PyObject *self, PyObject *args) {
66326632
if (!resultobj)
66336633
SWIG_fail;
66346634
// Store a weak ref to the new memoryview
6635-
if (store_view(self, resultobj))
6635+
if (store_view(self, resultobj, NULL))
66366636
SWIG_fail;
66376637

66386638
return resultobj;
@@ -6660,7 +6660,7 @@ SWIGINTERN PyObject *_wrap_PreviewImage_pData(PyObject *self, PyObject *args) {
66606660
if (!resultobj)
66616661
SWIG_fail;
66626662
// Store a weak ref to the new memoryview
6663-
if (store_view(self, resultobj))
6663+
if (store_view(self, resultobj, NULL))
66646664
SWIG_fail;
66656665

66666666
return resultobj;

src/swig-0_27_7/types_wrap.cxx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6062,7 +6062,7 @@ SWIGINTERN PyObject *_wrap_DataBuf_pData__get(PyObject *self, PyObject *args) {
60626062
if (!resultobj)
60636063
SWIG_fail;
60646064
// Store a weak ref to the new memoryview
6065-
if (store_view(self, resultobj))
6065+
if (store_view(self, resultobj, NULL))
60666066
SWIG_fail;
60676067

60686068

@@ -6287,7 +6287,7 @@ SWIGINTERN PyObject *_wrap_DataBuf_data(PyObject *self, PyObject *args) {
62876287
if (!resultobj)
62886288
SWIG_fail;
62896289
// Store a weak ref to the new memoryview
6290-
if (store_view(self, resultobj))
6290+
if (store_view(self, resultobj, NULL))
62916291
SWIG_fail;
62926292

62936293
return resultobj;

src/swig-0_27_7/value_wrap.cxx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9450,7 +9450,7 @@ SWIGINTERN PyObject *_wrap_StringValueBase_data(PyObject *self, PyObject *args)
94509450
if (!resultobj)
94519451
SWIG_fail;
94529452
// Store a weak ref to the new memoryview
9453-
if (store_view(self, resultobj))
9453+
if (store_view(self, resultobj, NULL))
94549454
SWIG_fail;
94559455

94569456
return resultobj;
@@ -11579,7 +11579,7 @@ SWIGINTERN PyObject *_wrap_XmpTextValue_data(PyObject *self, PyObject *args) {
1157911579
if (!resultobj)
1158011580
SWIG_fail;
1158111581
// Store a weak ref to the new memoryview
11582-
if (store_view(self, resultobj))
11582+
if (store_view(self, resultobj, NULL))
1158311583
SWIG_fail;
1158411584

1158511585
return resultobj;

src/swig-0_28_5/basicio_wrap.cxx

Lines changed: 53 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5006,6 +5006,9 @@ SWIGINTERN char const *Exiv2_BasicIo_ioType(Exiv2::BasicIo *self){
50065006
}
50075007
return "unknown";
50085008
}
5009+
SWIGINTERN void Exiv2_BasicIo__release(Exiv2::BasicIo *self,PyObject *args,PyObject *kw){
5010+
self->munmap();
5011+
}
50095012
SWIGINTERN DataContext *Exiv2_BasicIo_data(Exiv2::BasicIo *self,bool isWriteable){
50105013
return new DataContext(self, isWriteable);
50115014
}
@@ -5878,6 +5881,9 @@ SWIGINTERN PyObject *_wrap_BasicIo_mmap(PyObject *self, PyObject *args) {
58785881
}
58795882
arg2 = static_cast< bool >(val2);
58805883
}
5884+
{
5885+
release_views(self);
5886+
}
58815887
{
58825888
try {
58835889
{
@@ -5896,7 +5902,7 @@ SWIGINTERN PyObject *_wrap_BasicIo_mmap(PyObject *self, PyObject *args) {
58965902
if (!resultobj)
58975903
SWIG_fail;
58985904
// Store a weak ref to the new memoryview
5899-
if (store_view(self, resultobj))
5905+
if (store_view(self, resultobj, self))
59005906
SWIG_fail;
59015907

59025908
return resultobj;
@@ -6114,6 +6120,44 @@ SWIGINTERN PyObject *_wrap_BasicIo_ioType(PyObject *self, PyObject *args) {
61146120
}
61156121

61166122

6123+
SWIGINTERN PyObject *_wrap_BasicIo__release(PyObject *self, PyObject *args) {
6124+
PyObject *resultobj = 0;
6125+
Exiv2::BasicIo *arg1 = (Exiv2::BasicIo *) 0 ;
6126+
PyObject *arg2 = (PyObject *) 0 ;
6127+
PyObject *arg3 = (PyObject *) 0 ;
6128+
void *argp1 = 0 ;
6129+
int res1 = 0 ;
6130+
PyObject * obj1 = 0 ;
6131+
PyObject * obj2 = 0 ;
6132+
6133+
if (!PyArg_UnpackTuple(args, "BasicIo__release", 2, 2, &obj1, &obj2)) SWIG_fail;
6134+
res1 = SWIG_ConvertPtr(self, &argp1,SWIGTYPE_p_Exiv2__BasicIo, 0 | 0 );
6135+
if (!SWIG_IsOK(res1)) {
6136+
SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "BasicIo__release" "', argument " "1"" of type '" "Exiv2::BasicIo *""'");
6137+
}
6138+
arg1 = reinterpret_cast< Exiv2::BasicIo * >(argp1);
6139+
arg2 = obj1;
6140+
arg3 = obj2;
6141+
{
6142+
try {
6143+
{
6144+
SWIG_PYTHON_THREAD_BEGIN_ALLOW;
6145+
Exiv2_BasicIo__release(arg1,arg2,arg3);
6146+
SWIG_PYTHON_THREAD_END_ALLOW;
6147+
}
6148+
}
6149+
catch(std::exception const& e) {
6150+
_set_python_exception();
6151+
SWIG_fail;
6152+
}
6153+
}
6154+
resultobj = SWIG_Py_Void();
6155+
return resultobj;
6156+
fail:
6157+
return NULL;
6158+
}
6159+
6160+
61176161
SWIGINTERN PyObject *_wrap_BasicIo_data(PyObject *self, PyObject *args) {
61186162
PyObject *resultobj = 0;
61196163
Exiv2::BasicIo *arg1 = (Exiv2::BasicIo *) 0 ;
@@ -6141,6 +6185,9 @@ SWIGINTERN PyObject *_wrap_BasicIo_data(PyObject *self, PyObject *args) {
61416185
}
61426186
arg2 = static_cast< bool >(val2);
61436187
}
6188+
{
6189+
release_views(self);
6190+
}
61446191
{
61456192
try {
61466193
{
@@ -6171,6 +6218,8 @@ SWIGPY_DESTRUCTOR_CLOSURE(_wrap_delete_BasicIo) /* defines _wrap_delete_BasicIo_
61716218

61726219
SWIGPY_LENFUNC_CLOSURE(_wrap_BasicIo_size) /* defines _wrap_BasicIo_size_lenfunc_closure */
61736220

6221+
SWIGPY_TERNARYFUNC_CLOSURE(_wrap_BasicIo__release) /* defines _wrap_BasicIo__release_ternaryfunc_closure */
6222+
61746223
static PyMethodDef SwigMethods[] = {
61756224
{ "_enum_list_Position", _wrap__enum_list_Position, METH_VARARGS, NULL},
61766225
{ NULL, NULL, 0, NULL }
@@ -6770,6 +6819,7 @@ SWIGINTERN PyMethodDef SwigPyBuiltin__Exiv2__BasicIo_methods[] = {
67706819
":rtype: str\n"
67716820
":return: A class name such as \"FileIo\".\n"
67726821
"" },
6822+
{ "_release", _wrap_BasicIo__release, METH_VARARGS, "" },
67736823
{ "data", _wrap_BasicIo_data, METH_VARARGS, "\n"
67746824
"Return a data context manager.\n"
67756825
"\n"
@@ -6815,7 +6865,7 @@ static PyHeapTypeObject SwigPyBuiltin__Exiv2__BasicIo_type = {
68156865
&SwigPyBuiltin__Exiv2__BasicIo_type.as_sequence, /* tp_as_sequence */
68166866
&SwigPyBuiltin__Exiv2__BasicIo_type.as_mapping, /* tp_as_mapping */
68176867
SwigPyObject_hash, /* tp_hash */
6818-
(ternaryfunc) 0, /* tp_call */
6868+
_wrap_BasicIo__release_ternaryfunc_closure, /* tp_call */
68196869
(reprfunc) 0, /* tp_str */
68206870
(getattrofunc) 0, /* tp_getattro */
68216871
(setattrofunc) 0, /* tp_setattro */
@@ -7051,7 +7101,7 @@ static PyTypeObject *SwigPyBuiltin__Exiv2__BasicIo_type_create(PyTypeObject *typ
70517101
{ Py_tp_methods, (void *)SwigPyBuiltin__Exiv2__BasicIo_methods },
70527102
{ Py_tp_getset, (void *)SwigPyBuiltin__Exiv2__BasicIo_getset },
70537103
{ Py_tp_hash, (void *)SwigPyObject_hash },
7054-
{ Py_tp_call, (void *)(ternaryfunc) 0 },
7104+
{ Py_tp_call, (void *)_wrap_BasicIo__release_ternaryfunc_closure },
70557105
{ Py_tp_getattro, (void *)(getattrofunc) 0 },
70567106
{ Py_tp_setattro, (void *)(setattrofunc) 0 },
70577107
{ Py_tp_descr_get, (void *)(descrgetfunc) 0 },

src/swig-0_28_5/preview_wrap.cxx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6632,7 +6632,7 @@ SWIGINTERN PyObject *_wrap_PreviewImage_data(PyObject *self, PyObject *args) {
66326632
if (!resultobj)
66336633
SWIG_fail;
66346634
// Store a weak ref to the new memoryview
6635-
if (store_view(self, resultobj))
6635+
if (store_view(self, resultobj, NULL))
66366636
SWIG_fail;
66376637

66386638
return resultobj;
@@ -6660,7 +6660,7 @@ SWIGINTERN PyObject *_wrap_PreviewImage_pData(PyObject *self, PyObject *args) {
66606660
if (!resultobj)
66616661
SWIG_fail;
66626662
// Store a weak ref to the new memoryview
6663-
if (store_view(self, resultobj))
6663+
if (store_view(self, resultobj, NULL))
66646664
SWIG_fail;
66656665

66666666
return resultobj;

src/swig-0_28_5/types_wrap.cxx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6138,7 +6138,7 @@ SWIGINTERN PyObject *_wrap_DataBuf_data(PyObject *self, PyObject *args) {
61386138
if (!resultobj)
61396139
SWIG_fail;
61406140
// Store a weak ref to the new memoryview
6141-
if (store_view(self, resultobj))
6141+
if (store_view(self, resultobj, NULL))
61426142
SWIG_fail;
61436143

61446144
return resultobj;

0 commit comments

Comments
 (0)