aboutsummaryrefslogtreecommitdiff
path: root/src/stream
diff options
context:
space:
mode:
authorSree Harsha Totakura <totakura@in.tum.de>2012-11-19 13:07:04 +0000
committerSree Harsha Totakura <totakura@in.tum.de>2012-11-19 13:07:04 +0000
commitc404e1af3fe0bb2521f86927b8e9e17735f7a3dc (patch)
tree94a6e054835205aa4cde33062d1133abb9e41424 /src/stream
parent203bb6f1d36b66c0ea4c81b0aaada34f336a8ae2 (diff)
downloadgnunet-c404e1af3fe0bb2521f86927b8e9e17735f7a3dc.tar.gz
gnunet-c404e1af3fe0bb2521f86927b8e9e17735f7a3dc.zip
- towards cleaner shutdowns
Diffstat (limited to 'src/stream')
-rw-r--r--src/stream/stream_api.c71
1 files changed, 60 insertions, 11 deletions
diff --git a/src/stream/stream_api.c b/src/stream/stream_api.c
index 05d09aced..24fd8e8f8 100644
--- a/src/stream/stream_api.c
+++ b/src/stream/stream_api.c
@@ -302,6 +302,16 @@ struct GNUNET_STREAM_Socket
302 int testing_active; 302 int testing_active;
303 303
304 /** 304 /**
305 * Is receive closed
306 */
307 int receive_closed;
308
309 /**
310 * Is transmission closed
311 */
312 int transmit_closed;
313
314 /**
305 * The application port number (type: uint32_t) 315 * The application port number (type: uint32_t)
306 */ 316 */
307 GNUNET_MESH_ApplicationType app_port; 317 GNUNET_MESH_ApplicationType app_port;
@@ -546,6 +556,11 @@ struct GNUNET_STREAM_ShutdownHandle
546 GNUNET_SCHEDULER_TaskIdentifier close_msg_retransmission_task_id; 556 GNUNET_SCHEDULER_TaskIdentifier close_msg_retransmission_task_id;
547 557
548 /** 558 /**
559 * Task scheduled to call the shutdown continuation callback
560 */
561 GNUNET_SCHEDULER_TaskIdentifier call_cont_task_id;
562
563 /**
549 * Which operation to shutdown? SHUT_RD, SHUT_WR or SHUT_RDWR 564 * Which operation to shutdown? SHUT_RD, SHUT_WR or SHUT_RDWR
550 */ 565 */
551 int operation; 566 int operation;
@@ -1673,6 +1688,28 @@ client_handle_transmit_close (void *cls,
1673 1688
1674 1689
1675/** 1690/**
1691 * Task for calling the shutdown continuation callback
1692 *
1693 * @param cls the socket
1694 * @param tc the scheduler task context
1695 */
1696static void
1697call_cont_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
1698{
1699 struct GNUNET_STREAM_Socket *socket = cls;
1700
1701 GNUNET_assert (NULL != socket->shutdown_handle);
1702 socket->shutdown_handle->call_cont_task_id = GNUNET_SCHEDULER_NO_TASK;
1703 if (NULL != socket->shutdown_handle->completion_cb)
1704 socket->shutdown_handle->completion_cb
1705 (socket->shutdown_handle->completion_cls,
1706 socket->shutdown_handle->operation);
1707 GNUNET_free (socket->shutdown_handle);
1708 socket->shutdown_handle = NULL;
1709}
1710
1711
1712/**
1676 * Generic handler for GNUNET_MESSAGE_TYPE_STREAM_*_CLOSE_ACK messages 1713 * Generic handler for GNUNET_MESSAGE_TYPE_STREAM_*_CLOSE_ACK messages
1677 * 1714 *
1678 * @param socket the socket 1715 * @param socket the socket
@@ -1697,6 +1734,7 @@ handle_generic_close_ack (struct GNUNET_STREAM_Socket *socket,
1697 shutdown_handle = socket->shutdown_handle; 1734 shutdown_handle = socket->shutdown_handle;
1698 if (NULL == shutdown_handle) 1735 if (NULL == shutdown_handle)
1699 { 1736 {
1737 /* This happens when the shudown handle is cancelled */
1700 LOG (GNUNET_ERROR_TYPE_DEBUG, 1738 LOG (GNUNET_ERROR_TYPE_DEBUG,
1701 "%s: Received CLOSE_ACK when shutdown handle is NULL\n", 1739 "%s: Received CLOSE_ACK when shutdown handle is NULL\n",
1702 GNUNET_i2s (&socket->other_peer)); 1740 GNUNET_i2s (&socket->other_peer));
@@ -1774,9 +1812,8 @@ handle_generic_close_ack (struct GNUNET_STREAM_Socket *socket,
1774 default: 1812 default:
1775 GNUNET_assert (0); 1813 GNUNET_assert (0);
1776 } 1814 }
1777 if (NULL != shutdown_handle->completion_cb) /* Shutdown completion */ 1815 shutdown_handle->call_cont_task_id = GNUNET_SCHEDULER_add_now
1778 shutdown_handle->completion_cb(shutdown_handle->completion_cls, 1816 (&call_cont_task, socket);
1779 operation);
1780 if (GNUNET_SCHEDULER_NO_TASK 1817 if (GNUNET_SCHEDULER_NO_TASK
1781 != shutdown_handle->close_msg_retransmission_task_id) 1818 != shutdown_handle->close_msg_retransmission_task_id)
1782 { 1819 {
@@ -1785,8 +1822,6 @@ handle_generic_close_ack (struct GNUNET_STREAM_Socket *socket,
1785 shutdown_handle->close_msg_retransmission_task_id = 1822 shutdown_handle->close_msg_retransmission_task_id =
1786 GNUNET_SCHEDULER_NO_TASK; 1823 GNUNET_SCHEDULER_NO_TASK;
1787 } 1824 }
1788 GNUNET_free (shutdown_handle); /* Free shutdown handle */
1789 socket->shutdown_handle = NULL;
1790 return GNUNET_OK; 1825 return GNUNET_OK;
1791} 1826}
1792 1827
@@ -1970,7 +2005,6 @@ handle_close (struct GNUNET_STREAM_Socket *socket,
1970 default: 2005 default:
1971 break; 2006 break;
1972 } 2007 }
1973
1974 LOG (GNUNET_ERROR_TYPE_DEBUG, 2008 LOG (GNUNET_ERROR_TYPE_DEBUG,
1975 "%s: Received CLOSE from %s\n", 2009 "%s: Received CLOSE from %s\n",
1976 GNUNET_i2s (&socket->other_peer), 2010 GNUNET_i2s (&socket->other_peer),
@@ -1979,9 +2013,10 @@ handle_close (struct GNUNET_STREAM_Socket *socket,
1979 close_ack->header.size = htons (sizeof (struct GNUNET_STREAM_MessageHeader)); 2013 close_ack->header.size = htons (sizeof (struct GNUNET_STREAM_MessageHeader));
1980 close_ack->header.type = htons (GNUNET_MESSAGE_TYPE_STREAM_CLOSE_ACK); 2014 close_ack->header.type = htons (GNUNET_MESSAGE_TYPE_STREAM_CLOSE_ACK);
1981 queue_message (socket, close_ack, &set_state_closed, NULL, GNUNET_NO); 2015 queue_message (socket, close_ack, &set_state_closed, NULL, GNUNET_NO);
1982 if (socket->state == STATE_CLOSED) 2016 if (STATE_CLOSED == socket->state)
1983 return GNUNET_OK; 2017 return GNUNET_OK;
1984 2018 socket->receive_closed = GNUNET_YES;
2019 socket->transmit_closed = GNUNET_YES;
1985 GNUNET_free_non_null (socket->receive_buffer); /* Free the receive buffer */ 2020 GNUNET_free_non_null (socket->receive_buffer); /* Free the receive buffer */
1986 socket->receive_buffer = NULL; 2021 socket->receive_buffer = NULL;
1987 socket->receive_buffer_size = 0; 2022 socket->receive_buffer_size = 0;
@@ -3037,13 +3072,22 @@ GNUNET_STREAM_shutdown (struct GNUNET_STREAM_Socket *socket,
3037 struct GNUNET_STREAM_MessageHeader *msg; 3072 struct GNUNET_STREAM_MessageHeader *msg;
3038 3073
3039 GNUNET_assert (NULL == socket->shutdown_handle); 3074 GNUNET_assert (NULL == socket->shutdown_handle);
3040
3041 handle = GNUNET_malloc (sizeof (struct GNUNET_STREAM_ShutdownHandle)); 3075 handle = GNUNET_malloc (sizeof (struct GNUNET_STREAM_ShutdownHandle));
3042 handle->socket = socket; 3076 handle->socket = socket;
3043 handle->completion_cb = completion_cb; 3077 handle->completion_cb = completion_cb;
3044 handle->completion_cls = completion_cls; 3078 handle->completion_cls = completion_cls;
3045 socket->shutdown_handle = handle; 3079 socket->shutdown_handle = handle;
3046 3080 if ( ((GNUNET_YES == socket->receive_closed) && (SHUT_RD == operation))
3081 || ((GNUNET_YES == socket->transmit_closed) && (SHUT_WR == operation))
3082 || ((GNUNET_YES == socket->transmit_closed)
3083 && (GNUNET_YES == socket->receive_closed)
3084 && (SHUT_RDWR == operation)) )
3085 {
3086 handle->operation = operation;
3087 handle->call_cont_task_id = GNUNET_SCHEDULER_add_now (&call_cont_task,
3088 socket);
3089 return handle;
3090 }
3047 msg = GNUNET_malloc (sizeof (struct GNUNET_STREAM_MessageHeader)); 3091 msg = GNUNET_malloc (sizeof (struct GNUNET_STREAM_MessageHeader));
3048 msg->header.size = htons (sizeof (struct GNUNET_STREAM_MessageHeader)); 3092 msg->header.size = htons (sizeof (struct GNUNET_STREAM_MessageHeader));
3049 switch (operation) 3093 switch (operation)
@@ -3098,7 +3142,10 @@ GNUNET_STREAM_shutdown (struct GNUNET_STREAM_Socket *socket,
3098 3142
3099 3143
3100/** 3144/**
3101 * Cancels a pending shutdown 3145 * Cancels a pending shutdown. Note that the shutdown messages may already be
3146 * sent and the stream is shutdown already for the operation given to
3147 * GNUNET_STREAM_shutdown(). This function only clears up any retranmissions of
3148 * shutdown messages and frees the shutdown handle.
3102 * 3149 *
3103 * @param handle the shutdown handle returned from GNUNET_STREAM_shutdown 3150 * @param handle the shutdown handle returned from GNUNET_STREAM_shutdown
3104 */ 3151 */
@@ -3107,6 +3154,8 @@ GNUNET_STREAM_shutdown_cancel (struct GNUNET_STREAM_ShutdownHandle *handle)
3107{ 3154{
3108 if (GNUNET_SCHEDULER_NO_TASK != handle->close_msg_retransmission_task_id) 3155 if (GNUNET_SCHEDULER_NO_TASK != handle->close_msg_retransmission_task_id)
3109 GNUNET_SCHEDULER_cancel (handle->close_msg_retransmission_task_id); 3156 GNUNET_SCHEDULER_cancel (handle->close_msg_retransmission_task_id);
3157 if (GNUNET_SCHEDULER_NO_TASK != handle->call_cont_task_id)
3158 GNUNET_SCHEDULER_cancel (handle->call_cont_task_id);
3110 handle->socket->shutdown_handle = NULL; 3159 handle->socket->shutdown_handle = NULL;
3111 GNUNET_free (handle); 3160 GNUNET_free (handle);
3112} 3161}