aboutsummaryrefslogtreecommitdiff
path: root/src/include/gnunet_scheduler_lib.h
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2017-03-27 11:44:46 +0200
committerChristian Grothoff <christian@grothoff.org>2017-03-28 02:27:25 +0200
commitd486f5da0f495d817a19efd077501c25e4eef6fa (patch)
treebb785996088c46ed38012b23698d6354f8da7cfe /src/include/gnunet_scheduler_lib.h
parent802f89d2979d3a92228543d42cee6bb8e3e786d1 (diff)
downloadgnunet-d486f5da0f495d817a19efd077501c25e4eef6fa.tar.gz
gnunet-d486f5da0f495d817a19efd077501c25e4eef6fa.zip
initial ideas for improving the scheduler API (far from finished)
Diffstat (limited to 'src/include/gnunet_scheduler_lib.h')
-rw-r--r--src/include/gnunet_scheduler_lib.h246
1 files changed, 238 insertions, 8 deletions
diff --git a/src/include/gnunet_scheduler_lib.h b/src/include/gnunet_scheduler_lib.h
index 2be1858ce..a7385e31c 100644
--- a/src/include/gnunet_scheduler_lib.h
+++ b/src/include/gnunet_scheduler_lib.h
@@ -97,6 +97,84 @@ enum GNUNET_SCHEDULER_Reason
97 97
98 98
99/** 99/**
100 * Possible events on FDs, used as a bitmask.
101 * Modelled after GPollFD.
102 */
103enum GNUNET_SCHEDULER_EventType
104{
105
106 /**
107 * No event (useful for timeout).
108 */
109 GNUNET_SCHEDULER_ET_NONE = 0,
110
111 /**
112 * Data available for reading.
113 */
114 GNUNET_SCHEDULER_ET_IN = 1,
115
116 /**
117 * Buffer available for writing.
118 */
119 GNUNET_SCHEDULER_ET_OUT = 2,
120
121 /**
122 *
123 */
124 GNUNET_SCHEDULER_ET_HUP = 4,
125
126 /**
127 *
128 */
129 GNUNET_SCHEDULER_ET_ERR = 8,
130
131 /**
132 *
133 */
134 GNUNET_SCHEDULER_ET_PRI = 16,
135
136 /**
137 *
138 */
139 GNUNET_SCHEDULER_ET_NVAL = 32
140
141};
142
143
144/**
145 * Information about an event relating to a file descriptor/socket.
146 */
147struct GNUNET_SCHEDULER_FdInfo
148{
149
150 /**
151 * GNUnet network socket the event is about, matches @a sock,
152 * NULL if this is about a file handle or if no network
153 * handle was given to the scheduler originally.
154 */
155 struct GNUNET_NETWORK_Handle *fd;
156
157 /**
158 * GNUnet file handle the event is about, matches @a sock,
159 * NULL if this is about a network socket or if no network
160 * handle was given to the scheduler originally.
161 */
162 struct GNUNET_DISK_FileHandle *fh;
163
164 /**
165 * Type of the event that was generated related to @e sock.
166 */
167 enum GNUNET_SCHEDULER_EventType et;
168
169 /**
170 * Underlying OS handle the event was about.
171 */
172 int sock;
173
174};
175
176
177/**
100 * Context information passed to each scheduler task. 178 * Context information passed to each scheduler task.
101 */ 179 */
102struct GNUNET_SCHEDULER_TaskContext 180struct GNUNET_SCHEDULER_TaskContext
@@ -107,16 +185,29 @@ struct GNUNET_SCHEDULER_TaskContext
107 enum GNUNET_SCHEDULER_Reason reason; 185 enum GNUNET_SCHEDULER_Reason reason;
108 186
109 /** 187 /**
110 * Set of file descriptors ready for reading; 188 * Length of the following array.
111 * note that additional bits may be set 189 */
112 * that were not in the original request 190 unsigned int fds_len;
191
192 /**
193 * Array of length @e fds_len with information about ready FDs.
194 * Note that we use the same format regardless of the internal
195 * event loop that was used. The given array should only contain
196 * information about file descriptors relevant to the current task.
197 */
198 const struct GNUNET_SCHEDULER_FdInfo *fds;
199
200 /**
201 * Set of file descriptors ready for reading; note that additional
202 * bits may be set that were not in the original request.
203 * @deprecated
113 */ 204 */
114 const struct GNUNET_NETWORK_FDSet *read_ready; 205 const struct GNUNET_NETWORK_FDSet *read_ready;
115 206
116 /** 207 /**
117 * Set of file descriptors ready for writing; 208 * Set of file descriptors ready for writing; note that additional
118 * note that additional bits may be set 209 * bits may be set that were not in the original request.
119 * that were not in the original request. 210 * @deprecated
120 */ 211 */
121 const struct GNUNET_NETWORK_FDSet *write_ready; 212 const struct GNUNET_NETWORK_FDSet *write_ready;
122 213
@@ -124,16 +215,155 @@ struct GNUNET_SCHEDULER_TaskContext
124 215
125 216
126/** 217/**
218 * Function used by event-loop implementations to signal the scheduler
219 * that a particular @a task is ready due to an event of type @a et.
220 *
221 * This function will then queue the task to notify the application
222 * that the task is ready (with the respective priority).
223 *
224 * @param task the task that is ready
225 * @param et information about why the task is ready
226 */
227void
228GNUNET_SCHEDULER_task_ready (struct GNUNET_SCHEDULER_Task *task,
229 enum GNUNET_SCHEDULER_EventType et);
230
231
232/**
233 * Handle to the scheduler's state to be used by the driver.
234 */
235struct GNUNET_SCHEDULER_Handle;
236
237
238/**
239 * Function called by the driver to tell the scheduler to run some of
240 * the tasks that are ready. This function may return even though
241 * there are tasks left to run just to give other tasks a chance as
242 * well. If we return #GNUNET_YES, the driver should call this
243 * function again as soon as possible, while if we return #GNUNET_NO
244 * it must block until the operating system has more work as the
245 * scheduler has no more work to do right now.
246 *
247 * @param sh scheduler handle that was given to the `loop`
248 * @return #GNUNET_OK if there are more tasks that are ready,
249 * and thus we would like to run more (yield to avoid
250 * blocking other activities for too long)
251 * #GNUNET_NO if we are done running tasks (yield to block)
252 * #GNUNET_SYSERR on error
253 */
254int
255GNUNET_SCHEDULER_run_from_driver (struct GNUNET_SCHEDULER_Handle *sh);
256
257
258/**
259 * API a driver has to implement for
260 * #GNUNET_SCHEDULER_run_with_driver().
261 */
262struct GNUNET_SCHEDULER_Driver
263{
264
265 /**
266 * Closure to pass to the functions in this struct.
267 */
268 void *cls;
269
270 /**
271 * Add a @a task to be run if the conditions given
272 * in @a fdi are satisfied.
273 *
274 * @param cls closure
275 * @param task task to add
276 * @param fdi conditions to watch for
277 * @return #GNUNET_OK on success, #GNUNET_SYSERR on failure
278 * (i.e. @a fdi too high or invalid)
279 */
280 int
281 (*add)(void *cls,
282 struct GNUNET_SCHEDULER_Task *task,
283 struct GNUNET_SCHEDULER_FdInfo *fdi);
284
285 /**
286 * Delete a @a task from the set of tasks to be run.
287 *
288 * @param cls closure
289 * @param task task to delete
290 * @param fdi conditions to watch for (must match @e add call)
291 * @return #GNUNET_OK on success, #GNUNET_SYSERR on failure
292 * (i.e. @a task or @a fdi do not match prior @e add call)
293 */
294 int
295 (*del)(void *cls,
296 struct GNUNET_SCHEDULER_Task *task,
297 const struct GNUNET_SCHEDULER_FdInfo *fdi);
298
299 /**
300 * Set time at which we definitively want to get a wakeup call.
301 *
302 * @param cls closure
303 * @param dt time when we want to wake up next
304 */
305 void
306 (*set_wakeup)(void *cls,
307 struct GNUNET_TIME_Absolute dt);
308
309 /**
310 * Event loop's "main" function, to be called from
311 * #GNUNET_SCHEDULER_run_with_driver() to actually
312 * launch the loop.
313 *
314 * @param cls closure
315 * @param sh scheduler handle to pass to
316 * #GNUNET_SCHEDULER_run_from_driver()
317 * @return #GNUNET_OK on success, #GNUNET_SYSERR on failure
318 */
319 int
320 (*loop)(void *cls,
321 struct GNUNET_SCHEDULER_Handle *sh);
322
323};
324
325
326/**
127 * Signature of the main function of a task. 327 * Signature of the main function of a task.
128 * 328 *
129 * @param cls closure 329 * @param cls closure
130 * @param tc context information (why was this task triggered now)
131 */ 330 */
132typedef void 331typedef void
133(*GNUNET_SCHEDULER_TaskCallback) (void *cls); 332(*GNUNET_SCHEDULER_TaskCallback) (void *cls);
134 333
135 334
136/** 335/**
336 * Initialize and run scheduler. This function will return when all
337 * tasks have completed. On systems with signals, receiving a SIGTERM
338 * (and other similar signals) will cause #GNUNET_SCHEDULER_shutdown
339 * to be run after the active task is complete. As a result, SIGTERM
340 * causes all shutdown tasks to be scheduled with reason
341 * #GNUNET_SCHEDULER_REASON_SHUTDOWN. (However, tasks added
342 * afterwards will execute normally!). Note that any particular
343 * signal will only shut down one scheduler; applications should
344 * always only create a single scheduler.
345 *
346 * @param driver drive to use for the event loop
347 * @param task task to run first (and immediately)
348 * @param task_cls closure of @a task
349 * @return #GNUNET_OK on success, #GNUNET_SYSERR on failure
350 */
351int
352GNUNET_SCHEDULER_run_with_driver (const struct GNUNET_SCHEDULER_Driver *driver,
353 GNUNET_SCHEDULER_TaskCallback task,
354 void *task_cls);
355
356
357/**
358 * Obtain the driver for using select() as the event loop.
359 *
360 * @return NULL on error
361 */
362const struct GNUNET_SCHEDULER_Driver *
363GNUNET_SCHEDULER_driver_select (void);
364
365
366/**
137 * Signature of the select function used by the scheduler. 367 * Signature of the select function used by the scheduler.
138 * #GNUNET_NETWORK_socket_select matches it. 368 * #GNUNET_NETWORK_socket_select matches it.
139 * 369 *
@@ -571,7 +801,7 @@ GNUNET_SCHEDULER_add_select (enum GNUNET_SCHEDULER_Priority prio,
571 * Sets the select function to use in the scheduler (scheduler_select). 801 * Sets the select function to use in the scheduler (scheduler_select).
572 * 802 *
573 * @param new_select new select function to use (NULL to reset to default) 803 * @param new_select new select function to use (NULL to reset to default)
574 * @param new_select_cls closure for 'new_select' 804 * @param new_select_cls closure for @a new_select
575 */ 805 */
576void 806void
577GNUNET_SCHEDULER_set_select (GNUNET_SCHEDULER_select new_select, 807GNUNET_SCHEDULER_set_select (GNUNET_SCHEDULER_select new_select,