I am receiving updates from two different sources (network listen) upon which I get a callback to a method somewhat like this:
void onUpdate(Update* update)
{
static MutexT lock;
static hash_set<UpdateID> set;
ScopedGuard _(lock); //lock here
hash_set<UpdateID>::iterator it = set.find(update->id);
if (it == set.end())
set.insert(update->id);
else
return;
listener->onUpdate(/*some stuff*/);
}
since both sources are feeding you the same updates, you want to avoid notifying on duplicates, you want to arbitrate between both sources to be up to date with the latest from whoever gives it to you first and also for missed updates if one sources is possibly unreliable. The thing is, it's expensive to lock on every update, is there a way around this lock if I definitely do not want duplicate onUpdate
calls?
(Or at least a way to reduce cost?)
First of all, the lock shouldn't be static, it should be a member variable.
You could make it more efficient by using a reader/writer mutex, e.g.
boost::shared_mutex mutex_;
std::unordered_set<UpdateID> set_;
void onUpdate(const Update& update)
{
boost::upgrade_lock<boost::shared_mutex> lock(mutex_);
auto it = set_.find(update.id);
if(it == set_.end())
{
boost::upgrade_to_unique_lock<boost::shared_mutex> unique_lock(mutex_);
set.insert(update.id);
}
listener->onUpdate(/*some stuff*/);
}