From cb1b41c1b23ed63df2ac4afca87a7e9de6ddf423 Mon Sep 17 00:00:00 2001 From: Michael Davidsaver Date: Tue, 21 Jun 2022 08:48:17 -0700 Subject: [PATCH] fixup AsWritePvt to be non-copyable Avoids double free via asTrapWriteAfterWrite() with c++98 --- pdbApp/pdb.h | 9 ++++++++- pdbApp/pdbgroup.cpp | 23 ++++++++++++----------- 2 files changed, 20 insertions(+), 12 deletions(-) diff --git a/pdbApp/pdb.h b/pdbApp/pdb.h index 65c0597..fd3c901 100644 --- a/pdbApp/pdb.h +++ b/pdbApp/pdb.h @@ -74,13 +74,20 @@ struct QSRV_API PDBProvider : public epics::pvAccess::ChannelProvider, QSRV_API void QSRVRegistrar_counters(); -class QSRV_API AsWritePvt { +class AsWritePvt { void * pvt; public: + AsWritePvt() :pvt(NULL) {} explicit AsWritePvt(void * pvt): pvt(pvt) {} ~AsWritePvt() { asTrapWriteAfterWrite(pvt); } + void swap(AsWritePvt& o) { + std::swap(pvt, o.pvt); + } +private: + AsWritePvt(const AsWritePvt&); + AsWritePvt& operator=(const AsWritePvt&); }; #endif // PDB_H diff --git a/pdbApp/pdbgroup.cpp b/pdbApp/pdbgroup.cpp index b329f5a..bb13e3a 100644 --- a/pdbApp/pdbgroup.cpp +++ b/pdbApp/pdbgroup.cpp @@ -350,22 +350,23 @@ void PDBGroupPut::put(pvd::PVStructure::shared_pointer const & value, // assume value may be a different struct each time... lot of wasted prep work const size_t npvs = channel->pv->members.size(); std::vector > putpvif(npvs); - std::vector asWritePvt; + pvd::shared_vector asWritePvt(npvs); for(size_t i=0; ipv->members[i]; - asWritePvt.push_back(AsWritePvt( - asTrapWriteWithData(channel->aspvt.at(i).aspvt, - std::string(channel->cred.user.begin(), channel->cred.user.end()).c_str(), - std::string(channel->cred.host.begin(), channel->cred.host.end()).c_str(), - info.chan, - info.chan->final_type, - info.chan->final_no_elements, - NULL - ) - )); + AsWritePvt wrt(asTrapWriteWithData( + channel->aspvt.at(i).aspvt, + &channel->cred.user[0], + &channel->cred.host[0], + info.chan.chan, + info.chan->final_type, + info.chan->final_no_elements, + NULL + ) + ); + asWritePvt[i].swap(wrt); if(!info.allowProc) continue; putpvif[i].reset(info.builder->attach(value, info.attachment));