gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[GNUnet-SVN] r34564 - in gnunet/src: include peerstore


From: gnunet
Subject: [GNUnet-SVN] r34564 - in gnunet/src: include peerstore
Date: Mon, 15 Dec 2014 01:32:17 +0100

Author: amatus
Date: 2014-12-15 01:32:17 +0100 (Mon, 15 Dec 2014)
New Revision: 34564

Modified:
   gnunet/src/include/gnunet_peerstore_plugin.h
   gnunet/src/include/gnunet_peerstore_service.h
   gnunet/src/peerstore/gnunet-service-peerstore.c
   gnunet/src/peerstore/plugin_peerstore_sqlite.c
Log:
Implement asynchronous peerstore plugin API

Resolves #3506


Modified: gnunet/src/include/gnunet_peerstore_plugin.h
===================================================================
--- gnunet/src/include/gnunet_peerstore_plugin.h        2014-12-14 22:15:55 UTC 
(rev 34563)
+++ gnunet/src/include/gnunet_peerstore_plugin.h        2014-12-15 00:32:17 UTC 
(rev 34564)
@@ -59,7 +59,11 @@
    * @param peer peer identity
    * @param value value to be stored
    * @param size size of value to be stored
-   * @return #GNUNET_OK on success, else #GNUNET_SYSERR
+   * @param expiry absolute time after which the record is (possibly) deleted
+   * @param options options related to the store operation
+   * @param cont continuation called when record is stored
+   * @param cont_cls continuation closure
+   * @return #GNUNET_OK on success, else #GNUNET_SYSERR and cont is not called
    */
   int
   (*store_record) (void *cls,
@@ -69,7 +73,9 @@
       const void *value,
       size_t size,
       struct GNUNET_TIME_Absolute expiry,
-      enum GNUNET_PEERSTORE_StoreOption options);
+      enum GNUNET_PEERSTORE_StoreOption options,
+      GNUNET_PEERSTORE_Continuation cont,
+      void *cont_cls);
 
   /**
    * Iterate over the records given an optional peer id
@@ -79,9 +85,11 @@
    * @param sub_system name of sub system
    * @param peer Peer identity (can be NULL)
    * @param key entry key string (can be NULL)
-   * @param iter function to call with the result
+   * @param iter function to call asynchronously with the results, terminated
+   * by a NULL result
    * @param iter_cls closure for @a iter
-   * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
+   * @return #GNUNET_OK on success, #GNUNET_SYSERR on error and iter is not
+   * called
    */
   int
   (*iterate_records) (void *cls,
@@ -95,11 +103,16 @@
    *
    * @param cls closure (internal context for the plugin)
    * @param now time to use as reference
-   * @return number of records deleted
+   * @param cont continuation called with the number of records expired
+   * @param cont_cls continuation closure
+   * @return #GNUNET_OK on success, #GNUNET_SYSERR on error and cont is not
+   * called
    */
   int
   (*expire_records) (void *cls,
-      struct GNUNET_TIME_Absolute now);
+      struct GNUNET_TIME_Absolute now,
+      GNUNET_PEERSTORE_Continuation cont,
+      void *cont_cls);
 
 };
 

Modified: gnunet/src/include/gnunet_peerstore_service.h
===================================================================
--- gnunet/src/include/gnunet_peerstore_service.h       2014-12-14 22:15:55 UTC 
(rev 34563)
+++ gnunet/src/include/gnunet_peerstore_service.h       2014-12-15 00:32:17 UTC 
(rev 34564)
@@ -102,6 +102,10 @@
    */
   struct GNUNET_TIME_Absolute *expiry;
 
+  /**
+   * Client from which this record originated
+   */
+  struct GNUNET_SERVER_Client *client;
 };
 
 /**

Modified: gnunet/src/peerstore/gnunet-service-peerstore.c
===================================================================
--- gnunet/src/peerstore/gnunet-service-peerstore.c     2014-12-14 22:15:55 UTC 
(rev 34563)
+++ gnunet/src/peerstore/gnunet-service-peerstore.c     2014-12-15 00:32:17 UTC 
(rev 34564)
@@ -136,6 +136,10 @@
 }
 
 
+/* Forward declaration */
+static void expire_records_continuation (void *cls, int success);
+
+
 /**
  * Deletes any expired records from storage
  */
@@ -143,14 +147,34 @@
 cleanup_expired_records (void *cls,
                          const struct GNUNET_SCHEDULER_TaskContext *tc)
 {
-  int deleted;
+  int ret;
 
   if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN))
     return;
   GNUNET_assert (NULL != db);
