const char *sxcfg,
size_t sxcfg_size,
size_t scfg_size,
- int is_subordinate);
+ int is_subordinate);
+
+
+/**
+ * Functions of this signature are called when a peer has been successfully
+ * created
+ *
+ * @param cls the closure from GNUNET_TESTBED_peer_create()
+ * @param peer the handle for the created peer; NULL on any error during
+ * creation
+ * @param emsg NULL if peer is not NULL; else MAY contain the error description
+ */
+typedef void (*GNUNET_TESTBED_PeerCreateCallback) (void *cls,
+ struct GNUNET_TESTBED_Peer *peer,
+ const char *emsg);
/**
* @param controller controller process to use
* @param host host to run the peer on
* @param cfg configuration to use for the peer
- * @return handle to the peer (actual startup will happen asynchronously)
+ * @param cb the callback to call when the peer has been created
+ * @param cls the closure to the above callback
+ * @return the operation handle
*/
-struct GNUNET_TESTBED_Peer *
+struct GNUNET_TESTBED_Operation *
GNUNET_TESTBED_peer_create (struct GNUNET_TESTBED_Controller *controller,
struct GNUNET_TESTBED_Host *host,
- const struct GNUNET_CONFIGURATION_Handle *cfg);
+ const struct GNUNET_CONFIGURATION_Handle *cfg,
+ GNUNET_TESTBED_PeerCreateCallback cb,
+ void *cls);
/**
const struct GNUNET_MessageHeader *message)
{
const struct GNUNET_TESTBED_PeerCreateMessage *msg;
+ struct GNUNET_TESTBED_PeerCreateSuccessEventMessage *reply;
struct GNUNET_CONFIGURATION_Handle *cfg;
char *config;
size_t dest_size;
return;
}
peer_list_add (peer);
+ reply = GNUNET_malloc (sizeof (struct GNUNET_TESTBED_PeerCreateSuccessEventMessage));
+ reply->header.size = htons (sizeof (struct GNUNET_TESTBED_PeerCreateSuccessEventMessage));
+ reply->header.type = htons (GNUNET_MESSAGE_TYPE_TESTBED_PEERCREATESUCCESS);
+ reply->peer_id = msg->peer_id;
+ reply->operation_id = msg->operation_id;
+ queue_message (client, &reply->header);
GNUNET_SERVER_receive_done (client, GNUNET_OK);
return;
}
reply->header.type = htons (GNUNET_MESSAGE_TYPE_TESTBED_GENERICOPSUCCESS);
reply->header.size = htons (reply_size);
reply->operation_id = msg->operation_id;
+ reply->event_type = htonl (GNUNET_TESTBED_ET_OPERATION_FINISHED);
queue_message (client, &reply->header);
GNUNET_SERVER_receive_done (client, GNUNET_OK);
}
const struct GNUNET_MessageHeader *message)
{
const struct GNUNET_TESTBED_PeerStartMessage *msg;
- struct GNUNET_TESTBED_PeerCreateSuccessEventMessage *reply;
+ struct GNUNET_TESTBED_PeerEventMessage *reply;
uint32_t peer_id;
msg = (const struct GNUNET_TESTBED_PeerStartMessage *) message;
GNUNET_SERVER_receive_done (client, GNUNET_OK);
return;
}
- reply = GNUNET_malloc (sizeof (struct GNUNET_TESTBED_PeerCreateSuccessEventMessage));
- reply->header.size = htons (sizeof (struct GNUNET_TESTBED_PeerCreateSuccessEventMessage));
- reply->header.type = htons (GNUNET_MESSAGE_TYPE_TESTBED_PEERCREATESUCCESS);
- reply->peer_id = htonl (peer_id);
+ if (GNUNET_OK != GNUNET_TESTING_peer_start (peer_list[peer_id]->peer))
+ {
+ /* FIXME: return FAILURE message */
+ GNUNET_break (0);
+ GNUNET_SERVER_receive_done (client, GNUNET_OK);
+ return;
+ }
+ reply = GNUNET_malloc (sizeof (struct GNUNET_TESTBED_PeerEventMessage));
+ reply->header.type = htons (GNUNET_MESSAGE_TYPE_TESTBED_PEEREVENT);
+ reply->header.size = htons (sizeof (struct GNUNET_TESTBED_PeerEventMessage));
+ reply->event_type = htonl (GNUNET_TESTBED_ET_PEER_START);
+ reply->host_id = htonl (master_context->host_id);
+ reply->peer_id = msg->peer_id;
reply->operation_id = msg->operation_id;
queue_message (client, &reply->header);
GNUNET_SERVER_receive_done (client, GNUNET_OK);
const struct GNUNET_MessageHeader *message)
{
const struct GNUNET_TESTBED_PeerStopMessage *msg;
- struct GNUNET_TESTBED_GenericOperationSuccessEventMessage *reply;
+ struct GNUNET_TESTBED_PeerEventMessage *reply;
uint32_t peer_id;
msg = (const struct GNUNET_TESTBED_PeerStopMessage *) message;
GNUNET_SERVER_receive_done (client, GNUNET_OK);
return;
}
- reply = GNUNET_malloc (sizeof (struct GNUNET_TESTBED_GenericOperationSuccessEventMessage));
- reply->header.type = htons (GNUNET_MESSAGE_TYPE_TESTBED_GENERICOPSUCCESS);
- reply->header.size = htons (sizeof (struct GNUNET_TESTBED_GenericOperationSuccessEventMessage));
- reply->operation_id = msg->operation_id;
+ reply = GNUNET_malloc (sizeof (struct GNUNET_TESTBED_PeerEventMessage));
+ reply->header.type = htons (GNUNET_MESSAGE_TYPE_TESTBED_PEEREVENT);
+ reply->header.size = htons (sizeof (struct GNUNET_TESTBED_PeerEventMessage));
reply->event_type = htonl (GNUNET_TESTBED_ET_PEER_STOP);
+ reply->host_id = htonl (master_context->host_id);
+ reply->peer_id = msg->peer_id;
+ reply->operation_id = msg->operation_id;
queue_message (client, &reply->header);
GNUNET_SERVER_receive_done (client, GNUNET_OK);
}
}
+/**
+ * Functions of this signature are called when a peer has been successfully
+ * created
+ *
+ * @param cls the closure from GNUNET_TESTBED_peer_create()
+ * @param peer the handle for the created peer; NULL on any error during
+ * creation
+ * @param emsg NULL if peer is not NULL; else MAY contain the error description
+ */
+static void
+peer_create_cb (void *cls,
+ struct GNUNET_TESTBED_Peer *peer, const char *emsg)
+{
+ struct GNUNET_TESTBED_Peer **peer_ptr;
+
+ peer_ptr = cls;
+ GNUNET_assert (NULL != peer);
+ GNUNET_assert (NULL != peer_ptr);
+ *peer_ptr = peer;
+ operation = GNUNET_TESTBED_peer_destroy (peer);
+ GNUNET_assert (NULL != operation);
+}
+
+
/**
* Callback which will be called to after a host registration succeeded or failed
*
{
GNUNET_assert (cls == neighbour);
reg_handle = NULL;
- peer = GNUNET_TESTBED_peer_create (controller, host, cfg);
- GNUNET_assert (NULL != peer);
- operation = GNUNET_TESTBED_peer_destroy (peer);
+ operation = GNUNET_TESTBED_peer_create (controller, host, cfg, &peer_create_cb, &peer);
GNUNET_assert (NULL != operation);
}
}
+/**
+ * Functions of this signature are called when a peer has been successfully
+ * created
+ *
+ * @param cls the closure from GNUNET_TESTBED_peer_create()
+ * @param peer the handle for the created peer; NULL on any error during
+ * creation
+ * @param emsg NULL if peer is not NULL; else MAY contain the error description
+ */
+static void
+peer_create_cb (void *cls,
+ struct GNUNET_TESTBED_Peer *peer, const char *emsg)
+{
+ struct GNUNET_TESTBED_Peer **peer_ptr;
+
+ peer_ptr = cls;
+ GNUNET_assert (NULL != peer);
+ GNUNET_assert (NULL != peer_ptr);
+ *peer_ptr = peer;
+ operation = GNUNET_TESTBED_peer_destroy (peer);
+ GNUNET_assert (NULL != operation);
+}
+
+
/**
* Callback which will be called to after a host registration succeeded or failed
*
{
GNUNET_assert (cls == neighbour);
reg_handle = NULL;
- peer = GNUNET_TESTBED_peer_create (controller, host, cfg);
- GNUNET_assert (NULL != peer);
- operation = GNUNET_TESTBED_peer_destroy (peer);
+ operation = GNUNET_TESTBED_peer_create (controller, host, cfg, &peer_create_cb, &peer);
GNUNET_assert (NULL != operation);
}
*/
struct GNUNET_MessageHeader header;
+ /**
+ * Unique operation id
+ */
+ uint64_t operation_id GNUNET_PACKED;
+
/**
* On which host should the peer be started?
*/
GNUNET_TESTBED_PeerCreateSuccessEventMessage *msg)
{
struct GNUNET_TESTBED_Operation *op;
+ struct PeerCreateData *data;
struct GNUNET_TESTBED_Peer *peer;
+ GNUNET_TESTBED_PeerCreateCallback cb;
+ void *cls;
uint64_t op_id;
GNUNET_assert (sizeof (struct GNUNET_TESTBED_PeerCreateSuccessEventMessage)
if (op->operation_id == op_id)
break;
}
- GNUNET_assert (NULL != op);
- peer = op->data;
- GNUNET_assert (NULL != peer);
- GNUNET_assert (peer->unique_id == ntohl (msg->peer_id));
- if (0 != (c->event_mask & (1L << GNUNET_TESTBED_ET_PEER_START)))
+ if (NULL == op)
{
- struct GNUNET_TESTBED_EventInformation info;
-
- info.details.peer_start.host = peer->host;
- info.details.peer_start.peer = peer;
- if (NULL != c->cc)
- c->cc (c->cc_cls, &info);
+ LOG_DEBUG ("Operation not found\n");
+ return GNUNET_YES;
}
+ GNUNET_assert (OP_PEER_CREATE == op->type);
+ GNUNET_assert (NULL != op->data);
+ data = op->data;
+ GNUNET_assert (NULL != data->peer);
+ peer = data->peer;
+ GNUNET_assert (peer->unique_id == ntohl (msg->peer_id));
+ cb = data->cb;
+ cls = data->cls;
GNUNET_CONTAINER_DLL_remove (c->op_head, c->op_tail, op);
+ GNUNET_free (data);
GNUNET_free (op);
+ if (NULL != cb)
+ cb (cls, peer, NULL);
return GNUNET_YES;
}
*/
enum OperationType
{
+ /**
+ * Peer create operation
+ */
+ OP_PEER_CREATE,
+
/**
* Peer start operation
*/
* @param controller controller process to use
* @param host host to run the peer on
* @param cfg configuration to use for the peer
- * @return handle to the peer (actual startup will happen asynchronously)
+ * @param cb the callback to call when the peer has been created
+ * @param cls the closure to the above callback
+ * @return the operation handle
*/
-struct GNUNET_TESTBED_Peer *
+struct GNUNET_TESTBED_Operation *
GNUNET_TESTBED_peer_create_with_id_ (uint32_t unique_id,
struct GNUNET_TESTBED_Controller *controller,
struct GNUNET_TESTBED_Host *host,
- const struct GNUNET_CONFIGURATION_Handle *cfg)
+ const struct GNUNET_CONFIGURATION_Handle *cfg,
+ GNUNET_TESTBED_PeerCreateCallback cb,
+ void *cls)
{
struct GNUNET_TESTBED_Peer *peer;
+ struct PeerCreateData *data;
+ struct GNUNET_TESTBED_Operation *op;
struct GNUNET_TESTBED_PeerCreateMessage *msg;
char *config;
char *xconfig;
peer->controller = controller;
peer->host = host;
peer->unique_id = unique_id;
+ data = GNUNET_malloc (sizeof (struct PeerCreateData));
+ data->cb = cb;
+ data->cls = cls;
+ data->peer = peer;
+ op = GNUNET_malloc (sizeof (struct GNUNET_TESTBED_Operation));
+ op->operation_id = controller->operation_counter++;
+ op->type = OP_PEER_CREATE;
+ op->data = data;
config = GNUNET_CONFIGURATION_serialize (cfg, &c_size);
xc_size = GNUNET_TESTBED_compress_config_ (config, c_size, &xconfig);
GNUNET_free (config);
memmove (&msg[1], msg, xc_size); /* Move the compressed config */
msg->header.size = htons (msize);
msg->header.type = htons (GNUNET_MESSAGE_TYPE_TESTBED_CREATEPEER);
+ msg->operation_id = GNUNET_htonll (op->operation_id);
msg->host_id = htonl (GNUNET_TESTBED_host_get_id_ (peer->host));
msg->peer_id = htonl (peer->unique_id);
msg->config_size = htonl (c_size);
+ GNUNET_CONTAINER_DLL_insert_tail (peer->controller->op_head,
+ peer->controller->op_tail, op);
GNUNET_TESTBED_queue_message_ (controller,
(struct GNUNET_MessageHeader *) msg);
- return peer;
+ return op;
}
* @param controller controller process to use
* @param host host to run the peer on
* @param cfg configuration to use for the peer
- * @return handle to the peer (actual startup will happen asynchronously)
+ * @param cb the callback to call when the peer has been created
+ * @param cls the closure to the above callback
+ * @return the operation handle
*/
-struct GNUNET_TESTBED_Peer *
+struct GNUNET_TESTBED_Operation *
GNUNET_TESTBED_peer_create (struct GNUNET_TESTBED_Controller *controller,
struct GNUNET_TESTBED_Host *host,
- const struct GNUNET_CONFIGURATION_Handle *cfg)
+ const struct GNUNET_CONFIGURATION_Handle *cfg,
+ GNUNET_TESTBED_PeerCreateCallback cb,
+ void *cls)
{
static uint32_t id_gen;
return GNUNET_TESTBED_peer_create_with_id_ (++id_gen,
controller,
host,
- cfg);
+ cfg,
+ cb, cls);
}
};
+/**
+ * Data for the OperationType OP_PEER_CREATE
+ */
+struct PeerCreateData
+{
+ /**
+ * THe call back to call when we receive peer create success message
+ */
+ GNUNET_TESTBED_PeerCreateCallback cb;
+
+ /**
+ * The closure for the above callback
+ */
+ void *cls;
+
+ /**
+ * The peer structure to return when we get success message
+ */
+ struct GNUNET_TESTBED_Peer *peer;
+
+};
+
+
/**
* Data for the OperationType OP_PEER_DESTROY;
*/
* @param controller controller process to use
* @param host host to run the peer on
* @param cfg configuration to use for the peer
- * @return handle to the peer (actual startup will happen asynchronously)
+ * @param cb the callback to call when the peer has been created
+ * @param cls the closure to the above callback
+ * @return the operation handle
*/
-struct GNUNET_TESTBED_Peer *
+struct GNUNET_TESTBED_Operation *
GNUNET_TESTBED_peer_create_with_id_ (uint32_t unique_id,
- struct GNUNET_TESTBED_Controller *controller,
+ struct GNUNET_TESTBED_Controller *controller,
struct GNUNET_TESTBED_Host *host,
- const struct GNUNET_CONFIGURATION_Handle *cfg);
+ const struct GNUNET_CONFIGURATION_Handle *cfg,
+ GNUNET_TESTBED_PeerCreateCallback cb,
+ void *cls);