mirror of
https://gitlab.rtems.org/rtems/rtos/rtems.git
synced 2026-02-04 20:51:36 +00:00
@@ -105,17 +105,6 @@ int _POSIX_Message_queue_Send_support(
|
||||
&lock_context
|
||||
);
|
||||
|
||||
/*
|
||||
* If we had to block, then this is where the task returns
|
||||
* after it wakes up. The returned status is correct for
|
||||
* non-blocking operations but if we blocked, then we need
|
||||
* to look at the status in our TCB.
|
||||
*/
|
||||
|
||||
if ( msg_status == CORE_MESSAGE_QUEUE_STATUS_UNSATISFIED_WAIT ) {
|
||||
msg_status = executing->Wait.return_code;
|
||||
}
|
||||
|
||||
if ( msg_status != CORE_MESSAGE_QUEUE_STATUS_SUCCESSFUL ) {
|
||||
rtems_set_errno_and_return_minus_one(
|
||||
_POSIX_Message_queue_Translate_core_message_queue_return_code(
|
||||
|
||||
@@ -46,8 +46,7 @@ static
|
||||
ENOMEM, /* CORE_MESSAGE_QUEUE_STATUS_UNSATISFIED */
|
||||
EAGAIN, /* CORE_MESSAGE_QUEUE_STATUS_UNSATISFIED_NOWAIT */
|
||||
EBADF, /* CORE_MESSAGE_QUEUE_STATUS_WAS_DELETED */
|
||||
ETIMEDOUT, /* CORE_MESSAGE_QUEUE_STATUS_TIMEOUT */
|
||||
ENOSYS /* CORE_MESSAGE_QUEUE_STATUS_UNSATISFIED_WAIT */
|
||||
ETIMEDOUT /* CORE_MESSAGE_QUEUE_STATUS_TIMEOUT */
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -89,8 +89,6 @@ typedef enum {
|
||||
* to receive a message because one did not become available.
|
||||
*/
|
||||
CORE_MESSAGE_QUEUE_STATUS_TIMEOUT,
|
||||
/** This value indicates that a blocking receive was unsuccessful. */
|
||||
CORE_MESSAGE_QUEUE_STATUS_UNSATISFIED_WAIT
|
||||
} CORE_message_queue_Status;
|
||||
|
||||
/**
|
||||
@@ -98,7 +96,7 @@ typedef enum {
|
||||
*
|
||||
* This is the last status value.
|
||||
*/
|
||||
#define CORE_MESSAGE_QUEUE_STATUS_LAST CORE_MESSAGE_QUEUE_STATUS_UNSATISFIED_WAIT
|
||||
#define CORE_MESSAGE_QUEUE_STATUS_LAST CORE_MESSAGE_QUEUE_STATUS_TIMEOUT
|
||||
|
||||
/**
|
||||
* @brief Initialize a message queue.
|
||||
|
||||
@@ -133,6 +133,7 @@ CORE_message_queue_Status _CORE_message_queue_Do_submit(
|
||||
* it as a variable. Doing this emphasizes how dangerous it
|
||||
* would be to use this variable prior to here.
|
||||
*/
|
||||
executing->Wait.return_code = CORE_MESSAGE_QUEUE_STATUS_SUCCESSFUL;
|
||||
executing->Wait.return_argument_second.immutable_object = buffer;
|
||||
executing->Wait.option = (uint32_t) size;
|
||||
executing->Wait.count = submit_type;
|
||||
@@ -146,6 +147,6 @@ CORE_message_queue_Status _CORE_message_queue_Do_submit(
|
||||
CORE_MESSAGE_QUEUE_STATUS_TIMEOUT,
|
||||
lock_context
|
||||
);
|
||||
return CORE_MESSAGE_QUEUE_STATUS_UNSATISFIED_WAIT;
|
||||
return executing->Wait.return_code;
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -1259,6 +1259,82 @@ void verify_mq_send(void)
|
||||
}
|
||||
}
|
||||
|
||||
static void *receive_maxmsg_plus_one( void *arg )
|
||||
{
|
||||
mqd_t mq;
|
||||
const Test_Message_t *m;
|
||||
int i;
|
||||
|
||||
mq = Test_q[ BLOCKING ].mq;
|
||||
m = &Predefined_Msgs[ 0 ];
|
||||
|
||||
for ( i = 0; i < MAXMSG + 1; ++i ) {
|
||||
Test_Message_t a;
|
||||
unsigned prio;
|
||||
ssize_t n;
|
||||
|
||||
n = mq_receive( mq, &a.msg[0], sizeof(a.msg), &prio);
|
||||
rtems_test_assert( n == m->size );
|
||||
rtems_test_assert( prio == m->priority );
|
||||
rtems_test_assert( memcmp( &a.msg[0], &m->msg[0], (size_t) n ) == 0 );
|
||||
}
|
||||
|
||||
return arg;
|
||||
}
|
||||
|
||||
static void verify_blocking_mq_timedsend( void )
|
||||
{
|
||||
mqd_t mq;
|
||||
const Test_Message_t *m;
|
||||
int status;
|
||||
struct timespec timeout;
|
||||
pthread_t thread;
|
||||
void *exit_value;
|
||||
rtems_status_code sc;
|
||||
|
||||
Start_Test( "verify_blocking_mq_timedsend" );
|
||||
|
||||
mq = Test_q[ BLOCKING ].mq;
|
||||
m = &Predefined_Msgs[ 0 ];
|
||||
|
||||
/*
|
||||
* Create and suspend the receive thread early so that we don't overwrite the
|
||||
* ETIMEDOUT in executing->Wait.return_code. This verifies the succesful
|
||||
* mq_timedreceive() later.
|
||||
*/
|
||||
|
||||
status = pthread_create( &thread, NULL, receive_maxmsg_plus_one, &thread );
|
||||
fatal_posix_service_status( status, 0, "pthread_create" );
|
||||
|
||||
sc = rtems_task_suspend( thread );
|
||||
fatal_directive_status( sc, RTEMS_SUCCESSFUL, "rtems_task_suspend" );
|
||||
|
||||
do {
|
||||
status = clock_gettime( CLOCK_REALTIME, &timeout );
|
||||
fatal_posix_service_status( status, 0, "clock_gettime" );
|
||||
++timeout.tv_sec;
|
||||
|
||||
status = mq_timedsend( mq, m->msg, m->size , m->priority, &timeout );
|
||||
} while ( status == 0 );
|
||||
|
||||
fatal_posix_service_status_errno( status, ETIMEDOUT, "mq_timedsend");
|
||||
|
||||
sc = rtems_task_resume( thread );
|
||||
fatal_directive_status( sc, RTEMS_SUCCESSFUL, "rtems_task_restart" );
|
||||
|
||||
status = clock_gettime( CLOCK_REALTIME, &timeout );
|
||||
fatal_posix_service_status( status, 0, "clock_gettime" );
|
||||
++timeout.tv_sec;
|
||||
|
||||
status = mq_timedsend( mq, m->msg, m->size , m->priority, &timeout );
|
||||
fatal_posix_service_status( status, 0, "mq_timedsend" );
|
||||
|
||||
exit_value = NULL;
|
||||
status = pthread_join( thread, &exit_value );
|
||||
fatal_posix_service_status( status, 0, "pthread_join" );
|
||||
rtems_test_assert( exit_value == &thread );
|
||||
}
|
||||
|
||||
void *POSIX_Init(
|
||||
void *argument
|
||||
)
|
||||
@@ -1267,6 +1343,7 @@ void *POSIX_Init(
|
||||
|
||||
validate_mq_open_error_codes( );
|
||||
open_test_queues();
|
||||
verify_blocking_mq_timedsend();
|
||||
validate_mq_unlink_error_codes();
|
||||
validate_mq_close_error_codes();
|
||||
verify_unlink_functionality();
|
||||
|
||||
@@ -9,6 +9,7 @@ Init: mq_open - SUCCESSFUL
|
||||
Init: mq_open - system is out of resources (ENFILE)
|
||||
Init: mq_close and mq_unlink (mq3...mqn) - SUCCESSFUL
|
||||
Init: Open Test Queues
|
||||
_______________verify_blocking_mq_timedsend
|
||||
_______________mq_unlink errors
|
||||
Init: mq_unlink - mq_unlink with too long of a name (ENAMETOOLONG)
|
||||
Init: mq_unlink - A Queue not opened (ENOENT)
|
||||
|
||||
Reference in New Issue
Block a user