* 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:
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2008, Axel Dörfler, [email protected]. All rights reserved.
|
* Copyright 2008-2009, Axel Dörfler, [email protected].
|
||||||
* Distributed under the terms of the MIT License.
|
* Distributed under the terms of the MIT License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -33,3 +33,9 @@ void
|
|||||||
BaseDevice::UninitDevice()
|
BaseDevice::UninitDevice()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
BaseDevice::Removed()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2008, Axel Dörfler, [email protected]. All rights reserved.
|
* Copyright 2008-2009, Axel Dörfler, [email protected].
|
||||||
* Distributed under the terms of the MIT License.
|
* Distributed under the terms of the MIT License.
|
||||||
*/
|
*/
|
||||||
#ifndef BASE_DEVICE_H
|
#ifndef BASE_DEVICE_H
|
||||||
@@ -22,6 +22,8 @@ public:
|
|||||||
virtual status_t InitDevice();
|
virtual status_t InitDevice();
|
||||||
virtual void UninitDevice();
|
virtual void UninitDevice();
|
||||||
|
|
||||||
|
virtual void Removed();
|
||||||
|
|
||||||
device_module_info* Module() const { return fDeviceModule; }
|
device_module_info* Module() const { return fDeviceModule; }
|
||||||
void* Data() const { return fDeviceData; }
|
void* Data() const { return fDeviceData; }
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2002-2008, Axel Dörfler, [email protected]. All rights reserved.
|
* Copyright 2002-2009, Axel Dörfler, [email protected].
|
||||||
* Distributed under the terms of the MIT License.
|
* Distributed under the terms of the MIT License.
|
||||||
*
|
*
|
||||||
* Copyright 2001-2002, Travis Geiselbrecht. All rights reserved.
|
* 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);
|
hash_remove(fs->vnode_hash, vnode);
|
||||||
|
|
||||||
if (S_ISCHR(vnode->stream.type)) {
|
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
|
// for partitions, we have to release the raw device but must
|
||||||
// not free the device info as it was inherited from the raw
|
// not free the device info as it was inherited from the raw
|
||||||
// device and is still in use there
|
// device and is still in use there
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2008, Axel Dörfler, [email protected]. All rights reserved.
|
* Copyright 2008-2009, Axel Dörfler, [email protected].
|
||||||
* Distributed under the terms of the MIT License.
|
* Distributed under the terms of the MIT License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -84,8 +84,14 @@ public:
|
|||||||
virtual status_t InitDevice();
|
virtual status_t InitDevice();
|
||||||
virtual void UninitDevice();
|
virtual void UninitDevice();
|
||||||
|
|
||||||
|
virtual void Removed();
|
||||||
|
|
||||||
|
void SetRemovedFromParent(bool removed)
|
||||||
|
{ fRemovedFromParent = removed; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const char* fModuleName;
|
const char* fModuleName;
|
||||||
|
bool fRemovedFromParent;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef DoublyLinkedList<Device> DeviceList;
|
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)
|
Device::Device(device_node* node, const char* moduleName)
|
||||||
|
:
|
||||||
|
fRemovedFromParent(false)
|
||||||
{
|
{
|
||||||
fNode = node;
|
fNode = node;
|
||||||
fModuleName = strdup(moduleName);
|
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
|
// #pragma mark - device_node
|
||||||
|
|
||||||
|
|
||||||
@@ -1201,8 +1221,8 @@ device_node::~device_node()
|
|||||||
|
|
||||||
// Delete devices
|
// Delete devices
|
||||||
while (Device* device = fDevices.RemoveHead()) {
|
while (Device* device = fDevices.RemoveHead()) {
|
||||||
|
device->SetRemovedFromParent(true);
|
||||||
devfs_unpublish_device(device, true);
|
devfs_unpublish_device(device, true);
|
||||||
delete device;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Delete attributes
|
// 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.
|
* Distributed under the terms of the MIT License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -54,6 +54,8 @@ public:
|
|||||||
virtual status_t InitDevice();
|
virtual status_t InitDevice();
|
||||||
virtual void UninitDevice();
|
virtual void UninitDevice();
|
||||||
|
|
||||||
|
virtual void Removed();
|
||||||
|
|
||||||
void SetHooks(device_hooks* hooks);
|
void SetHooks(device_hooks* hooks);
|
||||||
|
|
||||||
legacy_driver* Driver() const { return fDriver; }
|
legacy_driver* Driver() const { return fDriver; }
|
||||||
@@ -67,11 +69,16 @@ public:
|
|||||||
bool Republished() const { return fRepublished; }
|
bool Republished() const { return fRepublished; }
|
||||||
void SetRepublished(bool republished)
|
void SetRepublished(bool republished)
|
||||||
{ fRepublished = republished; }
|
{ fRepublished = republished; }
|
||||||
|
|
||||||
|
void SetRemovedFromParent(bool removed)
|
||||||
|
{ fRemovedFromParent = removed; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
legacy_driver* fDriver;
|
legacy_driver* fDriver;
|
||||||
const char* fPath;
|
const char* fPath;
|
||||||
device_hooks* fHooks;
|
device_hooks* fHooks;
|
||||||
bool fRepublished;
|
bool fRepublished;
|
||||||
|
bool fRemovedFromParent;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef DoublyLinkedList<LegacyDevice> DeviceList;
|
typedef DoublyLinkedList<LegacyDevice> DeviceList;
|
||||||
@@ -284,9 +291,9 @@ republish_driver(legacy_driver* driver)
|
|||||||
|
|
||||||
TRACE(("devfs: unpublishing no more present \"%s\"\n", device->Path()));
|
TRACE(("devfs: unpublishing no more present \"%s\"\n", device->Path()));
|
||||||
iterator.Remove();
|
iterator.Remove();
|
||||||
|
device->SetRemovedFromParent(true);
|
||||||
|
|
||||||
devfs_unpublish_device(device, true);
|
devfs_unpublish_device(device, true);
|
||||||
delete device;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (exported == 0) {
|
if (exported == 0) {
|
||||||
@@ -430,8 +437,8 @@ static void
|
|||||||
unpublish_driver(legacy_driver *driver)
|
unpublish_driver(legacy_driver *driver)
|
||||||
{
|
{
|
||||||
while (LegacyDevice* device = driver->devices.RemoveHead()) {
|
while (LegacyDevice* device = driver->devices.RemoveHead()) {
|
||||||
if (devfs_unpublish_device(device, true) == B_OK)
|
device->SetRemovedFromParent(true);
|
||||||
delete device;
|
devfs_unpublish_device(device, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1109,7 +1116,8 @@ LegacyDevice::LegacyDevice(legacy_driver* driver, const char* path,
|
|||||||
device_hooks* hooks)
|
device_hooks* hooks)
|
||||||
:
|
:
|
||||||
fDriver(driver),
|
fDriver(driver),
|
||||||
fRepublished(true)
|
fRepublished(true),
|
||||||
|
fRemovedFromParent(false)
|
||||||
{
|
{
|
||||||
fDeviceModule = (device_module_info*)malloc(sizeof(device_module_info));
|
fDeviceModule = (device_module_info*)malloc(sizeof(device_module_info));
|
||||||
if (fDeviceModule != NULL)
|
if (fDeviceModule != NULL)
|
||||||
@@ -1171,6 +1179,18 @@ LegacyDevice::UninitDevice()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
LegacyDevice::Removed()
|
||||||
|
{
|
||||||
|
RecursiveLocker _(sLock);
|
||||||
|
|
||||||
|
if (!fRemovedFromParent)
|
||||||
|
fDriver->devices.Remove(this);
|
||||||
|
|
||||||
|
delete this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
LegacyDevice::SetHooks(device_hooks* hooks)
|
LegacyDevice::SetHooks(device_hooks* hooks)
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user