From 32fc30fa02a6d46b78f45e446b2347754ba2136a Mon Sep 17 00:00:00 2001 From: Denis Kenzior Date: Thu, 10 Sep 2009 23:01:59 -0500 Subject: [PATCH] Refactor various watch functions Use a common core kernel for all the watcher registrations / notifications. This is now done in watch.c --- Makefile.am | 2 +- src/modem.c | 113 +++++++++++++++------------------------------------- src/ofono.h | 25 +++++++++++- src/ssn.c | 110 +++++++++++++------------------------------------- src/watch.c | 104 +++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 188 insertions(+), 166 deletions(-) create mode 100644 src/watch.c diff --git a/Makefile.am b/Makefile.am index 395247d9..02a9cb4a 100644 --- a/Makefile.am +++ b/Makefile.am @@ -161,7 +161,7 @@ src_ofonod_SOURCES = $(gdbus_sources) $(builtin_sources) \ src/ssn.c src/call-barring.c src/sim.c \ src/phonebook.c src/history.c src/message-waiting.c \ src/simutil.h src/simutil.c src/storage.h \ - src/storage.c src/cbs.c + src/storage.c src/cbs.c src/watch.c src_ofonod_LDADD = $(builtin_libadd) \ @GLIB_LIBS@ @GTHREAD_LIBS@ @DBUS_LIBS@ -ldl diff --git a/src/modem.c b/src/modem.c index 5e6e582a..1a654afa 100644 --- a/src/modem.c +++ b/src/modem.c @@ -48,22 +48,21 @@ enum ofono_property_type { }; struct ofono_modem { - char *path; - GSList *atoms; - GSList *atom_watches; - int next_atom_watch_id; - GSList *interface_list; - unsigned int call_ids; - DBusMessage *pending; - guint interface_update; - ofono_bool_t powered; - ofono_bool_t powered_pending; - ofono_bool_t powered_persistent; - guint timeout; - GHashTable *properties; + char *path; + GSList *atoms; + struct ofono_watchlist *atom_watches; + GSList *interface_list; + unsigned int call_ids; + DBusMessage *pending; + guint interface_update; + ofono_bool_t powered; + ofono_bool_t powered_pending; + ofono_bool_t powered_persistent; + guint timeout; + GHashTable *properties; const struct ofono_modem_driver *driver; - void *driver_data; - char *driver_type; + void *driver_data; + char *driver_type; }; struct ofono_devinfo { @@ -85,11 +84,8 @@ struct ofono_atom { }; struct ofono_atom_watch { + struct ofono_watchlist_item item; enum ofono_atom_type type; - int id; - ofono_atom_watch_func notify; - ofono_destroy_func destroy; - void *notify_data; }; struct ofono_property { @@ -182,16 +178,19 @@ static void call_watches(struct ofono_atom *atom, enum ofono_atom_watch_condition cond) { struct ofono_modem *modem = atom->modem; + GSList *atom_watches = modem->atom_watches->items; GSList *l; struct ofono_atom_watch *watch; + ofono_atom_watch_func notify; - for (l = modem->atom_watches; l; l = l->next) { + for (l = atom_watches; l; l = l->next) { watch = l->data; if (watch->type != atom->type) continue; - watch->notify(atom, cond, watch->notify_data); + notify = watch->item.notify; + notify(atom, cond, watch->item.notify_data); } } @@ -221,7 +220,7 @@ gboolean __ofono_atom_get_registered(struct ofono_atom *atom) return atom->unregister ? TRUE : FALSE; } -int __ofono_modem_add_atom_watch(struct ofono_modem *modem, +unsigned int __ofono_modem_add_atom_watch(struct ofono_modem *modem, enum ofono_atom_type type, ofono_atom_watch_func notify, void *data, ofono_destroy_func destroy) @@ -234,67 +233,18 @@ int __ofono_modem_add_atom_watch(struct ofono_modem *modem, watch = g_new0(struct ofono_atom_watch, 1); watch->type = type; - watch->id = ++modem->next_atom_watch_id; - watch->notify = notify; - watch->destroy = destroy; - watch->notify_data = data; + watch->item.notify = notify; + watch->item.destroy = destroy; + watch->item.notify_data = data; - modem->atom_watches = g_slist_prepend(modem->atom_watches, watch); - - return watch->id; + return __ofono_watchlist_add_item(modem->atom_watches, + (struct ofono_watchlist_item *)watch); } -gboolean __ofono_modem_remove_atom_watch(struct ofono_modem *modem, int id) +gboolean __ofono_modem_remove_atom_watch(struct ofono_modem *modem, + unsigned int id) { - struct ofono_atom_watch *watch; - GSList *p; - GSList *c; - - p = NULL; - c = modem->atom_watches; - - while (c) { - watch = c->data; - - if (watch->id != id) { - p = c; - c = c->next; - continue; - } - - if (p) - p->next = c->next; - else - modem->atom_watches = c->next; - - if (watch->destroy) - watch->destroy(watch->notify_data); - - g_free(watch); - g_slist_free_1(c); - - return TRUE; - } - - return FALSE; -} - -static void remove_all_watches(struct ofono_modem *modem) -{ - struct ofono_atom_watch *watch; - GSList *l; - - for (l = modem->atom_watches; l; l = l->next) { - watch = l->data; - - if (watch->destroy) - watch->destroy(watch->notify_data); - - g_free(watch); - } - - g_slist_free(modem->atom_watches); - modem->atom_watches = NULL; + return __ofono_watchlist_remove_item(modem->atom_watches, id); } struct ofono_atom *__ofono_modem_find_atom(struct ofono_modem *modem, @@ -1076,6 +1026,7 @@ struct ofono_modem *ofono_modem_create(const char *type) modem->driver_type = g_strdup(type); modem->properties = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, unregister_property); + modem->atom_watches = __ofono_watchlist_new(g_free); g_modem_list = g_slist_prepend(g_modem_list, modem); @@ -1165,7 +1116,9 @@ static void modem_unregister(struct ofono_modem *modem) return; remove_all_atoms(modem); - remove_all_watches(modem); + + __ofono_watchlist_free(modem->atom_watches); + modem->atom_watches = NULL; g_slist_foreach(modem->interface_list, (GFunc)g_free, NULL); g_slist_free(modem->interface_list); diff --git a/src/ofono.h b/src/ofono.h index 79226b04..0234cf97 100644 --- a/src/ofono.h +++ b/src/ofono.h @@ -57,6 +57,26 @@ gboolean __ofono_dbus_valid_object_path(const char *path); #include +struct ofono_watchlist_item { + unsigned int id; + void *notify; + void *notify_data; + ofono_destroy_func destroy; +}; + +struct ofono_watchlist { + int next_id; + GSList *items; + ofono_destroy_func destroy; +}; + +struct ofono_watchlist *__ofono_watchlist_new(ofono_destroy_func destroy); +unsigned int __ofono_watchlist_add_item(struct ofono_watchlist *watchlist, + struct ofono_watchlist_item *item); +gboolean __ofono_watchlist_remove_item(struct ofono_watchlist *watchlist, + unsigned int id); +void __ofono_watchlist_free(struct ofono_watchlist *watchlist); + #include int __ofono_plugin_init(const char *pattern, const char *exclude); @@ -120,11 +140,12 @@ void __ofono_atom_unregister(struct ofono_atom *atom); gboolean __ofono_atom_get_registered(struct ofono_atom *atom); -int __ofono_modem_add_atom_watch(struct ofono_modem *modem, +unsigned int __ofono_modem_add_atom_watch(struct ofono_modem *modem, enum ofono_atom_type type, ofono_atom_watch_func notify, void *data, ofono_destroy_func destroy); -gboolean __ofono_modem_remove_atom_watch(struct ofono_modem *modem, int id); +gboolean __ofono_modem_remove_atom_watch(struct ofono_modem *modem, + unsigned int id); void __ofono_atom_free(struct ofono_atom *atom); diff --git a/src/ssn.c b/src/ssn.c index b5b76c57..6d5e279d 100644 --- a/src/ssn.c +++ b/src/ssn.c @@ -36,23 +36,19 @@ static GSList *g_drivers = NULL; struct ssn_handler { - unsigned int id; + struct ofono_watchlist_item item; int code; - void *notify; - void *data; - ofono_destroy_func destroy; }; struct ofono_ssn { - GSList *mo_handler_list; - GSList *mt_handler_list; - unsigned int next_id; + struct ofono_watchlist *mo_handler_list; + struct ofono_watchlist *mt_handler_list; const struct ofono_ssn_driver *driver; void *driver_data; struct ofono_atom *atom; }; -static unsigned int add_ssn_handler(GSList **l, unsigned int *id, +static unsigned int add_ssn_handler(struct ofono_watchlist *watchlist, int code, void *notify, void *data, ofono_destroy_func destroy) { @@ -64,68 +60,12 @@ static unsigned int add_ssn_handler(GSList **l, unsigned int *id, handler = g_new0(struct ssn_handler, 1); handler->code = code; - handler->id = *id; - *id = *id + 1; - handler->notify = notify; - handler->destroy = destroy; - handler->data = data; + handler->item.notify = notify; + handler->item.notify_data = data; + handler->item.destroy = destroy; - *l = g_slist_prepend(*l, handler); - - return handler->id; -} - -static gboolean remove_ssn_handler_by_id(GSList **l, unsigned int id) -{ - struct ssn_handler *handler; - GSList *p; - GSList *c; - - p = NULL; - c = *l; - - while (c) { - handler = c->data; - - if (handler->id != id) { - p = c; - c = c->next; - continue; - } - - if (p) - p->next = c->next; - else - *l = c->next; - - if (handler->destroy) - handler->destroy(handler->data); - - g_free(handler); - g_slist_free_1(c); - - return TRUE; - } - - return FALSE; -} - -static void remove_all_handlers(GSList **l) -{ - struct ssn_handler *handler; - GSList *c; - - for (c = *l; c; c = c->next) { - handler = c->data; - - if (handler->destroy) - handler->destroy(handler->data); - - g_free(handler); - } - - g_slist_free(*l); - *l = NULL; + return __ofono_watchlist_add_item(watchlist, + (struct ofono_watchlist_item *)handler); } unsigned int __ofono_ssn_mo_watch_add(struct ofono_ssn *ssn, int code1, @@ -137,8 +77,7 @@ unsigned int __ofono_ssn_mo_watch_add(struct ofono_ssn *ssn, int code1, DBG("%p, %d", ssn, code1); - return add_ssn_handler(&ssn->mo_handler_list, &ssn->next_id, - code1, cb, user, destroy); + return add_ssn_handler(ssn->mo_handler_list, code1, cb, user, destroy); } gboolean __ofono_ssn_mo_watch_remove(struct ofono_ssn *ssn, int id) @@ -148,7 +87,7 @@ gboolean __ofono_ssn_mo_watch_remove(struct ofono_ssn *ssn, int id) DBG("%p, %u", ssn, id); - return remove_ssn_handler_by_id(&ssn->mo_handler_list, id); + return __ofono_watchlist_remove_item(ssn->mo_handler_list, id); } unsigned int __ofono_ssn_mt_watch_add(struct ofono_ssn *ssn, int code2, @@ -160,8 +99,7 @@ unsigned int __ofono_ssn_mt_watch_add(struct ofono_ssn *ssn, int code2, DBG("%p, %d", ssn, code2); - return add_ssn_handler(&ssn->mt_handler_list, &ssn->next_id, - code2, cb, user, destroy); + return add_ssn_handler(ssn->mt_handler_list, code2, cb, user, destroy); } gboolean __ofono_ssn_mt_watch_remove(struct ofono_ssn *ssn, int id) @@ -171,7 +109,7 @@ gboolean __ofono_ssn_mt_watch_remove(struct ofono_ssn *ssn, int id) DBG("%p, %u", ssn, id); - return remove_ssn_handler_by_id(&ssn->mt_handler_list, id); + return __ofono_watchlist_remove_item(ssn->mt_handler_list, id); } void ofono_ssn_cssi_notify(struct ofono_ssn *ssn, int code1, int index) @@ -180,12 +118,12 @@ void ofono_ssn_cssi_notify(struct ofono_ssn *ssn, int code1, int index) GSList *l; ofono_ssn_mo_notify_cb notify; - for (l = ssn->mo_handler_list; l; l = l->next) { + for (l = ssn->mo_handler_list->items; l; l = l->next) { h = l->data; - notify = h->notify; + notify = h->item.notify; if (h->code == code1) - notify(index, h->data); + notify(index, h->item.notify_data); } } @@ -196,12 +134,12 @@ void ofono_ssn_cssu_notify(struct ofono_ssn *ssn, int code2, int index, GSList *l; ofono_ssn_mt_notify_cb notify; - for (l = ssn->mt_handler_list; l; l = l->next) { + for (l = ssn->mt_handler_list->items; l; l = l->next) { h = l->data; - notify = h->notify; + notify = h->item.notify; if (h->code == code2) - notify(index, ph, h->data); + notify(index, ph, h->item.notify_data); } } @@ -228,8 +166,11 @@ static void ssn_unregister(struct ofono_atom *atom) { struct ofono_ssn *ssn = __ofono_atom_get_data(atom); - remove_all_handlers(&ssn->mo_handler_list); - remove_all_handlers(&ssn->mt_handler_list); + __ofono_watchlist_free(ssn->mo_handler_list); + ssn->mo_handler_list = NULL; + + __ofono_watchlist_free(ssn->mt_handler_list); + ssn->mt_handler_list = NULL; } static void ssn_remove(struct ofono_atom *atom) @@ -263,6 +204,9 @@ struct ofono_ssn *ofono_ssn_create(struct ofono_modem *modem, if (ssn == NULL) return NULL; + ssn->mo_handler_list = __ofono_watchlist_new(g_free); + ssn->mt_handler_list = __ofono_watchlist_new(g_free); + ssn->atom = __ofono_modem_add_atom(modem, OFONO_ATOM_TYPE_SSN, ssn_remove, ssn); diff --git a/src/watch.c b/src/watch.c new file mode 100644 index 00000000..9d5f8fbf --- /dev/null +++ b/src/watch.c @@ -0,0 +1,104 @@ +/* + * + * oFono - Open Source Telephony + * + * Copyright (C) 2008-2009 Intel Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include "ofono.h" + +struct ofono_watchlist *__ofono_watchlist_new(ofono_destroy_func destroy) +{ + struct ofono_watchlist *watchlist; + + watchlist = g_new0(struct ofono_watchlist, 1); + watchlist->destroy = destroy; + + return watchlist; +} + +unsigned int __ofono_watchlist_add_item(struct ofono_watchlist *watchlist, + struct ofono_watchlist_item *item) +{ + item->id = ++watchlist->next_id; + + watchlist->items = g_slist_prepend(watchlist->items, item); + + return item->id; +} + +gboolean __ofono_watchlist_remove_item(struct ofono_watchlist *watchlist, + unsigned int id) +{ + struct ofono_watchlist_item *item; + GSList *p; + GSList *c; + + p = NULL; + c = watchlist->items; + + while (c) { + item = c->data; + + if (item->id != id) { + p = c; + c = c->next; + continue; + } + + if (p) + p->next = c->next; + else + watchlist->items = c->next; + + if (item->destroy) + item->destroy(item->notify_data); + + if (watchlist->destroy) + watchlist->destroy(item); + g_slist_free_1(c); + + return TRUE; + } + + return FALSE; +} + +void __ofono_watchlist_free(struct ofono_watchlist *watchlist) +{ + struct ofono_watchlist_item *item; + GSList *l; + + for (l = watchlist->items; l; l = l->next) { + item = l->data; + + if (item->destroy) + item->destroy(item->notify_data); + + if (watchlist->destroy) + watchlist->destroy(item); + } + + g_slist_free(watchlist->items); + watchlist->items = NULL; + g_free(watchlist); +}