From d93f7580244e69045a8a1747e85d5baae3dd4e4d Mon Sep 17 00:00:00 2001 From: Chris Danford Date: Wed, 7 Apr 2004 01:18:11 +0000 Subject: [PATCH] do memory card write test in a separate thread --- stepmania/src/PrefsManager.h | 2 +- stepmania/src/StepMania.dsp | 37 +++-- stepmania/src/StepMania.vcproj | 18 ++- .../MemoryCard/MemoryCardDriverThreaded.cpp | 91 +++++++++++++ .../MemoryCard/MemoryCardDriverThreaded.h | 57 ++++++++ .../MemoryCardDriverThreaded_Windows.cpp | 128 ++++++++++++++++++ .../MemoryCardDriverThreaded_Windows.h | 23 ++++ stepmania/src/arch/arch.cpp | 2 +- stepmania/src/arch/arch_Win32.h | 2 +- 9 files changed, 340 insertions(+), 20 deletions(-) create mode 100644 stepmania/src/arch/MemoryCard/MemoryCardDriverThreaded.cpp create mode 100644 stepmania/src/arch/MemoryCard/MemoryCardDriverThreaded.h create mode 100644 stepmania/src/arch/MemoryCard/MemoryCardDriverThreaded_Windows.cpp create mode 100644 stepmania/src/arch/MemoryCard/MemoryCardDriverThreaded_Windows.h diff --git a/stepmania/src/PrefsManager.h b/stepmania/src/PrefsManager.h index d719c6d000..8ee9fcd826 100644 --- a/stepmania/src/PrefsManager.h +++ b/stepmania/src/PrefsManager.h @@ -178,7 +178,7 @@ public: int m_iEndlessBreakLength; bool m_bDisableScreenSaver; CString m_sLanguage; - CString m_sMemoryCardProfileSubdir; // if set, always use the device that mounts to this point + CString m_sMemoryCardProfileSubdir; // the directory on a memory card to look in for a profile CString m_sDefaultLocalProfileID[NUM_PLAYERS]; CString m_sMemoryCardOsMountPoint[NUM_PLAYERS]; // if set, always use the device that mounts to this point int m_iMemoryCardUsbBus[NUM_PLAYERS]; // take the first storage device on this usb bus diff --git a/stepmania/src/StepMania.dsp b/stepmania/src/StepMania.dsp index a2f9106de0..63a293bf53 100644 --- a/stepmania/src/StepMania.dsp +++ b/stepmania/src/StepMania.dsp @@ -1,5 +1,5 @@ # Microsoft Developer Studio Project File - Name="StepMania" - Package Owner=<4> -# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# Microsoft Developer Studio Generated Build File, Format Version 60000 # ** DO NOT EDIT ** # TARGTYPE "Win32 (x86) Application" 0x0101 @@ -62,10 +62,10 @@ LINK32=link.exe # SUBTRACT LINK32 /verbose /profile /pdb:none /incremental:no /nodefaultlib # Begin Special Build Tool IntDir=.\../Debug6 -TargetDir=\temp\stepmania\Program +TargetDir=\stepmania\stepmania\Program TargetName=StepMania-debug SOURCE="$(InputPath)" -PreLink_Cmds=disasm\verinc cl /Zl /nologo /c verstub.cpp /Fo$(IntDir)\ +PreLink_Cmds=disasm\verinc cl /Zl /nologo /c verstub.cpp /Fo$(IntDir)\ PostBuild_Cmds=disasm\mapconv $(IntDir)\$(TargetName).map $(TargetDir)\StepMania.vdi # End Special Build Tool @@ -135,10 +135,10 @@ LINK32=link.exe # SUBTRACT LINK32 /verbose /pdb:none /debug # Begin Special Build Tool IntDir=.\../Release6 -TargetDir=\temp\stepmania\Program +TargetDir=\stepmania\stepmania\Program TargetName=StepMania SOURCE="$(InputPath)" -PreLink_Cmds=disasm\verinc cl /Zl /nologo /c verstub.cpp /Fo$(IntDir)\ +PreLink_Cmds=disasm\verinc cl /Zl /nologo /c verstub.cpp /Fo$(IntDir)\ PostBuild_Cmds=disasm\mapconv $(IntDir)\$(TargetName).map $(TargetDir)\StepMania.vdi # End Special Build Tool @@ -2657,26 +2657,41 @@ SOURCE=.\arch\MemoryCard\MemoryCardDriver_Null.h # End Source File # Begin Source File -SOURCE=.\arch\MemoryCard\MemoryCardDriver_Windows.cpp +SOURCE=.\arch\MemoryCard\MemoryCardDriverThreaded.cpp !IF "$(CFG)" == "StepMania - Win32 Debug" !ELSEIF "$(CFG)" == "StepMania - Xbox Debug" -# PROP Exclude_From_Build 1 - !ELSEIF "$(CFG)" == "StepMania - Win32 Release" !ELSEIF "$(CFG)" == "StepMania - Xbox Release" -# PROP Exclude_From_Build 1 - !ENDIF # End Source File # Begin Source File -SOURCE=.\arch\MemoryCard\MemoryCardDriver_Windows.h +SOURCE=.\arch\MemoryCard\MemoryCardDriverThreaded.h +# End Source File +# Begin Source File + +SOURCE=.\arch\MemoryCard\MemoryCardDriverThreaded_Windows.cpp + +!IF "$(CFG)" == "StepMania - Win32 Debug" + +!ELSEIF "$(CFG)" == "StepMania - Xbox Debug" + +!ELSEIF "$(CFG)" == "StepMania - Win32 Release" + +!ELSEIF "$(CFG)" == "StepMania - Xbox Release" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\arch\MemoryCard\MemoryCardDriverThreaded_Windows.h # End Source File # End Group # Begin Source File diff --git a/stepmania/src/StepMania.vcproj b/stepmania/src/StepMania.vcproj index e6f06b1d1a..6e621f5fa9 100644 --- a/stepmania/src/StepMania.vcproj +++ b/stepmania/src/StepMania.vcproj @@ -1097,15 +1097,21 @@ cl /Zl /nologo /c verstub.cpp /Fo"$(IntDir)"\ + + + + + + + + - - - - MountThreadMain(); + return 0; +} + +template +bool VectorsAreEqual( const T &a, const T &b ) +{ + if( a.size() != b.size() ) + return false; + + for( unsigned i=0; iTrace( "Shutting down Mount thread..." ); + m_threadMemoryCardMount.Wait(); + LOG->Trace( "Mount thread shut down." ); +} + +bool MemoryCardDriverThreaded::StorageDevicesChanged() +{ + LockMut( m_mutexStorageDevices ); + if( m_bStorageDevicesChanged ) + { + m_bStorageDevicesChanged = false; + return true; + } + else + { + return false; + } +} + +void MemoryCardDriverThreaded::GetStorageDevices( vector& vDevicesOut ) +{ + LockMut( m_mutexStorageDevices ); + vDevicesOut.clear(); + for( unsigned i=0; i::const_iterator iter = find( m_vStorageDevices.begin(), m_vStorageDevices.end(), *pDevice ); + if( iter == m_vStorageDevices.end() ) + { + LOG->Warn( "Tried to mount a memory card that is no longer connected" ); + return false; + } + + if( !iter->bWriteTestSucceeded ) + return false; + + this->Mount( pDevice, sMountPoint ); + return true; +} + +/* +* Copyright (c) 2003 by the person(s) listed below. All rights reserved. +* Chris Danford +*/ diff --git a/stepmania/src/arch/MemoryCard/MemoryCardDriverThreaded.h b/stepmania/src/arch/MemoryCard/MemoryCardDriverThreaded.h new file mode 100644 index 0000000000..5a55374956 --- /dev/null +++ b/stepmania/src/arch/MemoryCard/MemoryCardDriverThreaded.h @@ -0,0 +1,57 @@ +#ifndef MemoryCardDriverThreaded_H +#define MemoryCardDriverThreaded_H 1 +/* +----------------------------------------------------------------------------- + Class: MemoryCardDriverThreaded + + Desc: Adapter . + + Copyright (c) 2001-2004 by the person(s) listed below. All rights reserved. + Chris Danford +----------------------------------------------------------------------------- +*/ + +#include "MemoryCardDriver.h" +#include "RageThreads.h" + +struct UsbStorageDeviceEx : public UsbStorageDevice +{ + UsbStorageDeviceEx() { MakeBlank(); } + + void MakeBlank() + { + bWriteTestSucceeded = false; + } + + bool bWriteTestSucceeded; +}; + +class MemoryCardDriverThreaded : public MemoryCardDriver +{ +public: + MemoryCardDriverThreaded(); + ~MemoryCardDriverThreaded(); + void StartThread(); // call this in the derived constructor to start the mounting thread + + virtual bool StorageDevicesChanged(); + virtual void GetStorageDevices( vector& vStorageDevicesOut ); + virtual bool MountAndTestWrite( UsbStorageDevice* pDevice, CString sMountPoint ); + static int MountThread_Start( void *p ); +protected: + virtual void MountThreadMain() = 0; + virtual void Mount( UsbStorageDevice* pDevice, CString sMountPoint ) = 0; + + RageThread m_threadMemoryCardMount; + bool m_bShutdown; + + vector m_vStorageDevices; + bool m_bStorageDevicesChanged; + RageMutex m_mutexStorageDevices; // protects the above two +}; + +#endif + +/* + * Copyright (c) 2003 by the person(s) listed below. All rights reserved. + * Chris Danford + */ diff --git a/stepmania/src/arch/MemoryCard/MemoryCardDriverThreaded_Windows.cpp b/stepmania/src/arch/MemoryCard/MemoryCardDriverThreaded_Windows.cpp new file mode 100644 index 0000000000..becb99f729 --- /dev/null +++ b/stepmania/src/arch/MemoryCard/MemoryCardDriverThreaded_Windows.cpp @@ -0,0 +1,128 @@ +#include "global.h" +#include "MemoryCardDriverThreaded_Windows.h" +#include "RageUtil.h" +#include +#include +#include "RageFileManager.h" +#include "RageLog.h" +#include + +MemoryCardDriverThreaded_Windows::MemoryCardDriverThreaded_Windows() +{ + StartThread(); +} + +typedef const CString& CCStringRef; + +bool TestWrite( CCStringRef sDrive ) +{ + // TODO: Use RageFileDirect here to detect ready state? + TCHAR szVolumeNameBuffer[MAX_PATH]; + DWORD dwVolumeSerialNumber; + DWORD dwMaximumComponentLength; + DWORD lpFileSystemFlags; + TCHAR szFileSystemNameBuffer[MAX_PATH]; + BOOL bReady = GetVolumeInformation( + sDrive, + szVolumeNameBuffer, + sizeof(szVolumeNameBuffer), + &dwVolumeSerialNumber, + &dwMaximumComponentLength, + &lpFileSystemFlags, + szFileSystemNameBuffer, + sizeof(szFileSystemNameBuffer) ); + if( !bReady ) + return false; + + // Try to write a file. + // TODO: Can we use RageFile for this? + CString sFile = sDrive + "temp"; + FILE* fp = fopen( sFile, "w" ); + if( fp == NULL ) + return false; + fclose( fp ); + remove( sFile ); + + return true; +} + +void MemoryCardDriverThreaded_Windows::MountThreadMain() +{ + DWORD dwLastLogicalDrives = 0; + + while( !m_bShutdown ) + { + DWORD dwNewLogicalDrives = ::GetLogicalDrives(); + if( dwNewLogicalDrives != dwLastLogicalDrives ) + { + vector vNewStorageDevices; + + const int MAX_DRIVES = 26; + for( int i=2; iWarn( "Found drive %s", sDrive.c_str() ); + + if( GetDriveType(sDrive) == DRIVE_REMOVABLE ) // is a removable drive + { + UsbStorageDeviceEx usbd; + usbd.sOsMountDir = sDrive; + usbd.bWriteTestSucceeded = TestWrite( sDrive ); + vNewStorageDevices.push_back( usbd ); + } + } + } + + { + LockMut( m_mutexStorageDevices ); + m_bStorageDevicesChanged = true; + m_vStorageDevices = vNewStorageDevices; + } + } + dwLastLogicalDrives = dwNewLogicalDrives; + + ::Sleep( 100 ); + } +} + +void MemoryCardDriverThreaded_Windows::Mount( UsbStorageDevice* pDevice, CString sMountPoint ) +{ + ASSERT( !pDevice->sOsMountDir.empty() ); + + /* Unmount any previous mounts for this mountpoint. */ + vector Mounts; + FILEMAN->GetLoadedDrivers( Mounts ); + for( unsigned i = 0; i < Mounts.size(); ++i ) + { + if( Mounts[i].Type.CompareNoCase( "dir" ) ) + continue; // wrong type + if( Mounts[i].Root.CompareNoCase( pDevice->sOsMountDir ) ) + continue; // wrong root + FILEMAN->Unmount( Mounts[i].Type, Mounts[i].Root, Mounts[i].MountPoint ); + } + + FILEMAN->Mount( "dir", pDevice->sOsMountDir, sMountPoint.c_str() ); + LOG->Trace( "FILEMAN->Mount %s %s", pDevice->sOsMountDir.c_str(), sMountPoint.c_str() ); +} + +void MemoryCardDriverThreaded_Windows::Unmount( UsbStorageDevice* pDevice, CString sMountPoint ) +{ + + // nothing to do here... +} + +void MemoryCardDriverThreaded_Windows::Flush( UsbStorageDevice* pDevice ) +{ + // Do we need anything here? I don't lose data if ejecting + // soon after a write. From the activity LED, it looks like + // Windows flushes automatically every ~2 seconds. -Chris +} + +/* + * Copyright (c) 2003 by the person(s) listed below. All rights reserved. + * Chris Danford + */ diff --git a/stepmania/src/arch/MemoryCard/MemoryCardDriverThreaded_Windows.h b/stepmania/src/arch/MemoryCard/MemoryCardDriverThreaded_Windows.h new file mode 100644 index 0000000000..92d7ed3764 --- /dev/null +++ b/stepmania/src/arch/MemoryCard/MemoryCardDriverThreaded_Windows.h @@ -0,0 +1,23 @@ +#ifndef MemoryCardDriverThreaded_Windows_H +#define MemoryCardDriverThreaded_Windows_H 1 + +#include "MemoryCardDriverThreaded.h" + +class MemoryCardDriverThreaded_Windows : public MemoryCardDriverThreaded +{ +public: + MemoryCardDriverThreaded_Windows(); + + virtual void Unmount( UsbStorageDevice* pDevice, CString sMountPoint ); + virtual void Flush( UsbStorageDevice* pDevice ); +protected: + virtual void MountThreadMain(); + virtual void Mount( UsbStorageDevice* pDevice, CString sMountPoint ); +}; + +#endif + +/* + * Copyright (c) 2003 by the person(s) listed below. All rights reserved. + * Chris Danford + */ diff --git a/stepmania/src/arch/arch.cpp b/stepmania/src/arch/arch.cpp index c9dca82e67..2aac17c8ce 100644 --- a/stepmania/src/arch/arch.cpp +++ b/stepmania/src/arch/arch.cpp @@ -161,7 +161,7 @@ MemoryCardDriver *MakeMemoryCardDriver() #ifdef LINUX ret = new MemoryCardDriver_Linux; #elif _WINDOWS - ret = new MemoryCardDriver_Windows; + ret = new MemoryCardDriverThreaded_Windows; #endif if( !ret ) ret = new MemoryCardDriver_Null; diff --git a/stepmania/src/arch/arch_Win32.h b/stepmania/src/arch/arch_Win32.h index d28af2946f..3c18cad9f2 100644 --- a/stepmania/src/arch/arch_Win32.h +++ b/stepmania/src/arch/arch_Win32.h @@ -15,7 +15,7 @@ #include "Lights/LightsDriver_Win32Parallel.h" -#include "MemoryCard/MemoryCardDriver_Windows.h" +#include "MemoryCard/MemoryCardDriverThreaded_Windows.h" #define HAVE_FFMPEG #undef SUPPORT_SDL_INPUT