peerstore: iterate request timeout
authorOmar Tarabai <tarabai@devegypt.com>
Tue, 27 May 2014 18:37:44 +0000 (18:37 +0000)
committerOmar Tarabai <tarabai@devegypt.com>
Tue, 27 May 2014 18:37:44 +0000 (18:37 +0000)
src/peerstore/gnunet-service-peerstore.c
src/peerstore/peerstore_api.c
src/peerstore/plugin_peerstore_sqlite.c

index b7827692242733db2641eb1d30ffcfe459fe6131..c410630c9e2bff37c5a2d650591236d1dbc0912f 100644 (file)
@@ -67,6 +67,8 @@ shutdown_task (void *cls,
     GNUNET_free (db_lib_name);
     db_lib_name = NULL;
   }
+
+  GNUNET_SCHEDULER_shutdown();
 }
 
 /**
@@ -78,6 +80,8 @@ cleanup_expired_records(void *cls,
 {
   int deleted;
 
+  if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN))
+    return;
   GNUNET_assert(NULL != db);
   deleted = db->expire_records(db->cls, GNUNET_TIME_absolute_get());
   GNUNET_log(GNUNET_ERROR_TYPE_INFO, "%d records expired.\n", deleted);
@@ -266,7 +270,7 @@ run (void *cls,
          GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "Could not load database backend `%s'\n", db_lib_name);
   else
   {
-    cleanup_expired_records(NULL, NULL);
+    GNUNET_SCHEDULER_add_now(&cleanup_expired_records, NULL);
     GNUNET_SERVER_add_handlers (server, handlers);
     GNUNET_SERVER_disconnect_notify (server,
              &handle_client_disconnect,
index d6acd2dafc01565f9cb70063b29d75b86f6d366f..57c6318521a7824bf16c95e2620ea1b99d86f931 100644 (file)
@@ -161,6 +161,12 @@ struct GNUNET_PEERSTORE_IterateContext
    */
   int request_sent;
 
+  /**
+   * Task identifier for the function called
+   * on iterate request timeout
+   */
+  GNUNET_SCHEDULER_TaskIdentifier timeout_task;
+
 };
 
 /******************************************************************************/
