source: filezilla/trunk/fuentes/src/putty/callback.c @ 130

Last change on this file since 130 was 130, checked in by jrpelegrina, 4 years ago

First release to xenial

File size: 1.7 KB
Line 
1/*
2 * Facility for queueing callback functions to be run from the
3 * top-level event loop after the current top-level activity finishes.
4 */
5
6#include <stddef.h>
7
8#include "putty.h"
9
10struct callback {
11    struct callback *next;
12
13    toplevel_callback_fn_t fn;
14    void *ctx;
15};
16
17struct callback *cbhead = NULL, *cbtail = NULL;
18
19toplevel_callback_notify_fn_t notify_frontend = NULL;
20void *frontend = NULL;
21
22void request_callback_notifications(toplevel_callback_notify_fn_t fn,
23                                    void *fr)
24{
25    notify_frontend = fn;
26    frontend = fr;
27}
28
29void queue_toplevel_callback(toplevel_callback_fn_t fn, void *ctx)
30{
31    struct callback *cb;
32
33    cb = snew(struct callback);
34    cb->fn = fn;
35    cb->ctx = ctx;
36
37    /* If the front end has requested notification of pending
38     * callbacks, and we didn't already have one queued, let it know
39     * we do have one now. */
40    if (notify_frontend && !cbhead)
41        notify_frontend(frontend);
42
43    if (cbtail)
44        cbtail->next = cb;
45    else
46        cbhead = cb;
47    cbtail = cb;
48    cb->next = NULL;
49}
50
51void run_toplevel_callbacks(void)
52{
53    if (cbhead) {
54        struct callback *cb = cbhead;
55        /*
56         * Careful ordering here. We call the function _before_
57         * advancing cbhead (though, of course, we must free cb
58         * _after_ advancing it). This means that if the very last
59         * callback schedules another callback, cbhead does not become
60         * NULL at any point, and so the frontend notification
61         * function won't be needlessly pestered.
62         */
63        cb->fn(cb->ctx);
64        cbhead = cb->next;
65        sfree(cb);
66        if (!cbhead)
67            cbtail = NULL;
68    }
69}
70
71int toplevel_callback_pending(void)
72{
73    return cbhead != NULL;
74}
Note: See TracBrowser for help on using the repository browser.