* Added get_root() to device_manager_info. Surprisingly enough, it

returns the root device node. Now its actually possible to
  traverse the device node tree without a node to start with.
* Fixed execution order problem in dm_get_next_child_node(). The
  supplied node was put first (which could cause its immediate
  deletion), but was still accessed thereafter.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@16268 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Ingo Weinhold
2006-02-07 02:29:14 +00:00
parent 41f7459c23
commit 3277aade49
4 changed files with 23 additions and 4 deletions
+2
View File
@@ -77,6 +77,7 @@ typedef struct device_manager_info {
device_node_handle *node);
status_t (*unregister_device)(device_node_handle node);
device_node_handle (*get_root)();
status_t (*get_next_child_device)(device_node_handle parent,
device_node_handle *_node, const device_attr *attrs);
device_node_handle (*get_parent)(device_node_handle node);
@@ -165,6 +166,7 @@ struct driver_module_info {
#define B_MISC_DRIVER_TYPE "misc"
#define B_NETWORK_DRIVER_TYPE "net"
#define B_VIDEO_DRIVER_TYPE "video"
#define B_INTERRUPT_CONTROLLER_DRIVER_TYPE "interrupt controller"
#define PNP_DRIVER_CONNECTION "connection"
// connection of parent the device is attached to (optional, string)
@@ -79,6 +79,7 @@ device_manager_info gDeviceManagerModule = {
dm_register_node,
dm_unregister_node,
dm_get_root,
dm_get_next_child_node,
dm_get_parent,
dm_put_node,
@@ -173,6 +173,7 @@ status_t dm_init_nodes(void);
void dm_put_node(device_node_info *node);
status_t dm_get_next_child_node(device_node_info *parent,
device_node_info **_node, const device_attr *attrs);
device_node_info *dm_get_root(void);
device_node_info *dm_get_parent(device_node_info *node);
+19 -4
View File
@@ -328,7 +328,7 @@ dm_get_node(device_node_info *node)
// remove node reference and clean it up if necessary
// (node_lock must be hold)
// (gNodeLock must be hold)
void
dm_put_node_nolock(device_node_info *node)
@@ -453,6 +453,14 @@ dm_put_node(device_node_info *node)
}
device_node_info *
dm_get_root(void)
{
dm_get_node(gRootNode);
return gRootNode;
}
device_node_info *
dm_get_parent(device_node_info *node)
{
@@ -466,9 +474,8 @@ dm_get_next_child_node(device_node_info *parent, device_node_info **_node,
const device_attr *attrs)
{
device_node_info *node = *_node;
if (node != NULL)
dm_put_node(node);
device_node_info *nodeToPut = node;
benaphore_lock(&gNodeLock);
while ((node = (device_node_info *)list_get_next_item(&parent->children, node)) != NULL) {
@@ -490,10 +497,18 @@ dm_get_next_child_node(device_node_info *parent, device_node_info **_node,
// we found a node
dm_get_node_nolock(node);
*_node = node;
if (nodeToPut != NULL)
dm_put_node_nolock(nodeToPut);
benaphore_unlock(&gNodeLock);
return B_OK;
}
if (nodeToPut != NULL)
dm_put_node_nolock(nodeToPut);
benaphore_unlock(&gNodeLock);
return B_ENTRY_NOT_FOUND;
}