* @brief Wait for a child process status change event * * @param[in] cur_thr Current thread context that will be suspended * @param[in] self_lwp Lightweight process (parent) waiting for the event * @param[in,out] handle Waitpid handle containing filter criteria and wait queue node * @param[in] destiny Process ID or process group to wait for (-1 for any child, -pgid for process group) * * @r
| 1458 | * event that matches the specified criteria (process ID or process group). |
| 1459 | */ |
| 1460 | static rt_err_t _wait_for_event(rt_thread_t cur_thr, rt_lwp_t self_lwp, |
| 1461 | struct waitpid_handle *handle, pid_t destiny) |
| 1462 | { |
| 1463 | rt_err_t ret; |
| 1464 | |
| 1465 | /* current context checking */ |
| 1466 | RT_DEBUG_SCHEDULER_AVAILABLE(RT_TRUE); |
| 1467 | |
| 1468 | handle->wq_node.polling_thread = cur_thr; |
| 1469 | handle->wq_node.key = destiny; |
| 1470 | handle->wq_node.wakeup = _waitq_filter; |
| 1471 | handle->wq_node.wqueue = &self_lwp->waitpid_waiters; |
| 1472 | rt_list_init(&handle->wq_node.list); |
| 1473 | |
| 1474 | cur_thr->error = RT_EOK; |
| 1475 | |
| 1476 | LOG_D("%s(self_lwp=%d) wait for event", __func__, self_lwp->pid); |
| 1477 | |
| 1478 | rt_enter_critical(); |
| 1479 | ret = rt_thread_suspend_with_flag(cur_thr, RT_INTERRUPTIBLE); |
| 1480 | if (ret == RT_EOK) |
| 1481 | { |
| 1482 | rt_wqueue_add(handle->wq_node.wqueue, &handle->wq_node); |
| 1483 | rt_exit_critical(); |
| 1484 | |
| 1485 | rt_schedule(); |
| 1486 | |
| 1487 | ret = cur_thr->error; |
| 1488 | |
| 1489 | /** |
| 1490 | * cur_thr error is a positive value, but some legacy implementation |
| 1491 | * use a negative one. So we check to avoid errors |
| 1492 | */ |
| 1493 | ret = ret > 0 ? -ret : ret; |
| 1494 | |
| 1495 | /** |
| 1496 | * we dont rely on this actually, but we cleanup it since wakeup API |
| 1497 | * set this up durint operation, and this will cause some messy condition |
| 1498 | */ |
| 1499 | handle->wq_node.wqueue->flag = RT_WQ_FLAG_CLEAN; |
| 1500 | rt_wqueue_remove(&handle->wq_node); |
| 1501 | } |
| 1502 | else |
| 1503 | { |
| 1504 | /* failed to suspend, return immediately with failure */ |
| 1505 | rt_exit_critical(); |
| 1506 | } |
| 1507 | |
| 1508 | return ret; |
| 1509 | } |
| 1510 | |
| 1511 | /** |
| 1512 | * @brief Wait for and reap a child process status change |
no test coverage detected