gnunet-svn
[Top][All Lists]
Advanced

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

[GNUnet-SVN] r26911 - in gnunet/src: include set


From: gnunet
Subject: [GNUnet-SVN] r26911 - in gnunet/src: include set
Date: Wed, 17 Apr 2013 02:44:29 +0200

Author: dold
Date: 2013-04-17 02:44:29 +0200 (Wed, 17 Apr 2013)
New Revision: 26911

Added:
   gnunet/src/set/mq.c
   gnunet/src/set/mq.h
   gnunet/src/set/set.h
Modified:
   gnunet/src/include/gnunet_protocols.h
   gnunet/src/include/gnunet_set_service.h
   gnunet/src/include/gnunet_testing_lib.h
   gnunet/src/set/Makefile.am
   gnunet/src/set/set_api.c
   gnunet/src/set/test_set_api.c
Log:
started implementing set api, draft for mq


Modified: gnunet/src/include/gnunet_protocols.h
===================================================================
--- gnunet/src/include/gnunet_protocols.h       2013-04-16 22:21:50 UTC (rev 
26910)
+++ gnunet/src/include/gnunet_protocols.h       2013-04-17 00:44:29 UTC (rev 
26911)
@@ -1760,11 +1760,69 @@
 #define GNUNET_MESSAGE_TYPE_CONSENSUS_P2P_ABORT 548
 
 
+/*******************************************************************************
+ * SET message types
+ 
******************************************************************************/
+
 /**
- *  Next available: 570
+ * Cancel a set operation
  */
+#define GNUNET_MESSAGE_TYPE_SET_CANCEL 570
 
+/**
+ * Acknowledge results
+ */
+#define GNUNET_MESSAGE_TYPE_SET_ACK 571
 
+/**
+ * Create an empty set
+ */
+#define GNUNET_MESSAGE_TYPE_SET_RESULT 572
+
+/**
+ * Add element to set
+ */
+#define GNUNET_MESSAGE_TYPE_SET_ADD 573
+
+
+/**
+ * Remove element from set
+ */
+#define GNUNET_MESSAGE_TYPE_SET_REMOVE 574
+
+
+/**
+ * Listen for operation requests
+ */
+#define GNUNET_MESSAGE_TYPE_SET_LISTEN 575
+
+/**
+ * Accept a set request
+ */
+#define GNUNET_MESSAGE_TYPE_SET_ACCEPT 576
+
+/**
+ * Evaluate a set operation
+ */
+#define GNUNET_MESSAGE_TYPE_SET_EVALUATE 577
+
+/**
+ * Evaluate a set operation
+ */
+#define GNUNET_MESSAGE_TYPE_SET_REQUEST 578
+
+
+/**
+ * Evaluate a set operation
+ */
+#define GNUNET_MESSAGE_TYPE_SET_CREATE 579
+
+
+/**
+ *  Next available: 600
+ */
+
+
 
/*******************************************************************************
  * TODO: we need a way to register message types centrally (via some webpage).
  * For now: unofficial extensions should start at 48k, internal extensions

Modified: gnunet/src/include/gnunet_set_service.h
===================================================================
--- gnunet/src/include/gnunet_set_service.h     2013-04-16 22:21:50 UTC (rev 
26910)
+++ gnunet/src/include/gnunet_set_service.h     2013-04-17 00:44:29 UTC (rev 
26911)
@@ -1,9 +1,76 @@
-// FIXME: copyright, etc.
+/*
+      This file is part of GNUnet
+      (C) 2013 Christian Grothoff (and other contributing authors)
 
+      GNUnet is free software; you can redistribute it and/or modify
+      it under the terms of the GNU General Public License as published
+      by the Free Software Foundation; either version 2, or (at your
+      option) any later version.
+
+      GNUnet 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 GNUnet; see the file COPYING.  If not, write to the
+      Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+      Boston, MA 02111-1307, USA.
+ */
+
 /**
+ * @file include/gnunet_set_service.h
+ * @brief two-peer set operations
+ * @author Florian Dold
+ */
+
+#ifndef GNUNET_SET_SERVICE_H
+#define GNUNET_SET_SERVICE_H
+
+#ifdef __cplusplus
+extern "C"
+{
+#if 0                           /* keep Emacsens' auto-indent happy */
+}
+#endif
+#endif
+
+#include "platform.h"
+#include "gnunet_common.h"
+#include "gnunet_time_lib.h"
+#include "gnunet_configuration_lib.h"
+
+
+/**
+ * Opaque handle to a set.
+ */
+struct GNUNET_SET_Handle;
+
+/**
+ * Opaque handle to a set operation request from another peer.
+ */
+struct GNUNET_SET_Request;
+
+/**
+ * Opaque handle to a listen operation.
+ */
+struct GNUNET_SET_ListenHandle;
+
+/**
+ * Opaque handle to a set operation.
+ */
+struct GNUNET_SET_OperationHandle;
+
+
+/**
+ * Opaque handle to a listen operation.
+ */
+struct GNUNET_SET_ListenHandle;
+
+/**
  * The operation that a set set supports.
  */
