From b19f5f159c18d5d0685af67628ee6f24c86b7c27 Mon Sep 17 00:00:00 2001 From: Sree Harsha Totakura Date: Wed, 12 Dec 2012 23:00:05 +0000 Subject: [PATCH] - fixes --- src/stream/stream_api.c | 162 +++++++++++++--------- src/stream/test_stream_2peers_halfclose.c | 7 +- 2 files changed, 104 insertions(+), 65 deletions(-) diff --git a/src/stream/stream_api.c b/src/stream/stream_api.c index 498d64d81..4b86bece0 100644 --- a/src/stream/stream_api.c +++ b/src/stream/stream_api.c @@ -295,11 +295,6 @@ struct GNUNET_STREAM_Socket */ enum State state; - /** - * The status of the socket - */ - enum GNUNET_STREAM_Status status; - /** * Whether testing mode is active or not */ @@ -1022,7 +1017,7 @@ call_read_processor (void *cls, /* Call the data processor */ LOG (GNUNET_ERROR_TYPE_DEBUG, "%s: Calling read processor\n", GNUNET_i2s (&socket->other_peer)); - read_size = proc (proc_cls, socket->status, + read_size = proc (proc_cls, GNUNET_STREAM_OK, socket->receive_buffer + socket->copy_offset, valid_read_size); LOG (GNUNET_ERROR_TYPE_DEBUG, "%s: Read processor read %d bytes\n", @@ -1659,6 +1654,63 @@ client_handle_reset (void *cls, } +/** + * Frees the socket's receive buffers, marks the socket as receive closed and + * calls the DataProcessor with GNUNET_STREAM_SHUTDOWN status if a read handle + * is present + * + * @param socket the socket + */ +static void +do_receive_shutdown (struct GNUNET_STREAM_Socket *socket) +{ + socket->receive_closed = GNUNET_YES; + GNUNET_free_non_null (socket->receive_buffer); /* Free the receive buffer */ + socket->receive_buffer = NULL; + socket->receive_buffer_size = 0; + if (NULL != socket->read_handle) + { + GNUNET_STREAM_DataProcessor proc; + void *proc_cls; + + proc = socket->read_handle->proc; + proc_cls = socket->read_handle->proc_cls; + GNUNET_STREAM_read_cancel (socket->read_handle); + socket->read_handle = NULL; + if (NULL != proc) + proc (proc_cls, GNUNET_STREAM_SHUTDOWN, NULL, 0); + } +} + + +/** + * Marks the socket as transmit closed and calls the CompletionContinuation with + * GNUNET_STREAM_SHUTDOWN status if a write handle is present + * + * @param socket the socket + */ +static void +do_transmit_shutdown (struct GNUNET_STREAM_Socket *socket) +{ + socket->transmit_closed = GNUNET_YES; + /* If write handle is present call it with GNUNET_STREAM_SHUTDOWN to signal + that that stream has been shutdown */ + if (NULL != socket->write_handle) + { + GNUNET_STREAM_CompletionContinuation wc; + void *wc_cls; + + wc = socket->write_handle->write_cont; + wc_cls = socket->write_handle->write_cont_cls; + GNUNET_STREAM_write_cancel (socket->write_handle); + socket->write_handle = NULL; + if (NULL != wc) + wc (wc_cls, + GNUNET_STREAM_SHUTDOWN, 0); + } +} + + /** * Common message handler for handling TRANSMIT_CLOSE messages * @@ -1691,19 +1743,29 @@ handle_transmit_close (struct GNUNET_STREAM_Socket *socket, default: break; } - LOG (GNUNET_ERROR_TYPE_DEBUG, "%s: Received TRANSMIT_CLOSE from %s\n", - GNUNET_i2s (&socket->other_peer), GNUNET_i2s (&socket->other_peer)); - socket->receive_closed = GNUNET_YES; - if (GNUNET_YES == socket->transmit_closed) - socket->state = STATE_CLOSED; - else - socket->state = STATE_RECEIVE_CLOSED; /* Send TRANSMIT_CLOSE_ACK */ reply = GNUNET_malloc (sizeof (struct GNUNET_STREAM_MessageHeader)); reply->header.type = htons (GNUNET_MESSAGE_TYPE_STREAM_TRANSMIT_CLOSE_ACK); reply->header.size = htons (sizeof (struct GNUNET_STREAM_MessageHeader)); queue_message (socket, reply, NULL, NULL, GNUNET_NO); + LOG (GNUNET_ERROR_TYPE_DEBUG, "%s: Received TRANSMIT_CLOSE from %s\n", + GNUNET_i2s (&socket->other_peer), GNUNET_i2s (&socket->other_peer)); + switch(socket->state) + { + case STATE_RECEIVE_CLOSED: + case STATE_RECEIVE_CLOSE_WAIT: + case STATE_CLOSE_WAIT: + case STATE_CLOSED: + return GNUNET_OK; + default: + break; + } + do_receive_shutdown (socket); + if (GNUNET_YES == socket->transmit_closed) + socket->state = STATE_CLOSED; + else + socket->state = STATE_RECEIVE_CLOSED; return GNUNET_OK; } @@ -1942,12 +2004,7 @@ handle_receive_close (struct GNUNET_STREAM_Socket *socket, break; } LOG (GNUNET_ERROR_TYPE_DEBUG, "%s: Received RECEIVE_CLOSE from %s\n", - GNUNET_i2s (&socket->other_peer), GNUNET_i2s (&socket->other_peer)); - socket->transmit_closed = GNUNET_YES; - if (GNUNET_YES == socket->receive_closed) - socket->state = STATE_CLOSED; - else - socket->state = STATE_TRANSMIT_CLOSED; + GNUNET_i2s (&socket->other_peer), GNUNET_i2s (&socket->other_peer)); receive_close_ack = GNUNET_malloc (sizeof (struct GNUNET_STREAM_MessageHeader)); receive_close_ack->header.size = @@ -1955,21 +2012,21 @@ handle_receive_close (struct GNUNET_STREAM_Socket *socket, receive_close_ack->header.type = htons (GNUNET_MESSAGE_TYPE_STREAM_RECEIVE_CLOSE_ACK); queue_message (socket, receive_close_ack, NULL, NULL, GNUNET_NO); - /* If write handle is present call it with GNUNET_STREAM_SHUTDOWN to signal - that that stream has been shutdown */ - if (NULL != socket->write_handle) + switch (socket->state) { - GNUNET_STREAM_CompletionContinuation wc; - void *wc_cls; - - wc = socket->write_handle->write_cont; - wc_cls = socket->write_handle->write_cont_cls; - GNUNET_STREAM_write_cancel (socket->write_handle); - socket->write_handle = NULL; - if (NULL != wc) - wc (wc_cls, - GNUNET_STREAM_SHUTDOWN, 0); + case STATE_TRANSMIT_CLOSED: + case STATE_TRANSMIT_CLOSE_WAIT: + case STATE_CLOSED: + case STATE_CLOSE_WAIT: + return GNUNET_OK; + default: + break; } + do_transmit_shutdown (socket); + if (GNUNET_YES == socket->receive_closed) + socket->state = STATE_CLOSED; + else + socket->state = STATE_TRANSMIT_CLOSED; return GNUNET_OK; } @@ -2075,28 +2132,12 @@ handle_close (struct GNUNET_STREAM_Socket *socket, close_ack->header.size = htons (sizeof (struct GNUNET_STREAM_MessageHeader)); close_ack->header.type = htons (GNUNET_MESSAGE_TYPE_STREAM_CLOSE_ACK); queue_message (socket, close_ack, &set_state_closed, NULL, GNUNET_NO); - if (STATE_CLOSED == socket->state) + if ((STATE_CLOSED == socket->state) || (STATE_CLOSE_WAIT == socket->state)) return GNUNET_OK; - socket->receive_closed = GNUNET_YES; - socket->transmit_closed = GNUNET_YES; - GNUNET_free_non_null (socket->receive_buffer); /* Free the receive buffer */ - socket->receive_buffer = NULL; - socket->receive_buffer_size = 0; - /* If write handle is present call it with GNUNET_STREAM_SHUTDOWN to signal - that that stream has been shutdown */ - if (NULL != socket->write_handle) - { - GNUNET_STREAM_CompletionContinuation wc; - void *wc_cls; - - wc = socket->write_handle->write_cont; - wc_cls = socket->write_handle->write_cont_cls; - GNUNET_STREAM_write_cancel (socket->write_handle); - socket->write_handle = NULL; - if (NULL != wc) - wc (wc_cls, - GNUNET_STREAM_SHUTDOWN, 0); - } + if (GNUNET_NO == socket->transmit_closed) + do_transmit_shutdown (socket); + if (GNUNET_NO == socket->receive_closed) + do_receive_shutdown (socket); return GNUNET_OK; } @@ -2665,7 +2706,7 @@ handle_ack (struct GNUNET_STREAM_Socket *socket, socket->write_handle = NULL; if (NULL != write_handle->write_cont) write_handle->write_cont (write_handle->write_cont_cls, - socket->status, + GNUNET_STREAM_OK, write_handle->size); /* We are done with the write handle - Freeing it */ GNUNET_free (write_handle); @@ -2941,7 +2982,6 @@ tunnel_cleaner (void *cls, GNUNET_STATISTICS_update (socket->stat_handle, "inbound connections", -1, GNUNET_NO); } - socket->status = GNUNET_STREAM_SYSERR; /* Clear Transmit handles */ if (NULL != socket->transmit_handle) { @@ -3632,14 +3672,12 @@ GNUNET_STREAM_read (struct GNUNET_STREAM_Socket *socket, "%s: %s()\n", GNUNET_i2s (&socket->other_peer), __func__); - /* Return NULL if there is already a read handle; the user has to cancel that - first before continuing or has to wait until it is completed */ - if (NULL != socket->read_handle) - { - GNUNET_assert (0); - return NULL; - } + /* Only one read handle is permitted at any time; cancel the existing or wait + for it to complete */ + GNUNET_assert (NULL == socket->read_handle); GNUNET_assert (NULL != proc); + if (GNUNET_YES == socket->receive_closed) + return NULL; switch (socket->state) { case STATE_RECEIVE_CLOSED: diff --git a/src/stream/test_stream_2peers_halfclose.c b/src/stream/test_stream_2peers_halfclose.c index 58f9f19cf..fa7b8194e 100644 --- a/src/stream/test_stream_2peers_halfclose.c +++ b/src/stream/test_stream_2peers_halfclose.c @@ -259,6 +259,7 @@ stream_read_task (void *cls, case PEER1_WRITE_SHUTDOWN: GNUNET_assert (&peer2 == peer); GNUNET_assert (NULL == peer->io_read_handle); + peer2.test_ok = GNUNET_YES; transition (); /* to PEER1_HALFCLOSE_READ */ break; default: @@ -614,8 +615,8 @@ input_processor (void *cls, } break; case PEER1_WRITE_SHUTDOWN: - GNUNET_assert (GNUNET_STREAM_SHUTDOWN == status); - peer2.test_ok = GNUNET_YES; + GNUNET_assert (0); /* This callback will not be called when stream + is shutdown */ break; case PEER1_HALFCLOSE_WRITE_FAIL: case PEER1_READ_SHUTDOWN: @@ -868,7 +869,7 @@ test_master (void *cls, unsigned int num_peers, setup_state = INIT; abort_task = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply - (GNUNET_TIME_UNIT_SECONDS, 40), &do_abort, + (GNUNET_TIME_UNIT_SECONDS, 1000), &do_abort, NULL); } -- 2.25.1