mirror of
https://github.com/servalproject/serval-dna.git
synced 2025-01-18 02:39:44 +00:00
Allow SIGIO to unblock poll() without dying
This commit is contained in:
parent
d5b96b9931
commit
a3de276999
70
fdqueue.c
70
fdqueue.c
@ -339,48 +339,57 @@ int fd_poll2(time_ms_t (*waiting)(time_ms_t, time_ms_t, time_ms_t), void (*wokeu
|
||||
RETURN(1);
|
||||
}
|
||||
|
||||
// return 0 when there's nothing to do, it doesn't make sense to wait for infinity
|
||||
if (!run_now && !wake_list && fdcount==0)
|
||||
RETURN(0);
|
||||
|
||||
time_ms_t wait;
|
||||
time_ms_t now = gettime_ms();
|
||||
time_ms_t wait_until=TIME_MS_NEVER_WILL;
|
||||
uint8_t called_waiting = 0;
|
||||
|
||||
if (run_now)
|
||||
wait = 0;
|
||||
else {
|
||||
if (run_now){
|
||||
wait_until = now;
|
||||
}else{
|
||||
time_ms_t next_run=TIME_MS_NEVER_WILL;
|
||||
if(run_soon)
|
||||
next_run = run_soon->run_after;
|
||||
|
||||
time_ms_t next_wake=TIME_MS_NEVER_WILL;
|
||||
if (wake_list)
|
||||
next_wake = wake_list->wake_at;
|
||||
|
||||
time_ms_t wait_until;
|
||||
time_ms_t now = gettime_ms();
|
||||
|
||||
if (waiting)
|
||||
wait_until = waiting(now, next_run, next_wake);
|
||||
else
|
||||
wait_until = next_wake;
|
||||
|
||||
if (wait_until==TIME_MS_NEVER_WILL)
|
||||
wait = -1;
|
||||
else if (wait_until < now)
|
||||
wait = 0;
|
||||
else
|
||||
wait = wait_until - now;
|
||||
wait_until = wake_list->wake_at;
|
||||
|
||||
if (waiting && wait_until > now){
|
||||
wait_until = waiting(now, next_run, wait_until);
|
||||
now = gettime_ms();
|
||||
called_waiting = 1;
|
||||
}
|
||||
}
|
||||
|
||||
// check for IO and/or wait for the next wake_at
|
||||
int wait=0;
|
||||
int r=0;
|
||||
if (fdcount || wait>0){
|
||||
|
||||
{
|
||||
struct call_stats call_stats;
|
||||
call_stats.totals=&poll_stats;
|
||||
fd_func_enter(__HERE__, &call_stats);
|
||||
if (fdcount==0){
|
||||
sleep_ms(wait);
|
||||
}else{
|
||||
|
||||
if (wait_until==TIME_MS_NEVER_WILL)
|
||||
wait = -1;
|
||||
else if (wait_until <= now)
|
||||
wait = 0;
|
||||
else
|
||||
wait = wait_until - now;
|
||||
|
||||
if (fdcount){
|
||||
if (config.debug.io)
|
||||
DEBUGF("Calling poll with %dms wait", wait);
|
||||
|
||||
fd_func_enter(__HERE__, &call_stats);
|
||||
r = poll(fds, fdcount, wait);
|
||||
fd_func_exit(__HERE__, &call_stats);
|
||||
|
||||
if (r==-1 && errno!=EINTR)
|
||||
WHY_perror("poll");
|
||||
|
||||
if (config.debug.io) {
|
||||
strbuf b = strbuf_alloca(1024);
|
||||
int i;
|
||||
@ -394,11 +403,16 @@ int fd_poll2(time_ms_t (*waiting)(time_ms_t, time_ms_t, time_ms_t), void (*wokeu
|
||||
}
|
||||
DEBUGF("poll(fds=(%s), fdcount=%d, ms=%d) -> %d", strbuf_str(b), fdcount, wait, r);
|
||||
}
|
||||
|
||||
}else if(wait>0){
|
||||
fd_func_enter(__HERE__, &call_stats);
|
||||
sleep_ms(wait);
|
||||
fd_func_exit(__HERE__, &call_stats);
|
||||
|
||||
}
|
||||
fd_func_exit(__HERE__, &call_stats);
|
||||
}
|
||||
|
||||
if (wokeup && !run_now)
|
||||
if (wokeup && called_waiting)
|
||||
wokeup();
|
||||
|
||||
move_run_list();
|
||||
|
20
server.c
20
server.c
@ -252,13 +252,24 @@ static int server_bind()
|
||||
|
||||
/* Catch SIGHUP etc so that we can respond to requests to do things, eg, shut down. */
|
||||
struct sigaction sig;
|
||||
bzero(&sig, sizeof sig);
|
||||
|
||||
sig.sa_flags = 0;
|
||||
sig.sa_handler = signal_handler;
|
||||
sigemptyset(&sig.sa_mask); // Block the same signals during handler
|
||||
sigaddset(&sig.sa_mask, SIGHUP);
|
||||
sigaddset(&sig.sa_mask, SIGINT);
|
||||
sig.sa_flags = 0;
|
||||
sigaddset(&sig.sa_mask, SIGIO);
|
||||
|
||||
#ifdef ANDROID
|
||||
// batphone depends on this constant to wake up the scheduler
|
||||
// break the build if it changes.
|
||||
assert(SIGIO==29);
|
||||
#endif
|
||||
|
||||
sigaction(SIGHUP, &sig, NULL);
|
||||
sigaction(SIGINT, &sig, NULL);
|
||||
sigaction(SIGIO, &sig, NULL);
|
||||
|
||||
/* Setup up client API sockets before writing our PID file
|
||||
We want clients to be able to connect to our sockets as soon
|
||||
@ -303,7 +314,7 @@ static int server_bind()
|
||||
time_ms_t now = gettime_ms();
|
||||
|
||||
// Periodically check for server shut down
|
||||
RESCHEDULE(&ALARM_STRUCT(server_shutdown_check), now, now+30000, now);
|
||||
RESCHEDULE(&ALARM_STRUCT(server_shutdown_check), now, TIME_MS_NEVER_WILL, now);
|
||||
|
||||
overlay_mdp_bind_internal_services();
|
||||
|
||||
@ -599,7 +610,7 @@ void server_shutdown_check(struct sched_ent *alarm)
|
||||
}
|
||||
}
|
||||
if (alarm){
|
||||
RESCHEDULE(alarm, now+1000, now+30000, now+1100);
|
||||
RESCHEDULE(alarm, now+1000, TIME_MS_NEVER_WILL, now+1100);
|
||||
}
|
||||
}
|
||||
|
||||
@ -639,6 +650,9 @@ static void serverCleanUp()
|
||||
static void signal_handler(int signal)
|
||||
{
|
||||
switch (signal) {
|
||||
case SIGIO:
|
||||
// noop to break out of poll
|
||||
return;
|
||||
case SIGHUP:
|
||||
case SIGINT:
|
||||
/* Trigger the server to close gracefully after any current alarm has completed.
|
||||
|
Loading…
Reference in New Issue
Block a user