Implement patty_timer type
Changes: * Implement patty_timer type to store both a struct timeval and a bitfield for indicating timer state; currently, this only holds the PATTY_TIMER_RUNNING flag to indicate whether a timer has been stopped (irrespective of its "expired" status) * Remove 'target' argument from patty_timer_start(); instead, rely on select() polling every 1s to cause events to trigger at a regular interval * Make patty_timer_expired() return false if PATTY_TIMER_RUNNING is not set * Implement patty_timer_stop() to clear the PATTY_TIMER_RUNNING flag of a timer * Make patty_timer_clear() set all fields to zero, including clearing the PATTY_TIMER_RUNNING flag
This commit is contained in:
parent
a619bc4906
commit
ba3923495e
5 changed files with 69 additions and 51 deletions
|
@ -1,6 +1,11 @@
|
|||
#ifndef _PATTY_AX25_SOCK_H
|
||||
#define _PATTY_AX25_SOCK_H
|
||||
|
||||
#include <patty/timer.h>
|
||||
|
||||
#define PATTY_AX25_SOCK_DEFAULT_KEEPALIVE (1000 * 5)
|
||||
#define PATTY_AX25_SOCK_DEFAULT_DELAY 3000
|
||||
|
||||
#define PATTY_AX25_SOCK_DEFAULT_CLASSES \
|
||||
(PATTY_AX25_PARAM_CLASSES_ABM)
|
||||
|
||||
|
@ -62,13 +67,13 @@ typedef struct _patty_ax25_sock {
|
|||
n_ack,
|
||||
n_retry;
|
||||
|
||||
struct timeval timer_t1,
|
||||
timer_t2,
|
||||
timer_t3;
|
||||
|
||||
uint32_t flags_classes,
|
||||
flags_hdlc;
|
||||
|
||||
patty_timer timer_t1,
|
||||
timer_t2,
|
||||
timer_t3;
|
||||
|
||||
unsigned int seq_send,
|
||||
seq_recv;
|
||||
|
||||
|
|
|
@ -1,17 +1,30 @@
|
|||
#ifndef _PATTY_TIMER_H
|
||||
#define _PATTY_TIMER_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
int patty_timer_expired(struct timeval *timer);
|
||||
enum patty_timer_flags {
|
||||
PATTY_TIMER_RUNNING = (1 << 0)
|
||||
};
|
||||
|
||||
void patty_timer_cancel(struct timeval *timer);
|
||||
typedef struct _patty_timer {
|
||||
struct timeval t;
|
||||
uint32_t flags;
|
||||
} patty_timer;
|
||||
|
||||
void patty_timer_start(struct timeval *timer,
|
||||
struct timeval *target,
|
||||
int patty_timer_running(patty_timer *timer);
|
||||
|
||||
int patty_timer_expired(patty_timer *timer);
|
||||
|
||||
void patty_timer_clear(patty_timer *timer);
|
||||
|
||||
void patty_timer_start(patty_timer *timer,
|
||||
time_t ms);
|
||||
|
||||
void patty_timer_tick(struct timeval *timer,
|
||||
void patty_timer_stop(patty_timer *timer);
|
||||
|
||||
void patty_timer_tick(patty_timer *timer,
|
||||
struct timeval *elapsed);
|
||||
|
||||
#endif /* _PATTY_TIMER_H */
|
||||
|
|
34
src/server.c
34
src/server.c
|
@ -11,7 +11,6 @@
|
|||
|
||||
#include <patty/ax25.h>
|
||||
#include <patty/hash.h>
|
||||
#include <patty/timer.h>
|
||||
|
||||
typedef int (*patty_ax25_server_call)(patty_ax25_server *, int);
|
||||
|
||||
|
@ -21,8 +20,7 @@ struct _patty_ax25_server {
|
|||
int fd, /* fd of UNIX domain socket */
|
||||
fd_max;
|
||||
|
||||
struct timeval timer,
|
||||
elapsed;
|
||||
struct timeval elapsed;
|
||||
|
||||
fd_set fds_watch, /* fds to monitor with select() */
|
||||
fds_r; /* fds select()ed for reading */
|
||||
|
@ -830,7 +828,7 @@ static int server_connect(patty_ax25_server *server,
|
|||
return respond_connect(client, -1, errno);
|
||||
}
|
||||
|
||||
patty_timer_start(&sock->timer_t1, &server->timer, sock->n_ack);
|
||||
patty_timer_start(&sock->timer_t1, sock->n_ack);
|
||||
|
||||
/*
|
||||
* At this point, we will wait for a DM, FRMR or XID response, which
|
||||
|
@ -1153,7 +1151,7 @@ static int handle_frmr(patty_ax25_server *server,
|
|||
if (sock->status == PATTY_AX25_SOCK_PENDING_CONNECT) {
|
||||
int ret = patty_ax25_sock_send_sabm(sock, PATTY_AX25_FRAME_POLL);
|
||||
|
||||
patty_timer_start(&sock->timer_t1, &server->timer, sock->n_ack);
|
||||
patty_timer_start(&sock->timer_t1, sock->n_ack);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -1251,7 +1249,7 @@ static int handle_ua(patty_ax25_server *server,
|
|||
return reply_dm(iface, frame, PATTY_AX25_FRAME_FINAL);
|
||||
}
|
||||
|
||||
patty_timer_cancel(&sock->timer_t1);
|
||||
patty_timer_stop(&sock->timer_t1);
|
||||
|
||||
sock->status = PATTY_AX25_SOCK_ESTABLISHED;
|
||||
|
||||
|
@ -1316,7 +1314,7 @@ static int handle_i(patty_ax25_server *server,
|
|||
|
||||
if (++sock->pending == sock->n_window_rx / 2) {
|
||||
sock->pending = 0;
|
||||
patty_timer_cancel(&sock->timer_t2);
|
||||
patty_timer_stop(&sock->timer_t2);
|
||||
|
||||
return patty_ax25_sock_send_rr(sock, PATTY_AX25_FRAME_RESPONSE, 0);
|
||||
} else {
|
||||
|
@ -1460,7 +1458,7 @@ static int handle_xid(patty_ax25_server *server,
|
|||
|
||||
ret = patty_ax25_sock_send_sabm(remote, PATTY_AX25_FRAME_POLL);
|
||||
|
||||
patty_timer_start(&remote->timer_t1, &server->timer, remote->n_ack);
|
||||
patty_timer_start(&remote->timer_t1, remote->n_ack);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -1645,7 +1643,7 @@ static int handle_sock(uint32_t key,
|
|||
int ret = patty_ax25_sock_send_sabm(sock, PATTY_AX25_FRAME_POLL);
|
||||
|
||||
sock->retries--;
|
||||
patty_timer_start(&sock->timer_t1, &server->timer, sock->n_ack);
|
||||
patty_timer_start(&sock->timer_t1, sock->n_ack);
|
||||
|
||||
return ret;
|
||||
} else {
|
||||
|
@ -1704,7 +1702,7 @@ static int handle_sock(uint32_t key,
|
|||
/*
|
||||
* AX.25 v2.2, Section 6.4.1 "Sending I Frames"
|
||||
*/
|
||||
patty_timer_start(&sock->timer_t1, &server->timer, sock->n_ack);
|
||||
patty_timer_start(&sock->timer_t1, sock->n_ack);
|
||||
|
||||
done:
|
||||
return 0;
|
||||
|
@ -1726,28 +1724,20 @@ int patty_ax25_server_run(patty_ax25_server *server) {
|
|||
while (1) {
|
||||
int nready;
|
||||
|
||||
struct timeval remaining,
|
||||
*timer;
|
||||
struct timeval timer = { 1, 0 },
|
||||
remaining = { 1, 0 };
|
||||
|
||||
memcpy(&server->fds_r, &server->fds_watch, sizeof(server->fds_r));
|
||||
memcpy(&remaining, &server->timer, sizeof(remaining));
|
||||
|
||||
timer = timerisset(&remaining)? &remaining: NULL;
|
||||
|
||||
if ((nready = select( server->fd_max,
|
||||
&server->fds_r,
|
||||
NULL,
|
||||
NULL,
|
||||
timer)) < 0) {
|
||||
&remaining)) < 0) {
|
||||
goto error_io;
|
||||
}
|
||||
|
||||
if (timer) {
|
||||
timersub(&server->timer, &remaining, &server->elapsed);
|
||||
memcpy(&server->timer, &remaining, sizeof(server->timer));
|
||||
} else {
|
||||
timerclear(&server->elapsed);
|
||||
}
|
||||
timersub(&timer, &remaining, &server->elapsed);
|
||||
|
||||
if (handle_clients(server) < 0) {
|
||||
goto error_io;
|
||||
|
|
|
@ -182,9 +182,9 @@ int patty_ax25_sock_reset(patty_ax25_sock *sock) {
|
|||
sock->retries = sock->n_retry;
|
||||
sock->pending = 0;
|
||||
|
||||
timerclear(&sock->timer_t1);
|
||||
timerclear(&sock->timer_t2);
|
||||
timerclear(&sock->timer_t3);
|
||||
patty_timer_clear(&sock->timer_t1);
|
||||
patty_timer_clear(&sock->timer_t2);
|
||||
patty_timer_clear(&sock->timer_t3);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
46
src/timer.c
46
src/timer.c
|
@ -1,32 +1,42 @@
|
|||
#include <patty/timer.h>
|
||||
|
||||
int patty_timer_expired(struct timeval *timer) {
|
||||
return timer->tv_sec <= 0? 1: 0;
|
||||
int patty_timer_running(patty_timer *timer) {
|
||||
return (timer->flags & PATTY_TIMER_RUNNING)? 1: 0;
|
||||
}
|
||||
|
||||
void patty_timer_cancel(struct timeval *timer) {
|
||||
timer->tv_sec = 0;
|
||||
timer->tv_usec = 0;
|
||||
int patty_timer_expired(patty_timer *timer) {
|
||||
return (timer->flags & PATTY_TIMER_RUNNING) && timer->t.tv_sec <= 0? 1: 0;
|
||||
}
|
||||
|
||||
void patty_timer_start(struct timeval *timer,
|
||||
struct timeval *target,
|
||||
void patty_timer_clear(patty_timer *timer) {
|
||||
timer->t.tv_sec = 0;
|
||||
timer->t.tv_usec = 0;
|
||||
|
||||
timer->flags &= ~PATTY_TIMER_RUNNING;
|
||||
}
|
||||
|
||||
void patty_timer_start(patty_timer *timer,
|
||||
time_t ms) {
|
||||
timer->tv_sec = ms / 1000;
|
||||
timer->tv_usec = (ms % 1000) * 1000;
|
||||
timer->t.tv_sec = ms / 1000;
|
||||
timer->t.tv_usec = (ms % 1000) * 1000;
|
||||
|
||||
if (timercmp(timer, target, >)) {
|
||||
target->tv_sec = timer->tv_sec;
|
||||
target->tv_usec = timer->tv_usec;
|
||||
}
|
||||
timer->flags |= PATTY_TIMER_RUNNING;
|
||||
}
|
||||
|
||||
void patty_timer_tick(struct timeval *timer,
|
||||
void patty_timer_stop(patty_timer *timer) {
|
||||
timer->flags &= ~PATTY_TIMER_RUNNING;
|
||||
}
|
||||
|
||||
void patty_timer_tick(patty_timer *timer,
|
||||
struct timeval *elapsed) {
|
||||
struct timeval res;
|
||||
|
||||
timersub(timer, elapsed, &res);
|
||||
|
||||
timer->tv_sec = res.tv_sec;
|
||||
timer->tv_usec = res.tv_usec;
|
||||
if (!(timer->flags & PATTY_TIMER_RUNNING)) {
|
||||
return;
|
||||
}
|
||||
|
||||
timersub(&timer->t, elapsed, &res);
|
||||
|
||||
timer->t.tv_sec = res.tv_sec;
|
||||
timer->t.tv_usec = res.tv_usec;
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue