// Ryzom - MMORPG Framework // Copyright (C) 2010 Winch Gate Property Limited // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU Affero General Public License as // published by the Free Software Foundation, either version 3 of the // License, or (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Affero General Public License for more details. // // You should have received a copy of the GNU Affero General Public License // along with this program. If not, see . #include "stdpch.h" #include "change_tracker_client.h" using namespace NLMISC; /* * Access the tracker header and item array (shared memory) */ void CChangeTrackerClient::access( sint32 shmid ) { _SMId = shmid; _Header = (TChangeTrackerHeader*)CSharedMemory::accessSharedMemory( toSharedMemId(_SMId) ); if ( ! _Header ) { // This can occur when a service disconnects from the MS when between the moment when // the MS sent the "add trackers" message and the moment when we received and applied it: // the MS deletes the tracker, thus the shared memory is immediatel destroyed as we did not // accessed it yet. nlwarning( "MIRROR: Cannot access shared memory for tracker" ); return; } _Array = (TChangeTrackerItem*)(((uint8*)_Header) + sizeof( TChangeTrackerHeader )); //nlinfo( "Setting _Array = %p + d% = %p", _Header, sizeof( TChangeTrackerHeader ), _Array ); } #if 0 /* * Set all entities as unchanged */ void CChangeTrackerClient::clean() { // Clear the changed rows until the last one that was notified in the current cycle // (do not clear the ones that could have been added (by a parallel recordChange()) // since the latest call to notifyNext() trackerMutex().enter(); TDataSetRow entityIndex = getFirstChanged(), entityIndex2; #ifdef NL_DEBUG //nlassert( entityIndex.isValid() ); #endif /*if ( entityIndex == LAST_CHANGED ) return;*/ /////////nldebug( "Cleaning tracker (smid %u): first changed=E%d lastNotified=%d", smid(), entityIndex, lastNotifiedRow() ); while ( entityIndex != lastNotifiedRow() ) { // Clear a row and get next one entityIndex2 = entityIndex; entityIndex = getNextChanged( entityIndex ); #ifdef NL_DEBUG //nlassert( entityIndex.isValid() ); #endif _Array[entityIndex2].NextChanged = TDataSetRow(); #ifdef COUNT_MIRROR_PROP_CHANGES --_Header->NbDistinctChanges; #endif /////////nldebug( "Tracker (smid %u): E%d cleaned, next is %d", smid(), entityIndex2, entityIndex ); } // Protect the consistency between clean() and recordChange() // Set the new entry point of the queue if ( entityIndex != LAST_CHANGED ) { _Header->First = _Array[entityIndex].NextChanged; _Array[entityIndex].NextChanged = TDataSetRow(); #ifdef COUNT_MIRROR_PROP_CHANGES --_Header->NbDistinctChanges; #endif } else { _Header->First = LAST_CHANGED; } // If there are no more changed rows, clear the exit point of the queue if ( _Header->First == LAST_CHANGED ) { _Header->Last = TDataSetRow(); } trackerMutex().leave(); } #endif /* * Release the tracker (unaccess shared memory + release mutex) */ void CChangeTrackerClient::release() { if ( (_Header != NULL) && (! isPointingToGroupTracker()) ) { NLMISC::CSharedMemory::closeSharedMemory( _Header ); _Header = NULL; _Array = NULL; _SMId = -1; #ifndef USE_FAST_MUTEX #ifdef NL_OS_WINDOWS trackerMutex().destroy(); #endif #endif } }