add a mutex to NodeData and leverage in AvatarMixer threads

This commit is contained in:
Stephen Birarda 2014-03-25 15:49:47 -07:00
parent 6f4f55038b
commit c8b3ae0c40
5 changed files with 30 additions and 6 deletions

View file

@ -114,21 +114,25 @@ void AvatarMixer::broadcastAvatarData() {
NodeList* nodeList = NodeList::getInstance(); NodeList* nodeList = NodeList::getInstance();
AvatarMixerClientData* nodeData = NULL;
AvatarMixerClientData* otherNodeData = NULL;
foreach (const SharedNodePointer& node, nodeList->getNodeHash()) { foreach (const SharedNodePointer& node, nodeList->getNodeHash()) {
if (node->getLinkedData() && node->getType() == NodeType::Agent && node->getActiveSocket()) { if (node->getLinkedData() && node->getType() == NodeType::Agent && node->getActiveSocket()
&& (nodeData = reinterpret_cast<AvatarMixerClientData*>(node->getLinkedData()))->getMutex().tryLock()) {
++_sumListeners; ++_sumListeners;
// reset packet pointers for this node // reset packet pointers for this node
mixedAvatarByteArray.resize(numPacketHeaderBytes); mixedAvatarByteArray.resize(numPacketHeaderBytes);
AvatarMixerClientData* myData = reinterpret_cast<AvatarMixerClientData*>(node->getLinkedData()); AvatarData& avatar = nodeData->getAvatar();
AvatarData& avatar = myData->getAvatar();
glm::vec3 myPosition = avatar.getPosition(); glm::vec3 myPosition = avatar.getPosition();
// this is an AGENT we have received head data from // this is an AGENT we have received head data from
// send back a packet with other active node data to this node // send back a packet with other active node data to this node
foreach (const SharedNodePointer& otherNode, nodeList->getNodeHash()) { foreach (const SharedNodePointer& otherNode, nodeList->getNodeHash()) {
if (otherNode->getLinkedData() && otherNode->getUUID() != node->getUUID()) { if (otherNode->getLinkedData() && otherNode->getUUID() != node->getUUID()
&& (otherNodeData = reinterpret_cast<AvatarMixerClientData*>(otherNode->getLinkedData()))->getMutex().tryLock()) {
AvatarMixerClientData* otherNodeData = reinterpret_cast<AvatarMixerClientData*>(otherNode->getLinkedData()); AvatarMixerClientData* otherNodeData = reinterpret_cast<AvatarMixerClientData*>(otherNode->getLinkedData());
AvatarData& otherAvatar = otherNodeData->getAvatar(); AvatarData& otherAvatar = otherNodeData->getAvatar();
@ -158,7 +162,7 @@ void AvatarMixer::broadcastAvatarData() {
// if the receiving avatar has just connected make sure we send out the mesh and billboard // if the receiving avatar has just connected make sure we send out the mesh and billboard
// for this avatar (assuming they exist) // for this avatar (assuming they exist)
bool forceSend = !myData->checkAndSetHasReceivedFirstPackets(); bool forceSend = !nodeData->checkAndSetHasReceivedFirstPackets();
// we will also force a send of billboard or identity packet // we will also force a send of billboard or identity packet
// if either has changed in the last frame // if either has changed in the last frame
@ -191,10 +195,14 @@ void AvatarMixer::broadcastAvatarData() {
++_sumIdentityPackets; ++_sumIdentityPackets;
} }
} }
otherNodeData->getMutex().unlock();
} }
} }
nodeList->writeDatagram(mixedAvatarByteArray, node); nodeList->writeDatagram(mixedAvatarByteArray, node);
nodeData->getMutex().unlock();
} }
} }
@ -238,6 +246,7 @@ void AvatarMixer::readPendingDatagrams() {
// parse the identity packet and update the change timestamp if appropriate // parse the identity packet and update the change timestamp if appropriate
if (avatar.hasIdentityChangedAfterParsing(receivedPacket)) { if (avatar.hasIdentityChangedAfterParsing(receivedPacket)) {
QMutexLocker nodeDataLocker(&nodeData->getMutex());
nodeData->setIdentityChangeTimestamp(QDateTime::currentMSecsSinceEpoch()); nodeData->setIdentityChangeTimestamp(QDateTime::currentMSecsSinceEpoch());
} }
} }
@ -254,6 +263,7 @@ void AvatarMixer::readPendingDatagrams() {
// parse the billboard packet and update the change timestamp if appropriate // parse the billboard packet and update the change timestamp if appropriate
if (avatar.hasBillboardChangedAfterParsing(receivedPacket)) { if (avatar.hasBillboardChangedAfterParsing(receivedPacket)) {
QMutexLocker nodeDataLocker(&nodeData->getMutex());
nodeData->setBillboardChangeTimestamp(QDateTime::currentMSecsSinceEpoch()); nodeData->setBillboardChangeTimestamp(QDateTime::currentMSecsSinceEpoch());
} }

View file

@ -9,6 +9,7 @@
#ifndef __hifi__AvatarMixerClientData__ #ifndef __hifi__AvatarMixerClientData__
#define __hifi__AvatarMixerClientData__ #define __hifi__AvatarMixerClientData__
#include <QtCore/QMutex>
#include <QtCore/QUrl> #include <QtCore/QUrl>
#include <AvatarData.h> #include <AvatarData.h>

View file

@ -8,6 +8,12 @@
#include "NodeData.h" #include "NodeData.h"
NodeData::NodeData() :
_mutex()
{
}
NodeData::~NodeData() { NodeData::~NodeData() {
} }

View file

@ -16,9 +16,14 @@ class Node;
class NodeData : public QObject { class NodeData : public QObject {
Q_OBJECT Q_OBJECT
public: public:
NodeData();
virtual ~NodeData() = 0; virtual ~NodeData() = 0;
virtual int parseData(const QByteArray& packet) = 0; virtual int parseData(const QByteArray& packet) = 0;
QMutex& getMutex() { return _mutex; }
private:
QMutex _mutex;
}; };
#endif #endif

View file

@ -317,6 +317,8 @@ int NodeList::updateNodeWithDataFromPacket(const SharedNodePointer& matchingNode
linkedDataCreateCallback(matchingNode.data()); linkedDataCreateCallback(matchingNode.data());
} }
QMutexLocker linkedDataLocker(&matchingNode->getLinkedData()->getMutex());
return matchingNode->getLinkedData()->parseData(packet); return matchingNode->getLinkedData()->parseData(packet);
} }