123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475 |
- /*
- * 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;
- }
|