mirror of
https://github.com/opencv/opencv.git
synced 2025-06-07 17:44:04 +08:00
fix opencv/opencv#20594 - exception handling with refcounts
This commit is contained in:
parent
9bda96d39e
commit
54a9e00970
@ -749,18 +749,17 @@ Mat::Mat(const Mat& m, const Rect& roi)
|
|||||||
data += roi.x*esz;
|
data += roi.x*esz;
|
||||||
CV_Assert( 0 <= roi.x && 0 <= roi.width && roi.x + roi.width <= m.cols &&
|
CV_Assert( 0 <= roi.x && 0 <= roi.width && roi.x + roi.width <= m.cols &&
|
||||||
0 <= roi.y && 0 <= roi.height && roi.y + roi.height <= m.rows );
|
0 <= roi.y && 0 <= roi.height && roi.y + roi.height <= m.rows );
|
||||||
if( u )
|
|
||||||
CV_XADD(&u->refcount, 1);
|
|
||||||
if( roi.width < m.cols || roi.height < m.rows )
|
if( roi.width < m.cols || roi.height < m.rows )
|
||||||
flags |= SUBMATRIX_FLAG;
|
flags |= SUBMATRIX_FLAG;
|
||||||
|
|
||||||
step[0] = m.step[0]; step[1] = esz;
|
step[0] = m.step[0]; step[1] = esz;
|
||||||
updateContinuityFlag();
|
updateContinuityFlag();
|
||||||
|
|
||||||
|
addref();
|
||||||
if( rows <= 0 || cols <= 0 )
|
if( rows <= 0 || cols <= 0 )
|
||||||
{
|
{
|
||||||
release();
|
|
||||||
rows = cols = 0;
|
rows = cols = 0;
|
||||||
|
release();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2774,19 +2774,33 @@ struct Kernel::Impl
|
|||||||
|
|
||||||
void cleanupUMats()
|
void cleanupUMats()
|
||||||
{
|
{
|
||||||
|
bool exceptionOccurred = false;
|
||||||
for( int i = 0; i < MAX_ARRS; i++ )
|
for( int i = 0; i < MAX_ARRS; i++ )
|
||||||
|
{
|
||||||
if( u[i] )
|
if( u[i] )
|
||||||
{
|
{
|
||||||
if( CV_XADD(&u[i]->urefcount, -1) == 1 )
|
if( CV_XADD(&u[i]->urefcount, -1) == 1 )
|
||||||
{
|
{
|
||||||
u[i]->flags |= UMatData::ASYNC_CLEANUP;
|
u[i]->flags |= UMatData::ASYNC_CLEANUP;
|
||||||
u[i]->currAllocator->deallocate(u[i]);
|
try
|
||||||
|
{
|
||||||
|
u[i]->currAllocator->deallocate(u[i]);
|
||||||
|
}
|
||||||
|
catch(const std::exception& exc)
|
||||||
|
{
|
||||||
|
// limited by legacy before C++11, therefore log and
|
||||||
|
// remember some exception occurred to throw below
|
||||||
|
CV_LOG_ERROR(NULL, "OCL: Unexpected C++ exception in OpenCL Kernel::Impl::cleanupUMats(): " << exc.what());
|
||||||
|
exceptionOccurred = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
u[i] = 0;
|
u[i] = 0;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
nu = 0;
|
nu = 0;
|
||||||
haveTempDstUMats = false;
|
haveTempDstUMats = false;
|
||||||
haveTempSrcUMats = false;
|
haveTempSrcUMats = false;
|
||||||
|
CV_Assert(!exceptionOccurred);
|
||||||
}
|
}
|
||||||
|
|
||||||
void addUMat(const UMat& m, bool dst)
|
void addUMat(const UMat& m, bool dst)
|
||||||
@ -2817,8 +2831,16 @@ struct Kernel::Impl
|
|||||||
void finit(cl_event e)
|
void finit(cl_event e)
|
||||||
{
|
{
|
||||||
CV_UNUSED(e);
|
CV_UNUSED(e);
|
||||||
cleanupUMats();
|
|
||||||
isInProgress = false;
|
isInProgress = false;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
cleanupUMats();
|
||||||
|
}
|
||||||
|
catch(...)
|
||||||
|
{
|
||||||
|
release();
|
||||||
|
throw;
|
||||||
|
}
|
||||||
release();
|
release();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -540,13 +540,26 @@ UMat Mat::getUMat(int accessFlags, UMatUsageFlags usageFlags) const
|
|||||||
CV_XADD(&(u->refcount), 1);
|
CV_XADD(&(u->refcount), 1);
|
||||||
CV_XADD(&(u->urefcount), 1);
|
CV_XADD(&(u->urefcount), 1);
|
||||||
}
|
}
|
||||||
hdr.flags = flags;
|
try
|
||||||
setSize(hdr, dims, size.p, step.p);
|
{
|
||||||
finalizeHdr(hdr);
|
hdr.flags = flags;
|
||||||
hdr.u = new_u;
|
setSize(hdr, dims, size.p, step.p);
|
||||||
hdr.offset = 0; //data - datastart;
|
finalizeHdr(hdr);
|
||||||
hdr.addref();
|
hdr.u = new_u;
|
||||||
return hdr;
|
hdr.offset = 0; //data - datastart;
|
||||||
|
hdr.addref();
|
||||||
|
return hdr;
|
||||||
|
}
|
||||||
|
catch(...)
|
||||||
|
{
|
||||||
|
if (u != NULL)
|
||||||
|
{
|
||||||
|
CV_XADD(&(u->refcount), -1);
|
||||||
|
CV_XADD(&(u->urefcount), -1);
|
||||||
|
}
|
||||||
|
new_u->currAllocator->deallocate(new_u);
|
||||||
|
throw;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void UMat::create(int d, const int* _sizes, int _type, UMatUsageFlags _usageFlags)
|
void UMat::create(int d, const int* _sizes, int _type, UMatUsageFlags _usageFlags)
|
||||||
@ -692,18 +705,17 @@ UMat::UMat(const UMat& m, const Rect& roi)
|
|||||||
offset += roi.x*esz;
|
offset += roi.x*esz;
|
||||||
CV_Assert( 0 <= roi.x && 0 <= roi.width && roi.x + roi.width <= m.cols &&
|
CV_Assert( 0 <= roi.x && 0 <= roi.width && roi.x + roi.width <= m.cols &&
|
||||||
0 <= roi.y && 0 <= roi.height && roi.y + roi.height <= m.rows );
|
0 <= roi.y && 0 <= roi.height && roi.y + roi.height <= m.rows );
|
||||||
if( u )
|
|
||||||
CV_XADD(&(u->urefcount), 1);
|
|
||||||
if( roi.width < m.cols || roi.height < m.rows )
|
if( roi.width < m.cols || roi.height < m.rows )
|
||||||
flags |= SUBMATRIX_FLAG;
|
flags |= SUBMATRIX_FLAG;
|
||||||
|
|
||||||
step[0] = m.step[0]; step[1] = esz;
|
step[0] = m.step[0]; step[1] = esz;
|
||||||
updateContinuityFlag();
|
updateContinuityFlag();
|
||||||
|
|
||||||
|
addref();
|
||||||
if( rows <= 0 || cols <= 0 )
|
if( rows <= 0 || cols <= 0 )
|
||||||
{
|
{
|
||||||
release();
|
|
||||||
rows = cols = 0;
|
rows = cols = 0;
|
||||||
|
release();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -969,24 +981,29 @@ Mat UMat::getMat(int accessFlags) const
|
|||||||
// TODO Support ACCESS_READ (ACCESS_WRITE) without unnecessary data transfers
|
// TODO Support ACCESS_READ (ACCESS_WRITE) without unnecessary data transfers
|
||||||
accessFlags |= ACCESS_RW;
|
accessFlags |= ACCESS_RW;
|
||||||
UMatDataAutoLock autolock(u);
|
UMatDataAutoLock autolock(u);
|
||||||
if(CV_XADD(&u->refcount, 1) == 0)
|
try
|
||||||
u->currAllocator->map(u, accessFlags);
|
|
||||||
if (u->data != 0)
|
|
||||||
{
|
{
|
||||||
Mat hdr(dims, size.p, type(), u->data + offset, step.p);
|
if(CV_XADD(&u->refcount, 1) == 0)
|
||||||
hdr.flags = flags;
|
u->currAllocator->map(u, accessFlags);
|
||||||
hdr.u = u;
|
if (u->data != 0)
|
||||||
hdr.datastart = u->data;
|
{
|
||||||
hdr.data = u->data + offset;
|
Mat hdr(dims, size.p, type(), u->data + offset, step.p);
|
||||||
hdr.datalimit = hdr.dataend = u->data + u->size;
|
hdr.flags = flags;
|
||||||
return hdr;
|
hdr.u = u;
|
||||||
|
hdr.datastart = u->data;
|
||||||
|
hdr.data = u->data + offset;
|
||||||
|
hdr.datalimit = hdr.dataend = u->data + u->size;
|
||||||
|
return hdr;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
catch(...)
|
||||||
{
|
{
|
||||||
CV_XADD(&u->refcount, -1);
|
CV_XADD(&u->refcount, -1);
|
||||||
CV_Assert(u->data != 0 && "Error mapping of UMat to host memory.");
|
throw;
|
||||||
return Mat();
|
|
||||||
}
|
}
|
||||||
|
CV_XADD(&u->refcount, -1);
|
||||||
|
CV_Assert(u->data != 0 && "Error mapping of UMat to host memory.");
|
||||||
|
return Mat();
|
||||||
}
|
}
|
||||||
|
|
||||||
void* UMat::handle(int accessFlags) const
|
void* UMat::handle(int accessFlags) const
|
||||||
|
Loading…
Reference in New Issue
Block a user