handle_peer_config (struct GNUNET_TESTBED_Controller *c,
const struct GNUNET_TESTBED_PeerConfigurationInformationMessage *msg)
{
- struct GNUNET_TESTBED_Operation *op;
+ struct OperationContext *opc;
struct GNUNET_TESTBED_Peer *peer;
struct PeerInfoData *data;
struct PeerInfoData2 *response_data;
uint64_t op_id;
op_id = GNUNET_ntohll (msg->operation_id);
- for (op = c->op_head; NULL != op; op = op->next)
- {
- if (op->operation_id == op_id)
- break;
- }
- if (NULL == op)
+ if (NULL == (opc = find_opc (c, op_id)))
{
- LOG_DEBUG ("Operation not found");
+ LOG_DEBUG ("Operation not found\n");
return GNUNET_YES;
}
- data = op->data;
+ data = opc->data;
GNUNET_assert (NULL != data);
peer = data->peer;
GNUNET_assert (NULL != peer);
GNUNET_assert (ntohl (msg->peer_id) == peer->unique_id);
+ opc->completed = GNUNET_YES;
if (0 == (c->event_mask & (1L << GNUNET_TESTBED_ET_OPERATION_FINISHED)))
{
LOG_DEBUG ("Skipping operation callback as flag not set\n");
- GNUNET_CONTAINER_DLL_remove (c->op_head, c->op_tail, op);
return GNUNET_YES;
}
response_data = GNUNET_malloc (sizeof (struct PeerInfoData2));
response_data->pit = data->pit;
GNUNET_free (data);
+ opc->data = NULL;
info.type = GNUNET_TESTBED_ET_OPERATION_FINISHED;
- info.details.operation_finished.operation = op;
+ info.details.operation_finished.operation = opc->op;
info.details.operation_finished.op_cls = NULL;
info.details.operation_finished.emsg = NULL;
info.details.operation_finished.pit = response_data->pit;
if (Z_OK != (ret = uncompress ((Bytef *) config, &config_size,
(const Bytef *) &msg[1], (uLong) msize)))
GNUNET_assert (0);
- cfg = GNUNET_CONFIGURATION_create ();
+ cfg = GNUNET_CONFIGURATION_create (); /* Freed in oprelease_peer_getinfo */
GNUNET_assert (GNUNET_OK ==
GNUNET_CONFIGURATION_deserialize (cfg, config,
(size_t) config_size,
GNUNET_assert (0); /* never reach here */
break;
}
- op->data = response_data;
- GNUNET_CONTAINER_DLL_remove (c->op_head, c->op_tail, op);
+ opc->data = response_data;
c->cc (c->cc_cls, &info);
return GNUNET_YES;
}
case OP_PEER_DESTROY:
case OP_PEER_START:
case OP_PEER_STOP:
+ case OP_PEER_INFO:
GNUNET_TESTBED_operation_release_ (operation);
return;
- case OP_PEER_INFO:
- {
- struct PeerInfoData2 *data;
-
- data = operation->data;
- switch (data->pit)
- {
- case GNUNET_TESTBED_PIT_IDENTITY:
- GNUNET_free (data->details.peer_identity);
- break;
- case GNUNET_TESTBED_PIT_CONFIGURATION:
- GNUNET_CONFIGURATION_destroy (data->details.cfg);
- break;
- case GNUNET_TESTBED_PIT_GENERIC:
- GNUNET_assert (0); /* never reach here */
- break;
- }
- }
- GNUNET_free_non_null (operation->data);
- break;
case OP_OVERLAY_CONNECT:
GNUNET_free_non_null (operation->data);
break;
}
+/**
+ * Function to called when a peer get information operation is ready
+ *
+ * @param cls the closure from GNUNET_TESTBED_operation_create_()
+ */
+static void
+opstart_peer_getinfo (void *cls)
+{
+ struct OperationContext *opc = cls;
+ struct PeerInfoData *data;
+ struct GNUNET_TESTBED_PeerGetConfigurationMessage *msg;
+
+ data = opc->data;
+ GNUNET_assert (NULL != data);
+ msg = GNUNET_malloc (sizeof (struct
+ GNUNET_TESTBED_PeerGetConfigurationMessage));
+ msg->header.size = htons
+ (sizeof (struct GNUNET_TESTBED_PeerGetConfigurationMessage));
+ msg->header.type = htons (GNUNET_MESSAGE_TYPE_TESTBED_GETPEERCONFIG);
+ msg->peer_id = htonl (data->peer->unique_id);
+ msg->operation_id = GNUNET_htonll (opc->id);
+ GNUNET_CONTAINER_DLL_insert_tail (opc->c->ocq_head, opc->c->ocq_tail, opc);
+ GNUNET_TESTBED_queue_message_ (opc->c, &msg->header);
+}
+
+
+/**
+ * Callback which will be called when peer stop type operation is released
+ *
+ * @param cls the closure from GNUNET_TESTBED_operation_create_()
+ */
+static void
+oprelease_peer_getinfo (void *cls)
+{
+ struct OperationContext *opc = cls;
+ struct PeerInfoData2 *data;
+
+ if (GNUNET_YES != opc->completed)
+ GNUNET_free_non_null (opc->data);
+ else
+ {
+ data = opc->data;
+ GNUNET_assert (NULL != data);
+ switch (data->pit)
+ {
+ case GNUNET_TESTBED_PIT_CONFIGURATION:
+ GNUNET_CONFIGURATION_destroy (data->details.cfg);
+ break;
+ case GNUNET_TESTBED_PIT_IDENTITY:
+ GNUNET_free (data->details.peer_identity);
+ break;
+ default:
+ GNUNET_assert (0); /* We should never reach here */
+ }
+ GNUNET_free (data);
+ }
+ GNUNET_CONTAINER_DLL_remove (opc->c->ocq_head, opc->c->ocq_tail, opc);
+ GNUNET_free (opc);
+}
+
+
+
/**
* Lookup a peer by ID.
*
GNUNET_TESTBED_peer_get_information (struct GNUNET_TESTBED_Peer *peer,
enum GNUNET_TESTBED_PeerInformationType pit)
{
- struct GNUNET_TESTBED_PeerGetConfigurationMessage *msg;
- struct GNUNET_TESTBED_Operation *op;
+ struct OperationContext *opc;
struct PeerInfoData *data;
-
+
GNUNET_assert (GNUNET_TESTBED_PIT_GENERIC != pit);
data = GNUNET_malloc (sizeof (struct PeerInfoData));
data->peer = peer;
data->pit = pit;
- op = GNUNET_malloc (sizeof (struct GNUNET_TESTBED_Operation));
- op->type = OP_PEER_INFO;
- op->operation_id = peer->controller->operation_counter++;
- op->controller = peer->controller;
- op->data = data;
- msg = GNUNET_malloc (sizeof (struct
- GNUNET_TESTBED_PeerGetConfigurationMessage));
- msg->header.size = htons
- (sizeof (struct GNUNET_TESTBED_PeerGetConfigurationMessage));
- msg->header.type = htons (GNUNET_MESSAGE_TYPE_TESTBED_GETPEERCONFIG);
- msg->peer_id = htonl (peer->unique_id);
- msg->operation_id = GNUNET_htonll (op->operation_id);
- GNUNET_CONTAINER_DLL_insert_tail (peer->controller->op_head,
- peer->controller->op_tail, op);
- GNUNET_TESTBED_queue_message_ (peer->controller, &msg->header);
- return op;
+ opc = GNUNET_malloc (sizeof (struct OperationContext));
+ opc->c = peer->controller;
+ opc->data = data;
+ opc->type = OP_PEER_INFO;
+ opc->id = opc->c->operation_counter++;
+ opc->op = GNUNET_TESTBED_operation_create_ (opc, &opstart_peer_getinfo,
+ &oprelease_peer_getinfo);
+ GNUNET_TESTBED_operation_queue_insert_ (opc->c->opq_peer_create, opc->op);
+ return opc->op;
}