Fix timeserver API
authorSamuel Ortiz <sameo@linux.intel.com>
Mon, 31 May 2010 23:58:17 +0000 (01:58 +0200)
committerSamuel Ortiz <sameo@linux.intel.com>
Tue, 1 Jun 2010 00:06:09 +0000 (02:06 +0200)
We want to keep the server pointer constant.

include/timeserver.h
plugins/ntpd.c
src/timeserver.c

index f1b5c9c..cb1ac9c 100644 (file)
@@ -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);
 };
 
index ce14027..2ab3072 100644 (file)
@@ -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;
 }
index bca66f3..584be26 100644 (file)
@@ -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;
 }