* 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:
parent
8ec35e364a
commit
f15da085fb
@ -64,10 +64,14 @@ public:
|
||||
void** _cookie);
|
||||
virtual status_t Select(void* cookie, uint8 event, selectsync* sync);
|
||||
|
||||
bool Republished() const { return fRepublished; }
|
||||
void SetRepublished(bool republished)
|
||||
{ fRepublished = republished; }
|
||||
private:
|
||||
legacy_driver* fDriver;
|
||||
const char* fPath;
|
||||
device_hooks* fHooks;
|
||||
bool fRepublished;
|
||||
};
|
||||
|
||||
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
|
||||
driver would publish now, and then publishes/unpublishes the devices
|
||||
as needed.
|
||||
@ -241,59 +230,42 @@ republish_driver(legacy_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();
|
||||
DoublyLinkedList<path_entry> currentNodes;
|
||||
while (iterator.HasNext()) {
|
||||
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);
|
||||
while (LegacyDevice* device = iterator.Next()) {
|
||||
device->SetRepublished(false);
|
||||
}
|
||||
|
||||
// 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;
|
||||
for (; devicePaths != NULL && devicePaths[0]; devicePaths++) {
|
||||
bool present = false;
|
||||
path_entry *entry = currentNodes.Head();
|
||||
while (entry) {
|
||||
if (strncmp(entry->path, devicePaths[0], B_PATH_NAME_LENGTH) == 0) {
|
||||
// this device was present before and still is -> no republish
|
||||
currentNodes.Remove(entry);
|
||||
delete entry;
|
||||
LegacyDevice* device;
|
||||
|
||||
iterator = driver->devices.GetIterator();
|
||||
while ((device = iterator.Next()) != NULL) {
|
||||
if (!strncmp(device->Path(), devicePaths[0], B_PATH_NAME_LENGTH)) {
|
||||
// mark device as republished
|
||||
device->SetRepublished(true);
|
||||
exported++;
|
||||
present = true;
|
||||
break;
|
||||
}
|
||||
|
||||
entry = currentNodes.GetNext(entry);
|
||||
}
|
||||
|
||||
device_hooks *hooks = driver->find_device(devicePaths[0]);
|
||||
device_hooks* hooks = driver->find_device(devicePaths[0]);
|
||||
if (hooks == NULL)
|
||||
continue;
|
||||
|
||||
if (present) {
|
||||
if (device != NULL) {
|
||||
// update hooks
|
||||
LegacyDevice* device = get_device_for_path(driver, devicePaths[0]);
|
||||
if (device != NULL)
|
||||
device->SetHooks(hooks);
|
||||
device->SetHooks(hooks);
|
||||
continue;
|
||||
}
|
||||
|
||||
// the device was not present before -> publish it now
|
||||
TRACE(("devfs: publishing new device \"%s\"\n", devicePaths[0]));
|
||||
LegacyDevice* device = new(std::nothrow) LegacyDevice(driver,
|
||||
devicePaths[0], hooks);
|
||||
device = new(std::nothrow) LegacyDevice(driver, devicePaths[0], hooks);
|
||||
if (device != NULL && device->InitCheck() == B_OK
|
||||
&& devfs_publish_device(devicePaths[0], device) == B_OK) {
|
||||
driver->devices.Add(device);
|
||||
@ -302,24 +274,22 @@ republish_driver(legacy_driver* driver)
|
||||
delete device;
|
||||
}
|
||||
|
||||
// what's left in currentNodes was present but is not anymore -> unpublish
|
||||
while (true) {
|
||||
path_entry *entry = currentNodes.RemoveHead();
|
||||
if (entry == NULL)
|
||||
break;
|
||||
// remove all devices that weren't republished
|
||||
iterator = driver->devices.GetIterator();
|
||||
while (LegacyDevice* device = iterator.Next()) {
|
||||
if (device->Republished())
|
||||
continue;
|
||||
|
||||
TRACE(("devfs: unpublishing no more present \"%s\"\n", entry->path));
|
||||
LegacyDevice* device = get_device_for_path(driver, entry->path);
|
||||
if (device != NULL)
|
||||
driver->devices.Remove(device);
|
||||
TRACE(("devfs: unpublishing no more present \"%s\"\n", device->Path()));
|
||||
iterator.Remove();
|
||||
|
||||
devfs_unpublish_device(entry->path, true);
|
||||
devfs_unpublish_device(device, true);
|
||||
delete device;
|
||||
delete entry;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
@ -458,8 +428,8 @@ static void
|
||||
unpublish_driver(legacy_driver *driver)
|
||||
{
|
||||
while (LegacyDevice* device = driver->devices.RemoveHead()) {
|
||||
devfs_unpublish_device(device, true);
|
||||
delete device;
|
||||
if (devfs_unpublish_device(device, true) == B_OK)
|
||||
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
|
||||
// case this driver was loaded so early that it has a boot module
|
||||
// path and not a proper driver path
|
||||
free((char *)driver->path);
|
||||
free((char*)driver->path);
|
||||
driver->path = strdup(path);
|
||||
driver->name = get_leaf(driver->path);
|
||||
driver->binary_updated = true;
|
||||
@ -652,7 +622,7 @@ handle_driver_events(void */*_fs*/, int /*iteration*/)
|
||||
RecursiveLocker locker(sLock);
|
||||
|
||||
while (true) {
|
||||
path_entry *path = sDriversToAdd.RemoveHead();
|
||||
path_entry* path = sDriversToAdd.RemoveHead();
|
||||
if (path == NULL)
|
||||
break;
|
||||
|
||||
@ -679,17 +649,17 @@ handle_driver_events(void */*_fs*/, int /*iteration*/)
|
||||
|
||||
|
||||
static void
|
||||
driver_added(const char *path)
|
||||
driver_added(const char* path)
|
||||
{
|
||||
int32 priority = get_priority(path);
|
||||
RecursiveLocker locker(sLock);
|
||||
|
||||
legacy_driver *driver = (legacy_driver *)hash_lookup(sDriverHash,
|
||||
legacy_driver* driver = (legacy_driver*)hash_lookup(sDriverHash,
|
||||
get_leaf(path));
|
||||
|
||||
if (driver == NULL) {
|
||||
// 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)
|
||||
return;
|
||||
|
||||
@ -1155,7 +1125,8 @@ probe_for_drivers(const char *type)
|
||||
LegacyDevice::LegacyDevice(legacy_driver* driver, const char* path,
|
||||
device_hooks* hooks)
|
||||
:
|
||||
fDriver(driver)
|
||||
fDriver(driver),
|
||||
fRepublished(true)
|
||||
{
|
||||
fDeviceModule = (device_module_info*)malloc(sizeof(device_module_info));
|
||||
if (fDeviceModule != NULL)
|
||||
|
Loading…
Reference in New Issue
Block a user