add unsafeEachNode to iterate nodes when read lock held elsewhere

This commit is contained in:
Stephen Birarda 2017-06-12 17:51:54 -07:00
parent 682fa24745
commit 30d2e9fd23
2 changed files with 26 additions and 15 deletions

View file

@ -113,6 +113,7 @@ void AudioMixerClientData::optionallyReplicatePacket(ReceivedMessage& message, c
// first, make sure that this is a packet from a node we are supposed to replicate // first, make sure that this is a packet from a node we are supposed to replicate
if (node.isReplicated()) { if (node.isReplicated()) {
auto nodeList = DependencyManager::get<NodeList>(); auto nodeList = DependencyManager::get<NodeList>();
// now make sure it's a packet type that we want to replicate // now make sure it's a packet type that we want to replicate
@ -133,9 +134,8 @@ void AudioMixerClientData::optionallyReplicatePacket(ReceivedMessage& message, c
std::unique_ptr<NLPacket> packet; std::unique_ptr<NLPacket> packet;
// enumerate the downstream audio mixers and send them the replicated version of this packet // enumerate the downstream audio mixers and send them the replicated version of this packet
nodeList->eachMatchingNode([&](const SharedNodePointer& node)->bool { nodeList->unsafeEachNode([&](const SharedNodePointer& node) {
return node->getType() == NodeType::DownstreamAudioMixer; if (node->getType() == NodeType::DownstreamAudioMixer) {
}, [&](const SharedNodePointer& node) {
// construct the packet only once, if we have any downstream audio mixers to send to // construct the packet only once, if we have any downstream audio mixers to send to
if (!packet) { if (!packet) {
// construct an NLPacket to send to the replicant that has the contents of the received packet // construct an NLPacket to send to the replicant that has the contents of the received packet
@ -152,6 +152,7 @@ void AudioMixerClientData::optionallyReplicatePacket(ReceivedMessage& message, c
} }
nodeList->sendUnreliablePacket(*packet, node->getPublicSocket()); nodeList->sendUnreliablePacket(*packet, node->getPublicSocket());
}
}); });
} }

View file

@ -257,6 +257,16 @@ public:
return SharedNodePointer(); return SharedNodePointer();
} }
// This is unsafe because it does not take a lock
// Must only be called when you know that a read lock on the node mutex is held
// and will be held for the duration of your iteration
template<typename NodeLambda>
void unsafeEachNode(NodeLambda functor) {
for (NodeHash::const_iterator it = _nodeHash.cbegin(); it != _nodeHash.cend(); ++it) {
functor(it->second);
}
}
void putLocalPortIntoSharedMemory(const QString key, QObject* parent, quint16 localPort); void putLocalPortIntoSharedMemory(const QString key, QObject* parent, quint16 localPort);
bool getLocalServerPortFromSharedMemory(const QString key, quint16& localPort); bool getLocalServerPortFromSharedMemory(const QString key, quint16& localPort);