diff options
author | marha <marha@users.sourceforge.net> | 2014-04-14 23:54:18 +0200 |
---|---|---|
committer | marha <marha@users.sourceforge.net> | 2014-04-14 23:54:18 +0200 |
commit | 64e01951590b2856a10dd0cadd14de2b855daad0 (patch) | |
tree | 8bc7d6ffdad366957a052007f93845b18da868d3 /tools/plink/callback.c | |
parent | fe6059d8026ecc19206f0779d6dd4ee37f30cbd6 (diff) | |
download | vcxsrv-64e01951590b2856a10dd0cadd14de2b855daad0.tar.gz vcxsrv-64e01951590b2856a10dd0cadd14de2b855daad0.tar.bz2 vcxsrv-64e01951590b2856a10dd0cadd14de2b855daad0.zip |
Added plink callback.c sshshare.c winsecur.c
Diffstat (limited to 'tools/plink/callback.c')
-rw-r--r-- | tools/plink/callback.c | 74 |
1 files changed, 74 insertions, 0 deletions
diff --git a/tools/plink/callback.c b/tools/plink/callback.c new file mode 100644 index 000000000..c70dc53fb --- /dev/null +++ b/tools/plink/callback.c @@ -0,0 +1,74 @@ +/* + * Facility for queueing callback functions to be run from the + * top-level event loop after the current top-level activity finishes. + */ + +#include <stddef.h> + +#include "putty.h" + +struct callback { + struct callback *next; + + toplevel_callback_fn_t fn; + void *ctx; +}; + +struct callback *cbhead = NULL, *cbtail = NULL; + +toplevel_callback_notify_fn_t notify_frontend = NULL; +void *frontend = NULL; + +void request_callback_notifications(toplevel_callback_notify_fn_t fn, + void *fr) +{ + notify_frontend = fn; + frontend = fr; +} + +void queue_toplevel_callback(toplevel_callback_fn_t fn, void *ctx) +{ + struct callback *cb; + + cb = snew(struct callback); + cb->fn = fn; + cb->ctx = ctx; + + /* If the front end has requested notification of pending + * callbacks, and we didn't already have one queued, let it know + * we do have one now. */ + if (notify_frontend && !cbhead) + notify_frontend(frontend); + + if (cbtail) + cbtail->next = cb; + else + cbhead = cb; + cbtail = cb; + cb->next = NULL; +} + +void run_toplevel_callbacks(void) +{ + if (cbhead) { + struct callback *cb = cbhead; + /* + * Careful ordering here. We call the function _before_ + * advancing cbhead (though, of course, we must free cb + * _after_ advancing it). This means that if the very last + * callback schedules another callback, cbhead does not become + * NULL at any point, and so the frontend notification + * function won't be needlessly pestered. + */ + cb->fn(cb->ctx); + cbhead = cb->next; + sfree(cb); + if (!cbhead) + cbtail = NULL; + } +} + +int toplevel_callback_pending(void) +{ + return cbhead != NULL; +} |