From 9cb31e86ae538c01fa1e6452b49cad08993ed38a Mon Sep 17 00:00:00 2001 From: Alexander Alekhin Date: Mon, 16 Dec 2013 16:46:36 +0400 Subject: [PATCH] umat: fix memory leaks --- modules/core/include/opencv2/core/mat.inl.hpp | 2 +- modules/core/src/matrix.cpp | 8 +++++++- modules/core/src/ocl.cpp | 8 ++++---- modules/core/src/umatrix.cpp | 4 ++++ 4 files changed, 16 insertions(+), 6 deletions(-) diff --git a/modules/core/include/opencv2/core/mat.inl.hpp b/modules/core/include/opencv2/core/mat.inl.hpp index 8a0a6a6bea..9c2f595b6a 100644 --- a/modules/core/include/opencv2/core/mat.inl.hpp +++ b/modules/core/include/opencv2/core/mat.inl.hpp @@ -617,9 +617,9 @@ inline void Mat::release() { if( u && CV_XADD(&u->refcount, -1) == 1 ) deallocate(); + u = NULL; data = datastart = dataend = datalimit = 0; size.p[0] = 0; - u = 0; } inline diff --git a/modules/core/src/matrix.cpp b/modules/core/src/matrix.cpp index 871fb385d6..9ddaf3298c 100644 --- a/modules/core/src/matrix.cpp +++ b/modules/core/src/matrix.cpp @@ -56,7 +56,10 @@ void MatAllocator::map(UMatData*, int) const void MatAllocator::unmap(UMatData* u) const { if(u->urefcount == 0 && u->refcount == 0) + { deallocate(u); + u = NULL; + } } void MatAllocator::download(UMatData* u, void* dstptr, @@ -179,7 +182,6 @@ public: UMatData* u = new UMatData(this); u->data = u->origdata = data; u->size = total; - u->refcount = data0 == 0; if(data0) u->flags |= UMatData::USER_ALLOCATED; @@ -195,6 +197,8 @@ public: void deallocate(UMatData* u) const { + CV_Assert(u->urefcount >= 0); + CV_Assert(u->refcount >= 0); if(u && u->refcount == 0) { if( !(u->flags & UMatData::USER_ALLOCATED) ) @@ -392,6 +396,7 @@ void Mat::create(int d, const int* _sizes, int _type) CV_Assert( step[dims-1] == (size_t)CV_ELEM_SIZE(flags) ); } + addref(); finalizeHdr(*this); } @@ -409,6 +414,7 @@ void Mat::deallocate() { if(u) (u->currAllocator ? u->currAllocator : allocator ? allocator : getStdAllocator())->unmap(u); + u = NULL; } Mat::Mat(const Mat& m, const Range& _rowRange, const Range& _colRange) diff --git a/modules/core/src/ocl.cpp b/modules/core/src/ocl.cpp index 6681e8181a..08d88d9283 100644 --- a/modules/core/src/ocl.cpp +++ b/modules/core/src/ocl.cpp @@ -1469,6 +1469,7 @@ struct Device::Impl Impl(void* d) { handle = (cl_device_id)d; + refcount = 1; } template @@ -2693,8 +2694,6 @@ public: UMatData* defaultAllocate(int dims, const int* sizes, int type, void* data, size_t* step, int flags) const { UMatData* u = matStdAllocator->allocate(dims, sizes, type, data, step, flags); - u->urefcount = 1; - u->refcount = 0; return u; } @@ -2736,7 +2735,6 @@ public: u->data = 0; u->size = total; u->handle = handle; - u->urefcount = 1; u->flags = flags0; return u; @@ -2775,7 +2773,6 @@ public: } if(accessFlags & ACCESS_WRITE) u->markHostCopyObsolete(true); - CV_XADD(&u->urefcount, 1); return true; } @@ -2814,6 +2811,9 @@ public: if(!u) return; + CV_Assert(u->urefcount >= 0); + CV_Assert(u->refcount >= 0); + // TODO: !!! when we add Shared Virtual Memory Support, // this function (as well as the others) should be corrected CV_Assert(u->handle != 0 && u->urefcount == 0); diff --git a/modules/core/src/umatrix.cpp b/modules/core/src/umatrix.cpp index 12483877bc..a13abcf59c 100644 --- a/modules/core/src/umatrix.cpp +++ b/modules/core/src/umatrix.cpp @@ -217,6 +217,7 @@ UMat Mat::getUMat(int accessFlags) const if(!a) a = a0; temp_u = a->allocate(dims, size.p, type(), data, step.p, accessFlags); + temp_u->refcount = 1; } UMat::getStdAllocator()->allocate(temp_u, accessFlags); hdr.flags = flags; @@ -224,6 +225,7 @@ UMat Mat::getUMat(int accessFlags) const finalizeHdr(hdr); hdr.u = temp_u; hdr.offset = data - datastart; + hdr.addref(); return hdr; } @@ -271,6 +273,7 @@ void UMat::create(int d, const int* _sizes, int _type) } finalizeHdr(*this); + addref(); } void UMat::copySize(const UMat& m) @@ -294,6 +297,7 @@ UMat::~UMat() void UMat::deallocate() { u->currAllocator->deallocate(u); + u = NULL; }