-enum GNUNET_SET_Operation
+enum GNUNET_SET_OperationType
 {
   /**
    * Set intersection, only return elements that are in both sets.
@@ -31,10 +98,37 @@
   /*
    * The other peer refused to to the operation with us
    */
-  GNUNET_SET_STATUS_REFUSED
+  GNUNET_SET_STATUS_REFUSED,
+  /*
+   * Success, all elements have been sent.
+   */
+  GNUNET_SET_STATUS_DONE
 };
 
-// FIXME: comment
+/**
+ * The way results are given to the client.
+ */
+enum GNUNET_SET_ResultMode
+{
+  /**
+   * Client gets every element in the resulting set.
+   */
+  GNUNET_SET_RESULT_FULL,
+  /**
+   * Client gets only elements that have been added to the set.
+   * Only works with set union.
+   */
+  GNUNET_SET_RESULT_ADDED,
+  /**
+   * Client gets only elements that have been removed from the set.
+   * Only works with set intersection.
+   */
+  GNUNET_SET_RESULT_REMOVED
+};
+
+/**
+ * Element stored in a set.
+ */
 struct GNUNET_SET_Element
 {
   /**
@@ -53,8 +147,53 @@
 
 
 /**
+ * Continuation used for some of the set operations
+ *
+ * @cls closure
+ */
+typedef void (*GNUNET_SET_Continuation) (void *cls);
+
+/**
+ * Callback for set operation results. Called for each element
+ * in the result set.
+ *
+ * @param cls closure
+ * @param element a result element, only valid if status is 
GNUNET_SET_STATUS_OK
+ * @param status see enum GNUNET_SET_Status
+ */
+typedef void
+(*GNUNET_SET_ResultIterator) (void *cls,
+                              struct GNUNET_SET_Element *element,
+                              enum GNUNET_SET_Status status);
+
+
+/**
+ * Called when another peer wants to do a set operation with the
+ * local peer
+ *
+ * @param other_peer the other peer
+ * @param context_msg message with application specific information from
+ *        the other peer
+ * @param request request from the other peer, use GNUNET_SET_accept
+ *        to accept it, otherwise the request will be refused
+ *        Note that we don't use a return value here, as it is also
+ *        necessary to specify the set we want to do the operation with,
+ *        whith sometimes can be derived from the context message.
+ *        Also necessary to specify the timeout.
+ */
+typedef void
+(*GNUNET_SET_ListenCallback) (void *cls,
+                              const struct GNUNET_PeerIdentity *other_peer,
+                              const struct GNUNET_MessageHeader *context_msg,
+                              struct GNUNET_SET_Request *request);
+
+
+
+/**
  * Create an empty set, supporting the specified operation.
  *
+ * @param cfg configuration to use for connecting to the
+ *        set service
  * @param op operation supported by the set
  *        Note that the operation has to be specified
  *        beforehand, as certain set operations need to maintain
@@ -62,10 +201,21 @@
  * @return a handle to the set
  */
 struct GNUNET_SET_Handle *
-GNUNET_SET_create (enum GNUNET_SET_Operation op);
+GNUNET_SET_create (struct GNUNET_CONFIGURATION_Handle *cfg,
+                   enum GNUNET_SET_OperationType op);
 
 
-// FIXME: comment
+/**
+ * Add an element to the given set.
+ * After the element has been added (in the sense of being
+ * transmitted to the set service), cont will be called.
+ * Calls to add_element can be queued
+ *
+ * @param set set to add element to
+ * @param element element to add to the set
+ * @param cont continuation called after the element has been added
+ * @param cont_cls closure for cont
+ */
 void
 GNUNET_SET_add_element (struct GNUNET_SET_Handle *set,
                         const struct GNUNET_SET_Element *element,
@@ -73,7 +223,17 @@
                         void *cont_cls);
 
 
-// FIXME: comment
+/**
+ * Remove an element to the given set.
+ * After the element has been removed (in the sense of the
+ * request being transmitted to the set service), cont will be called.
+ * Calls to remove_element can be queued
+ *
+ * @param set set to remove element from
+ * @param element element to remove from the set
+ * @param cont continuation called after the element has been removed
+ * @param cont_cls closure for cont
+ */
 void
 GNUNET_SET_remove_element (struct GNUNET_SET_Handle *set,
                            const struct GNUNET_SET_Element *element,
@@ -81,37 +241,17 @@
                            void *cont_cls);
 
 
-// FIXME: comment
-struct GNUNET_SET_Handle *
-GNUNET_SET_clone (struct GNUNET_SET_Handle *set);
-
-
-// FIXME: comment
+/**
+ * Destroy the set handle, and free all associated resources.
+ */
 void
 GNUNET_SET_destroy (struct GNUNET_SET_Handle *set);
 
 
-
 /**
- * Callback for set operation results. Called for each element
- * in the result set.
-// FIXME: might want a way to just get the 'additional/removd' elements
- *
- * @param cls closure
- * @param element element, or NULL to indicate that all elements
- *        have been passed to the callback
- *        Only valid if (status==GNUNET_SET_STATUS_OK) holds.
- * @param status see enum GNUNET_SET_Status
- */
-typedef void
-(*GNUNET_SET_ResultIterator) (void *cls,
-                              struct GNUNET_SET_Element *element,
-                              enum GNUNET_SET_ResultStatus status);
-
-
-/**
  * Evaluate a set operation with our set and the set of another peer.
  *
+ * @param set set to use
  * @param other_peer peer with the other set
  * @param app_id hash for the application using the set
  * @param context_msg additional information for the request
@@ -120,38 +260,23 @@
  * @return a handle to cancel the operation
  */
 struct GNUNET_SET_OperationHandle *
-GNUNET_SET_evaluate (const struct GNUNET_PeerIdentity *other_peer,
+GNUNET_SET_evaluate (struct GNUNET_SET_Handle *set,
+                     const struct GNUNET_PeerIdentity *other_peer,
                      const struct GNUNET_HashCode *app_id,
                      const struct GNUNET_MessageHeader *context_msg,
                      struct GNUNET_TIME_Relative timeout,
+                     enum GNUNET_SET_ResultMode result_mode,
                      GNUNET_SET_ResultIterator result_cb,
                      void *result_cls);
 
 
-/**
- * Called when another peer wants to do a set operation with the
- * local peer
- *
- * @param other_peer the other peer
- * @param context_msg message with application specific information from
- *        the other peer
- * @param request request from the other peer, use GNUNET_SET_accept
- *        to accept it, otherwise the request will be refused
- *        Note that we don't use a return value here, as it is also
- *        necessary to specify the set we want to do the operation with,
- *        whith sometimes can be derived from the context message.
- *        Also necessary to specify the timeout.
- */
-typedef void
-(*GNUNET_SET_ListenCallback) (void *cls,
-                              const struct GNUNET_PeerIdentity *other_peer,
-                              const struct GNUNET_MessageHeader *context_msg,
-                              struct GNUNET_SET_Request *request);
 
 
 /**
  * Wait for set operation requests for the given application id
  * 
+ * @param cfg configuration to use for connecting to
+ *            the set service
  * @param operation operation we want to listen for
  * @param app_id id of the application that handles set operation requests
  * @param listen_cb called for each incoming request matching the operation
@@ -160,14 +285,19 @@
  * @return a handle that can be used to cancel the listen operation
  */
 struct GNUNET_SET_ListenHandle *
-GNUNET_SET_listen (enum GNUNET_SET_Operation operation,
+GNUNET_SET_listen (struct GNUNET_CONFIGURATION_Handle *cfg,
+                   enum GNUNET_SET_OperationType op_type,
                    const struct GNUNET_HashCode *app_id,
                    GNUNET_SET_ListenCallback listen_cb,
                    void *listen_cls);
 
 
 
-// FIXME: comment
+/**
+ * Cancel the given listen operation.
+ *
+ * @param lh handle for the listen operation
+ */
 void
 GNUNET_SET_listen_cancel (struct GNUNET_SET_ListenHandle *lh);
 
@@ -185,12 +315,25 @@
 GNUNET_SET_accept (struct GNUNET_SET_Request *request,
                    struct GNUNET_SET_Handle *set,
                    struct GNUNET_TIME_Relative timeout,
+                   enum GNUNET_SET_ResultMode result_mode,
                    GNUNET_SET_ResultIterator result_cb,
-                   void *cls)
+                   void *cls);
 
 
-// FIXME: comment
+/**
+ * Cancel the given set operation.
+ *
+ * @param op set operation to cancel
+ */
 void
-GNUNET_SET_operation_cancel (struct GNUNET_SET_OperationHandle *op);
-                          
+GNUNET_SET_operation_cancel (struct GNUNET_SET_OperationHandle *oh);
 
+
+#if 0                           /* keep Emacsens' auto-indent happy */
+{
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+#endif

Modified: gnunet/src/include/gnunet_testing_lib.h
===================================================================
--- gnunet/src/include/gnunet_testing_lib.h     2013-04-16 22:21:50 UTC (rev 
26910)
+++ gnunet/src/include/gnunet_testing_lib.h     2013-04-17 00:44:29 UTC (rev 
26911)
@@ -325,9 +325,9 @@
  * @param cfg configuration of the peer that was started
  * @param peer identity of the peer that was created
  */
-typedef void (*GNUNET_TESTING_TestMain)(void *cls,
-                                       const struct 
GNUNET_CONFIGURATION_Handle *cfg,
-                                       struct GNUNET_TESTING_Peer *peer);
+typedef void (*GNUNET_TESTING_TestMain) (void *cls,
+                                         const struct 
GNUNET_CONFIGURATION_Handle *cfg,
+                                         struct GNUNET_TESTING_Peer *peer);
 
 
 /**

Modified: gnunet/src/set/Makefile.am
===================================================================
--- gnunet/src/set/Makefile.am  2013-04-16 22:21:50 UTC (rev 26910)
+++ gnunet/src/set/Makefile.am  2013-04-17 00:44:29 UTC (rev 26911)
@@ -46,7 +46,8 @@
   $(GN_LIBINTL)
 
 libgnunetset_la_SOURCES = \
-  set_api.c
+  set_api.c \
+  mq.c
 libgnunetset_la_LIBADD = \
   $(top_builddir)/src/util/libgnunetutil.la \
   $(LTLIBINTL)

Added: gnunet/src/set/mq.c
===================================================================
--- gnunet/src/set/mq.c                         (rev 0)
+++ gnunet/src/set/mq.c 2013-04-17 00:44:29 UTC (rev 26911)
@@ -0,0 +1,47 @@
+/*
+     This file is part of GNUnet.
+     (C) 2012 Christian Grothoff (and other contributing authors)
+
+     GNUnet is free software; you can redistribute it and/or modify
+     it under the terms of the GNU General Public License as published
+     by the Free Software Foundation; either version 2, or (at your
+     option) any later version.
+
+     GNUnet 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 GNUnet; see the file COPYING.  If not, write to the
+     Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+     Boston, MA 02111-1307, USA.
+*/
+
+/**
+ * @author Florian Dold
+ * @file mq/mq.c
+ * @brief general purpose request queue
+ */
+
+#include "mq.h"
+
+
+struct GNUNET_MQ_Message
+{
+  struct GNUNET_MessageHeader *mh;
+};
+
+
+struct GNUNET_MQ_Message *
+GNUNET_MQ_msg_ (struct GNUNET_MessageHeader **mhp, uint16_t size, uint16_t 
type)
+{
+  struct GNUNET_MQ_Message *mqm;
+  mqm = GNUNET_malloc (sizeof *mqm + size);
+  mqm->mh = (struct GNUNET_MessageHeader *) &mqm[1];
+  mqm->mh->size = htons (size);
+  mqm->mh->type = htons(type);
+  if (NULL != mhp)
+    *mhp = mqm->mh;
+  return mqm;
+}

Added: gnunet/src/set/mq.h
===================================================================
--- gnunet/src/set/mq.h                         (rev 0)
+++ gnunet/src/set/mq.h 2013-04-17 00:44:29 UTC (rev 26911)
@@ -0,0 +1,94 @@
+/*
+     This file is part of GNUnet.
+     (C) 2012 Christian Grothoff (and other contributing authors)
+
+     GNUnet is free software; you can redistribute it and/or modify
+     it under the terms of the GNU General Public License as published
+     by the Free Software Foundation; either version 2, or (at your
+     option) any later version.
+
+     GNUnet 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 GNUnet; see the file COPYING.  If not, write to the
+     Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+     Boston, MA 02111-1307, USA.
+*/
+
+/**
+ * @author Florian Dold
+ * @file mq/mq.h
+ * @brief general purpose request queue
+ */
+#ifndef MQ_H
+#define MQ_H
+
+#include "platform.h"
+#include "gnunet_common.h"
+#include "gnunet_util_lib.h"
+#include "gnunet_connection_lib.h"
+
+
+#define GNUNET_MQ_msg_extra(mvar, esize, type) GNUNET_MQ_msg_(((void) 
mvar->header, (struct GNUNET_MessageHeader**) &mvar), (esize) + sizeof *mvar, 
type)
+
+#define GNUNET_MQ_msg(mvar, type) GNUNET_MQ_msg_extra(mvar, 0, type)
+
+#define GNUNET_MQ_msg_raw(type) GNUNET_MQ_msg_ (NULL, sizeof (struct 
GNUNET_MessageHeader), type)
+
+#define GNUNET_MQ_HANDLERS_END {NULL, 0}
+
+struct GNUNET_MQ_MessageQueue;
+
+struct GNUNET_MQ_Message;
+
+struct GNUNET_MQ_Handler
+{
+  void *cb;
+  uint16_t type;
+};
+
+struct GNUNET_MQ_Message *
+GNUNET_MQ_msg_ (struct GNUNET_MessageHeader **mhp, uint16_t size, uint16_t 
type);
+
+void
+GNUNET_MQ_send (struct GNUNET_MQ_MessageQueue *mq, struct GNUNET_MQ_Message 
*mqm);
+
+void *
+GNUNET_MQ_assoc_remove (struct GNUNET_MQ_MessageQueue *mq, uint32_t 
request_id);
+
+uint32_t
+GNUNET_MQ_assoc_add (struct GNUNET_MQ_MessageQueue *mq,
+                     struct GNUNET_MQ_Message *mqm,
+                     void *assoc_data);
+
+
+struct GNUNET_MQ_MessageQueue *
+GNUNET_MQ_queue_for_connection_client (struct GNUNET_CLIENT_Connection 
*connection,
+                                       const struct GNUNET_MQ_Handler 
*handlers,
+                                       void *cls);
+
+
+void
+GNUNET_MQ_notify_sent (struct GNUNET_MQ_Message *mqm,
+                       void (*)(void*),
+                       void *cls);
+
+
+void
+GNUNET_MQ_notify_timeout (struct GNUNET_MQ_Message *mqm,
+                          void (*)(void*),
+                          void *cls);
+
+
+void
+GNUNET_MQ_notify_destroy (struct GNUNET_MQ_Message *mqm,
+                          void (*)(void*),
+                          void *cls);
+
+void
+GNUNET_MQ_destroy (struct GNUNET_MQ_MessageQueue *mq);
+
+#endif

