diff options
author | Sree Harsha Totakura <totakura@in.tum.de> | 2013-03-08 15:34:45 +0000 |
---|---|---|
committer | Sree Harsha Totakura <totakura@in.tum.de> | 2013-03-08 15:34:45 +0000 |
commit | 19b4dacf08575bd188f9010558e8299c6c8eb56e (patch) | |
tree | 1555b7c5ac0e6a4ac39028830a50086c70d19830 /src/testbed/gnunet-service-testbed.c | |
parent | 6419502e4bb83f53caf9f3fd5170f8219516e38a (diff) | |
download | gnunet-19b4dacf08575bd188f9010558e8299c6c8eb56e.tar.gz gnunet-19b4dacf08575bd188f9010558e8299c6c8eb56e.zip |
- fix (case where peers <= 2)
Diffstat (limited to 'src/testbed/gnunet-service-testbed.c')
-rw-r--r-- | src/testbed/gnunet-service-testbed.c | 228 |
1 files changed, 202 insertions, 26 deletions
diff --git a/src/testbed/gnunet-service-testbed.c b/src/testbed/gnunet-service-testbed.c index 2435ba50e..a7af7b99c 100644 --- a/src/testbed/gnunet-service-testbed.c +++ b/src/testbed/gnunet-service-testbed.c | |||
@@ -1973,6 +1973,194 @@ handle_slave_get_config (void *cls, struct GNUNET_SERVER_Client *client, | |||
1973 | 1973 | ||
1974 | 1974 | ||
1975 | /** | 1975 | /** |
1976 | * Context data for GNUNET_MESSAGE_TYPE_TESTBED_SHUTDOWN_PEERS handler | ||
1977 | */ | ||
1978 | struct HandlerContext_ShutdownPeers | ||
1979 | { | ||
1980 | /** | ||
1981 | * The number of slave we expect to hear from since we forwarded the | ||
1982 | * GNUNET_MESSAGE_TYPE_TESTBED_SHUTDOWN_PEERS message to them | ||
1983 | */ | ||
1984 | unsigned int nslaves; | ||
1985 | |||
1986 | /** | ||
1987 | * Did we observe a timeout with respect to this operation at any of the | ||
1988 | * slaves | ||
1989 | */ | ||
1990 | int timeout; | ||
1991 | }; | ||
1992 | |||
1993 | |||
1994 | /** | ||
1995 | * Task run upon timeout of forwarded SHUTDOWN_PEERS operation | ||
1996 | * | ||
1997 | * @param cls the ForwardedOperationContext | ||
1998 | * @param tc the scheduler task context | ||
1999 | */ | ||
2000 | static void | ||
2001 | shutdown_peers_timeout_cb (void *cls, | ||
2002 | const struct GNUNET_SCHEDULER_TaskContext *tc) | ||
2003 | { | ||
2004 | struct ForwardedOperationContext *fo_ctxt = cls; | ||
2005 | struct HandlerContext_ShutdownPeers *hc; | ||
2006 | |||
2007 | hc = fo_ctxt->cls; | ||
2008 | hc->timeout = GNUNET_YES; | ||
2009 | GNUNET_assert (0 < hc->nslaves); | ||
2010 | hc->nslaves--; | ||
2011 | if (0 == hc->nslaves) | ||
2012 | GST_send_operation_fail_msg (fo_ctxt->client, fo_ctxt->operation_id, | ||
2013 | "Timeout at a slave controller"); | ||
2014 | GNUNET_TESTBED_forward_operation_msg_cancel_ (fo_ctxt->opc); | ||
2015 | GNUNET_SERVER_client_drop (fo_ctxt->client); | ||
2016 | GNUNET_CONTAINER_DLL_remove (fopcq_head, fopcq_tail, fo_ctxt); | ||
2017 | GNUNET_free (fo_ctxt); | ||
2018 | } | ||
2019 | |||
2020 | |||
2021 | /** | ||
2022 | * The reply msg handler forwarded SHUTDOWN_PEERS operation. Checks if a | ||
2023 | * success reply is received from all clients and then sends the success message | ||
2024 | * to the client | ||
2025 | * | ||
2026 | * @param cls ForwardedOperationContext | ||
2027 | * @param msg the message to relay | ||
2028 | */ | ||
2029 | static void | ||
2030 | shutdown_peers_reply_cb (void *cls, | ||
2031 | const struct GNUNET_MessageHeader *msg) | ||
2032 | { | ||
2033 | struct ForwardedOperationContext *fo_ctxt = cls; | ||
2034 | struct HandlerContext_ShutdownPeers *hc; | ||
2035 | |||
2036 | hc = fo_ctxt->cls; | ||
2037 | GNUNET_assert (0 < hc->nslaves); | ||
2038 | hc->nslaves--; | ||
2039 | if (GNUNET_MESSAGE_TYPE_TESTBED_GENERIC_OPERATION_SUCCESS != | ||
2040 | ntohs (msg->type)) | ||
2041 | hc->timeout = GNUNET_YES; | ||
2042 | if (0 == hc->nslaves) | ||
2043 | { | ||
2044 | if (GNUNET_YES == hc->timeout) | ||
2045 | GST_send_operation_fail_msg (fo_ctxt->client, fo_ctxt->operation_id, | ||
2046 | "Timeout at a slave controller"); | ||
2047 | else | ||
2048 | send_operation_success_msg (fo_ctxt->client, fo_ctxt->operation_id); | ||
2049 | } | ||
2050 | GNUNET_SERVER_client_drop (fo_ctxt->client); | ||
2051 | GNUNET_CONTAINER_DLL_remove (fopcq_head, fopcq_tail, fo_ctxt); | ||
2052 | GNUNET_free (fo_ctxt); | ||
2053 | } | ||
2054 | |||
2055 | |||
2056 | /** | ||
2057 | * Stops and destroys all peers | ||
2058 | */ | ||
2059 | static void | ||
2060 | destroy_peers () | ||
2061 | { | ||
2062 | struct Peer *peer; | ||
2063 | unsigned int id; | ||
2064 | |||
2065 | if (NULL == GST_peer_list) | ||
2066 | return; | ||
2067 | for (id = 0; id < GST_peer_list_size; id++) | ||
2068 | { | ||
2069 | peer = GST_peer_list[id]; | ||
2070 | if (NULL == peer) | ||
2071 | continue; | ||
2072 | /* If destroy flag is set it means that this peer should have been | ||
2073 | * destroyed by a context which we destroy before */ | ||
2074 | GNUNET_break (GNUNET_NO == peer->destroy_flag); | ||
2075 | /* counter should be zero as we free all contexts before */ | ||
2076 | GNUNET_break (0 == peer->reference_cnt); | ||
2077 | if ((GNUNET_NO == peer->is_remote) && | ||
2078 | (GNUNET_YES == peer->details.local.is_running)) | ||
2079 | GNUNET_TESTING_peer_kill (peer->details.local.peer); | ||
2080 | } | ||
2081 | for (id = 0; id < GST_peer_list_size; id++) | ||
2082 | { | ||
2083 | peer = GST_peer_list[id]; | ||
2084 | if (NULL == peer) | ||
2085 | continue; | ||
2086 | if (GNUNET_NO == peer->is_remote) | ||
2087 | { | ||
2088 | if (GNUNET_YES == peer->details.local.is_running) | ||
2089 | GNUNET_TESTING_peer_wait (peer->details.local.peer); | ||
2090 | GNUNET_TESTING_peer_destroy (peer->details.local.peer); | ||
2091 | GNUNET_CONFIGURATION_destroy (peer->details.local.cfg); | ||
2092 | } | ||
2093 | GNUNET_free (peer); | ||
2094 | } | ||
2095 | GNUNET_free_non_null (GST_peer_list); | ||
2096 | GST_peer_list = NULL; | ||
2097 | } | ||
2098 | |||
2099 | |||
2100 | /** | ||
2101 | * Handler for GNUNET_MESSAGE_TYPE_TESTBED_SHUTDOWN_PEERS messages | ||
2102 | * | ||
2103 | * @param cls NULL | ||
2104 | * @param client identification of the client | ||
2105 | * @param message the actual message | ||
2106 | */ | ||
2107 | static void | ||
2108 | handle_shutdown_peers (void *cls, struct GNUNET_SERVER_Client *client, | ||
2109 | const struct GNUNET_MessageHeader *message) | ||
2110 | { | ||
2111 | const struct GNUNET_TESTBED_ShutdownPeersMessage *msg; | ||
2112 | struct HandlerContext_ShutdownPeers *hc; | ||
2113 | struct Slave *slave; | ||
2114 | struct ForwardedOperationContext *fo_ctxt; | ||
2115 | uint64_t op_id; | ||
2116 | unsigned int cnt; | ||
2117 | |||
2118 | msg = (const struct GNUNET_TESTBED_ShutdownPeersMessage *) message; | ||
2119 | LOG_DEBUG ("Received SHUTDOWN_PEERS\n"); | ||
2120 | /* Forward to all slaves which we have started */ | ||
2121 | op_id = GNUNET_ntohll (msg->operation_id); | ||
2122 | hc = GNUNET_malloc (sizeof (struct HandlerContext_ShutdownPeers)); | ||
2123 | /* FIXME: have a better implementation where we track which slaves are | ||
2124 | started by this controller */ | ||
2125 | for (cnt = 0; cnt < GST_slave_list_size; cnt++) | ||
2126 | { | ||
2127 | slave = GST_slave_list[cnt]; | ||
2128 | if (NULL == slave) | ||
2129 | continue; | ||
2130 | if (NULL == slave->controller_proc) /* We didn't start the slave */ | ||
2131 | continue; | ||
2132 | LOG_DEBUG ("Forwarding SHUTDOWN_PEERS\n"); | ||
2133 | hc->nslaves++; | ||
2134 | fo_ctxt = GNUNET_malloc (sizeof (struct ForwardedOperationContext)); | ||
2135 | GNUNET_SERVER_client_keep (client); | ||
2136 | fo_ctxt->client = client; | ||
2137 | fo_ctxt->operation_id = op_id; | ||
2138 | fo_ctxt->cls = hc; | ||
2139 | fo_ctxt->type = OP_SHUTDOWN_PEERS; | ||
2140 | fo_ctxt->opc = | ||
2141 | GNUNET_TESTBED_forward_operation_msg_ (slave->controller, | ||
2142 | fo_ctxt->operation_id, | ||
2143 | &msg->header, | ||
2144 | shutdown_peers_reply_cb, | ||
2145 | fo_ctxt); | ||
2146 | fo_ctxt->timeout_task = | ||
2147 | GNUNET_SCHEDULER_add_delayed (GST_timeout, &shutdown_peers_timeout_cb, | ||
2148 | fo_ctxt); | ||
2149 | GNUNET_CONTAINER_DLL_insert_tail (fopcq_head, fopcq_tail, fo_ctxt); | ||
2150 | } | ||
2151 | LOG_DEBUG ("Shutting down peers\n"); | ||
2152 | /* Stop and destroy all peers */ | ||
2153 | destroy_peers (); | ||
2154 | if (0 == hc->nslaves) | ||
2155 | { | ||
2156 | send_operation_success_msg (client, op_id); | ||
2157 | GNUNET_free (hc); | ||
2158 | } | ||
2159 | GNUNET_SERVER_receive_done (client, GNUNET_OK); | ||
2160 | } | ||
2161 | |||
2162 | |||
2163 | /** | ||
1976 | * Iterator over hash map entries. | 2164 | * Iterator over hash map entries. |
1977 | * | 2165 | * |
1978 | * @param cls closure | 2166 | * @param cls closure |
@@ -2062,6 +2250,16 @@ shutdown_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | |||
2062 | case OP_PEER_CREATE: | 2250 | case OP_PEER_CREATE: |
2063 | GNUNET_free (fopc->cls); | 2251 | GNUNET_free (fopc->cls); |
2064 | break; | 2252 | break; |
2253 | case OP_SHUTDOWN_PEERS: | ||
2254 | { | ||
2255 | struct HandlerContext_ShutdownPeers *hc = fopc->cls; | ||
2256 | |||
2257 | GNUNET_assert (0 < hc->nslaves); | ||
2258 | hc->nslaves--; | ||
2259 | if (0 == hc->nslaves) | ||
2260 | GNUNET_free (hc); | ||
2261 | } | ||
2262 | break; | ||
2065 | case OP_PEER_START: | 2263 | case OP_PEER_START: |
2066 | case OP_PEER_STOP: | 2264 | case OP_PEER_STOP: |
2067 | case OP_PEER_DESTROY: | 2265 | case OP_PEER_DESTROY: |
@@ -2096,31 +2294,7 @@ shutdown_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | |||
2096 | GST_free_occq (); | 2294 | GST_free_occq (); |
2097 | GST_free_roccq (); | 2295 | GST_free_roccq (); |
2098 | /* Clear peer list */ | 2296 | /* Clear peer list */ |
2099 | for (id = 0; id < GST_peer_list_size; id++) | 2297 | destroy_peers (); |
2100 | if (NULL != GST_peer_list[id]) | ||
2101 | { | ||
2102 | /* If destroy flag is set it means that this peer should have been | ||
2103 | * destroyed by a context which we destroy before */ | ||
2104 | GNUNET_break (GNUNET_NO == GST_peer_list[id]->destroy_flag); | ||
2105 | /* counter should be zero as we free all contexts before */ | ||
2106 | GNUNET_break (0 == GST_peer_list[id]->reference_cnt); | ||
2107 | if ((GNUNET_NO == GST_peer_list[id]->is_remote) && | ||
2108 | (GNUNET_YES == GST_peer_list[id]->details.local.is_running)) | ||
2109 | GNUNET_TESTING_peer_kill (GST_peer_list[id]->details.local.peer); | ||
2110 | } | ||
2111 | for (id = 0; id < GST_peer_list_size; id++) | ||
2112 | if (NULL != GST_peer_list[id]) | ||
2113 | { | ||
2114 | if (GNUNET_NO == GST_peer_list[id]->is_remote) | ||
2115 | { | ||
2116 | if (GNUNET_YES == GST_peer_list[id]->details.local.is_running) | ||
2117 | GNUNET_TESTING_peer_wait (GST_peer_list[id]->details.local.peer); | ||
2118 | GNUNET_TESTING_peer_destroy (GST_peer_list[id]->details.local.peer); | ||
2119 | GNUNET_CONFIGURATION_destroy (GST_peer_list[id]->details.local.cfg); | ||
2120 | } | ||
2121 | GNUNET_free (GST_peer_list[id]); | ||
2122 | } | ||
2123 | GNUNET_free_non_null (GST_peer_list); | ||
2124 | /* Clear host list */ | 2298 | /* Clear host list */ |
2125 | for (id = 0; id < GST_host_list_size; id++) | 2299 | for (id = 0; id < GST_host_list_size; id++) |
2126 | if (NULL != GST_host_list[id]) | 2300 | if (NULL != GST_host_list[id]) |
@@ -2242,9 +2416,11 @@ testbed_run (void *cls, struct GNUNET_SERVER_Handle *server, | |||
2242 | sizeof (struct GNUNET_TESTBED_OverlayConnectMessage)}, | 2416 | sizeof (struct GNUNET_TESTBED_OverlayConnectMessage)}, |
2243 | {&GST_handle_remote_overlay_connect, NULL, | 2417 | {&GST_handle_remote_overlay_connect, NULL, |
2244 | GNUNET_MESSAGE_TYPE_TESTBED_REMOTE_OVERLAY_CONNECT, 0}, | 2418 | GNUNET_MESSAGE_TYPE_TESTBED_REMOTE_OVERLAY_CONNECT, 0}, |
2245 | {handle_slave_get_config, NULL, | 2419 | {&handle_slave_get_config, NULL, |
2246 | GNUNET_MESSAGE_TYPE_TESTBED_GET_SLAVE_CONFIGURATION, | 2420 | GNUNET_MESSAGE_TYPE_TESTBED_GET_SLAVE_CONFIGURATION, |
2247 | sizeof (struct GNUNET_TESTBED_SlaveGetConfigurationMessage)}, | 2421 | sizeof (struct GNUNET_TESTBED_SlaveGetConfigurationMessage)}, |
2422 | {&handle_shutdown_peers, NULL, GNUNET_MESSAGE_TYPE_TESTBED_SHUTDOWN_PEERS, | ||
2423 | sizeof (struct GNUNET_TESTBED_ShutdownPeersMessage)}, | ||
2248 | {NULL} | 2424 | {NULL} |
2249 | }; | 2425 | }; |
2250 | char *logfile; | 2426 | char *logfile; |