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:
parent
cfc3386a15
commit
2ee07f8c71
19
callback.c
19
callback.c
@ -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
16
putty.h
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user