aboutsummaryrefslogtreecommitdiff
path: root/src/scalarproduct
diff options
context:
space:
mode:
authorChristian Fuchs <christian.fuchs@cfuchs.net>2013-09-05 15:45:42 +0000
committerChristian Fuchs <christian.fuchs@cfuchs.net>2013-09-05 15:45:42 +0000
commit9a1ff3ca18fa008ca7f707a09af792d97fcec489 (patch)
treec26939045ad4b9bff576f82562adadefcce4e7a6 /src/scalarproduct
parentf0e8d8a426ab418be6aa37411e94c716e461bc75 (diff)
downloadgnunet-9a1ff3ca18fa008ca7f707a09af792d97fcec489.tar.gz
gnunet-9a1ff3ca18fa008ca7f707a09af792d97fcec489.zip
reworked task housekeeping\
added a couple of TODOs introduced due to the recent logics changes
Diffstat (limited to 'src/scalarproduct')
-rw-r--r--src/scalarproduct/gnunet-service-scalarproduct.c225
1 files changed, 94 insertions, 131 deletions
diff --git a/src/scalarproduct/gnunet-service-scalarproduct.c b/src/scalarproduct/gnunet-service-scalarproduct.c
index bbc08128a..dd0c1f29d 100644
--- a/src/scalarproduct/gnunet-service-scalarproduct.c
+++ b/src/scalarproduct/gnunet-service-scalarproduct.c
@@ -160,6 +160,10 @@ struct ServiceSession
160 * tunnel-handle associated with our mesh handle 160 * tunnel-handle associated with our mesh handle
161 */ 161 */
162 struct GNUNET_MESH_Tunnel * tunnel; 162 struct GNUNET_MESH_Tunnel * tunnel;
163
164 GNUNET_SCHEDULER_TaskIdentifier client_notification_task;
165
166 GNUNET_SCHEDULER_TaskIdentifier service_request_task;
163}; 167};
164 168
165/** 169/**
@@ -179,32 +183,6 @@ struct MessageObject
179 struct GNUNET_MessageHeader * msg; 183 struct GNUNET_MessageHeader * msg;
180}; 184};
181 185
182/**
183 * Linked list for all queued tasks.
184 */
185struct TaskClosure
186{
187
188 /**
189 * point to the next element of the list
190 */
191 struct TaskClosure *next;
192
193 /**
194 * point to the previous element of the list
195 */
196 struct TaskClosure *prev;
197
198 /**
199 * the handle associated with this task, canceled upon shutdown
200 */
201 GNUNET_SCHEDULER_TaskIdentifier my_handle;
202
203 /**
204 * the closure, as it's always a session-struct, we don't cast this to void
205 */
206 struct ServiceSession * my_session;
207};
208/////////////////////////////////////////////////////////////////////////////// 186///////////////////////////////////////////////////////////////////////////////
209// Global Variables 187// Global Variables
210/////////////////////////////////////////////////////////////////////////////// 188///////////////////////////////////////////////////////////////////////////////
@@ -292,15 +270,6 @@ static struct ServiceSession * from_service_tail;
292 */ 270 */
293static int do_shutdown; 271static int do_shutdown;
294 272
295/**
296 * DLL for all out active, queued tasks. Purged upon disconnect
297 */
298static struct TaskClosure * tasklist_head;
299/**
300 * DLL for all out active, queued tasks. Purged upon disconnect
301 */
302static struct TaskClosure * tasklist_tail;
303
304/////////////////////////////////////////////////////////////////////////////// 273///////////////////////////////////////////////////////////////////////////////
305// Helper Functions 274// Helper Functions
306/////////////////////////////////////////////////////////////////////////////// 275///////////////////////////////////////////////////////////////////////////////
@@ -701,18 +670,6 @@ free_session (struct ServiceSession * session)
701 670
702 GNUNET_free_non_null (session->vector); 671 GNUNET_free_non_null (session->vector);
703 } 672 }
704#if FIXME_FUCHS
705 if (GNUNET_SCHEDULER_NO_TASK != session->prepare_response_task)
706 {
707 GNUNET_SCHEDULER_cancel (session->prepare_response_task);
708 session->prepare_response_task = GNUNET_SCHEDULER_NO_TASK;
709 }
710 if (NULL != session->client_transmit_handle)
711 {
712 GNUNET_SERVER_notify_transmit_ready_cancel (session->client_transmit_handle);
713 session->client_transmit_handle = NULL;
714 }
715#endif
716 GNUNET_free (session); 673 GNUNET_free (session);
717} 674}
718/////////////////////////////////////////////////////////////////////////////// 675///////////////////////////////////////////////////////////////////////////////
@@ -733,24 +690,39 @@ static void
733handle_client_disconnect (void *cls, 690handle_client_disconnect (void *cls,
734 struct GNUNET_SERVER_Client *client) 691 struct GNUNET_SERVER_Client *client)
735{ 692{
736 struct ServiceSession *elem; 693 struct ServiceSession *session;
737 694
738 elem = GNUNET_SERVER_client_get_user_context (client, struct ServiceSession); 695 session = GNUNET_SERVER_client_get_user_context (client, struct ServiceSession);
739 if (NULL == elem) 696 if (NULL == session)
740 return; 697 return;
741 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 698 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
742 _ ("Client (%p) disconnected from us.\n"), client); 699 _ ("Client (%p) disconnected from us.\n"), client);
743 GNUNET_CONTAINER_DLL_remove (from_client_head, from_client_tail, elem); 700 GNUNET_CONTAINER_DLL_remove (from_client_head, from_client_tail, session);
744 701
745 if (!(elem->role == BOB && elem->state == FINALIZED)) 702 if (!(session->role == BOB && session->state == FINALIZED))
746 { 703 {
747 //we MUST terminate any client message underway 704 //we MUST terminate any client message underway
748 if (elem->service_transmit_handle && elem->tunnel) 705 if (session->service_transmit_handle && session->tunnel)
749 GNUNET_MESH_notify_transmit_ready_cancel (elem->service_transmit_handle); 706 GNUNET_MESH_notify_transmit_ready_cancel (session->service_transmit_handle);
750 if (elem->tunnel && elem->state == WAITING_FOR_RESPONSE_FROM_SERVICE) 707 if (session->tunnel && session->state == WAITING_FOR_RESPONSE_FROM_SERVICE)
751 GNUNET_MESH_tunnel_destroy (elem->tunnel); 708 GNUNET_MESH_tunnel_destroy (session->tunnel);
709 }
710 if (GNUNET_SCHEDULER_NO_TASK != session->client_notification_task)
711 {
712 GNUNET_SCHEDULER_cancel (session->client_notification_task);
713 session->client_notification_task = GNUNET_SCHEDULER_NO_TASK;
714 }
715 if (GNUNET_SCHEDULER_NO_TASK != session->service_request_task)
716 {
717 GNUNET_SCHEDULER_cancel (session->service_request_task);
718 session->service_request_task = GNUNET_SCHEDULER_NO_TASK;
752 } 719 }
753 free_session (elem); 720 if (NULL != session->client_transmit_handle)
721 {
722 GNUNET_SERVER_notify_transmit_ready_cancel (session->client_transmit_handle);
723 session->client_transmit_handle = NULL;
724 }
725 free_session (session);
754} 726}
755 727
756 728
@@ -768,13 +740,11 @@ static void
768prepare_client_end_notification (void * cls, 740prepare_client_end_notification (void * cls,
769 const struct GNUNET_SCHEDULER_TaskContext * tc) 741 const struct GNUNET_SCHEDULER_TaskContext * tc)
770{ 742{
771 struct TaskClosure * task = cls; 743 struct ServiceSession * session = cls;
772 struct ServiceSession * session = task->my_session;
773 struct GNUNET_SCALARPRODUCT_client_response * msg; 744 struct GNUNET_SCALARPRODUCT_client_response * msg;
774 struct MessageObject * msg_obj; 745 struct MessageObject * msg_obj;
775 746
776 GNUNET_CONTAINER_DLL_remove (tasklist_head, tasklist_tail, task); 747 session->client_notification_task = GNUNET_SCHEDULER_NO_TASK;
777 GNUNET_free(task);
778 748
779 msg = GNUNET_new (struct GNUNET_SCALARPRODUCT_client_response); 749 msg = GNUNET_new (struct GNUNET_SCALARPRODUCT_client_response);
780 msg->header.type = htons (GNUNET_MESSAGE_TYPE_SCALARPRODUCT_SERVICE_TO_CLIENT); 750 msg->header.type = htons (GNUNET_MESSAGE_TYPE_SCALARPRODUCT_SERVICE_TO_CLIENT);
@@ -797,11 +767,9 @@ prepare_client_end_notification (void * cls,
797 &do_send_message, 767 &do_send_message,
798 msg_obj); 768 msg_obj);
799 769
800
801 // if we could not even queue our request, something is wrong 770 // if we could not even queue our request, something is wrong
802 if ( ! session->client_transmit_handle) 771 if ( ! session->client_transmit_handle)
803 { 772 {
804
805 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, _ ("Could not send message to client (%p)! This is OK if it was disconnected beforehand already.\n"), session->client); 773 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, _ ("Could not send message to client (%p)! This is OK if it was disconnected beforehand already.\n"), session->client);
806 // usually gets freed by do_send_message 774 // usually gets freed by do_send_message
807 GNUNET_free (msg_obj); 775 GNUNET_free (msg_obj);
@@ -810,7 +778,6 @@ prepare_client_end_notification (void * cls,
810 else 778 else
811 GNUNET_log (GNUNET_ERROR_TYPE_INFO, _ ("Sending session-end notification to client (%p) for session %s\n"), &session->client, GNUNET_h2s (&session->key)); 779 GNUNET_log (GNUNET_ERROR_TYPE_INFO, _ ("Sending session-end notification to client (%p) for session %s\n"), &session->client, GNUNET_h2s (&session->key));
812 780
813 free_session(session);
814} 781}
815 782
816 783
@@ -946,14 +913,12 @@ prepare_service_response (gcry_mpi_t * r,
946 //disconnect our client 913 //disconnect our client
947 if ( ! request->service_transmit_handle) 914 if ( ! request->service_transmit_handle)
948 { 915 {
949 struct TaskClosure * task = GNUNET_new(struct TaskClosure);
950
951 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _ ("Could not send service-response message via mesh!)\n")); 916 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _ ("Could not send service-response message via mesh!)\n"));
952 GNUNET_CONTAINER_DLL_remove (from_client_head, from_client_tail, response); 917 GNUNET_CONTAINER_DLL_remove (from_client_head, from_client_tail, response);
953 task->my_session = response; 918
954 task->my_handle = GNUNET_SCHEDULER_add_now (&prepare_client_end_notification, 919 response->client_notification_task =
955 task); 920 GNUNET_SCHEDULER_add_now (&prepare_client_end_notification,
956 GNUNET_CONTAINER_DLL_insert (tasklist_head, tasklist_tail, task); 921 response);
957 return GNUNET_NO; 922 return GNUNET_NO;
958 } 923 }
959 return GNUNET_OK; 924 return GNUNET_OK;
@@ -1186,8 +1151,7 @@ static void
1186prepare_service_request (void *cls, 1151prepare_service_request (void *cls,
1187 const struct GNUNET_SCHEDULER_TaskContext *tc) 1152 const struct GNUNET_SCHEDULER_TaskContext *tc)
1188{ 1153{
1189 struct TaskClosure * task = cls; 1154 struct ServiceSession * session = cls;
1190 struct ServiceSession * session = task->my_session;
1191 unsigned char * current; 1155 unsigned char * current;
1192 struct GNUNET_SCALARPRODUCT_service_request * msg; 1156 struct GNUNET_SCALARPRODUCT_service_request * msg;
1193 struct MessageObject * msg_obj; 1157 struct MessageObject * msg_obj;
@@ -1198,8 +1162,7 @@ prepare_service_request (void *cls,
1198 gcry_mpi_t a; 1162 gcry_mpi_t a;
1199 uint32_t value; 1163 uint32_t value;
1200 1164
1201 GNUNET_CONTAINER_DLL_remove (tasklist_head, tasklist_tail, task); 1165 session->service_request_task = GNUNET_SCHEDULER_NO_TASK;
1202 GNUNET_free(task);
1203 1166
1204 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, _ ("Successfully created new tunnel to peer (%s)!\n"), GNUNET_i2s (&session->peer)); 1167 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, _ ("Successfully created new tunnel to peer (%s)!\n"), GNUNET_i2s (&session->peer));
1205 1168
@@ -1213,15 +1176,13 @@ prepare_service_request (void *cls,
1213 + session->mask_length 1176 + session->mask_length
1214 + my_pubkey_external_length) 1177 + my_pubkey_external_length)
1215 { 1178 {
1216 struct TaskClosure * task = GNUNET_new(struct TaskClosure);
1217 // TODO FEATURE: fallback to fragmentation, in case the message is too long 1179 // TODO FEATURE: fallback to fragmentation, in case the message is too long
1218 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, _ ("Message too large, fragmentation is currently not supported!\n")); 1180 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, _ ("Message too large, fragmentation is currently not supported!\n"));
1219 GNUNET_CONTAINER_DLL_remove (from_client_head, from_client_tail, session); 1181 GNUNET_CONTAINER_DLL_remove (from_client_head, from_client_tail, session);
1220 1182
1221 task->my_session = session; 1183 session->client_notification_task =
1222 task->my_handle = GNUNET_SCHEDULER_add_now (&prepare_client_end_notification, 1184 GNUNET_SCHEDULER_add_now (&prepare_client_end_notification,
1223 task); 1185 session);
1224 GNUNET_CONTAINER_DLL_insert (tasklist_head, tasklist_tail, task);
1225 return; 1186 return;
1226 } 1187 }
1227 msg = GNUNET_malloc (msg_length); 1188 msg = GNUNET_malloc (msg_length);
@@ -1297,16 +1258,14 @@ prepare_service_request (void *cls,
1297 msg_obj); 1258 msg_obj);
1298 if ( ! session->service_transmit_handle) 1259 if ( ! session->service_transmit_handle)
1299 { 1260 {
1300 struct TaskClosure * task = GNUNET_new(struct TaskClosure);
1301 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("Could not send mutlicast message to tunnel!\n")); 1261 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("Could not send mutlicast message to tunnel!\n"));
1302 GNUNET_free (msg_obj); 1262 GNUNET_free (msg_obj);
1303 GNUNET_free (msg); 1263 GNUNET_free (msg);
1304 GNUNET_CONTAINER_DLL_remove (from_client_head, from_client_tail, session); 1264 GNUNET_CONTAINER_DLL_remove (from_client_head, from_client_tail, session);
1305 1265
1306 task->my_session = session; 1266 session->client_notification_task =
1307 task->my_handle = GNUNET_SCHEDULER_add_now (&prepare_client_end_notification, 1267 GNUNET_SCHEDULER_add_now (&prepare_client_end_notification,
1308 task); 1268 session);
1309 GNUNET_CONTAINER_DLL_insert (tasklist_head, tasklist_tail, task);
1310 } 1269 }
1311} 1270}
1312 1271
@@ -1326,7 +1285,6 @@ handle_client_request (void *cls,
1326 const struct GNUNET_MessageHeader *message) 1285 const struct GNUNET_MessageHeader *message)
1327{ 1286{
1328 const struct GNUNET_SCALARPRODUCT_client_request * msg = (const struct GNUNET_SCALARPRODUCT_client_request *) message; 1287 const struct GNUNET_SCALARPRODUCT_client_request * msg = (const struct GNUNET_SCALARPRODUCT_client_request *) message;
1329 struct TaskClosure * task;
1330 struct ServiceSession * session; 1288 struct ServiceSession * session;
1331 uint16_t element_count; 1289 uint16_t element_count;
1332 uint16_t mask_length; 1290 uint16_t mask_length;
@@ -1334,7 +1292,12 @@ handle_client_request (void *cls,
1334 int32_t * vector; 1292 int32_t * vector;
1335 uint32_t i; 1293 uint32_t i;
1336 1294
1337 GNUNET_assert (message); 1295 GNUNET_SERVER_client_get_user_context (client, session);
1296 if (NULL != session){
1297 free_session(session);
1298 // FIXME: also terminate active handles and tasks, in it's not finalized
1299 GNUNET_SERVER_client_set_user_context (client, NULL);
1300 }
1338 1301
1339 //we need at least a peer and one message id to compare 1302 //we need at least a peer and one message id to compare
1340 if (sizeof (struct GNUNET_SCALARPRODUCT_client_request) > ntohs (msg->header.size)) 1303 if (sizeof (struct GNUNET_SCALARPRODUCT_client_request) > ntohs (msg->header.size))
@@ -1373,7 +1336,10 @@ handle_client_request (void *cls,
1373 } 1336 }
1374 1337
1375 session = GNUNET_new (struct ServiceSession); 1338 session = GNUNET_new (struct ServiceSession);
1339 //FIXME: this actually should not happen here!
1376 GNUNET_SERVER_client_set_user_context (client, session); 1340 GNUNET_SERVER_client_set_user_context (client, session);
1341 session->service_request_task = GNUNET_SCHEDULER_NO_TASK;
1342 session->client_notification_task = GNUNET_SCHEDULER_NO_TASK;
1377 session->client = client; 1343 session->client = client;
1378 session->element_count = element_count; 1344 session->element_count = element_count;
1379 session->mask_length = mask_length; 1345 session->mask_length = mask_length;
@@ -1447,10 +1413,9 @@ handle_client_request (void *cls,
1447 } 1413 }
1448 session->state = WAITING_FOR_BOBS_CONNECT; 1414 session->state = WAITING_FOR_BOBS_CONNECT;
1449 1415
1450 task = GNUNET_new(struct TaskClosure); 1416 session->service_request_task =
1451 task->my_session = session; 1417 GNUNET_SCHEDULER_add_now (&prepare_service_request,
1452 task->my_handle = GNUNET_SCHEDULER_add_now (&prepare_service_request, task); 1418 session);
1453 GNUNET_CONTAINER_DLL_insert (tasklist_head, tasklist_tail, task);
1454 1419
1455 GNUNET_SERVER_receive_done (client, GNUNET_YES); 1420 GNUNET_SERVER_receive_done (client, GNUNET_YES);
1456 } 1421 }
@@ -1481,10 +1446,9 @@ handle_client_request (void *cls,
1481 { 1446 {
1482 GNUNET_CONTAINER_DLL_remove (from_client_head, from_client_tail, session); 1447 GNUNET_CONTAINER_DLL_remove (from_client_head, from_client_tail, session);
1483 1448
1484 task = GNUNET_new(struct TaskClosure); 1449 session->client_notification_task =
1485 task->my_session = session; 1450 GNUNET_SCHEDULER_add_now (&prepare_client_end_notification,
1486 task->my_handle = GNUNET_SCHEDULER_add_now (&prepare_client_end_notification, task); 1451 session);
1487 GNUNET_CONTAINER_DLL_insert (tasklist_head, tasklist_tail, task);
1488 } 1452 }
1489 } 1453 }
1490 else 1454 else
@@ -1539,7 +1503,6 @@ tunnel_destruction_handler (void *cls,
1539 struct ServiceSession * session = tunnel_ctx; 1503 struct ServiceSession * session = tunnel_ctx;
1540 struct ServiceSession * client_session; 1504 struct ServiceSession * client_session;
1541 struct ServiceSession * curr; 1505 struct ServiceSession * curr;
1542 struct TaskClosure * task;
1543 1506
1544 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1507 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1545 _("Peer disconnected, terminating session %s with peer (%s)\n"), 1508 _("Peer disconnected, terminating session %s with peer (%s)\n"),
@@ -1558,17 +1521,16 @@ tunnel_destruction_handler (void *cls,
1558 } 1521 }
1559 session->tunnel = NULL; 1522 session->tunnel = NULL;
1560 // if this happened before we received the answer, we must terminate the session 1523 // if this happened before we received the answer, we must terminate the session
1561 task = GNUNET_new(struct TaskClosure); 1524 session->client_notification_task =
1562 task->my_session = session; 1525 GNUNET_SCHEDULER_add_now (&prepare_client_end_notification,
1563 task->my_handle = GNUNET_SCHEDULER_add_now (&prepare_client_end_notification, 1526 session);
1564 task);
1565 GNUNET_CONTAINER_DLL_insert (tasklist_head, tasklist_tail, task);
1566 } 1527 }
1567 } 1528 }
1568 else { //(BOB == session->role) 1529 else { //(BOB == session->role) service session
1569 1530
1570 // remove the session, unless it has already been dequeued, but somehow still active 1531 // remove the session, unless it has already been dequeued, but somehow still active
1571 // this could bug without the IF in case the queue is empty and the service session was the only one know to the service 1532 // this could bug without the IF in case the queue is empty and the service session was the only one know to the service
1533 // scenario: disconnect before alice can send her message to bob.
1572 for (curr = from_service_head; NULL != curr; curr = curr->next) 1534 for (curr = from_service_head; NULL != curr; curr = curr->next)
1573 if (curr == session) 1535 if (curr == session)
1574 { 1536 {
@@ -1590,11 +1552,9 @@ tunnel_destruction_handler (void *cls,
1590 // remove the session, we just found it in the queue, so it must be there 1552 // remove the session, we just found it in the queue, so it must be there
1591 GNUNET_CONTAINER_DLL_remove (from_client_head, from_client_tail, client_session); 1553 GNUNET_CONTAINER_DLL_remove (from_client_head, from_client_tail, client_session);
1592 1554
1593 task = GNUNET_new(struct TaskClosure); 1555 client_session->client_notification_task =
1594 task->my_session = client_session; 1556 GNUNET_SCHEDULER_add_now (&prepare_client_end_notification,
1595 task->my_handle = GNUNET_SCHEDULER_add_now (&prepare_client_end_notification, 1557 client_session);
1596 task);
1597 GNUNET_CONTAINER_DLL_insert (tasklist_head, tasklist_tail, task);
1598 } 1558 }
1599 } 1559 }
1600} 1560}
@@ -1701,8 +1661,7 @@ static void
1701prepare_client_response (void *cls, 1661prepare_client_response (void *cls,
1702 const struct GNUNET_SCHEDULER_TaskContext *tc) 1662 const struct GNUNET_SCHEDULER_TaskContext *tc)
1703{ 1663{
1704 struct TaskClosure * task = cls; 1664 struct ServiceSession * session = cls;
1705 struct ServiceSession * session = task->my_session;
1706 struct GNUNET_SCALARPRODUCT_client_response * msg; 1665 struct GNUNET_SCALARPRODUCT_client_response * msg;
1707 unsigned char * product_exported = NULL; 1666 unsigned char * product_exported = NULL;
1708 size_t product_length = 0; 1667 size_t product_length = 0;
@@ -1712,8 +1671,7 @@ prepare_client_response (void *cls,
1712 gcry_error_t rc; 1671 gcry_error_t rc;
1713 int sign; 1672 int sign;
1714 1673
1715 GNUNET_CONTAINER_DLL_remove (tasklist_head, tasklist_tail, task); 1674 session->client_notification_task = GNUNET_SCHEDULER_NO_TASK;
1716 GNUNET_free(task);
1717 1675
1718 if (session->product) 1676 if (session->product)
1719 { 1677 {
@@ -1766,7 +1724,7 @@ prepare_client_response (void *cls,
1766 msg_obj->transmit_handle = NULL; // don't reset the transmit handle 1724 msg_obj->transmit_handle = NULL; // don't reset the transmit handle
1767 1725
1768 //transmit this message to our client 1726 //transmit this message to our client
1769 session->client_transmit_handle = // FIXME: use after free possibility during shutdown 1727 session->client_transmit_handle =
1770 GNUNET_SERVER_notify_transmit_ready (session->client, 1728 GNUNET_SERVER_notify_transmit_ready (session->client,
1771 msg_length, 1729 msg_length,
1772 GNUNET_TIME_UNIT_FOREVER_REL, 1730 GNUNET_TIME_UNIT_FOREVER_REL,
@@ -1788,7 +1746,6 @@ prepare_client_response (void *cls,
1788 _ ("Sent result to client (%p), this session (%s) has ended!\n"), 1746 _ ("Sent result to client (%p), this session (%s) has ended!\n"),
1789 session->client, 1747 session->client,
1790 GNUNET_h2s (&session->key)); 1748 GNUNET_h2s (&session->key));
1791 free_session (session);
1792} 1749}
1793 1750
1794 1751
@@ -1968,13 +1925,11 @@ except:
1968 // and notify our client-session that we could not complete the session 1925 // and notify our client-session that we could not complete the session
1969 if (responder_session) 1926 if (responder_session)
1970 { 1927 {
1971 struct TaskClosure * task = GNUNET_new(struct TaskClosure);
1972 // we just found the responder session in this queue 1928 // we just found the responder session in this queue
1973 GNUNET_CONTAINER_DLL_remove (from_client_head, from_client_tail, responder_session); 1929 GNUNET_CONTAINER_DLL_remove (from_client_head, from_client_tail, responder_session);
1974 task->my_session = responder_session; 1930 responder_session->client_notification_task =
1975 task->my_handle = GNUNET_SCHEDULER_add_now (&prepare_client_end_notification, 1931 GNUNET_SCHEDULER_add_now (&prepare_client_end_notification,
1976 task); 1932 responder_session);
1977 GNUNET_CONTAINER_DLL_insert (tasklist_head, tasklist_tail, task);
1978 } 1933 }
1979 return GNUNET_SYSERR; 1934 return GNUNET_SYSERR;
1980} 1935}
@@ -2000,7 +1955,6 @@ handle_service_response (void *cls,
2000{ 1955{
2001 struct ServiceSession * session; 1956 struct ServiceSession * session;
2002 const struct GNUNET_SCALARPRODUCT_service_response * msg = (const struct GNUNET_SCALARPRODUCT_service_response *) message; 1957 const struct GNUNET_SCALARPRODUCT_service_response * msg = (const struct GNUNET_SCALARPRODUCT_service_response *) message;
2003 struct TaskClosure * task;
2004 unsigned char * current; 1958 unsigned char * current;
2005 uint16_t count; 1959 uint16_t count;
2006 gcry_mpi_t s = NULL; 1960 gcry_mpi_t s = NULL;
@@ -2109,15 +2063,13 @@ invalid_msg:
2109 GNUNET_CONTAINER_DLL_remove (from_client_head, from_client_tail, session); 2063 GNUNET_CONTAINER_DLL_remove (from_client_head, from_client_tail, session);
2110 // send message with product to client 2064 // send message with product to client
2111 2065
2112 task = GNUNET_new (struct TaskClosure); 2066 session->client_notification_task =
2113 task->my_session = session; 2067 GNUNET_SCHEDULER_add_now (&prepare_client_response,
2114 task->my_handle = GNUNET_SCHEDULER_add_now (&prepare_client_response, task); 2068 session);
2115 GNUNET_CONTAINER_DLL_insert (tasklist_head, tasklist_tail, task);
2116 // just close the connection. 2069 // just close the connection.
2117 return GNUNET_SYSERR; 2070 return GNUNET_SYSERR;
2118} 2071}
2119 2072
2120
2121/** 2073/**
2122 * Task run during shutdown. 2074 * Task run during shutdown.
2123 * 2075 *
@@ -2129,18 +2081,29 @@ shutdown_task (void *cls,
2129 const struct GNUNET_SCHEDULER_TaskContext *tc) 2081 const struct GNUNET_SCHEDULER_TaskContext *tc)
2130{ 2082{
2131 struct ServiceSession * session; 2083 struct ServiceSession * session;
2132 struct TaskClosure * task;
2133 GNUNET_log (GNUNET_ERROR_TYPE_INFO, _ ("Shutting down, initiating cleanup.\n")); 2084 GNUNET_log (GNUNET_ERROR_TYPE_INFO, _ ("Shutting down, initiating cleanup.\n"));
2134 2085
2135 do_shutdown = GNUNET_YES; 2086 do_shutdown = GNUNET_YES;
2136 for (task = tasklist_head; NULL != task; task = task->next) 2087
2137 GNUNET_SCHEDULER_cancel(task->my_handle);
2138
2139 // terminate all owned open tunnels. 2088 // terminate all owned open tunnels.
2140 for (session = from_client_head; NULL != session; session = session->next) 2089 for (session = from_client_head; NULL != session; session = session->next)
2141 if (FINALIZED != session->state) 2090 {
2142 GNUNET_MESH_tunnel_destroy (session->tunnel); 2091 if (FINALIZED != session->state)
2143 if (my_mesh) 2092 GNUNET_MESH_tunnel_destroy (session->tunnel);
2093 if (GNUNET_SCHEDULER_NO_TASK != session->client_notification_task)
2094 {
2095 GNUNET_SCHEDULER_cancel (session->client_notification_task);
2096 session->client_notification_task = GNUNET_SCHEDULER_NO_TASK;
2097 }
2098 if (GNUNET_SCHEDULER_NO_TASK != session->service_request_task)
2099 {
2100 GNUNET_SCHEDULER_cancel (session->service_request_task);
2101 session->service_request_task = GNUNET_SCHEDULER_NO_TASK;
2102 }
2103 }
2104 for (session = from_service_head; NULL != session; session = session->next)
2105
2106 if (my_mesh)
2144 { 2107 {
2145 GNUNET_MESH_disconnect (my_mesh); 2108 GNUNET_MESH_disconnect (my_mesh);
2146 my_mesh = NULL; 2109 my_mesh = NULL;