From 877dc201bdb0158263691dad8b8df81f729e246f Mon Sep 17 00:00:00 2001 From: Andrew Hutchings Date: Sun, 23 Oct 2016 16:12:38 +0100 Subject: [PATCH] MCOL-371 fix mutex free crash It is possible for an exception to be thrown when a memory limit is hit whilst a mutex is lock. That mutex is never unlocked and in Ubuntu 16.04 release build it can cause a crash when freed. This patch catches the exception, releases the lock and then re-throws. --- dbcon/joblist/tupleaggregatestep.cpp | 34 ++++++++++++++++++++-------- 1 file changed, 25 insertions(+), 9 deletions(-) diff --git a/dbcon/joblist/tupleaggregatestep.cpp b/dbcon/joblist/tupleaggregatestep.cpp index 695878710..595cb174d 100644 --- a/dbcon/joblist/tupleaggregatestep.cpp +++ b/dbcon/joblist/tupleaggregatestep.cpp @@ -348,10 +348,18 @@ void TupleAggregateStep::doThreadedSecondPhaseAggregate(uint32_t threadID) { if (!bucketDone[c] && fAgg_mutex[c]->try_lock()) { - if (multiDist) - dynamic_cast(fAggregators[c].get())->doDistinctAggregation_rowVec(rowBucketVecs[c]); - else - dynamic_cast(fAggregators[c].get())->doDistinctAggregation_rowVec(rowBucketVecs[c][0]); + try + { + if (multiDist) + dynamic_cast(fAggregators[c].get())->doDistinctAggregation_rowVec(rowBucketVecs[c]); + else + dynamic_cast(fAggregators[c].get())->doDistinctAggregation_rowVec(rowBucketVecs[c][0]); + } + catch(...) + { + fAgg_mutex[c]->unlock(); + throw; + } fAgg_mutex[c]->unlock(); bucketDone[c] = true; rowBucketVecs[c][0].clear(); @@ -4301,11 +4309,19 @@ void TupleAggregateStep::threadedAggregateRowGroups(uint32_t threadID) { if (!fEndOfResult && !bucketDone[c] && fAgg_mutex[c]->try_lock()) { - didWork = true; - if (multiDist) - dynamic_cast(fAggregators[c].get())->addRowGroup(&fRowGroupIns[threadID], rowBucketVecs[c]); - else - fAggregators[c]->addRowGroup(&fRowGroupIns[threadID], rowBucketVecs[c][0]); + try + { + didWork = true; + if (multiDist) + dynamic_cast(fAggregators[c].get())->addRowGroup(&fRowGroupIns[threadID], rowBucketVecs[c]); + else + fAggregators[c]->addRowGroup(&fRowGroupIns[threadID], rowBucketVecs[c][0]); + } + catch(...) + { + fAgg_mutex[c]->unlock(); + throw; + } fAgg_mutex[c]->unlock(); rowBucketVecs[c][0].clear(); bucketDone[c] = true;