diff options
author | Samuel Ortiz <sameo@linux.intel.com> | 2010-06-01 01:58:17 +0200 |
---|---|---|
committer | Samuel Ortiz <sameo@linux.intel.com> | 2010-06-01 02:06:09 +0200 |
commit | 40ee49bad468402fa7242801979a392152a039c6 (patch) | |
tree | 2c00bc74a58131f88b8c2c177f8046e4baa81122 | |
parent | ec6dc19bbeb4c93e951ba5419ccf6768d5811ae6 (diff) | |
download | connman-40ee49bad468402fa7242801979a392152a039c6.tar.gz connman-40ee49bad468402fa7242801979a392152a039c6.tar.bz2 connman-40ee49bad468402fa7242801979a392152a039c6.zip |
Fix timeserver API
We want to keep the server pointer constant.
-rw-r--r-- | include/timeserver.h | 8 | ||||
-rw-r--r-- | plugins/ntpd.c | 97 | ||||
-rw-r--r-- | src/timeserver.c | 15 |
3 files changed, 101 insertions, 19 deletions
diff --git a/include/timeserver.h b/include/timeserver.h index f1b5c9c8..cb1ac9c9 100644 --- a/include/timeserver.h +++ b/include/timeserver.h @@ -32,15 +32,15 @@ extern "C" { * @short_description: Functions for handling time servers (including NTP) */ -int connman_timeserver_append(char *server); -int connman_timeserver_remove(char *server); +int connman_timeserver_append(const char *server); +int connman_timeserver_remove(const char *server); void connman_timeserver_sync(void); struct connman_timeserver_driver { const char *name; int priority; - int (*append) (char *server); - int (*remove) (char *server); + int (*append) (const char *server); + int (*remove) (const char *server); void (*sync) (void); }; diff --git a/plugins/ntpd.c b/plugins/ntpd.c index ce140276..2ab30721 100644 --- a/plugins/ntpd.c +++ b/plugins/ntpd.c @@ -47,12 +47,42 @@ static GList *pending_peers = NULL; #define NTPD_PORT 123 #define DEFAULT_NTP_PEER "ntp.meego.com" +struct ntpd_peer { + char *server; + gint refcount; +}; + struct ntpdate_task { struct connman_task *task; gint conf_fd; char *conf_path; }; +static struct ntpd_peer *find_peer(GList *peer_list, const char* server) +{ + GList *list; + struct ntpd_peer *peer; + + for (list = peer_list; list; list = list->next) { + peer = list->data; + + if (g_str_equal(peer->server, server)) + return peer; + } + + return NULL; +} + +static void remove_peer(GList *peer_list, struct ntpd_peer *peer) +{ + if (!g_atomic_int_dec_and_test(&peer->refcount)) + return; + + g_free(peer->server); + g_free(peer); + peer_list = g_list_remove(peer_list, peer); +} + static connman_bool_t ntpd_running(void) { int sock; @@ -113,6 +143,7 @@ static int ntpdate(void) int err; GError *g_err; GList *list; + struct ntpd_peer *peer; struct ntpdate_task *ntpdate; DBG(""); @@ -146,11 +177,17 @@ static int ntpdate(void) if (pending_peers == NULL && peers == NULL) ntpdate_add_peer(ntpdate, DEFAULT_NTP_PEER); - for (list = pending_peers; list; list = list->next) - ntpdate_add_peer(ntpdate, list->data); + for (list = pending_peers; list; list = list->next) { + peer = list->data; + + ntpdate_add_peer(ntpdate, peer->server); + } + + for (list = peers; list; list = list->next) { + peer = list->data; - for (list = peers; list; list = list->next) - ntpdate_add_peer(ntpdate, list->data); + ntpdate_add_peer(ntpdate, peer->server); + } close(ntpdate->conf_fd); @@ -188,9 +225,9 @@ static void ntpd_sync(void) list = g_list_first(pending_peers); while(list) { - char *peer = list->data; + struct ntpd_peer *peer = list->data; - err = ntpd_add_peer(peer); + err = ntpd_add_peer(peer->server); if (err) continue; @@ -202,23 +239,61 @@ static void ntpd_sync(void) }; } -static int ntpd_append(char *server) +static int ntpd_append(const char *server) { + struct ntpd_peer *peer; + DBG(""); - pending_peers = g_list_prepend(pending_peers, server); + if (server == NULL) + return 0; + + if ((peer = find_peer(pending_peers, server)) || + (peer = find_peer(peers, server))) { + g_atomic_int_inc(&peer->refcount); + return 0; + } + + peer = g_try_new0(struct ntpd_peer, 1); + if (peer == NULL) + return -ENOMEM; + + peer->server = g_strdup(server); + if (peer->server == NULL) { + g_free(peer); + return -ENOMEM; + } + + peer->refcount = 1; + + pending_peers = g_list_prepend(pending_peers, peer); return 0; } -static int ntpd_remove(char *server) +static int ntpd_remove(const char *server) { + struct ntpd_peer *peer; + DBG(""); - peers = g_list_remove(peers, server); + if (server == NULL) + return 0; + + peer = find_peer(peers, server); + if (peer == NULL) + goto remove; + + remove_peer(peers, peer); + +remove: /* TODO: send ntpd remove command */ - pending_peers = g_list_remove(pending_peers, server); + peer = find_peer(pending_peers, server); + if (peer == NULL) + return 0; + + remove_peer(pending_peers, peer); return 0; } diff --git a/src/timeserver.c b/src/timeserver.c index bca66f3a..584be263 100644 --- a/src/timeserver.c +++ b/src/timeserver.c @@ -75,7 +75,7 @@ void connman_timeserver_driver_unregister(struct connman_timeserver_driver *driv * * Append time server server address to current list */ -int connman_timeserver_append(char *server) +int connman_timeserver_append(const char *server) { GSList *list; @@ -90,12 +90,17 @@ int connman_timeserver_append(char *server) for (list = driver_list; list; list = list->next) { struct connman_timeserver_driver *driver = list->data; + char *new_server; if (driver->append == NULL) continue; + new_server = g_strdup(server); + if (new_server == NULL) + return -ENOMEM; + if (driver->append(server) == 0) { - g_hash_table_insert(server_hash, server, driver); + g_hash_table_insert(server_hash, new_server, driver); return 0; } } @@ -109,7 +114,7 @@ int connman_timeserver_append(char *server) * * Remover time server server address from current list */ -int connman_timeserver_remove(char *server) +int connman_timeserver_remove(const char *server) { struct connman_timeserver_driver *driver; @@ -122,6 +127,8 @@ int connman_timeserver_remove(char *server) if (driver == NULL) return -EINVAL; + g_hash_table_remove(server_hash, server); + if (driver->remove == NULL) return -ENOENT; @@ -149,7 +156,7 @@ int __connman_timeserver_init(void) DBG(""); server_hash = g_hash_table_new_full(g_str_hash, g_str_equal, - NULL, NULL); + g_free, NULL); return 0; } |