very temporary hack to try to track down all_sounds corruption
This commit is contained in:
@@ -13,6 +13,26 @@
|
||||
#include "arch/Sound/RageSoundDriver.h"
|
||||
#include "SDL_audio.h"
|
||||
|
||||
#if defined(WIN32)
|
||||
set<void *> g_ProtectedPages;
|
||||
void EnableWrites()
|
||||
{
|
||||
DWORD ignore;
|
||||
for( set<void *>::iterator it = g_ProtectedPages.begin(); it != g_ProtectedPages.end(); ++it )
|
||||
VirtualProtect( *it, 4096, PAGE_READWRITE, &ignore );
|
||||
}
|
||||
|
||||
void DisableWrites()
|
||||
{
|
||||
DWORD ignore;
|
||||
for( set<void *>::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<RageSound *>::iterator parent = ToDelete.find( (*it)->GetOriginal() );
|
||||
set<RageSound *>::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<RageSound *>::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<RageSound *> &snds, boo
|
||||
g_DeletionMutex.Lock();
|
||||
|
||||
g_SoundManMutex.Lock(); /* lock for access to all_sounds */
|
||||
const set<RageSound *> sounds = all_sounds;
|
||||
const all_sounds_type sounds = all_sounds;
|
||||
g_SoundManMutex.Unlock(); /* finished with all_sounds */
|
||||
|
||||
RageSound *parent = snd.GetOriginal();
|
||||
|
||||
set<RageSound *>::const_iterator it;
|
||||
all_sounds_type::const_iterator it;
|
||||
for( it = sounds.begin(); it != sounds.end(); ++it )
|
||||
{
|
||||
CHECKPOINT_M( ssprintf("%p %p", *it, parent) );
|
||||
|
||||
@@ -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 <windows.h>
|
||||
|
||||
extern set<void *> g_ProtectedPages;
|
||||
template<typename T>
|
||||
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<typename U> struct rebind
|
||||
{
|
||||
typedef ProtAllocator<U> other;
|
||||
};
|
||||
|
||||
explicit ProtAllocator() {}
|
||||
~ProtAllocator() {}
|
||||
ProtAllocator( ProtAllocator const & ) {}
|
||||
template<typename U> ProtAllocator( ProtAllocator<U> const& ) {}
|
||||
|
||||
pointer address( reference r ) { return &r; }
|
||||
const_pointer address( const_reference r ) { return &r; }
|
||||
|
||||
pointer allocate( size_type cnt, typename std::allocator<void>::const_pointer = 0 )
|
||||
{
|
||||
cnt *= sizeof (T);
|
||||
void *p = VirtualAlloc( NULL, cnt, MEM_COMMIT, PAGE_READWRITE );
|
||||
g_ProtectedPages.insert( p );
|
||||
|
||||
return reinterpret_cast<pointer>( 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<RageSound *> playing_sounds;
|
||||
|
||||
/* A list of all sounds that currently exist. */
|
||||
set<RageSound *> all_sounds;
|
||||
typedef set<RageSound *, less<RageSound*>, ProtAllocator<RageSound*> > all_sounds_type;
|
||||
all_sounds_type all_sounds;
|
||||
|
||||
RageSoundDriver *driver;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user