From 15f4d07a0a03d4c2358c92976cca4708fcca7ff4 Mon Sep 17 00:00:00 2001 From: Sree Harsha Totakura Date: Fri, 20 Jul 2012 12:02:27 +0000 Subject: [PATCH] peer create callback --- src/include/gnunet_testbed_service.h | 26 +++++++++++++++--- src/testbed/gnunet-service-testbed.c | 39 ++++++++++++++++++++------- src/testbed/test_testbed_api.c | 28 ++++++++++++++++--- src/testbed/test_testbed_api_2peers.c | 28 ++++++++++++++++--- src/testbed/testbed.h | 5 ++++ src/testbed/testbed_api.c | 28 +++++++++++-------- src/testbed/testbed_api.h | 5 ++++ src/testbed/testbed_api_peers.c | 38 ++++++++++++++++++++------ src/testbed/testbed_api_peers.h | 35 +++++++++++++++++++++--- 9 files changed, 189 insertions(+), 43 deletions(-) diff --git a/src/include/gnunet_testbed_service.h b/src/include/gnunet_testbed_service.h index d6c4354fe..19928623f 100644 --- a/src/include/gnunet_testbed_service.h +++ b/src/include/gnunet_testbed_service.h @@ -612,7 +612,21 @@ GNUNET_TESTBED_controller_link_2 (struct GNUNET_TESTBED_Controller *master, 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); /** @@ -639,12 +653,16 @@ GNUNET_TESTBED_controller_link_2 (struct GNUNET_TESTBED_Controller *master, * @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); /** diff --git a/src/testbed/gnunet-service-testbed.c b/src/testbed/gnunet-service-testbed.c index ef4a5838f..b0fb72228 100644 --- a/src/testbed/gnunet-service-testbed.c +++ b/src/testbed/gnunet-service-testbed.c @@ -1157,6 +1157,7 @@ handle_peer_create (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; @@ -1224,6 +1225,12 @@ handle_peer_create (void *cls, 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; } @@ -1284,6 +1291,7 @@ handle_peer_destroy (void *cls, 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); } @@ -1302,7 +1310,7 @@ handle_peer_start (void *cls, 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; @@ -1316,10 +1324,19 @@ handle_peer_start (void *cls, 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); @@ -1339,7 +1356,7 @@ handle_peer_stop (void *cls, 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; @@ -1357,11 +1374,13 @@ handle_peer_stop (void *cls, 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); } diff --git a/src/testbed/test_testbed_api.c b/src/testbed/test_testbed_api.c index 6378fd9cc..3ae6dbd67 100644 --- a/src/testbed/test_testbed_api.c +++ b/src/testbed/test_testbed_api.c @@ -152,6 +152,30 @@ controller_cb(void *cls, const struct GNUNET_TESTBED_EventInformation *event) } +/** + * 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 * @@ -163,9 +187,7 @@ registration_comp (void *cls, const char *emsg) { 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); } diff --git a/src/testbed/test_testbed_api_2peers.c b/src/testbed/test_testbed_api_2peers.c index 9f55b61eb..c8422ba9d 100644 --- a/src/testbed/test_testbed_api_2peers.c +++ b/src/testbed/test_testbed_api_2peers.c @@ -153,6 +153,30 @@ controller_cb(void *cls, const struct GNUNET_TESTBED_EventInformation *event) } +/** + * 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 * @@ -164,9 +188,7 @@ registration_comp (void *cls, const char *emsg) { 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); } diff --git a/src/testbed/testbed.h b/src/testbed/testbed.h index fff76f2ec..a2bb77e3d 100644 --- a/src/testbed/testbed.h +++ b/src/testbed/testbed.h @@ -197,6 +197,11 @@ struct GNUNET_TESTBED_PeerCreateMessage */ struct GNUNET_MessageHeader header; + /** + * Unique operation id + */ + uint64_t operation_id GNUNET_PACKED; + /** * On which host should the peer be started? */ diff --git a/src/testbed/testbed_api.c b/src/testbed/testbed_api.c index e343daa31..f7d58e9bb 100644 --- a/src/testbed/testbed_api.c +++ b/src/testbed/testbed_api.c @@ -300,7 +300,10 @@ handle_peer_create_success (struct GNUNET_TESTBED_Controller *c, 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) @@ -311,21 +314,24 @@ handle_peer_create_success (struct GNUNET_TESTBED_Controller *c, 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; } diff --git a/src/testbed/testbed_api.h b/src/testbed/testbed_api.h index a01ea1c29..e83e21b52 100644 --- a/src/testbed/testbed_api.h +++ b/src/testbed/testbed_api.h @@ -33,6 +33,11 @@ */ enum OperationType { + /** + * Peer create operation + */ + OP_PEER_CREATE, + /** * Peer start operation */ diff --git a/src/testbed/testbed_api_peers.c b/src/testbed/testbed_api_peers.c index 8beae14f9..0010105dc 100644 --- a/src/testbed/testbed_api_peers.c +++ b/src/testbed/testbed_api_peers.c @@ -72,15 +72,21 @@ GNUNET_TESTBED_peer_lookup_by_id_ (uint32_t id) * @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; @@ -92,6 +98,14 @@ GNUNET_TESTBED_peer_create_with_id_ (uint32_t unique_id, 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); @@ -100,12 +114,15 @@ GNUNET_TESTBED_peer_create_with_id_ (uint32_t unique_id, 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; } @@ -133,19 +150,24 @@ GNUNET_TESTBED_peer_create_with_id_ (uint32_t unique_id, * @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); } diff --git a/src/testbed/testbed_api_peers.h b/src/testbed/testbed_api_peers.h index ee5ec3bd9..83d2d890f 100644 --- a/src/testbed/testbed_api_peers.h +++ b/src/testbed/testbed_api_peers.h @@ -78,6 +78,29 @@ struct GNUNET_TESTBED_Peer }; +/** + * 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; */ @@ -119,13 +142,17 @@ struct PeerDestroyData * @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); -- 2.25.1