diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/curl/curl.c | 89 | ||||
-rw-r--r-- | src/include/gnunet_common.h | 64 | ||||
-rw-r--r-- | src/include/gnunet_curl_lib.h | 10 | ||||
-rw-r--r-- | src/include/gnunet_scheduler_lib.h | 20 | ||||
-rw-r--r-- | src/util/common_logging.c | 83 | ||||
-rw-r--r-- | src/util/scheduler.c | 43 |
6 files changed, 295 insertions, 14 deletions
diff --git a/src/curl/curl.c b/src/curl/curl.c index e13c1478f..871401c60 100644 --- a/src/curl/curl.c +++ b/src/curl/curl.c | |||
@@ -105,6 +105,18 @@ struct GNUNET_CURL_Job | |||
105 | * Buffer for response received from CURL. | 105 | * Buffer for response received from CURL. |
106 | */ | 106 | */ |
107 | struct GNUNET_CURL_DownloadBuffer db; | 107 | struct GNUNET_CURL_DownloadBuffer db; |
108 | |||
109 | /** | ||
110 | * Headers used for this job, the list needs to be freed | ||
111 | * after the job has finished. | ||
112 | */ | ||
113 | struct curl_slist *job_headers; | ||
114 | |||
115 | /** | ||
116 | * Header for the async scope id or NULL. | ||
117 | */ | ||
118 | char *aid_header; | ||
119 | |||
108 | }; | 120 | }; |
109 | 121 | ||
110 | 122 | ||
@@ -134,10 +146,15 @@ struct GNUNET_CURL_Context | |||
134 | struct GNUNET_CURL_Job *jobs_tail; | 146 | struct GNUNET_CURL_Job *jobs_tail; |
135 | 147 | ||
136 | /** | 148 | /** |
137 | * HTTP header "application/json", created once and used | 149 | * Headers common for all requests in the context. |
138 | * for all requests that need it. | 150 | */ |
151 | struct curl_slist *common_headers; | ||
152 | |||
153 | /** | ||
154 | * If non-NULL, the async scope ID is sent in a request | ||
155 | * header of this name. | ||
139 | */ | 156 | */ |
140 | struct curl_slist *json_header; | 157 | const char *async_scope_id_header; |
141 | 158 | ||
142 | /** | 159 | /** |
143 | * Function we need to call whenever the event loop's | 160 | * Function we need to call whenever the event loop's |
@@ -149,6 +166,7 @@ struct GNUNET_CURL_Context | |||
149 | * Closure for @e cb. | 166 | * Closure for @e cb. |
150 | */ | 167 | */ |
151 | void *cb_cls; | 168 | void *cb_cls; |
169 | |||
152 | }; | 170 | }; |
153 | 171 | ||
154 | 172 | ||
@@ -189,14 +207,24 @@ GNUNET_CURL_init (GNUNET_CURL_RescheduleCallback cb, void *cb_cls) | |||
189 | ctx->cb_cls = cb_cls; | 207 | ctx->cb_cls = cb_cls; |
190 | ctx->multi = multi; | 208 | ctx->multi = multi; |
191 | ctx->share = share; | 209 | ctx->share = share; |
192 | GNUNET_assert ( | ||
193 | NULL != (ctx->json_header = | ||
194 | curl_slist_append (NULL, "Content-Type: application/json"))); | ||
195 | return ctx; | 210 | return ctx; |
196 | } | 211 | } |
197 | 212 | ||
198 | 213 | ||
199 | /** | 214 | /** |
215 | * Enable sending the async scope ID as a header. | ||
216 | * | ||
217 | * @param ctx the context to enable this for | ||
218 | * @param header_name name of the header to send. | ||
219 | */ | ||
220 | void | ||
221 | GNUNET_CURL_enable_async_scope_header (struct GNUNET_CURL_Context *ctx, const char *header_name) | ||
222 | { | ||
223 | ctx->async_scope_id_header = header_name; | ||
224 | } | ||
225 | |||
226 | |||
227 | /** | ||
200 | * Callback used when downloading the reply to an HTTP request. | 228 | * Callback used when downloading the reply to an HTTP request. |
201 | * Just appends all of the data to the `buf` in the | 229 | * Just appends all of the data to the `buf` in the |
202 | * `struct DownloadBuffer` for further processing. The size of | 230 | * `struct DownloadBuffer` for further processing. The size of |
@@ -259,16 +287,49 @@ GNUNET_CURL_job_add (struct GNUNET_CURL_Context *ctx, | |||
259 | void *jcc_cls) | 287 | void *jcc_cls) |
260 | { | 288 | { |
261 | struct GNUNET_CURL_Job *job; | 289 | struct GNUNET_CURL_Job *job; |
290 | struct curl_slist *all_headers = NULL; | ||
291 | char *aid_header = NULL; | ||
262 | 292 | ||
263 | if (GNUNET_YES == add_json) | 293 | if (GNUNET_YES == add_json) |
264 | if (CURLE_OK != curl_easy_setopt (eh, CURLOPT_HTTPHEADER, ctx->json_header)) | 294 | { |
295 | GNUNET_assert ( | ||
296 | NULL != (all_headers = | ||
297 | curl_slist_append (NULL, "Content-Type: application/json"))); | ||
298 | } | ||
299 | |||
300 | for (struct curl_slist *curr = ctx->common_headers; | ||
301 | curr != NULL; | ||
302 | curr = curr->next) | ||
303 | { | ||
304 | GNUNET_assert ( | ||
305 | NULL != (all_headers = | ||
306 | curl_slist_append (all_headers, "Content-Type: application/json"))); | ||
307 | } | ||
308 | |||
309 | if (NULL != ctx->async_scope_id_header) | ||
310 | { | ||
311 | struct GNUNET_AsyncScopeSave scope; | ||
312 | |||
313 | GNUNET_async_scope_get (&scope); | ||
314 | if (GNUNET_YES == scope.have_scope) | ||
265 | { | 315 | { |
266 | GNUNET_break (0); | 316 | aid_header = GNUNET_STRINGS_data_to_string_alloc (&scope.scope_id, |
267 | curl_easy_cleanup (eh); | 317 | sizeof (struct GNUNET_AsyncScopeId)); |
268 | return NULL; | 318 | GNUNET_assert (NULL != curl_slist_append(all_headers, aid_header)); |
269 | } | 319 | } |
320 | } | ||
321 | |||
322 | if (CURLE_OK != curl_easy_setopt (eh, CURLOPT_HTTPHEADER, all_headers)) | ||
323 | { | ||
324 | GNUNET_break (0); | ||
325 | curl_easy_cleanup (eh); | ||
326 | return NULL; | ||
327 | } | ||
270 | 328 | ||
271 | job = GNUNET_new (struct GNUNET_CURL_Job); | 329 | job = GNUNET_new (struct GNUNET_CURL_Job); |
330 | job->job_headers = all_headers; | ||
331 | job->aid_header = aid_header; | ||
332 | |||
272 | if ((CURLE_OK != curl_easy_setopt (eh, CURLOPT_PRIVATE, job)) || | 333 | if ((CURLE_OK != curl_easy_setopt (eh, CURLOPT_PRIVATE, job)) || |
273 | (CURLE_OK != | 334 | (CURLE_OK != |
274 | curl_easy_setopt (eh, CURLOPT_WRITEFUNCTION, &download_cb)) || | 335 | curl_easy_setopt (eh, CURLOPT_WRITEFUNCTION, &download_cb)) || |
@@ -308,6 +369,8 @@ GNUNET_CURL_job_cancel (struct GNUNET_CURL_Job *job) | |||
308 | curl_multi_remove_handle (ctx->multi, job->easy_handle)); | 369 | curl_multi_remove_handle (ctx->multi, job->easy_handle)); |
309 | curl_easy_cleanup (job->easy_handle); | 370 | curl_easy_cleanup (job->easy_handle); |
310 | GNUNET_free_non_null (job->db.buf); | 371 | GNUNET_free_non_null (job->db.buf); |
372 | GNUNET_free_non_null (job->aid_header); | ||
373 | curl_slist_free_all (job->job_headers); | ||
311 | GNUNET_free (job); | 374 | GNUNET_free (job); |
312 | } | 375 | } |
313 | 376 | ||
@@ -401,8 +464,8 @@ download_get_result (struct GNUNET_CURL_DownloadBuffer *db, | |||
401 | int | 464 | int |
402 | GNUNET_CURL_append_header (struct GNUNET_CURL_Context *ctx, const char *header) | 465 | GNUNET_CURL_append_header (struct GNUNET_CURL_Context *ctx, const char *header) |
403 | { | 466 | { |
404 | ctx->json_header = curl_slist_append (ctx->json_header, header); | 467 | ctx->common_headers = curl_slist_append (ctx->common_headers, header); |
405 | if (NULL == ctx->json_header) | 468 | if (NULL == ctx->common_headers) |
406 | return GNUNET_SYSERR; | 469 | return GNUNET_SYSERR; |
407 | 470 | ||
408 | return GNUNET_OK; | 471 | return GNUNET_OK; |
@@ -599,7 +662,7 @@ GNUNET_CURL_fini (struct GNUNET_CURL_Context *ctx) | |||
599 | GNUNET_assert (NULL == ctx->jobs_head); | 662 | GNUNET_assert (NULL == ctx->jobs_head); |
600 | curl_share_cleanup (ctx->share); | 663 | curl_share_cleanup (ctx->share); |
601 | curl_multi_cleanup (ctx->multi); | 664 | curl_multi_cleanup (ctx->multi); |
602 | curl_slist_free_all (ctx->json_header); | 665 | curl_slist_free_all (ctx->common_headers); |
603 | GNUNET_free (ctx); | 666 | GNUNET_free (ctx); |
604 | } | 667 | } |
605 | 668 | ||
diff --git a/src/include/gnunet_common.h b/src/include/gnunet_common.h index 2c40aef79..1f5600381 100644 --- a/src/include/gnunet_common.h +++ b/src/include/gnunet_common.h | |||
@@ -319,8 +319,34 @@ struct GNUNET_OperationResultMessage | |||
319 | /* Followed by data. */ | 319 | /* Followed by data. */ |
320 | }; | 320 | }; |
321 | 321 | ||
322 | |||
323 | /** | ||
324 | * Identifier for an asynchronous execution context. | ||
325 | */ | ||
326 | struct GNUNET_AsyncScopeId | ||
327 | { | ||
328 | uint32_t bits[16 / sizeof (uint32_t)]; /* = 16 bytes */ | ||
329 | }; | ||
330 | |||
322 | GNUNET_NETWORK_STRUCT_END | 331 | GNUNET_NETWORK_STRUCT_END |
323 | 332 | ||
333 | |||
334 | /** | ||
335 | * Saved async scope identifier or root scope. | ||
336 | */ | ||
337 | struct GNUNET_AsyncScopeSave { | ||
338 | /** | ||
339 | * Saved scope. Unused if 'have_scope==GNUNET_NO'. | ||
340 | */ | ||
341 | struct GNUNET_AsyncScopeId scope_id; | ||
342 | |||
343 | /** | ||
344 | * GNUNET_YES unless this saved scope is the unnamed root scope. | ||
345 | */ | ||
346 | int have_scope; | ||
347 | }; | ||
348 | |||
349 | |||
324 | /** | 350 | /** |
325 | * Function called with a filename. | 351 | * Function called with a filename. |
326 | * | 352 | * |
@@ -1331,6 +1357,44 @@ struct GNUNET_MessageHeader * | |||
1331 | GNUNET_copy_message (const struct GNUNET_MessageHeader *msg); | 1357 | GNUNET_copy_message (const struct GNUNET_MessageHeader *msg); |
1332 | 1358 | ||
1333 | 1359 | ||
1360 | /** | ||
1361 | * Set the async scope for the current thread. | ||
1362 | * | ||
1363 | * @param aid the async scope identifier | ||
1364 | * @param old_scope[out] location to save the old scope | ||
1365 | */ | ||
1366 | void | ||
1367 | GNUNET_async_scope_enter (const struct GNUNET_AsyncScopeId *aid, | ||
1368 | struct GNUNET_AsyncScopeSave *old_scope); | ||
1369 | |||
1370 | |||
1371 | /** | ||
1372 | * Clear the current thread's async scope. | ||
1373 | * | ||
1374 | * @param old_scope scope to restore | ||
1375 | */ | ||
1376 | void | ||
1377 | GNUNET_async_scope_restore (struct GNUNET_AsyncScopeSave *old_scope); | ||
1378 | |||
1379 | |||
1380 | /** | ||
1381 | * Get the current async scope. | ||
1382 | * | ||
1383 | * @param[out] scope_ret pointer to where the result is stored | ||
1384 | */ | ||
1385 | void | ||
1386 | GNUNET_async_scope_get (struct GNUNET_AsyncScopeSave *scope_ret); | ||
1387 | |||
1388 | |||
1389 | /** | ||
1390 | * Generate a fresh async scope identifier. | ||
1391 | * | ||
1392 | * @param[out] aid_ret pointer to where the result is stored | ||
1393 | */ | ||
1394 | void | ||
1395 | GNUNET_async_scope_fresh (struct GNUNET_AsyncScopeId *aid_ret); | ||
1396 | |||
1397 | |||
1334 | #if __STDC_VERSION__ < 199901L | 1398 | #if __STDC_VERSION__ < 199901L |
1335 | #if __GNUC__ >= 2 | 1399 | #if __GNUC__ >= 2 |
1336 | #define __func__ __FUNCTION__ | 1400 | #define __func__ __FUNCTION__ |
diff --git a/src/include/gnunet_curl_lib.h b/src/include/gnunet_curl_lib.h index 86cb54f6b..84c8d59f8 100644 --- a/src/include/gnunet_curl_lib.h +++ b/src/include/gnunet_curl_lib.h | |||
@@ -294,6 +294,16 @@ void | |||
294 | GNUNET_CURL_gnunet_scheduler_reschedule (void *cls); | 294 | GNUNET_CURL_gnunet_scheduler_reschedule (void *cls); |
295 | 295 | ||
296 | 296 | ||
297 | /** | ||
298 | * Enable sending the async scope ID as a header. | ||
299 | * | ||
300 | * @param ctx the context to enable this for | ||
301 | * @param header_name name of the header to send. | ||
302 | */ | ||
303 | void | ||
304 | GNUNET_CURL_enable_async_scope_header (struct GNUNET_CURL_Context *ctx, const char *header_name); | ||
305 | |||
306 | |||
297 | #endif | 307 | #endif |
298 | /** @} */ /* end of group */ | 308 | /** @} */ /* end of group */ |
299 | 309 | ||
diff --git a/src/include/gnunet_scheduler_lib.h b/src/include/gnunet_scheduler_lib.h index 3f4e3c9a8..3f0350f54 100644 --- a/src/include/gnunet_scheduler_lib.h +++ b/src/include/gnunet_scheduler_lib.h | |||
@@ -214,6 +214,8 @@ struct GNUNET_SCHEDULER_TaskContext | |||
214 | }; | 214 | }; |
215 | 215 | ||
216 | 216 | ||
217 | |||
218 | |||
217 | /** | 219 | /** |
218 | * Function used by event-loop implementations to signal the scheduler | 220 | * Function used by event-loop implementations to signal the scheduler |
219 | * that a particular @a task is ready due to an event specified in the | 221 | * that a particular @a task is ready due to an event specified in the |
@@ -904,6 +906,24 @@ GNUNET_SCHEDULER_set_select (GNUNET_SCHEDULER_select new_select, | |||
904 | void *new_select_cls); | 906 | void *new_select_cls); |
905 | 907 | ||
906 | 908 | ||
909 | |||
910 | /** | ||
911 | * Change the async scope for the currently executing task and (transitively) | ||
912 | * for all tasks scheduled by the current task after calling this function. | ||
913 | * Nested tasks can begin their own nested async scope. | ||
914 | * | ||
915 | * Once the current task is finished, the async scope ID is reset to | ||
916 | * its previous value. | ||
917 | * | ||
918 | * Must only be called from a running task. | ||
919 | * | ||
920 | * @param aid the asynchronous scope id to enter | ||
921 | */ | ||
922 | void | ||
923 | GNUNET_SCHEDULER_begin_async_scope (struct GNUNET_AsyncScopeId *aid); | ||
924 | |||
925 | |||
926 | |||
907 | #if 0 /* keep Emacsens' auto-indent happy */ | 927 | #if 0 /* keep Emacsens' auto-indent happy */ |
908 | { | 928 | { |
909 | #endif | 929 | #endif |
diff --git a/src/util/common_logging.c b/src/util/common_logging.c index 77a595878..5052134f8 100644 --- a/src/util/common_logging.c +++ b/src/util/common_logging.c | |||
@@ -95,6 +95,13 @@ struct CustomLogger | |||
95 | void *logger_cls; | 95 | void *logger_cls; |
96 | }; | 96 | }; |
97 | 97 | ||
98 | |||
99 | /** | ||
100 | * Asynchronous scope of the current thread, or NULL if we have not | ||
101 | * entered an async scope yet. | ||
102 | */ | ||
103 | static __thread struct GNUNET_AsyncScopeSave current_async_scope; | ||
104 | |||
98 | /** | 105 | /** |
99 | * The last "bulk" error message that we have been logging. | 106 | * The last "bulk" error message that we have been logging. |
100 | * Note that this message maybe truncated to the first BULK_TRACK_SIZE | 107 | * Note that this message maybe truncated to the first BULK_TRACK_SIZE |
@@ -838,6 +845,28 @@ output_message (enum GNUNET_ErrorType kind, | |||
838 | "* %s", | 845 | "* %s", |
839 | msg); | 846 | msg); |
840 | } | 847 | } |
848 | else if (GNUNET_YES == current_async_scope.have_scope) | ||
849 | { | ||
850 | static GNUNET_THREAD_LOCAL char id_buf[27]; | ||
851 | char *end; | ||
852 | |||
853 | /* We're logging, so skip_log must be currently 0. */ | ||
854 | skip_log = 100; | ||
855 | end = GNUNET_STRINGS_data_to_string (¤t_async_scope.scope_id, | ||
856 | sizeof (struct GNUNET_AsyncScopeId), | ||
857 | id_buf, | ||
858 | sizeof (id_buf) - 1); | ||
859 | GNUNET_assert (NULL != end); | ||
860 | *end = '\0'; | ||
861 | skip_log = 0; | ||
862 | FPRINTF (GNUNET_stderr, | ||
863 | "%s %s(%s) %s %s", | ||
864 | datestr, | ||
865 | comp, | ||
866 | id_buf, | ||
867 | GNUNET_error_type_to_string (kind), | ||
868 | msg); | ||
869 | } | ||
841 | else | 870 | else |
842 | { | 871 | { |
843 | FPRINTF (GNUNET_stderr, | 872 | FPRINTF (GNUNET_stderr, |
@@ -1548,6 +1577,60 @@ GNUNET_log_config_invalid (enum GNUNET_ErrorType kind, | |||
1548 | 1577 | ||
1549 | 1578 | ||
1550 | /** | 1579 | /** |
1580 | * Set the async scope for the current thread. | ||
1581 | * | ||
1582 | * @param aid the async scope identifier | ||
1583 | * @param old_scope[out] location to save the old scope | ||
1584 | */ | ||
1585 | void | ||
1586 | GNUNET_async_scope_enter (const struct GNUNET_AsyncScopeId *aid, | ||
1587 | struct GNUNET_AsyncScopeSave *old_scope) | ||
1588 | { | ||
1589 | *old_scope = current_async_scope; | ||
1590 | current_async_scope.have_scope = GNUNET_YES; | ||
1591 | current_async_scope.scope_id = *aid; | ||
1592 | } | ||
1593 | |||
1594 | |||
1595 | /** | ||
1596 | * Clear the current thread's async scope. | ||
1597 | * | ||
1598 | * @param old_scope scope to restore | ||
1599 | */ | ||
1600 | void | ||
1601 | GNUNET_async_scope_restore (struct GNUNET_AsyncScopeSave *old_scope) | ||
1602 | { | ||
1603 | current_async_scope = *old_scope; | ||
1604 | } | ||
1605 | |||
1606 | |||
1607 | /** | ||
1608 | * Generate a fresh async scope identifier. | ||
1609 | * | ||
1610 | * @param[out] aid_ret pointer to where the result is stored | ||
1611 | */ | ||
1612 | void | ||
1613 | GNUNET_async_scope_fresh (struct GNUNET_AsyncScopeId *aid_ret) | ||
1614 | { | ||
1615 | GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_WEAK, | ||
1616 | aid_ret, | ||
1617 | sizeof (struct GNUNET_AsyncScopeId)); | ||
1618 | } | ||
1619 | |||
1620 | |||
1621 | /** | ||
1622 | * Get the current async scope. | ||
1623 | * | ||
1624 | * @param[out] scope_ret pointer to where the result is stored | ||
1625 | */ | ||
1626 | void | ||
1627 | GNUNET_async_scope_get (struct GNUNET_AsyncScopeSave *scope_ret) | ||
1628 | { | ||
1629 | *scope_ret = current_async_scope; | ||
1630 | } | ||
1631 | |||
1632 | |||
1633 | /** | ||
1551 | * Initializer | 1634 | * Initializer |
1552 | */ | 1635 | */ |
1553 | void __attribute__ ((constructor)) | 1636 | void __attribute__ ((constructor)) |
diff --git a/src/util/scheduler.c b/src/util/scheduler.c index 2ddbb8c60..c818e91ee 100644 --- a/src/util/scheduler.c +++ b/src/util/scheduler.c | |||
@@ -241,6 +241,11 @@ struct GNUNET_SCHEDULER_Task | |||
241 | int num_backtrace_strings; | 241 | int num_backtrace_strings; |
242 | #endif | 242 | #endif |
243 | 243 | ||
244 | /** | ||
245 | * Asynchronous scope of the task that scheduled this scope, | ||
246 | */ | ||
247 | struct GNUNET_AsyncScopeSave scope; | ||
248 | |||
244 | }; | 249 | }; |
245 | 250 | ||
246 | 251 | ||
@@ -1105,6 +1110,7 @@ GNUNET_SCHEDULER_add_at_with_priority (struct GNUNET_TIME_Absolute at, | |||
1105 | GNUNET_assert (NULL != scheduler_driver); | 1110 | GNUNET_assert (NULL != scheduler_driver); |
1106 | GNUNET_assert (NULL != task); | 1111 | GNUNET_assert (NULL != task); |
1107 | t = GNUNET_new (struct GNUNET_SCHEDULER_Task); | 1112 | t = GNUNET_new (struct GNUNET_SCHEDULER_Task); |
1113 | GNUNET_async_scope_get (&t->scope); | ||
1108 | t->callback = task; | 1114 | t->callback = task; |
1109 | t->callback_cls = task_cls; | 1115 | t->callback_cls = task_cls; |
1110 | t->read_fd = -1; | 1116 | t->read_fd = -1; |
@@ -1293,6 +1299,7 @@ GNUNET_SCHEDULER_add_shutdown (GNUNET_SCHEDULER_TaskCallback task, | |||
1293 | GNUNET_assert (NULL != scheduler_driver); | 1299 | GNUNET_assert (NULL != scheduler_driver); |
1294 | GNUNET_assert (NULL != task); | 1300 | GNUNET_assert (NULL != task); |
1295 | t = GNUNET_new (struct GNUNET_SCHEDULER_Task); | 1301 | t = GNUNET_new (struct GNUNET_SCHEDULER_Task); |
1302 | GNUNET_async_scope_get (&t->scope); | ||
1296 | t->callback = task; | 1303 | t->callback = task; |
1297 | t->callback_cls = task_cls; | 1304 | t->callback_cls = task_cls; |
1298 | t->read_fd = -1; | 1305 | t->read_fd = -1; |
@@ -1411,6 +1418,7 @@ add_without_sets (struct GNUNET_TIME_Relative delay, | |||
1411 | GNUNET_assert (NULL != scheduler_driver); | 1418 | GNUNET_assert (NULL != scheduler_driver); |
1412 | GNUNET_assert (NULL != task); | 1419 | GNUNET_assert (NULL != task); |
1413 | t = GNUNET_new (struct GNUNET_SCHEDULER_Task); | 1420 | t = GNUNET_new (struct GNUNET_SCHEDULER_Task); |
1421 | GNUNET_async_scope_get (&t->scope); | ||
1414 | init_fd_info (t, | 1422 | init_fd_info (t, |
1415 | &read_nh, | 1423 | &read_nh, |
1416 | read_nh ? 1 : 0, | 1424 | read_nh ? 1 : 0, |
@@ -1882,6 +1890,7 @@ GNUNET_SCHEDULER_add_select (enum GNUNET_SCHEDULER_Priority prio, | |||
1882 | task, | 1890 | task, |
1883 | task_cls); | 1891 | task_cls); |
1884 | t = GNUNET_new (struct GNUNET_SCHEDULER_Task); | 1892 | t = GNUNET_new (struct GNUNET_SCHEDULER_Task); |
1893 | GNUNET_async_scope_get (&t->scope); | ||
1885 | init_fd_info (t, | 1894 | init_fd_info (t, |
1886 | read_nhandles, | 1895 | read_nhandles, |
1887 | read_nhandles_len, | 1896 | read_nhandles_len, |
@@ -2114,7 +2123,15 @@ GNUNET_SCHEDULER_do_work (struct GNUNET_SCHEDULER_Handle *sh) | |||
2114 | "Running task %p\n", | 2123 | "Running task %p\n", |
2115 | pos); | 2124 | pos); |
2116 | GNUNET_assert (NULL != pos->callback); | 2125 | GNUNET_assert (NULL != pos->callback); |
2117 | pos->callback (pos->callback_cls); | 2126 | { |
2127 | struct GNUNET_AsyncScopeSave old_scope; | ||
2128 | if (pos->scope.have_scope) | ||
2129 | GNUNET_async_scope_enter (&pos->scope.scope_id, &old_scope); | ||
2130 | else | ||
2131 | GNUNET_async_scope_get (&old_scope); | ||
2132 | pos->callback (pos->callback_cls); | ||
2133 | GNUNET_async_scope_restore (&old_scope); | ||
2134 | } | ||
2118 | if (NULL != pos->fds) | 2135 | if (NULL != pos->fds) |
2119 | { | 2136 | { |
2120 | int del_result = scheduler_driver->del (scheduler_driver->cls, pos); | 2137 | int del_result = scheduler_driver->del (scheduler_driver->cls, pos); |
@@ -2513,4 +2530,28 @@ GNUNET_SCHEDULER_driver_select () | |||
2513 | } | 2530 | } |
2514 | 2531 | ||
2515 | 2532 | ||
2533 | /** | ||
2534 | * Change the async scope for the currently executing task and (transitively) | ||
2535 | * for all tasks scheduled by the current task after calling this function. | ||
2536 | * Nested tasks can begin their own nested async scope. | ||
2537 | * | ||
2538 | * Once the current task is finished, the async scope ID is reset to | ||
2539 | * its previous value. | ||
2540 | * | ||
2541 | * Must only be called from a running task. | ||
2542 | * | ||
2543 | * @param aid the asynchronous scope id to enter | ||
2544 | */ | ||
2545 | void | ||
2546 | GNUNET_SCHEDULER_begin_async_scope (struct GNUNET_AsyncScopeId *aid) | ||
2547 | { | ||
2548 | struct GNUNET_AsyncScopeSave dummy_old_scope; | ||
2549 | |||
2550 | GNUNET_assert (NULL != active_task); | ||
2551 | /* Since we're in a task, the context will be automatically | ||
2552 | restored by the scheduler. */ | ||
2553 | GNUNET_async_scope_enter (aid, &dummy_old_scope); | ||
2554 | } | ||
2555 | |||
2556 | |||
2516 | /* end of scheduler.c */ | 2557 | /* end of scheduler.c */ |