diff options
author | Christian Fuchs <christian.fuchs@cfuchs.net> | 2013-09-05 15:45:42 +0000 |
---|---|---|
committer | Christian Fuchs <christian.fuchs@cfuchs.net> | 2013-09-05 15:45:42 +0000 |
commit | 9a1ff3ca18fa008ca7f707a09af792d97fcec489 (patch) | |
tree | c26939045ad4b9bff576f82562adadefcce4e7a6 /src/scalarproduct | |
parent | f0e8d8a426ab418be6aa37411e94c716e461bc75 (diff) | |
download | gnunet-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.c | 225 |
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 | */ | ||
185 | struct 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 | */ |
293 | static int do_shutdown; | 271 | static int do_shutdown; |
294 | 272 | ||
295 | /** | ||
296 | * DLL for all out active, queued tasks. Purged upon disconnect | ||
297 | */ | ||
298 | static struct TaskClosure * tasklist_head; | ||
299 | /** | ||
300 | * DLL for all out active, queued tasks. Purged upon disconnect | ||
301 | */ | ||
302 | static 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 | |||
733 | handle_client_disconnect (void *cls, | 690 | handle_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 | |||
768 | prepare_client_end_notification (void * cls, | 740 | prepare_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 | |||
1186 | prepare_service_request (void *cls, | 1151 | prepare_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 | |||
1701 | prepare_client_response (void *cls, | 1661 | prepare_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; |