From 0768785cfd5ac5180adfb7011f628439d4588484 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Wed, 17 Apr 2013 11:01:08 -0700 Subject: [PATCH] fix mutex movement when resizing AgentList vector --- libraries/shared/src/Agent.cpp | 16 ++++++++++++---- libraries/shared/src/Agent.h | 25 ++++++++++++------------- libraries/shared/src/AgentList.cpp | 2 +- voxel-server/src/main.cpp | 8 ++++---- 4 files changed, 29 insertions(+), 22 deletions(-) diff --git a/libraries/shared/src/Agent.cpp b/libraries/shared/src/Agent.cpp index 8c14d9a617..1ac676e916 100644 --- a/libraries/shared/src/Agent.cpp +++ b/libraries/shared/src/Agent.cpp @@ -19,8 +19,6 @@ #include #endif -Agent::Agent() {} - Agent::Agent(sockaddr *agentPublicSocket, sockaddr *agentLocalSocket, char agentType, uint16_t thisAgentId) { publicSocket = new sockaddr; memcpy(publicSocket, agentPublicSocket, sizeof(sockaddr)); @@ -37,7 +35,8 @@ Agent::Agent(sockaddr *agentPublicSocket, sockaddr *agentLocalSocket, char agent activeSocket = NULL; linkedData = NULL; - pthread_mutex_init(&deleteMutex, NULL); + deleteMutex = new pthread_mutex_t; + pthread_mutex_init(deleteMutex, NULL); } Agent::Agent(const Agent &otherAgent) { @@ -67,25 +66,34 @@ Agent::Agent(const Agent &otherAgent) { linkedData = NULL; } - pthread_mutex_init(&deleteMutex, NULL); + deleteMutex = new pthread_mutex_t; + pthread_mutex_init(deleteMutex, NULL); } Agent& Agent::operator=(Agent otherAgent) { + std::cout << "Agent swap constructor called on resize?\n"; swap(*this, otherAgent); return *this; } void Agent::swap(Agent &first, Agent &second) { using std::swap; + swap(first.publicSocket, second.publicSocket); swap(first.localSocket, second.localSocket); swap(first.activeSocket, second.activeSocket); swap(first.type, second.type); swap(first.linkedData, second.linkedData); swap(first.agentId, second.agentId); + swap(first.firstRecvTimeUsecs, second.firstRecvTimeUsecs); + swap(first.lastRecvTimeUsecs, second.lastRecvTimeUsecs); + swap(first.deleteMutex, second.deleteMutex); } Agent::~Agent() { + // the deleteMutex isn't destroyed here + // that's handled by the agent list silent agent removal thread + delete publicSocket; delete localSocket; delete linkedData; diff --git a/libraries/shared/src/Agent.h b/libraries/shared/src/Agent.h index bc6a6eb714..13d3326e57 100644 --- a/libraries/shared/src/Agent.h +++ b/libraries/shared/src/Agent.h @@ -19,17 +19,8 @@ #include #endif -class Agent { - void swap(Agent &first, Agent &second); - sockaddr *publicSocket, *localSocket, *activeSocket; - char type; - uint16_t agentId; - double firstRecvTimeUsecs; - double lastRecvTimeUsecs; - AgentData *linkedData; - -public: - Agent(); +class Agent { +public: Agent(sockaddr *agentPublicSocket, sockaddr *agentLocalSocket, char agentType, uint16_t thisAgentId); Agent(const Agent &otherAgent); ~Agent(); @@ -38,7 +29,7 @@ public: bool matches(sockaddr *otherPublicSocket, sockaddr *otherLocalSocket, char otherAgentType); - pthread_mutex_t deleteMutex; + pthread_mutex_t *deleteMutex; char getType() const; const char* getTypeName() const; @@ -59,7 +50,15 @@ public: AgentData* getLinkedData(); void setLinkedData(AgentData *newData); - friend std::ostream& operator<<(std::ostream& os, const Agent* agent); + friend std::ostream& operator<<(std::ostream& os, const Agent* agent); +private: + void swap(Agent &first, Agent &second); + sockaddr *publicSocket, *localSocket, *activeSocket; + char type; + uint16_t agentId; + double firstRecvTimeUsecs; + double lastRecvTimeUsecs; + AgentData *linkedData; }; std::ostream& operator<<(std::ostream& os, const Agent* agent); diff --git a/libraries/shared/src/AgentList.cpp b/libraries/shared/src/AgentList.cpp index 2751527d37..33716ec9f1 100644 --- a/libraries/shared/src/AgentList.cpp +++ b/libraries/shared/src/AgentList.cpp @@ -331,7 +331,7 @@ void *removeSilentAgents(void *args) { for(std::vector::iterator agent = agents->begin(); agent != agents->end();) { - pthread_mutex_t * agentDeleteMutex = &agent->deleteMutex; + pthread_mutex_t* agentDeleteMutex = agent->deleteMutex; if ((checkTimeUSecs - agent->getLastRecvTimeUsecs()) > AGENT_SILENCE_THRESHOLD_USECS && agent->getType() != AGENT_TYPE_VOXEL diff --git a/voxel-server/src/main.cpp b/voxel-server/src/main.cpp index 70a743b9c0..8f6bab7dc7 100644 --- a/voxel-server/src/main.cpp +++ b/voxel-server/src/main.cpp @@ -129,7 +129,7 @@ void eraseVoxelTreeAndCleanupAgentVisitData() { // lock this agent's delete mutex so that the delete thread doesn't // kill the agent while we are working with it - pthread_mutex_lock(&thisAgent->deleteMutex); + pthread_mutex_lock(thisAgent->deleteMutex); // clean up the agent visit data delete agentData->rootMarkerNode; @@ -137,7 +137,7 @@ void eraseVoxelTreeAndCleanupAgentVisitData() { // unlock the delete mutex so the other thread can // kill the agent if it has dissapeared - pthread_mutex_unlock(&thisAgent->deleteMutex); + pthread_mutex_unlock(thisAgent->deleteMutex); } } @@ -167,7 +167,7 @@ void *distributeVoxelsToListeners(void *args) { // lock this agent's delete mutex so that the delete thread doesn't // kill the agent while we are working with it - pthread_mutex_lock(&thisAgent->deleteMutex); + pthread_mutex_lock(thisAgent->deleteMutex); stopOctal = NULL; packetCount = 0; @@ -207,7 +207,7 @@ void *distributeVoxelsToListeners(void *args) { // unlock the delete mutex so the other thread can // kill the agent if it has dissapeared - pthread_mutex_unlock(&thisAgent->deleteMutex); + pthread_mutex_unlock(thisAgent->deleteMutex); } // dynamically sleep until we need to fire off the next set of voxels