* Greatly simplified republish_driver(); it doesn't need to use the path_entry

stuff at all, anymore.
* Removed now unused get_device_for_path().
* unpublish_driver() now only deletes the device if unpublishing actually
  worked out okay.
* Minor cleanup.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@27038 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Axel Dörfler
2008-08-18 12:36:27 +00:00
parent 8ec35e364a
commit f15da085fb
@@ -64,10 +64,14 @@ public:
void** _cookie); void** _cookie);
virtual status_t Select(void* cookie, uint8 event, selectsync* sync); virtual status_t Select(void* cookie, uint8 event, selectsync* sync);
bool Republished() const { return fRepublished; }
void SetRepublished(bool republished)
{ fRepublished = republished; }
private: private:
legacy_driver* fDriver; legacy_driver* fDriver;
const char* fPath; const char* fPath;
device_hooks* fHooks; device_hooks* fHooks;
bool fRepublished;
}; };
typedef DoublyLinkedList<LegacyDevice> DeviceList; typedef DoublyLinkedList<LegacyDevice> DeviceList;
@@ -213,21 +217,6 @@ driver_entry_compare(void *_driver, const void *_key)
} }
static LegacyDevice*
get_device_for_path(legacy_driver* driver, const char* path)
{
DeviceList::Iterator iterator = driver->devices.GetIterator();
while (iterator.HasNext()) {
LegacyDevice* device = iterator.Next();
if (!strcmp(device->Path(), path))
return device;
}
return NULL;
}
/*! Collects all published devices of a driver, compares them to what the /*! Collects all published devices of a driver, compares them to what the
driver would publish now, and then publishes/unpublishes the devices driver would publish now, and then publishes/unpublishes the devices
as needed. as needed.
@@ -241,59 +230,42 @@ republish_driver(legacy_driver* driver)
return load_driver(driver); return load_driver(driver);
} }
// build the list of currently present devices of this driver // mark all devices
DeviceList::Iterator iterator = driver->devices.GetIterator(); DeviceList::Iterator iterator = driver->devices.GetIterator();
DoublyLinkedList<path_entry> currentNodes; while (LegacyDevice* device = iterator.Next()) {
while (iterator.HasNext()) { device->SetRepublished(false);
LegacyDevice* device = iterator.Next();
path_entry* entry = new(std::nothrow) path_entry;
if (entry == NULL) {
while ((entry = currentNodes.RemoveHead()))
delete entry;
return B_NO_MEMORY;
}
strlcpy(entry->path, device->Path(), sizeof(entry->path));
currentNodes.Add(entry);
} }
// now ask the driver for it's currently published devices // now ask the driver for it's currently published devices
const char **devicePaths = driver->publish_devices(); const char** devicePaths = driver->publish_devices();
int32 exported = 0; int32 exported = 0;
for (; devicePaths != NULL && devicePaths[0]; devicePaths++) { for (; devicePaths != NULL && devicePaths[0]; devicePaths++) {
bool present = false; LegacyDevice* device;
path_entry *entry = currentNodes.Head();
while (entry) { iterator = driver->devices.GetIterator();
if (strncmp(entry->path, devicePaths[0], B_PATH_NAME_LENGTH) == 0) { while ((device = iterator.Next()) != NULL) {
// this device was present before and still is -> no republish if (!strncmp(device->Path(), devicePaths[0], B_PATH_NAME_LENGTH)) {
currentNodes.Remove(entry); // mark device as republished
delete entry; device->SetRepublished(true);
exported++; exported++;
present = true;
break; break;
} }
entry = currentNodes.GetNext(entry);
} }
device_hooks *hooks = driver->find_device(devicePaths[0]); device_hooks* hooks = driver->find_device(devicePaths[0]);
if (hooks == NULL) if (hooks == NULL)
continue; continue;
if (present) { if (device != NULL) {
// update hooks // update hooks
LegacyDevice* device = get_device_for_path(driver, devicePaths[0]); device->SetHooks(hooks);
if (device != NULL)
device->SetHooks(hooks);
continue; continue;
} }
// the device was not present before -> publish it now // the device was not present before -> publish it now
TRACE(("devfs: publishing new device \"%s\"\n", devicePaths[0])); TRACE(("devfs: publishing new device \"%s\"\n", devicePaths[0]));
LegacyDevice* device = new(std::nothrow) LegacyDevice(driver, device = new(std::nothrow) LegacyDevice(driver, devicePaths[0], hooks);
devicePaths[0], hooks);
if (device != NULL && device->InitCheck() == B_OK if (device != NULL && device->InitCheck() == B_OK
&& devfs_publish_device(devicePaths[0], device) == B_OK) { && devfs_publish_device(devicePaths[0], device) == B_OK) {
driver->devices.Add(device); driver->devices.Add(device);
@@ -302,24 +274,22 @@ republish_driver(legacy_driver* driver)
delete device; delete device;
} }
// what's left in currentNodes was present but is not anymore -> unpublish // remove all devices that weren't republished
while (true) { iterator = driver->devices.GetIterator();
path_entry *entry = currentNodes.RemoveHead(); while (LegacyDevice* device = iterator.Next()) {
if (entry == NULL) if (device->Republished())
break; continue;
TRACE(("devfs: unpublishing no more present \"%s\"\n", entry->path)); TRACE(("devfs: unpublishing no more present \"%s\"\n", device->Path()));
LegacyDevice* device = get_device_for_path(driver, entry->path); iterator.Remove();
if (device != NULL)
driver->devices.Remove(device);
devfs_unpublish_device(entry->path, true); devfs_unpublish_device(device, true);
delete device; delete device;
delete entry;
} }
if (exported == 0) { if (exported == 0) {
TRACE(("devfs: driver \"%s\" does not publish any more nodes and is unloaded\n", driver->path)); TRACE(("devfs: driver \"%s\" does not publish any more nodes and is "
"unloaded\n", driver->path));
unload_driver(driver); unload_driver(driver);
} }
@@ -458,8 +428,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()) {
devfs_unpublish_device(device, true); if (devfs_unpublish_device(device, true) == B_OK)
delete device; delete device;
} }
} }
@@ -550,7 +520,7 @@ add_driver(const char *path, image_id image)
// isn't the same anymore so rescanning of drivers will work in // isn't the same anymore so rescanning of drivers will work in
// case this driver was loaded so early that it has a boot module // case this driver was loaded so early that it has a boot module
// path and not a proper driver path // path and not a proper driver path
free((char *)driver->path); free((char*)driver->path);
driver->path = strdup(path); driver->path = strdup(path);
driver->name = get_leaf(driver->path); driver->name = get_leaf(driver->path);
driver->binary_updated = true; driver->binary_updated = true;
@@ -652,7 +622,7 @@ handle_driver_events(void */*_fs*/, int /*iteration*/)
RecursiveLocker locker(sLock); RecursiveLocker locker(sLock);
while (true) { while (true) {
path_entry *path = sDriversToAdd.RemoveHead(); path_entry* path = sDriversToAdd.RemoveHead();
if (path == NULL) if (path == NULL)
break; break;
@@ -679,17 +649,17 @@ handle_driver_events(void */*_fs*/, int /*iteration*/)
static void static void
driver_added(const char *path) driver_added(const char* path)
{ {
int32 priority = get_priority(path); int32 priority = get_priority(path);
RecursiveLocker locker(sLock); RecursiveLocker locker(sLock);
legacy_driver *driver = (legacy_driver *)hash_lookup(sDriverHash, legacy_driver* driver = (legacy_driver*)hash_lookup(sDriverHash,
get_leaf(path)); get_leaf(path));
if (driver == NULL) { if (driver == NULL) {
// Add the driver to our list // Add the driver to our list
path_entry *entry = new(std::nothrow) path_entry; path_entry* entry = new(std::nothrow) path_entry;
if (entry == NULL) if (entry == NULL)
return; return;
@@ -1155,7 +1125,8 @@ probe_for_drivers(const char *type)
LegacyDevice::LegacyDevice(legacy_driver* driver, const char* path, LegacyDevice::LegacyDevice(legacy_driver* driver, const char* path,
device_hooks* hooks) device_hooks* hooks)
: :
fDriver(driver) fDriver(driver),
fRepublished(true)
{ {
fDeviceModule = (device_module_info*)malloc(sizeof(device_module_info)); fDeviceModule = (device_module_info*)malloc(sizeof(device_module_info));
if (fDeviceModule != NULL) if (fDeviceModule != NULL)