* @brief This function will receive a mail from mailbox object, if there is no mail in mailbox 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 the set timeout. If the mail * is
| 2847 | * If the return value is any other values, it means that the mailbox release failed. |
| 2848 | */ |
| 2849 | static rt_err_t _rt_mb_recv(rt_mailbox_t mb, rt_ubase_t *value, rt_int32_t timeout, int suspend_flag) |
| 2850 | { |
| 2851 | struct rt_thread *thread; |
| 2852 | rt_base_t level; |
| 2853 | rt_uint32_t tick_delta; |
| 2854 | rt_err_t ret; |
| 2855 | |
| 2856 | /* parameter check */ |
| 2857 | RT_ASSERT(mb != RT_NULL); |
| 2858 | RT_ASSERT(rt_object_get_type(&mb->parent.parent) == RT_Object_Class_MailBox); |
| 2859 | |
| 2860 | /* current context checking */ |
| 2861 | RT_DEBUG_SCHEDULER_AVAILABLE(timeout != 0); |
| 2862 | |
| 2863 | /* initialize delta tick */ |
| 2864 | tick_delta = 0; |
| 2865 | /* get current thread */ |
| 2866 | thread = rt_thread_self(); |
| 2867 | |
| 2868 | RT_OBJECT_HOOK_CALL(rt_object_trytake_hook, (&(mb->parent.parent))); |
| 2869 | |
| 2870 | level = rt_spin_lock_irqsave(&(mb->spinlock)); |
| 2871 | |
| 2872 | /* for non-blocking call */ |
| 2873 | if (mb->entry == 0 && timeout == 0) |
| 2874 | { |
| 2875 | rt_spin_unlock_irqrestore(&(mb->spinlock), level); |
| 2876 | |
| 2877 | return -RT_ETIMEOUT; |
| 2878 | } |
| 2879 | |
| 2880 | /* mailbox is empty */ |
| 2881 | while (mb->entry == 0) |
| 2882 | { |
| 2883 | /* reset error number in thread */ |
| 2884 | thread->error = -RT_EINTR; |
| 2885 | |
| 2886 | /* no waiting, return timeout */ |
| 2887 | if (timeout == 0) |
| 2888 | { |
| 2889 | rt_spin_unlock_irqrestore(&(mb->spinlock), level); |
| 2890 | |
| 2891 | thread->error = -RT_ETIMEOUT; |
| 2892 | |
| 2893 | return -RT_ETIMEOUT; |
| 2894 | } |
| 2895 | |
| 2896 | /* suspend current thread */ |
| 2897 | ret = rt_thread_suspend_to_list(thread, &(mb->parent.suspend_thread), |
| 2898 | mb->parent.parent.flag, suspend_flag); |
| 2899 | if (ret != RT_EOK) |
| 2900 | { |
| 2901 | rt_spin_unlock_irqrestore(&(mb->spinlock), level); |
| 2902 | return ret; |
| 2903 | } |
| 2904 | |
| 2905 | /* has waiting time, start thread timer */ |
| 2906 | if (timeout > 0) |
no test coverage detected