* Get a message. if waitok is false, thread will not be * blocked if there is no data in queue, otherwise, absolute * time will be checked. */
| 1847 | * time will be checked. |
| 1848 | */ |
| 1849 | int |
| 1850 | mqueue_receive(struct mqueue *mq, char *msg_ptr, |
| 1851 | size_t msg_len, unsigned *msg_prio, int waitok, |
| 1852 | const struct timespec *abs_timeout) |
| 1853 | { |
| 1854 | struct mqueue_msg *msg; |
| 1855 | struct timespec ts, ts2; |
| 1856 | struct timeval tv; |
| 1857 | int error; |
| 1858 | |
| 1859 | if (msg_len < mq->mq_msgsize) |
| 1860 | return (EMSGSIZE); |
| 1861 | |
| 1862 | /* O_NONBLOCK case */ |
| 1863 | if (!waitok) { |
| 1864 | error = _mqueue_recv(mq, &msg, -1); |
| 1865 | if (error) |
| 1866 | return (error); |
| 1867 | goto received; |
| 1868 | } |
| 1869 | |
| 1870 | /* we allow a null timeout (wait forever). */ |
| 1871 | if (abs_timeout == NULL) { |
| 1872 | error = _mqueue_recv(mq, &msg, 0); |
| 1873 | if (error) |
| 1874 | return (error); |
| 1875 | goto received; |
| 1876 | } |
| 1877 | |
| 1878 | /* try to get a message before checking time */ |
| 1879 | error = _mqueue_recv(mq, &msg, -1); |
| 1880 | if (error == 0) |
| 1881 | goto received; |
| 1882 | |
| 1883 | if (error != EAGAIN) |
| 1884 | return (error); |
| 1885 | |
| 1886 | if (abs_timeout->tv_nsec >= 1000000000 || abs_timeout->tv_nsec < 0) { |
| 1887 | error = EINVAL; |
| 1888 | return (error); |
| 1889 | } |
| 1890 | |
| 1891 | for (;;) { |
| 1892 | getnanotime(&ts); |
| 1893 | timespecsub(abs_timeout, &ts, &ts2); |
| 1894 | if (ts2.tv_sec < 0 || (ts2.tv_sec == 0 && ts2.tv_nsec <= 0)) { |
| 1895 | error = ETIMEDOUT; |
| 1896 | return (error); |
| 1897 | } |
| 1898 | TIMESPEC_TO_TIMEVAL(&tv, &ts2); |
| 1899 | error = _mqueue_recv(mq, &msg, tvtohz(&tv)); |
| 1900 | if (error == 0) |
| 1901 | break; |
| 1902 | if (error != ETIMEDOUT) |
| 1903 | return (error); |
| 1904 | } |
| 1905 | |
| 1906 | received: |
no test coverage detected