*/
struct GSF_LocalClient *lc;
+ /**
+ * Task scheduled to destroy the request.
+ */
+ GNUNET_SCHEDULER_TaskIdentifier kill_task;
+
};
}
+/**
+ * Free the given client request.
+ *
+ * @param cls the client request to free
+ * @param tc task context
+ */
+static void
+client_request_destroy (void *cls,
+ const struct GNUNET_SCHEDULER_TaskContext *tc)
+{
+ struct ClientRequest *cr = cls;
+ struct GSF_LocalClient *lc;
+
+ cr->kill_task = GNUNET_SCHEDULER_NO_TASK;
+ lc = cr->lc;
+ GNUNET_CONTAINER_DLL_remove (lc->cr_head,
+ lc->cr_tail,
+ cr);
+ GSF_pending_request_cancel_ (cr->pr);
+ GNUNET_STATISTICS_update (GSF_stats,
+ gettext_noop ("# client searches active"),
+ - 1,
+ GNUNET_NO);
+ GNUNET_free (cr);
+}
+
+
/**
* Handle a reply to a pending request. Also called if a request
* expires (then with data == NULL). The handler may be called
* expiration.
*
* @param cls user-specified closure
+ * @param eval evaluation of the result
* @param pr handle to the original pending request
+ * @param reply_anonymity_level anonymity level for the reply, UINT32_MAX for "unknown"
* @param expiration when does 'data' expire?
* @param type type of the block
* @param data response data, NULL on request expiration
*/
static void
client_response_handler (void *cls,
+ enum GNUNET_BLOCK_EvaluationResult eval,
struct GSF_PendingRequest *pr,
+ uint32_t reply_anonymity_level,
struct GNUNET_TIME_Absolute expiration,
enum GNUNET_BLOCK_Type type,
const void *data,
GNUNET_assert (pr == cr->pr);
lc = cr->lc;
msize = sizeof (struct PutMessage) + data_len;
- pm = GNUNET_malloc (msize);
- pm->header.type = htons (GNUNET_MESSAGE_TYPE_FS_PUT);
- pm->header.size = htons (msize);
- pm->type = htonl (type);
- pm->expiration = GNUNET_TIME_absolute_hton (expiration);
- memcpy (&pm[1], data, data_len);
- GSF_local_client_transmit_ (lc, &pm->header);
-#if DEBUG_FS
+ {
+ char buf[msize];
+
+ pm = (struct PutMessage*) buf;
+ pm->header.type = htons (GNUNET_MESSAGE_TYPE_FS_PUT);
+ pm->header.size = htons (msize);
+ pm->type = htonl (type);
+ pm->expiration = GNUNET_TIME_absolute_hton (expiration);
+ memcpy (&pm[1], data, data_len);
+ GSF_local_client_transmit_ (lc, &pm->header);
+ }
+#if DEBUG_FS_CLIENT
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"Queued reply to query `%s' for local client\n",
GNUNET_h2s (&prd->query),
(unsigned int) prd->type);
#endif
+ if (eval != GNUNET_BLOCK_EVALUATION_OK_LAST)
+ return;
+ cr->kill_task = GNUNET_SCHEDULER_add_now (&client_request_destroy,
+ cr);
}
sc = (msize - sizeof (struct SearchMessage)) / sizeof (GNUNET_HashCode);
sm = (const struct SearchMessage*) message;
type = ntohl (sm->type);
-#if DEBUG_FS
+#if DEBUG_FS_CLIENT
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"Received request for `%s' of type %u from local client\n",
GNUNET_h2s (&sm->query),
}
if (cr != NULL)
{
-#if DEBUG_FS
+#if DEBUG_FS_CLIENT
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"Have existing request, merging content-seen lists.\n");
#endif
gettext_noop ("# client searches active"),
- 1,
GNUNET_NO);
+ if (GNUNET_SCHEDULER_NO_TASK != cr->kill_task)
+ GNUNET_SCHEDULER_cancel (cr->kill_task);
GNUNET_free (cr);
}
while (NULL != (res = pos->res_head))