/** * @brief Sends as many bytes as possible without blocking the calling task. * * rt_mbx_send_wp atomically sends as many bytes of message @e msg as * possible to the mailbox @e mbx then returns immediately. * * @param mbx is a pointer to a user allocated mailbox structure. * * @param msg corresponds to the message to be sent. * * @param msg_size is the size of the message. * * @return On success, the number of unsent bytes is returned. On * failure a negative value is returned as described below: * - @b EINVAL: @e mbx points to an invalid mailbox. */ RTAI_SYSCALL_MODE int _rt_mbx_send_wp(MBX *mbx, void *msg, int msg_size, int space) { unsigned long flags; RT_TASK *rt_current = RT_CURRENT; int size = msg_size; CHK_MBX_MAGIC; flags = rt_global_save_flags_and_cli(); if (mbx->sndsem.count > 0 && mbx->frbs) { mbx->sndsem.count = 0; if (mbx->sndsem.type > 0) { mbx->sndsem.owndby = rt_current; enqueue_resqel(&mbx->sndsem.resq, rt_current); } rt_global_restore_flags(flags); msg_size = mbxput(mbx, (char **)(&msg), msg_size, space); mbx_signal(mbx); rt_sem_signal(&mbx->sndsem); } else { rt_global_restore_flags(flags); } if (msg_size < size) { rt_wakeup_pollers(&mbx->poll_recv, 0); } return msg_size; }
/** * @brief Sends a message with absolute timeout. * * rt_mbx_send_until sends a message @e msg of @e msg_size bytes to * the mailbox @e mbx. The caller will be blocked until all bytes of * message is enqueued, timeout expires or an error occurs. * * @param mbx is a pointer to a user allocated mailbox structure. * * @param msg is the message to be sent. * * @param msg_size corresponds to the size of the message. * * @param time is an absolute value for the timeout. * * @return On success, 0 is returned. * On failure a value is returned as described below: * - the number of bytes not received: an error is occured * in the queueing of all sending tasks or the timeout has expired. * - @b EINVAL: mbx points to an invalid mailbox. * * See also: notes under @ref _rt_mbx_send_timed(). */ RTAI_SYSCALL_MODE int _rt_mbx_send_until(MBX *mbx, void *msg, int msg_size, RTIME time, int space) { RT_TASK *rt_current = RT_CURRENT; int retval; CHK_MBX_MAGIC; if ((retval = rt_sem_wait_until(&mbx->sndsem, time)) > 1) { return MBX_RET(msg_size, retval); } while (msg_size) { if ((retval = mbx_wait_until(mbx, &mbx->frbs, time, rt_current))) { rt_sem_signal(&mbx->sndsem); retval = MBX_RET(msg_size, retval); rt_wakeup_pollers(&mbx->poll_recv, retval); return retval; } msg_size = mbxput(mbx, (char **)(&msg), msg_size, space); mbx_signal(mbx); } rt_sem_signal(&mbx->sndsem); rt_wakeup_pollers(&mbx->poll_recv, 0); return 0; }