mirror of
https://git.tartarus.org/simon/putty.git
synced 2025-01-09 17:38:00 +00:00
d5836982e2
First, make absolute times unsigned. This means that it's safe to depend on their overflow behaviour (which is undefined for signed integers). This requires a little extra care in handling comparisons, but I think I've correctly adjusted them all. Second, functions registered with schedule_timer() are guaranteed to be called with precisely the time that was returned by schedule_timer(). Thus, it's only necessary to check these values for equality rather than doing risky range checks, so do that. The timing code still does lots that's undefined, unnecessary, or just wrong, but this is a good start. [originally from svn r9667]
73 lines
1.6 KiB
C
73 lines
1.6 KiB
C
/*
|
|
* pinger.c: centralised module that deals with sending TS_PING
|
|
* keepalives, to avoid replicating this code in multiple backends.
|
|
*/
|
|
|
|
#include "putty.h"
|
|
|
|
struct pinger_tag {
|
|
int interval;
|
|
int pending;
|
|
unsigned long next;
|
|
Backend *back;
|
|
void *backhandle;
|
|
};
|
|
|
|
static void pinger_schedule(Pinger pinger);
|
|
|
|
static void pinger_timer(void *ctx, unsigned long now)
|
|
{
|
|
Pinger pinger = (Pinger)ctx;
|
|
|
|
if (pinger->pending && now == pinger->next) {
|
|
pinger->back->special(pinger->backhandle, TS_PING);
|
|
pinger->pending = FALSE;
|
|
pinger_schedule(pinger);
|
|
}
|
|
}
|
|
|
|
static void pinger_schedule(Pinger pinger)
|
|
{
|
|
int next;
|
|
|
|
if (!pinger->interval) {
|
|
pinger->pending = FALSE; /* cancel any pending ping */
|
|
return;
|
|
}
|
|
|
|
next = schedule_timer(pinger->interval * TICKSPERSEC,
|
|
pinger_timer, pinger);
|
|
if (!pinger->pending || next < pinger->next) {
|
|
pinger->next = next;
|
|
pinger->pending = TRUE;
|
|
}
|
|
}
|
|
|
|
Pinger pinger_new(Conf *conf, Backend *back, void *backhandle)
|
|
{
|
|
Pinger pinger = snew(struct pinger_tag);
|
|
|
|
pinger->interval = conf_get_int(conf, CONF_ping_interval);
|
|
pinger->pending = FALSE;
|
|
pinger->back = back;
|
|
pinger->backhandle = backhandle;
|
|
pinger_schedule(pinger);
|
|
|
|
return pinger;
|
|
}
|
|
|
|
void pinger_reconfig(Pinger pinger, Conf *oldconf, Conf *newconf)
|
|
{
|
|
int newinterval = conf_get_int(newconf, CONF_ping_interval);
|
|
if (conf_get_int(oldconf, CONF_ping_interval) != newinterval) {
|
|
pinger->interval = newinterval;
|
|
pinger_schedule(pinger);
|
|
}
|
|
}
|
|
|
|
void pinger_free(Pinger pinger)
|
|
{
|
|
expire_timer_context(pinger);
|
|
sfree(pinger);
|
|
}
|