diff options
-rw-r--r-- | src/stream/stream_api.c | 50 | ||||
-rw-r--r-- | src/stream/test_stream_local.c | 49 |
2 files changed, 92 insertions, 7 deletions
diff --git a/src/stream/stream_api.c b/src/stream/stream_api.c index 92c1093f7..535850de2 100644 --- a/src/stream/stream_api.c +++ b/src/stream/stream_api.c | |||
@@ -232,6 +232,11 @@ struct GNUNET_STREAM_Socket | |||
232 | struct GNUNET_STREAM_IOReadHandle *read_handle; | 232 | struct GNUNET_STREAM_IOReadHandle *read_handle; |
233 | 233 | ||
234 | /** | 234 | /** |
235 | * The shutdown handle associated with this socket | ||
236 | */ | ||
237 | struct GNUNET_STREAM_ShutdownHandle *shutdown_handle; | ||
238 | |||
239 | /** | ||
235 | * Buffer for storing received messages | 240 | * Buffer for storing received messages |
236 | */ | 241 | */ |
237 | void *receive_buffer; | 242 | void *receive_buffer; |
@@ -443,6 +448,16 @@ struct GNUNET_STREAM_ShutdownHandle | |||
443 | * Which operation to shutdown? SHUT_RD, SHUT_WR or SHUT_RDWR | 448 | * Which operation to shutdown? SHUT_RD, SHUT_WR or SHUT_RDWR |
444 | */ | 449 | */ |
445 | int operation; | 450 | int operation; |
451 | |||
452 | /** | ||
453 | * Shutdown completion callback | ||
454 | */ | ||
455 | GNUNET_STREAM_ShutdownCompletion completion_cb; | ||
456 | |||
457 | /** | ||
458 | * Closure for completion callback | ||
459 | */ | ||
460 | void *completion_cls; | ||
446 | }; | 461 | }; |
447 | 462 | ||
448 | 463 | ||
@@ -1559,6 +1574,10 @@ handle_close (struct GNUNET_STREAM_Socket *socket, | |||
1559 | { | 1574 | { |
1560 | struct GNUNET_STREAM_MessageHeader *close_ack; | 1575 | struct GNUNET_STREAM_MessageHeader *close_ack; |
1561 | 1576 | ||
1577 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1578 | "%x: Received CLOSE from %x\n", | ||
1579 | socket->our_id, | ||
1580 | socket->other_peer); | ||
1562 | close_ack = GNUNET_malloc (sizeof (struct GNUNET_STREAM_MessageHeader)); | 1581 | close_ack = GNUNET_malloc (sizeof (struct GNUNET_STREAM_MessageHeader)); |
1563 | close_ack->header.size = htons (sizeof (struct GNUNET_STREAM_MessageHeader)); | 1582 | close_ack->header.size = htons (sizeof (struct GNUNET_STREAM_MessageHeader)); |
1564 | close_ack->header.type = htons (GNUNET_MESSAGE_TYPE_STREAM_CLOSE_ACK); | 1583 | close_ack->header.type = htons (GNUNET_MESSAGE_TYPE_STREAM_CLOSE_ACK); |
@@ -1625,10 +1644,30 @@ handle_close_ack (struct GNUNET_STREAM_Socket *socket, | |||
1625 | const struct GNUNET_STREAM_MessageHeader *message, | 1644 | const struct GNUNET_STREAM_MessageHeader *message, |
1626 | const struct GNUNET_ATS_Information*atsi) | 1645 | const struct GNUNET_ATS_Information*atsi) |
1627 | { | 1646 | { |
1647 | struct GNUNET_STREAM_ShutdownHandle *shutdown_handle; | ||
1648 | |||
1649 | shutdown_handle = socket->shutdown_handle; | ||
1628 | switch (socket->state) | 1650 | switch (socket->state) |
1629 | { | 1651 | { |
1630 | case STATE_CLOSE_WAIT: | 1652 | case STATE_CLOSE_WAIT: |
1631 | socket->state = STATE_CLOSED; | 1653 | socket->state = STATE_CLOSED; |
1654 | if ( (NULL == shutdown_handle) || | ||
1655 | (SHUT_RDWR != shutdown_handle->operation) ) | ||
1656 | { | ||
1657 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1658 | "%x: Received CLOSE_ACK when shutdown handle is NULL or " | ||
1659 | "not for SHUT_RDWR\n", | ||
1660 | socket->our_id); | ||
1661 | return GNUNET_OK; | ||
1662 | } | ||
1663 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1664 | "%x: Received CLOSE_ACK from %x\n", | ||
1665 | socket->our_id, | ||
1666 | socket->other_peer); | ||
1667 | if (NULL != shutdown_handle->completion_cb) /* Shutdown completion */ | ||
1668 | shutdown_handle->completion_cb(shutdown_handle->completion_cls, | ||
1669 | SHUT_RDWR); | ||
1670 | GNUNET_free (shutdown_handle); /* Free shutdown handle */ | ||
1632 | break; | 1671 | break; |
1633 | default: | 1672 | default: |
1634 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 1673 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
@@ -2515,16 +2554,25 @@ GNUNET_STREAM_shutdown (struct GNUNET_STREAM_Socket *socket, | |||
2515 | { | 2554 | { |
2516 | struct GNUNET_STREAM_ShutdownHandle *handle; | 2555 | struct GNUNET_STREAM_ShutdownHandle *handle; |
2517 | struct GNUNET_STREAM_MessageHeader *msg; | 2556 | struct GNUNET_STREAM_MessageHeader *msg; |
2557 | |||
2558 | GNUNET_assert (NULL == socket->shutdown_handle); | ||
2518 | 2559 | ||
2519 | handle = GNUNET_malloc (sizeof (struct GNUNET_STREAM_ShutdownHandle)); | 2560 | handle = GNUNET_malloc (sizeof (struct GNUNET_STREAM_ShutdownHandle)); |
2520 | handle->socket = socket; | 2561 | handle->socket = socket; |
2562 | handle->completion_cb = completion_cb; | ||
2563 | handle->completion_cls = completion_cls; | ||
2564 | socket->shutdown_handle = handle; | ||
2565 | |||
2521 | msg = GNUNET_malloc (sizeof (struct GNUNET_STREAM_MessageHeader)); | 2566 | msg = GNUNET_malloc (sizeof (struct GNUNET_STREAM_MessageHeader)); |
2522 | msg->header.size = htons (sizeof (struct GNUNET_STREAM_MessageHeader)); | 2567 | msg->header.size = htons (sizeof (struct GNUNET_STREAM_MessageHeader)); |
2523 | switch (operation) | 2568 | switch (operation) |
2524 | { | 2569 | { |
2525 | case SHUT_RD: | 2570 | case SHUT_RD: |
2526 | handle->operation = SHUT_RD; | 2571 | handle->operation = SHUT_RD; |
2527 | 2572 | if (NULL != socket->read_handle) | |
2573 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | ||
2574 | "Existing read handle should be cancelled before shutting" | ||
2575 | " down reading\n"); | ||
2528 | break; | 2576 | break; |
2529 | case SHUT_WR: | 2577 | case SHUT_WR: |
2530 | handle->operation = SHUT_WR; | 2578 | handle->operation = SHUT_WR; |
diff --git a/src/stream/test_stream_local.c b/src/stream/test_stream_local.c index c3fcc6492..125873acf 100644 --- a/src/stream/test_stream_local.c +++ b/src/stream/test_stream_local.c | |||
@@ -60,6 +60,11 @@ struct PeerData | |||
60 | struct GNUNET_STREAM_IOReadHandle *io_read_handle; | 60 | struct GNUNET_STREAM_IOReadHandle *io_read_handle; |
61 | 61 | ||
62 | /** | 62 | /** |
63 | * Peer's shutdown handle | ||
64 | */ | ||
65 | struct GNUNET_STREAM_ShutdownHandle *shutdown_handle; | ||
66 | |||
67 | /** | ||
63 | * Our Peer id | 68 | * Our Peer id |
64 | */ | 69 | */ |
65 | struct GNUNET_PeerIdentity our_id; | 70 | struct GNUNET_PeerIdentity our_id; |
@@ -109,7 +114,7 @@ static int reading_success; | |||
109 | * Check whether peers successfully shut down. | 114 | * Check whether peers successfully shut down. |
110 | */ | 115 | */ |
111 | static void | 116 | static void |
112 | shutdown_callback (void *cls, const char *emsg) | 117 | peergroup_shutdown_callback (void *cls, const char *emsg) |
113 | { | 118 | { |
114 | if (emsg != NULL) | 119 | if (emsg != NULL) |
115 | { | 120 | { |
@@ -126,10 +131,10 @@ shutdown_callback (void *cls, const char *emsg) | |||
126 | 131 | ||
127 | 132 | ||
128 | /** | 133 | /** |
129 | * Shutdown nicely | 134 | * Close sockets and stop testing deamons nicely |
130 | */ | 135 | */ |
131 | static void | 136 | static void |
132 | do_shutdown (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | 137 | do_close (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) |
133 | { | 138 | { |
134 | if (NULL != peer1.socket) | 139 | if (NULL != peer1.socket) |
135 | GNUNET_STREAM_close (peer1.socket); | 140 | GNUNET_STREAM_close (peer1.socket); |
@@ -149,12 +154,44 @@ do_shutdown (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | |||
149 | GNUNET_TESTING_daemons_stop (pg, | 154 | GNUNET_TESTING_daemons_stop (pg, |
150 | GNUNET_TIME_relative_multiply | 155 | GNUNET_TIME_relative_multiply |
151 | (GNUNET_TIME_UNIT_SECONDS, 5), | 156 | (GNUNET_TIME_UNIT_SECONDS, 5), |
152 | &shutdown_callback, | 157 | &peergroup_shutdown_callback, |
153 | NULL); | 158 | NULL); |
154 | } | 159 | } |
155 | 160 | ||
156 | 161 | ||
157 | /** | 162 | /** |
163 | * Completion callback for shutdown | ||
164 | * | ||
165 | * @param cls the closure from GNUNET_STREAM_shutdown call | ||
166 | * @param operation the operation that was shutdown (SHUT_RD, SHUT_WR, | ||
167 | * SHUT_RDWR) | ||
168 | */ | ||
169 | static void | ||
170 | shutdown_completion (void *cls, | ||
171 | int operation) | ||
172 | { | ||
173 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
174 | "STREAM shutdown successful\n"); | ||
175 | GNUNET_SCHEDULER_add_now (&do_close, | ||
176 | cls); | ||
177 | } | ||
178 | |||
179 | |||
180 | |||
181 | /** | ||
182 | * Shutdown sockets gracefully | ||
183 | */ | ||
184 | static void | ||
185 | do_shutdown (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | ||
186 | { | ||
187 | peer1.shutdown_handle = GNUNET_STREAM_shutdown (peer1.socket, | ||
188 | SHUT_RDWR, | ||
189 | &shutdown_completion, | ||
190 | cls); | ||
191 | } | ||
192 | |||
193 | |||
194 | /** | ||
158 | * Something went wrong and timed out. Kill everything and set error flag | 195 | * Something went wrong and timed out. Kill everything and set error flag |
159 | */ | 196 | */ |
160 | static void | 197 | static void |
@@ -167,7 +204,7 @@ do_abort (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | |||
167 | } | 204 | } |
168 | result = GNUNET_SYSERR; | 205 | result = GNUNET_SYSERR; |
169 | abort_task = 0; | 206 | abort_task = 0; |
170 | do_shutdown (cls, tc); | 207 | do_close (cls, tc); |
171 | } | 208 | } |
172 | 209 | ||
173 | /** | 210 | /** |
@@ -237,7 +274,7 @@ write_completion (void *cls, | |||
237 | else | 274 | else |
238 | { | 275 | { |
239 | writing_success = GNUNET_YES; | 276 | writing_success = GNUNET_YES; |
240 | if (GNUNET_YES == reading_success) | 277 | if (GNUNET_YES == reading_success) |
241 | GNUNET_SCHEDULER_add_now (&do_shutdown, NULL); | 278 | GNUNET_SCHEDULER_add_now (&do_shutdown, NULL); |
242 | } | 279 | } |
243 | } | 280 | } |