From e544dd59154d2d123ec74c778176bdb995ae7f08 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Axel=20D=C3=B6rfler?= Date: Fri, 19 Oct 2007 15:20:36 +0000 Subject: [PATCH] * 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 --- .../kernel/disk_device_manager/KDiskDevice.h | 4 ++- .../disk_device_manager/KDiskDevice.cpp | 19 ++++++++++- .../KDiskDeviceManager.cpp | 33 +++++-------------- 3 files changed, 30 insertions(+), 26 deletions(-) diff --git a/headers/private/kernel/disk_device_manager/KDiskDevice.h b/headers/private/kernel/disk_device_manager/KDiskDevice.h index 47105770c4..4397fdb72d 100644 --- a/headers/private/kernel/disk_device_manager/KDiskDevice.h +++ b/headers/private/kernel/disk_device_manager/KDiskDevice.h @@ -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: diff --git a/src/system/kernel/disk_device_manager/KDiskDevice.cpp b/src/system/kernel/disk_device_manager/KDiskDevice.cpp index 62ce05c26b..62a685e818 100644 --- a/src/system/kernel/disk_device_manager/KDiskDevice.cpp +++ b/src/system/kernel/disk_device_manager/KDiskDevice.cpp @@ -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) diff --git a/src/system/kernel/disk_device_manager/KDiskDeviceManager.cpp b/src/system/kernel/disk_device_manager/KDiskDeviceManager.cpp index 19be2393ae..1104bd8e80 100644 --- a/src/system/kernel/disk_device_manager/KDiskDeviceManager.cpp +++ b/src/system/kernel/disk_device_manager/KDiskDeviceManager.cpp @@ -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(); }