Added: gnunet/src/set/set.h
===================================================================
--- gnunet/src/set/set.h                                (rev 0)
+++ gnunet/src/set/set.h        2013-04-17 00:44:29 UTC (rev 26911)
@@ -0,0 +1,189 @@
+/*
+     This file is part of GNUnet.
+     (C) 2012 Christian Grothoff (and other contributing authors)
+
+     GNUnet is free software; you can redistribute it and/or modify
+     it under the terms of the GNU General Public License as published
+     by the Free Software Foundation; either version 2, or (at your
+     option) any later version.
+
+     GNUnet 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 GNUnet; see the file COPYING.  If not, write to the
+     Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+     Boston, MA 02111-1307, USA.
+*/
+
+/**
+ * @author Florian Dold
+ * @file consensus/consensus.h
+ * @brief
+ */
+#ifndef SET_H
+#define SET_H
+
+#include "gnunet_common.h"
+
+
+/**
+ * The service sends up to GNUNET_SET_ACK_WINDOW messages per client handle,
+ * the client should send an ack every GNUNET_SET_ACK_WINDOW/2 messages.
+ */
+#define GNUNET_SET_ACK_WINDOW 8
+
+
+GNUNET_NETWORK_STRUCT_BEGIN
+
+struct SetCreateMessage
+{
+  /**
+   * Type: GNUNET_MESSAGE_TYPE_SET_CREATE
+   */
+  struct GNUNET_MessageHeader header;
+
+  /**
+   * Operation type, values of enum GNUNET_SET_OperationType
+   */
+  uint16_t operation GNUNET_PACKED;
+};
+
+
+struct ListenMessage
+{
+  /**
+   * Type: GNUNET_MESSAGE_TYPE_SET_LISTEN
+   */
+  struct GNUNET_MessageHeader header;
+
+  /**
+   * application id
+   */
+  struct GNUNET_HashCode app_id;
+
+  /**
+   * Operation type, values of enum GNUNET_SET_OperationType
+   */
+  uint16_t operation GNUNET_PACKED;
+
+  /**
+   * Operation type, values of enum GNUNET_SET_OperationType
+   */
+  uint16_t op GNUNET_PACKED;
+  
+};
+
+
+struct AcceptMessage
+{
+  /**
+   * Type: GNUNET_MESSAGE_TYPE_SET_ACCEPT
+   */
+  struct GNUNET_MessageHeader header;
+
+  /**
+   * request id of the request we want to accept
+   */
+  uint32_t request_id GNUNET_PACKED;
+
+
+  struct GNUNET_TIME_RelativeNBO timeout;
+};
+
+
+struct RequestMessage
+{
+  /**
+   * Type: GNUNET_MESSAGE_TYPE_SET_Request
+   */
+  struct GNUNET_MessageHeader header;
+
+  /**
+   * requesting peer
+   */
+  struct GNUNET_PeerIdentity peer_id;
+
+  /**
+   * request id of the request we want to accept
+   */
+  uint32_t request_id GNUNET_PACKED;
+
+  /* rest: inner message */
+};
+
+
+struct EvaluateMessage
+{
+  /**
+   * Type: GNUNET_MESSAGE_TYPE_SET_EVALUATE
+   */
+  struct GNUNET_MessageHeader header;
+
+  struct GNUNET_PeerIdentity other_peer;
+
+  struct GNUNET_HashCode app_id;
+
+  struct GNUNET_TIME_RelativeNBO timeout;
+
+  /**
+   * id of our evaluate
+   */
+  uint32_t request_id GNUNET_PACKED;
+
+  /* rest: inner message */
+};
+
+
+struct ResultMessage
+{
+  /**
+   * Type: GNUNET_MESSAGE_TYPE_SET_RESULT
+   */
+  struct GNUNET_MessageHeader header;
+
+  /**
+   * id the result belongs to
+   */
+  uint32_t request_id GNUNET_PACKED;
+
+  uint16_t result_status GNUNET_PACKED;
+
+  uint16_t element_type GNUNET_PACKED;
+
+  /* rest: the actual element */
+};
+
+
+struct ElementMessage
+{
+  /**
+   * Type: GNUNET_MESSAGE_TYPE_SET_ADD or
+   *       GNUNET_MESSAGE_TYPE_SET_REMOVE
+   */
+  struct GNUNET_MessageHeader header;
+
+  uint16_t element_type GNUNET_PACKED;
+
+  /* rest: the actual element */
+};
+
+
+struct CancelMessage
+{
+  /**
+   * Type: GNUNET_MESSAGE_TYPE_SET_CANCEL
+   */
+  struct GNUNET_MessageHeader header;
+
+  /**
+   * id we want to cancel result belongs to
+   */
+  uint32_t request_id GNUNET_PACKED;
+};
+
+GNUNET_NETWORK_STRUCT_END
+
+#endif

