* Send a message. if waitok is false, thread will not be * blocked if there is no data in queue, otherwise, absolute * time will be checked. */
| 1692 | * time will be checked. |
| 1693 | */ |
| 1694 | int |
| 1695 | mqueue_send(struct mqueue *mq, const char *msg_ptr, |
| 1696 | size_t msg_len, unsigned msg_prio, int waitok, |
| 1697 | const struct timespec *abs_timeout) |
| 1698 | { |
| 1699 | struct mqueue_msg *msg; |
| 1700 | struct timespec ts, ts2; |
| 1701 | struct timeval tv; |
| 1702 | int error; |
| 1703 | |
| 1704 | if (msg_prio >= MQ_PRIO_MAX) |
| 1705 | return (EINVAL); |
| 1706 | if (msg_len > mq->mq_msgsize) |
| 1707 | return (EMSGSIZE); |
| 1708 | msg = mqueue_loadmsg(msg_ptr, msg_len, msg_prio); |
| 1709 | if (msg == NULL) |
| 1710 | return (EFAULT); |
| 1711 | |
| 1712 | /* O_NONBLOCK case */ |
| 1713 | if (!waitok) { |
| 1714 | error = _mqueue_send(mq, msg, -1); |
| 1715 | if (error) |
| 1716 | goto bad; |
| 1717 | return (0); |
| 1718 | } |
| 1719 | |
| 1720 | /* we allow a null timeout (wait forever) */ |
| 1721 | if (abs_timeout == NULL) { |
| 1722 | error = _mqueue_send(mq, msg, 0); |
| 1723 | if (error) |
| 1724 | goto bad; |
| 1725 | return (0); |
| 1726 | } |
| 1727 | |
| 1728 | /* send it before checking time */ |
| 1729 | error = _mqueue_send(mq, msg, -1); |
| 1730 | if (error == 0) |
| 1731 | return (0); |
| 1732 | |
| 1733 | if (error != EAGAIN) |
| 1734 | goto bad; |
| 1735 | |
| 1736 | if (abs_timeout->tv_nsec >= 1000000000 || abs_timeout->tv_nsec < 0) { |
| 1737 | error = EINVAL; |
| 1738 | goto bad; |
| 1739 | } |
| 1740 | for (;;) { |
| 1741 | getnanotime(&ts); |
| 1742 | timespecsub(abs_timeout, &ts, &ts2); |
| 1743 | if (ts2.tv_sec < 0 || (ts2.tv_sec == 0 && ts2.tv_nsec <= 0)) { |
| 1744 | error = ETIMEDOUT; |
| 1745 | break; |
| 1746 | } |
| 1747 | TIMESPEC_TO_TIMEVAL(&tv, &ts2); |
| 1748 | error = _mqueue_send(mq, msg, tvtohz(&tv)); |
| 1749 | if (error != ETIMEDOUT) |
| 1750 | break; |
| 1751 | } |
no test coverage detected