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

Put an optional IdempotentCallback in packet queues.

This means that someone putting things on a packet queue doesn't need
to separately hold a pointer to someone who needs notifying about it,
or remember to call the notification function every time they push
things on the queue. It's all taken care of automatically, without
having to put extra stuff at the call sites.

The precise semantics are that the callback will be scheduled whenever
_new_ packets appear on the queue, but not when packets are removed.
(Because the expectation is that the callback is notifying whoever is
consuming the queue.)
This commit is contained in:
Simon Tatham 2018-09-21 13:16:38 +01:00
parent a703f86731
commit 623c7b720c
2 changed files with 14 additions and 0 deletions

1
ssh.h
View File

@ -85,6 +85,7 @@ typedef struct PktOut {
typedef struct PacketQueueBase {
PacketQueueNode end;
struct IdempotentCallback *ic;
} PacketQueueBase;
typedef struct PktInQueue {

View File

@ -33,6 +33,9 @@ void pq_base_push(PacketQueueBase *pqb, PacketQueueNode *node)
node->prev = pqb->end.prev;
node->next->prev = node;
node->prev->next = node;
if (pqb->ic)
queue_idempotent_callback(pqb->ic);
}
void pq_base_push_front(PacketQueueBase *pqb, PacketQueueNode *node)
@ -42,6 +45,9 @@ void pq_base_push_front(PacketQueueBase *pqb, PacketQueueNode *node)
node->next = pqb->end.next;
node->next->prev = node;
node->prev->next = node;
if (pqb->ic)
queue_idempotent_callback(pqb->ic);
}
static PacketQueueNode pktin_freeq_head = {
@ -102,12 +108,14 @@ static PktOut *pq_out_get(PacketQueueBase *pqb, int pop)
void pq_in_init(PktInQueue *pq)
{
pq->pqb.ic = NULL;
pq->pqb.end.next = pq->pqb.end.prev = &pq->pqb.end;
pq->get = pq_in_get;
}
void pq_out_init(PktOutQueue *pq)
{
pq->pqb.ic = NULL;
pq->pqb.end.next = pq->pqb.end.prev = &pq->pqb.end;
pq->get = pq_out_get;
}
@ -115,6 +123,7 @@ void pq_out_init(PktOutQueue *pq)
void pq_in_clear(PktInQueue *pq)
{
PktIn *pkt;
pq->pqb.ic = NULL;
while ((pkt = pq_pop(pq)) != NULL) {
/* No need to actually free these packets: pq_pop on a
* PktInQueue will automatically move them to the free
@ -125,6 +134,7 @@ void pq_in_clear(PktInQueue *pq)
void pq_out_clear(PktOutQueue *pq)
{
PktOut *pkt;
pq->pqb.ic = NULL;
while ((pkt = pq_pop(pq)) != NULL)
ssh_free_pktout(pkt);
}
@ -188,6 +198,9 @@ void pq_base_concatenate(PacketQueueBase *qdest,
qdest->end.prev = tail2;
head1->prev = &qdest->end;
tail2->next = &qdest->end;
if (qdest->ic)
queue_idempotent_callback(qdest->ic);
}
}