Skip to content

Commit

Permalink
[Peripheral] Fix early lock.Leave() in UnregisterRemovedDevices in Pe…
Browse files Browse the repository at this point in the history
…ripheralBus.cpp and call OnDeviceRemoved for devices with features.

CriticalSection was unlocked inside 'for', could potentially cause problem in case that other thread change list of peripheral.
OnDeviceRemoved wasn't called for devices with type == UNKNOWN even if device is mapped to something with usable feature.
  • Loading branch information
Karlson2k committed Oct 1, 2012
1 parent 5465992 commit 86bf90f
Showing 1 changed file with 18 additions and 8 deletions.
26 changes: 18 additions & 8 deletions xbmc/peripherals/bus/PeripheralBus.cpp
Expand Up @@ -133,6 +133,7 @@ void CPeripheralBus::Clear(void)
void CPeripheralBus::UnregisterRemovedDevices(const PeripheralScanResults &results)
{
CSingleLock lock(m_critSection);
vector<CPeripheral *> removedPeripherals;
for (int iDevicePtr = (int) m_peripherals.size() - 1; iDevicePtr >= 0; iDevicePtr--)
{
CPeripheral *peripheral = m_peripherals.at(iDevicePtr);
Expand All @@ -141,17 +142,26 @@ void CPeripheralBus::UnregisterRemovedDevices(const PeripheralScanResults &resul
updatedDevice != *peripheral)
{
/* device removed */
if (peripheral->Type() != PERIPHERAL_UNKNOWN)
{
CLog::Log(LOGNOTICE, "%s - device removed from %s/%s: %s (%s:%s)", __FUNCTION__, PeripheralTypeTranslator::TypeToString(peripheral->Type()), peripheral->Location().c_str(), peripheral->DeviceName().c_str(), peripheral->VendorIdAsString(), peripheral->ProductIdAsString());
peripheral->OnDeviceRemoved();
}
removedPeripherals.push_back(peripheral);
m_peripherals.erase(m_peripherals.begin() + iDevicePtr);
lock.Leave();
}
}
lock.Leave();

m_manager->OnDeviceDeleted(*this, *peripheral);
delete peripheral;
for (unsigned int iDevicePtr = 0; iDevicePtr < removedPeripherals.size(); iDevicePtr++)
{
CPeripheral *peripheral = removedPeripherals.at(iDevicePtr);
vector<PeripheralFeature> features;
peripheral->GetFeatures(features);
bool peripheralHasFeatures = features.size() > 1 || (features.size() == 1 && features.at(0) != FEATURE_UNKNOWN);
if (peripheral->Type() != PERIPHERAL_UNKNOWN || peripheralHasFeatures)
{
CLog::Log(LOGNOTICE, "%s - device removed from %s/%s: %s (%s:%s)", __FUNCTION__, PeripheralTypeTranslator::TypeToString(peripheral->Type()), peripheral->Location().c_str(), peripheral->DeviceName().c_str(), peripheral->VendorIdAsString(), peripheral->ProductIdAsString());
peripheral->OnDeviceRemoved();
}

m_manager->OnDeviceDeleted(*this, *peripheral);
delete peripheral;
}
}

Expand Down

0 comments on commit 86bf90f

Please sign in to comment.