mirror of
https://git.FreeBSD.org/src.git
synced 2024-12-19 10:53:58 +00:00
Fix time math overflows and improve zero intervals handling in poll(),
select(), nanosleep() and kevent() functions after calloutng changes. Reported by: bde
This commit is contained in:
parent
9461964cc9
commit
980c545d76
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=247898
@ -1329,11 +1329,16 @@ kqueue_scan(struct kqueue *kq, int maxevents, struct kevent_copyops *k_ops,
|
||||
goto done_nl;
|
||||
}
|
||||
if (timespecisset(tsp)) {
|
||||
rsbt = tstosbt(*tsp);
|
||||
if (TIMESEL(&asbt, rsbt))
|
||||
asbt += tc_tick_sbt;
|
||||
asbt += rsbt;
|
||||
rsbt >>= tc_precexp;
|
||||
if (tsp->tv_sec < INT32_MAX) {
|
||||
rsbt = tstosbt(*tsp);
|
||||
if (TIMESEL(&asbt, rsbt))
|
||||
asbt += tc_tick_sbt;
|
||||
asbt += rsbt;
|
||||
if (asbt < rsbt)
|
||||
asbt = 0;
|
||||
rsbt >>= tc_precexp;
|
||||
} else
|
||||
asbt = 0;
|
||||
} else
|
||||
asbt = -1;
|
||||
} else
|
||||
|
@ -484,13 +484,20 @@ kern_nanosleep(struct thread *td, struct timespec *rqt, struct timespec *rmt)
|
||||
{
|
||||
struct timespec ts;
|
||||
sbintime_t sbt, sbtt, prec, tmp;
|
||||
time_t over;
|
||||
int error;
|
||||
|
||||
if (rqt->tv_nsec < 0 || rqt->tv_nsec >= 1000000000)
|
||||
return (EINVAL);
|
||||
if (rqt->tv_sec < 0 || (rqt->tv_sec == 0 && rqt->tv_nsec == 0))
|
||||
return (0);
|
||||
tmp = tstosbt(*rqt);
|
||||
ts = *rqt;
|
||||
if (ts.tv_sec > INT32_MAX / 2) {
|
||||
over = ts.tv_sec - INT32_MAX / 2;
|
||||
ts.tv_sec -= over;
|
||||
} else
|
||||
over = 0;
|
||||
tmp = tstosbt(ts);
|
||||
prec = tmp;
|
||||
prec >>= tc_precexp;
|
||||
if (TIMESEL(&sbt, tmp))
|
||||
@ -504,6 +511,7 @@ kern_nanosleep(struct thread *td, struct timespec *rqt, struct timespec *rmt)
|
||||
TIMESEL(&sbtt, tmp);
|
||||
if (rmt != NULL) {
|
||||
ts = sbttots(sbt - sbtt);
|
||||
ts.tv_sec += over;
|
||||
if (ts.tv_sec < 0)
|
||||
timespecclear(&ts);
|
||||
*rmt = ts;
|
||||
|
@ -1051,12 +1051,19 @@ kern_select(struct thread *td, int nd, fd_set *fd_in, fd_set *fd_ou,
|
||||
error = EINVAL;
|
||||
goto done;
|
||||
}
|
||||
rsbt = tvtosbt(rtv);
|
||||
precision = rsbt;
|
||||
precision >>= tc_precexp;
|
||||
if (TIMESEL(&asbt, rsbt))
|
||||
asbt += tc_tick_sbt;
|
||||
asbt += rsbt;
|
||||
if (rtv.tv_sec == 0 && rtv.tv_usec == 0)
|
||||
asbt = 0;
|
||||
else if (rtv.tv_sec < INT32_MAX) {
|
||||
rsbt = tvtosbt(rtv);
|
||||
precision = rsbt;
|
||||
precision >>= tc_precexp;
|
||||
if (TIMESEL(&asbt, rsbt))
|
||||
asbt += tc_tick_sbt;
|
||||
asbt += rsbt;
|
||||
if (asbt < rsbt)
|
||||
asbt = -1;
|
||||
} else
|
||||
asbt = -1;
|
||||
} else
|
||||
asbt = -1;
|
||||
seltdinit(td);
|
||||
@ -1295,12 +1302,16 @@ sys_poll(td, uap)
|
||||
error = EINVAL;
|
||||
goto done;
|
||||
}
|
||||
rsbt = SBT_1MS * uap->timeout;
|
||||
precision = rsbt;
|
||||
precision >>= tc_precexp;
|
||||
if (TIMESEL(&asbt, rsbt))
|
||||
asbt += tc_tick_sbt;
|
||||
asbt += rsbt;
|
||||
if (uap->timeout == 0)
|
||||
asbt = 0;
|
||||
else {
|
||||
rsbt = SBT_1MS * uap->timeout;
|
||||
precision = rsbt;
|
||||
precision >>= tc_precexp;
|
||||
if (TIMESEL(&asbt, rsbt))
|
||||
asbt += tc_tick_sbt;
|
||||
asbt += rsbt;
|
||||
}
|
||||
} else
|
||||
asbt = -1;
|
||||
seltdinit(td);
|
||||
|
Loading…
Reference in New Issue
Block a user