* handle_driver_events() kept the sDriversListLock locked over the whole
time. But since this is also locked from within the driver/directory watcher (with the node monitor lock held), and handle_driver_events() could cause node monitoring updates, the locking order could be reverted, causing a deadlock (I just ran into). git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@32152 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -196,6 +196,7 @@ static int32 sDriverEvents;
|
||||
static EntryList sDriversToAdd;
|
||||
static EntryList sDriversToRemove;
|
||||
static mutex sDriversListLock = MUTEX_INITIALIZER("driversList");
|
||||
// inner lock, protects the sDriversToAdd/sDriversToRemove lists only
|
||||
static DirectoryWatcher sDirectoryWatcher;
|
||||
static DirectoryNodeHash sDirectoryNodeHash;
|
||||
static recursive_lock sLock;
|
||||
@@ -641,14 +642,19 @@ handle_driver_events(void */*_fs*/, int /*iteration*/)
|
||||
|
||||
// something happened, let's see what it was
|
||||
|
||||
RecursiveLocker locker(sLock);
|
||||
MutexLocker _(sDriversListLock);
|
||||
RecursiveLocker _(sLock);
|
||||
|
||||
// Add new drivers
|
||||
|
||||
while (true) {
|
||||
MutexLocker listLocker(sDriversListLock);
|
||||
|
||||
path_entry* path = sDriversToAdd.RemoveHead();
|
||||
if (path == NULL)
|
||||
break;
|
||||
|
||||
listLocker.Unlock();
|
||||
|
||||
legacy_driver* driver = (legacy_driver*)hash_lookup(sDriverHash,
|
||||
get_leaf(path->path));
|
||||
if (driver == NULL)
|
||||
@@ -657,11 +663,18 @@ handle_driver_events(void */*_fs*/, int /*iteration*/)
|
||||
driver->binary_updated = true;
|
||||
delete path;
|
||||
}
|
||||
|
||||
// Mark removed drivers as updated
|
||||
|
||||
while (true) {
|
||||
MutexLocker listLocker(sDriversListLock);
|
||||
|
||||
path_entry* path = sDriversToRemove.RemoveHead();
|
||||
if (path == NULL)
|
||||
break;
|
||||
|
||||
listLocker.Unlock();
|
||||
|
||||
legacy_driver* driver = (legacy_driver*)hash_lookup(sDriverHash,
|
||||
get_leaf(path->path));
|
||||
if (driver != NULL && get_priority(path->path) >= driver->priority)
|
||||
@@ -669,6 +682,8 @@ handle_driver_events(void */*_fs*/, int /*iteration*/)
|
||||
delete path;
|
||||
}
|
||||
|
||||
// Reload updated drivers
|
||||
|
||||
hash_iterator iterator;
|
||||
hash_open(sDriverHash, &iterator);
|
||||
legacy_driver *driver;
|
||||
|
||||
Reference in New Issue
Block a user