void MessageManager::DeleteEndpoint(int socketFD) { //Ensure that only one thread can be deleting an Endpoint at a time Lock functionLock(&m_deleteEndpointMutex); //Deleting the message endpoint requires that nobody else is using it! Lock lock(&m_endpointsMutex); if(m_endpoints.count(socketFD) > 0) { //First, shut down the endpoint, so as to signal anyone using it to clear out { Lock lock(m_endpoints[socketFD].second, READ_LOCK); if(m_endpoints[socketFD].first == NULL) { //If there is no endpoint, then just quit return; } m_endpoints[socketFD].first->Shutdown(); } //We unlock and relock in order to prevent a deadlock here with ~Ticket pthread_rwlock_t *rwlock = m_endpoints[socketFD].second; pthread_mutex_unlock(&m_endpointsMutex); Lock lock(rwlock, WRITE_LOCK); pthread_mutex_lock(&m_endpointsMutex); delete m_endpoints[socketFD].first; m_endpoints[socketFD].first = NULL; } }
cacheItem* WCache<cacheItem, cacheActual>::LoadIntoCache(int id, const string& filename, int submode, int style) { // note: my original implementation only had one lock (the cache mutex lock) - I eventually // added this second one, as locking at the Get() call means that the main thread is blocked on doing a simple cache // check. If you're hitting the system hard (like, paging up in the deck editor which forces 7 cards to load simultaneously), // we'd block the UI thread for a long period at this point. So I moved the cache mutex to lock specifically only attempts to touch // the shared cache container, and this separate lock was added to insulate us against thread safety issues in JGE. In particular, // JFileSystem is particularly unsafe, as it assumes that we have only one zip loaded at a time... rather than add mutexes in JGE, // I've kept it local to here. boost::mutex::scoped_lock functionLock(sLoadFunctionMutex); cacheItem* item = AttemptNew(filename, submode); //assert(item); if (style == RETRIEVE_MANAGE) { if (mError == CACHE_ERROR_404 || item) { managed[id] = item; //Record a hit or miss. } if (item) { item->deadbolt(); //Make permanent. } } else { if (mError == CACHE_ERROR_404 || item) { boost::mutex::scoped_lock lock(sCacheMutex); cache[id] = item; DebugTrace("inserted item ptr " << ToHex(item) << " at index " << id); } } if (item == NULL) { DebugTrace("Can't locate "); if (submode & TEXTURE_SUB_THUMB) { DebugTrace("thumbnail "); } DebugTrace(filename); return NULL; //Failure } //Succeeded in making a new item. unsigned long isize = item->size(); totalSize += isize; mError = CACHE_ERROR_NONE; if (style != RETRIEVE_MANAGE) { cacheItems++; cacheSize += isize; } #ifdef DEBUG_CACHE std::ostringstream stream; stream << "Cache insert: " << filename << " " << id << ", cacheItem count: " << cacheItems << ", cacheSize is now: " << cacheSize; LOG(stream.str().c_str()); #endif return item; }