Previously, the main mount loop was unlocking the thread and then immediately
re-locking it. In some threads implementations (Linux 2.6), this causes the mount thread to hog the lock, which causes SetMountThreadState to hang. Move the "check and delay" part of the mount thread outside of the lock, so other threads have opportunity to get the lock.
This commit is contained in:
@@ -79,11 +79,20 @@ void MemoryCardDriverThreaded::MountThreadMain()
|
|||||||
|
|
||||||
while( !m_bShutdownNextUpdate )
|
while( !m_bShutdownNextUpdate )
|
||||||
{
|
{
|
||||||
|
if( !this->MountThreadWaitForUpdate() )
|
||||||
|
continue;
|
||||||
|
|
||||||
LockMut( m_mutexPause ); // wait until we're unpaused
|
LockMut( m_mutexPause ); // wait until we're unpaused
|
||||||
this->MountThreadDoOneUpdate();
|
this->MountThreadDoOneUpdate();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool MemoryCardDriverThreaded::MountThreadWaitForUpdate()
|
||||||
|
{
|
||||||
|
usleep( 100000 );
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
bool MemoryCardDriverThreaded::StorageDevicesChanged()
|
bool MemoryCardDriverThreaded::StorageDevicesChanged()
|
||||||
{
|
{
|
||||||
CHECKPOINT;
|
CHECKPOINT;
|
||||||
|
|||||||
@@ -33,6 +33,7 @@ protected:
|
|||||||
void StartThread(); // call this in the derived constructor to start the mounting thread
|
void StartThread(); // call this in the derived constructor to start the mounting thread
|
||||||
void StopThread(); // call this in the derived desstructor to stop the mounting thread
|
void StopThread(); // call this in the derived desstructor to stop the mounting thread
|
||||||
virtual void MountThreadDoOneUpdate() = 0; // this will get called as fast as possible
|
virtual void MountThreadDoOneUpdate() = 0; // this will get called as fast as possible
|
||||||
|
virtual bool MountThreadWaitForUpdate();
|
||||||
virtual void Mount( UsbStorageDevice* pDevice, CString sMountPoint ) = 0;
|
virtual void Mount( UsbStorageDevice* pDevice, CString sMountPoint ) = 0;
|
||||||
bool ShouldDoOsMount() { return m_MountThreadState==detect_and_mount; }
|
bool ShouldDoOsMount() { return m_MountThreadState==detect_and_mount; }
|
||||||
|
|
||||||
|
|||||||
@@ -187,32 +187,29 @@ bool UsbStorageDevicesChanged()
|
|||||||
return bChanged;
|
return bChanged;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MemoryCardDriverThreaded_Linux::MountThreadDoOneUpdate()
|
/* Return true if MountThreadDoOneUpdate should be called. */
|
||||||
|
bool MemoryCardDriverThreaded_Linux::MountThreadWaitForUpdate()
|
||||||
{
|
{
|
||||||
bool bNeedToDoAnyMounts = false;
|
/* Check if any devices need a write test. */
|
||||||
for( unsigned i=0; i<m_vDevicesLastSeen.size(); i++ )
|
for( unsigned i=0; i<m_vDevicesLastSeen.size(); i++ )
|
||||||
{
|
{
|
||||||
UsbStorageDevice &d = m_vDevicesLastSeen[i];
|
UsbStorageDevice &d = m_vDevicesLastSeen[i];
|
||||||
if( d.bNeedsWriteTest )
|
if( d.bNeedsWriteTest )
|
||||||
{
|
return true;
|
||||||
bNeedToDoAnyMounts = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if( bNeedToDoAnyMounts )
|
/* Nothing needs a write test. If no devices have changed, either,
|
||||||
{
|
* delay. */
|
||||||
// fall through
|
if( UsbStorageDevicesChanged() )
|
||||||
}
|
return true;
|
||||||
else
|
|
||||||
{
|
|
||||||
if( !UsbStorageDevicesChanged() )
|
|
||||||
{
|
|
||||||
usleep(1000*300); // 300 ms
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
/* Nothing to do. Delay, so we don't busy loop. */
|
||||||
|
usleep(1000*300); // 300 ms
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MemoryCardDriverThreaded_Linux::MountThreadDoOneUpdate()
|
||||||
|
{
|
||||||
// TRICKY: We're waiting for a change in the USB device list, but
|
// TRICKY: We're waiting for a change in the USB device list, but
|
||||||
// the usb-storage descriptors take a bit longer to update. It's more convenient to wait
|
// the usb-storage descriptors take a bit longer to update. It's more convenient to wait
|
||||||
// on the USB device list because the usb-storage descriptors are separate files per
|
// on the USB device list because the usb-storage descriptors are separate files per
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ protected:
|
|||||||
virtual void Mount( UsbStorageDevice* pDevice, CString sMountPoint );
|
virtual void Mount( UsbStorageDevice* pDevice, CString sMountPoint );
|
||||||
virtual void ResetUsbStorage();
|
virtual void ResetUsbStorage();
|
||||||
virtual void MountThreadDoOneUpdate();
|
virtual void MountThreadDoOneUpdate();
|
||||||
|
virtual bool MountThreadWaitForUpdate();
|
||||||
|
|
||||||
vector<UsbStorageDevice> m_vDevicesLastSeen;
|
vector<UsbStorageDevice> m_vDevicesLastSeen;
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user