Changeset 53fb837a in rtems


Ignore:
Timestamp:
Jan 13, 2000, 7:25:15 PM (21 years ago)
Author:
Joel Sherrill <joel.sherrill@…>
Branches:
4.10, 4.11, 4.8, 4.9, 5, master
Children:
85d62357
Parents:
ee4ddd83
Message:

POSIX message queues now include complete functionality including
blocking sends when the queue is full. The SuperCore? was enhanced
to support blocking on send. The existing POSIX API was debugged
and numerous test cases were added to psxmsgq01 by Jennifer Averett.
SuperCore? enhancements and resulting modifications to other APIs
were done by Joel.

There is one significant point of interpretation for the POSIX API.
What happens to threads already blocked on a message queue when the
mode of that same message queue is changed from blocking to non-blocking?
We decided to unblock all waiting tasks with an EAGAIN error just
as if a non-blocking version of the same operation had returned
unsatisfied. This case is not discussed in the POSIX standard and
other implementations may have chosen differently.

Files:
28 edited

Legend:

Unmodified
Added
Removed
  • c/src/exec/itron/src/cre_mbf.c

    ree4ddd83 r53fb837a  
    2626)
    2727{
    28   CORE_message_queue_Attributes   the_message_queue_attributes;
     28  CORE_message_queue_Attributes    the_msgq_attributes;
    2929  ITRON_Message_buffer_Control    *the_message_buffer;
    3030
     
    5858
    5959  if ( pk_cmbf->mbfatr & TA_TPRI )
    60     the_message_queue_attributes.discipline =
    61         CORE_MESSAGE_QUEUE_DISCIPLINES_PRIORITY;
     60    the_msgq_attributes.discipline = CORE_MESSAGE_QUEUE_DISCIPLINES_PRIORITY;
    6261  else
    63     the_message_queue_attributes.discipline =
    64         CORE_MESSAGE_QUEUE_DISCIPLINES_FIFO;
     62    the_msgq_attributes.discipline = CORE_MESSAGE_QUEUE_DISCIPLINES_FIFO;
    6563
    6664  _CORE_message_queue_Initialize(
    6765    &the_message_buffer->message_queue,
    6866    OBJECTS_ITRON_MESSAGE_BUFFERS,
    69     &the_message_queue_attributes,
     67    &the_msgq_attributes,
    7068    pk_cmbf->bufsz / pk_cmbf->maxmsz,
    7169    pk_cmbf->maxmsz,
  • c/src/exec/itron/src/snd_mbx.c

    ree4ddd83 r53fb837a  
    2828  register ITRON_Mailbox_Control *the_mailbox;
    2929  Objects_Locations                location;
    30   CORE_message_queue_Status        status = E_OK;
    3130  unsigned32                       message_priority;
    3231  void                            *message_contents;
     
    4847
    4948      message_contents = pk_msg;
    50       status = _CORE_message_queue_Submit(
     49      _CORE_message_queue_Submit(
    5150        &the_mailbox->message_queue,
    5251        &message_contents,
     
    5453        the_mailbox->Object.id,
    5554        NULL,          /* multiprocessing not supported */
    56         message_priority
     55        message_priority,
     56        FALSE,     /* do not allow sender to block */
     57        0          /* no timeout */
    5758     );
    5859     break;
     
    6061
    6162  _ITRON_return_errorno(
    62      _ITRON_Mailbox_Translate_core_message_queue_return_code(status) );
     63     _ITRON_Mailbox_Translate_core_message_queue_return_code(
     64          _Thread_Executing->Wait.return_code
     65     )
     66  );
    6367}
  • c/src/exec/itron/src/trcv_mbf.c

    ree4ddd83 r53fb837a  
    3333  boolean                         wait;
    3434  Watchdog_Interval               interval;
    35   CORE_message_queue_Submit_types core_priority;
    3635
    3736  interval = 0;
     
    6362          p_msgsz,
    6463          wait,
    65           &core_priority,
    6664          interval
    6765      );
  • c/src/exec/itron/src/tsnd_mbf.c

    ree4ddd83 r53fb837a  
    3434  Watchdog_Interval              interval;
    3535  boolean                        wait;
    36   CORE_message_queue_Status      status;
    3736
    3837  if (msgsz <= 0 || !msg)
     
    5150    return E_CTX;
    5251
    53   assert( wait == FALSE );
    54 
    5552  the_message_buffer = _ITRON_Message_buffer_Get(mbfid, &location);
    5653  switch (location) {
     
    6158    case OBJECTS_LOCAL:
    6259      /* XXX Submit needs to take into account blocking */
    63       status = _CORE_message_queue_Submit(
     60      _CORE_message_queue_Submit(
    6461        &the_message_buffer->message_queue,
    6562        msg,
     
    6764        the_message_buffer->Object.id,
    6865        NULL,
    69         CORE_MESSAGE_QUEUE_SEND_REQUEST
     66        CORE_MESSAGE_QUEUE_SEND_REQUEST,
     67        wait,      /* sender may block */
     68        interval   /* timeout interval */
    7069      );
    7170      _Thread_Enable_dispatch();
    72       return
    73         _ITRON_Message_buffer_Translate_core_message_buffer_return_code(status);
     71      return _ITRON_Message_buffer_Translate_core_message_buffer_return_code(
     72          _Thread_Executing->Wait.return_code
     73      );
    7474    }
    7575
  • c/src/exec/posix/include/rtems/posix/mqueue.h

    ree4ddd83 r53fb837a  
    3333   Objects_Control             Object;
    3434   int                         process_shared;
    35    int                         flags;
    3635   boolean                     named;
    3736   boolean                     linked;
    38    boolean                     blocking;
    3937   int                         oflag;
    4038   unsigned32                  open_count;
  • c/src/exec/rtems/src/msgqcreate.c

    ree4ddd83 r53fb837a  
    6060{
    6161  register Message_queue_Control *the_message_queue;
    62   CORE_message_queue_Attributes   the_message_queue_attributes;
     62  CORE_message_queue_Attributes   the_msgq_attributes;
    6363  void                           *handler;
    6464#if defined(RTEMS_MULTIPROCESSING)
     
    7575#endif
    7676
    77   if (count == 0)
     77  if ( count == 0 )
    7878      return RTEMS_INVALID_NUMBER;
    7979
    80   if (max_message_size == 0)
     80  if ( max_message_size == 0 )
    8181      return RTEMS_INVALID_SIZE;
    8282
     
    116116
    117117  if (_Attributes_Is_priority( attribute_set ) )
    118     the_message_queue_attributes.discipline =
    119                                       CORE_MESSAGE_QUEUE_DISCIPLINES_PRIORITY;
     118    the_msgq_attributes.discipline = CORE_MESSAGE_QUEUE_DISCIPLINES_PRIORITY;
    120119  else
    121     the_message_queue_attributes.discipline =
    122                                       CORE_MESSAGE_QUEUE_DISCIPLINES_FIFO;
     120    the_msgq_attributes.discipline = CORE_MESSAGE_QUEUE_DISCIPLINES_FIFO;
    123121
    124122  handler = NULL;
     
    130128           &the_message_queue->message_queue,
    131129           OBJECTS_RTEMS_MESSAGE_QUEUES,
    132            &the_message_queue_attributes,
     130           &the_msgq_attributes,
    133131           count,
    134132           max_message_size,
  • c/src/exec/rtems/src/msgqreceive.c

    ree4ddd83 r53fb837a  
    9393        size,
    9494        wait,
    95         &core_priority,
    9695        timeout
    9796      );
    9897      _Thread_Enable_dispatch();
    99       return( _Message_queue_Translate_core_message_queue_return_code(
    100                   _Thread_Executing->Wait.return_code ) );
     98      return _Message_queue_Translate_core_message_queue_return_code(
     99        _Thread_Executing->Wait.return_code
     100      );
    101101
    102102  }
  • c/src/exec/rtems/src/msgqsubmit.c

    ree4ddd83 r53fb837a  
    6262  register Message_queue_Control  *the_message_queue;
    6363  Objects_Locations                location;
    64   CORE_message_queue_Status        core_status;
    6564
    6665  the_message_queue = _Message_queue_Get( id, &location );
     
    9998      switch ( submit_type ) {
    10099        case MESSAGE_QUEUE_SEND_REQUEST:
    101           core_status = _CORE_message_queue_Send(
    102                           &the_message_queue->message_queue,
    103                           buffer,
    104                           size,
    105                           id,
     100          _CORE_message_queue_Send(
     101            &the_message_queue->message_queue,
     102            buffer,
     103            size,
     104            id,
    106105#if defined(RTEMS_MULTIPROCESSING)
    107                           _Message_queue_Core_message_queue_mp_support
     106            _Message_queue_Core_message_queue_mp_support,
    108107#else
    109                           NULL
     108            NULL,
    110109#endif
    111                         );
     110            FALSE,   /* sender does not block */
     111            0        /* no timeout */
     112          );
    112113          break;
    113114        case MESSAGE_QUEUE_URGENT_REQUEST:
    114           core_status = _CORE_message_queue_Urgent(
    115                           &the_message_queue->message_queue,
    116                           buffer,
    117                           size,
    118                           id,
     115          _CORE_message_queue_Urgent(
     116            &the_message_queue->message_queue,
     117            buffer,
     118            size,
     119            id,
    119120#if defined(RTEMS_MULTIPROCESSING)
    120                           _Message_queue_Core_message_queue_mp_support
     121            _Message_queue_Core_message_queue_mp_support,
    121122#else
    122                           NULL
     123            NULL,
    123124#endif
    124                         );
     125            FALSE,   /* sender does not block */
     126            0        /* no timeout */
     127          );
    125128          break;
    126129        default:
    127           core_status = CORE_MESSAGE_QUEUE_STATUS_SUCCESSFUL;
    128130          return RTEMS_INTERNAL_ERROR;   /* should never get here */
    129131      }
     
    131133      _Thread_Enable_dispatch();
    132134      return _Message_queue_Translate_core_message_queue_return_code(
    133                 core_status );
     135        _Thread_Executing->Wait.return_code
     136      );
    134137         
    135138  }
  • c/src/exec/score/include/rtems/score/coremsg.h

    ree4ddd83 r53fb837a  
    167167
    168168/*
    169  *
    170169 *  _CORE_message_queue_Flush
    171170 *
    172171 *  DESCRIPTION:
    173172 *
    174  *  This function flushes the message_queue's task wait queue.  The number
    175  *  messages flushed from the queue is returned.
     173 *  This function flushes the message_queue's pending message queue.  The
     174 *  number of messages flushed from the queue is returned.
    176175 *
    177176 */
     
    195194 
    196195/*
    197  *
     196 *  _CORE_message_queue_Flush_waiting_threads
     197 *
     198 *  DESCRIPTION:
     199 *
     200 *  This function flushes the threads which are blocked on this
     201 *  message_queue's pending message queue.  They are unblocked whether
     202 *  blocked sending or receiving.
     203 */
     204
     205void _CORE_message_queue_Flush_waiting_threads(
     206  CORE_message_queue_Control *the_message_queue
     207);
     208
     209/*
    198210 *  _CORE_message_queue_Broadcast
    199211 *
     
    215227
    216228/*
    217  *
    218229 *  _CORE_message_queue_Submit
    219230 *
     
    229240 */
    230241 
    231 CORE_message_queue_Status _CORE_message_queue_Submit(
     242void _CORE_message_queue_Submit(
    232243  CORE_message_queue_Control                *the_message_queue,
    233244  void                                      *buffer,
     
    235246  Objects_Id                                 id,
    236247  CORE_message_queue_API_mp_support_callout  api_message_queue_mp_support,
    237   CORE_message_queue_Submit_types            submit_type
    238 );
    239 
    240 /*
    241  *
     248  CORE_message_queue_Submit_types            submit_type,
     249  boolean                                    wait,
     250  Watchdog_Interval                          timeout
     251);
     252
     253/*
    242254 *  _CORE_message_queue_Seize
    243255 *
     
    249261 *  otherwise an error will be given to the thread if no messages are available.
    250262 *
     263 *  NOTE: Returns message priority via return are in TCB.
    251264 */
    252265 
     
    257270  unsigned32                      *size,
    258271  boolean                          wait,
    259   CORE_message_queue_Submit_types *priority,
    260272  Watchdog_Interval                timeout
     273);
     274
     275/*
     276 *  _CORE_message_queue_Insert_message
     277 *
     278 *  DESCRIPTION:
     279 *
     280 *  This kernel routine inserts the specified message into the
     281 *  message queue.  It is assumed that the message has been filled
     282 *  in before this routine is called.
     283 */
     284
     285void _CORE_message_queue_Insert_message(
     286  CORE_message_queue_Control        *the_message_queue,
     287  CORE_message_queue_Buffer_control *the_message,
     288  CORE_message_queue_Submit_types    submit_type
    261289);
    262290
  • c/src/exec/score/inline/rtems/score/coremsg.inl

    ree4ddd83 r53fb837a  
    2828 */
    2929 
    30 RTEMS_INLINE_ROUTINE CORE_message_queue_Status _CORE_message_queue_Send(
     30RTEMS_INLINE_ROUTINE void _CORE_message_queue_Send(
    3131  CORE_message_queue_Control                *the_message_queue,
    3232  void                                      *buffer,
    3333  unsigned32                                 size,
    3434  Objects_Id                                 id,
    35   CORE_message_queue_API_mp_support_callout  api_message_queue_mp_support
    36 )
    37 {
    38   return _CORE_message_queue_Submit(
     35  CORE_message_queue_API_mp_support_callout  api_message_queue_mp_support,
     36  boolean                                    wait,
     37  Watchdog_Interval                          timeout
     38)
     39{
     40  _CORE_message_queue_Submit(
    3941    the_message_queue,
    4042    buffer,
     
    4648    NULL,
    4749#endif
    48     CORE_MESSAGE_QUEUE_SEND_REQUEST
     50    CORE_MESSAGE_QUEUE_SEND_REQUEST,
     51    wait,     /* sender may block */
     52    timeout   /* timeout interval */
    4953  );
    5054}
     
    5963 */
    6064 
    61 RTEMS_INLINE_ROUTINE CORE_message_queue_Status _CORE_message_queue_Urgent(
     65RTEMS_INLINE_ROUTINE void _CORE_message_queue_Urgent(
    6266  CORE_message_queue_Control                *the_message_queue,
    6367  void                                      *buffer,
    6468  unsigned32                                 size,
    6569  Objects_Id                                 id,
    66   CORE_message_queue_API_mp_support_callout  api_message_queue_mp_support
    67 )
    68 {
    69   return _CORE_message_queue_Submit(
     70  CORE_message_queue_API_mp_support_callout  api_message_queue_mp_support,
     71  boolean                                    wait,
     72  Watchdog_Interval                          timeout
     73)
     74{
     75  _CORE_message_queue_Submit(
    7076    the_message_queue,
    7177    buffer,
     
    7783    NULL,
    7884#endif
    79     CORE_MESSAGE_QUEUE_URGENT_REQUEST
     85    CORE_MESSAGE_QUEUE_URGENT_REQUEST,
     86    wait,     /* sender may block */
     87    timeout   /* timeout interval */
    8088 );
    8189}
  • c/src/exec/score/macros/rtems/score/coremsg.inl

    ree4ddd83 r53fb837a  
    2424 
    2525#define _CORE_message_queue_Send( _the_message_queue, _buffer, _size, \
    26 _id, _api_message_queue_mp_support ) \
     26       _id, _api_message_queue_mp_support, _wait, _timeout ) \
    2727  _CORE_message_queue_Submit( (_the_message_queue), (_buffer), (_size), \
    28      (_id), (_api_message_queue_mp_support), CORE_MESSAGE_QUEUE_SEND_REQUEST )
     28     (_id), (_api_message_queue_mp_support), \
     29     CORE_MESSAGE_QUEUE_SEND_REQUEST, (_wait), (_timeout)
    2930 
    3031/*PAGE
     
    3536 
    3637#define _CORE_message_queue_Urgent( _the_message_queue, _buffer, _size, \
    37 _id, _api_message_queue_mp_support ) \
     38       _id, _api_message_queue_mp_support, _wait, _timeout ) \
    3839  _CORE_message_queue_Submit( (_the_message_queue), (_buffer), (_size), \
    39      (_id), (_api_message_queue_mp_support), CORE_MESSAGE_QUEUE_URGENT_REQUEST )
     40     (_id), (_api_message_queue_mp_support), \
     41     CORE_MESSAGE_QUEUE_URGENT_REQUEST, (_wait), (_timeout)
    4042
    4143/*PAGE
  • c/src/exec/score/src/coremsgbroadcast.c

    ree4ddd83 r53fb837a  
    6565  unsigned32               constrained_size;
    6666
     67  /*
     68   *  If there are pending messages, then there can't be threads
     69   *  waiting for us to send them a message.
     70   *
     71   *  NOTE: This check is critical because threads can block on
     72   *        send and receive and this ensures that we are broadcasting
     73   *        the message to threads waiting to receive -- not to send.
     74   */
     75
     76  if ( the_message_queue->number_of_pending_messages != 0 ) {
     77    *count = 0;
     78    return CORE_MESSAGE_QUEUE_STATUS_SUCCESSFUL;
     79  }
     80
     81  /*
     82   *  There must be no pending messages if there is a thread waiting to
     83   *  receive a message.
     84   */
     85
    6786  number_broadcasted = 0;
    6887  while ((the_thread = _Thread_queue_Dequeue(&the_message_queue->Wait_queue))) {
  • c/src/exec/score/src/coremsgsubmit.c

    ree4ddd83 r53fb837a  
    5454 */
    5555
    56 CORE_message_queue_Status _CORE_message_queue_Submit(
     56void _CORE_message_queue_Submit(
    5757  CORE_message_queue_Control                *the_message_queue,
    5858  void                                      *buffer,
     
    6060  Objects_Id                                 id,
    6161  CORE_message_queue_API_mp_support_callout  api_message_queue_mp_support,
    62   CORE_message_queue_Submit_types            submit_type
     62  CORE_message_queue_Submit_types            submit_type,
     63  boolean                                    wait,
     64  Watchdog_Interval                          timeout
    6365)
    6466{
     67  ISR_Level                            level;
    6568  CORE_message_queue_Buffer_control   *the_message;
    6669  Thread_Control                      *the_thread;
     70  Thread_Control                      *executing;
    6771
    68   if ( size > the_message_queue->maximum_message_size )
    69     return CORE_MESSAGE_QUEUE_STATUS_INVALID_SIZE;
     72  _Thread_Executing->Wait.return_code = CORE_MESSAGE_QUEUE_STATUS_SUCCESSFUL;
    7073
    71   /*
    72    * Is there a thread currently waiting on this message queue?
    73    */
    74      
    75   the_thread = _Thread_queue_Dequeue( &the_message_queue->Wait_queue );
    76   if ( the_thread ) {
    77     _CORE_message_queue_Copy_buffer(
    78       buffer,
    79       the_thread->Wait.return_argument,
    80       size
    81     );
    82     *(unsigned32 *)the_thread->Wait.return_argument_1 = size;
    83     the_thread->Wait.count = submit_type;
    84    
    85 #if defined(RTEMS_MULTIPROCESSING)
    86     if ( !_Objects_Is_local_id( the_thread->Object.id ) )
    87       (*api_message_queue_mp_support) ( the_thread, id );
    88 #endif
    89 
    90     return CORE_MESSAGE_QUEUE_STATUS_SUCCESSFUL;
     74  if ( size > the_message_queue->maximum_message_size ) {
     75    _Thread_Executing->Wait.return_code =
     76       CORE_MESSAGE_QUEUE_STATUS_INVALID_SIZE;
     77    return;
    9178  }
    9279
    9380  /*
    94    * No one waiting on this one currently.
    95    * Allocate a message buffer and store it away
     81   *  Is there a thread currently waiting on this message queue?
    9682   */
    97 
    98   if ( the_message_queue->number_of_pending_messages ==
    99        the_message_queue->maximum_pending_messages ) {
    100     return CORE_MESSAGE_QUEUE_STATUS_TOO_MANY;
    101   }
    102 
    103   the_message = _CORE_message_queue_Allocate_message_buffer(the_message_queue);
    104   if ( the_message == 0 )
    105     return CORE_MESSAGE_QUEUE_STATUS_UNSATISFIED;
    106 
    107   _CORE_message_queue_Copy_buffer( buffer, the_message->Contents.buffer, size );
    108   the_message->Contents.size = size;
    109   the_message->priority  = submit_type;
    110 
    111   the_message_queue->number_of_pending_messages += 1;
    112 
    113   switch ( submit_type ) {
    114     case CORE_MESSAGE_QUEUE_SEND_REQUEST:
    115       _CORE_message_queue_Append( the_message_queue, the_message );
    116       break;
    117     case CORE_MESSAGE_QUEUE_URGENT_REQUEST:
    118       _CORE_message_queue_Prepend( the_message_queue, the_message );
    119       break;
    120     default:
    121       /* XXX interrupt critical section needs to be addressed */
    122       {
    123         CORE_message_queue_Buffer_control *this_message;
    124         Chain_Node                        *the_node;
    125 
    126         the_message->priority = submit_type;
    127         for ( the_node = the_message_queue->Pending_messages.first ;
    128            !_Chain_Is_tail( &the_message_queue->Pending_messages, the_node ) ;
    129            the_node = the_node->next ) {
    130 
    131           this_message = (CORE_message_queue_Buffer_control *) the_node;
    132 
    133           if ( this_message->priority >= the_message->priority )
    134             continue;
    135 
    136           _Chain_Insert( the_node, &the_message->Node );
    137           break;
    138         }
    139       }
    140       break;
     83     
     84  if ( the_message_queue->number_of_pending_messages == 0 ) {
     85    the_thread = _Thread_queue_Dequeue( &the_message_queue->Wait_queue );
     86    if ( the_thread ) {
     87      _CORE_message_queue_Copy_buffer(
     88        buffer,
     89        the_thread->Wait.return_argument,
     90        size
     91      );
     92      *(unsigned32 *)the_thread->Wait.return_argument_1 = size;
     93      the_thread->Wait.count = submit_type;
     94   
     95#if defined(RTEMS_MULTIPROCESSING)
     96      if ( !_Objects_Is_local_id( the_thread->Object.id ) )
     97        (*api_message_queue_mp_support) ( the_thread, id );
     98#endif
     99      return;
     100    }
    141101  }
    142102
    143103  /*
    144    *  According to POSIX, does this happen before or after the message
    145    *  is actually enqueued.  It is logical to think afterwards, because
    146    *  the message is actually in the queue at this point.
     104   *  No one waiting on the message queue at this time, so attempt to
     105   *  queue the message up for a future receive.
    147106   */
    148107
    149   if ( the_message_queue->number_of_pending_messages == 1 &&
    150        the_message_queue->notify_handler )
    151     (*the_message_queue->notify_handler)( the_message_queue->notify_argument );
    152  
    153   return CORE_MESSAGE_QUEUE_STATUS_SUCCESSFUL;
     108  if ( the_message_queue->number_of_pending_messages <
     109       the_message_queue->maximum_pending_messages ) {
     110
     111    the_message =
     112        _CORE_message_queue_Allocate_message_buffer( the_message_queue );
     113
     114    /*
     115     *  NOTE: If the system is consistent, this error should never occur.
     116     */
     117    if ( !the_message ) {
     118      _Thread_Executing->Wait.return_code =
     119          CORE_MESSAGE_QUEUE_STATUS_UNSATISFIED;
     120      return;
     121    }
     122
     123    _CORE_message_queue_Copy_buffer(
     124      buffer,
     125      the_message->Contents.buffer,
     126      size
     127    );
     128    the_message->Contents.size = size;
     129    the_message->priority  = submit_type;
     130
     131    _CORE_message_queue_Insert_message(
     132       the_message_queue,
     133       the_message,
     134       submit_type
     135    );
     136    return;
     137  }
     138
     139  /*
     140   *  No message buffers were available so we may need to return an
     141   *  overflow error or block the sender until the message is placed
     142   *  on the queue.
     143   */
     144
     145  if ( !wait ) {
     146    _Thread_Executing->Wait.return_code = CORE_MESSAGE_QUEUE_STATUS_TOO_MANY;
     147    return;
     148  }
     149
     150  executing = _Thread_Executing;
     151
     152  _ISR_Disable( level );
     153  _Thread_queue_Enter_critical_section( &the_message_queue->Wait_queue );
     154  executing->Wait.queue              = &the_message_queue->Wait_queue;
     155  executing->Wait.id                 = id;
     156  executing->Wait.return_argument    = (void *)buffer;
     157  executing->Wait.return_argument_1  = (void *)size;
     158  executing->Wait.count              = submit_type;
     159  _ISR_Enable( level );
     160
     161  _Thread_queue_Enqueue( &the_message_queue->Wait_queue, timeout );
    154162}
  • c/src/tests/psxtests/psxmsgq01/init.c

    ree4ddd83 r53fb837a  
    1616#include <time.h>
    1717#include <tmacros.h>
     18#include <signal.h>   /* signal facilities */
     19
     20typedef struct {
     21  char         msg[ 50 ];
     22  int          size;
     23  unsigned int priority;
     24}Test_Message_t;
     25Test_Message_t Predefined_Msgs[MAXMSG+1];
     26Test_Message_t Predefined_Msgs[MAXMSG+1] = {
     27  { "12345678",   9, MQ_PRIO_MAX-1 },  /* Max Length Message med  */
     28  { "",           1, 1             },  /* NULL  Message      low  */
     29  { "Last",       5, MQ_PRIO_MAX   },  /* Queue Full Message hi   */ 
     30  { "No Message", 0, MQ_PRIO_MAX-1 },  /* 0 length Message   med  */
     31  { "1",          2, 0             },  /* Cause Overflow Behavior */
     32};
     33int Priority_Order[MAXMSG+1] = { 2, 0, 3, 1, MAXMSG };
     34
     35
     36typedef struct {
     37  mqd_t              mq;
     38  Test_Queue_Types   index;
     39  char              *name;
     40  int                oflag;
     41  int                maxmsg;
     42  int                msgsize;
     43  int                count;
     44} Test_queue_type;
     45
     46Test_queue_type Test_q[ NUMBER_OF_TEST_QUEUES ] =
     47{
     48  { 0, 0, "Qread",    ( O_CREAT | O_RDONLY | O_NONBLOCK ), MAXMSG, MSGSIZE, 0 },
     49  { 0, 1, "Qwrite",   ( O_CREAT | O_WRONLY | O_NONBLOCK ), MAXMSG, MSGSIZE, 0 },
     50  { 0, 2, "Qnoblock", ( O_CREAT | O_RDWR   | O_NONBLOCK ), MAXMSG, MSGSIZE, 0 },
     51  { 0, 3, "Qblock",   ( O_CREAT | O_RDWR )               , MAXMSG, MSGSIZE, 0 },
     52  { 0, 4, "Qdefault", ( O_CREAT | O_RDWR )               , 10,     16,      0 },
     53  { 0, 5, "mq6",      ( O_CREAT | O_WRONLY | O_NONBLOCK ), MAXMSG, MSGSIZE, 0 },
     54};
     55
     56#define RW_NAME             Test_q[ RW_QUEUE ].name
     57#define DEFAULT_NAME        Test_q[ DEFAULT_RW ].name
     58#define RD_NAME             Test_q[ RD_QUEUE ].name
     59#define WR_NAME             Test_q[ WR_QUEUE ].name
     60#define BLOCKING_NAME       Test_q[ BLOCKING ].name
     61#define CLOSED_NAME         Test_q[ CLOSED ].name
     62
     63#define RW_ATTR         Test_q[ RW_QUEUE ].oflag
     64#define DEFAULT_ATTR    Test_q[ DEFAULT_RW ].oflag
     65#define RD_ATTR         Test_q[ RD_QUEUE ].oflag
     66#define WR_ATTR         Test_q[ WR_QUEUE ].oflag
     67#define BLOCK_ATTR      Test_q[ BLOCKING ].oflag
     68#define CLOSED_ATTR     Test_q[ CLOSED ].oflag
     69
     70/*
     71 * Outputs a header at each test section.
     72 */
     73void Start_Test(
     74  char *description
     75)
     76{
     77  printf( "_______________%s\n", description );
     78}
     79
     80
     81void Validate_attributes(
     82    mqd_t  mq,
     83    int    oflag,
     84    int    msg_count
     85)
     86{
     87  int             status;
     88  struct mq_attr  attr;
     89
     90  status = mq_getattr( mq, &attr );
     91  fatal_posix_service_status( status, 0, "mq_getattr valid return status");
     92 
     93  if ( mq != Test_q[ DEFAULT_RW ].mq ){
     94    fatal_int_service_status((int)attr.mq_maxmsg, MAXMSG, "maxmsg attribute" );
     95    fatal_int_service_status((int)attr.mq_msgsize,MSGSIZE,"msgsize attribute");
     96  }
     97
     98  fatal_int_service_status((int)attr.mq_curmsgs, msg_count, "count attribute" );
     99  fatal_int_service_status((int)attr.mq_flags, oflag, "flag attribute" );
     100}
    18101
    19102char Queue_Name[PATH_MAX + 2];
    20 char *Get_Queue_Name(
    21   int i
    22 )
    23 {
    24   sprintf(Queue_Name,"mq%d",i+1);
     103#define Get_Queue_Name( i )  Test_q[i].name
     104
     105char *Build_Queue_Name( int i ) {
     106  sprintf(Queue_Name,"mq%d", i+1 );
    25107  return Queue_Name;
    26108}
     
    36118}
    37119
    38 typedef enum {
    39   DEFAULT_SIZE_TYPE,
    40   TEST_SIZE_TYPE,
    41   MAX_SIZE,
    42   TYPES_OF_TEST_SIZES
    43 } TEST_MQ_SIZE_TYPES;
    44 
     120
     121void open_test_queues()
     122{
     123  struct mq_attr   attr;
     124  int              status;
     125  Test_queue_type *tq;
     126  int              que;
     127
     128  attr.mq_maxmsg  = MAXMSG;
     129  attr.mq_msgsize = MSGSIZE;
     130
     131  puts( "Init: Open Test Queues" );
     132
     133  for( que = 0; que < NUMBER_OF_TEST_QUEUES; que++ ) {
     134
     135    tq = &Test_q[ que ];
     136    if ( que == DEFAULT_RW)
     137      Test_q[que].mq = mq_open( tq->name, tq->oflag, 0x777, NULL );
     138    else
     139      Test_q[que].mq = mq_open( tq->name, tq->oflag, 0x777, &attr );
     140
     141    assert( Test_q[que].mq != (-1) );
     142  }
     143
     144  status = mq_close( Test_q[CLOSED].mq );
     145  fatal_posix_service_status( status, 0, "mq_close message queue");
     146  status = mq_unlink( CLOSED_NAME );
     147  fatal_posix_service_status( status, 0, "mq_unlink message queue");
     148}
    45149
    46150/*
     
    49153 */
    50154
    51 void validate_mq_open_error_codes(
    52   mqd_t   *mqs,      /* Must be large enough for Maximum to be opened. */
    53   int      size
    54 )
     155void validate_mq_open_error_codes()
    55156{
    56157  int             i;
     
    58159  struct mq_attr  attr;
    59160  int             status;
    60 
    61   assert( size < (CONFIGURE_MAXIMUM_POSIX_MESSAGE_QUEUES-1) );
    62 
    63   /*
    64    * Validate mq_open errors that can occur when no queues are open.
    65    *  EINVAL
    66    *  ENOENT
    67    *  EINTR
    68    */
     161  mqd_t           open_mq[CONFIGURE_MAXIMUM_POSIX_MESSAGE_QUEUES];
     162
     163  attr.mq_maxmsg  = MAXMSG;
     164  attr.mq_msgsize = MSGSIZE;
     165
     166  Start_Test( "mq_open errors" );
    69167
    70168  /*
     
    72170   */
    73171
     172  /*
     173   * EINVAL - Create with negative maxmsg.
     174   */
     175
    74176  attr.mq_maxmsg = -1;
    75   puts( "mq_open - Create with maxmsg (-1) (EINVAL)" );
    76   n_mq2 = mq_open("mq2", O_CREAT | O_RDONLY, 0x777, &attr);
    77   fatal_directive_status(
     177  puts( "Init: mq_open - Create with maxmsg (-1) (EINVAL)" );
     178  n_mq2 = mq_open( "mq2", O_CREAT | O_RDONLY, 0x777, &attr);
     179  fatal_posix_service_status(
    78180    (int) n_mq2, (int ) (-1), "mq_open error return status" );
    79   fatal_directive_status( errno, EINVAL,  "mq_open errno EINVAL");
     181  fatal_posix_service_status( errno, EINVAL,  "mq_open errno EINVAL");
     182  attr.mq_maxmsg  = MAXMSG;
     183
     184  /*
     185   * EINVAL - Create withnegative msgsize.
     186   */
    80187
    81188  attr.mq_msgsize = -1;
    82   puts( "mq_open - Create with msgsize (-1) (EINVAL)" );
    83   n_mq2 = mq_open("mq2", O_CREAT | O_RDONLY, 0x777, &attr);
    84   fatal_directive_status(
     189  puts( "Init: mq_open - Create with msgsize (-1) (EINVAL)" );
     190  n_mq2 = mq_open( "mq2", O_CREAT | O_RDONLY, 0x777, &attr);
     191  fatal_posix_service_status(
    85192    (int) n_mq2, (int ) (-1), "mq_open error return status" );
    86   fatal_directive_status( errno, EINVAL,  "mq_open errno EINVAL");
    87 
    88   puts( "mq_open - Open new mq without create flag (ENOENT)" );
    89   n_mq2 = mq_open("mq3", O_EXCL | O_RDONLY, 0x777, NULL);
    90   fatal_directive_status(
     193  fatal_posix_service_status( errno, EINVAL,  "mq_open errno EINVAL");
     194  attr.mq_msgsize = MSGSIZE;
     195
     196  /*
     197   * ENOENT - Open a non-created file.
     198   */
     199
     200  puts( "Init: mq_open - Open new mq without create flag (ENOENT)" );
     201  n_mq2 = mq_open( "mq3", O_EXCL | O_RDONLY, 0x777, NULL);
     202  fatal_posix_service_status(
    91203    (int) n_mq2, (int ) (-1), "mq_open error return status" );
    92   fatal_directive_status( errno, ENOENT,  "mq_open errno ENOENT");
     204  fatal_posix_service_status( errno, ENOENT,  "mq_open errno ENOENT");
     205
    93206
    94207  /*
     
    97210
    98211  /*
    99    * XXX ENAMETOOLONG - Not checked in either sem_open or mq_open is
    100    *                    this an error?
    101    */
    102 
    103   puts( "mq_open - Open with too long of a name (ENAMETOOLONG)" );
     212   * ENAMETOOLONG - Give a name greater than PATH_MAX.
     213   */
     214
     215  puts( "Init: mq_open - Open with too long of a name (ENAMETOOLONG)" );
    104216  n_mq2 = mq_open( Get_Too_Long_Name(), O_CREAT | O_RDONLY, 0x777, NULL );
    105   fatal_directive_status(
     217  fatal_posix_service_status(
    106218    (int) n_mq2, (int ) (-1), "mq_open error return status" );
    107   fatal_directive_status( errno, ENAMETOOLONG,  "mq_open errno ENAMETOOLONG");
     219  fatal_posix_service_status( errno, ENAMETOOLONG, "mq_open errno ENAMETOOLONG");
    108220 
    109221  /*
     222   * XXX - ENAMETOOLONG - Give a name greater than NAME_MAX
     223   *       Per implementation not possible.
     224   */
     225
     226  /*
    110227   * Open maximum number of message queues
    111228   */
    112229
    113   puts( "mq_open - SUCCESSFUL" );
     230  puts( "Init: mq_open - SUCCESSFUL" );
    114231  for (i = 0; i < CONFIGURE_MAXIMUM_POSIX_MESSAGE_QUEUES; i++) {
    115     mqs[i] = mq_open( Get_Queue_Name(i), O_CREAT | O_RDWR, 0x777, NULL );
    116     assert( mqs[i] != (-1) );
     232    open_mq[i] = mq_open(
     233      Build_Queue_Name(i), O_CREAT | O_RDWR | O_NONBLOCK, 0x777, NULL );
     234    assert( open_mq[i] != (-1) );
    117235    /*XXX - Isn't there a more general check */
    118236  }
    119237
    120238  /*
    121    * Validate open errors that must occur after message queues are open.
    122    *   EACCES
    123    *   EEXIST
    124    *   EMFILE
    125    *   ENFILE
    126    */
    127 
    128   /*
    129239   * XXX EACCES - permission to create is denied.
    130240   */
     
    132242  /*
    133243   * XXX EACCES - queue exists permissions specified by o_flag are denied.
    134   puts( "mq_open - open mq as write (EACCES)" );
    135   n_mq2 = mq_open("mq1", O_CREAT | O_WRONLY, 0x777, NULL);
    136   fatal_directive_status(
     244   */
     245
     246  /*
     247   * EEXIST - Create an existing queue.
     248   */
     249
     250  puts( "Init: mq_open - Create an Existing mq (EEXIST)" );
     251  n_mq2 = mq_open(
     252    Build_Queue_Name(0), O_CREAT | O_EXCL | O_RDONLY, 0x777, NULL);
     253  fatal_posix_service_status(
    137254    (int) n_mq2, (int ) (-1), "mq_open error return status" );
    138   fatal_directive_status( errno, EACCES,  "mq_open errno EACCES");
    139    */
    140 
    141   puts( "mq_open - Create an Existing mq (EEXIST)" );
    142   n_mq2 = mq_open("mq1", O_CREAT | O_EXCL | O_RDONLY, 0x777, NULL);
    143   fatal_directive_status(
     255  fatal_posix_service_status( errno, EEXIST,  "mq_open errno EEXIST");
     256
     257  /*
     258   * XXX EMFILE  - Too many message queues in use by the process
     259   */
     260
     261  /*
     262   * ENFILE -  Too many message queues open in the system
     263   */
     264
     265  puts( "Init: mq_open - system is out of resources (ENFILE)" );
     266  n_mq2 = mq_open( Build_Queue_Name(i), O_CREAT | O_RDONLY, 0x777, NULL );
     267  fatal_posix_service_status(
    144268    (int) n_mq2, (int ) (-1), "mq_open error return status" );
    145   fatal_directive_status( errno, EEXIST,  "mq_open errno EEXIST");
    146 
    147 
    148   /*
    149    * XXX EMFILE  - Too many message queues open
    150    */
    151 
    152   puts( "mq_open - system is out of resources (ENFILE)" );
    153   n_mq2 = mq_open( Get_Queue_Name(i), O_CREAT | O_RDONLY, 0x777, NULL );
    154   fatal_directive_status(
    155     (int) n_mq2, (int ) (-1), "mq_open error return status" );
    156   fatal_directive_status( errno, ENFILE,  "mq_open errno ENFILE");
    157 
    158   /*
    159    * Unlink and Close .
    160    */
    161 
    162   puts( "mq_close and mq_unlink (mq3...mqn) - SUCCESSFUL" );
    163   for (i = size; i < CONFIGURE_MAXIMUM_POSIX_MESSAGE_QUEUES; i++) {
    164 
    165     status = mq_close( mqs[i] );
    166     fatal_directive_status( status, 0, "mq_close message queue");
    167 
    168     status = mq_unlink( Get_Queue_Name(i) );
    169     fatal_directive_status( status, 0, "mq_unlink message queue");
    170   }
    171 }
    172 
    173 void validate_mq_unlink_error_codes(
    174   mqd_t   *mqs,     
    175   int      size      /* Number still open in mqs */
    176 )
     269  fatal_posix_service_status( errno, ENFILE,  "mq_open errno ENFILE");
     270
     271  /*
     272   * Unlink and Close all queues.
     273   */
     274
     275  puts( "Init: mq_close and mq_unlink (mq3...mqn) - SUCCESSFUL" );
     276  for (i = 0; i < CONFIGURE_MAXIMUM_POSIX_MESSAGE_QUEUES; i++) {
     277
     278    status = mq_close( open_mq[i]);
     279    fatal_posix_service_status( status, 0, "mq_close message queue");
     280
     281    status = mq_unlink( Build_Queue_Name(i) );
     282    fatal_posix_service_status( status, 0, "mq_unlink message queue");
     283  }
     284}
     285
     286void validate_mq_unlink_error_codes()
    177287{
    178288  int             status;
    179289
     290  Start_Test( "mq_unlink errors" );
     291
    180292  /*
    181293   * XXX - EACCES Permission Denied
     
    183295
    184296  /*
    185    * XXX ENAMETOOLONG - Not checked in either sem_unlink or mq_unlink is
    186    *                    this an error?
    187    */
    188 
    189   puts( "mq_unlink - mq_unlink with too long of a name (ENAMETOOLONG)" );
     297   * ENAMETOOLONG - Give a name greater than PATH_MAX.
     298   */
     299
     300  puts( "Init: mq_unlink - mq_unlink with too long of a name (ENAMETOOLONG)" );
    190301  status = mq_unlink( Get_Too_Long_Name() );
    191   fatal_directive_status( status, -1, "mq_unlink error return status");
    192   fatal_directive_status( errno, ENAMETOOLONG, "mq_unlink errno ENAMETOOLONG");
     302  fatal_posix_service_status( status, -1, "mq_unlink error return status");
     303  fatal_posix_service_status( errno, ENAMETOOLONG, "mq_unlink errno ENAMETOOLONG");
    193304 
    194   puts( "mq_unlink - UNSUCCESSFUL (ENOENT)" );
    195   status = mq_unlink(Get_Queue_Name(size));
    196   fatal_directive_status( status, -1, "mq_unlink error return status");
    197   fatal_directive_status( errno, ENOENT, "mq_unlink errno ENOENT");
    198 
    199   /*
    200    * XXX - These errors are not in the POSIX manual but may occur.
    201    */
    202 
    203   puts( "mq_unlink (NULL) - EINVAL" );
     305  /*
     306   * XXX - ENAMETOOLONG - Give a name greater than NAME_MAX
     307   *       Per implementation not possible.
     308   */
     309
     310  /*
     311   *  ENOENT - Unlink an unopened queue
     312   */
     313
     314  puts( "Init: mq_unlink - A Queue not opened  (ENOENT)" );
     315  status = mq_unlink( CLOSED_NAME );
     316  fatal_posix_service_status( status, -1, "mq_unlink error return status");
     317  fatal_posix_service_status( errno, ENOENT, "mq_unlink errno ENOENT");
     318
     319  /*
     320   * XXX - The following were not listed in the POSIX document as
     321   *       possible errors.  Under other commands the EINVAL is
     322   *       given for these conditions.
     323   */
     324
     325  /*
     326   *  EINVAL - Unlink a queue with no name
     327   */
     328
     329  puts( "Init: mq_unlink (NULL) - EINVAL" );
    204330  status = mq_unlink( NULL );
    205   fatal_directive_status( status, -1, "mq_unlink error return status");
    206   fatal_directive_status( errno, EINVAL, "mq_unlink errno value");
    207 
    208   puts( "mq_unlink (\"\") - EINVAL" );
     331  fatal_posix_service_status( status, -1, "mq_unlink error return status");
     332  fatal_posix_service_status( errno, EINVAL, "mq_unlink errno value");
     333
     334  /*
     335   *  EINVAL - Unlink a queue with a null name
     336   */
     337
     338  puts( "Init: mq_unlink (\"\") - EINVAL" );
    209339  status = mq_unlink( "" );
    210   fatal_directive_status( status, -1, "mq_unlink error return status");
    211   fatal_directive_status( errno, EINVAL, "mq_unlink errno value");
    212 }
    213 
    214 void validate_mq_close_error_codes(
    215   mqd_t   *mqs,     
    216   int      size      /* Number still open in mqs */
    217 )
     340  fatal_posix_service_status( status, -1, "mq_unlink error return status");
     341  fatal_posix_service_status( errno, EINVAL, "mq_unlink errno value");
     342}
     343
     344void validate_mq_close_error_codes()
    218345{
    219346  int             status;
    220347
    221   puts( "mq_close - UNSUCCESSFUL (EBADF)" );
    222   status = mq_close(mqs[size]);
    223   fatal_directive_status( status, -1, "mq_close error return status");
    224   fatal_directive_status( errno, EBADF, "mq_close errno EBADF");
     348  Start_Test( "mq_close errors" );
     349
     350  /*
     351   * EBADF - Close a queue that is not open.
     352   */
     353
     354  puts( "Init: mq_close - unopened queue (EBADF)" );
     355  status = mq_close( Test_q[CLOSED].mq );
     356  fatal_posix_service_status( status, -1, "mq_close error return status");
     357  fatal_posix_service_status( errno, EBADF, "mq_close errno EBADF");
    225358}
    226359 
     360
     361void validate_mq_getattr_error_codes()
     362{
     363  struct mq_attr  attr;
     364  int             status;
     365
     366  Start_Test( "mq_getattr errors" );
     367
     368  /*
     369   * EBADF - Get the attributes from a closed queue.
     370   */
     371
     372  puts( "Init: mq_getattr - unopened queue (EBADF)" );
     373  status = mq_getattr( Test_q[CLOSED].mq, &attr );
     374  fatal_posix_service_status( status, -1, "mq_close error return status");
     375  fatal_posix_service_status( errno, EBADF, "mq_close errno EBADF"); 
     376
     377  /*
     378   * XXX - The following are not listed in the POSIX manual but
     379   *       may occur.
     380   */
     381
     382  /*
     383   * EINVAL - NULL attributes
     384   */
     385
     386  puts( "Init: mq_getattr - NULL attributes (EINVAL)" );
     387  status = mq_getattr( Test_q[RW_QUEUE].mq, NULL );
     388  fatal_posix_service_status( status, -1, "mq_close error return status");
     389  fatal_posix_service_status( errno, EINVAL, "mq_close errno EINVAL"); 
     390
     391}
     392
     393
     394void Send_msg_to_que(
     395  int que,
     396  int msg
     397)
     398{
     399  Test_Message_t *ptr = &Predefined_Msgs[msg];
     400  int             status;
     401
     402  status = mq_send( Test_q[que].mq, ptr->msg, ptr->size , ptr->priority );
     403  fatal_posix_service_status( status, 0, "mq_send valid return status");
     404  Test_q[que].count++;
     405}
     406
     407void Show_send_msg_to_que(
     408  char *task_name,
     409  int   que,
     410  int   msg
     411)
     412{
     413  Test_Message_t *ptr = &Predefined_Msgs[msg];
     414  printf( "%s mq_send -  to %s msg: %s priority %d\n",
     415    task_name, Test_q[que].name, ptr->msg, ptr->priority);
     416  Send_msg_to_que( que, msg );
     417}
     418
     419void verify_queues_full( 
     420  char *task_name
     421)
     422{
     423  int          que;
     424
     425  /*
     426   * Validate that the queues are full.
     427   */
     428
     429  printf( "%s Verify Queues are full\n", task_name );
     430  for( que = RW_QUEUE; que < CLOSED; que++ )
     431    Validate_attributes( Test_q[que].mq, Test_q[que].oflag, Test_q[que].count );
     432
     433}
     434void verify_queues_empty(
     435  char *task_name
     436)
     437{
     438  int             que;
     439
     440  printf( "%s Verify Queues are empty\n", task_name );
     441  for( que = RW_QUEUE; que < CLOSED; que++ )
     442    Validate_attributes( Test_q[que].mq, Test_q[que].oflag, 0 );
     443}
     444
     445int fill_message_queues(
     446  char *task_name
     447)
     448{
     449  int             msg;
     450  int             status;
     451  int             que;
     452
     453
     454  verify_queues_empty( task_name );
     455
     456  /*
     457   * Fill Queue with predefined messages.
     458   */
     459
     460  printf( "%s Fill Queues with messages\n", task_name );
     461  for(msg=0; msg<MAXMSG; msg++){
     462    for( que = RW_QUEUE; que < CLOSED; que++ ) {
     463      Send_msg_to_que( que, msg );
     464    }
     465  }
     466
     467  verify_queues_full( "Init:" );
     468  return msg;
     469}
     470
     471
     472void Read_msg_from_que(
     473  int que,
     474  int msg
     475)
     476{
     477  unsigned int    priority;
     478  Test_Message_t *ptr;
     479  int             status;
     480  char            message[100];
     481  char            err_msg[100];
     482
     483  ptr = &Predefined_Msgs[msg];
     484  status = mq_receive(Test_q[ que ].mq, message, 100, &priority );
     485  Test_q[que].count--;
     486
     487  sprintf( err_msg, "%s msg %s size failure", Test_q[ que ].name, ptr->msg );
     488  fatal_int_service_status( status, ptr->size, err_msg );
     489
     490  assert( !strcmp( message, ptr->msg ) );
     491  strcpy( message, "No Message" );
     492
     493  sprintf( err_msg,"%s msg %s size failure", Test_q[ que ].name, ptr->msg );
     494  fatal_int_service_status(priority, ptr->priority, err_msg );
     495}
     496
     497int empty_message_queues(
     498  char *task_name
     499)
     500{
     501  int que;
     502  int i;
     503
     504  printf( "%s Empty all Queues\n", task_name );
     505  for( que = RW_QUEUE; que < CLOSED; que++ ) {
     506    for(i=0; Test_q[que].count != 0; i++ )
     507      Read_msg_from_que( que,  Priority_Order[i] );
     508
     509    Validate_attributes( Test_q[ que].mq, Test_q[ que ].oflag, 0 );
     510  }
     511  return 0;
     512}
     513
    227514/*
    228515 * Returns the number of messages queued after the test on the
     
    230517 */
    231518
    232 int validate_mq_send_error_codes(
    233   mqd_t   *mqs,
    234   int      size      /* Number still open in mqs */
    235 )
     519int validate_mq_send_error_codes( )
    236520{
    237521  int             status;
    238522  int             i;
    239   mqd_t           n_mq1;
     523  char           *str;
     524
     525  Start_Test( "mq_send errors" );
     526
     527  /*
     528   * EBADF - Write to a closed queue.
     529   */
     530
     531  puts( "Init: mq_send - Closed message queue (EBADF)" );
     532  status = mq_send( Test_q[CLOSED].mq, "", 1, 0 );
     533  fatal_posix_service_status( status, -1, "mq_send error return status");
     534  fatal_posix_service_status( errno, EBADF, "mq_send errno EBADF");
     535
     536  /*
     537   * EBADF - Write to a read only  queue.
     538   */
     539
     540  puts( "Init: mq_send - Read only message queue (EBADF)" );
     541  status = mq_send( Test_q[ RD_QUEUE ].mq, "", 1, 0 );
     542  fatal_posix_service_status( status, -1, "mq_send error return status");
     543  fatal_posix_service_status( errno, EBADF, "mq_send errno EBADF");
     544
     545  /*
     546   * XXX - EINTR      Signal interrupted the call.
     547   *
     548  puts( "Init: mq_send - UNSUCCESSFUL (EINTR)" );
     549  status = mq_send( Test_q, "", 0xffff, 0 );
     550  fatal_posix_service_status( status, -1, "mq_send error return status");
     551  fatal_posix_service_status( errno, E, "mq_send errno E");
     552   */
     553
     554  /*
     555   * EINVAL priority is out of range.
     556   */
     557
     558  puts( "Init: mq_send - Priority out of range (EINVAL)" );
     559  status = mq_send( Test_q[ RW_QUEUE ].mq, "", 1, MQ_PRIO_MAX + 1 );
     560  fatal_posix_service_status( status, -1, "mq_send error return status");
     561  fatal_posix_service_status( errno, EINVAL, "mq_send errno EINVAL");
     562
     563  /*
     564   *  EMSGSIZE - Message size larger than msg_len
     565   *             Validates that msgsize is stored correctly.
     566   */
     567
     568  puts( "Init: mq_send - Message longer than msg_len (EMSGSIZE)" );
     569  status = mq_send( Test_q[ RW_QUEUE ].mq, "", MSGSIZE+1, 0 );
     570  fatal_posix_service_status( status, -1, "mq_send error return status");
     571  fatal_posix_service_status( errno, EMSGSIZE, "mq_send errno EMSGSIZE");
     572
     573  i = fill_message_queues( "Init:" );
     574
     575  /*
     576   * ENOSYS - send not supported
     577  puts( "Init: mq_send - Blocking Queue overflow (ENOSYS)" );
     578  status = mq_send( n_mq1, Predefined_Msgs[i], 0, 0 );
     579  fatal_posix_service_status( status, -1, "mq_send error return status");
     580  fatal_posix_service_status( errno, EBADF, "mq_send errno EBADF");
     581
     582  status = mq_close( n_mq1 );
     583  fatal_posix_service_status( status, 0, "mq_close message queue");
     584
     585  status = mq_unlink( "read_only" );
     586  fatal_posix_service_status( status, 0, "mq_unlink message queue");
     587   */
     588
     589  /*
     590   * EAGAIN - O_NONBLOCK and message queue is full.
     591   */
     592
     593  puts( "Init: mq_send - on a FULL non-blocking queue with (EAGAIN)" );
     594  str = Predefined_Msgs[i].msg;
     595  status = mq_send(Test_q[RW_QUEUE].mq, str, 0, 0 );
     596  fatal_posix_service_status( status, -1, "mq_send error return status");
     597  fatal_posix_service_status( errno, EAGAIN, "mq_send errno EAGAIN");
     598
     599  return i-1;
     600}
     601
     602void validate_mq_receive_error_codes( )
     603{
     604  int            status;
     605  char           message[100];
     606  unsigned int   priority;
     607  int            i;
     608
     609  Start_Test( "mq_receive errors"  );
     610
     611  /*
     612   * EBADF - Not A Valid Message Queue
     613   */
     614
     615  puts( "Init: mq_receive - Unopened message queue (EBADF)" );
     616  status = mq_receive( Test_q[CLOSED].mq, message, 100, &priority );
     617  fatal_posix_service_status( status, -1, "mq_ error return status");
     618  fatal_posix_service_status( errno, EBADF, "mq_receive errno EBADF");
     619
     620  /*
     621   * EBADF - Queue not opened to read
     622   */
     623
     624  puts( "Init: mq_receive - Write only queue (EBADF)" );
     625  status = mq_receive( Test_q[WR_QUEUE].mq, message, 100, &priority  );
     626  fatal_posix_service_status( status, -1, "mq_ error return status");
     627  fatal_posix_service_status( errno, EBADF, "mq_receive errno EBADF");
     628
     629  /*
     630   * EMSGSIZE - Size is less than the message size attribute
     631   */
     632
     633  puts( "Init: mq_receive - Size is less than the message (EMSGSIZE)" );
     634  status = mq_receive(
     635    Test_q[RW_QUEUE].mq, message, Predefined_Msgs[0].size-1, &priority );
     636  fatal_posix_service_status( status, -1, "mq_ error return status");
     637  fatal_posix_service_status( errno, EMSGSIZE, "mq_receive errno EMSGSIZE");
     638
     639
     640  /*
     641   * EAGAIN - O_NONBLOCK and Queue is empty
     642   */
     643  verify_queues_full( "Init:" );
     644  empty_message_queues( "Init:" );
     645
     646  puts( "Init: mq_receive - Queue is empty (EAGAIN)" );
     647  status = mq_receive( Test_q[RW_QUEUE].mq, message, 100, &priority );
     648  fatal_posix_service_status( status, -1, "mq_ error return status");
     649  fatal_posix_service_status( errno, EAGAIN, "mq_receive errno EAGAIN");
     650
     651  /*
     652   * XXX - EINTR - Interrupted by a signal
     653   */
     654
     655  /*
     656   * XXX - EBADMSG - a data corruption problem.
     657   */
     658
     659  /*
     660   * XXX - ENOSYS - mq_receive not supported
     661   */
     662}
     663
     664void verify_open_functionality()
     665{
     666  mqd_t           n_mq;
     667
     668  Start_Test( "mq_open functionality" );
     669
     670  /*
     671   * Validate a second open returns the same message queue.
     672   */
     673
     674  puts( "Init: mq_open - Open an existing mq ( same id )" );
     675  n_mq = mq_open( RD_NAME, 0 );
     676  fatal_posix_service_status(
     677    (int) n_mq, (int ) Test_q[RD_QUEUE].mq, "mq_open error return status" );
     678}
     679
     680void verify_unlink_functionality()
     681
     682  mqd_t           n_mq;
     683  int             status;
     684
     685  Start_Test( "mq_unlink functionality" );
     686
     687  /*
     688   * Unlink the message queue, then verify an open of the same name produces a
     689   * different message queue.
     690   */
     691
     692  puts( "Init: Unlink and Open without closing SUCCESSFUL" );
     693  status = mq_unlink( DEFAULT_NAME );
     694  fatal_posix_service_status( status, 0, "mq_unlink locked message queue");
     695
     696  n_mq = mq_open( DEFAULT_NAME, DEFAULT_ATTR, 0x777, NULL );
     697  assert( n_mq != (-1) );
     698  assert( n_mq != Test_q[ DEFAULT_RW ].mq );
     699
     700
     701  status = mq_unlink( DEFAULT_NAME );
     702  fatal_posix_service_status( status, 0, "mq_unlink locked message queue");
     703  status = mq_close( Test_q[ DEFAULT_RW ].mq );
     704  fatal_posix_service_status( status, 0, "mq_close message queue");
     705
     706  Test_q[ DEFAULT_RW ].mq = n_mq;
     707}
     708
     709void verify_close_functionality()
     710{
     711  int i;
     712  int status;
     713  Start_Test( "Unlink and Close All Files"  );
     714  for (i=0; i<DEFAULT_RW; i++) {
     715   
     716    status = mq_unlink( Get_Queue_Name(i) );
     717    fatal_posix_service_status( status, 0, "mq_unlink message queue");
     718
     719    status = mq_close( Test_q[i].mq );
     720    fatal_posix_service_status( status, 0, "mq_close message queue");
     721  }
     722}
     723
     724
     725void verify_timed_send_queue(
     726  int  que,
     727  int  is_blocking
     728)
     729{
     730  int             i;
     731  struct timespec timeout;
     732  struct timeval  tv1, tv2, tv3;
     733  struct timezone tz1, tz2;
     734  int              len;
     735  int              status;
     736  char            *msg;
     737
     738  timeout.tv_sec  = 1;
     739  timeout.tv_nsec = 0;
     740 
     741  printf( "Init: mq_timedsend - on queue %s ", Test_q[que].name);
     742  len = Predefined_Msgs[MAXMSG].size;
     743  msg = Predefined_Msgs[MAXMSG].msg;
     744  gettimeofday( &tv1, &tz1 );
     745  status = mq_timedsend( Test_q[que].mq, msg, len , 0, &timeout );
     746  gettimeofday( &tv2, &tz2 );
     747  tv3.tv_sec  = tv2.tv_sec - tv1.tv_sec;
     748  tv3.tv_usec = tv2.tv_usec - tv1.tv_usec;
     749
     750  if ( is_blocking ) { /* Don't verify the non-blocking queue */
     751    fatal_int_service_status( status, -1, "mq_timedsend status");
     752    fatal_posix_service_status( errno, ETIMEDOUT,  "errno ETIMEDOUT");
     753  }
     754
     755  printf("Init: %d sec %d us\n", tv3.tv_sec, tv3.tv_usec );
     756
     757  if ( is_blocking ) /* non-blocking queue */
     758    assert( tv3.tv_sec == 1 );
     759  else
     760    assert( tv3.tv_sec == 0 );
     761
     762  if ( que == DEFAULT_RW )
     763    Test_q[que].count++;
     764}
     765
     766void verify_timed_send()
     767{
     768  int              que;
     769
     770  Start_Test( "mq_timedsend"  );
     771
     772  for( que = RW_QUEUE; que < CLOSED; que++ ) {
     773    if ( que == BLOCKING )
     774      verify_timed_send_queue( que, 1 );
     775    else
     776      verify_timed_send_queue( que, 0 );
     777  }
     778}
     779
     780void verify_timed_receive_queue(
     781  char *task_name,
     782  int   que,
     783  int   is_blocking
     784)
     785{
     786  char message[ 100 ];
     787  unsigned int priority;
     788  struct timespec tm;
     789  struct timeval  tv1, tv2, tv3;
     790  struct timezone tz1, tz2;
     791  int              status;
     792 
     793  tm.tv_sec  = 1;
     794  tm.tv_nsec = 0;
     795
     796  printf( "Init: %s mq_timedreceive - on queue %s ", task_name, Test_q[que].name);
     797
     798  gettimeofday( &tv1, &tz1 );
     799  status = mq_timedreceive( Test_q[ que ].mq, message, 100, &priority, &tm );
     800  gettimeofday( &tv2, &tz2 );
     801  tv3.tv_sec  = tv2.tv_sec - tv1.tv_sec;
     802  tv3.tv_usec = tv2.tv_usec - tv1.tv_usec;
     803
     804  fatal_int_service_status( status, -1, "mq_timedreceive status");
     805  if ( is_blocking )
     806    fatal_posix_service_status( errno, ETIMEDOUT,  "errno ETIMEDOUT");
     807  printf( "Init: %d sec %d us\n", tv3.tv_sec, tv3.tv_usec );
     808
     809  if ( is_blocking )
     810    assert( tv3.tv_sec == 1 );
     811  else
     812    assert( tv3.tv_sec == 0 );
     813}
     814
     815
     816
     817void verify_timed_receive()
     818{
     819  int  que;
     820 
     821  Start_Test( "mq_timedreceive"  );
     822
     823  for( que = RW_QUEUE; que < CLOSED; que++ ) {
     824    if (( que == BLOCKING ) || ( que == DEFAULT_RW ))
     825      verify_timed_receive_queue( "Init:", que, 1 );
     826    else
     827      verify_timed_receive_queue( "Init:", que, 0 );
     828  }
     829}
     830
     831#if (0)
     832void verify_set_attr()
     833{
     834  struct mq_attr save_attr[ NUMBER_OF_TEST_QUEUES ];
     835  struct mq_attr attr;
     836  int            i;
     837  int            status;
     838
     839  attr.mq_maxmsg  = 0;
     840  attr.mq_msgsize = 0;
     841
     842  Start_Test( "mq_setattr"  );
     843
     844  puts( "Init: set_attr all queues to blocking" );
     845  for(i=0; i<CLOSED; i++) {
     846    attr.mq_flags =  Test_q[i].oflag & (~O_NONBLOCK );
     847    status = mq_setattr( Test_q[i].mq, &attr, &save_attr[i] );
     848    fatal_int_service_status( status, 0, "mq_setattr valid return status");
     849
     850    Validate_attributes( Test_q[i].mq, attr.mq_flags, 0 );
     851  }
     852
     853  for( i = RW_QUEUE; i < CLOSED; i++ ) {
     854    verify_timed_receive_queue( "Init:", i, 1 );
     855  }
     856 
     857  for(i=0; i<CLOSED; i++) {
     858    attr.mq_flags =  Test_q[i].oflag & (~O_NONBLOCK );
     859    status = mq_setattr( Test_q[i].mq, &save_attr[i], NULL );
     860    fatal_int_service_status( status, 0, "mq_setattr valid return status");
     861
     862    Validate_attributes( Test_q[i].mq, Test_q[i].oflag, 0 );
     863  }
     864}
     865#endif
     866
     867void wait_for_signal(
     868  sigset_t     *waitset,
     869  int           sec,
     870  int           expect_signal
     871)
     872{
     873  siginfo_t         siginfo;
     874  int               status;
     875  struct timespec   timeout;
     876  int               signo;
     877
     878  siginfo.si_code = -1;
     879  siginfo.si_signo = -1;
     880  siginfo.si_value.sival_int = -1;
     881
     882  timeout.tv_sec = sec;
     883  timeout.tv_nsec = 0;
     884
     885  status = sigemptyset( waitset );
     886  assert( !status );
     887
     888  status = sigaddset( waitset, SIGUSR1 );
     889  assert( !status );
     890
     891  printf( "waiting on any signal for %d seconds.\n", sec );
     892  signo = sigtimedwait( waitset, &siginfo, &timeout );
     893  if (expect_signal) {
     894    fatal_int_service_status( signo, SIGUSR1, "got SISUSR1" );
     895  } else {
     896    fatal_int_service_status( signo, -1, "error return status");
     897    fatal_posix_service_status( errno, EAGAIN, "errno EAGAIN");
     898  }
     899}
     900
     901void verify_notify()
     902{
     903  struct sigevent event;
     904  int             status;
     905  timer_t         timer_id;
     906  sigset_t        set;
     907  Test_Message_t *ptr;
     908
     909  Start_Test( "mq_notify"  );
     910
     911  /* timer create */
     912  event.sigev_notify = SIGEV_SIGNAL;
     913  event.sigev_signo  = SIGUSR1;
     914  if (timer_create (CLOCK_REALTIME, &event, &timer_id) == -1)
     915    fatal_posix_service_status( errno, 0,  "errno ETIMEDOUT");
     916
     917  /* block the timer signal */
     918  sigemptyset( &set );
     919  sigaddset( &set, SIGUSR1 );
     920  pthread_sigmask( SIG_BLOCK, &set, NULL );
     921
     922  /*
     923   * EBADF - Not A Valid Message Queue
     924   */
     925
     926  puts( "Init: mq_notify - Unopened message queue (EBADF)" );
     927  status = mq_notify( Test_q[CLOSED].mq, NULL );
     928  fatal_posix_service_status( status, -1, "mq_ error return status");
     929  fatal_posix_service_status( errno, EBADF, "mq_receive errno EBADF");
     930
     931  /*
     932   * Create ...
     933   */
     934
     935  /*
     936   * XXX setup notification
     937   */
     938
     939  printf( "_____mq_notify - notify when %s gets a message\n",RW_NAME);
     940  status = mq_notify( Test_q[RW_QUEUE].mq, &event );
     941  fatal_posix_service_status( status, 0, "mq_notify valid status");
     942  wait_for_signal( &set, 3, 0 );
     943
     944  /*
     945   * Send and verify signal occurs and registration is removed.
     946   */
     947
     948  puts( "Init: Verify Signal when send" );
     949  Show_send_msg_to_que( "Init:", RW_QUEUE, 0 );
     950  wait_for_signal( &set, 3, 1 );
     951  Read_msg_from_que( RW_QUEUE, 0 );
     952
     953  puts( "Init: Verify No Signal when send" );
     954  Show_send_msg_to_que( "Init:", RW_QUEUE, 0 );
     955  wait_for_signal( &set, 3, 0 );
     956  Read_msg_from_que( RW_QUEUE, 0 );
     957
     958
     959  /*
     960   * EBUSY - Already Registered
     961   */
     962
     963  printf( "____mq_notify - notify when %s gets a message\n",RD_NAME);
     964  status = mq_notify( Test_q[RW_QUEUE].mq, &event );
     965  fatal_posix_service_status( status, 0, "mq_notify valid status");
     966  wait_for_signal( &set, 3, 0 );
     967
     968  puts( "Init: mq_notify -  (EBUSY)" );
     969  status = mq_notify( Test_q[RW_QUEUE].mq, &event );
     970  fatal_posix_service_status( status, -1, "mq_notify error return status");
     971  fatal_posix_service_status( errno, EBUSY, "mq_notify errno EBUSY");
     972
     973  /*
     974   * Verify NULL removes registration.
     975   */
     976
     977  puts( "Init: mq_notify - Remove notification with null" );
     978  status = mq_notify( Test_q[RW_QUEUE].mq, NULL );
     979  fatal_posix_service_status( status, 0, "mq_notify valid status");
     980
     981  puts( "Init: Verify No Signal when send" );
     982  Show_send_msg_to_que( "Init:", RW_QUEUE, 0 );
     983  wait_for_signal( &set, 3, 0 );
     984  Read_msg_from_que( RW_QUEUE, 0 );
     985
     986}
     987
     988void verify_with_threads()
     989{
     990  int               status;
     991  pthread_t         id;
     992  Test_Message_t   *ptr;
     993  unsigned int      priority;
     994  char              message[100];
     995
     996
     997  /*
     998   * Create a task then block until the task sends the message.
     999   * Task tests set attributes so one queue will have a thread
     1000   * blocked while attributes are changed.
     1001   */
     1002
     1003  Start_Test( "multi-thread Task 4 Receive Test"  );
     1004  status = pthread_create( &id, NULL, Task_4, NULL );
     1005  assert( !status );
     1006  puts( "Init: mq_receive - Empty queue changes to non-blocking (EAGAIN)" );
     1007  status = mq_receive( Test_q[BLOCKING].mq, message, 100, &priority );
     1008  fatal_int_service_status( status, -1, "mq_receive error return status");
     1009  fatal_posix_service_status( errno, EAGAIN, "mq_receive errno EAGAIN");
     1010  print_current_time( "Init: ", "" );
     1011
     1012  /*
     1013   * Create a task then block until the task sends the message.
     1014   * Task tests set attributes so one queue will have a thread
     1015   * blocked while attributes are changed.
     1016   */
     1017
     1018  Start_Test( "multi-thread Task 1 Test"  );
     1019  status = pthread_create( &id, NULL, Task_1, NULL );
     1020  assert( !status );
     1021  Read_msg_from_que(  BLOCKING, 0 ); /* Block until init writes */
     1022  print_current_time( "Init: ", "" );
     1023
     1024  /*
     1025   * Create a task then block until the task reads a message.
     1026   */
     1027
     1028  Start_Test( "multi-thread Task 4 Send Test"  );
     1029  fill_message_queues( "Init:" );
     1030  status = pthread_create( &id, NULL, Task_4, NULL );
     1031  assert( !status );
     1032  puts( "Init: mq_send - Full queue changes to non-blocking (EAGAIN)" );
     1033  status = mq_send(Test_q[BLOCKING].mq, message, 0, 0 );
     1034  fatal_posix_service_status( status, -1, "mq_send error return status");
     1035  fatal_posix_service_status( errno, EAGAIN, "mq_send errno EAGAIN");
     1036  verify_queues_full( "Init:" );
     1037  empty_message_queues( "Init:" );
     1038
     1039  /*
     1040   * Create a task then block until the task reads a message.
     1041   */
     1042
     1043  Start_Test( "multi-thread Task 2 Test"  );
     1044  fill_message_queues( "Init:" );
     1045  status = pthread_create( &id, NULL, Task_2, NULL );
     1046  assert( !status );
     1047  Show_send_msg_to_que( "Init:", BLOCKING, Priority_Order[0] );
     1048  print_current_time( "Init: ", "" );
     1049  verify_queues_full( "Init:" );
     1050  empty_message_queues( "Init:" );
     1051
     1052  /*
     1053   * Create a task then block until it deletes and closes all queues.
     1054   *     EBADF - Queue unlinked and closed while blocked
     1055   */
     1056
     1057  Start_Test( "multi-thread Task 3 Test"  );
     1058  fill_message_queues( "Init:" );
     1059  status = pthread_create( &id, NULL, Task_3, NULL );
     1060  assert( !status );
     1061  puts( "Init: mq_send - Block while thread deletes queue (EBADF)" );
     1062  ptr = &Predefined_Msgs[0];
     1063  status = mq_send( Test_q[BLOCKING].mq, ptr->msg, ptr->size , ptr->priority );
     1064  fatal_posix_service_status( status, -1, "mq_send error return status");
     1065  fatal_posix_service_status( errno, EBADF, "mq_send errno EBADF");
     1066
     1067}
     1068
     1069void validate_mq_setattr()
     1070{
    2401071  struct mq_attr  attr;
    241 
    242   attr.mq_maxmsg  = 3;
    243   attr.mq_msgsize = 8;
    244 
    245   /*
    246    * XXX - EBADF  Not a valid message descriptor.
    247    *       Write to a invalid message descriptor
    248    * XXX - Write to a read only queue
    249    */
    250 
    251   puts( "mq_send - Closed message queue (EBADF)" );
    252   status = mq_send( mqs[size], "", 1, 0 );
    253   fatal_directive_status( status, -1, "mq_send error return status");
    254   fatal_directive_status( errno, EBADF, "mq_send errno EBADF");
    255 
    256   puts( "mq_open - Open a read only queue" );
    257   n_mq1 = mq_open("read_only", O_CREAT | O_RDONLY, 0x777, &attr);
    258   assert( n_mq1 != (-1) );
    259   /*XXX - Isn't there a more general check */
    260 
    261   puts( "mq_send - Read only message queue (EBADF)" );
    262   status = mq_send( n_mq1, "", 1, 0 );
    263   fatal_directive_status( status, -1, "mq_send error return status");
    264   fatal_directive_status( errno, EBADF, "mq_send errno EBADF");
    265 
    266   status = mq_close( n_mq1 );
    267   fatal_directive_status( status, 0, "mq_close message queue");
    268 
    269   status = mq_unlink( "read_only" );
    270   fatal_directive_status( status, 0, "mq_unlink message queue");
    271 
    272   /*
    273    * XXX - EINTR
    274    *       Signal interrupted the call.
    275 
    276   puts( "mq_send - UNSUCCESSFUL (EINTR)" );
    277   status = mq_send( mqs, "", 0xffff, 0 );
    278   fatal_directive_status( status, -1, "mq_send error return status");
    279   fatal_directive_status( errno, E, "mq_send errno E");
    280    */
    281 
    282   /*
    283    * XXX - EINVAL priority is out of range.
    284    */
    285 
    286   puts( "mq_send - Priority out of range (EINVAL)" );
    287   status = mq_send( mqs[0], "", 1, MQ_PRIO_MAX + 1 );
    288   fatal_directive_status( status, -1, "mq_send error return status");
    289   fatal_directive_status( errno, EINVAL, "mq_send errno EINVAL");
    290 
    291   /*
    292    * XXX - EMSGSIZE - Message size larger than msg_len
    293    */
    294 
    295   puts( "mq_send - Message longer than msg_len (EMSGSIZE)" );
    296   status = mq_send( mqs[0], "", 0xffff, 0 );
    297   fatal_directive_status( status, -1, "mq_send error return status");
    298   fatal_directive_status( errno, EMSGSIZE, "mq_send errno EMSGSIZE");
    299 
    300   /*
    301    * ENOSYS - send is supported should never happen.
    302    */
    303 
    304 
    305   /*
    306    * XXX - EAGAIN
    307    *       O_NONBLOCK and message queue is full.
    308    *       This is validated in the read/write test.
    309    */
    310 
    311   i=0;
    312   do {
    313     status = mq_send( mqs[0], "", 1, 0 );
    314     i++;
    315   } while (status == 0);
    316   fatal_directive_status( status, -1, "mq_send error return status");
    317   fatal_directive_status( errno, EAGAIN, "mq_send errno EAGAIN");
    318 
    319   return i-1;
    320 }
    321 
    322 void validate_mq_receive_error_codes(
    323   mqd_t   *mqs,     
    324   int      size      /* Number still open in mqs */
    325 )
    326 {
     1072  struct mq_attr  save_attr[ NUMBER_OF_TEST_QUEUES ];
    3271073  int             status;
    328 
    329   /*
    330    * EAGAIN -
    331    */
    332 
    333   /*
    334    * EBADF -
    335    */
    336 
    337   /*
    338    * EMSGSIZE -
    339    */
    340 
    341   /*
    342    * EINTR -
    343    */
    344 
    345   /*
    346    * EBADMSG - a data corruption problem.
    347    *  XXX - Can not cause.
    348    */
    349 
    350   /*
    351   puts( "mq_ - UNSUCCESSFUL ()" );
    352   status = mq_(  );
    353   fatal_directive_status( status, -1, "mq_ error return status");
    354   fatal_directive_status( errno, E, "mq_c errno E");
    355 
    356   */
    357   /*
    358    * ENOSYS -
    359    */
    360 
    361 }
    362 
    363 void non_blocking_mq_read_write(
    364   mqd_t   *mqs,     
    365   int      size      /* Number still open in mqs */
    366 )
    367 {
    368   /*
    369   int         status;
    370   char       *messages[] = {
    371     "Msg 1",
    372     "Test 2",
    373     "12345678901234567890"
    374   };
    375 
    376   status = mq_send( mqs[0], messages[0], strlen( messages[0] ), 0 );
    377   fatal_directive_status( status, 0, "mq_send error return status" );
    378    
    379   puts( "mq_send - UNSUCCESSFUL ()" );
    380   do {
    381     status = mq_send(  );
    382   fatal_directive_status( status, -1, "mq_send error return status");
    383   fatal_directive_status( errno, E, "mq_send errno E");
    384   }
    385   */
     1074  int            i;
     1075
     1076  /*
     1077   * EBADF - Get the attributes from a closed queue.
     1078   */
     1079
     1080  puts( "Task1:mq_setattr - unopened queue (EBADF)" );
     1081  status = mq_setattr( Test_q[CLOSED].mq, &attr, NULL );
     1082  fatal_posix_service_status( status, -1, "mq_setattr error return status");
     1083  fatal_posix_service_status( errno, EBADF, "mq_setattr errno EBADF"); 
     1084
     1085  /*
     1086   * XXX - The following are not listed in the POSIX manual but
     1087   *       may occur.
     1088   */
     1089
     1090  /*
     1091   * EINVAL - NULL attributes
     1092   */
     1093
     1094  puts( "Task1:mq_setattr - NULL attributes (EINVAL)" );
     1095  status = mq_setattr( Test_q[RW_QUEUE].mq, NULL, NULL );
     1096  fatal_posix_service_status( status, -1, "mq_setattr error return status");
     1097  fatal_posix_service_status( errno, EINVAL, "mq_setattr errno EINVAL"); 
     1098
     1099  /*
     1100   * Verify change queues to blocking, by verifying all queues block
     1101   * for a timed receive.
     1102   */
     1103
     1104  puts( "Init: set_attr all queues to blocking" );
     1105  for(i=0; i<CLOSED; i++) {
     1106    attr.mq_flags =  Test_q[i].oflag & (~O_NONBLOCK );
     1107    status = mq_setattr( Test_q[i].mq, &attr, &save_attr[i] );
     1108    fatal_int_service_status( status, 0, "mq_setattr valid return status");
     1109    Validate_attributes( Test_q[i].mq, attr.mq_flags, 0 );
     1110  }
     1111  for( i = RW_QUEUE; i < CLOSED; i++ ) {
     1112    verify_timed_receive_queue( "Init:", i, 1 );
     1113  }
     1114
     1115  /*
     1116   * Restore restore all queues to their old attribute.
     1117   */
     1118 
     1119  for(i=0; i<CLOSED; i++) {
     1120    status = mq_setattr( Test_q[i].mq, &save_attr[i], NULL );
     1121    fatal_int_service_status( status, 0, "mq_setattr valid return status");
     1122    Validate_attributes( Test_q[i].mq, Test_q[i].oflag, 0 );
     1123  }
    3861124}
    3871125
     
    3911129{
    3921130  int             status;
    393   mqd_t           mqs[CONFIGURE_MAXIMUM_POSIX_MESSAGE_QUEUES];
    394   mqd_t           n_mq1;
    3951131  mqd_t           n_mq2;
    396   char           *messages[] = {
    397     "Msg 1",
    398     "Test 2",
    399     "12345678901234567890"
    400   };
    4011132
    4021133  puts( "\n\n*** POSIX MESSAGE QUEUE TEST ***" );
    4031134
    404   validate_mq_open_error_codes( mqs, 2 );
    405   validate_mq_unlink_error_codes( mqs, 2 );
    406   validate_mq_close_error_codes( mqs, 2 );
    407 
    408   validate_mq_send_error_codes( mqs, 2 );
    409   validate_mq_receive_error_codes( mqs, 2 );
    410 
    411 
    412   /*
    413    * Validate a second open returns the same message queue.
    414    */
    415 
    416   puts( "mq_open - Open an existing mq ( same id )" );
    417   n_mq1 = mq_open("mq1", 0 );
    418   fatal_directive_status(
    419     (int) n_mq1, (int ) mqs[0], "mq_open error return status" );
     1135  validate_mq_open_error_codes( );
     1136  open_test_queues();
     1137  validate_mq_unlink_error_codes();
     1138  validate_mq_close_error_codes();
     1139  verify_unlink_functionality();
     1140  validate_mq_setattr( );
     1141  validate_mq_send_error_codes();
     1142  validate_mq_getattr_error_codes();
     1143  verify_timed_send();
     1144  validate_mq_receive_error_codes();
     1145  verify_timed_receive();
     1146  verify_open_functionality();
     1147  verify_notify();
     1148  verify_with_threads();
    4201149 
    421   /*
    422    * Unlink the message queue, then verify an open of the same name produces a
    423    * different message queue.
    424    */
    425 
    426   puts( "mq_unlink - mq1 SUCCESSFUL" );
    427   status = mq_unlink( "mq1" );
    428   fatal_directive_status( status, 0, "mq_unlink locked message queue");
    429 
    430   puts( "mq_open - Reopen mq1 SUCCESSFUL with a different id" );
    431   n_mq2 = mq_open( "mq1", O_CREAT | O_EXCL, 00777, NULL);
    432   assert( n_mq2 != (-1) );
    433   assert( n_mq2 != n_mq1 );
    434 
    435   /*
    436    * Validate it "mq1" can be closed and unlinked.
    437    */
    438 
    439   puts( "mq_unlink - mq1 SUCCESSFUL" );
    440   status = mq_unlink( "mq1" );
    441   fatal_directive_status( status, 0, "mq_unlink locked message queue");
    442 
    443   puts( "mq_close mq1 - SUCCESSFUL" );
    444   status = mq_close( n_mq2 );
    445   fatal_directive_status( status, 0, "mq_close message queue");
    446   status = mq_close( n_mq1 );
    447   fatal_directive_status( status, 0, "mq_close message queue");
    448   status = mq_close( mqs[0] );
    449   fatal_directive_status( status, 0, "mq_close message queue");
    450 
    451   puts( "mq_unlink - UNSUCCESSFUL (ENOENT)" );
    452   status = mq_unlink("mq1");
    453   fatal_directive_status( status, -1, "mq_unlink error return status");
    454   fatal_directive_status( errno, ENOENT, "mq_close errno EINVAL");
    455 
    456   /*
    457    * XXX - Cant' create location OBJECTS_ERROR or OBJECTS_REMOTE.
    458    *       mq_close and mq_unlink.
    459    * XXX - Don't think we need this save until yellow line tested.
    460   puts( "Init: mq_unlink - UNSUCCESSFUL (ENOENT)" );
    461   status = mq_unlink("mq3");
    462   fatal_directive_status( status, -1, "mq_unlink error return status");
    463   fatal_directive_status( errno, ENOENT, "mq_unlink errno ENOENT");
    464   assert( (status == -1) && (errno == ENOENT) );
    465   */
    466 
    467 
    468   /*
    469    * Validate we can wait on a message queue opened with mq_open.
    470    */
    471 #if (0) /* XXX FIX ME */
    472   puts( "Init: mq_wait on mq1" );
    473   status = mq_receive(n_mq1);
    474   fatal_directive_status( status, 0, "mq_wait opened message queue");
    475 #endif
    476 
    477 
    4781150  puts( "*** END OF POSIX MESSAGE QUEUE TEST ***" );
    4791151  exit( 0 );
     
    4831155
    4841156
     1157void *Task_1 (
     1158  void *argument
     1159)
     1160{
     1161  int      status;
     1162  int      count = 0;
     1163  sigset_t set;
     1164
     1165  /* Block Waiting for a message */
     1166
     1167  print_current_time( "Task_1: ", "" );
     1168
     1169  Show_send_msg_to_que( "Task_1:", BLOCKING, 0 );
     1170
     1171  puts( "Task_1: pthread_exit" );
     1172  pthread_exit( NULL );
     1173
     1174  /* switch to Init */
     1175
     1176  assert( 0 );
     1177  return NULL; /* just so the compiler thinks we returned something */
     1178}
     1179
     1180void *Task_2(
     1181  void *argument
     1182)
     1183{
     1184  int status;
     1185
     1186 
     1187  print_current_time( "Task_2: ", "" );
     1188
     1189 
     1190  /* Block waiting to send a message */
     1191
     1192  verify_queues_full( "Task_2:" );
     1193  Read_msg_from_que( BLOCKING, Priority_Order[0] ); /* Cause context switch */
     1194
     1195  puts( "Task_2: pthread_exit" );
     1196  pthread_exit( NULL );
     1197
     1198     /* switch to Init */
     1199
     1200  return NULL; /* just so the compiler thinks we returned something */
     1201}
     1202
     1203void *Task_3 (
     1204  void *argument
     1205)
     1206{
     1207
     1208  print_current_time( "Task_3: ", "" );
     1209
     1210  /*
     1211   * close and unlink all queues.
     1212   */
     1213
     1214  verify_close_functionality( "Task_3: " );
     1215  puts( "Task_3: pthread_exit" );
     1216  pthread_exit( NULL );
     1217
     1218     /* switch to Init */
     1219
     1220  return NULL; /* just so the compiler thinks we returned something */
     1221
     1222}
     1223
     1224void *Task_4 (
     1225  void *argument
     1226)
     1227{
     1228  struct mq_attr  attr;
     1229  int             status;
     1230  int             count;
     1231
     1232  print_current_time( "Task_4: ", "" );
     1233
     1234  /*
     1235   * Set the count to the number of messages in the queue.
     1236   */
     1237
     1238  status = mq_getattr( Test_q[BLOCKING].mq, &attr );
     1239  fatal_posix_service_status( status, 0, "mq_getattr valid return status");
     1240  count = attr.mq_curmsgs;
     1241
     1242  puts("Task_4: Set queue to non-blocking");
     1243  attr.mq_flags =  Test_q[BLOCKING].oflag | O_NONBLOCK;
     1244  status = mq_setattr( Test_q[BLOCKING].mq, &attr, NULL );
     1245  fatal_int_service_status( status, 0, "mq_setattr valid return status");
     1246  Validate_attributes( Test_q[BLOCKING].mq, attr.mq_flags, count );
     1247
     1248  puts("Task_4: Return queue to blocking");
     1249  attr.mq_flags =  Test_q[BLOCKING].oflag;
     1250  status = mq_setattr( Test_q[BLOCKING].mq, &attr, NULL );
     1251  fatal_int_service_status( status, 0, "mq_setattr valid return status");
     1252  Validate_attributes( Test_q[BLOCKING].mq, attr.mq_flags, count );
     1253
     1254  puts( "Task_4: pthread_exit" );
     1255  pthread_exit( NULL );
     1256
     1257     /* switch to Init */
     1258
     1259  return NULL; /* just so the compiler thinks we returned something */
     1260
     1261}
     1262
     1263void *Task_5 (
     1264  void *argument
     1265)
     1266{
     1267
     1268  print_current_time( "Task_5: ", "" );
     1269
     1270  puts( "Task_5: pthread_exit" );
     1271  pthread_exit( NULL );
     1272
     1273     /* switch to Init */
     1274
     1275  return NULL; /* just so the compiler thinks we returned something */
     1276
     1277}
     1278
     1279void *Task_ (
     1280  void *argument
     1281)
     1282{
     1283
     1284  print_current_time( "Task_: ", "" );
     1285
     1286  puts( "Task_: pthread_exit" );
     1287  pthread_exit( NULL );
     1288
     1289     /* switch to Init */
     1290
     1291  return NULL; /* just so the compiler thinks we returned something */
     1292
     1293}
     1294
     1295
     1296
     1297 
     1298
     1299
     1300
     1301
     1302
     1303
     1304
     1305
     1306
     1307
     1308
     1309
     1310
     1311
  • cpukit/itron/src/cre_mbf.c

    ree4ddd83 r53fb837a  
    2626)
    2727{
    28   CORE_message_queue_Attributes   the_message_queue_attributes;
     28  CORE_message_queue_Attributes    the_msgq_attributes;
    2929  ITRON_Message_buffer_Control    *the_message_buffer;
    3030
     
    5858
    5959  if ( pk_cmbf->mbfatr & TA_TPRI )
    60     the_message_queue_attributes.discipline =
    61         CORE_MESSAGE_QUEUE_DISCIPLINES_PRIORITY;
     60    the_msgq_attributes.discipline = CORE_MESSAGE_QUEUE_DISCIPLINES_PRIORITY;
    6261  else
    63     the_message_queue_attributes.discipline =
    64         CORE_MESSAGE_QUEUE_DISCIPLINES_FIFO;
     62    the_msgq_attributes.discipline = CORE_MESSAGE_QUEUE_DISCIPLINES_FIFO;
    6563
    6664  _CORE_message_queue_Initialize(
    6765    &the_message_buffer->message_queue,
    6866    OBJECTS_ITRON_MESSAGE_BUFFERS,
    69     &the_message_queue_attributes,
     67    &the_msgq_attributes,
    7068    pk_cmbf->bufsz / pk_cmbf->maxmsz,
    7169    pk_cmbf->maxmsz,
  • cpukit/itron/src/snd_mbx.c

    ree4ddd83 r53fb837a  
    2828  register ITRON_Mailbox_Control *the_mailbox;
    2929  Objects_Locations                location;
    30   CORE_message_queue_Status        status = E_OK;
    3130  unsigned32                       message_priority;
    3231  void                            *message_contents;
     
    4847
    4948      message_contents = pk_msg;
    50       status = _CORE_message_queue_Submit(
     49      _CORE_message_queue_Submit(
    5150        &the_mailbox->message_queue,
    5251        &message_contents,
     
    5453        the_mailbox->Object.id,
    5554        NULL,          /* multiprocessing not supported */
    56         message_priority
     55        message_priority,
     56        FALSE,     /* do not allow sender to block */
     57        0          /* no timeout */
    5758     );
    5859     break;
     
    6061
    6162  _ITRON_return_errorno(
    62      _ITRON_Mailbox_Translate_core_message_queue_return_code(status) );
     63     _ITRON_Mailbox_Translate_core_message_queue_return_code(
     64          _Thread_Executing->Wait.return_code
     65     )
     66  );
    6367}
  • cpukit/itron/src/trcv_mbf.c

    ree4ddd83 r53fb837a  
    3333  boolean                         wait;
    3434  Watchdog_Interval               interval;
    35   CORE_message_queue_Submit_types core_priority;
    3635
    3736  interval = 0;
     
    6362          p_msgsz,
    6463          wait,
    65           &core_priority,
    6664          interval
    6765      );
  • cpukit/itron/src/tsnd_mbf.c

    ree4ddd83 r53fb837a  
    3434  Watchdog_Interval              interval;
    3535  boolean                        wait;
    36   CORE_message_queue_Status      status;
    3736
    3837  if (msgsz <= 0 || !msg)
     
    5150    return E_CTX;
    5251
    53   assert( wait == FALSE );
    54 
    5552  the_message_buffer = _ITRON_Message_buffer_Get(mbfid, &location);
    5653  switch (location) {
     
    6158    case OBJECTS_LOCAL:
    6259      /* XXX Submit needs to take into account blocking */
    63       status = _CORE_message_queue_Submit(
     60      _CORE_message_queue_Submit(
    6461        &the_message_buffer->message_queue,
    6562        msg,
     
    6764        the_message_buffer->Object.id,
    6865        NULL,
    69         CORE_MESSAGE_QUEUE_SEND_REQUEST
     66        CORE_MESSAGE_QUEUE_SEND_REQUEST,
     67        wait,      /* sender may block */
     68        interval   /* timeout interval */
    7069      );
    7170      _Thread_Enable_dispatch();
    72       return
    73         _ITRON_Message_buffer_Translate_core_message_buffer_return_code(status);
     71      return _ITRON_Message_buffer_Translate_core_message_buffer_return_code(
     72          _Thread_Executing->Wait.return_code
     73      );
    7474    }
    7575
  • cpukit/posix/include/rtems/posix/mqueue.h

    ree4ddd83 r53fb837a  
    3333   Objects_Control             Object;
    3434   int                         process_shared;
    35    int                         flags;
    3635   boolean                     named;
    3736   boolean                     linked;
    38    boolean                     blocking;
    3937   int                         oflag;
    4038   unsigned32                  open_count;
  • cpukit/rtems/src/msgqcreate.c

    ree4ddd83 r53fb837a  
    6060{
    6161  register Message_queue_Control *the_message_queue;
    62   CORE_message_queue_Attributes   the_message_queue_attributes;
     62  CORE_message_queue_Attributes   the_msgq_attributes;
    6363  void                           *handler;
    6464#if defined(RTEMS_MULTIPROCESSING)
     
    7575#endif
    7676
    77   if (count == 0)
     77  if ( count == 0 )
    7878      return RTEMS_INVALID_NUMBER;
    7979
    80   if (max_message_size == 0)
     80  if ( max_message_size == 0 )
    8181      return RTEMS_INVALID_SIZE;
    8282
     
    116116
    117117  if (_Attributes_Is_priority( attribute_set ) )
    118     the_message_queue_attributes.discipline =
    119                                       CORE_MESSAGE_QUEUE_DISCIPLINES_PRIORITY;
     118    the_msgq_attributes.discipline = CORE_MESSAGE_QUEUE_DISCIPLINES_PRIORITY;
    120119  else
    121     the_message_queue_attributes.discipline =
    122                                       CORE_MESSAGE_QUEUE_DISCIPLINES_FIFO;
     120    the_msgq_attributes.discipline = CORE_MESSAGE_QUEUE_DISCIPLINES_FIFO;
    123121
    124122  handler = NULL;
     
    130128           &the_message_queue->message_queue,
    131129           OBJECTS_RTEMS_MESSAGE_QUEUES,
    132            &the_message_queue_attributes,
     130           &the_msgq_attributes,
    133131           count,
    134132           max_message_size,
  • cpukit/rtems/src/msgqreceive.c

    ree4ddd83 r53fb837a  
    9393        size,
    9494        wait,
    95         &core_priority,
    9695        timeout
    9796      );
    9897      _Thread_Enable_dispatch();
    99       return( _Message_queue_Translate_core_message_queue_return_code(
    100                   _Thread_Executing->Wait.return_code ) );
     98      return _Message_queue_Translate_core_message_queue_return_code(
     99        _Thread_Executing->Wait.return_code
     100      );
    101101
    102102  }
  • cpukit/rtems/src/msgqsubmit.c

    ree4ddd83 r53fb837a  
    6262  register Message_queue_Control  *the_message_queue;
    6363  Objects_Locations                location;
    64   CORE_message_queue_Status        core_status;
    6564
    6665  the_message_queue = _Message_queue_Get( id, &location );
     
    9998      switch ( submit_type ) {
    10099        case MESSAGE_QUEUE_SEND_REQUEST:
    101           core_status = _CORE_message_queue_Send(
    102                           &the_message_queue->message_queue,
    103                           buffer,
    104                           size,
    105                           id,
     100          _CORE_message_queue_Send(
     101            &the_message_queue->message_queue,
     102            buffer,
     103            size,
     104            id,
    106105#if defined(RTEMS_MULTIPROCESSING)
    107                           _Message_queue_Core_message_queue_mp_support
     106            _Message_queue_Core_message_queue_mp_support,
    108107#else
    109                           NULL
     108            NULL,
    110109#endif
    111                         );
     110            FALSE,   /* sender does not block */
     111            0        /* no timeout */
     112          );
    112113          break;
    113114        case MESSAGE_QUEUE_URGENT_REQUEST:
    114           core_status = _CORE_message_queue_Urgent(
    115                           &the_message_queue->message_queue,
    116                           buffer,
    117                           size,
    118                           id,
     115          _CORE_message_queue_Urgent(
     116            &the_message_queue->message_queue,
     117            buffer,
     118            size,
     119            id,
    119120#if defined(RTEMS_MULTIPROCESSING)
    120                           _Message_queue_Core_message_queue_mp_support
     121            _Message_queue_Core_message_queue_mp_support,
    121122#else
    122                           NULL
     123            NULL,
    123124#endif
    124                         );
     125            FALSE,   /* sender does not block */
     126            0        /* no timeout */
     127          );
    125128          break;
    126129        default:
    127           core_status = CORE_MESSAGE_QUEUE_STATUS_SUCCESSFUL;
    128130          return RTEMS_INTERNAL_ERROR;   /* should never get here */
    129131      }
     
    131133      _Thread_Enable_dispatch();
    132134      return _Message_queue_Translate_core_message_queue_return_code(
    133                 core_status );
     135        _Thread_Executing->Wait.return_code
     136      );
    134137         
    135138  }
  • cpukit/score/include/rtems/score/coremsg.h

    ree4ddd83 r53fb837a  
    167167
    168168/*
    169  *
    170169 *  _CORE_message_queue_Flush
    171170 *
    172171 *  DESCRIPTION:
    173172 *
    174  *  This function flushes the message_queue's task wait queue.  The number
    175  *  messages flushed from the queue is returned.
     173 *  This function flushes the message_queue's pending message queue.  The
     174 *  number of messages flushed from the queue is returned.
    176175 *
    177176 */
     
    195194 
    196195/*
    197  *
     196 *  _CORE_message_queue_Flush_waiting_threads
     197 *
     198 *  DESCRIPTION:
     199 *
     200 *  This function flushes the threads which are blocked on this
     201 *  message_queue's pending message queue.  They are unblocked whether
     202 *  blocked sending or receiving.
     203 */
     204
     205void _CORE_message_queue_Flush_waiting_threads(
     206  CORE_message_queue_Control *the_message_queue
     207);
     208
     209/*
    198210 *  _CORE_message_queue_Broadcast
    199211 *
     
    215227
    216228/*
    217  *
    218229 *  _CORE_message_queue_Submit
    219230 *
     
    229240 */
    230241 
    231 CORE_message_queue_Status _CORE_message_queue_Submit(
     242void _CORE_message_queue_Submit(
    232243  CORE_message_queue_Control                *the_message_queue,
    233244  void                                      *buffer,
     
    235246  Objects_Id                                 id,
    236247  CORE_message_queue_API_mp_support_callout  api_message_queue_mp_support,
    237   CORE_message_queue_Submit_types            submit_type
    238 );
    239 
    240 /*
    241  *
     248  CORE_message_queue_Submit_types            submit_type,
     249  boolean                                    wait,
     250  Watchdog_Interval                          timeout
     251);
     252
     253/*
    242254 *  _CORE_message_queue_Seize
    243255 *
     
    249261 *  otherwise an error will be given to the thread if no messages are available.
    250262 *
     263 *  NOTE: Returns message priority via return are in TCB.
    251264 */
    252265 
     
    257270  unsigned32                      *size,
    258271  boolean                          wait,
    259   CORE_message_queue_Submit_types *priority,
    260272  Watchdog_Interval                timeout
     273);
     274
     275/*
     276 *  _CORE_message_queue_Insert_message
     277 *
     278 *  DESCRIPTION:
     279 *
     280 *  This kernel routine inserts the specified message into the
     281 *  message queue.  It is assumed that the message has been filled
     282 *  in before this routine is called.
     283 */
     284
     285void _CORE_message_queue_Insert_message(
     286  CORE_message_queue_Control        *the_message_queue,
     287  CORE_message_queue_Buffer_control *the_message,
     288  CORE_message_queue_Submit_types    submit_type
    261289);
    262290
  • cpukit/score/inline/rtems/score/coremsg.inl

    ree4ddd83 r53fb837a  
    2828 */
    2929 
    30 RTEMS_INLINE_ROUTINE CORE_message_queue_Status _CORE_message_queue_Send(
     30RTEMS_INLINE_ROUTINE void _CORE_message_queue_Send(
    3131  CORE_message_queue_Control                *the_message_queue,
    3232  void                                      *buffer,
    3333  unsigned32                                 size,
    3434  Objects_Id                                 id,
    35   CORE_message_queue_API_mp_support_callout  api_message_queue_mp_support
    36 )
    37 {
    38   return _CORE_message_queue_Submit(
     35  CORE_message_queue_API_mp_support_callout  api_message_queue_mp_support,
     36  boolean                                    wait,
     37  Watchdog_Interval                          timeout
     38)
     39{
     40  _CORE_message_queue_Submit(
    3941    the_message_queue,
    4042    buffer,
     
    4648    NULL,
    4749#endif
    48     CORE_MESSAGE_QUEUE_SEND_REQUEST
     50    CORE_MESSAGE_QUEUE_SEND_REQUEST,
     51    wait,     /* sender may block */
     52    timeout   /* timeout interval */
    4953  );
    5054}
     
    5963 */
    6064 
    61 RTEMS_INLINE_ROUTINE CORE_message_queue_Status _CORE_message_queue_Urgent(
     65RTEMS_INLINE_ROUTINE void _CORE_message_queue_Urgent(
    6266  CORE_message_queue_Control                *the_message_queue,
    6367  void                                      *buffer,
    6468  unsigned32                                 size,
    6569  Objects_Id                                 id,
    66   CORE_message_queue_API_mp_support_callout  api_message_queue_mp_support
    67 )
    68 {
    69   return _CORE_message_queue_Submit(
     70  CORE_message_queue_API_mp_support_callout  api_message_queue_mp_support,
     71  boolean                                    wait,
     72  Watchdog_Interval                          timeout
     73)
     74{
     75  _CORE_message_queue_Submit(
    7076    the_message_queue,
    7177    buffer,
     
    7783    NULL,
    7884#endif
    79     CORE_MESSAGE_QUEUE_URGENT_REQUEST
     85    CORE_MESSAGE_QUEUE_URGENT_REQUEST,
     86    wait,     /* sender may block */
     87    timeout   /* timeout interval */
    8088 );
    8189}
  • cpukit/score/macros/rtems/score/coremsg.inl

    ree4ddd83 r53fb837a  
    2424 
    2525#define _CORE_message_queue_Send( _the_message_queue, _buffer, _size, \
    26 _id, _api_message_queue_mp_support ) \
     26       _id, _api_message_queue_mp_support, _wait, _timeout ) \
    2727  _CORE_message_queue_Submit( (_the_message_queue), (_buffer), (_size), \
    28      (_id), (_api_message_queue_mp_support), CORE_MESSAGE_QUEUE_SEND_REQUEST )
     28     (_id), (_api_message_queue_mp_support), \
     29     CORE_MESSAGE_QUEUE_SEND_REQUEST, (_wait), (_timeout)
    2930 
    3031/*PAGE
     
    3536 
    3637#define _CORE_message_queue_Urgent( _the_message_queue, _buffer, _size, \
    37 _id, _api_message_queue_mp_support ) \
     38       _id, _api_message_queue_mp_support, _wait, _timeout ) \
    3839  _CORE_message_queue_Submit( (_the_message_queue), (_buffer), (_size), \
    39      (_id), (_api_message_queue_mp_support), CORE_MESSAGE_QUEUE_URGENT_REQUEST )
     40     (_id), (_api_message_queue_mp_support), \
     41     CORE_MESSAGE_QUEUE_URGENT_REQUEST, (_wait), (_timeout)
    4042
    4143/*PAGE
  • cpukit/score/src/coremsgbroadcast.c

    ree4ddd83 r53fb837a  
    6565  unsigned32               constrained_size;
    6666
     67  /*
     68   *  If there are pending messages, then there can't be threads
     69   *  waiting for us to send them a message.
     70   *
     71   *  NOTE: This check is critical because threads can block on
     72   *        send and receive and this ensures that we are broadcasting
     73   *        the message to threads waiting to receive -- not to send.
     74   */
     75
     76  if ( the_message_queue->number_of_pending_messages != 0 ) {
     77    *count = 0;
     78    return CORE_MESSAGE_QUEUE_STATUS_SUCCESSFUL;
     79  }
     80
     81  /*
     82   *  There must be no pending messages if there is a thread waiting to
     83   *  receive a message.
     84   */
     85
    6786  number_broadcasted = 0;
    6887  while ((the_thread = _Thread_queue_Dequeue(&the_message_queue->Wait_queue))) {
  • cpukit/score/src/coremsgsubmit.c

    ree4ddd83 r53fb837a  
    5454 */
    5555
    56 CORE_message_queue_Status _CORE_message_queue_Submit(
     56void _CORE_message_queue_Submit(
    5757  CORE_message_queue_Control                *the_message_queue,
    5858  void                                      *buffer,
     
    6060  Objects_Id                                 id,
    6161  CORE_message_queue_API_mp_support_callout  api_message_queue_mp_support,
    62   CORE_message_queue_Submit_types            submit_type
     62  CORE_message_queue_Submit_types            submit_type,
     63  boolean                                    wait,
     64  Watchdog_Interval                          timeout
    6365)
    6466{
     67  ISR_Level                            level;
    6568  CORE_message_queue_Buffer_control   *the_message;
    6669  Thread_Control                      *the_thread;
     70  Thread_Control                      *executing;
    6771
    68   if ( size > the_message_queue->maximum_message_size )
    69     return CORE_MESSAGE_QUEUE_STATUS_INVALID_SIZE;
     72  _Thread_Executing->Wait.return_code = CORE_MESSAGE_QUEUE_STATUS_SUCCESSFUL;
    7073
    71   /*
    72    * Is there a thread currently waiting on this message queue?
    73    */
    74      
    75   the_thread = _Thread_queue_Dequeue( &the_message_queue->Wait_queue );
    76   if ( the_thread ) {
    77     _CORE_message_queue_Copy_buffer(
    78       buffer,
    79       the_thread->Wait.return_argument,
    80       size
    81     );
    82     *(unsigned32 *)the_thread->Wait.return_argument_1 = size;
    83     the_thread->Wait.count = submit_type;
    84    
    85 #if defined(RTEMS_MULTIPROCESSING)
    86     if ( !_Objects_Is_local_id( the_thread->Object.id ) )
    87       (*api_message_queue_mp_support) ( the_thread, id );
    88 #endif
    89 
    90     return CORE_MESSAGE_QUEUE_STATUS_SUCCESSFUL;
     74  if ( size > the_message_queue->maximum_message_size ) {
     75    _Thread_Executing->Wait.return_code =
     76       CORE_MESSAGE_QUEUE_STATUS_INVALID_SIZE;
     77    return;
    9178  }
    9279
    9380  /*
    94    * No one waiting on this one currently.
    95    * Allocate a message buffer and store it away
     81   *  Is there a thread currently waiting on this message queue?
    9682   */
    97 
    98   if ( the_message_queue->number_of_pending_messages ==
    99        the_message_queue->maximum_pending_messages ) {
    100     return CORE_MESSAGE_QUEUE_STATUS_TOO_MANY;
    101   }
    102 
    103   the_message = _CORE_message_queue_Allocate_message_buffer(the_message_queue);
    104   if ( the_message == 0 )
    105     return CORE_MESSAGE_QUEUE_STATUS_UNSATISFIED;
    106 
    107   _CORE_message_queue_Copy_buffer( buffer, the_message->Contents.buffer, size );
    108   the_message->Contents.size = size;
    109   the_message->priority  = submit_type;
    110 
    111   the_message_queue->number_of_pending_messages += 1;
    112 
    113   switch ( submit_type ) {
    114     case CORE_MESSAGE_QUEUE_SEND_REQUEST:
    115       _CORE_message_queue_Append( the_message_queue, the_message );
    116       break;
    117     case CORE_MESSAGE_QUEUE_URGENT_REQUEST:
    118       _CORE_message_queue_Prepend( the_message_queue, the_message );
    119       break;
    120     default:
    121       /* XXX interrupt critical section needs to be addressed */
    122       {
    123         CORE_message_queue_Buffer_control *this_message;
    124         Chain_Node                        *the_node;
    125 
    126         the_message->priority = submit_type;
    127         for ( the_node = the_message_queue->Pending_messages.first ;
    128            !_Chain_Is_tail( &the_message_queue->Pending_messages, the_node ) ;
    129            the_node = the_node->next ) {
    130 
    131           this_message = (CORE_message_queue_Buffer_control *) the_node;
    132 
    133           if ( this_message->priority >= the_message->priority )
    134             continue;
    135 
    136           _Chain_Insert( the_node, &the_message->Node );
    137           break;
    138         }
    139       }
    140       break;
     83     
     84  if ( the_message_queue->number_of_pending_messages == 0 ) {
     85    the_thread = _Thread_queue_Dequeue( &the_message_queue->Wait_queue );
     86    if ( the_thread ) {
     87      _CORE_message_queue_Copy_buffer(
     88        buffer,
     89        the_thread->Wait.return_argument,
     90        size
     91      );
     92      *(unsigned32 *)the_thread->Wait.return_argument_1 = size;
     93      the_thread->Wait.count = submit_type;
     94   
     95#if defined(RTEMS_MULTIPROCESSING)
     96      if ( !_Objects_Is_local_id( the_thread->Object.id ) )
     97        (*api_message_queue_mp_support) ( the_thread, id );
     98#endif
     99      return;
     100    }
    141101  }
    142102
    143103  /*
    144    *  According to POSIX, does this happen before or after the message
    145    *  is actually enqueued.  It is logical to think afterwards, because
    146    *  the message is actually in the queue at this point.
     104   *  No one waiting on the message queue at this time, so attempt to
     105   *  queue the message up for a future receive.
    147106   */
    148107
    149   if ( the_message_queue->number_of_pending_messages == 1 &&
    150        the_message_queue->notify_handler )
    151     (*the_message_queue->notify_handler)( the_message_queue->notify_argument );
    152  
    153   return CORE_MESSAGE_QUEUE_STATUS_SUCCESSFUL;
     108  if ( the_message_queue->number_of_pending_messages <
     109       the_message_queue->maximum_pending_messages ) {
     110
     111    the_message =
     112        _CORE_message_queue_Allocate_message_buffer( the_message_queue );
     113
     114    /*
     115     *  NOTE: If the system is consistent, this error should never occur.
     116     */
     117    if ( !the_message ) {
     118      _Thread_Executing->Wait.return_code =
     119          CORE_MESSAGE_QUEUE_STATUS_UNSATISFIED;
     120      return;
     121    }
     122
     123    _CORE_message_queue_Copy_buffer(
     124      buffer,
     125      the_message->Contents.buffer,
     126      size
     127    );
     128    the_message->Contents.size = size;
     129    the_message->priority  = submit_type;
     130
     131    _CORE_message_queue_Insert_message(
     132       the_message_queue,
     133       the_message,
     134       submit_type
     135    );
     136    return;
     137  }
     138
     139  /*
     140   *  No message buffers were available so we may need to return an
     141   *  overflow error or block the sender until the message is placed
     142   *  on the queue.
     143   */
     144
     145  if ( !wait ) {
     146    _Thread_Executing->Wait.return_code = CORE_MESSAGE_QUEUE_STATUS_TOO_MANY;
     147    return;
     148  }
     149
     150  executing = _Thread_Executing;
     151
     152  _ISR_Disable( level );
     153  _Thread_queue_Enter_critical_section( &the_message_queue->Wait_queue );
     154  executing->Wait.queue              = &the_message_queue->Wait_queue;
     155  executing->Wait.id                 = id;
     156  executing->Wait.return_argument    = (void *)buffer;
     157  executing->Wait.return_argument_1  = (void *)size;
     158  executing->Wait.count              = submit_type;
     159  _ISR_Enable( level );
     160
     161  _Thread_queue_Enqueue( &the_message_queue->Wait_queue, timeout );
    154162}
  • testsuites/psxtests/psxmsgq01/init.c

    ree4ddd83 r53fb837a  
    1616#include <time.h>
    1717#include <tmacros.h>
     18#include <signal.h>   /* signal facilities */
     19
     20typedef struct {
     21  char         msg[ 50 ];
     22  int          size;
     23  unsigned int priority;
     24}Test_Message_t;
     25Test_Message_t Predefined_Msgs[MAXMSG+1];
     26Test_Message_t Predefined_Msgs[MAXMSG+1] = {
     27  { "12345678",   9, MQ_PRIO_MAX-1 },  /* Max Length Message med  */
     28  { "",           1, 1             },  /* NULL  Message      low  */
     29  { "Last",       5, MQ_PRIO_MAX   },  /* Queue Full Message hi   */ 
     30  { "No Message", 0, MQ_PRIO_MAX-1 },  /* 0 length Message   med  */
     31  { "1",          2, 0             },  /* Cause Overflow Behavior */
     32};
     33int Priority_Order[MAXMSG+1] = { 2, 0, 3, 1, MAXMSG };
     34
     35
     36typedef struct {
     37  mqd_t              mq;
     38  Test_Queue_Types   index;
     39  char              *name;
     40  int                oflag;
     41  int                maxmsg;
     42  int                msgsize;
     43  int                count;
     44} Test_queue_type;
     45
     46Test_queue_type Test_q[ NUMBER_OF_TEST_QUEUES ] =
     47{
     48  { 0, 0, "Qread",    ( O_CREAT | O_RDONLY | O_NONBLOCK ), MAXMSG, MSGSIZE, 0 },
     49  { 0, 1, "Qwrite",   ( O_CREAT | O_WRONLY | O_NONBLOCK ), MAXMSG, MSGSIZE, 0 },
     50  { 0, 2, "Qnoblock", ( O_CREAT | O_RDWR   | O_NONBLOCK ), MAXMSG, MSGSIZE, 0 },
     51  { 0, 3, "Qblock",   ( O_CREAT | O_RDWR )               , MAXMSG, MSGSIZE, 0 },
     52  { 0, 4, "Qdefault", ( O_CREAT | O_RDWR )               , 10,     16,      0 },
     53  { 0, 5, "mq6",      ( O_CREAT | O_WRONLY | O_NONBLOCK ), MAXMSG, MSGSIZE, 0 },
     54};
     55
     56#define RW_NAME             Test_q[ RW_QUEUE ].name
     57#define DEFAULT_NAME        Test_q[ DEFAULT_RW ].name
     58#define RD_NAME             Test_q[ RD_QUEUE ].name
     59#define WR_NAME             Test_q[ WR_QUEUE ].name
     60#define BLOCKING_NAME       Test_q[ BLOCKING ].name
     61#define CLOSED_NAME         Test_q[ CLOSED ].name
     62
     63#define RW_ATTR         Test_q[ RW_QUEUE ].oflag
     64#define DEFAULT_ATTR    Test_q[ DEFAULT_RW ].oflag
     65#define RD_ATTR         Test_q[ RD_QUEUE ].oflag
     66#define WR_ATTR         Test_q[ WR_QUEUE ].oflag
     67#define BLOCK_ATTR      Test_q[ BLOCKING ].oflag
     68#define CLOSED_ATTR     Test_q[ CLOSED ].oflag
     69
     70/*
     71 * Outputs a header at each test section.
     72 */
     73void Start_Test(
     74  char *description
     75)
     76{
     77  printf( "_______________%s\n", description );
     78}
     79
     80
     81void Validate_attributes(
     82    mqd_t  mq,
     83    int    oflag,
     84    int    msg_count
     85)
     86{
     87  int             status;
     88  struct mq_attr  attr;
     89
     90  status = mq_getattr( mq, &attr );
     91  fatal_posix_service_status( status, 0, "mq_getattr valid return status");
     92 
     93  if ( mq != Test_q[ DEFAULT_RW ].mq ){
     94    fatal_int_service_status((int)attr.mq_maxmsg, MAXMSG, "maxmsg attribute" );
     95    fatal_int_service_status((int)attr.mq_msgsize,MSGSIZE,"msgsize attribute");
     96  }
     97
     98  fatal_int_service_status((int)attr.mq_curmsgs, msg_count, "count attribute" );
     99  fatal_int_service_status((int)attr.mq_flags, oflag, "flag attribute" );
     100}
    18101
    19102char Queue_Name[PATH_MAX + 2];
    20 char *Get_Queue_Name(
    21   int i
    22 )
    23 {
    24   sprintf(Queue_Name,"mq%d",i+1);
     103#define Get_Queue_Name( i )  Test_q[i].name
     104
     105char *Build_Queue_Name( int i ) {
     106  sprintf(Queue_Name,"mq%d", i+1 );
    25107  return Queue_Name;
    26108}
     
    36118}
    37119
    38 typedef enum {
    39   DEFAULT_SIZE_TYPE,
    40   TEST_SIZE_TYPE,
    41   MAX_SIZE,
    42   TYPES_OF_TEST_SIZES
    43 } TEST_MQ_SIZE_TYPES;
    44 
     120
     121void open_test_queues()
     122{
     123  struct mq_attr   attr;
     124  int              status;
     125  Test_queue_type *tq;
     126  int              que;
     127
     128  attr.mq_maxmsg  = MAXMSG;
     129  attr.mq_msgsize = MSGSIZE;
     130
     131  puts( "Init: Open Test Queues" );
     132
     133  for( que = 0; que < NUMBER_OF_TEST_QUEUES; que++ ) {
     134
     135    tq = &Test_q[ que ];
     136    if ( que == DEFAULT_RW)
     137      Test_q[que].mq = mq_open( tq->name, tq->oflag, 0x777, NULL );
     138    else
     139      Test_q[que].mq = mq_open( tq->name, tq->oflag, 0x777, &attr );
     140
     141    assert( Test_q[que].mq != (-1) );
     142  }
     143
     144  status = mq_close( Test_q[CLOSED].mq );
     145  fatal_posix_service_status( status, 0, "mq_close message queue");
     146  status = mq_unlink( CLOSED_NAME );
     147  fatal_posix_service_status( status, 0, "mq_unlink message queue");
     148}
    45149
    46150/*
     
    49153 */
    50154
    51 void validate_mq_open_error_codes(
    52   mqd_t   *mqs,      /* Must be large enough for Maximum to be opened. */
    53   int      size
    54 )
     155void validate_mq_open_error_codes()
    55156{
    56157  int             i;
     
    58159  struct mq_attr  attr;
    59160  int             status;
    60 
    61   assert( size < (CONFIGURE_MAXIMUM_POSIX_MESSAGE_QUEUES-1) );
    62 
    63   /*
    64    * Validate mq_open errors that can occur when no queues are open.
    65    *  EINVAL
    66    *  ENOENT
    67    *  EINTR
    68    */
     161  mqd_t           open_mq[CONFIGURE_MAXIMUM_POSIX_MESSAGE_QUEUES];
     162
     163  attr.mq_maxmsg  = MAXMSG;
     164  attr.mq_msgsize = MSGSIZE;
     165
     166  Start_Test( "mq_open errors" );
    69167
    70168  /*
     
    72170   */
    73171
     172  /*
     173   * EINVAL - Create with negative maxmsg.
     174   */
     175
    74176  attr.mq_maxmsg = -1;
    75   puts( "mq_open - Create with maxmsg (-1) (EINVAL)" );
    76   n_mq2 = mq_open("mq2", O_CREAT | O_RDONLY, 0x777, &attr);
    77   fatal_directive_status(
     177  puts( "Init: mq_open - Create with maxmsg (-1) (EINVAL)" );
     178  n_mq2 = mq_open( "mq2", O_CREAT | O_RDONLY, 0x777, &attr);
     179  fatal_posix_service_status(
    78180    (int) n_mq2, (int ) (-1), "mq_open error return status" );
    79   fatal_directive_status( errno, EINVAL,  "mq_open errno EINVAL");
     181  fatal_posix_service_status( errno, EINVAL,  "mq_open errno EINVAL");
     182  attr.mq_maxmsg  = MAXMSG;
     183
     184  /*
     185   * EINVAL - Create withnegative msgsize.
     186   */
    80187
    81188  attr.mq_msgsize = -1;
    82   puts( "mq_open - Create with msgsize (-1) (EINVAL)" );
    83   n_mq2 = mq_open("mq2", O_CREAT | O_RDONLY, 0x777, &attr);
    84   fatal_directive_status(
     189  puts( "Init: mq_open - Create with msgsize (-1) (EINVAL)" );
     190  n_mq2 = mq_open( "mq2", O_CREAT | O_RDONLY, 0x777, &attr);
     191  fatal_posix_service_status(
    85192    (int) n_mq2, (int ) (-1), "mq_open error return status" );
    86   fatal_directive_status( errno, EINVAL,  "mq_open errno EINVAL");
    87 
    88   puts( "mq_open - Open new mq without create flag (ENOENT)" );
    89   n_mq2 = mq_open("mq3", O_EXCL | O_RDONLY, 0x777, NULL);
    90   fatal_directive_status(
     193  fatal_posix_service_status( errno, EINVAL,  "mq_open errno EINVAL");
     194  attr.mq_msgsize = MSGSIZE;
     195
     196  /*
     197   * ENOENT - Open a non-created file.
     198   */
     199
     200  puts( "Init: mq_open - Open new mq without create flag (ENOENT)" );
     201  n_mq2 = mq_open( "mq3", O_EXCL | O_RDONLY, 0x777, NULL);
     202  fatal_posix_service_status(
    91203    (int) n_mq2, (int ) (-1), "mq_open error return status" );
    92   fatal_directive_status( errno, ENOENT,  "mq_open errno ENOENT");
     204  fatal_posix_service_status( errno, ENOENT,  "mq_open errno ENOENT");
     205
    93206
    94207  /*
     
    97210
    98211  /*
    99    * XXX ENAMETOOLONG - Not checked in either sem_open or mq_open is
    100    *                    this an error?
    101    */
    102 
    103   puts( "mq_open - Open with too long of a name (ENAMETOOLONG)" );
     212   * ENAMETOOLONG - Give a name greater than PATH_MAX.
     213   */
     214
     215  puts( "Init: mq_open - Open with too long of a name (ENAMETOOLONG)" );
    104216  n_mq2 = mq_open( Get_Too_Long_Name(), O_CREAT | O_RDONLY, 0x777, NULL );
    105   fatal_directive_status(
     217  fatal_posix_service_status(
    106218    (int) n_mq2, (int ) (-1), "mq_open error return status" );
    107   fatal_directive_status( errno, ENAMETOOLONG,  "mq_open errno ENAMETOOLONG");
     219  fatal_posix_service_status( errno, ENAMETOOLONG, "mq_open errno ENAMETOOLONG");
    108220 
    109221  /*
     222   * XXX - ENAMETOOLONG - Give a name greater than NAME_MAX
     223   *       Per implementation not possible.
     224   */
     225
     226  /*
    110227   * Open maximum number of message queues
    111228   */
    112229
    113   puts( "mq_open - SUCCESSFUL" );
     230  puts( "Init: mq_open - SUCCESSFUL" );
    114231  for (i = 0; i < CONFIGURE_MAXIMUM_POSIX_MESSAGE_QUEUES; i++) {
    115     mqs[i] = mq_open( Get_Queue_Name(i), O_CREAT | O_RDWR, 0x777, NULL );
    116     assert( mqs[i] != (-1) );
     232    open_mq[i] = mq_open(
     233      Build_Queue_Name(i), O_CREAT | O_RDWR | O_NONBLOCK, 0x777, NULL );
     234    assert( open_mq[i] != (-1) );
    117235    /*XXX - Isn't there a more general check */
    118236  }
    119237
    120238  /*
    121    * Validate open errors that must occur after message queues are open.
    122    *   EACCES
    123    *   EEXIST
    124    *   EMFILE
    125    *   ENFILE
    126    */
    127 
    128   /*
    129239   * XXX EACCES - permission to create is denied.
    130240   */
     
    132242  /*
    133243   * XXX EACCES - queue exists permissions specified by o_flag are denied.
    134   puts( "mq_open - open mq as write (EACCES)" );
    135   n_mq2 = mq_open("mq1", O_CREAT | O_WRONLY, 0x777, NULL);
    136   fatal_directive_status(
     244   */
     245
     246  /*
     247   * EEXIST - Create an existing queue.
     248   */
     249
     250  puts( "Init: mq_open - Create an Existing mq (EEXIST)" );
     251  n_mq2 = mq_open(
     252    Build_Queue_Name(0), O_CREAT | O_EXCL | O_RDONLY, 0x777, NULL);
     253  fatal_posix_service_status(
    137254    (int) n_mq2, (int ) (-1), "mq_open error return status" );
    138   fatal_directive_status( errno, EACCES,  "mq_open errno EACCES");
    139    */
    140 
    141   puts( "mq_open - Create an Existing mq (EEXIST)" );
    142   n_mq2 = mq_open("mq1", O_CREAT | O_EXCL | O_RDONLY, 0x777, NULL);
    143   fatal_directive_status(
     255  fatal_posix_service_status( errno, EEXIST,  "mq_open errno EEXIST");
     256
     257  /*
     258   * XXX EMFILE  - Too many message queues in use by the process
     259   */
     260
     261  /*
     262   * ENFILE -  Too many message queues open in the system
     263   */
     264
     265  puts( "Init: mq_open - system is out of resources (ENFILE)" );
     266  n_mq2 = mq_open( Build_Queue_Name(i), O_CREAT | O_RDONLY, 0x777, NULL );
     267  fatal_posix_service_status(
    144268    (int) n_mq2, (int ) (-1), "mq_open error return status" );
    145   fatal_directive_status( errno, EEXIST,  "mq_open errno EEXIST");
    146 
    147 
    148   /*
    149    * XXX EMFILE  - Too many message queues open
    150    */
    151 
    152   puts( "mq_open - system is out of resources (ENFILE)" );
    153   n_mq2 = mq_open( Get_Queue_Name(i), O_CREAT | O_RDONLY, 0x777, NULL );
    154   fatal_directive_status(
    155     (int) n_mq2, (int ) (-1), "mq_open error return status" );
    156   fatal_directive_status( errno, ENFILE,  "mq_open errno ENFILE");
    157 
    158   /*
    159    * Unlink and Close .
    160    */
    161 
    162   puts( "mq_close and mq_unlink (mq3...mqn) - SUCCESSFUL" );
    163   for (i = size; i < CONFIGURE_MAXIMUM_POSIX_MESSAGE_QUEUES; i++) {
    164 
    165     status = mq_close( mqs[i] );
    166     fatal_directive_status( status, 0, "mq_close message queue");
    167 
    168     status = mq_unlink( Get_Queue_Name(i) );
    169     fatal_directive_status( status, 0, "mq_unlink message queue");
    170   }
    171 }
    172 
    173 void validate_mq_unlink_error_codes(
    174   mqd_t   *mqs,     
    175   int      size      /* Number still open in mqs */
    176 )
     269  fatal_posix_service_status( errno, ENFILE,  "mq_open errno ENFILE");
     270
     271  /*
     272   * Unlink and Close all queues.
     273   */
     274
     275  puts( "Init: mq_close and mq_unlink (mq3...mqn) - SUCCESSFUL" );
     276  for (i = 0; i < CONFIGURE_MAXIMUM_POSIX_MESSAGE_QUEUES; i++) {
     277
     278    status = mq_close( open_mq[i]);
     279    fatal_posix_service_status( status, 0, "mq_close message queue");
     280
     281    status = mq_unlink( Build_Queue_Name(i) );
     282    fatal_posix_service_status( status, 0, "mq_unlink message queue");
     283  }
     284}
     285
     286void validate_mq_unlink_error_codes()
    177287{
    178288  int             status;
    179289
     290  Start_Test( "mq_unlink errors" );
     291
    180292  /*
    181293   * XXX - EACCES Permission Denied
     
    183295
    184296  /*
    185    * XXX ENAMETOOLONG - Not checked in either sem_unlink or mq_unlink is
    186    *                    this an error?
    187    */
    188 
    189   puts( "mq_unlink - mq_unlink with too long of a name (ENAMETOOLONG)" );
     297   * ENAMETOOLONG - Give a name greater than PATH_MAX.
     298   */
     299
     300  puts( "Init: mq_unlink - mq_unlink with too long of a name (ENAMETOOLONG)" );
    190301  status = mq_unlink( Get_Too_Long_Name() );
    191   fatal_directive_status( status, -1, "mq_unlink error return status");
    192   fatal_directive_status( errno, ENAMETOOLONG, "mq_unlink errno ENAMETOOLONG");
     302  fatal_posix_service_status( status, -1, "mq_unlink error return status");
     303  fatal_posix_service_status( errno, ENAMETOOLONG, "mq_unlink errno ENAMETOOLONG");
    193304 
    194   puts( "mq_unlink - UNSUCCESSFUL (ENOENT)" );
    195   status = mq_unlink(Get_Queue_Name(size));
    196   fatal_directive_status( status, -1, "mq_unlink error return status");
    197   fatal_directive_status( errno, ENOENT, "mq_unlink errno ENOENT");
    198 
    199   /*
    200    * XXX - These errors are not in the POSIX manual but may occur.
    201    */
    202 
    203   puts( "mq_unlink (NULL) - EINVAL" );
     305  /*
     306   * XXX - ENAMETOOLONG - Give a name greater than NAME_MAX
     307   *       Per implementation not possible.
     308   */
     309
     310  /*
     311   *  ENOENT - Unlink an unopened queue
     312   */
     313
     314  puts( "Init: mq_unlink - A Queue not opened  (ENOENT)" );
     315  status = mq_unlink( CLOSED_NAME );
     316  fatal_posix_service_status( status, -1, "mq_unlink error return status");
     317  fatal_posix_service_status( errno, ENOENT, "mq_unlink errno ENOENT");
     318
     319  /*
     320   * XXX - The following were not listed in the POSIX document as
     321   *       possible errors.  Under other commands the EINVAL is
     322   *       given for these conditions.
     323   */
     324
     325  /*
     326   *  EINVAL - Unlink a queue with no name
     327   */
     328
     329  puts( "Init: mq_unlink (NULL) - EINVAL" );
    204330  status = mq_unlink( NULL );
    205   fatal_directive_status( status, -1, "mq_unlink error return status");
    206   fatal_directive_status( errno, EINVAL, "mq_unlink errno value");
    207 
    208   puts( "mq_unlink (\"\") - EINVAL" );
     331  fatal_posix_service_status( status, -1, "mq_unlink error return status");
     332  fatal_posix_service_status( errno, EINVAL, "mq_unlink errno value");
     333
     334  /*
     335   *  EINVAL - Unlink a queue with a null name
     336   */
     337
     338  puts( "Init: mq_unlink (\"\") - EINVAL" );
    209339  status = mq_unlink( "" );
    210   fatal_directive_status( status, -1, "mq_unlink error return status");
    211   fatal_directive_status( errno, EINVAL, "mq_unlink errno value");
    212 }
    213 
    214 void validate_mq_close_error_codes(
    215   mqd_t   *mqs,     
    216   int      size      /* Number still open in mqs */
    217 )
     340  fatal_posix_service_status( status, -1, "mq_unlink error return status");
     341  fatal_posix_service_status( errno, EINVAL, "mq_unlink errno value");
     342}
     343
     344void validate_mq_close_error_codes()
    218345{
    219346  int             status;
    220347
    221   puts( "mq_close - UNSUCCESSFUL (EBADF)" );
    222   status = mq_close(mqs[size]);
    223   fatal_directive_status( status, -1, "mq_close error return status");
    224   fatal_directive_status( errno, EBADF, "mq_close errno EBADF");
     348  Start_Test( "mq_close errors" );
     349
     350  /*
     351   * EBADF - Close a queue that is not open.
     352   */
     353
     354  puts( "Init: mq_close - unopened queue (EBADF)" );
     355  status = mq_close( Test_q[CLOSED].mq );
     356  fatal_posix_service_status( status, -1, "mq_close error return status");
     357  fatal_posix_service_status( errno, EBADF, "mq_close errno EBADF");
    225358}
    226359 
     360
     361void validate_mq_getattr_error_codes()
     362{
     363  struct mq_attr  attr;
     364  int             status;
     365
     366  Start_Test( "mq_getattr errors" );
     367
     368  /*
     369   * EBADF - Get the attributes from a closed queue.
     370   */
     371
     372  puts( "Init: mq_getattr - unopened queue (EBADF)" );
     373  status = mq_getattr( Test_q[CLOSED].mq, &attr );
     374  fatal_posix_service_status( status, -1, "mq_close error return status");
     375  fatal_posix_service_status( errno, EBADF, "mq_close errno EBADF"); 
     376
     377  /*
     378   * XXX - The following are not listed in the POSIX manual but
     379   *       may occur.
     380   */
     381
     382  /*
     383   * EINVAL - NULL attributes
     384   */
     385
     386  puts( "Init: mq_getattr - NULL attributes (EINVAL)" );
     387  status = mq_getattr( Test_q[RW_QUEUE].mq, NULL );
     388  fatal_posix_service_status( status, -1, "mq_close error return status");
     389  fatal_posix_service_status( errno, EINVAL, "mq_close errno EINVAL"); 
     390
     391}
     392
     393
     394void Send_msg_to_que(
     395  int que,
     396  int msg
     397)
     398{
     399  Test_Message_t *ptr = &Predefined_Msgs[msg];
     400  int             status;
     401
     402  status = mq_send( Test_q[que].mq, ptr->msg, ptr->size , ptr->priority );
     403  fatal_posix_service_status( status, 0, "mq_send valid return status");
     404  Test_q[que].count++;
     405}
     406
     407void Show_send_msg_to_que(
     408  char *task_name,
     409  int   que,
     410  int   msg
     411)
     412{
     413  Test_Message_t *ptr = &Predefined_Msgs[msg];
     414  printf( "%s mq_send -  to %s msg: %s priority %d\n",
     415    task_name, Test_q[que].name, ptr->msg, ptr->priority);
     416  Send_msg_to_que( que, msg );
     417}
     418
     419void verify_queues_full( 
     420  char *task_name
     421)
     422{
     423  int          que;
     424
     425  /*
     426   * Validate that the queues are full.
     427   */
     428
     429  printf( "%s Verify Queues are full\n", task_name );
     430  for( que = RW_QUEUE; que < CLOSED; que++ )
     431    Validate_attributes( Test_q[que].mq, Test_q[que].oflag, Test_q[que].count );
     432
     433}
     434void verify_queues_empty(
     435  char *task_name
     436)
     437{
     438  int             que;
     439
     440  printf( "%s Verify Queues are empty\n", task_name );
     441  for( que = RW_QUEUE; que < CLOSED; que++ )
     442    Validate_attributes( Test_q[que].mq, Test_q[que].oflag, 0 );
     443}
     444
     445int fill_message_queues(
     446  char *task_name
     447)
     448{
     449  int             msg;
     450  int             status;
     451  int             que;
     452
     453
     454  verify_queues_empty( task_name );
     455
     456  /*
     457   * Fill Queue with predefined messages.
     458   */
     459
     460  printf( "%s Fill Queues with messages\n", task_name );
     461  for(msg=0; msg<MAXMSG; msg++){
     462    for( que = RW_QUEUE; que < CLOSED; que++ ) {
     463      Send_msg_to_que( que, msg );
     464    }
     465  }
     466
     467  verify_queues_full( "Init:" );
     468  return msg;
     469}
     470
     471
     472void Read_msg_from_que(
     473  int que,
     474  int msg
     475)
     476{
     477  unsigned int    priority;
     478  Test_Message_t *ptr;
     479  int             status;
     480  char            message[100];
     481  char            err_msg[100];
     482
     483  ptr = &Predefined_Msgs[msg];
     484  status = mq_receive(Test_q[ que ].mq, message, 100, &priority );
     485  Test_q[que].count--;
     486
     487  sprintf( err_msg, "%s msg %s size failure", Test_q[ que ].name, ptr->msg );
     488  fatal_int_service_status( status, ptr->size, err_msg );
     489
     490  assert( !strcmp( message, ptr->msg ) );
     491  strcpy( message, "No Message" );
     492
     493  sprintf( err_msg,"%s msg %s size failure", Test_q[ que ].name, ptr->msg );
     494  fatal_int_service_status(priority, ptr->priority, err_msg );
     495}
     496
     497int empty_message_queues(
     498  char *task_name
     499)
     500{
     501  int que;
     502  int i;
     503
     504  printf( "%s Empty all Queues\n", task_name );
     505  for( que = RW_QUEUE; que < CLOSED; que++ ) {
     506    for(i=0; Test_q[que].count != 0; i++ )
     507      Read_msg_from_que( que,  Priority_Order[i] );
     508
     509    Validate_attributes( Test_q[ que].mq, Test_q[ que ].oflag, 0 );
     510  }
     511  return 0;
     512}
     513
    227514/*
    228515 * Returns the number of messages queued after the test on the
     
    230517 */
    231518
    232 int validate_mq_send_error_codes(
    233   mqd_t   *mqs,
    234   int      size      /* Number still open in mqs */
    235 )
     519int validate_mq_send_error_codes( )
    236520{
    237521  int             status;
    238522  int             i;
    239   mqd_t           n_mq1;
     523  char           *str;
     524
     525  Start_Test( "mq_send errors" );
     526
     527  /*
     528   * EBADF - Write to a closed queue.
     529   */
     530
     531  puts( "Init: mq_send - Closed message queue (EBADF)" );
     532  status = mq_send( Test_q[CLOSED].mq, "", 1, 0 );
     533  fatal_posix_service_status( status, -1, "mq_send error return status");
     534  fatal_posix_service_status( errno, EBADF, "mq_send errno EBADF");
     535
     536  /*
     537   * EBADF - Write to a read only  queue.
     538   */
     539
     540  puts( "Init: mq_send - Read only message queue (EBADF)" );
     541  status = mq_send( Test_q[ RD_QUEUE ].mq, "", 1, 0 );
     542  fatal_posix_service_status( status, -1, "mq_send error return status");
     543  fatal_posix_service_status( errno, EBADF, "mq_send errno EBADF");
     544
     545  /*
     546   * XXX - EINTR      Signal interrupted the call.
     547   *
     548  puts( "Init: mq_send - UNSUCCESSFUL (EINTR)" );
     549  status = mq_send( Test_q, "", 0xffff, 0 );
     550  fatal_posix_service_status( status, -1, "mq_send error return status");
     551  fatal_posix_service_status( errno, E, "mq_send errno E");
     552   */
     553
     554  /*
     555   * EINVAL priority is out of range.
     556   */
     557
     558  puts( "Init: mq_send - Priority out of range (EINVAL)" );
     559  status = mq_send( Test_q[ RW_QUEUE ].mq, "", 1, MQ_PRIO_MAX + 1 );
     560  fatal_posix_service_status( status, -1, "mq_send error return status");
     561  fatal_posix_service_status( errno, EINVAL, "mq_send errno EINVAL");
     562
     563  /*
     564   *  EMSGSIZE - Message size larger than msg_len
     565   *             Validates that msgsize is stored correctly.
     566   */
     567
     568  puts( "Init: mq_send - Message longer than msg_len (EMSGSIZE)" );
     569  status = mq_send( Test_q[ RW_QUEUE ].mq, "", MSGSIZE+1, 0 );
     570  fatal_posix_service_status( status, -1, "mq_send error return status");
     571  fatal_posix_service_status( errno, EMSGSIZE, "mq_send errno EMSGSIZE");
     572
     573  i = fill_message_queues( "Init:" );
     574
     575  /*
     576   * ENOSYS - send not supported
     577  puts( "Init: mq_send - Blocking Queue overflow (ENOSYS)" );
     578  status = mq_send( n_mq1, Predefined_Msgs[i], 0, 0 );
     579  fatal_posix_service_status( status, -1, "mq_send error return status");
     580  fatal_posix_service_status( errno, EBADF, "mq_send errno EBADF");
     581
     582  status = mq_close( n_mq1 );
     583  fatal_posix_service_status( status, 0, "mq_close message queue");
     584
     585  status = mq_unlink( "read_only" );
     586  fatal_posix_service_status( status, 0, "mq_unlink message queue");
     587   */
     588
     589  /*
     590   * EAGAIN - O_NONBLOCK and message queue is full.
     591   */
     592
     593  puts( "Init: mq_send - on a FULL non-blocking queue with (EAGAIN)" );
     594  str = Predefined_Msgs[i].msg;
     595  status = mq_send(Test_q[RW_QUEUE].mq, str, 0, 0 );
     596  fatal_posix_service_status( status, -1, "mq_send error return status");
     597  fatal_posix_service_status( errno, EAGAIN, "mq_send errno EAGAIN");
     598
     599  return i-1;
     600}
     601
     602void validate_mq_receive_error_codes( )
     603{
     604  int            status;
     605  char           message[100];
     606  unsigned int   priority;
     607  int            i;
     608
     609  Start_Test( "mq_receive errors"  );
     610
     611  /*
     612   * EBADF - Not A Valid Message Queue
     613   */
     614
     615  puts( "Init: mq_receive - Unopened message queue (EBADF)" );
     616  status = mq_receive( Test_q[CLOSED].mq, message, 100, &priority );
     617  fatal_posix_service_status( status, -1, "mq_ error return status");
     618  fatal_posix_service_status( errno, EBADF, "mq_receive errno EBADF");
     619
     620  /*
     621   * EBADF - Queue not opened to read
     622   */
     623
     624  puts( "Init: mq_receive - Write only queue (EBADF)" );
     625  status = mq_receive( Test_q[WR_QUEUE].mq, message, 100, &priority  );
     626  fatal_posix_service_status( status, -1, "mq_ error return status");
     627  fatal_posix_service_status( errno, EBADF, "mq_receive errno EBADF");
     628
     629  /*
     630   * EMSGSIZE - Size is less than the message size attribute
     631   */
     632
     633  puts( "Init: mq_receive - Size is less than the message (EMSGSIZE)" );
     634  status = mq_receive(
     635    Test_q[RW_QUEUE].mq, message, Predefined_Msgs[0].size-1, &priority );
     636  fatal_posix_service_status( status, -1, "mq_ error return status");
     637  fatal_posix_service_status( errno, EMSGSIZE, "mq_receive errno EMSGSIZE");
     638
     639
     640  /*
     641   * EAGAIN - O_NONBLOCK and Queue is empty
     642   */
     643  verify_queues_full( "Init:" );
     644  empty_message_queues( "Init:" );
     645
     646  puts( "Init: mq_receive - Queue is empty (EAGAIN)" );
     647  status = mq_receive( Test_q[RW_QUEUE].mq, message, 100, &priority );
     648  fatal_posix_service_status( status, -1, "mq_ error return status");
     649  fatal_posix_service_status( errno, EAGAIN, "mq_receive errno EAGAIN");
     650
     651  /*
     652   * XXX - EINTR - Interrupted by a signal
     653   */
     654
     655  /*
     656   * XXX - EBADMSG - a data corruption problem.
     657   */
     658
     659  /*
     660   * XXX - ENOSYS - mq_receive not supported
     661   */
     662}
     663
     664void verify_open_functionality()
     665{
     666  mqd_t           n_mq;
     667
     668  Start_Test( "mq_open functionality" );
     669
     670  /*
     671   * Validate a second open returns the same message queue.
     672   */
     673
     674  puts( "Init: mq_open - Open an existing mq ( same id )" );
     675  n_mq = mq_open( RD_NAME, 0 );
     676  fatal_posix_service_status(
     677    (int) n_mq, (int ) Test_q[RD_QUEUE].mq, "mq_open error return status" );
     678}
     679
     680void verify_unlink_functionality()
     681
     682  mqd_t           n_mq;
     683  int             status;
     684
     685  Start_Test( "mq_unlink functionality" );
     686
     687  /*
     688   * Unlink the message queue, then verify an open of the same name produces a
     689   * different message queue.
     690   */
     691
     692  puts( "Init: Unlink and Open without closing SUCCESSFUL" );
     693  status = mq_unlink( DEFAULT_NAME );
     694  fatal_posix_service_status( status, 0, "mq_unlink locked message queue");
     695
     696  n_mq = mq_open( DEFAULT_NAME, DEFAULT_ATTR, 0x777, NULL );
     697  assert( n_mq != (-1) );
     698  assert( n_mq != Test_q[ DEFAULT_RW ].mq );
     699
     700
     701  status = mq_unlink( DEFAULT_NAME );
     702  fatal_posix_service_status( status, 0, "mq_unlink locked message queue");
     703  status = mq_close( Test_q[ DEFAULT_RW ].mq );
     704  fatal_posix_service_status( status, 0, "mq_close message queue");
     705
     706  Test_q[ DEFAULT_RW ].mq = n_mq;
     707}
     708
     709void verify_close_functionality()
     710{
     711  int i;
     712  int status;
     713  Start_Test( "Unlink and Close All Files"  );
     714  for (i=0; i<DEFAULT_RW; i++) {
     715   
     716    status = mq_unlink( Get_Queue_Name(i) );
     717    fatal_posix_service_status( status, 0, "mq_unlink message queue");
     718
     719    status = mq_close( Test_q[i].mq );
     720    fatal_posix_service_status( status, 0, "mq_close message queue");
     721  }
     722}
     723
     724
     725void verify_timed_send_queue(
     726  int  que,
     727  int  is_blocking
     728)
     729{
     730  int             i;
     731  struct timespec timeout;
     732  struct timeval  tv1, tv2, tv3;
     733  struct timezone tz1, tz2;
     734  int              len;
     735  int              status;
     736  char            *msg;
     737
     738  timeout.tv_sec  = 1;
     739  timeout.tv_nsec = 0;
     740 
     741  printf( "Init: mq_timedsend - on queue %s ", Test_q[que].name);
     742  len = Predefined_Msgs[MAXMSG].size;
     743  msg = Predefined_Msgs[MAXMSG].msg;
     744  gettimeofday( &tv1, &tz1 );
     745  status = mq_timedsend( Test_q[que].mq, msg, len , 0, &timeout );
     746  gettimeofday( &tv2, &tz2 );
     747  tv3.tv_sec  = tv2.tv_sec - tv1.tv_sec;
     748  tv3.tv_usec = tv2.tv_usec - tv1.tv_usec;
     749
     750  if ( is_blocking ) { /* Don't verify the non-blocking queue */
     751    fatal_int_service_status( status, -1, "mq_timedsend status");
     752    fatal_posix_service_status( errno, ETIMEDOUT,  "errno ETIMEDOUT");
     753  }
     754
     755  printf("Init: %d sec %d us\n", tv3.tv_sec, tv3.tv_usec );
     756
     757  if ( is_blocking ) /* non-blocking queue */
     758    assert( tv3.tv_sec == 1 );
     759  else
     760    assert( tv3.tv_sec == 0 );
     761
     762  if ( que == DEFAULT_RW )
     763    Test_q[que].count++;
     764}
     765
     766void verify_timed_send()
     767{
     768  int              que;
     769
     770  Start_Test( "mq_timedsend"  );
     771
     772  for( que = RW_QUEUE; que < CLOSED; que++ ) {
     773    if ( que == BLOCKING )
     774      verify_timed_send_queue( que, 1 );
     775    else
     776      verify_timed_send_queue( que, 0 );
     777  }
     778}
     779
     780void verify_timed_receive_queue(
     781  char *task_name,
     782  int   que,
     783  int   is_blocking
     784)
     785{
     786  char message[ 100 ];
     787  unsigned int priority;
     788  struct timespec tm;
     789  struct timeval  tv1, tv2, tv3;
     790  struct timezone tz1, tz2;
     791  int              status;
     792 
     793  tm.tv_sec  = 1;
     794  tm.tv_nsec = 0;
     795
     796  printf( "Init: %s mq_timedreceive - on queue %s ", task_name, Test_q[que].name);
     797
     798  gettimeofday( &tv1, &tz1 );
     799  status = mq_timedreceive( Test_q[ que ].mq, message, 100, &priority, &tm );
     800  gettimeofday( &tv2, &tz2 );
     801  tv3.tv_sec  = tv2.tv_sec - tv1.tv_sec;
     802  tv3.tv_usec = tv2.tv_usec - tv1.tv_usec;
     803
     804  fatal_int_service_status( status, -1, "mq_timedreceive status");
     805  if ( is_blocking )
     806    fatal_posix_service_status( errno, ETIMEDOUT,  "errno ETIMEDOUT");
     807  printf( "Init: %d sec %d us\n", tv3.tv_sec, tv3.tv_usec );
     808
     809  if ( is_blocking )
     810    assert( tv3.tv_sec == 1 );
     811  else
     812    assert( tv3.tv_sec == 0 );
     813}
     814
     815
     816
     817void verify_timed_receive()
     818{
     819  int  que;
     820 
     821  Start_Test( "mq_timedreceive"  );
     822
     823  for( que = RW_QUEUE; que < CLOSED; que++ ) {
     824    if (( que == BLOCKING ) || ( que == DEFAULT_RW ))
     825      verify_timed_receive_queue( "Init:", que, 1 );
     826    else
     827      verify_timed_receive_queue( "Init:", que, 0 );
     828  }
     829}
     830
     831#if (0)
     832void verify_set_attr()
     833{
     834  struct mq_attr save_attr[ NUMBER_OF_TEST_QUEUES ];
     835  struct mq_attr attr;
     836  int            i;
     837  int            status;
     838
     839  attr.mq_maxmsg  = 0;
     840  attr.mq_msgsize = 0;
     841
     842  Start_Test( "mq_setattr"  );
     843
     844  puts( "Init: set_attr all queues to blocking" );
     845  for(i=0; i<CLOSED; i++) {
     846    attr.mq_flags =  Test_q[i].oflag & (~O_NONBLOCK );
     847    status = mq_setattr( Test_q[i].mq, &attr, &save_attr[i] );
     848    fatal_int_service_status( status, 0, "mq_setattr valid return status");
     849
     850    Validate_attributes( Test_q[i].mq, attr.mq_flags, 0 );
     851  }
     852
     853  for( i = RW_QUEUE; i < CLOSED; i++ ) {
     854    verify_timed_receive_queue( "Init:", i, 1 );
     855  }
     856 
     857  for(i=0; i<CLOSED; i++) {
     858    attr.mq_flags =  Test_q[i].oflag & (~O_NONBLOCK );
     859    status = mq_setattr( Test_q[i].mq, &save_attr[i], NULL );
     860    fatal_int_service_status( status, 0, "mq_setattr valid return status");
     861
     862    Validate_attributes( Test_q[i].mq, Test_q[i].oflag, 0 );
     863  }
     864}
     865#endif
     866
     867void wait_for_signal(
     868  sigset_t     *waitset,
     869  int           sec,
     870  int           expect_signal
     871)
     872{
     873  siginfo_t         siginfo;
     874  int               status;
     875  struct timespec   timeout;
     876  int               signo;
     877
     878  siginfo.si_code = -1;
     879  siginfo.si_signo = -1;
     880  siginfo.si_value.sival_int = -1;
     881
     882  timeout.tv_sec = sec;
     883  timeout.tv_nsec = 0;
     884
     885  status = sigemptyset( waitset );
     886  assert( !status );
     887
     888  status = sigaddset( waitset, SIGUSR1 );
     889  assert( !status );
     890
     891  printf( "waiting on any signal for %d seconds.\n", sec );
     892  signo = sigtimedwait( waitset, &siginfo, &timeout );
     893  if (expect_signal) {
     894    fatal_int_service_status( signo, SIGUSR1, "got SISUSR1" );
     895  } else {
     896    fatal_int_service_status( signo, -1, "error return status");
     897    fatal_posix_service_status( errno, EAGAIN, "errno EAGAIN");
     898  }
     899}
     900
     901void verify_notify()
     902{
     903  struct sigevent event;
     904  int             status;
     905  timer_t         timer_id;
     906  sigset_t        set;
     907  Test_Message_t *ptr;
     908
     909  Start_Test( "mq_notify"  );
     910
     911  /* timer create */
     912  event.sigev_notify = SIGEV_SIGNAL;
     913  event.sigev_signo  = SIGUSR1;
     914  if (timer_create (CLOCK_REALTIME, &event, &timer_id) == -1)
     915    fatal_posix_service_status( errno, 0,  "errno ETIMEDOUT");
     916
     917  /* block the timer signal */
     918  sigemptyset( &set );
     919  sigaddset( &set, SIGUSR1 );
     920  pthread_sigmask( SIG_BLOCK, &set, NULL );
     921
     922  /*
     923   * EBADF - Not A Valid Message Queue
     924   */
     925
     926  puts( "Init: mq_notify - Unopened message queue (EBADF)" );
     927  status = mq_notify( Test_q[CLOSED].mq, NULL );
     928  fatal_posix_service_status( status, -1, "mq_ error return status");
     929  fatal_posix_service_status( errno, EBADF, "mq_receive errno EBADF");
     930
     931  /*
     932   * Create ...
     933   */
     934
     935  /*
     936   * XXX setup notification
     937   */
     938
     939  printf( "_____mq_notify - notify when %s gets a message\n",RW_NAME);
     940  status = mq_notify( Test_q[RW_QUEUE].mq, &event );
     941  fatal_posix_service_status( status, 0, "mq_notify valid status");
     942  wait_for_signal( &set, 3, 0 );
     943
     944  /*
     945   * Send and verify signal occurs and registration is removed.
     946   */
     947
     948  puts( "Init: Verify Signal when send" );
     949  Show_send_msg_to_que( "Init:", RW_QUEUE, 0 );
     950  wait_for_signal( &set, 3, 1 );
     951  Read_msg_from_que( RW_QUEUE, 0 );
     952
     953  puts( "Init: Verify No Signal when send" );
     954  Show_send_msg_to_que( "Init:", RW_QUEUE, 0 );
     955  wait_for_signal( &set, 3, 0 );
     956  Read_msg_from_que( RW_QUEUE, 0 );
     957
     958
     959  /*
     960   * EBUSY - Already Registered
     961   */
     962
     963  printf( "____mq_notify - notify when %s gets a message\n",RD_NAME);
     964  status = mq_notify( Test_q[RW_QUEUE].mq, &event );
     965  fatal_posix_service_status( status, 0, "mq_notify valid status");
     966  wait_for_signal( &set, 3, 0 );
     967
     968  puts( "Init: mq_notify -  (EBUSY)" );
     969  status = mq_notify( Test_q[RW_QUEUE].mq, &event );
     970  fatal_posix_service_status( status, -1, "mq_notify error return status");
     971  fatal_posix_service_status( errno, EBUSY, "mq_notify errno EBUSY");
     972
     973  /*
     974   * Verify NULL removes registration.
     975   */
     976
     977  puts( "Init: mq_notify - Remove notification with null" );
     978  status = mq_notify( Test_q[RW_QUEUE].mq, NULL );
     979  fatal_posix_service_status( status, 0, "mq_notify valid status");
     980
     981  puts( "Init: Verify No Signal when send" );
     982  Show_send_msg_to_que( "Init:", RW_QUEUE, 0 );
     983  wait_for_signal( &set, 3, 0 );
     984  Read_msg_from_que( RW_QUEUE, 0 );
     985
     986}
     987
     988void verify_with_threads()
     989{
     990  int               status;
     991  pthread_t         id;
     992  Test_Message_t   *ptr;
     993  unsigned int      priority;
     994  char              message[100];
     995
     996
     997  /*
     998   * Create a task then block until the task sends the message.
     999   * Task tests set attributes so one queue will have a thread
     1000   * blocked while attributes are changed.
     1001   */
     1002
     1003  Start_Test( "multi-thread Task 4 Receive Test"  );
     1004  status = pthread_create( &id, NULL, Task_4, NULL );
     1005  assert( !status );
     1006  puts( "Init: mq_receive - Empty queue changes to non-blocking (EAGAIN)" );
     1007  status = mq_receive( Test_q[BLOCKING].mq, message, 100, &priority );
     1008  fatal_int_service_status( status, -1, "mq_receive error return status");
     1009  fatal_posix_service_status( errno, EAGAIN, "mq_receive errno EAGAIN");
     1010  print_current_time( "Init: ", "" );
     1011
     1012  /*
     1013   * Create a task then block until the task sends the message.
     1014   * Task tests set attributes so one queue will have a thread
     1015   * blocked while attributes are changed.
     1016   */
     1017
     1018  Start_Test( "multi-thread Task 1 Test"  );
     1019  status = pthread_create( &id, NULL, Task_1, NULL );
     1020  assert( !status );
     1021  Read_msg_from_que(  BLOCKING, 0 ); /* Block until init writes */
     1022  print_current_time( "Init: ", "" );
     1023
     1024  /*
     1025   * Create a task then block until the task reads a message.
     1026   */
     1027
     1028  Start_Test( "multi-thread Task 4 Send Test"  );
     1029  fill_message_queues( "Init:" );
     1030  status = pthread_create( &id, NULL, Task_4, NULL );
     1031  assert( !status );
     1032  puts( "Init: mq_send - Full queue changes to non-blocking (EAGAIN)" );
     1033  status = mq_send(Test_q[BLOCKING].mq, message, 0, 0 );
     1034  fatal_posix_service_status( status, -1, "mq_send error return status");
     1035  fatal_posix_service_status( errno, EAGAIN, "mq_send errno EAGAIN");
     1036  verify_queues_full( "Init:" );
     1037  empty_message_queues( "Init:" );
     1038
     1039  /*
     1040   * Create a task then block until the task reads a message.
     1041   */
     1042
     1043  Start_Test( "multi-thread Task 2 Test"  );
     1044  fill_message_queues( "Init:" );
     1045  status = pthread_create( &id, NULL, Task_2, NULL );
     1046  assert( !status );
     1047  Show_send_msg_to_que( "Init:", BLOCKING, Priority_Order[0] );
     1048  print_current_time( "Init: ", "" );
     1049  verify_queues_full( "Init:" );
     1050  empty_message_queues( "Init:" );
     1051
     1052  /*
     1053   * Create a task then block until it deletes and closes all queues.
     1054   *     EBADF - Queue unlinked and closed while blocked
     1055   */
     1056
     1057  Start_Test( "multi-thread Task 3 Test"  );
     1058  fill_message_queues( "Init:" );
     1059  status = pthread_create( &id, NULL, Task_3, NULL );
     1060  assert( !status );
     1061  puts( "Init: mq_send - Block while thread deletes queue (EBADF)" );
     1062  ptr = &Predefined_Msgs[0];
     1063  status = mq_send( Test_q[BLOCKING].mq, ptr->msg, ptr->size , ptr->priority );
     1064  fatal_posix_service_status( status, -1, "mq_send error return status");
     1065  fatal_posix_service_status( errno, EBADF, "mq_send errno EBADF");
     1066
     1067}
     1068
     1069void validate_mq_setattr()
     1070{
    2401071  struct mq_attr  attr;
    241 
    242   attr.mq_maxmsg  = 3;
    243   attr.mq_msgsize = 8;
    244 
    245   /*
    246    * XXX - EBADF  Not a valid message descriptor.
    247    *       Write to a invalid message descriptor
    248    * XXX - Write to a read only queue
    249    */
    250 
    251   puts( "mq_send - Closed message queue (EBADF)" );
    252   status = mq_send( mqs[size], "", 1, 0 );
    253   fatal_directive_status( status, -1, "mq_send error return status");
    254   fatal_directive_status( errno, EBADF, "mq_send errno EBADF");
    255 
    256   puts( "mq_open - Open a read only queue" );
    257   n_mq1 = mq_open("read_only", O_CREAT | O_RDONLY, 0x777, &attr);
    258   assert( n_mq1 != (-1) );
    259   /*XXX - Isn't there a more general check */
    260 
    261   puts( "mq_send - Read only message queue (EBADF)" );
    262   status = mq_send( n_mq1, "", 1, 0 );
    263   fatal_directive_status( status, -1, "mq_send error return status");
    264   fatal_directive_status( errno, EBADF, "mq_send errno EBADF");
    265 
    266   status = mq_close( n_mq1 );
    267   fatal_directive_status( status, 0, "mq_close message queue");
    268 
    269   status = mq_unlink( "read_only" );
    270   fatal_directive_status( status, 0, "mq_unlink message queue");
    271 
    272   /*
    273    * XXX - EINTR
    274    *       Signal interrupted the call.
    275 
    276   puts( "mq_send - UNSUCCESSFUL (EINTR)" );
    277   status = mq_send( mqs, "", 0xffff, 0 );
    278   fatal_directive_status( status, -1, "mq_send error return status");
    279   fatal_directive_status( errno, E, "mq_send errno E");
    280    */
    281 
    282   /*
    283    * XXX - EINVAL priority is out of range.
    284    */
    285 
    286   puts( "mq_send - Priority out of range (EINVAL)" );
    287   status = mq_send( mqs[0], "", 1, MQ_PRIO_MAX + 1 );
    288   fatal_directive_status( status, -1, "mq_send error return status");
    289   fatal_directive_status( errno, EINVAL, "mq_send errno EINVAL");
    290 
    291   /*
    292    * XXX - EMSGSIZE - Message size larger than msg_len
    293    */
    294 
    295   puts( "mq_send - Message longer than msg_len (EMSGSIZE)" );
    296   status = mq_send( mqs[0], "", 0xffff, 0 );
    297   fatal_directive_status( status, -1, "mq_send error return status");
    298   fatal_directive_status( errno, EMSGSIZE, "mq_send errno EMSGSIZE");
    299 
    300   /*
    301    * ENOSYS - send is supported should never happen.
    302    */
    303 
    304 
    305   /*
    306    * XXX - EAGAIN
    307    *       O_NONBLOCK and message queue is full.
    308    *       This is validated in the read/write test.
    309    */
    310 
    311   i=0;
    312   do {
    313     status = mq_send( mqs[0], "", 1, 0 );
    314     i++;
    315   } while (status == 0);
    316   fatal_directive_status( status, -1, "mq_send error return status");
    317   fatal_directive_status( errno, EAGAIN, "mq_send errno EAGAIN");
    318 
    319   return i-1;
    320 }
    321 
    322 void validate_mq_receive_error_codes(
    323   mqd_t   *mqs,     
    324   int      size      /* Number still open in mqs */
    325 )
    326 {
     1072  struct mq_attr  save_attr[ NUMBER_OF_TEST_QUEUES ];
    3271073  int             status;
    328 
    329   /*
    330    * EAGAIN -
    331    */
    332 
    333   /*
    334    * EBADF -
    335    */
    336 
    337   /*
    338    * EMSGSIZE -
    339    */
    340 
    341   /*
    342    * EINTR -
    343    */
    344 
    345   /*
    346    * EBADMSG - a data corruption problem.
    347    *  XXX - Can not cause.
    348    */
    349 
    350   /*
    351   puts( "mq_ - UNSUCCESSFUL ()" );
    352   status = mq_(  );
    353   fatal_directive_status( status, -1, "mq_ error return status");
    354   fatal_directive_status( errno, E, "mq_c errno E");
    355 
    356   */
    357   /*
    358    * ENOSYS -
    359    */
    360 
    361 }
    362 
    363 void non_blocking_mq_read_write(
    364   mqd_t   *mqs,     
    365   int      size      /* Number still open in mqs */
    366 )
    367 {
    368   /*
    369   int         status;
    370   char       *messages[] = {
    371     "Msg 1",
    372     "Test 2",
    373     "12345678901234567890"
    374   };
    375 
    376   status = mq_send( mqs[0], messages[0], strlen( messages[0] ), 0 );
    377   fatal_directive_status( status, 0, "mq_send error return status" );
    378    
    379   puts( "mq_send - UNSUCCESSFUL ()" );
    380   do {
    381     status = mq_send(  );
    382   fatal_directive_status( status, -1, "mq_send error return status");
    383   fatal_directive_status( errno, E, "mq_send errno E");
    384   }
    385   */
     1074  int            i;
     1075
     1076  /*
     1077   * EBADF - Get the attributes from a closed queue.
     1078   */
     1079
     1080  puts( "Task1:mq_setattr - unopened queue (EBADF)" );
     1081  status = mq_setattr( Test_q[CLOSED].mq, &attr, NULL );
     1082  fatal_posix_service_status( status, -1, "mq_setattr error return status");
     1083  fatal_posix_service_status( errno, EBADF, "mq_setattr errno EBADF"); 
     1084
     1085  /*
     1086   * XXX - The following are not listed in the POSIX manual but
     1087   *       may occur.
     1088   */
     1089
     1090  /*
     1091   * EINVAL - NULL attributes
     1092   */
     1093
     1094  puts( "Task1:mq_setattr - NULL attributes (EINVAL)" );
     1095  status = mq_setattr( Test_q[RW_QUEUE].mq, NULL, NULL );
     1096  fatal_posix_service_status( status, -1, "mq_setattr error return status");
     1097  fatal_posix_service_status( errno, EINVAL, "mq_setattr errno EINVAL"); 
     1098
     1099  /*
     1100   * Verify change queues to blocking, by verifying all queues block
     1101   * for a timed receive.
     1102   */
     1103
     1104  puts( "Init: set_attr all queues to blocking" );
     1105  for(i=0; i<CLOSED; i++) {
     1106    attr.mq_flags =  Test_q[i].oflag & (~O_NONBLOCK );
     1107    status = mq_setattr( Test_q[i].mq, &attr, &save_attr[i] );
     1108    fatal_int_service_status( status, 0, "mq_setattr valid return status");
     1109    Validate_attributes( Test_q[i].mq, attr.mq_flags, 0 );
     1110  }
     1111  for( i = RW_QUEUE; i < CLOSED; i++ ) {
     1112    verify_timed_receive_queue( "Init:", i, 1 );
     1113  }
     1114
     1115  /*
     1116   * Restore restore all queues to their old attribute.
     1117   */
     1118 
     1119  for(i=0; i<CLOSED; i++) {
     1120    status = mq_setattr( Test_q[i].mq, &save_attr[i], NULL );
     1121    fatal_int_service_status( status, 0, "mq_setattr valid return status");
     1122    Validate_attributes( Test_q[i].mq, Test_q[i].oflag, 0 );
     1123  }
    3861124}
    3871125
     
    3911129{
    3921130  int             status;
    393   mqd_t           mqs[CONFIGURE_MAXIMUM_POSIX_MESSAGE_QUEUES];
    394   mqd_t           n_mq1;
    3951131  mqd_t           n_mq2;
    396   char           *messages[] = {
    397     "Msg 1",
    398     "Test 2",
    399     "12345678901234567890"
    400   };
    4011132
    4021133  puts( "\n\n*** POSIX MESSAGE QUEUE TEST ***" );
    4031134
    404   validate_mq_open_error_codes( mqs, 2 );
    405   validate_mq_unlink_error_codes( mqs, 2 );
    406   validate_mq_close_error_codes( mqs, 2 );
    407 
    408   validate_mq_send_error_codes( mqs, 2 );
    409   validate_mq_receive_error_codes( mqs, 2 );
    410 
    411 
    412   /*
    413    * Validate a second open returns the same message queue.
    414    */
    415 
    416   puts( "mq_open - Open an existing mq ( same id )" );
    417   n_mq1 = mq_open("mq1", 0 );
    418   fatal_directive_status(
    419     (int) n_mq1, (int ) mqs[0], "mq_open error return status" );
     1135  validate_mq_open_error_codes( );
     1136  open_test_queues();
     1137  validate_mq_unlink_error_codes();
     1138  validate_mq_close_error_codes();
     1139  verify_unlink_functionality();
     1140  validate_mq_setattr( );
     1141  validate_mq_send_error_codes();
     1142  validate_mq_getattr_error_codes();
     1143  verify_timed_send();
     1144  validate_mq_receive_error_codes();
     1145  verify_timed_receive();
     1146  verify_open_functionality();
     1147  verify_notify();
     1148  verify_with_threads();
    4201149 
    421   /*
    422    * Unlink the message queue, then verify an open of the same name produces a
    423    * different message queue.
    424    */
    425 
    426   puts( "mq_unlink - mq1 SUCCESSFUL" );
    427   status = mq_unlink( "mq1" );
    428   fatal_directive_status( status, 0, "mq_unlink locked message queue");
    429 
    430   puts( "mq_open - Reopen mq1 SUCCESSFUL with a different id" );
    431   n_mq2 = mq_open( "mq1", O_CREAT | O_EXCL, 00777, NULL);
    432   assert( n_mq2 != (-1) );
    433   assert( n_mq2 != n_mq1 );
    434 
    435   /*
    436    * Validate it "mq1" can be closed and unlinked.
    437    */
    438 
    439   puts( "mq_unlink - mq1 SUCCESSFUL" );
    440   status = mq_unlink( "mq1" );
    441   fatal_directive_status( status, 0, "mq_unlink locked message queue");
    442 
    443   puts( "mq_close mq1 - SUCCESSFUL" );
    444   status = mq_close( n_mq2 );
    445   fatal_directive_status( status, 0, "mq_close message queue");
    446   status = mq_close( n_mq1 );
    447   fatal_directive_status( status, 0, "mq_close message queue");
    448   status = mq_close( mqs[0] );
    449   fatal_directive_status( status, 0, "mq_close message queue");
    450 
    451   puts( "mq_unlink - UNSUCCESSFUL (ENOENT)" );
    452   status = mq_unlink("mq1");
    453   fatal_directive_status( status, -1, "mq_unlink error return status");
    454   fatal_directive_status( errno, ENOENT, "mq_close errno EINVAL");
    455 
    456   /*
    457    * XXX - Cant' create location OBJECTS_ERROR or OBJECTS_REMOTE.
    458    *       mq_close and mq_unlink.
    459    * XXX - Don't think we need this save until yellow line tested.
    460   puts( "Init: mq_unlink - UNSUCCESSFUL (ENOENT)" );
    461   status = mq_unlink("mq3");
    462   fatal_directive_status( status, -1, "mq_unlink error return status");
    463   fatal_directive_status( errno, ENOENT, "mq_unlink errno ENOENT");
    464   assert( (status == -1) && (errno == ENOENT) );
    465   */
    466 
    467 
    468   /*
    469    * Validate we can wait on a message queue opened with mq_open.
    470    */
    471 #if (0) /* XXX FIX ME */
    472   puts( "Init: mq_wait on mq1" );
    473   status = mq_receive(n_mq1);
    474   fatal_directive_status( status, 0, "mq_wait opened message queue");
    475 #endif
    476 
    477 
    4781150  puts( "*** END OF POSIX MESSAGE QUEUE TEST ***" );
    4791151  exit( 0 );
     
    4831155
    4841156
     1157void *Task_1 (
     1158  void *argument
     1159)
     1160{
     1161  int      status;
     1162  int      count = 0;
     1163  sigset_t set;
     1164
     1165  /* Block Waiting for a message */
     1166
     1167  print_current_time( "Task_1: ", "" );
     1168
     1169  Show_send_msg_to_que( "Task_1:", BLOCKING, 0 );
     1170
     1171  puts( "Task_1: pthread_exit" );
     1172  pthread_exit( NULL );
     1173
     1174  /* switch to Init */
     1175
     1176  assert( 0 );
     1177  return NULL; /* just so the compiler thinks we returned something */
     1178}
     1179
     1180void *Task_2(
     1181  void *argument
     1182)
     1183{
     1184  int status;
     1185
     1186 
     1187  print_current_time( "Task_2: ", "" );
     1188
     1189 
     1190  /* Block waiting to send a message */
     1191
     1192  verify_queues_full( "Task_2:" );
     1193  Read_msg_from_que( BLOCKING, Priority_Order[0] ); /* Cause context switch */
     1194
     1195  puts( "Task_2: pthread_exit" );
     1196  pthread_exit( NULL );
     1197
     1198     /* switch to Init */
     1199
     1200  return NULL; /* just so the compiler thinks we returned something */
     1201}
     1202
     1203void *Task_3 (
     1204  void *argument
     1205)
     1206{
     1207
     1208  print_current_time( "Task_3: ", "" );
     1209
     1210  /*
     1211   * close and unlink all queues.
     1212   */
     1213
     1214  verify_close_functionality( "Task_3: " );
     1215  puts( "Task_3: pthread_exit" );
     1216  pthread_exit( NULL );
     1217
     1218     /* switch to Init */
     1219
     1220  return NULL; /* just so the compiler thinks we returned something */
     1221
     1222}
     1223
     1224void *Task_4 (
     1225  void *argument
     1226)
     1227{
     1228  struct mq_attr  attr;
     1229  int             status;
     1230  int             count;
     1231
     1232  print_current_time( "Task_4: ", "" );
     1233
     1234  /*
     1235   * Set the count to the number of messages in the queue.
     1236   */
     1237
     1238  status = mq_getattr( Test_q[BLOCKING].mq, &attr );
     1239  fatal_posix_service_status( status, 0, "mq_getattr valid return status");
     1240  count = attr.mq_curmsgs;
     1241
     1242  puts("Task_4: Set queue to non-blocking");
     1243  attr.mq_flags =  Test_q[BLOCKING].oflag | O_NONBLOCK;
     1244  status = mq_setattr( Test_q[BLOCKING].mq, &attr, NULL );
     1245  fatal_int_service_status( status, 0, "mq_setattr valid return status");
     1246  Validate_attributes( Test_q[BLOCKING].mq, attr.mq_flags, count );
     1247
     1248  puts("Task_4: Return queue to blocking");
     1249  attr.mq_flags =  Test_q[BLOCKING].oflag;
     1250  status = mq_setattr( Test_q[BLOCKING].mq, &attr, NULL );
     1251  fatal_int_service_status( status, 0, "mq_setattr valid return status");
     1252  Validate_attributes( Test_q[BLOCKING].mq, attr.mq_flags, count );
     1253
     1254  puts( "Task_4: pthread_exit" );
     1255  pthread_exit( NULL );
     1256
     1257     /* switch to Init */
     1258
     1259  return NULL; /* just so the compiler thinks we returned something */
     1260
     1261}
     1262
     1263void *Task_5 (
     1264  void *argument
     1265)
     1266{
     1267
     1268  print_current_time( "Task_5: ", "" );
     1269
     1270  puts( "Task_5: pthread_exit" );
     1271  pthread_exit( NULL );
     1272
     1273     /* switch to Init */
     1274
     1275  return NULL; /* just so the compiler thinks we returned something */
     1276
     1277}
     1278
     1279void *Task_ (
     1280  void *argument
     1281)
     1282{
     1283
     1284  print_current_time( "Task_: ", "" );
     1285
     1286  puts( "Task_: pthread_exit" );
     1287  pthread_exit( NULL );
     1288
     1289     /* switch to Init */
     1290
     1291  return NULL; /* just so the compiler thinks we returned something */
     1292
     1293}
     1294
     1295
     1296
     1297 
     1298
     1299
     1300
     1301
     1302
     1303
     1304
     1305
     1306
     1307
     1308
     1309
     1310
     1311
Note: See TracChangeset for help on using the changeset viewer.