* Instead of deleting the device directly, we now only remove it from its
parent. * Additionally, when a vnode is deleted, the new BaseDevice::Removed() method is called that will remove the device from its parent if needed, and delete it then. * This should fix #3856. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@30726 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
3aa9a86343
commit
6015793f57
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2008, Axel Dörfler, axeld@pinc-software.de. All rights reserved.
|
||||
* Copyright 2008-2009, Axel Dörfler, axeld@pinc-software.de.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
|
||||
@ -33,3 +33,9 @@ void
|
||||
BaseDevice::UninitDevice()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
BaseDevice::Removed()
|
||||
{
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2008, Axel Dörfler, axeld@pinc-software.de. All rights reserved.
|
||||
* Copyright 2008-2009, Axel Dörfler, axeld@pinc-software.de.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef BASE_DEVICE_H
|
||||
@ -22,6 +22,8 @@ public:
|
||||
virtual status_t InitDevice();
|
||||
virtual void UninitDevice();
|
||||
|
||||
virtual void Removed();
|
||||
|
||||
device_module_info* Module() const { return fDeviceModule; }
|
||||
void* Data() const { return fDeviceData; }
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2008, Axel Dörfler, axeld@pinc-software.de. All rights reserved.
|
||||
* Copyright 2002-2009, Axel Dörfler, axeld@pinc-software.de.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Copyright 2001-2002, Travis Geiselbrecht. All rights reserved.
|
||||
@ -252,6 +252,9 @@ devfs_delete_vnode(struct devfs* fs, struct devfs_vnode* vnode,
|
||||
hash_remove(fs->vnode_hash, vnode);
|
||||
|
||||
if (S_ISCHR(vnode->stream.type)) {
|
||||
// pass the call through to the underlying device
|
||||
vnode->stream.u.dev.device->Removed();
|
||||
|
||||
// for partitions, we have to release the raw device but must
|
||||
// not free the device info as it was inherited from the raw
|
||||
// device and is still in use there
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2008, Axel Dörfler, axeld@pinc-software.de. All rights reserved.
|
||||
* Copyright 2008-2009, Axel Dörfler, axeld@pinc-software.de.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
|
||||
@ -84,8 +84,14 @@ public:
|
||||
virtual status_t InitDevice();
|
||||
virtual void UninitDevice();
|
||||
|
||||
virtual void Removed();
|
||||
|
||||
void SetRemovedFromParent(bool removed)
|
||||
{ fRemovedFromParent = removed; }
|
||||
|
||||
private:
|
||||
const char* fModuleName;
|
||||
bool fRemovedFromParent;
|
||||
};
|
||||
|
||||
typedef DoublyLinkedList<Device> DeviceList;
|
||||
@ -1057,6 +1063,8 @@ device_attr_private::Compare(const device_attr* attrA, const device_attr *attrB)
|
||||
|
||||
|
||||
Device::Device(device_node* node, const char* moduleName)
|
||||
:
|
||||
fRemovedFromParent(false)
|
||||
{
|
||||
fNode = node;
|
||||
fModuleName = strdup(moduleName);
|
||||
@ -1144,6 +1152,18 @@ Device::UninitDevice()
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Device::Removed()
|
||||
{
|
||||
RecursiveLocker _(sLock);
|
||||
|
||||
if (!fRemovedFromParent)
|
||||
fNode->RemoveDevice(this);
|
||||
|
||||
delete this;
|
||||
}
|
||||
|
||||
|
||||
// #pragma mark - device_node
|
||||
|
||||
|
||||
@ -1201,8 +1221,8 @@ device_node::~device_node()
|
||||
|
||||
// Delete devices
|
||||
while (Device* device = fDevices.RemoveHead()) {
|
||||
device->SetRemovedFromParent(true);
|
||||
devfs_unpublish_device(device, true);
|
||||
delete device;
|
||||
}
|
||||
|
||||
// Delete attributes
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2009, Axel Dörfler, axeld@pinc-software.de. All rights reserved.
|
||||
* Copyright 2002-2009, Axel Dörfler, axeld@pinc-software.de.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
|
||||
@ -54,6 +54,8 @@ public:
|
||||
virtual status_t InitDevice();
|
||||
virtual void UninitDevice();
|
||||
|
||||
virtual void Removed();
|
||||
|
||||
void SetHooks(device_hooks* hooks);
|
||||
|
||||
legacy_driver* Driver() const { return fDriver; }
|
||||
@ -67,11 +69,16 @@ public:
|
||||
bool Republished() const { return fRepublished; }
|
||||
void SetRepublished(bool republished)
|
||||
{ fRepublished = republished; }
|
||||
|
||||
void SetRemovedFromParent(bool removed)
|
||||
{ fRemovedFromParent = removed; }
|
||||
|
||||
private:
|
||||
legacy_driver* fDriver;
|
||||
const char* fPath;
|
||||
device_hooks* fHooks;
|
||||
bool fRepublished;
|
||||
bool fRemovedFromParent;
|
||||
};
|
||||
|
||||
typedef DoublyLinkedList<LegacyDevice> DeviceList;
|
||||
@ -284,9 +291,9 @@ republish_driver(legacy_driver* driver)
|
||||
|
||||
TRACE(("devfs: unpublishing no more present \"%s\"\n", device->Path()));
|
||||
iterator.Remove();
|
||||
device->SetRemovedFromParent(true);
|
||||
|
||||
devfs_unpublish_device(device, true);
|
||||
delete device;
|
||||
}
|
||||
|
||||
if (exported == 0) {
|
||||
@ -430,8 +437,8 @@ static void
|
||||
unpublish_driver(legacy_driver *driver)
|
||||
{
|
||||
while (LegacyDevice* device = driver->devices.RemoveHead()) {
|
||||
if (devfs_unpublish_device(device, true) == B_OK)
|
||||
delete device;
|
||||
device->SetRemovedFromParent(true);
|
||||
devfs_unpublish_device(device, true);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1109,7 +1116,8 @@ LegacyDevice::LegacyDevice(legacy_driver* driver, const char* path,
|
||||
device_hooks* hooks)
|
||||
:
|
||||
fDriver(driver),
|
||||
fRepublished(true)
|
||||
fRepublished(true),
|
||||
fRemovedFromParent(false)
|
||||
{
|
||||
fDeviceModule = (device_module_info*)malloc(sizeof(device_module_info));
|
||||
if (fDeviceModule != NULL)
|
||||
@ -1171,6 +1179,18 @@ LegacyDevice::UninitDevice()
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
LegacyDevice::Removed()
|
||||
{
|
||||
RecursiveLocker _(sLock);
|
||||
|
||||
if (!fRemovedFromParent)
|
||||
fDriver->devices.Remove(this);
|
||||
|
||||
delete this;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
LegacyDevice::SetHooks(device_hooks* hooks)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user