* 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 sDriversToAdd;
|
||||||
static EntryList sDriversToRemove;
|
static EntryList sDriversToRemove;
|
||||||
static mutex sDriversListLock = MUTEX_INITIALIZER("driversList");
|
static mutex sDriversListLock = MUTEX_INITIALIZER("driversList");
|
||||||
|
// inner lock, protects the sDriversToAdd/sDriversToRemove lists only
|
||||||
static DirectoryWatcher sDirectoryWatcher;
|
static DirectoryWatcher sDirectoryWatcher;
|
||||||
static DirectoryNodeHash sDirectoryNodeHash;
|
static DirectoryNodeHash sDirectoryNodeHash;
|
||||||
static recursive_lock sLock;
|
static recursive_lock sLock;
|
||||||
@@ -641,14 +642,19 @@ handle_driver_events(void */*_fs*/, int /*iteration*/)
|
|||||||
|
|
||||||
// something happened, let's see what it was
|
// something happened, let's see what it was
|
||||||
|
|
||||||
RecursiveLocker locker(sLock);
|
RecursiveLocker _(sLock);
|
||||||
MutexLocker _(sDriversListLock);
|
|
||||||
|
// Add new drivers
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
|
MutexLocker listLocker(sDriversListLock);
|
||||||
|
|
||||||
path_entry* path = sDriversToAdd.RemoveHead();
|
path_entry* path = sDriversToAdd.RemoveHead();
|
||||||
if (path == NULL)
|
if (path == NULL)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
listLocker.Unlock();
|
||||||
|
|
||||||
legacy_driver* driver = (legacy_driver*)hash_lookup(sDriverHash,
|
legacy_driver* driver = (legacy_driver*)hash_lookup(sDriverHash,
|
||||||
get_leaf(path->path));
|
get_leaf(path->path));
|
||||||
if (driver == NULL)
|
if (driver == NULL)
|
||||||
@@ -657,11 +663,18 @@ handle_driver_events(void */*_fs*/, int /*iteration*/)
|
|||||||
driver->binary_updated = true;
|
driver->binary_updated = true;
|
||||||
delete path;
|
delete path;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Mark removed drivers as updated
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
|
MutexLocker listLocker(sDriversListLock);
|
||||||
|
|
||||||
path_entry* path = sDriversToRemove.RemoveHead();
|
path_entry* path = sDriversToRemove.RemoveHead();
|
||||||
if (path == NULL)
|
if (path == NULL)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
listLocker.Unlock();
|
||||||
|
|
||||||
legacy_driver* driver = (legacy_driver*)hash_lookup(sDriverHash,
|
legacy_driver* driver = (legacy_driver*)hash_lookup(sDriverHash,
|
||||||
get_leaf(path->path));
|
get_leaf(path->path));
|
||||||
if (driver != NULL && get_priority(path->path) >= driver->priority)
|
if (driver != NULL && get_priority(path->path) >= driver->priority)
|
||||||
@@ -669,6 +682,8 @@ handle_driver_events(void */*_fs*/, int /*iteration*/)
|
|||||||
delete path;
|
delete path;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Reload updated drivers
|
||||||
|
|
||||||
hash_iterator iterator;
|
hash_iterator iterator;
|
||||||
hash_open(sDriverHash, &iterator);
|
hash_open(sDriverHash, &iterator);
|
||||||
legacy_driver *driver;
|
legacy_driver *driver;
|
||||||
|
|||||||
Reference in New Issue
Block a user