-  deleted = db->expire_records (db->cls, GNUNET_TIME_absolute_get ());
-  if (deleted > 0)
-    GNUNET_log (GNUNET_ERROR_TYPE_INFO, "%d records expired.\n", deleted);
+  ret = db->expire_records (db->cls, GNUNET_TIME_absolute_get (),
+                            expire_records_continuation, NULL);
+  if (GNUNET_OK != ret)
+  {
+    GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply
+                                  (GNUNET_TIME_UNIT_SECONDS,
+                                   EXPIRED_RECORDS_CLEANUP_INTERVAL),
+                                  &cleanup_expired_records, NULL);
+  }
+}
+
+
+/**
+ * Continuation to expire_records called by the peerstore plugin
+ *
+ * @param cls unused
+ * @param success count of records deleted or #GNUNET_SYSERR
+ */
+static void
+expire_records_continuation(void *cls, int success)
+{
+  if (success > 0)
+    GNUNET_log (GNUNET_ERROR_TYPE_INFO, "%d records expired.\n", success);
   GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply
                                 (GNUNET_TIME_UNIT_SECONDS,
                                  EXPIRED_RECORDS_CLEANUP_INTERVAL),
@@ -217,15 +241,32 @@
 static int
 record_iterator (void *cls, struct GNUNET_PEERSTORE_Record *record, char *emsg)
 {
-  struct GNUNET_SERVER_Client *client = cls;
+  struct GNUNET_PEERSTORE_Record *cls_record = cls;
   struct StoreRecordMessage *srm;
 
+  if (NULL == record)
+  {
+    /* No more records */
+    struct GNUNET_MessageHeader *endmsg;
+
+    endmsg = GNUNET_new (struct GNUNET_MessageHeader);
+    endmsg->size = htons (sizeof (struct GNUNET_MessageHeader));
+    endmsg->type = htons (GNUNET_MESSAGE_TYPE_PEERSTORE_ITERATE_END);
+    GNUNET_SERVER_notification_context_unicast (nc, cls_record->client, endmsg,
+                                                GNUNET_NO);
+    GNUNET_free (endmsg);
+    GNUNET_SERVER_receive_done (cls_record->client,
+                                NULL == emsg ? GNUNET_OK : GNUNET_SYSERR);
+    PEERSTORE_destroy_record (cls_record);
+    return GNUNET_NO;
+  }
+
   srm =
       PEERSTORE_create_record_message (record->sub_system, record->peer,
                                        record->key, record->value,
                                        record->value_size, record->expiry,
                                        
GNUNET_MESSAGE_TYPE_PEERSTORE_ITERATE_RECORD);
-  GNUNET_SERVER_notification_context_unicast (nc, client,
+  GNUNET_SERVER_notification_context_unicast (nc, cls_record->client,
                                               (struct GNUNET_MessageHeader *)
                                               srm, GNUNET_NO);
   GNUNET_free (srm);
@@ -334,7 +375,6 @@
                 const struct GNUNET_MessageHeader *message)
 {
   struct GNUNET_PEERSTORE_Record *record;
-  struct GNUNET_MessageHeader *endmsg;
 
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received an iterate request.\n");
   record = PEERSTORE_parse_record_message (message);
@@ -358,21 +398,32 @@
               (NULL == record->peer) ? "NULL" : GNUNET_i2s (record->peer),
               (NULL == record->key) ? "NULL" : record->key);
   GNUNET_SERVER_notification_context_add (nc, client);
-  if (GNUNET_OK ==
+  record->client = client;
+  if (GNUNET_OK !=
       db->iterate_records (db->cls, record->sub_system, record->peer,
-                           record->key, &record_iterator, client))
+                           record->key, &record_iterator, record))
   {
-    endmsg = GNUNET_new (struct GNUNET_MessageHeader);
+    GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
+    PEERSTORE_destroy_record (record);
+  }
+}
 
-    endmsg->size = htons (sizeof (struct GNUNET_MessageHeader));
-    endmsg->type = htons (GNUNET_MESSAGE_TYPE_PEERSTORE_ITERATE_END);
-    GNUNET_SERVER_notification_context_unicast (nc, client, endmsg, GNUNET_NO);
-    GNUNET_free (endmsg);
-    GNUNET_SERVER_receive_done (client, GNUNET_OK);
-  }
-  else
+
+/**
+ * Continuation of store_record called by the peerstore plugin 
+ *
+ * @param cls closure
+ * @param success result
+ */
+static void
+store_record_continuation (void *cls, int success)
+{
+  struct GNUNET_PEERSTORE_Record *record = cls;
+
+  GNUNET_SERVER_receive_done (record->client, success);
+  if (GNUNET_OK == success)
   {
-    GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
+    watch_notifier (record);
   }
   PEERSTORE_destroy_record (record);
 }
