aboutsummaryrefslogtreecommitdiff
path: root/src/lib/curl/curl_reschedule.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/curl/curl_reschedule.c')
-rw-r--r--src/lib/curl/curl_reschedule.c181
1 files changed, 181 insertions, 0 deletions
diff --git a/src/lib/curl/curl_reschedule.c b/src/lib/curl/curl_reschedule.c
new file mode 100644
index 000000000..0c19bd171
--- /dev/null
+++ b/src/lib/curl/curl_reschedule.c
@@ -0,0 +1,181 @@
1/*
2 This file is part of GNUnet
3 Copyright (C) 2015, 2016 GNUnet e.V.
4
5 GNUnet is free software: you can redistribute it and/or modify it
6 under the terms of the GNU Affero General Public License as published
7 by the Free Software Foundation, either version 3 of the License,
8 or (at your option) any later version.
9
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Affero General Public License for more details.
14
15 You should have received a copy of the GNU Affero General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17
18 SPDX-License-Identifier: AGPL3.0-or-later
19 */
20/**
21 * @file curl/curl_reschedule.c
22 * @brief API for event loop integration with GNUnet SCHEDULER.
23 * @author Christian Grothoff
24 */
25#include "platform.h"
26#include <jansson.h>
27#include "gnunet_curl_lib.h"
28#include "gnunet_util_lib.h"
29
30extern void *
31GNUNET_CURL_download_get_result_ (struct GNUNET_CURL_DownloadBuffer *db,
32 CURL *eh,
33 long *response_code);
34
35/**
36 * Closure for #GNUNET_CURL_gnunet_scheduler_reschedule().
37 */
38struct GNUNET_CURL_RescheduleContext
39{
40 /**
41 * Just the task.
42 */
43 struct GNUNET_SCHEDULER_Task *task;
44
45 /**
46 * Context we manage.
47 */
48 struct GNUNET_CURL_Context *ctx;
49
50 /**
51 * Parser of the raw response.
52 */
53 GNUNET_CURL_RawParser parser;
54
55 /**
56 * Deallocate the response object.
57 */
58 GNUNET_CURL_ResponseCleaner cleaner;
59};
60
61
62struct GNUNET_CURL_RescheduleContext *
63GNUNET_CURL_gnunet_rc_create_with_parser (struct GNUNET_CURL_Context *ctx,
64 GNUNET_CURL_RawParser rp,
65 GNUNET_CURL_ResponseCleaner rc)
66{
67 struct GNUNET_CURL_RescheduleContext *rctx;
68
69 rctx = GNUNET_new (struct GNUNET_CURL_RescheduleContext);
70 rctx->ctx = ctx;
71 rctx->parser = rp;
72 rctx->cleaner = rc;
73
74 return rctx;
75}
76
77
78/**
79 * Just a wrapper to avoid casting of function pointers.
80 *
81 * @param response the (JSON) response to clean.
82 */
83static void
84clean_result (void *response)
85{
86 json_decref (response);
87}
88
89
90struct GNUNET_CURL_RescheduleContext *
91GNUNET_CURL_gnunet_rc_create (struct GNUNET_CURL_Context *ctx)
92{
93 struct GNUNET_CURL_RescheduleContext *rc;
94
95 rc = GNUNET_new (struct GNUNET_CURL_RescheduleContext);
96 rc->ctx = ctx;
97 rc->parser = &GNUNET_CURL_download_get_result_;
98 rc->cleaner = &clean_result;
99 return rc;
100}
101
102
103void
104GNUNET_CURL_gnunet_rc_destroy (struct GNUNET_CURL_RescheduleContext *rc)
105{
106 if (NULL != rc->task)
107 GNUNET_SCHEDULER_cancel (rc->task);
108 GNUNET_free (rc);
109}
110
111
112/**
113 * Task that runs the context's event loop with the GNUnet scheduler.
114 *
115 * @param cls a `struct GNUNET_CURL_RescheduleContext *`
116 */
117static void
118context_task (void *cls)
119{
120 struct GNUNET_CURL_RescheduleContext *rc = cls;
121 long timeout;
122 int max_fd;
123 fd_set read_fd_set;
124 fd_set write_fd_set;
125 fd_set except_fd_set;
126 struct GNUNET_NETWORK_FDSet *rs;
127 struct GNUNET_NETWORK_FDSet *ws;
128 struct GNUNET_TIME_Relative delay;
129
130 rc->task = NULL;
131 GNUNET_CURL_perform2 (rc->ctx, rc->parser, rc->cleaner);
132 max_fd = -1;
133 timeout = -1;
134 FD_ZERO (&read_fd_set);
135 FD_ZERO (&write_fd_set);
136 FD_ZERO (&except_fd_set);
137 GNUNET_CURL_get_select_info (rc->ctx,
138 &read_fd_set,
139 &write_fd_set,
140 &except_fd_set,
141 &max_fd,
142 &timeout);
143 if (timeout >= 0)
144 delay =
145 GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MILLISECONDS,
146 timeout);
147 else
148 delay = GNUNET_TIME_UNIT_FOREVER_REL;
149 rs = GNUNET_NETWORK_fdset_create ();
150 GNUNET_NETWORK_fdset_copy_native (rs,
151 &read_fd_set,
152 max_fd + 1);
153 ws = GNUNET_NETWORK_fdset_create ();
154 GNUNET_NETWORK_fdset_copy_native (ws,
155 &write_fd_set,
156 max_fd + 1);
157 if (NULL == rc->task)
158 rc->task = GNUNET_SCHEDULER_add_select (GNUNET_SCHEDULER_PRIORITY_DEFAULT,
159 delay,
160 rs,
161 ws,
162 &context_task,
163 rc);
164 GNUNET_NETWORK_fdset_destroy (rs);
165 GNUNET_NETWORK_fdset_destroy (ws);
166}
167
168
169void
170GNUNET_CURL_gnunet_scheduler_reschedule (void *cls)
171{
172 struct GNUNET_CURL_RescheduleContext *rc = *(void **) cls;
173
174 if (NULL != rc->task)
175 GNUNET_SCHEDULER_cancel (rc->task);
176 rc->task = GNUNET_SCHEDULER_add_now (&context_task,
177 rc);
178}
179
180
181/* end of curl_reschedule.c */