From 2ccea8dcf61775908a3407a6a986808ccf75518f Mon Sep 17 00:00:00 2001 From: Glenn Maynard Date: Sat, 5 Jun 2004 01:04:17 +0000 Subject: [PATCH] very temporary hack to try to track down all_sounds corruption --- stepmania/src/RageSoundManager.cpp | 39 +++++++++++++++--- stepmania/src/RageSoundManager.h | 64 +++++++++++++++++++++++++++++- 2 files changed, 96 insertions(+), 7 deletions(-) diff --git a/stepmania/src/RageSoundManager.cpp b/stepmania/src/RageSoundManager.cpp index 1620b32e5e..ca2a202e83 100644 --- a/stepmania/src/RageSoundManager.cpp +++ b/stepmania/src/RageSoundManager.cpp @@ -13,6 +13,26 @@ #include "arch/Sound/RageSoundDriver.h" #include "SDL_audio.h" +#if defined(WIN32) +set g_ProtectedPages; +void EnableWrites() +{ + DWORD ignore; + for( set::iterator it = g_ProtectedPages.begin(); it != g_ProtectedPages.end(); ++it ) + VirtualProtect( *it, 4096, PAGE_READWRITE, &ignore ); +} + +void DisableWrites() +{ + DWORD ignore; + for( set::iterator it = g_ProtectedPages.begin(); it != g_ProtectedPages.end(); ++it ) + VirtualProtect( *it, 4096, PAGE_READONLY, &ignore ); +} +#else +void EnableWrites() { } +void DisableWrites() { } +#endif + /* * This mutex is locked before Update() deletes old sounds from owned_sounds. Lock * this mutex if you want to ensure that sounds remain valid. (Other threads may @@ -37,6 +57,7 @@ RageSoundManager::RageSoundManager() { pos_map_queue.reserve( 1024 ); MixVolume = 1.0f; + DisableWrites(); } void RageSoundManager::Init( CString drivers ) @@ -59,6 +80,8 @@ RageSoundManager::~RageSoundManager() /* Don't lock while deleting the driver (the decoder thread might deadlock). */ delete driver; + + EnableWrites(); /* for dtor */ } void RageSoundManager::StartMixing( RageSoundBase *snd ) @@ -97,10 +120,10 @@ void RageSoundManager::Update(float delta) * child sounds first. Otherwise, another sound might be allocated that has the * same pointer as an old, deleted parent, and since we use the pointer to the * parent to determine which sounds share the same parent, it'll confuse GetCopies(). */ - for( it = all_sounds.begin(); it != all_sounds.end(); ++it ) - if( (*it)->GetOriginal() != (*it) ) // child + for( all_sounds_type::iterator iter = all_sounds.begin(); iter != all_sounds.end(); ++iter ) + if( (*iter)->GetOriginal() != (*iter) ) // child { - set::iterator parent = ToDelete.find( (*it)->GetOriginal() ); + set::iterator parent = ToDelete.find( (*iter)->GetOriginal() ); if( parent != ToDelete.end() ) ToDelete.erase( parent ); } @@ -122,14 +145,18 @@ void RageSoundManager::Update(float delta) void RageSoundManager::RegisterSound( RageSound *p ) { g_SoundManMutex.Lock(); /* lock for access to all_sounds */ + EnableWrites(); all_sounds.insert( p ); + DisableWrites(); g_SoundManMutex.Unlock(); /* finished with all_sounds */ } void RageSoundManager::UnregisterSound( RageSound *p ) { g_SoundManMutex.Lock(); /* lock for access to all_sounds */ + EnableWrites(); all_sounds.erase( p ); + DisableWrites(); g_SoundManMutex.Unlock(); /* finished with all_sounds */ } @@ -172,7 +199,7 @@ RageSound *RageSoundManager::GetSoundByID( int ID ) LockMut( g_SoundManMutex ); /* Find the sound with p.ID. */ - set::iterator it; + all_sounds_type::iterator it; for( it = all_sounds.begin(); it != all_sounds.end(); ++it ) if( (*it)->GetID() == ID ) return *it; @@ -308,12 +335,12 @@ void RageSoundManager::GetCopies( RageSound &snd, vector &snds, boo g_DeletionMutex.Lock(); g_SoundManMutex.Lock(); /* lock for access to all_sounds */ - const set sounds = all_sounds; + const all_sounds_type sounds = all_sounds; g_SoundManMutex.Unlock(); /* finished with all_sounds */ RageSound *parent = snd.GetOriginal(); - set::const_iterator it; + all_sounds_type::const_iterator it; for( it = sounds.begin(); it != sounds.end(); ++it ) { CHECKPOINT_M( ssprintf("%p %p", *it, parent) ); diff --git a/stepmania/src/RageSoundManager.h b/stepmania/src/RageSoundManager.h index 2cd4158904..1e20816ecd 100644 --- a/stepmania/src/RageSoundManager.h +++ b/stepmania/src/RageSoundManager.h @@ -10,6 +10,67 @@ class RageSoundBase; class RageSoundDriver; struct RageSoundParams; +/* This is a temporary hack, to try to track down an obscure crash. */ +#if defined(WIN32) +#include + +extern set g_ProtectedPages; +template +class ProtAllocator +{ +public: + typedef T value_type; + typedef value_type* pointer; + typedef const value_type* const_pointer; + typedef value_type& reference; + typedef const value_type& const_reference; + typedef std::size_t size_type; + typedef std::ptrdiff_t difference_type; + + template struct rebind + { + typedef ProtAllocator other; + }; + + explicit ProtAllocator() {} + ~ProtAllocator() {} + ProtAllocator( ProtAllocator const & ) {} + template ProtAllocator( ProtAllocator const& ) {} + + pointer address( reference r ) { return &r; } + const_pointer address( const_reference r ) { return &r; } + + pointer allocate( size_type cnt, typename std::allocator::const_pointer = 0 ) + { + cnt *= sizeof (T); + void *p = VirtualAlloc( NULL, cnt, MEM_COMMIT, PAGE_READWRITE ); + g_ProtectedPages.insert( p ); + + return reinterpret_cast( p ); + } + void deallocate( pointer p, size_type s ) + { + VirtualFree( p, 0, MEM_RELEASE ); + g_ProtectedPages.erase( p ); + } + + size_type max_size() const + { + return 2147483648 / sizeof(T); + } + + void construct( pointer p, const T& t ) { new(p) T(t); } + void destroy( pointer p ) { p->~T(); } + + bool operator==( ProtAllocator const& ) { return true; } + bool operator!=( ProtAllocator const& a ) { return !operator==(a); } +}; + +#else +#define ProtAllocator allocator +#endif + + class RageSoundManager { /* Set of sounds that we've taken over (and are responsible for deleting @@ -18,7 +79,8 @@ class RageSoundManager set playing_sounds; /* A list of all sounds that currently exist. */ - set all_sounds; + typedef set, ProtAllocator > all_sounds_type; + all_sounds_type all_sounds; RageSoundDriver *driver;