diff options
author | Felix Fietkau <nbd@openwrt.org> | 2011-09-04 15:00:25 +0200 |
---|---|---|
committer | Felix Fietkau <nbd@openwrt.org> | 2011-09-04 15:00:25 +0200 |
commit | 4e335f640fadda81aff9dd2dc06703961bea2826 (patch) | |
tree | bc9618ea20fdd6328f534488413dadd5530146ce /device.c | |
parent | dca8c7133b1db463f6ae71ccc6d34cd12735daef (diff) |
make device_claim/device_release operate on the device_user instead of the device to avoid refcount bugs
Diffstat (limited to 'device.c')
-rw-r--r-- | device.c | 18 |
1 files changed, 16 insertions, 2 deletions
@@ -120,10 +120,15 @@ static int set_device_state(struct device *dev, bool state) return 0; } -int device_claim(struct device *dev) +int device_claim(struct device_user *dep) { + struct device *dev = dep->dev; int ret; + if (dep->claimed) + return 0; + + dep->claimed = true; DPRINTF("claim device %s, new refcount: %d\n", dev->ifname, dev->active + 1); if (++dev->active != 1) return 0; @@ -138,8 +143,14 @@ int device_claim(struct device *dev) return ret; } -void device_release(struct device *dev) +void device_release(struct device_user *dep) { + struct device *dev = dep->dev; + + if (!dep->claimed) + return; + + dep->claimed = false; dev->active--; DPRINTF("release device %s, new refcount: %d\n", dev->ifname, dev->active); assert(dev->active >= 0); @@ -254,6 +265,9 @@ void device_remove_user(struct device_user *dep) { struct device *dev = dep->dev; + if (dep->claimed) + device_release(dep); + list_del(&dep->list); if (list_empty(&dev->users)) { |