Use timevals everywhere where it is possible, including API between main
loop and event dispatchers. This simplifies code and eliminates a bug, when kevent dispatcher is called with 0 timeout. While here, in the main loop call gettimeofday() right after event dispatcher returns. Otherwise, we are using outdated "timeofday" in second part of the loop. I don't know any bugs because of that, but they are possible.
This commit is contained in:
parent
cad8c922f0
commit
1d363c209f
2
event.h
2
event.h
@ -42,7 +42,7 @@ typedef int event_module_add_t(struct event *);
|
|||||||
typedef int event_module_del_t(struct event *, int flags);
|
typedef int event_module_del_t(struct event *, int flags);
|
||||||
typedef int event_module_init_t(void);
|
typedef int event_module_init_t(void);
|
||||||
typedef void event_module_fini_t(void);
|
typedef void event_module_fini_t(void);
|
||||||
typedef int event_module_process_t(u_long);
|
typedef int event_module_process_t(struct timeval *);
|
||||||
struct event_module {
|
struct event_module {
|
||||||
event_module_add_t *add;
|
event_module_add_t *add;
|
||||||
event_module_del_t *del;
|
event_module_del_t *del;
|
||||||
|
24
kqueue.c
24
kqueue.c
@ -178,27 +178,21 @@ kqueue_set(struct event *ev, short filter, u_short flags, u_int fflags)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
kqueue_process(u_long timer)
|
kqueue_process(struct timeval *tv)
|
||||||
{
|
{
|
||||||
struct event *ev;
|
struct event *ev;
|
||||||
int events, n, i;
|
int events, n, i;
|
||||||
struct timespec ts, *tp;
|
struct timespec ts;
|
||||||
|
|
||||||
n = (int) nchanges;
|
n = (int) nchanges;
|
||||||
nchanges = 0;
|
nchanges = 0;
|
||||||
|
|
||||||
if (timer == 0) {
|
TIMEVAL_TO_TIMESPEC(tv, &ts);
|
||||||
tp = NULL;
|
|
||||||
} else {
|
|
||||||
ts.tv_sec = timer / 1000;
|
|
||||||
ts.tv_nsec = (timer % 1000) * 1000000;
|
|
||||||
tp = &ts;
|
|
||||||
}
|
|
||||||
|
|
||||||
DPRINTF(E_DEBUG, L_GENERAL, "kevent timer: %lu, changes: %d\n",
|
DPRINTF(E_DEBUG, L_GENERAL, "kevent timer: %lu.%06lu, changes: %d\n",
|
||||||
timer, n);
|
ts.tv_sec, ts.tv_nsec, n);
|
||||||
|
|
||||||
events = kevent(kq, change_list, n, event_list, MAXEVENTS, tp);
|
events = kevent(kq, change_list, n, event_list, MAXEVENTS, &ts);
|
||||||
|
|
||||||
if (events == -1) {
|
if (events == -1) {
|
||||||
if (errno == EINTR)
|
if (errno == EINTR)
|
||||||
@ -208,12 +202,6 @@ kqueue_process(u_long timer)
|
|||||||
|
|
||||||
DPRINTF(E_DEBUG, L_GENERAL, "kevent events: %d\n", events);
|
DPRINTF(E_DEBUG, L_GENERAL, "kevent events: %d\n", events);
|
||||||
|
|
||||||
if (events == 0) {
|
|
||||||
if (timer != 0)
|
|
||||||
return (0);
|
|
||||||
DPRINTF(E_FATAL, L_GENERAL, "kevent() returned no events. EXITING\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 0; i < events; i++) {
|
for (i = 0; i < events; i++) {
|
||||||
if (event_list[i].flags & EV_ERROR) {
|
if (event_list[i].flags & EV_ERROR) {
|
||||||
DPRINTF(E_ERROR, L_GENERAL,
|
DPRINTF(E_ERROR, L_GENERAL,
|
||||||
|
43
minidlna.c
43
minidlna.c
@ -1112,7 +1112,6 @@ main(int argc, char **argv)
|
|||||||
struct upnphttp * next;
|
struct upnphttp * next;
|
||||||
struct timeval tv, timeofday, lastnotifytime = {0, 0};
|
struct timeval tv, timeofday, lastnotifytime = {0, 0};
|
||||||
time_t lastupdatetime = 0, lastdbtime = 0;
|
time_t lastupdatetime = 0, lastdbtime = 0;
|
||||||
u_long timeout; /* in milliseconds */
|
|
||||||
int last_changecnt = 0;
|
int last_changecnt = 0;
|
||||||
pid_t scanner_pid = 0;
|
pid_t scanner_pid = 0;
|
||||||
struct event ssdpev, httpev, monev;
|
struct event ssdpev, httpev, monev;
|
||||||
@ -1184,6 +1183,9 @@ main(int argc, char **argv)
|
|||||||
httpev = (struct event ){ .fd = shttpl, .rdwr = EVENT_READ, .process = ProcessListen };
|
httpev = (struct event ){ .fd = shttpl, .rdwr = EVENT_READ, .process = ProcessListen };
|
||||||
event_module.add(&httpev);
|
event_module.add(&httpev);
|
||||||
|
|
||||||
|
if (gettimeofday(&timeofday, 0) < 0)
|
||||||
|
DPRINTF(E_FATAL, L_GENERAL, "gettimeofday(): %s\n", strerror(errno));
|
||||||
|
|
||||||
#ifdef TIVO_SUPPORT
|
#ifdef TIVO_SUPPORT
|
||||||
if (GETFLAG(TIVO_MASK))
|
if (GETFLAG(TIVO_MASK))
|
||||||
{
|
{
|
||||||
@ -1208,18 +1210,17 @@ main(int argc, char **argv)
|
|||||||
tivo_bcast.sin_family = AF_INET;
|
tivo_bcast.sin_family = AF_INET;
|
||||||
tivo_bcast.sin_addr.s_addr = htonl(getBcastAddress());
|
tivo_bcast.sin_addr.s_addr = htonl(getBcastAddress());
|
||||||
tivo_bcast.sin_port = htons(2190);
|
tivo_bcast.sin_port = htons(2190);
|
||||||
|
lastbeacontime = timeofday;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
reload_ifaces(0);
|
reload_ifaces(0); /* sends SSDP notifies */
|
||||||
lastnotifytime.tv_sec = time(NULL) + runtime_vars.notify_interval;
|
lastnotifytime = timeofday;
|
||||||
|
|
||||||
/* main loop */
|
/* main loop */
|
||||||
while (!quitting)
|
while (!quitting)
|
||||||
{
|
{
|
||||||
if (gettimeofday(&timeofday, 0) < 0)
|
|
||||||
DPRINTF(E_FATAL, L_GENERAL, "gettimeofday(): %s\n", strerror(errno));
|
|
||||||
/* Check if we need to send SSDP NOTIFY messages and do it if
|
/* Check if we need to send SSDP NOTIFY messages and do it if
|
||||||
* needed */
|
* needed */
|
||||||
tv = lastnotifytime;
|
tv = lastnotifytime;
|
||||||
@ -1233,41 +1234,38 @@ main(int argc, char **argv)
|
|||||||
runtime_vars.port, runtime_vars.notify_interval);
|
runtime_vars.port, runtime_vars.notify_interval);
|
||||||
}
|
}
|
||||||
lastnotifytime = timeofday;
|
lastnotifytime = timeofday;
|
||||||
timeout = runtime_vars.notify_interval * 1000;
|
tv.tv_sec = runtime_vars.notify_interval;
|
||||||
|
tv.tv_usec = 0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
timevalsub(&tv, &timeofday);
|
timevalsub(&tv, &timeofday);
|
||||||
timeout = tv.tv_sec * 1000 + tv.tv_usec / 1000;
|
|
||||||
}
|
}
|
||||||
#ifdef TIVO_SUPPORT
|
#ifdef TIVO_SUPPORT
|
||||||
if (sbeacon >= 0)
|
if (sbeacon >= 0)
|
||||||
{
|
{
|
||||||
u_long beacontimeout;
|
struct timeval beacontv;
|
||||||
|
|
||||||
tv = lastbeacontime;
|
beacontv = lastbeacontime;
|
||||||
tv.tv_sec += beacon_interval;
|
beacontv.tv_sec += beacon_interval;
|
||||||
if (timevalcmp(&timeofday, &tv, >=))
|
if (timevalcmp(&timeofday, &beacontv, >=))
|
||||||
{
|
{
|
||||||
sendBeaconMessage(sbeacon, &tivo_bcast, sizeof(struct sockaddr_in), 1);
|
sendBeaconMessage(sbeacon, &tivo_bcast, sizeof(struct sockaddr_in), 1);
|
||||||
lastbeacontime = timeofday;
|
lastbeacontime = timeofday;
|
||||||
beacontimeout = beacon_interval * 1000;
|
|
||||||
if (timeout > beacon_interval * 1000)
|
|
||||||
timeout = beacon_interval * 1000;
|
|
||||||
/* Beacons should be sent every 5 seconds or
|
/* Beacons should be sent every 5 seconds or
|
||||||
* so for the first minute, then every minute
|
* so for the first minute, then every minute
|
||||||
* or so thereafter. */
|
* or so thereafter. */
|
||||||
if (beacon_interval == 5 && (timeofday.tv_sec - startup_time) > 60)
|
if (beacon_interval == 5 && (timeofday.tv_sec - startup_time) > 60)
|
||||||
beacon_interval = 60;
|
beacon_interval = 60;
|
||||||
|
beacontv.tv_sec = beacon_interval;
|
||||||
|
beacontv.tv_usec = 0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
timevalsub(&tv, &timeofday);
|
timevalsub(&beacontv, &timeofday);
|
||||||
beacontimeout = tv.tv_sec * 1000 +
|
|
||||||
tv.tv_usec / 1000;
|
|
||||||
}
|
}
|
||||||
if (timeout > beacontimeout)
|
if (timevalcmp(&tv, &beacontv, >))
|
||||||
timeout = beacontimeout;
|
tv = beacontv;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -1282,13 +1280,16 @@ main(int argc, char **argv)
|
|||||||
#endif
|
#endif
|
||||||
} else
|
} else
|
||||||
/* Keep checking for the scanner every sec. */
|
/* Keep checking for the scanner every sec. */
|
||||||
timeout = 1000;
|
tv.tv_sec = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
event_module.process(timeout);
|
event_module.process(&tv);
|
||||||
if (quitting)
|
if (quitting)
|
||||||
goto shutdown;
|
goto shutdown;
|
||||||
|
|
||||||
|
if (gettimeofday(&timeofday, 0) < 0)
|
||||||
|
DPRINTF(E_FATAL, L_GENERAL, "gettimeofday(): %s\n", strerror(errno));
|
||||||
|
|
||||||
upnpevents_gc();
|
upnpevents_gc();
|
||||||
|
|
||||||
/* increment SystemUpdateID if the content database has changed,
|
/* increment SystemUpdateID if the content database has changed,
|
||||||
|
9
select.c
9
select.c
@ -142,9 +142,8 @@ select_del(struct event *ev, int flags)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
select_process(u_long msec)
|
select_process(struct timeval *tv)
|
||||||
{
|
{
|
||||||
struct timeval tv, *tp;
|
|
||||||
struct event *ev;
|
struct event *ev;
|
||||||
int ready, i;
|
int ready, i;
|
||||||
|
|
||||||
@ -155,14 +154,10 @@ select_process(u_long msec)
|
|||||||
max_fd = events[i]->fd;
|
max_fd = events[i]->fd;
|
||||||
}
|
}
|
||||||
|
|
||||||
tv.tv_sec = (long) (msec / 1000);
|
|
||||||
tv.tv_usec = (long) ((msec % 1000) * 1000);
|
|
||||||
tp = &tv;
|
|
||||||
|
|
||||||
work_read_fd_set = master_read_fd_set;
|
work_read_fd_set = master_read_fd_set;
|
||||||
work_write_fd_set = master_write_fd_set;
|
work_write_fd_set = master_write_fd_set;
|
||||||
|
|
||||||
ready = select(max_fd + 1, &work_read_fd_set, &work_write_fd_set, NULL, tp);
|
ready = select(max_fd + 1, &work_read_fd_set, &work_write_fd_set, NULL, tv);
|
||||||
|
|
||||||
if (ready == -1) {
|
if (ready == -1) {
|
||||||
if (errno == EINTR)
|
if (errno == EINTR)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user