aboutsummaryrefslogtreecommitdiff
path: root/src/curl
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2016-05-02 06:11:57 +0000
committerChristian Grothoff <christian@grothoff.org>2016-05-02 06:11:57 +0000
commitbc1676b599937cd37d5fd625362ceea6f78fa42a (patch)
treef138a1e0fcd2b23a7711d13d7ef0499292210729 /src/curl
parent450bdaeaf612aa7717c23390239804bb28b7870f (diff)
downloadgnunet-bc1676b599937cd37d5fd625362ceea6f78fa42a.tar.gz
gnunet-bc1676b599937cd37d5fd625362ceea6f78fa42a.zip
add implementation of scheduler integration of curl context
Diffstat (limited to 'src/curl')
-rw-r--r--src/curl/Makefile.am3
-rw-r--r--src/curl/curl_reschedule.c149
2 files changed, 151 insertions, 1 deletions
diff --git a/src/curl/Makefile.am b/src/curl/Makefile.am
index 9867ba634..c716abe52 100644
--- a/src/curl/Makefile.am
+++ b/src/curl/Makefile.am
@@ -13,7 +13,8 @@ libgnunetcurl_la_LDFLAGS = \
13 -version-info 0:0:0 \ 13 -version-info 0:0:0 \
14 -no-undefined 14 -no-undefined
15libgnunetcurl_la_SOURCES = \ 15libgnunetcurl_la_SOURCES = \
16 curl.c 16 curl.c \
17 curl_reschedule.c
17libgnunetcurl_la_LIBADD = \ 18libgnunetcurl_la_LIBADD = \
18 $(top_builddir)/src/util/libgnunetutil.la \ 19 $(top_builddir)/src/util/libgnunetutil.la \
19 -ljansson \ 20 -ljansson \
diff --git a/src/curl/curl_reschedule.c b/src/curl/curl_reschedule.c
new file mode 100644
index 000000000..3e6c887f3
--- /dev/null
+++ b/src/curl/curl_reschedule.c
@@ -0,0 +1,149 @@
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 under the
6 terms of the GNU General Public License as published by the Free Software
7 Foundation; either version 3, or (at your option) any later version.
8
9 GNUnet is distributed in the hope that it will be useful, but WITHOUT ANY
10 WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
11 A PARTICULAR PURPOSE. See the GNU General Public License for more details.
12
13 You should have received a copy of the GNU General Public License along with
14 GNUnet; see the file COPYING. If not, If not, see
15 <http://www.gnu.org/licenses/>
16*/
17/**
18 * @file curl/curl_reschedule.c
19 * @brief API for event loop integration with GNUnet SCHEDULER.
20 * @author Christian Grothoff
21 */
22#include "platform.h"
23#include "gnunet_curl_lib.h"
24#include "gnunet_util_lib.h"
25
26
27/**
28 * Closure for #GNUNET_CURL_gnunet_scheduler_reschedule().
29 */
30struct GNUNET_CURL_RescheduleContext
31{
32 /**
33 * Just the task.
34 */
35 struct GNUNET_SCHEDULER_Task *task;
36
37 /**
38 * Context we manage.
39 */
40 struct GNUNET_CURL_Context *ctx;
41};
42
43
44/**
45 * Initialize reschedule context.
46 *
47 * @param ctx context to manage
48 * @return closure for #GNUNET_CURL_gnunet_scheduler_reschedule().
49 */
50struct GNUNET_CURL_RescheduleContext *
51GNUNET_CURL_gnunet_rc_create (struct GNUNET_CURL_Context *ctx)
52{
53 struct GNUNET_CURL_RescheduleContext *rc;
54
55 rc = GNUNET_new (struct GNUNET_CURL_RescheduleContext);
56 rc->ctx = ctx;
57 return rc;
58}
59
60
61/**
62 * Destroy reschedule context.
63 *
64 * @param rc context to destroy
65 */
66void
67GNUNET_CURL_gnunet_rc_destroy (struct GNUNET_CURL_RescheduleContext *rc)
68{
69 if (NULL != rc->task)
70 GNUNET_SCHEDULER_cancel (rc->task);
71 GNUNET_free (rc);
72}
73
74
75/**
76 * Task that runs the context's event loop with the GNUnet scheduler.
77 *
78 * @param cls the `struct GNUNET_CURL_RescheduleContext`
79 */
80static void
81context_task (void *cls)
82{
83 struct GNUNET_CURL_RescheduleContext *rc = cls;
84 long timeout;
85 int max_fd;
86 fd_set read_fd_set;
87 fd_set write_fd_set;
88 fd_set except_fd_set;
89 struct GNUNET_NETWORK_FDSet *rs;
90 struct GNUNET_NETWORK_FDSet *ws;
91 struct GNUNET_TIME_Relative delay;
92
93 rc->task = NULL;
94 GNUNET_CURL_perform (rc->ctx);
95 max_fd = -1;
96 timeout = -1;
97 FD_ZERO (&read_fd_set);
98 FD_ZERO (&write_fd_set);
99 FD_ZERO (&except_fd_set);
100 GNUNET_CURL_get_select_info (rc->ctx,
101 &read_fd_set,
102 &write_fd_set,
103 &except_fd_set,
104 &max_fd,
105 &timeout);
106 if (timeout >= 0)
107 delay = GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MILLISECONDS,
108 timeout);
109 else
110 delay = GNUNET_TIME_UNIT_FOREVER_REL;
111 rs = GNUNET_NETWORK_fdset_create ();
112 GNUNET_NETWORK_fdset_copy_native (rs,
113 &read_fd_set,
114 max_fd + 1);
115 ws = GNUNET_NETWORK_fdset_create ();
116 GNUNET_NETWORK_fdset_copy_native (ws,
117 &write_fd_set,
118 max_fd + 1);
119 rc->task = GNUNET_SCHEDULER_add_select (GNUNET_SCHEDULER_PRIORITY_DEFAULT,
120 delay,
121 rs,
122 ws,
123 &context_task,
124 rc);
125 GNUNET_NETWORK_fdset_destroy (rs);
126 GNUNET_NETWORK_fdset_destroy (ws);
127}
128
129
130/**
131 * Implementation of the #GNUNET_CURL_RescheduleCallback for GNUnet's
132 * scheduler. Will run the CURL context using GNUnet's scheduler.
133 * Note that you MUST immediately destroy the reschedule context after
134 * calling #GNUNET_CURL_fini().
135 *
136 * @param cls must point to a `struct GNUNET_CURL_RescheduleContext`
137 */
138void
139GNUNET_CURL_gnunet_scheduler_reschedule (void *cls)
140{
141 struct GNUNET_CURL_RescheduleContext *rc = cls;
142
143 if (NULL != rc->task)
144 GNUNET_SCHEDULER_cancel (rc->task);
145 rc->task = GNUNET_SCHEDULER_add_now (&context_task,
146 rc);
147}
148
149/* end of curl_reschedule.c */