device: Convert device watches to watchlist

This commit is contained in:
Denis Kenzior 2016-09-14 09:31:11 -05:00
parent ef18c03322
commit 09dcd78e30
3 changed files with 33 additions and 81 deletions

View File

@ -78,82 +78,18 @@ struct device {
struct netdev *netdev;
};
static struct l_queue *device_watches = NULL;
static uint32_t device_next_watch_id = 0;
static struct watchlist device_watches;
static struct l_queue *device_list;
static void device_watchlist_item_free(void *userdata)
{
struct device_watchlist_item *item = userdata;
if (item->destroy)
item->destroy(item->userdata);
l_free(item);
}
static bool device_watchlist_item_match(const void *a, const void *b)
{
const struct device_watchlist_item *item = a;
uint32_t id = L_PTR_TO_UINT(b);
return item->id == id;
}
uint32_t device_watch_add(device_watch_func_t added,
device_watch_func_t removed,
uint32_t device_watch_add(device_watch_func_t func,
void *userdata, device_destroy_func_t destroy)
{
struct device_watchlist_item *item;
item = l_new(struct device_watchlist_item, 1);
item->id = ++device_next_watch_id;
item->added = added;
item->removed = removed;
item->userdata = userdata;
item->destroy = destroy;
l_queue_push_tail(device_watches, item);
return item->id;
return watchlist_add(&device_watches, func, userdata, destroy);
}
bool device_watch_remove(uint32_t id)
{
struct device_watchlist_item *item;
item = l_queue_remove_if(device_watches, device_watchlist_item_match,
L_UINT_TO_PTR(id));
if (!item)
return false;
device_watchlist_item_free(item);
return true;
}
void __device_watch_call_added(struct device *device)
{
const struct l_queue_entry *e;
for (e = l_queue_get_entries(device_watches); e; e = e->next) {
struct device_watchlist_item *item = e->data;
if (item->added)
item->added(device, item->userdata);
}
}
void __device_watch_call_removed(struct device *device)
{
const struct l_queue_entry *e;
for (e = l_queue_get_entries(device_watches); e; e = e->next) {
struct device_watchlist_item *item = e->data;
if (item->removed)
item->removed(device, item->userdata);
}
return watchlist_remove(&device_watches, id);
}
void __iwd_device_foreach(iwd_device_foreach_func func, void *user_data)
@ -1113,7 +1049,8 @@ static void device_netdev_notify(struct netdev *netdev,
case NETDEV_WATCH_EVENT_UP:
device_enter_state(device, DEVICE_STATE_AUTOCONNECT);
__device_watch_call_added(device);
WATCHLIST_NOTIFY(&device_watches, device_watch_func_t,
device, DEVICE_EVENT_INSERTED);
l_dbus_property_changed(dbus, device_get_path(device),
IWD_DEVICE_INTERFACE, "Powered");
@ -1155,7 +1092,8 @@ static void device_netdev_notify(struct netdev *netdev,
l_queue_destroy(device->networks_sorted, NULL);
device->networks_sorted = l_queue_new();
__device_watch_call_removed(device);
WATCHLIST_NOTIFY(&device_watches, device_watch_func_t,
device, DEVICE_EVENT_REMOVED);
l_dbus_property_changed(dbus, device_get_path(device),
IWD_DEVICE_INTERFACE, "Powered");
@ -1221,7 +1159,8 @@ static void device_free(void *user)
watchlist_destroy(&device->state_watches);
if (device->state != DEVICE_STATE_OFF)
__device_watch_call_removed(device);
WATCHLIST_NOTIFY(&device_watches, device_watch_func_t,
device, DEVICE_EVENT_REMOVED);
dbus = dbus_get_bus();
l_dbus_unregister_object(dbus, device_get_path(device));
@ -1255,7 +1194,7 @@ bool device_init(void)
NULL, true))
return false;
device_watches = l_queue_new();
watchlist_init(&device_watches);
device_list = l_queue_new();
return true;
@ -1269,7 +1208,7 @@ bool device_exit(void)
l_queue_destroy(device_list, device_free);
device_list = NULL;
l_queue_destroy(device_watches, device_watchlist_item_free);
watchlist_destroy(&device_watches);
l_dbus_unregister_interface(dbus_get_bus(), IWD_DEVICE_INTERFACE);

View File

@ -27,6 +27,11 @@ struct wiphy;
struct netdev;
struct device;
enum device_event {
DEVICE_EVENT_INSERTED,
DEVICE_EVENT_REMOVED,
};
enum device_state {
DEVICE_STATE_OFF = 0, /* Interface down */
DEVICE_STATE_DISCONNECTED, /* Disconnected, no auto-connect */
@ -36,18 +41,16 @@ enum device_state {
DEVICE_STATE_DISCONNECTING,
};
typedef void (*device_watch_func_t)(struct device *device, void *userdata);
typedef void (*device_watch_func_t)(struct device *device,
enum device_event event,
void *userdata);
typedef void (*device_state_watch_func_t)(enum device_state, void *userdata);
typedef void (*device_destroy_func_t)(void *userdata);
uint32_t device_watch_add(device_watch_func_t added,
device_watch_func_t removed,
uint32_t device_watch_add(device_watch_func_t func,
void *userdata, device_destroy_func_t destroy);
bool device_watch_remove(uint32_t id);
void __device_watch_call_added(struct device *device);
void __device_watch_call_removed(struct device *device);
struct network *device_get_connected_network(struct device *device);
const char *device_get_path(struct device *device);
bool device_is_busy(struct device *device);

View File

@ -323,6 +323,17 @@ static void device_disappeared(struct device *device, void *userdata)
IWD_WSC_INTERFACE);
}
static void device_event(struct device *device, enum device_event event,
void *userdata)
{
switch (event) {
case DEVICE_EVENT_INSERTED:
return device_appeared(device, userdata);
case DEVICE_EVENT_REMOVED:
return device_disappeared(device, userdata);
}
}
bool wsc_init(struct l_genl_family *in)
{
if (!l_dbus_register_interface(dbus_get_bus(), IWD_WSC_INTERFACE,
@ -330,8 +341,7 @@ bool wsc_init(struct l_genl_family *in)
wsc_free, false))
return false;
device_watch = device_watch_add(device_appeared, device_disappeared,
NULL, NULL);
device_watch = device_watch_add(device_event, NULL, NULL);
if (!device_watch)
return false;