Modified: gnunet/src/set/set_api.c
===================================================================
--- gnunet/src/set/set_api.c    2013-04-16 22:21:50 UTC (rev 26910)
+++ gnunet/src/set/set_api.c    2013-04-17 00:44:29 UTC (rev 26911)
@@ -0,0 +1,395 @@
+/*
+     This file is part of GNUnet.
+     (C) 2012 Christian Grothoff (and other contributing authors)
+
+     GNUnet is free software; you can redistribute it and/or modify
+     it under the terms of the GNU General Public License as published
+     by the Free Software Foundation; either version 3, or (at your
+     option) any later version.
+
+     GNUnet 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 GNUnet; see the file COPYING.  If not, write to the
+     Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+     Boston, MA 02111-1307, USA.
+*/
+
+/**
+ * @file set/set_api.c
+ * @brief api for the set service
+ * @author Florian Dold
+ */
+#include "platform.h"
+#include "gnunet_util_lib.h"
+#include "gnunet_protocols.h"
+#include "gnunet_client_lib.h"
+#include "gnunet_set_service.h"
+#include "set.h"
+#include "mq.h"
+
+
+#define LOG(kind,...) GNUNET_log_from (kind, "set-api",__VA_ARGS__)
+
+/**
+ * Opaque handle to a set.
+ */
+struct GNUNET_SET_Handle
+{
+  struct GNUNET_CLIENT_Connection *client;
+  struct GNUNET_MQ_MessageQueue *mq;
+  unsigned int messages_since_ack;
+};
+
+/**
+ * Opaque handle to a set operation request from another peer.
+ */
+struct GNUNET_SET_Request
+{
+  uint32_t request_id;
+  int accepted;
+};
+
+
+struct GNUNET_SET_OperationHandle
+{
+  GNUNET_SET_ResultIterator result_cb;
+  void *result_cls;
+  struct GNUNET_SET_Handle *set;
+  uint32_t request_id;
+};
+
+
+/**
+ * Opaque handle to a listen operation.
+ */
+struct GNUNET_SET_ListenHandle
+{
+  struct GNUNET_CLIENT_Connection *client;
+  struct GNUNET_MQ_MessageQueue* mq;
+  GNUNET_SET_ListenCallback listen_cb;
+  void *listen_cls;
+};
+
+
+void
+handle_result (void *cls, struct GNUNET_MessageHeader *mh)
+{
+  struct ResultMessage *msg = (struct ResultMessage *) mh;
+  struct GNUNET_SET_Handle *set = cls;
+  struct GNUNET_SET_OperationHandle *oh;
+  struct GNUNET_SET_Element e;
+
+  if (set->messages_since_ack >= GNUNET_SET_ACK_WINDOW/2)
+  {
+    struct GNUNET_MQ_Message *mqm;
+    mqm = GNUNET_MQ_msg_raw (GNUNET_MESSAGE_TYPE_SET_ACK);
+    GNUNET_MQ_send (set->mq, mqm);
+  }
+
+  oh = GNUNET_MQ_assoc_remove (set->mq, ntohl (msg->request_id));
+  GNUNET_break (NULL != oh);
+  if (htons (msg->result_status) != GNUNET_SET_STATUS_OK)
+  {
+    oh->result_cb (oh->result_cls, NULL, htons (msg->result_status));
+    GNUNET_free (oh);
+    return;
+  }
+  e.data = &msg[1];
+  e.size = ntohs (mh->size) - sizeof (struct ResultMessage);
+  e.type = msg->element_type;
+  oh->result_cb (oh->result_cls, &e, htons (msg->result_status));
+}
+
+void
+handle_request (void *cls, struct GNUNET_MessageHeader *mh)
+{
+  struct RequestMessage *msg = (struct RequestMessage *) mh;
+  struct GNUNET_SET_ListenHandle *lh = cls;
+  struct GNUNET_SET_Request *req;
+
+  req = GNUNET_new (struct GNUNET_SET_Request);
+  req->request_id = ntohl (msg->request_id);
+  lh->listen_cb (lh->listen_cls, &msg->peer_id, &mh[1], req);
+  if (GNUNET_NO == req->accepted)
+    GNUNET_free (req);
+}
+
+
+/**
+ * Create an empty set, supporting the specified operation.
+ *
+ * @param cfg configuration to use for connecting to the
+ *        set service
+ * @param op operation supported by the set
+ *        Note that the operation has to be specified
+ *        beforehand, as certain set operations need to maintain
+ *        data structures spefific to the operation
+ * @return a handle to the set
+ */
+struct GNUNET_SET_Handle *
+GNUNET_SET_create (struct GNUNET_CONFIGURATION_Handle *cfg,
+                   enum GNUNET_SET_OperationType op)
+{
+  struct GNUNET_SET_Handle *set;
+  struct GNUNET_MQ_Message *mqm;
+  struct SetCreateMessage *msg;
+  static const struct GNUNET_MQ_Handler mq_handlers[] = {
+    {handle_result, GNUNET_MESSAGE_TYPE_SET_RESULT},
+    GNUNET_MQ_HANDLERS_END
+  };
+
+  set = GNUNET_new (struct GNUNET_SET_Handle);
+  set->client = GNUNET_CLIENT_connect ("set", cfg);
+  GNUNET_assert (NULL != set->client);
+  set->mq = GNUNET_MQ_queue_for_connection_client (set->client, mq_handlers, 
set);
+  mqm = GNUNET_MQ_msg (msg, GNUNET_MESSAGE_TYPE_SET_CREATE);
+  msg->operation = htons (op);
+  GNUNET_MQ_send (set->mq, mqm);
+  return set;
+}
+
+
+/**
+ * Add an element to the given set.
+ * After the element has been added (in the sense of being
+ * transmitted to the set service), cont will be called.
+ * Calls to add_element can be queued
+ *
+ * @param set set to add element to
+ * @param element element to add to the set
+ * @param cont continuation called after the element has been added
+ * @param cont_cls closure for cont
+ */
+void
+GNUNET_SET_add_element (struct GNUNET_SET_Handle *set,
+                        const struct GNUNET_SET_Element *element,
+                        GNUNET_SET_Continuation cont,
+                        void *cont_cls)
+{
+  struct GNUNET_MQ_Message *mqm;
+  struct ElementMessage *msg;
+
+  mqm = GNUNET_MQ_msg_extra (msg, element->size, GNUNET_MESSAGE_TYPE_SET_ADD);
+  msg->element_type = element->type;
+  memcpy (&msg[1], element->data, element->size);
+  GNUNET_MQ_notify_sent (mqm, cont, cont_cls);
+  GNUNET_MQ_send (set->mq, mqm);
+}
+
+
+/**
+ * Remove an element to the given set.
+ * After the element has been removed (in the sense of the
+ * request being transmitted to the set service), cont will be called.
+ * Calls to remove_element can be queued
+ *
+ * @param set set to remove element from
+ * @param element element to remove from the set
+ * @param cont continuation called after the element has been removed
+ * @param cont_cls closure for cont
+ */
+void
+GNUNET_SET_remove_element (struct GNUNET_SET_Handle *set,
+                           const struct GNUNET_SET_Element *element,
+                           GNUNET_SET_Continuation cont,
+                           void *cont_cls)
+{
+  struct GNUNET_MQ_Message *mqm;
+  struct ElementMessage *msg;
+
+  mqm = GNUNET_MQ_msg_extra (msg, element->size, 
GNUNET_MESSAGE_TYPE_SET_REMOVE);
+  msg->element_type = element->type;
+  memcpy (&msg[1], element->data, element->size);
+  GNUNET_MQ_notify_sent (mqm, cont, cont_cls);
+  GNUNET_MQ_send (set->mq, mqm);
+}
+
+
+/**
+ * Destroy the set handle, and free all associated resources.
+ */
+void
+GNUNET_SET_destroy (struct GNUNET_SET_Handle *set)
+{
+  GNUNET_CLIENT_disconnect (set->client);
+  set->client = NULL;
+  GNUNET_MQ_destroy (set->mq);
+  set->mq = NULL;
+}
+
+static void
+operation_destroy (void *cls)
+{
+  struct GNUNET_SET_OperationHandle *oh = cls;
+  struct GNUNET_SET_OperationHandle *oh_assoc;
+
+  oh_assoc = GNUNET_MQ_assoc_remove (oh->set->mq, oh->request_id);
+  GNUNET_assert (oh_assoc == oh);
+}
+
+
+/**
+ * Evaluate a set operation with our set and the set of another peer.
+ *
+ * @param set set to use
+ * @param other_peer peer with the other set
+ * @param app_id hash for the application using the set
+ * @param context_msg additional information for the request
+ * @param result_cb called on error or success
+ * @param result_cls closure for result_cb
+ * @return a handle to cancel the operation
+ */
+struct GNUNET_SET_OperationHandle *
+GNUNET_SET_evaluate (struct GNUNET_SET_Handle *set,
+                     const struct GNUNET_PeerIdentity *other_peer,
+                     const struct GNUNET_HashCode *app_id,
+                     const struct GNUNET_MessageHeader *context_msg,
+                     struct GNUNET_TIME_Relative timeout,
+                     enum GNUNET_SET_ResultMode result_mode,
+                     GNUNET_SET_ResultIterator result_cb,
+                     void *result_cls)
+{
+  struct GNUNET_MQ_Message *mqm;
+  struct EvaluateMessage *msg;
+  struct GNUNET_SET_OperationHandle *oh;
+
+  oh = GNUNET_new (struct GNUNET_SET_OperationHandle);
+  oh->result_cb = result_cb;
+  oh->result_cls = result_cls;
+  oh->set = set;
+
+  mqm = GNUNET_MQ_msg_extra (msg, htons(context_msg->size), 
GNUNET_MESSAGE_TYPE_SET_EVALUATE);
+  msg->request_id = htonl (GNUNET_MQ_assoc_add (set->mq, mqm, oh));
+  msg->other_peer = *other_peer;
+  msg->app_id = *app_id;
+  msg->timeout = GNUNET_TIME_relative_hton (timeout);
+  memcpy (&msg[1], context_msg, htons (context_msg->size));
+  GNUNET_MQ_notify_timeout (mqm, operation_destroy, oh);
+  GNUNET_MQ_notify_destroy (mqm, operation_destroy, oh);
+  GNUNET_MQ_send (set->mq, mqm);
+
+  return oh;
+}
+
+
+/**
+ * Wait for set operation requests for the given application id
+ * 
+ * @param cfg configuration to use for connecting to
+ *            the set service
+ * @param operation operation we want to listen for
+ * @param app_id id of the application that handles set operation requests
+ * @param listen_cb called for each incoming request matching the operation
+ *                  and application id
+ * @param listen_cls handle for listen_cb
+ * @return a handle that can be used to cancel the listen operation
+ */
+struct GNUNET_SET_ListenHandle *
+GNUNET_SET_listen (struct GNUNET_CONFIGURATION_Handle *cfg,
+                   enum GNUNET_SET_OperationType operation,
+                   const struct GNUNET_HashCode *app_id,
+                   GNUNET_SET_ListenCallback listen_cb,
+                   void *listen_cls)
+{
+  struct GNUNET_SET_ListenHandle *lh;
+  struct GNUNET_MQ_Message *mqm;
+  struct ListenMessage *msg;
+  static const struct GNUNET_MQ_Handler mq_handlers[] = {
+    {handle_request, GNUNET_MESSAGE_TYPE_SET_REQUEST},
+    GNUNET_MQ_HANDLERS_END
+  };
+
+  lh = GNUNET_new (struct GNUNET_SET_ListenHandle);
+  lh->client = GNUNET_CLIENT_connect ("set", cfg);
+  lh->listen_cb = listen_cb;
+  lh->listen_cls = listen_cls;
+  GNUNET_assert (NULL != lh->client);
+  lh->mq = GNUNET_MQ_queue_for_connection_client (lh->client, mq_handlers, lh);
+  mqm = GNUNET_MQ_msg (msg, GNUNET_MESSAGE_TYPE_SET_LISTEN);
+  msg->operation = htons (operation);
+  msg->app_id = *app_id;
+  GNUNET_MQ_send (lh->mq, mqm);
+
+  return lh;
+}
+
+
+/**
+ * Cancel the given listen operation.
+ *
+ * @param lh handle for the listen operation
+ */
+void
+GNUNET_SET_listen_cancel (struct GNUNET_SET_ListenHandle *lh)
+{
+  GNUNET_MQ_destroy (lh->mq);
+  lh->mq = NULL;
+  GNUNET_CLIENT_disconnect (lh->client);
+  lh->client = NULL;
+  lh->listen_cb = NULL;
+  lh->listen_cls = NULL;
+}
+
+
+/**
+ * Accept a request we got via GNUNET_SET_listen
+ *
+ * @param request request to accept
+ * @param set set used for the requested operation 
+ * @param timeout timeout for the set operation
+ * @param result_cb callback for the results
+ * @param cls closure for result_cb
+ */
+struct GNUNET_SET_OperationHandle *
+GNUNET_SET_accept (struct GNUNET_SET_Request *request,
+                   struct GNUNET_SET_Handle *set,
+                   struct GNUNET_TIME_Relative timeout,
+                   enum GNUNET_SET_ResultMode result_mode,
+                   GNUNET_SET_ResultIterator result_cb,
+                   void *result_cls)
+{
+  struct GNUNET_MQ_Message *mqm;
+  struct AcceptMessage *msg;
+  struct GNUNET_SET_OperationHandle *oh;
+
+  /* don't accept a request twice! */
+  GNUNET_assert (GNUNET_NO == request->accepted);
+  request->accepted = GNUNET_YES;
+
+  oh = GNUNET_new (struct GNUNET_SET_OperationHandle);
+  oh->result_cb = result_cb;
+  oh->result_cls = result_cls;
+  oh->set = set;
+
+  mqm = GNUNET_MQ_msg (msg , GNUNET_MESSAGE_TYPE_SET_ACCEPT);
+  msg->timeout = GNUNET_TIME_relative_hton (timeout);
+  msg->request_id = htonl (request->request_id);
+  GNUNET_MQ_notify_timeout (mqm, operation_destroy, oh);
+  GNUNET_MQ_notify_destroy (mqm, operation_destroy, oh);
+  GNUNET_MQ_send (set->mq, mqm);
+
+  return oh;
+}
+
+
+/**
+ * Cancel the given set operation.
+ *
+ * @param op set operation to cancel
+ */
+void
+GNUNET_SET_operation_cancel (struct GNUNET_SET_OperationHandle *h)
+{
+  struct GNUNET_MQ_Message *mqm;
+  struct GNUNET_SET_OperationHandle *h_assoc;
+
+  h_assoc = GNUNET_MQ_assoc_remove (h->set->mq, h->request_id);
+  GNUNET_assert (h_assoc == h);
+  mqm = GNUNET_MQ_msg_raw (GNUNET_MESSAGE_TYPE_SET_CANCEL);
+  GNUNET_MQ_send (h->set->mq, mqm);
+}
+

