[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)
{
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [GNUnet-SVN] r26911 - in gnunet/src: include set,
gnunet <=