2 * packetq - packet queue management. try to send packets several times before discarding.
3 * Copyright 2005 Renzo Davoli
4 * Licensed under the GPLv2
12 #include <sys/types.h>
19 #include <vdecommon.h>
26 int packetq_timeout
= -1;
33 int (*sender
)(int fd
, int fd_ctl
, void *packet
, int len
, void *data
, int port
);
41 struct packetqq
*next
;
44 static struct packetqq
*pqh
=NULL
;
45 static struct packetqq
*pqt
=NULL
;
46 static struct timeval last_try
;
48 void packetq_add(int (*sender
)(int fd
, int fd_ctl
, void *packet
, int len
, void *data
, int port
),
49 int fd
, int fd_ctl
, void *packet
, int len
, void *data
, int port
)
51 if (countq
< MAXQLEN
) {
52 struct packetqq
*new=malloc(sizeof(struct packetqq
));
53 void *packetcopy
=malloc(len
);
54 if (new != NULL
&& packetcopy
!= NULL
&& len
> 0) {
59 memcpy(packetcopy
,packet
,len
);
60 new->packet
=packetcopy
;
67 gettimeofday(&last_try
,NULL
);
68 packetq_timeout
=TIMEOUT
;
75 if (new != NULL
) free(new);
76 if (packetcopy
!= NULL
) free(packetcopy
);
81 static struct packetqq
*packetq_scantry(struct packetqq
*h
,struct packetqq
**t
,fd_set
*fds
)
84 int sendrv
=!(FD_ISSET(h
->fd
,fds
));
86 if ((sendrv
&& (sendrv
=h
->sender(h
->fd
,h
->fd_ctl
,h
->packet
,h
->len
,h
->data
,h
->port
)) == 0) /*send OK*/
87 || h
->times
<=0) { /*or max number of attempts reached*/
88 struct packetqq
*next
;
93 return packetq_scantry(next
,t
,fds
);
96 h
->next
=packetq_scantry(h
->next
,t
,fds
);
97 if (h
->next
== NULL
) *t
=h
;
104 void packetq_try(void)
107 struct timeval this_try
;
108 gettimeofday(&this_try
,NULL
);
109 packetq_timeout
=TIMEOUT
- ((this_try
.tv_sec
-last_try
.tv_sec
) * 1000 +
110 (this_try
.tv_usec
-last_try
.tv_usec
) / 1000);
111 if (packetq_timeout
<= 0) {
114 pqh
=packetq_scantry(pqh
,&pqt
,&fds
);
116 gettimeofday(&last_try
,NULL
);
117 packetq_timeout
=TIMEOUT
;
119 packetq_timeout
= -1;
124 static struct packetqq
*packetq_scandelfd(int fd
,struct packetqq
*h
,struct packetqq
**t
)
128 struct packetqq
*next
=h
->next
;
132 return packetq_scandelfd(fd
,next
,t
);
134 h
->next
=packetq_scandelfd(fd
,h
->next
,t
);
135 if (h
->next
== NULL
) *t
=h
;
142 void packetq_delfd(int fd
)
144 pqh
=packetq_scandelfd(fd
,pqh
,&pqt
);
146 packetq_timeout
= -1;