Modified: gnunet/src/set/test_set_api.c
===================================================================
--- gnunet/src/set/test_set_api.c       2013-04-16 22:21:50 UTC (rev 26910)
+++ gnunet/src/set/test_set_api.c       2013-04-17 00:44:29 UTC (rev 26911)
@@ -25,7 +25,29 @@
 #include "platform.h"
 #include "gnunet_util_lib.h"
 #include "gnunet_testing_lib.h"
+#include "gnunet_set_service.h"
 
+
+/**
+ * Signature of the 'main' function for a (single-peer) testcase that
+ * is run using 'GNUNET_TESTING_peer_run'.
+ * 
+ * @param cls closure
+ * @param cfg configuration of the peer that was started
+ * @param peer identity of the peer that was created
+ */
+static void
+run (void *cls,
+     const struct GNUNET_CONFIGURATION_Handle *cfg,
+     struct GNUNET_TESTING_Peer *peer)
+{
+  struct GNUNET_SET_Handle *set1;
+  struct GNUNET_SET_Handle *set2;
+
+  set1 = GNUNET_SET_create (GNUNET_SET_OPERATION_UNION);
+  set2 = GNUNET_SET_create (GNUNET_SET_OPERATION_UNION);
+}
+
 int
 main (int argc, char **argv)
 {




reply via email to

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