1
0
mirror of https://git.tartarus.org/simon/putty.git synced 2025-01-09 17:38:00 +00:00

Add a concept of 'idempotent callback'.

This is a set of convenience wrappers around the existing toplevel
callback function, which arranges to avoid scheduling a second call to
a callback function if one is already in the queue.

Just like the last few commits, this is a piece of infrastructure that
nothing is yet using. But it will.
This commit is contained in:
Simon Tatham 2018-05-18 07:22:57 +01:00
parent cfc3386a15
commit 2ee07f8c71
2 changed files with 34 additions and 1 deletions

View File

@ -26,6 +26,21 @@ void request_callback_notifications(toplevel_callback_notify_fn_t fn,
frontend = fr;
}
static void run_idempotent_callback(void *ctx)
{
struct IdempotentCallback *ic = (struct IdempotentCallback *)ctx;
ic->queued = FALSE;
ic->fn(ic->ctx);
}
void queue_idempotent_callback(struct IdempotentCallback *ic)
{
if (ic->queued)
return;
ic->queued = TRUE;
queue_toplevel_callback(run_idempotent_callback, ic);
}
void delete_callbacks_for_context(void *ctx)
{
struct callback *newhead, *newtail;
@ -34,7 +49,9 @@ void delete_callbacks_for_context(void *ctx)
while (cbhead) {
struct callback *cb = cbhead;
cbhead = cbhead->next;
if (cb->ctx == ctx) {
if (cb->ctx == ctx ||
(cb->fn == run_idempotent_callback &&
((struct IdempotentCallback *)cb->ctx)->ctx == ctx)) {
sfree(cb);
} else {
if (!newhead)

16
putty.h
View File

@ -1603,6 +1603,22 @@ void run_toplevel_callbacks(void);
int toplevel_callback_pending(void);
void delete_callbacks_for_context(void *ctx);
/*
* Another facility in callback.c deals with 'idempotent' callbacks,
* defined as those which never need to be scheduled again if they are
* already scheduled and have not yet run. (An example would be one
* which, when called, empties a queue of data completely: when data
* is added to the queue, you must ensure a run of the queue-consuming
* function has been scheduled, but if one is already pending, you
* don't need to schedule a second one.)
*/
struct IdempotentCallback {
toplevel_callback_fn_t fn;
void *ctx;
int queued;
};
void queue_idempotent_callback(struct IdempotentCallback *ic);
typedef void (*toplevel_callback_notify_fn_t)(void *frontend);
void request_callback_notifications(toplevel_callback_notify_fn_t notify,
void *frontend);