@@ -432,7 +438,7 @@ GNUNET_PEERSTORE_store (struct GNUNET_PEERSTORE_Handle *h,
     GNUNET_PEERSTORE_Continuation cont,
     void *cont_cls)
 {
-  struct GNUNET_MQ_Envelope *ev;
+  struct GNUNET_MQ_Envelope *ev; //FIXME: add 'replace' flag in store function (similar to multihashmap)
   struct GNUNET_PEERSTORE_StoreContext *sc;
 
   LOG (GNUNET_ERROR_TYPE_DEBUG,
@@ -452,7 +458,7 @@ GNUNET_PEERSTORE_store (struct GNUNET_PEERSTORE_Handle *h,
   sc->h = h;
   sc->request_sent = GNUNET_NO;
   GNUNET_CONTAINER_DLL_insert(h->store_head, h->store_tail, sc);
-  GNUNET_MQ_notify_sent(ev, &store_request_sent, ev);
+  GNUNET_MQ_notify_sent(ev, &store_request_sent, sc);
   GNUNET_MQ_send(h->mq, ev);
   return sc;
 
@@ -499,8 +505,7 @@ void handle_iterate_result (void *cls, const struct GNUNET_MessageHeader *msg)
   msg_type = ntohs(msg->type);
   if(GNUNET_MESSAGE_TYPE_PEERSTORE_ITERATE_END == msg_type)
   {
-    GNUNET_CONTAINER_DLL_remove(ic->h->iterate_head, ic->h->iterate_tail, ic);
-    GNUNET_free(ic);
+    GNUNET_PEERSTORE_iterate_cancel(ic);
     if(NULL != callback)
       callback(callback_cls, NULL, NULL);
     return;
@@ -532,6 +537,19 @@ void iterate_request_sent (void *cls)
   ic->ev = NULL;
 }
 
+/**
+ * Called when the iterate request is timedout
+ *
+ * @param cls a 'struct GNUNET_PEERSTORE_IterateContext *'
+ */
+void iterate_timeout (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
+{
+  struct GNUNET_PEERSTORE_IterateContext *ic = cls;
+
+  ic->timeout_task = GNUNET_SCHEDULER_NO_TASK;
+  GNUNET_PEERSTORE_iterate_cancel(ic);
+}
+
 /**
  * Cancel an iterate request
  * Please do not call after the iterate request is done
@@ -541,7 +559,12 @@ void iterate_request_sent (void *cls)
 void
 GNUNET_PEERSTORE_iterate_cancel (struct GNUNET_PEERSTORE_IterateContext *ic)
 {
-  LOG(GNUNET_ERROR_TYPE_DEBUG, "User request cancel of iterate request.\n");
+  LOG(GNUNET_ERROR_TYPE_DEBUG, "Canceling iterate request.\n");
+  if(GNUNET_SCHEDULER_NO_TASK != ic->timeout_task)
+  {
+    GNUNET_SCHEDULER_cancel(ic->timeout_task);
+    ic->timeout_task = GNUNET_SCHEDULER_NO_TASK;
+  }
   if(GNUNET_NO == ic->request_sent)
   {
     if(NULL != ic->ev)
@@ -566,13 +589,14 @@ GNUNET_PEERSTORE_iterate_cancel (struct GNUNET_PEERSTORE_IterateContext *ic)
  * @param timeout time after which the iterate request is canceled
  * @param callback function called with each matching record, all NULL's on end
  * @param callback_cls closure for @a callback
+ * @return Handle to iteration request
  */
 struct GNUNET_PEERSTORE_IterateContext *
 GNUNET_PEERSTORE_iterate (struct GNUNET_PEERSTORE_Handle *h,
     char *sub_system,
     const struct GNUNET_PeerIdentity *peer,
     const char *key,
-    struct GNUNET_TIME_Relative timeout, //FIXME: handle timeout
+    struct GNUNET_TIME_Relative timeout,
     GNUNET_PEERSTORE_Processor callback, void *callback_cls)
 {
   struct GNUNET_MQ_Envelope *ev;
@@ -594,8 +618,9 @@ GNUNET_PEERSTORE_iterate (struct GNUNET_PEERSTORE_Handle *h,
   GNUNET_CONTAINER_DLL_insert(h->iterate_head, h->iterate_tail, ic);
   LOG(GNUNET_ERROR_TYPE_DEBUG,
         "Sending an iterate request for sub system `%s'\n", sub_system);
-  GNUNET_MQ_notify_sent(ev, &iterate_request_sent, ev);
+  GNUNET_MQ_notify_sent(ev, &iterate_request_sent, ic);
   GNUNET_MQ_send(h->mq, ev);
+  ic->timeout_task = GNUNET_SCHEDULER_add_delayed(timeout, &iterate_timeout, ic);
   return ic;
 }
 
index ead2aade6bd450e30d4e1573f1098c803fa77e8e..8d35466de10240adae1409af7a75d242f425afc3 100644 (file)
@@ -51,6 +51,8 @@
 
 #define LOG(kind,...) GNUNET_log_from (kind, "peerstore-sqlite", __VA_ARGS__)
 
+//FIXME: Indexes
+
 /**
  * Context for all functions in this plugin.
  */
@@ -97,11 +99,6 @@ struct Plugin
    */
   sqlite3_stmt *select_peerstoredata_by_all;
 
-  /**
-   * Precompiled SQL for selecting from peerstoredata
-   */
-  sqlite3_stmt *select_peerstoredata_by_all_and_value;
-
   /**
    * Precompiled SQL for deleting expired records from peerstoredata
    */
@@ -236,42 +233,6 @@ peerstore_sqlite_iterate_records (void *cls,
   return GNUNET_OK;
 }
 
-/**
- * Checks if a record with the given information
- * already exists
- *
- * @return #GNUNET_YES / #GNUNET_NO
- *
-static int
-check_existing(void *cls,
-    const char *sub_system,
-    const struct GNUNET_PeerIdentity *peer,
-    const char *key,
-    const void *value,
-    size_t size)
-{
-  struct Plugin *plugin = cls;
-  sqlite3_stmt *stmt = plugin->select_peerstoredata_by_all_and_value;
-  int sret;
-
-  if(SQLITE_OK != sqlite3_bind_text(stmt, 1, sub_system, strlen(sub_system) + 1, SQLITE_STATIC)
-      || SQLITE_OK != sqlite3_bind_blob(stmt, 2, peer, sizeof(struct GNUNET_PeerIdentity), SQLITE_STATIC)
-      || SQLITE_OK != sqlite3_bind_text(stmt, 3, key, strlen(key) + 1, SQLITE_STATIC)
-      || SQLITE_OK != sqlite3_bind_blob(stmt, 4, value, size, SQLITE_STATIC))
-  {
-    LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
-        "sqlite3_bind");
-    sqlite3_reset(stmt);
-    return GNUNET_NO;
-  }
-  sret = sqlite3_step (stmt);
-  sqlite3_reset(stmt);
-  if(SQLITE_ROW == sret)
-    return GNUNET_YES;
-  return GNUNET_NO;
-
-}*/
-
 /**
  * Store a record in the peerstore.
  * Key is the combination of sub system and peer identity.
@@ -296,17 +257,6 @@ peerstore_sqlite_store_record(void *cls,
   struct Plugin *plugin = cls;
   sqlite3_stmt *stmt = plugin->insert_peerstoredata;
 
-  //FIXME: check if value exists with the same key first
-  /*if(GNUNET_YES == check_existing(cls,
-      sub_system,
-      peer,
-      key,
-      value,
-      size))
-  {
-
-  }*/
-
   if(SQLITE_OK != sqlite3_bind_text(stmt, 1, sub_system, strlen(sub_system) + 1, SQLITE_STATIC)
       || SQLITE_OK != sqlite3_bind_blob(stmt, 2, peer, sizeof(struct GNUNET_PeerIdentity), SQLITE_STATIC)
       || SQLITE_OK != sqlite3_bind_text(stmt, 3, key, strlen(key) + 1, SQLITE_STATIC)
@@ -465,13 +415,6 @@ database_setup (struct Plugin *plugin)
       " AND peer_id = ?"
       " AND key = ?",
       &plugin->select_peerstoredata_by_all);
-  sql_prepare(plugin->dbh,
-      "SELECT * FROM peerstoredata"
-      " WHERE sub_system = ?"
-      " AND peer_id = ?"
-      " AND key = ?"
-      " AND value = ?",
-      &plugin->select_peerstoredata_by_all_and_value);
   sql_prepare(plugin->dbh,
       "DELETE FROM peerstoredata"
       " WHERE expiry < ?",