| 1327 | } |
| 1328 | |
| 1329 | rt_err_t lwp_thread_signal_timedwait(rt_thread_t thread, lwp_sigset_t *sigset, |
| 1330 | siginfo_t *usi, struct timespec *timeout) |
| 1331 | { |
| 1332 | rt_err_t ret; |
| 1333 | lwp_sigset_t saved_sigset; |
| 1334 | lwp_sigset_t blocked_sigset; |
| 1335 | lwp_sigset_t dontwait_sigset; |
| 1336 | int sig; |
| 1337 | struct rt_lwp *lwp = thread->lwp; |
| 1338 | |
| 1339 | /** |
| 1340 | * Brief: POSIX |
| 1341 | * If one of the signals in set is already pending for the calling thread, |
| 1342 | * sigwaitinfo() will return immediately |
| 1343 | */ |
| 1344 | |
| 1345 | /* Create a mask of signals user dont want or cannot catch */ |
| 1346 | _sigdelset(sigset, SIGKILL); |
| 1347 | _sigdelset(sigset, SIGSTOP); |
| 1348 | _signotsets(&dontwait_sigset, sigset); |
| 1349 | |
| 1350 | LWP_LOCK(lwp); |
| 1351 | sig = _dequeue_signal(thread, &dontwait_sigset, usi); |
| 1352 | LWP_UNLOCK(lwp); |
| 1353 | if (sig) |
| 1354 | return sig; |
| 1355 | |
| 1356 | /** |
| 1357 | * Brief: POSIX |
| 1358 | * if none of the signals specified by set are pending, sigtimedwait() shall |
| 1359 | * wait for the time interval specified in the timespec structure referenced |
| 1360 | * by timeout. |
| 1361 | * |
| 1362 | * Note: If the pending signal arrives before thread suspend, the suspend |
| 1363 | * operation will return a failure |
| 1364 | */ |
| 1365 | _sigandsets(&blocked_sigset, &thread->signal.sigset_mask, &dontwait_sigset); |
| 1366 | _thread_signal_mask(thread, LWP_SIG_MASK_CMD_SET_MASK, &blocked_sigset, &saved_sigset); |
| 1367 | if (timeout) |
| 1368 | { |
| 1369 | rt_tick_t time; |
| 1370 | time = (timeout->tv_sec * RT_TICK_PER_SECOND) + ((timeout->tv_nsec * RT_TICK_PER_SECOND) / NANOSECOND_PER_SECOND); |
| 1371 | /** |
| 1372 | * Brief: POSIX |
| 1373 | * If the timespec structure pointed to by timeout is zero-valued and |
| 1374 | * if none of the signals specified by set are pending, then |
| 1375 | * sigtimedwait() shall return immediately with an error |
| 1376 | */ |
| 1377 | if (time == 0) |
| 1378 | return -EAGAIN; |
| 1379 | |
| 1380 | rt_enter_critical(); |
| 1381 | ret = rt_thread_suspend_with_flag(thread, RT_INTERRUPTIBLE); |
| 1382 | rt_timer_control(&(thread->thread_timer), |
| 1383 | RT_TIMER_CTRL_SET_TIME, |
| 1384 | &time); |
| 1385 | rt_timer_start(&(thread->thread_timer)); |
| 1386 | rt_exit_critical(); |
no test coverage detected