@@ -418,20 +469,19 @@
               " Options: %d.\n",
               record->value_size, record->sub_system, GNUNET_i2s 
(record->peer),
               record->key, record->value_size, ntohl (srm->options));
+  record->client = client;
   if (GNUNET_OK !=
       db->store_record (db->cls, record->sub_system, record->peer, record->key,
                         record->value, record->value_size, *record->expiry,
-                        ntohl (srm->options)))
+                        ntohl (srm->options), store_record_continuation,
+                       record))
   {
     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                _("Failed to store requested value, sqlite database error."));
+                _("Failed to store requested value, database error."));
     PEERSTORE_destroy_record (record);
     GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
     return;
   }
-  GNUNET_SERVER_receive_done (client, GNUNET_OK);
-  watch_notifier (record);
-  PEERSTORE_destroy_record (record);
 }
 
 

Modified: gnunet/src/peerstore/plugin_peerstore_sqlite.c
===================================================================
--- gnunet/src/peerstore/plugin_peerstore_sqlite.c      2014-12-14 22:15:55 UTC 
(rev 34563)
+++ gnunet/src/peerstore/plugin_peerstore_sqlite.c      2014-12-15 00:32:17 UTC 
(rev 34564)
@@ -160,10 +160,15 @@
  *
  * @param cls closure (internal context for the plugin)
  * @param now time to use as reference
- * @return number of records deleted
+ * @param cont continuation called with the number of records expired
+ * @param cont_cls continuation closure
+ * @return #GNUNET_OK on success, #GNUNET_SYSERR on error and cont is not
+ * called
  */
 static int
-peerstore_sqlite_expire_records (void *cls, struct GNUNET_TIME_Absolute now)
+peerstore_sqlite_expire_records (void *cls, struct GNUNET_TIME_Absolute now,
+                                 GNUNET_PEERSTORE_Continuation cont,
+                                 void *cont_cls)
 {
   struct Plugin *plugin = cls;
   sqlite3_stmt *stmt = plugin->expire_peerstoredata;
@@ -183,9 +188,13 @@
   {
     LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
                 "sqlite3_reset");
-    return 0;
+    return GNUNET_SYSERR;
   }
-  return sqlite3_changes (plugin->dbh);
+  if (NULL != cont)
+  {
+    cont (cont_cls, sqlite3_changes (plugin->dbh));
+  }
+  return GNUNET_OK;
 }
 
 
@@ -197,9 +206,11 @@
  * @param sub_system name of sub system
  * @param peer Peer identity (can be NULL)
  * @param key entry key string (can be NULL)
- * @param iter function to call with the result
+ * @param iter function to call asynchronously with the results, terminated
+ * by a NULL result
  * @param iter_cls closure for @a iter
- * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
+ * @return #GNUNET_OK on success, #GNUNET_SYSERR on error and iter is not
+ * called
  */
 static int
 peerstore_sqlite_iterate_records (void *cls, const char *sub_system,
@@ -296,8 +307,10 @@
                 "sqlite3_reset");
     err = 1;
   }
-  if (err)
-    return GNUNET_SYSERR;
+  if (NULL != iter)
+  {
+    iter (iter_cls, NULL, err ? "sqlite error" : NULL);
+  }
   return GNUNET_OK;
 }
 
@@ -315,14 +328,18 @@
  * @param size size of value to be stored
  * @param expiry absolute time after which the record is (possibly) deleted
  * @param options options related to the store operation
- * @return #GNUNET_OK on success, else #GNUNET_SYSERR
+ * @param cont continuation called when record is stored
+ * @param cont_cls continuation closure
+ * @return #GNUNET_OK on success, else #GNUNET_SYSERR and cont is not called
  */
 static int
 peerstore_sqlite_store_record (void *cls, const char *sub_system,
                                const struct GNUNET_PeerIdentity *peer,
                                const char *key, const void *value, size_t size,
                                struct GNUNET_TIME_Absolute expiry,
-                               enum GNUNET_PEERSTORE_StoreOption options)
+                               enum GNUNET_PEERSTORE_StoreOption options,
+                               GNUNET_PEERSTORE_Continuation cont,
+                               void *cont_cls)
 {
   struct Plugin *plugin = cls;
   sqlite3_stmt *stmt = plugin->insert_peerstoredata;
@@ -355,6 +372,10 @@
                 "sqlite3_reset");
     return GNUNET_SYSERR;
   }
+  if (NULL != cont)
+  {
+    cont (cont_cls, GNUNET_OK);
+  }
   return GNUNET_OK;
 }
 




reply via email to

[Prev in Thread] Current Thread [Next in Thread]