* proposition to fix a deadlock between kernel daemon and package installer install thread (bug #3447)

to manage this, avoid locking the main sLock in notification handling methods. Instead fill up two lists which will be emptied later by the kernel daemon thread.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@29603 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Jérôme Duval 2009-03-18 22:59:50 +00:00
parent 98092e9867
commit 7305309909

View File

@ -185,6 +185,8 @@ static hash_table* sDriverHash;
static DriverWatcher sDriverWatcher;
static int32 sDriverEvents;
static DoublyLinkedList<path_entry> sDriversToAdd;
static DoublyLinkedList<path_entry> sDriversToRemove;
static mutex sDriversListLock = MUTEX_INITIALIZER("driversList");
static DirectoryWatcher sDirectoryWatcher;
static DirectoryNodeHash sDirectoryNodeHash;
static recursive_lock sLock;
@ -620,13 +622,30 @@ handle_driver_events(void */*_fs*/, int /*iteration*/)
// something happened, let's see what it was
RecursiveLocker locker(sLock);
MutexLocker _(sDriversListLock);
while (true) {
path_entry* path = sDriversToAdd.RemoveHead();
if (path == NULL)
break;
legacy_driver_add(path->path);
legacy_driver* driver = (legacy_driver*)hash_lookup(sDriverHash,
get_leaf(path->path));
if (driver == NULL)
legacy_driver_add(path->path);
else if (get_priority(path->path) >= driver->priority)
driver->binary_updated = true;
delete path;
}
while (true) {
path_entry* path = sDriversToRemove.RemoveHead();
if (path == NULL)
break;
legacy_driver* driver = (legacy_driver*)hash_lookup(sDriverHash,
get_leaf(path->path));
if (driver != NULL && get_priority(path->path) >= driver->priority)
driver->binary_updated = true;
delete path;
}
@ -648,51 +667,6 @@ handle_driver_events(void */*_fs*/, int /*iteration*/)
}
static void
driver_added(const char* path)
{
int32 priority = get_priority(path);
RecursiveLocker locker(sLock);
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;
if (entry == NULL)
return;
strlcpy(entry->path, path, sizeof(entry->path));
sDriversToAdd.Add(entry);
} else {
// Update the driver if it is affected by the new entry
if (priority < driver->priority)
return;
driver->binary_updated = true;
}
atomic_add(&sDriverEvents, 1);
}
static void
driver_removed(const char* path)
{
int32 priority = get_priority(path);
RecursiveLocker locker(sLock);
legacy_driver* driver = (legacy_driver*)hash_lookup(sDriverHash,
get_leaf(path));
if (driver == NULL || priority < driver->priority)
return;
driver->binary_updated = true;
atomic_add(&sDriverEvents, 1);
}
// #pragma mark - DriverWatcher
@ -974,14 +948,22 @@ DirectoryWatcher::EventOccured(NotificationService& service,
dprintf("driver \"%s\" %s\n", path.Leaf(),
opcode == B_ENTRY_CREATED ? "added" : "removed");
path_entry* entry = new(std::nothrow) path_entry;
if (entry == NULL)
return;
strlcpy(entry->path, path.Path(), sizeof(entry->path));
MutexLocker _(sDriversListLock);
switch (opcode) {
case B_ENTRY_CREATED:
driver_added(path.Path());
sDriversToAdd.Add(entry);
break;
case B_ENTRY_REMOVED:
driver_removed(path.Path());
sDriversToRemove.Add(entry);
break;
}
atomic_add(&sDriverEvents, 1);
}