diff --git a/stepmania/src/GameState.cpp b/stepmania/src/GameState.cpp index 014cb7a9a5..227cce2cd2 100644 --- a/stepmania/src/GameState.cpp +++ b/stepmania/src/GameState.cpp @@ -230,8 +230,9 @@ void GameState::PlayersFinalized() m_bPlayersFinalized = true; - MEMCARDMAN->PauseMountingThread(); MEMCARDMAN->LockCards(); + + /* Mount all available cards, for loading the profile and edits. */ MEMCARDMAN->TryMountAllCards(); // apply saved default modifiers if any @@ -276,7 +277,6 @@ void GameState::PlayersFinalized() } MEMCARDMAN->UnmountAllUsedCards(); - MEMCARDMAN->UnPauseMountingThread(); } /* This data is added to each player profile, and to the machine profile per-player. */ @@ -350,7 +350,6 @@ void GameState::EndGame() } } - MEMCARDMAN->PauseMountingThread(); MEMCARDMAN->MountAllUsedCards(); BOOKKEEPER->WriteToDisk(); @@ -371,8 +370,6 @@ void GameState::EndGame() MEMCARDMAN->FlushAndReset(); CHECKPOINT; - MEMCARDMAN->UnPauseMountingThread(); - SONGMAN->FreeAllLoadedFromProfiles(); // make sure we don't execute EndGame twice. diff --git a/stepmania/src/MemoryCardManager.cpp b/stepmania/src/MemoryCardManager.cpp index d508945915..a361237631 100644 --- a/stepmania/src/MemoryCardManager.cpp +++ b/stepmania/src/MemoryCardManager.cpp @@ -35,6 +35,7 @@ MemoryCardManager::MemoryCardManager() FOREACH_PlayerNumber( p ) { m_bTooLate[p] = false; + m_bMounted[p] = false; } /* These can play at any time. Preload them, so we don't cause a skip in gameplay. */ @@ -261,6 +262,8 @@ void MemoryCardManager::MountAllUsedCards() } } +/* Called in EndGame just after writing the profile. Called by PlayersFinalized just after + * reading the profile. Should never block; use FlushAndReset to block until writes complete. */ void MemoryCardManager::UnmountAllUsedCards() { FOREACH_EnabledPlayer( p ) @@ -279,8 +282,23 @@ void MemoryCardManager::MountCard( PlayerNumber pn ) { ASSERT( !m_Device[pn].IsBlank() ); + /* Pause the mounting thread when we mount the first drive. */ + bool bNeedPause = true; + FOREACH_PlayerNumber( p ) + if( m_bMounted[p] ) + bNeedPause = false; + if( bNeedPause ) + this->PauseMountingThread(); + if( !m_pDriver->MountAndTestWrite(&m_Device[pn]) ) + { + if( bNeedPause ) + this->UnPauseMountingThread(); + return; + } + + m_bMounted[p] = true; /* If this is the first time we're mounting the device, mount the VFS drivers. * Simply mounting our VFS on a directory doesn't actually touch the directory, @@ -305,8 +323,21 @@ void MemoryCardManager::UnmountCard( PlayerNumber pn ) { ASSERT( !m_Device[pn].IsBlank() ); + if( !m_bMounted[pn] ) + return; + /* Leave our own filesystem drivers mounted. */ m_pDriver->Unmount( &m_Device[pn] ); + + m_bMounted[pn] = false; + + /* Unpause the mounting thread when we unmount the last drive. */ + bool bNeedUnpause = true; + FOREACH_PlayerNumber( p ) + if( m_bMounted[p] ) + bNeedUnpause = false; + if( bNeedUnpause ) + this->UnPauseMountingThread(); } void MemoryCardManager::FlushAndReset() diff --git a/stepmania/src/MemoryCardManager.h b/stepmania/src/MemoryCardManager.h index 7e6e41b9be..6ce7f7c521 100644 --- a/stepmania/src/MemoryCardManager.h +++ b/stepmania/src/MemoryCardManager.h @@ -19,8 +19,6 @@ public: MemoryCardState GetCardState( PlayerNumber pn ); -// CString GetOsMountDir( PlayerNumber pn ); // only valid when state = ready - void LockCards(); // prevent removing or changing of memory cards void UnlockCards(); void TryMountAllCards(); @@ -29,9 +27,6 @@ public: void MountCard( PlayerNumber pn ); void UnmountCard( PlayerNumber pn ); - void PauseMountingThread(); // call this before mouting, reading, or writing to memory card - void UnPauseMountingThread(); // call this when done mouting, reading, or writing to memory card - void FlushAndReset(); // force all files to be flushed to mounted memory cards bool PathIsMemCard( CString sDir ) const; @@ -41,6 +36,8 @@ public: protected: void UpdateUnassignedCards(); // do our best to assign a Device to each player + void PauseMountingThread(); // call this before mouting, reading, or writing to memory card + void UnPauseMountingThread(); // call this when done mouting, reading, or writing to memory card MemoryCardDriver *m_pDriver; @@ -48,6 +45,7 @@ protected: bool m_bCardsLocked; bool m_bTooLate[NUM_PLAYERS]; // card was inserted after lock + bool m_bMounted[NUM_PLAYERS]; // card is currently mounted UsbStorageDevice m_Device[NUM_PLAYERS]; // device in the memory card slot, NULL if none RageSound m_soundReady; diff --git a/stepmania/src/ScreenEvaluation.cpp b/stepmania/src/ScreenEvaluation.cpp index e417d79d6c..70496972bc 100644 --- a/stepmania/src/ScreenEvaluation.cpp +++ b/stepmania/src/ScreenEvaluation.cpp @@ -1357,7 +1357,6 @@ void ScreenEvaluation::Input( const DeviceInput& DeviceI, const InputEventType t if( !m_bSavedScreenshot[pn] && // only allow one screenshot PROFILEMAN->IsUsingProfile(pn) ) { - MEMCARDMAN->PauseMountingThread(); if( PROFILEMAN->ProfileWasLoadedFromMemoryCard(pn) ) MEMCARDMAN->MountCard( pn ); @@ -1369,7 +1368,6 @@ void ScreenEvaluation::Input( const DeviceInput& DeviceI, const InputEventType t if( PROFILEMAN->ProfileWasLoadedFromMemoryCard(pn) ) MEMCARDMAN->UnmountCard( pn ); - MEMCARDMAN->UnPauseMountingThread(); if( !sFileName.empty() ) {