From 4b623d655bb4f4853a6ce385ae17e505dddbe7ce Mon Sep 17 00:00:00 2001 From: Sebastian Huber Date: Tue, 24 May 2016 07:40:18 +0200 Subject: score: Fix blocking _CORE_message_queue_Submit() Close #2718. --- cpukit/posix/src/mqueuesendsupp.c | 11 ---- cpukit/posix/src/mqueuetranslatereturncode.c | 3 +- cpukit/score/include/rtems/score/coremsgimpl.h | 4 +- cpukit/score/src/coremsgsubmit.c | 3 +- testsuites/psxtests/psxmsgq01/init.c | 77 ++++++++++++++++++++++++++ testsuites/psxtests/psxmsgq01/psxmsgq01.scn | 1 + 6 files changed, 82 insertions(+), 17 deletions(-) diff --git a/cpukit/posix/src/mqueuesendsupp.c b/cpukit/posix/src/mqueuesendsupp.c index 0d9974afe4..f13339ffa7 100644 --- a/cpukit/posix/src/mqueuesendsupp.c +++ b/cpukit/posix/src/mqueuesendsupp.c @@ -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( diff --git a/cpukit/posix/src/mqueuetranslatereturncode.c b/cpukit/posix/src/mqueuetranslatereturncode.c index 30d1c57503..901d5aaa3a 100644 --- a/cpukit/posix/src/mqueuetranslatereturncode.c +++ b/cpukit/posix/src/mqueuetranslatereturncode.c @@ -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 */ }; diff --git a/cpukit/score/include/rtems/score/coremsgimpl.h b/cpukit/score/include/rtems/score/coremsgimpl.h index 34f214da6c..395d44dafd 100644 --- a/cpukit/score/include/rtems/score/coremsgimpl.h +++ b/cpukit/score/include/rtems/score/coremsgimpl.h @@ -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. diff --git a/cpukit/score/src/coremsgsubmit.c b/cpukit/score/src/coremsgsubmit.c index 7e589e7754..91fb332e76 100644 --- a/cpukit/score/src/coremsgsubmit.c +++ b/cpukit/score/src/coremsgsubmit.c @@ -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 } diff --git a/testsuites/psxtests/psxmsgq01/init.c b/testsuites/psxtests/psxmsgq01/init.c index 0c34cd972b..3243a40c3c 100644 --- a/testsuites/psxtests/psxmsgq01/init.c +++ b/testsuites/psxtests/psxmsgq01/init.c @@ -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(); diff --git a/testsuites/psxtests/psxmsgq01/psxmsgq01.scn b/testsuites/psxtests/psxmsgq01/psxmsgq01.scn index 70da5f322e..4705bcf3a6 100644 --- a/testsuites/psxtests/psxmsgq01/psxmsgq01.scn +++ b/testsuites/psxtests/psxmsgq01/psxmsgq01.scn @@ -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) -- cgit v1.2.3