* Fixed a possible dead lock between the kernel daemon and the DDM; the media

status checker now only tries to lock the manager, it won't wait anymore.
* Added MediaChanged() and UpdateMediaStatusIfNeeded() methods to KDiskDevice.
* KDiskDeviceManager::_CheckMediaStatus() now uses these new methods; it should
  no longer detect removed media more than once :-)


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@22621 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Axel Dörfler
2007-10-19 15:20:36 +00:00
parent c70623faaf
commit e544dd5915
3 changed files with 30 additions and 26 deletions
@@ -51,8 +51,9 @@ public:
bool IsWriteOnce() const;
bool IsRemovable() const;
bool HasMedia() const;
bool MediaChanged() const;
virtual status_t GetMediaStatus(status_t *mediaStatus);
void UpdateMediaStatusIfNeeded();
status_t SetPath(const char *path);
// TODO: Remove this method or make it private. Once initialized the
@@ -81,6 +82,7 @@ public:
virtual void Dump(bool deep = true, int32 level = 0);
protected:
virtual status_t GetMediaStatus(status_t *mediaStatus);
virtual status_t GetGeometry(device_geometry *geometry);
private:
@@ -239,9 +239,26 @@ KDiskDevice::IsRemovable() const
bool
KDiskDevice::HasMedia() const
{
return (fMediaStatus == B_OK);
return fMediaStatus == B_OK || fMediaStatus == B_DEV_MEDIA_CHANGED;
}
bool
KDiskDevice::MediaChanged() const
{
return fMediaStatus == B_DEV_MEDIA_CHANGED;
}
void
KDiskDevice::UpdateMediaStatusIfNeeded()
{
// TODO: allow a device to notify us about its media status!
// This will then also need to clear any B_DEV_MEDIA_CHANGED
GetMediaStatus(&fMediaStatus);
}
// SetPath
status_t
KDiskDevice::SetPath(const char *path)
@@ -1252,8 +1252,7 @@ KDiskDeviceManager::_ScanPartition(KPartition *partition, bool async)
void
KDiskDeviceManager::_CheckMediaStatus()
{
ManagerLocker locker(this);
if (!locker.IsLocked())
if (fLock.LockWithTimeout(0) != B_OK)
return;
int32 cookie = 0;
@@ -1262,32 +1261,18 @@ KDiskDeviceManager::_CheckMediaStatus()
if (device == NULL)
break;
status_t mediaStatus;
if (device->GetMediaStatus(&mediaStatus) == B_OK) {
bool removed = false;
bool changed = false;
bool hadMedia = device->HasMedia();
device->UpdateMediaStatusIfNeeded();
switch (mediaStatus) {
case B_DEV_MEDIA_CHANGED:
changed = true;
break;
case B_DEV_NO_MEDIA:
case B_DEV_DOOR_OPEN:
removed = true;
break;
case B_DEV_MEDIA_CHANGE_REQUESTED:
case B_DEV_NOT_READY:
case B_OK:
break;
}
// TODO: propagate changes!
if (removed)
dprintf("Media removed from %s\n", device->Path());
if (changed)
// TODO: propagate changes!
if (device->MediaChanged()) {
dprintf("Media changed from %s\n", device->Path());
} else if (!device->HasMedia() && hadMedia) {
dprintf("Media removed from %s\n", device->Path());
}
}
fLock.Unlock();
}