X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=src%2Ftestbed%2Fgnunet-service-testbed_barriers.c;h=4450ddf777c2d59afd01f22e993fdda364be51af;hb=dd1927b960c7cea13733e061a11142274652ba27;hp=5668d03cfd506c09e2ca6028a66df3b9d20949b9;hpb=77139316eeecda84e45710d4dfd7c74dcff47942;p=oweals%2Fgnunet.git diff --git a/src/testbed/gnunet-service-testbed_barriers.c b/src/testbed/gnunet-service-testbed_barriers.c index 5668d03cf..4450ddf77 100644 --- a/src/testbed/gnunet-service-testbed_barriers.c +++ b/src/testbed/gnunet-service-testbed_barriers.c @@ -1,6 +1,6 @@ /* This file is part of GNUnet. - (C) 2008--2013 Christian Grothoff (and other contributing authors) + Copyright (C) 2008--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 @@ -14,14 +14,14 @@ 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. + Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. */ /** * @file testbed/gnunet-service-testbed_barriers.c * @brief barrier handling at the testbed controller - * @author Sree Harsha Totakura + * @author Sree Harsha Totakura */ #include "gnunet-service-testbed.h" @@ -199,13 +199,13 @@ struct Barrier /** * Identifier for the timeout task */ - GNUNET_SCHEDULER_TaskIdentifier tout_task; - + struct GNUNET_SCHEDULER_Task * tout_task; + /** * The status of this barrier */ enum GNUNET_TESTBED_BarrierStatus status; - + /** * Number of barriers wrapped in the above DLL */ @@ -235,7 +235,7 @@ struct Barrier * Quorum percentage to be reached */ uint8_t quorum; - + }; @@ -261,7 +261,7 @@ static struct GNUNET_SERVICE_Context *ctx; * @param buf where the callee should write the message * @return number of bytes written to buf */ -static size_t +static size_t transmit_ready_cb (void *cls, size_t size, void *buf) { struct ClientCtx *ctx = cls; @@ -271,12 +271,11 @@ transmit_ready_cb (void *cls, size_t size, void *buf) size_t wrote; ctx->tx = NULL; - wrote = 0; if ((0 == size) || (NULL == buf)) { GNUNET_assert (NULL != ctx->client); GNUNET_SERVER_client_drop (ctx->client); - ctx->client = NULL; + ctx->client = NULL; return 0; } mq = ctx->mq_head; @@ -306,8 +305,8 @@ queue_message (struct ClientCtx *ctx, struct GNUNET_MessageHeader *msg) { struct MessageQueue *mq; struct GNUNET_SERVER_Client *client = ctx->client; - - mq = GNUNET_malloc (sizeof (struct MessageQueue)); + + mq = GNUNET_new (struct MessageQueue); mq->msg = msg; LOG_DEBUG ("Queueing message of type %u, size %u for sending\n", ntohs (msg->type), ntohs (msg->size)); @@ -328,9 +327,12 @@ static void cleanup_clientctx (struct ClientCtx *ctx) { struct MessageQueue *mq; - + if (NULL != ctx->client) + { + GNUNET_SERVER_client_set_user_context_ (ctx->client, NULL, 0); GNUNET_SERVER_client_drop (ctx->client); + } if (NULL != ctx->tx) GNUNET_SERVER_notify_transmit_ready_cancel (ctx->tx); if (NULL != (mq = ctx->mq_head)) @@ -353,7 +355,7 @@ static void remove_barrier (struct Barrier *barrier) { struct ClientCtx *ctx; - + GNUNET_assert (GNUNET_YES == GNUNET_CONTAINER_multihashmap_remove (barrier_map, &barrier->hash, barrier)); @@ -394,7 +396,7 @@ cancel_wrappers (struct Barrier *barrier) * @param name the barrier name * @param status the status of the barrier * @param emsg the error message; should be non-NULL for - * status=BARRIER_STATUS_ERROR + * status=GNUNET_TESTBED_BARRIERSTATUS_ERROR */ static void send_client_status_msg (struct GNUNET_SERVER_Client *client, @@ -406,7 +408,7 @@ send_client_status_msg (struct GNUNET_SERVER_Client *client, size_t name_len; uint16_t msize; - GNUNET_assert ((NULL == emsg) || (BARRIER_STATUS_ERROR == status)); + GNUNET_assert ((NULL == emsg) || (GNUNET_TESTBED_BARRIERSTATUS_ERROR == status)); name_len = strlen (name); msize = sizeof (struct GNUNET_TESTBED_BarrierStatusMsg) + (name_len + 1) @@ -428,7 +430,7 @@ send_client_status_msg (struct GNUNET_SERVER_Client *client, * * @param barrier the corresponding barrier * @param emsg the error message; should be non-NULL for - * status=BARRIER_STATUS_ERROR + * status=GNUNET_TESTBED_BARRIERSTATUS_ERROR */ static void send_barrier_status_msg (struct Barrier *barrier, const char *emsg) @@ -461,7 +463,7 @@ handle_barrier_wait (void *cls, struct GNUNET_SERVER_Client *client, struct GNUNET_HashCode key; size_t name_len; uint16_t msize; - + msize = ntohs (message->size); if (msize <= sizeof (struct GNUNET_TESTBED_BarrierWait)) { @@ -482,28 +484,28 @@ handle_barrier_wait (void *cls, struct GNUNET_SERVER_Client *client, (void) memcpy (name, msg->name, name_len); LOG_DEBUG ("Received BARRIER_WAIT for barrier `%s'\n", name); GNUNET_CRYPTO_hash (name, name_len, &key); + GNUNET_free (name); if (NULL == (barrier = GNUNET_CONTAINER_multihashmap_get (barrier_map, &key))) { GNUNET_break (0); GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); - GNUNET_free (name); return; } client_ctx = GNUNET_SERVER_client_get_user_context (client, struct ClientCtx); if (NULL == client_ctx) { - client_ctx = GNUNET_malloc (sizeof (struct ClientCtx)); + client_ctx = GNUNET_new (struct ClientCtx); client_ctx->client = client; GNUNET_SERVER_client_keep (client); client_ctx->barrier = barrier; GNUNET_CONTAINER_DLL_insert_tail (barrier->head, barrier->tail, client_ctx); - GNUNET_SERVER_client_set_user_context (client, client_ctx); + GNUNET_SERVER_client_set_user_context (client, client_ctx); } barrier->nreached++; if ((barrier->num_wbarriers_reached == barrier->num_wbarriers) && (LOCAL_QUORUM_REACHED (barrier))) { - barrier->status = BARRIER_STATUS_CROSSED; + barrier->status = GNUNET_TESTBED_BARRIERSTATUS_CROSSED; send_barrier_status_msg (barrier, NULL); } GNUNET_SERVER_receive_done (client, GNUNET_OK); @@ -522,7 +524,7 @@ static void disconnect_cb (void *cls, struct GNUNET_SERVER_Client *client) { struct ClientCtx *client_ctx; - + if (NULL == client) return; client_ctx = GNUNET_SERVER_client_get_user_context (client, struct ClientCtx); @@ -551,7 +553,31 @@ GST_barriers_init (struct GNUNET_CONFIGURATION_Handle *cfg) GNUNET_SERVICE_OPTION_MANUAL_SHUTDOWN); srv = GNUNET_SERVICE_get_server (ctx); GNUNET_SERVER_add_handlers (srv, message_handlers); - GNUNET_SERVER_disconnect_notify (srv, &disconnect_cb, NULL); + GNUNET_SERVER_disconnect_notify (srv, &disconnect_cb, NULL); +} + + +/** + * Iterator over hash map entries. + * + * @param cls closure + * @param key current key code + * @param value value in the hash map + * @return #GNUNET_YES if we should continue to + * iterate, + * #GNUNET_NO if not. + */ +static int +barrier_destroy_iterator (void *cls, + const struct GNUNET_HashCode *key, + void *value) +{ + struct Barrier *barrier = value; + + GNUNET_assert (NULL != barrier); + cancel_wrappers (barrier); + remove_barrier (barrier); + return GNUNET_YES; } @@ -562,6 +588,10 @@ void GST_barriers_destroy () { GNUNET_assert (NULL != barrier_map); + GNUNET_assert (GNUNET_SYSERR != + GNUNET_CONTAINER_multihashmap_iterate (barrier_map, + &barrier_destroy_iterator, + NULL)); GNUNET_CONTAINER_multihashmap_destroy (barrier_map); GNUNET_assert (NULL != ctx); GNUNET_SERVICE_stop (ctx); @@ -581,7 +611,7 @@ GST_barriers_destroy () * @param emsg if the status were to be GNUNET_SYSERR, this parameter has the * error messsage */ -static void +static void wbarrier_status_cb (void *cls, const char *name, struct GNUNET_TESTBED_Barrier *b_, enum GNUNET_TESTBED_BarrierStatus status, @@ -596,18 +626,18 @@ wbarrier_status_cb (void *cls, const char *name, GNUNET_free (wrapper); switch (status) { - case BARRIER_STATUS_ERROR: + case GNUNET_TESTBED_BARRIERSTATUS_ERROR: LOG (GNUNET_ERROR_TYPE_ERROR, "Initialising barrier `%s' failed at a sub-controller: %s\n", barrier->name, (NULL != emsg) ? emsg : "NULL"); cancel_wrappers (barrier); if (NULL == emsg) emsg = "Initialisation failed at a sub-controller"; - barrier->status = BARRIER_STATUS_ERROR; + barrier->status = GNUNET_TESTBED_BARRIERSTATUS_ERROR; send_barrier_status_msg (barrier, emsg); return; - case BARRIER_STATUS_CROSSED: - if (BARRIER_STATUS_INITIALISED != barrier->status) + case GNUNET_TESTBED_BARRIERSTATUS_CROSSED: + if (GNUNET_TESTBED_BARRIERSTATUS_INITIALISED != barrier->status) { GNUNET_break_op (0); return; @@ -616,11 +646,11 @@ wbarrier_status_cb (void *cls, const char *name, if ((barrier->num_wbarriers_reached == barrier->num_wbarriers) && (LOCAL_QUORUM_REACHED (barrier))) { - barrier->status = BARRIER_STATUS_CROSSED; + barrier->status = GNUNET_TESTBED_BARRIERSTATUS_CROSSED; send_barrier_status_msg (barrier, NULL); } return; - case BARRIER_STATUS_INITIALISED: + case GNUNET_TESTBED_BARRIERSTATUS_INITIALISED: if (0 != barrier->status) { GNUNET_break_op (0); @@ -629,7 +659,7 @@ wbarrier_status_cb (void *cls, const char *name, barrier->num_wbarriers_inited++; if (barrier->num_wbarriers_inited == barrier->num_wbarriers) { - barrier->status = BARRIER_STATUS_INITIALISED; + barrier->status = GNUNET_TESTBED_BARRIERSTATUS_INITIALISED; send_barrier_status_msg (barrier, NULL); } return; @@ -648,9 +678,9 @@ static void fwd_tout_barrier_init (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) { struct Barrier *barrier = cls; - + cancel_wrappers (barrier); - barrier->status = BARRIER_STATUS_ERROR; + barrier->status = GNUNET_TESTBED_BARRIERSTATUS_ERROR; send_barrier_status_msg (barrier, "Timedout while propagating barrier initialisation\n"); remove_barrier (barrier); @@ -682,7 +712,7 @@ GST_handle_barrier_init (void *cls, struct GNUNET_SERVER_Client *client, size_t name_len; unsigned int cnt; uint16_t msize; - + if (NULL == GST_context) { GNUNET_break_op (0); @@ -710,14 +740,14 @@ GST_handle_barrier_init (void *cls, struct GNUNET_SERVER_Client *client, LOG_DEBUG ("Received BARRIER_INIT for barrier `%s'\n", name); if (GNUNET_YES == GNUNET_CONTAINER_multihashmap_contains (barrier_map, &hash)) { - - send_client_status_msg (client, name, BARRIER_STATUS_ERROR, + + send_client_status_msg (client, name, GNUNET_TESTBED_BARRIERSTATUS_ERROR, "A barrier with the same name already exists"); GNUNET_free (name); GNUNET_SERVER_receive_done (client, GNUNET_OK); return; } - barrier = GNUNET_malloc (sizeof (struct Barrier)); + barrier = GNUNET_new (struct Barrier); (void) memcpy (&barrier->hash, &hash, sizeof (struct GNUNET_HashCode)); barrier->quorum = msg->quorum; barrier->name = name; @@ -739,7 +769,7 @@ GST_handle_barrier_init (void *cls, struct GNUNET_SERVER_Client *client, GNUNET_break (0);/* May happen when we are connecting to the controller */ continue; } - wrapper = GNUNET_malloc (sizeof (struct WBarrier)); + wrapper = GNUNET_new (struct WBarrier); wrapper->barrier = barrier; GNUNET_CONTAINER_DLL_insert_tail (barrier->whead, barrier->wtail, wrapper); wrapper->hbarrier = GNUNET_TESTBED_barrier_init_ (slave->controller, @@ -751,8 +781,8 @@ GST_handle_barrier_init (void *cls, struct GNUNET_SERVER_Client *client, } if (NULL == barrier->whead) /* No further propagation */ { - barrier->status = BARRIER_STATUS_INITIALISED; - LOG_DEBUG ("Sending BARRIER_STATUS_INITIALISED for barrier `%s'\n", + barrier->status = GNUNET_TESTBED_BARRIERSTATUS_INITIALISED; + LOG_DEBUG ("Sending GNUNET_TESTBED_BARRIERSTATUS_INITIALISED for barrier `%s'\n", barrier->name); send_barrier_status_msg (barrier, NULL); }else @@ -790,7 +820,7 @@ GST_handle_barrier_cancel (void *cls, struct GNUNET_SERVER_Client *client, GNUNET_break_op (0); GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); return; - } + } if (client != GST_context->client) { GNUNET_break_op (0); @@ -819,7 +849,7 @@ GST_handle_barrier_cancel (void *cls, struct GNUNET_SERVER_Client *client, GNUNET_assert (NULL != barrier); cancel_wrappers (barrier); remove_barrier (barrier); - GNUNET_SERVER_receive_done (client, GNUNET_OK); + GNUNET_SERVER_receive_done (client, GNUNET_OK); } @@ -837,20 +867,20 @@ GST_handle_barrier_status (void *cls, struct GNUNET_SERVER_Client *client, const struct GNUNET_MessageHeader *message) { const struct GNUNET_TESTBED_BarrierStatusMsg *msg; - struct Barrier *barrier; + struct Barrier *barrier; struct ClientCtx *client_ctx; const char *name; struct GNUNET_HashCode key; enum GNUNET_TESTBED_BarrierStatus status; uint16_t msize; uint16_t name_len; - + if (NULL == GST_context) { GNUNET_break_op (0); GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); return; - } + } if (client != GST_context->client) { GNUNET_break_op (0); @@ -866,7 +896,7 @@ GST_handle_barrier_status (void *cls, struct GNUNET_SERVER_Client *client, } msg = (const struct GNUNET_TESTBED_BarrierStatusMsg *) message; status = ntohs (msg->status); - if (BARRIER_STATUS_CROSSED != status) + if (GNUNET_TESTBED_BARRIERSTATUS_CROSSED != status) { GNUNET_break_op (0); /* current we only expect BARRIER_CROSSED status message this way */