device_manager: add find_child_node

to find a node in the hierarchy.

Change-Id: Iee858f21ce134569bf25fccbef9fe18ea8787e9d
Reviewed-on: https://review.haiku-os.org/c/haiku/+/2419
Reviewed-by: Jérôme Duval <jerome.duval@gmail.com>
This commit is contained in:
Jérôme Duval 2020-03-15 19:53:06 +01:00
parent f4fce2fd2e
commit 08bc0cc9ca
2 changed files with 52 additions and 0 deletions

View File

@ -101,6 +101,10 @@ typedef struct device_manager_info {
const void **_data, size_t *_size, bool recursive);
status_t (*get_next_attr)(device_node *node, device_attr **_attr);
status_t (*find_child_node)(device_node *parent,
const device_attr *attrs, device_node **node);
} device_manager_info;

View File

@ -893,6 +893,53 @@ get_next_attr(device_node* node, device_attr** _attr)
}
static status_t
find_child_node(device_node* parent, const device_attr* attributes,
device_node** _node, bool *_lastFound)
{
RecursiveLocker _(sLock);
NodeList::ConstIterator iterator = parent->Children().GetIterator();
device_node* last = *_node;
// find the next one that fits
while (iterator.HasNext()) {
device_node* node = iterator.Next();
if (!node->IsRegistered())
continue;
if (node == last)
*_lastFound = true;
else if (!node->CompareTo(attributes) && *_lastFound) {
if (last != NULL)
last->Release();
node->Acquire();
*_node = node;
return B_OK;
}
if (find_child_node(node, attributes, _node, _lastFound) == B_OK)
return B_OK;
}
return B_ENTRY_NOT_FOUND;
}
static status_t
find_child_node(device_node* parent, const device_attr* attributes,
device_node** _node)
{
device_node* last = *_node;
bool lastFound = last == NULL;
status_t status = find_child_node(parent, attributes, _node, &lastFound);
if (status == B_ENTRY_NOT_FOUND && last != NULL && lastFound)
last->Release();
return status;
}
struct device_manager_info gDeviceManagerModule = {
{
B_DEVICE_MANAGER_MODULE_NAME,
@ -928,6 +975,7 @@ struct device_manager_info gDeviceManagerModule = {
get_attr_string,
get_attr_raw,
get_next_attr,
find_child_node
};