* @brief This function will receive a message from message queue object, * if there is no message in messagequeue object, the thread shall wait for a specified time. * * @note Only when there is mail in the mailbox, the receiving thread can get the mail immediately and return RT_EOK, * otherwise the receiving thread will be suspended until timeout. * If th
| 3762 | * If the return value is any other values, it means that the mailbox release failed. |
| 3763 | */ |
| 3764 | static rt_ssize_t _rt_mq_recv(rt_mq_t mq, |
| 3765 | void *buffer, |
| 3766 | rt_size_t size, |
| 3767 | rt_int32_t *prio, |
| 3768 | rt_int32_t timeout, |
| 3769 | int suspend_flag) |
| 3770 | { |
| 3771 | struct rt_thread *thread; |
| 3772 | rt_base_t level; |
| 3773 | struct rt_mq_message *msg; |
| 3774 | rt_uint32_t tick_delta; |
| 3775 | rt_err_t ret; |
| 3776 | rt_size_t len; |
| 3777 | |
| 3778 | RT_UNUSED(prio); |
| 3779 | |
| 3780 | /* parameter check */ |
| 3781 | RT_ASSERT(mq != RT_NULL); |
| 3782 | RT_ASSERT(rt_object_get_type(&mq->parent.parent) == RT_Object_Class_MessageQueue); |
| 3783 | RT_ASSERT(buffer != RT_NULL); |
| 3784 | RT_ASSERT(size != 0); |
| 3785 | |
| 3786 | /* current context checking */ |
| 3787 | RT_DEBUG_SCHEDULER_AVAILABLE(timeout != 0); |
| 3788 | |
| 3789 | /* initialize delta tick */ |
| 3790 | tick_delta = 0; |
| 3791 | /* get current thread */ |
| 3792 | thread = rt_thread_self(); |
| 3793 | RT_OBJECT_HOOK_CALL(rt_object_trytake_hook, (&(mq->parent.parent))); |
| 3794 | |
| 3795 | level = rt_spin_lock_irqsave(&(mq->spinlock)); |
| 3796 | |
| 3797 | /* for non-blocking call */ |
| 3798 | if (mq->entry == 0 && timeout == 0) |
| 3799 | { |
| 3800 | rt_spin_unlock_irqrestore(&(mq->spinlock), level); |
| 3801 | |
| 3802 | return -RT_ETIMEOUT; |
| 3803 | } |
| 3804 | |
| 3805 | /* message queue is empty */ |
| 3806 | while (mq->entry == 0) |
| 3807 | { |
| 3808 | /* reset error number in thread */ |
| 3809 | thread->error = -RT_EINTR; |
| 3810 | |
| 3811 | /* no waiting, return timeout */ |
| 3812 | if (timeout == 0) |
| 3813 | { |
| 3814 | /* enable interrupt */ |
| 3815 | rt_spin_unlock_irqrestore(&(mq->spinlock), level); |
| 3816 | |
| 3817 | thread->error = -RT_ETIMEOUT; |
| 3818 | |
| 3819 | return -RT_ETIMEOUT; |
| 3820 | } |
| 3821 |
no test coverage detected