X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=src%2Ftestbed%2Ftestbed_logger_api.c;h=56290221860ab645d9c0b82084a237305d4fc7a7;hb=27c12911f4f2aba2d90099270d70de846e83854f;hp=674a170d36e5725ee9405c0dcf3c30655d5e4835;hpb=0793e4b7af79a49bf1bc275be95f306136ac8cbb;p=oweals%2Fgnunet.git diff --git a/src/testbed/testbed_logger_api.c b/src/testbed/testbed_logger_api.c index 674a170d3..562902218 100644 --- a/src/testbed/testbed_logger_api.c +++ b/src/testbed/testbed_logger_api.c @@ -21,7 +21,7 @@ /** * @file testbed/testbed_logger_api.c * @brief Client-side routines for communicating with the tesbted logger service - * @author Sree Harsha Totakura + * @author Sree Harsha Totakura */ #include "platform.h" @@ -92,6 +92,9 @@ struct GNUNET_TESTBED_LOGGER_Handle */ struct GNUNET_CLIENT_Connection *client; + /** + * The transport handle + */ struct GNUNET_CLIENT_TransmitHandle *th; /** @@ -104,22 +107,61 @@ struct GNUNET_TESTBED_LOGGER_Handle */ struct MessageQueue *mq_tail; - GNUNET_SCHEDULER_TaskIdentifier flush_completion_task; - + /** + * Flush completion callback + */ GNUNET_TESTBED_LOGGER_FlushCompletion cb; + /** + * Closure for the above callback + */ void *cb_cls; + /** + * Local buffer for data to be transmitted + */ void *buf; + /** + * The size of the local buffer + */ size_t bs; + /** + * Number of bytes wrote since last flush + */ size_t bwrote; + /** + * How long after should we retry sending a message to the service? + */ struct GNUNET_TIME_Relative retry_backoff; + + /** + * Task to call the flush completion callback + */ + GNUNET_SCHEDULER_TaskIdentifier flush_completion_task; + + /** + * Task to be executed when flushing takes too long + */ + GNUNET_SCHEDULER_TaskIdentifier timeout_flush_task; }; +/** + * Cancels the flush timeout task + * + * @param h handle to the logger + */ +static void +cancel_timeout_flush (struct GNUNET_TESTBED_LOGGER_Handle *h) +{ + GNUNET_SCHEDULER_cancel (h->timeout_flush_task); + h->timeout_flush_task = GNUNET_SCHEDULER_NO_TASK; +} + + /** * Task to call the flush completion notification * @@ -129,7 +171,7 @@ struct GNUNET_TESTBED_LOGGER_Handle static void call_flush_completion (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) { - struct GNUNET_TESTBED_LOGGER_Handle *h = cls; + struct GNUNET_TESTBED_LOGGER_Handle *h = cls; GNUNET_TESTBED_LOGGER_FlushCompletion cb; void *cb_cls; size_t bw; @@ -141,6 +183,8 @@ call_flush_completion (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) h->cb = NULL; cb_cls = h->cb_cls; h->cb_cls = NULL; + if (GNUNET_SCHEDULER_NO_TASK != h->timeout_flush_task) + cancel_timeout_flush (h); if (NULL != cb) cb (cb_cls, bw); } @@ -266,7 +310,7 @@ dispatch_buffer (struct GNUNET_TESTBED_LOGGER_Handle *h) msg = GNUNET_realloc (h->buf, msize); h->buf = NULL; memmove (&msg[1], msg, h->bs); - h->bs = 0; + h->bs = 0; msg->type = htons (GNUNET_MESSAGE_TYPE_TESTBED_LOGGER_MSG); msg->size = htons (msize); queue_message (h, msg); @@ -285,7 +329,7 @@ GNUNET_TESTBED_LOGGER_connect (const struct GNUNET_CONFIGURATION_Handle *cfg) { struct GNUNET_TESTBED_LOGGER_Handle *h; struct GNUNET_CLIENT_Connection *client; - + client = GNUNET_CLIENT_connect ("testbed-logger", cfg); if (NULL == client) return NULL; @@ -330,7 +374,7 @@ GNUNET_TESTBED_LOGGER_disconnect (struct GNUNET_TESTBED_LOGGER_Handle *h) void GNUNET_TESTBED_LOGGER_write (struct GNUNET_TESTBED_LOGGER_Handle *h, const void *data, size_t size) -{ +{ size_t fit_size; GNUNET_assert (0 != size); @@ -354,20 +398,55 @@ GNUNET_TESTBED_LOGGER_write (struct GNUNET_TESTBED_LOGGER_Handle *h, } +/** + * Task to be executed when flushing our local buffer takes longer than timeout + * given to GNUNET_TESTBED_LOGGER_flush(). The flush completion callback will + * be called with 0 as the amount of data sent. + * + * @param cls the logger handle + * @param tc scheduler task context + */ +static void +timeout_flush (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) +{ + struct GNUNET_TESTBED_LOGGER_Handle *h = cls; + GNUNET_TESTBED_LOGGER_FlushCompletion cb; + void *cb_cls; + + h->timeout_flush_task = GNUNET_SCHEDULER_NO_TASK; + cb = h->cb; + h->cb = NULL; + cb_cls = h->cb_cls; + h->cb_cls = NULL; + if (GNUNET_SCHEDULER_NO_TASK != h->flush_completion_task) + { + GNUNET_SCHEDULER_cancel (h->flush_completion_task); + h->flush_completion_task = GNUNET_SCHEDULER_NO_TASK; + } + if (NULL != cb) + cb (cb_cls, 0); +} + + /** * Flush the buffered data to the logger service * * @param h the logger handle + * @param timeout how long to wait before calling the flust completion callback * @param cb the callback to call after the data is flushed * @param cb_cls the closure for the above callback */ void GNUNET_TESTBED_LOGGER_flush (struct GNUNET_TESTBED_LOGGER_Handle *h, + struct GNUNET_TIME_Relative timeout, GNUNET_TESTBED_LOGGER_FlushCompletion cb, void *cb_cls) { h->cb = cb; h->cb_cls = cb_cls; + GNUNET_assert (GNUNET_SCHEDULER_NO_TASK == h->timeout_flush_task); + h->timeout_flush_task = + GNUNET_SCHEDULER_add_delayed (timeout, &timeout_flush, h); if (NULL == h->buf) { trigger_flush_notification (h); @@ -378,7 +457,9 @@ GNUNET_TESTBED_LOGGER_flush (struct GNUNET_TESTBED_LOGGER_Handle *h, /** - * Cancel notification upon flush. + * Cancel notification upon flush. Should only be used when the flush + * completion callback given to GNUNET_TESTBED_LOGGER_flush() is not already + * called. * * @param h the logger handle */ @@ -390,6 +471,8 @@ GNUNET_TESTBED_LOGGER_flush_cancel (struct GNUNET_TESTBED_LOGGER_Handle *h) GNUNET_SCHEDULER_cancel (h->flush_completion_task); h->flush_completion_task = GNUNET_SCHEDULER_NO_TASK; } + if (GNUNET_SCHEDULER_NO_TASK != h->timeout_flush_task) + cancel_timeout_flush (h); h->cb = NULL; h->cb_cls = NULL; }