source: rtems/testsuites/psxtests/psxmsgq01/init.c @ b1860df5

5
Last change on this file since b1860df5 was b1860df5, checked in by Sebastian Huber <sebastian.huber@…>, on 05/24/16 at 13:39:07

psxtests/psxmsgq01: Fix typo

  • Property mode set to 100644
File size: 40.1 KB
Line 
1/*
2 *  COPYRIGHT (c) 1989-2012.
3 *  On-Line Applications Research Corporation (OAR).
4 *
5 *  The license and distribution terms for this file may be
6 *  found in the file LICENSE in this distribution or at
7 *  http://www.rtems.org/license/LICENSE.
8 */
9
10#ifdef HAVE_CONFIG_H
11#include "config.h"
12#endif
13
14#define CONFIGURE_INIT
15#include "system.h"
16#include <sched.h>
17#include <fcntl.h>
18#include <time.h>
19#include <tmacros.h>
20#include <signal.h>   /* signal facilities */
21#include "test_support.h"
22
23const char rtems_test_name[] = "PSXMSGQ 1";
24
25/* forward declarations to avoid warnings */
26void Start_Test(char *description);
27void Validate_attributes(mqd_t mq, int oflag, int msg_count);
28char *Build_Queue_Name(int i);
29void open_test_queues(void);
30void validate_mq_open_error_codes(void);
31void validate_mq_unlink_error_codes(void);
32void validate_mq_close_error_codes(void);
33void validate_mq_getattr_error_codes(void);
34void Send_msg_to_que(int que, int msg);
35void Show_send_msg_to_que(char *task_name, int que, int msg);
36void verify_queues_full(char *task_name);
37void verify_queues_empty(char *task_name);
38int empty_message_queues(char *task_name);
39int fill_message_queues(char *task_name);
40void Read_msg_from_que(int que, int msg);
41int validate_mq_send_error_codes(void);
42void validate_mq_receive_error_codes(void);
43void verify_open_functionality(void);
44void verify_unlink_functionality(void);
45void verify_close_functionality(void);
46void verify_timed_send_queue(int que, int is_blocking);
47void verify_timed_send(void);
48void verify_timed_receive_queue(char *task_name, int que, int is_blocking);
49void verify_timed_receive(void);
50void wait_for_signal(sigset_t *waitset, int sec, int expect_signal);
51void verify_notify(void);
52void verify_with_threads(void);
53void verify_timedout_mq_timedreceive(char *task_name, int que, int is_blocking);
54void verify_timedout_mq_timedsend(int que, int is_blocking);
55void verify_timed_receive(void);
56void validate_mq_setattr(void);
57void verify_timedout_mq_timedreceive(
58  char *task_name, int que, int is_blocking);
59void verify_mq_receive(void);
60void verify_timedout_mq_timedsend(int que, int is_blocking);
61void verify_mq_send(void);
62void verify_timed_receive(void);
63
64typedef struct {
65  char         msg[ 50 ];
66  int          size;
67  unsigned int priority;
68} Test_Message_t;
69
70Test_Message_t Predefined_Msgs[MAXMSG+1];
71Test_Message_t Predefined_Msgs[MAXMSG+1] = {
72  { "12345678",   9, MQ_PRIO_MAX-1 },  /* Max Length Message med  */
73  { "",           1, 1             },  /* NULL  Message      low  */
74  { "Last",       5, MQ_PRIO_MAX   },  /* Queue Full Message hi   */
75  { "No Message", 0, MQ_PRIO_MAX-1 },  /* 0 length Message   med  */
76  { "1",          2, 0             },  /* Cause Overflow Behavior */
77};
78int Priority_Order[MAXMSG+1] = { 2, 0, 3, 1, MAXMSG };
79
80
81typedef struct {
82  mqd_t              mq;
83  Test_Queue_Types   index;
84  char              *name;
85  int                oflag;
86  int                maxmsg;
87  int                msgsize;
88  int                count;
89} Test_queue_type;
90
91Test_queue_type Test_q[ NUMBER_OF_TEST_QUEUES + 1 ] =
92{
93  { 0, 0, "Qread",    ( O_CREAT | O_RDONLY | O_NONBLOCK ), MAXMSG, MSGSIZE, 0 },
94  { 0, 1, "Qwrite",   ( O_CREAT | O_WRONLY | O_NONBLOCK ), MAXMSG, MSGSIZE, 0 },
95  { 0, 2, "Qnoblock", ( O_CREAT | O_RDWR   | O_NONBLOCK ), MAXMSG, MSGSIZE, 0 },
96  { 0, 3, "Qblock",   ( O_CREAT | O_RDWR )               , MAXMSG, MSGSIZE, 0 },
97  { 0, 4, "Qdefault", ( O_CREAT | O_RDWR )               , 10,     16,      0 },
98  { 0, 5, "mq6",      ( O_CREAT | O_WRONLY | O_NONBLOCK ), MAXMSG, MSGSIZE, 0 },
99  { 0, 6, "Qblock",   (           O_RDWR )               , MAXMSG, MSGSIZE, 0 },
100};
101
102#define RW_NAME             Test_q[ RW_QUEUE ].name
103#define DEFAULT_NAME        Test_q[ DEFAULT_RW ].name
104#define RD_NAME             Test_q[ RD_QUEUE ].name
105#define WR_NAME             Test_q[ WR_QUEUE ].name
106#define BLOCKING_NAME       Test_q[ BLOCKING ].name
107#define CLOSED_NAME         Test_q[ CLOSED ].name
108
109#define RW_ATTR         Test_q[ RW_QUEUE ].oflag
110#define DEFAULT_ATTR    Test_q[ DEFAULT_RW ].oflag
111#define RD_ATTR         Test_q[ RD_QUEUE ].oflag
112#define WR_ATTR         Test_q[ WR_QUEUE ].oflag
113#define BLOCK_ATTR      Test_q[ BLOCKING ].oflag
114#define CLOSED_ATTR     Test_q[ CLOSED ].oflag
115
116/*
117 * Outputs a header at each test section.
118 */
119void Start_Test(
120  char *description
121)
122{
123  printf( "_______________%s\n", description );
124}
125
126
127void Validate_attributes(
128  mqd_t  mq,
129  int    oflag,
130  int    msg_count
131)
132{
133  int             status;
134  struct mq_attr  attr;
135
136  status = mq_getattr( mq, &attr );
137  fatal_posix_service_status( status, 0, "mq_getattr valid return status");
138
139  if ( mq != Test_q[ DEFAULT_RW ].mq ){
140    fatal_int_service_status((int)attr.mq_maxmsg, MAXMSG, "maxmsg attribute" );
141    fatal_int_service_status((int)attr.mq_msgsize,MSGSIZE,"msgsize attribute");
142  }
143
144  fatal_int_service_status((int)attr.mq_curmsgs, msg_count, "count attribute" );
145  fatal_int_service_status((int)attr.mq_flags, oflag, "flag attribute" );
146}
147
148#define Get_Queue_Name( i )  Test_q[i].name
149char *Build_Queue_Name(int i)
150{
151  static char Queue_Name[PATH_MAX + 2];
152
153  sprintf(Queue_Name,"mq%d", i+1 );
154  return Queue_Name;
155}
156
157void open_test_queues(void)
158{
159  struct mq_attr   attr;
160  int              status;
161  Test_queue_type *tq;
162  int              que;
163
164  attr.mq_maxmsg  = MAXMSG;
165  attr.mq_msgsize = MSGSIZE;
166
167  puts( "Init: Open Test Queues" );
168
169  for( que = 0; que < NUMBER_OF_TEST_QUEUES+1; que++ ) {
170
171    tq = &Test_q[ que ];
172    if ( que == DEFAULT_RW)
173      Test_q[que].mq = mq_open( tq->name, tq->oflag, 0x777, NULL );
174    else
175      Test_q[que].mq = mq_open( tq->name, tq->oflag, 0x777, &attr );
176
177    rtems_test_assert( Test_q[que].mq != (-1) );
178  }
179
180  status = mq_close( Test_q[NUMBER_OF_TEST_QUEUES].mq );
181  fatal_posix_service_status( status, 0, "mq_close duplicate message queue");
182  status = mq_close( Test_q[CLOSED].mq );
183  fatal_posix_service_status( status, 0, "mq_close message queue");
184  status = mq_unlink( CLOSED_NAME );
185  fatal_posix_service_status( status, 0, "mq_unlink message queue");
186}
187
188/*
189 * Opens CONFIGURE_MAXIMUM_POSIX_MESSAGE_QUEUES then leaves size queues
190 * opened but closes the rest.
191 */
192
193void validate_mq_open_error_codes(void)
194{
195  int             i;
196  mqd_t           n_mq2;
197  struct mq_attr  attr;
198  int             status;
199  mqd_t           open_mq[CONFIGURE_MAXIMUM_POSIX_MESSAGE_QUEUES + 1];
200
201  attr.mq_maxmsg  = MAXMSG;
202  attr.mq_msgsize = MSGSIZE;
203
204  Start_Test( "mq_open errors" );
205
206  /*
207   * XXX EINVAL - inappropriate name was given for the message queue
208   */
209
210  /*
211   * EINVAL - Create with negative maxmsg.
212   */
213
214  attr.mq_maxmsg = -1;
215  puts( "Init: mq_open - Create with maxmsg (-1) (EINVAL)" );
216  n_mq2 = mq_open( "mq2", O_CREAT | O_RDONLY, 0x777, &attr);
217  fatal_posix_mqd( n_mq2, "mq_open error return status" );
218  fatal_posix_service_status( errno, EINVAL,  "mq_open errno EINVAL");
219  attr.mq_maxmsg  = MAXMSG;
220
221  /*
222   * EINVAL - Create withnegative msgsize.
223   */
224
225  attr.mq_msgsize = -1;
226  puts( "Init: mq_open - Create with msgsize (-1) (EINVAL)" );
227  n_mq2 = mq_open( "mq2", O_CREAT | O_RDONLY, 0x777, &attr);
228  fatal_posix_mqd( n_mq2, "mq_open error return status" );
229  fatal_posix_service_status( errno, EINVAL,  "mq_open errno EINVAL");
230  attr.mq_msgsize = MSGSIZE;
231
232  /*
233   * ENOENT - Open a non-created file.
234   */
235
236  puts( "Init: mq_open - Open new mq without create flag (ENOENT)" );
237  n_mq2 = mq_open( "mq3", O_EXCL | O_RDONLY, 0x777, NULL);
238  fatal_posix_mqd( n_mq2, "mq_open error return status" );
239  fatal_posix_service_status( errno, ENOENT,  "mq_open errno ENOENT");
240
241  /*
242   * XXX EINTR  - call was interrupted by a signal
243   */
244
245  /*
246   * ENAMETOOLONG - Give a name greater than PATH_MAX.
247   */
248
249  puts( "Init: mq_open - Open with too long of a name (ENAMETOOLONG)" );
250  n_mq2 = mq_open( Get_Too_Long_Name(), O_CREAT | O_RDONLY, 0x777, NULL );
251  fatal_posix_mqd( n_mq2, "mq_open error return status" );
252  fatal_posix_service_status( errno, ENAMETOOLONG, "mq_open errno ENAMETOOLONG");
253
254  /*
255   * XXX - ENAMETOOLONG - Give a name greater than NAME_MAX
256   *       Per implementation not possible.
257   */
258
259  /*
260   * EEXIST - Create an existing queue.
261   */
262
263  puts( "Init: mq_open - Create an Existing mq (EEXIST)" );
264  open_mq[0] = mq_open(
265    Build_Queue_Name(0), O_CREAT | O_RDWR | O_NONBLOCK, 0x777, NULL );
266  rtems_test_assert( open_mq[0] != (-1) );
267
268  n_mq2 = mq_open(
269    Build_Queue_Name(0), O_CREAT | O_EXCL | O_RDONLY, 0x777, NULL);
270  fatal_posix_mqd( n_mq2, "mq_open error return status" );
271  fatal_posix_service_status( errno, EEXIST,  "mq_open errno EEXIST");
272
273  status = mq_unlink( Build_Queue_Name(0) );
274  fatal_posix_service_status( status, 0, "mq_unlink message queue");
275
276  status = mq_close( open_mq[0]);
277  fatal_posix_service_status( status, 0, "mq_close message queue");
278
279  /*
280   * Open maximum number of message queues
281   */
282
283  puts( "Init: mq_open - SUCCESSFUL" );
284  for (i = 0; i < CONFIGURE_MAXIMUM_POSIX_MESSAGE_QUEUES; i++) {
285    open_mq[i] = mq_open(
286      Build_Queue_Name(i), O_CREAT | O_RDWR | O_NONBLOCK, 0x777, NULL );
287    rtems_test_assert( open_mq[i] != (-1) );
288    rtems_test_assert( open_mq[i] );
289    /*XXX - Isn't there a more general check */
290/* JRS     printf( "mq_open 0x%x %s\n", open_mq[i], Build_Queue_Name(i) ); */
291  }
292
293  /*
294   * XXX EACCES - permission to create is denied.
295   */
296
297  /*
298   * XXX EACCES - queue exists permissions specified by o_flag are denied.
299   */
300
301  /*
302   * XXX EMFILE  - Too many message queues in use by the process
303   */
304
305  /*
306   * ENFILE -  Too many message queues open in the system
307   */
308
309  puts( "Init: mq_open - system is out of resources (ENFILE)" );
310  n_mq2 = mq_open( Build_Queue_Name(i), O_CREAT | O_RDONLY, 0x777, NULL );
311  fatal_posix_mqd( n_mq2, "mq_open error return status" );
312  fatal_posix_service_status( errno, ENFILE,  "mq_open errno ENFILE");
313
314  /*
315   * Unlink and Close all queues.
316   */
317
318  puts( "Init: mq_close and mq_unlink (mq3...mqn) - SUCCESSFUL" );
319  for (i = 0; i < CONFIGURE_MAXIMUM_POSIX_MESSAGE_QUEUES; i++) {
320
321    status = mq_close( open_mq[i]);
322    fatal_posix_service_status( status, 0, "mq_close message queue");
323
324    status = mq_unlink( Build_Queue_Name(i) );
325    if ( status == -1 )
326      perror( "mq_unlink" );
327    fatal_posix_service_status( status, 0, "mq_unlink message queue");
328    /* JRS printf( "mq_close/mq_unlink 0x%x %s\n", open_mq[i], Build_Queue_Name(i) ); */
329  }
330}
331
332void validate_mq_unlink_error_codes(void)
333{
334  int             status;
335
336  Start_Test( "mq_unlink errors" );
337
338  /*
339   * XXX - EACCES Permission Denied
340   */
341
342  /*
343   * ENAMETOOLONG - Give a name greater than PATH_MAX.
344   */
345
346  puts( "Init: mq_unlink - mq_unlink with too long of a name (ENAMETOOLONG)" );
347  status = mq_unlink( Get_Too_Long_Name() );
348  fatal_posix_service_status( status, -1, "mq_unlink error return status");
349  fatal_posix_service_status( errno, ENAMETOOLONG, "mq_unlink errno ENAMETOOLONG");
350
351  /*
352   * XXX - ENAMETOOLONG - Give a name greater than NAME_MAX
353   *       Per implementation not possible.
354   */
355
356  /*
357   *  ENOENT - Unlink an unopened queue
358   */
359
360  puts( "Init: mq_unlink - A Queue not opened  (ENOENT)" );
361  status = mq_unlink( CLOSED_NAME );
362  fatal_posix_service_status( status, -1, "mq_unlink error return status");
363  fatal_posix_service_status( errno, ENOENT, "mq_unlink errno ENOENT");
364
365  /*
366   * XXX - The following were not listed in the POSIX document as
367   *       possible errors.  Under other commands the EINVAL is
368   *       given for these conditions.
369   */
370
371  /*
372   *  EINVAL - Unlink a queue with no name
373   */
374
375  puts( "Init: mq_unlink (NULL) - EINVAL" );
376  status = mq_unlink( NULL );
377  fatal_posix_service_status( status, -1, "mq_unlink error return status");
378  fatal_posix_service_status( errno, EINVAL, "mq_unlink errno value");
379
380  /*
381   *  ENOENT - Unlink a queue with a zero length name
382   */
383
384  puts( "Init: mq_unlink (\"\") - ENOENT" );
385  status = mq_unlink( "" );
386  fatal_posix_service_status( status, -1, "mq_unlink error return status");
387  fatal_posix_service_status( errno, ENOENT, "mq_unlink errno value");
388}
389
390void validate_mq_close_error_codes(void)
391{
392  int             status;
393
394  Start_Test( "mq_close errors" );
395
396  /*
397   * EBADF - Close a queue that is not open.
398   */
399
400  puts( "Init: mq_close - unopened queue (EBADF)" );
401  status = mq_close( Test_q[CLOSED].mq );
402  fatal_posix_service_status( status, -1, "mq_close error return status");
403  fatal_posix_service_status( errno, EBADF, "mq_close errno EBADF");
404}
405
406
407void validate_mq_getattr_error_codes(void)
408{
409  struct mq_attr  attr;
410  int             status;
411
412  Start_Test( "mq_getattr errors" );
413
414  /*
415   * EBADF - Get the attributes from a closed queue.
416   */
417
418  puts( "Init: mq_getattr - unopened queue (EBADF)" );
419  status = mq_getattr( Test_q[CLOSED].mq, &attr );
420  fatal_posix_service_status( status, -1, "mq_close error return status");
421  fatal_posix_service_status( errno, EBADF, "mq_close errno EBADF");
422
423  /*
424   * XXX - The following are not listed in the POSIX manual but
425   *       may occur.
426   */
427
428  /*
429   * EINVAL - NULL attributes
430   */
431
432  puts( "Init: mq_getattr - NULL attributes (EINVAL)" );
433  status = mq_getattr( Test_q[RW_QUEUE].mq, NULL );
434  fatal_posix_service_status( status, -1, "mq_close error return status");
435  fatal_posix_service_status( errno, EINVAL, "mq_close errno EINVAL");
436
437}
438
439
440void Send_msg_to_que(
441  int que,
442  int msg
443)
444{
445  Test_Message_t *ptr = &Predefined_Msgs[msg];
446  int             status;
447
448  status = mq_send( Test_q[que].mq, ptr->msg, ptr->size , ptr->priority );
449  fatal_posix_service_status( status, 0, "mq_send valid return status");
450  Test_q[que].count++;
451}
452
453void Show_send_msg_to_que(
454  char *task_name,
455  int   que,
456  int   msg
457)
458{
459  Test_Message_t *ptr = &Predefined_Msgs[msg];
460  printf( "%s mq_send -  to %s msg: %s priority %d\n",
461    task_name, Test_q[que].name, ptr->msg, ptr->priority);
462  Send_msg_to_que( que, msg );
463}
464
465void verify_queues_full(
466  char *task_name
467)
468{
469  int          que;
470
471  /*
472   * Validate that the queues are full.
473   */
474
475  printf( "%s Verify Queues are full\n", task_name );
476  for( que = RW_QUEUE; que < CLOSED; que++ )
477    Validate_attributes( Test_q[que].mq, Test_q[que].oflag, Test_q[que].count );
478
479}
480void verify_queues_empty(
481  char *task_name
482)
483{
484  int             que;
485
486  printf( "%s Verify Queues are empty\n", task_name );
487  for( que = RW_QUEUE; que < CLOSED; que++ )
488    Validate_attributes( Test_q[que].mq, Test_q[que].oflag, 0 );
489}
490
491int fill_message_queues(
492  char *task_name
493)
494{
495  int             msg;
496  int             que;
497
498
499  verify_queues_empty( task_name );
500
501  /*
502   * Fill Queue with predefined messages.
503   */
504
505  printf( "%s Fill Queues with messages\n", task_name );
506  for(msg=0; msg<MAXMSG; msg++){
507    for( que = RW_QUEUE; que < CLOSED; que++ ) {
508      Send_msg_to_que( que, msg );
509    }
510  }
511
512  verify_queues_full( "Init:" );
513  return msg;
514}
515
516
517void Read_msg_from_que(
518  int que,
519  int msg
520)
521{
522  unsigned int    priority;
523  Test_Message_t *ptr;
524  int             status;
525  char            message[100];
526  char            err_msg[100];
527
528  ptr = &Predefined_Msgs[msg];
529  status = mq_receive(Test_q[ que ].mq, message, 100, &priority );
530  Test_q[que].count--;
531
532  sprintf( err_msg, "%s msg %s size failure", Test_q[ que ].name, ptr->msg );
533  fatal_int_service_status( status, ptr->size, err_msg );
534
535  rtems_test_assert( !strcmp( message, ptr->msg ) );
536  strcpy( message, "No Message" );
537
538  sprintf( err_msg,"%s msg %s size failure", Test_q[ que ].name, ptr->msg );
539  fatal_int_service_status(priority, ptr->priority, err_msg );
540}
541
542int empty_message_queues(
543  char *task_name
544)
545{
546  int que;
547  int i;
548
549  printf( "%s Empty all Queues\n", task_name );
550  for( que = RW_QUEUE; que < CLOSED; que++ ) {
551    for(i=0; Test_q[que].count != 0; i++ )
552      Read_msg_from_que( que,  Priority_Order[i] );
553
554    Validate_attributes( Test_q[ que].mq, Test_q[ que ].oflag, 0 );
555  }
556  return 0;
557}
558
559/*
560 * Returns the number of messages queued after the test on the
561 * first queue.
562 */
563int validate_mq_send_error_codes(void)
564{
565  int             status;
566  int             i;
567  char           *str;
568
569  Start_Test( "mq_send errors" );
570
571  /*
572   * EBADF - Write to a closed queue.
573   */
574
575  puts( "Init: mq_send - Closed message queue (EBADF)" );
576  status = mq_send( Test_q[CLOSED].mq, "", 1, 0 );
577  fatal_posix_service_status( status, -1, "mq_send error return status");
578  fatal_posix_service_status( errno, EBADF, "mq_send errno EBADF");
579
580  /*
581   * EBADF - Write to a read only  queue.
582   */
583
584  puts( "Init: mq_send - Read only message queue (EBADF)" );
585  status = mq_send( Test_q[ RD_QUEUE ].mq, "", 1, 0 );
586  fatal_posix_service_status( status, -1, "mq_send error return status");
587  fatal_posix_service_status( errno, EBADF, "mq_send errno EBADF");
588
589  /*
590   * XXX - EINTR      Signal interrupted the call.
591   *
592  puts( "Init: mq_send - UNSUCCESSFUL (EINTR)" );
593  status = mq_send( Test_q, "", 0xffff, 0 );
594  fatal_posix_service_status( status, -1, "mq_send error return status");
595  fatal_posix_service_status( errno, E, "mq_send errno E");
596   */
597
598  /*
599   * EINVAL priority is out of range.
600   */
601
602  puts( "Init: mq_send - Priority out of range (EINVAL)" );
603  status = mq_send( Test_q[ RW_QUEUE ].mq, "", 1, MQ_PRIO_MAX + 1 );
604  fatal_posix_service_status( status, -1, "mq_send error return status");
605  fatal_posix_service_status( errno, EINVAL, "mq_send errno EINVAL");
606
607  /*
608   *  EMSGSIZE - Message size larger than msg_len
609   *             Validates that msgsize is stored correctly.
610   */
611
612  puts( "Init: mq_send - Message longer than msg_len (EMSGSIZE)" );
613  status = mq_send( Test_q[ RW_QUEUE ].mq, "", MSGSIZE+1, 0 );
614  fatal_posix_service_status( status, -1, "mq_send error return status");
615  fatal_posix_service_status( errno, EMSGSIZE, "mq_send errno EMSGSIZE");
616
617  i = fill_message_queues( "Init:" );
618
619  /*
620   * ENOSYS - send not supported
621  puts( "Init: mq_send - Blocking Queue overflow (ENOSYS)" );
622  status = mq_send( n_mq1, Predefined_Msgs[i], 0, 0 );
623  fatal_posix_service_status( status, -1, "mq_send error return status");
624  fatal_posix_service_status( errno, EBADF, "mq_send errno EBADF");
625
626  status = mq_close( n_mq1 );
627  fatal_posix_service_status( status, 0, "mq_close message queue");
628
629  status = mq_unlink( "read_only" );
630  fatal_posix_service_status( status, 0, "mq_unlink message queue");
631   */
632
633  /*
634   * EAGAIN - O_NONBLOCK and message queue is full.
635   */
636
637  puts( "Init: mq_send - on a FULL non-blocking queue with (EAGAIN)" );
638  str = Predefined_Msgs[i].msg;
639  status = mq_send(Test_q[RW_QUEUE].mq, str, 0, 0 );
640  fatal_posix_service_status( status, -1, "mq_send error return status");
641  fatal_posix_service_status( errno, EAGAIN, "mq_send errno EAGAIN");
642
643  return i-1;
644}
645
646void validate_mq_receive_error_codes(void)
647{
648  int            status;
649  char           message[100];
650  unsigned int   priority;
651
652  Start_Test( "mq_receive errors"  );
653
654  /*
655   * EBADF - Not A Valid Message Queue
656   */
657
658  puts( "Init: mq_receive - Unopened message queue (EBADF)" );
659  status = mq_receive( Test_q[CLOSED].mq, message, 100, &priority );
660  fatal_posix_service_status( status, -1, "mq_ error return status");
661  fatal_posix_service_status( errno, EBADF, "mq_receive errno EBADF");
662
663  /*
664   * EBADF - Queue not opened to read
665   */
666
667  puts( "Init: mq_receive - Write only queue (EBADF)" );
668  status = mq_receive( Test_q[WR_QUEUE].mq, message, 100, &priority  );
669  fatal_posix_service_status( status, -1, "mq_ error return status");
670  fatal_posix_service_status( errno, EBADF, "mq_receive errno EBADF");
671
672  /*
673   * EMSGSIZE - Size is less than the message size attribute
674   */
675
676  puts( "Init: mq_receive - Size is less than the message (EMSGSIZE)" );
677  status = mq_receive(
678    Test_q[RW_QUEUE].mq, message, Predefined_Msgs[0].size-1, &priority );
679  fatal_posix_service_status( status, -1, "mq_ error return status");
680  fatal_posix_service_status( errno, EMSGSIZE, "mq_receive errno EMSGSIZE");
681
682
683  /*
684   * EAGAIN - O_NONBLOCK and Queue is empty
685   */
686  verify_queues_full( "Init:" );
687  empty_message_queues( "Init:" );
688
689  puts( "Init: mq_receive - Queue is empty (EAGAIN)" );
690  status = mq_receive( Test_q[RW_QUEUE].mq, message, 100, &priority );
691  fatal_posix_service_status( status, -1, "mq_ error return status");
692  fatal_posix_service_status( errno, EAGAIN, "mq_receive errno EAGAIN");
693
694  /*
695   * XXX - EINTR - Interrupted by a signal
696   */
697
698  /*
699   * XXX - EBADMSG - a data corruption problem.
700   */
701
702  /*
703   * XXX - ENOSYS - mq_receive not supported
704   */
705}
706
707void verify_open_functionality(void)
708{
709  mqd_t           n_mq;
710  int             status;
711
712  Start_Test( "mq_open functionality" );
713
714  /*
715   * Validate a second open returns the same message queue.
716   */
717
718  puts( "Init: mq_open - Open an existing mq ( same id )" );
719  n_mq = mq_open( RD_NAME, 0 );
720  rtems_test_assert( n_mq == Test_q[RD_QUEUE].mq );
721  status = mq_close( n_mq );
722  fatal_posix_service_status( status, 0, "mq_close");
723}
724
725void verify_unlink_functionality(void)
726{
727  mqd_t           n_mq;
728  int             status;
729
730  Start_Test( "mq_unlink functionality" );
731
732  /*
733   * Unlink the message queue, then verify an open of the same name produces a
734   * different message queue.
735   */
736
737  puts( "Init: Unlink and Open without closing SUCCESSFUL" );
738  status = mq_unlink( DEFAULT_NAME );
739  fatal_posix_service_status( status, 0, "mq_unlink locked message queue");
740
741  n_mq = mq_open( DEFAULT_NAME, DEFAULT_ATTR, 0x777, NULL );
742  rtems_test_assert( n_mq != (-1) );
743  rtems_test_assert( n_mq != Test_q[ DEFAULT_RW ].mq );
744
745
746  status = mq_unlink( DEFAULT_NAME );
747  fatal_posix_service_status( status, 0, "mq_unlink locked message queue");
748  status = mq_close( Test_q[ DEFAULT_RW ].mq );
749  fatal_posix_service_status( status, 0, "mq_close message queue");
750
751  Test_q[ DEFAULT_RW ].mq = n_mq;
752}
753
754void verify_close_functionality(void)
755{
756  int i;
757  int status;
758  Start_Test( "Unlink and Close All Files"  );
759  for (i=0; i<DEFAULT_RW; i++) {
760
761    status = mq_unlink( Get_Queue_Name(i) );
762    fatal_posix_service_status( status, 0, "mq_unlink message queue");
763
764    status = mq_close( Test_q[i].mq );
765    fatal_posix_service_status( status, 0, "mq_close message queue");
766  }
767}
768
769
770void verify_timed_send_queue(
771  int  que,
772  int  is_blocking
773)
774{
775  struct timespec timeout;
776  struct timeval  tv1, tv2, tv3;
777  struct timezone tz1, tz2;
778  int              len;
779  int              status;
780  char            *msg;
781
782  printf( "Init: mq_timedsend - on queue %s ", Test_q[que].name);
783  len = Predefined_Msgs[MAXMSG].size;
784  msg = Predefined_Msgs[MAXMSG].msg;
785
786  gettimeofday( &tv1, &tz1 );
787  timeout.tv_sec  = tv1.tv_sec + 1;
788  timeout.tv_nsec = tv1.tv_usec * 1000;
789
790  status = mq_timedsend( Test_q[que].mq, msg, len , 0, &timeout );
791
792  gettimeofday( &tv2, &tz2 );
793  tv3.tv_sec  = tv2.tv_sec - tv1.tv_sec;
794  tv3.tv_usec = tv2.tv_usec - tv1.tv_usec;
795
796  if ( is_blocking ) { /* Don't verify the non-blocking queue */
797    fatal_int_service_status( status, -1, "mq_timedsend status" );
798    fatal_posix_service_status( errno, ETIMEDOUT,  "errno ETIMEDOUT" );
799  }
800
801  printf( "Init: %ld sec %ld us\n", (long)tv3.tv_sec, (long)tv3.tv_usec );
802
803  if ( que == DEFAULT_RW )
804    Test_q[que].count++;
805}
806
807void verify_timed_send(void)
808{
809  int              que;
810
811  Start_Test( "mq_timedsend"  );
812
813  for( que = RW_QUEUE; que < CLOSED; que++ ) {
814    if ( que == BLOCKING )
815      verify_timed_send_queue( que, 1 );
816    else
817      verify_timed_send_queue( que, 0 );
818  }
819}
820
821void verify_timed_receive_queue(
822  char *task_name,
823  int   que,
824  int   is_blocking
825)
826{
827  char message[ 100 ];
828  unsigned int priority;
829  struct timespec tm;
830  struct timeval  tv1, tv2, tv3;
831  struct timezone tz1, tz2;
832  int              status;
833
834  printf(
835    "Init: %s mq_timedreceive - on queue %s ",
836    task_name,
837    Test_q[que].name
838  );
839
840  gettimeofday( &tv1, &tz1 );
841  tm.tv_sec  = tv1.tv_sec + 1;
842  tm.tv_nsec = tv1.tv_usec * 1000;
843
844  status = mq_timedreceive( Test_q[ que ].mq, message, 100, &priority, &tm );
845
846  gettimeofday( &tv2, &tz2 );
847  tv3.tv_sec  = tv2.tv_sec - tv1.tv_sec;
848  tv3.tv_usec = tv2.tv_usec - tv1.tv_usec;
849
850  fatal_int_service_status( status, -1, "mq_timedreceive status");
851  if ( is_blocking )
852    fatal_posix_service_status( errno, ETIMEDOUT,  "errno ETIMEDOUT");
853  printf( "Init: %ld sec %ld us\n", (long)tv3.tv_sec, (long)tv3.tv_usec );
854
855}
856
857void verify_timed_receive(void)
858{
859  int  que;
860
861  Start_Test( "mq_timedreceive"  );
862
863  for( que = RW_QUEUE; que < CLOSED; que++ ) {
864    if (( que == BLOCKING ) || ( que == DEFAULT_RW ))
865      verify_timed_receive_queue( "Init:", que, 1 );
866    else
867      verify_timed_receive_queue( "Init:", que, 0 );
868  }
869}
870
871#if (0)
872void verify_set_attr(void)
873{
874  struct mq_attr save_attr[ NUMBER_OF_TEST_QUEUES ];
875  struct mq_attr attr;
876  int            i;
877  int            status;
878
879  attr.mq_maxmsg  = 0;
880  attr.mq_msgsize = 0;
881
882  Start_Test( "mq_setattr"  );
883
884  puts( "Init: set_attr all queues to blocking" );
885  for(i=0; i<CLOSED; i++) {
886    attr.mq_flags =  Test_q[i].oflag & (~O_NONBLOCK );
887    status = mq_setattr( Test_q[i].mq, &attr, &save_attr[i] );
888    fatal_int_service_status( status, 0, "mq_setattr valid return status");
889
890    Validate_attributes( Test_q[i].mq, attr.mq_flags, 0 );
891  }
892
893  for( i = RW_QUEUE; i < CLOSED; i++ ) {
894    verify_timed_receive_queue( "Init:", i, 1 );
895  }
896
897  for(i=0; i<CLOSED; i++) {
898    attr.mq_flags =  Test_q[i].oflag & (~O_NONBLOCK );
899    status = mq_setattr( Test_q[i].mq, &save_attr[i], NULL );
900    fatal_int_service_status( status, 0, "mq_setattr valid return status");
901
902    Validate_attributes( Test_q[i].mq, Test_q[i].oflag, 0 );
903  }
904}
905#endif
906
907void wait_for_signal(
908  sigset_t     *waitset,
909  int           sec,
910  int           expect_signal
911)
912{
913  siginfo_t         siginfo;
914  int               status;
915  struct timespec   timeout;
916  int               signo;
917
918  siginfo.si_code = -1;
919  siginfo.si_signo = -1;
920  siginfo.si_value.sival_int = -1;
921
922  timeout.tv_sec = sec;
923  timeout.tv_nsec = 0;
924
925  status = sigemptyset( waitset );
926  rtems_test_assert( !status );
927
928  status = sigaddset( waitset, SIGUSR1 );
929  rtems_test_assert( !status );
930
931  printf( "waiting on any signal for %d seconds.\n", sec );
932  signo = sigtimedwait( waitset, &siginfo, &timeout );
933  if (expect_signal) {
934    fatal_int_service_status( signo, SIGUSR1, "got SISUSR1" );
935  } else {
936    fatal_int_service_status( signo, -1, "error return status");
937    fatal_posix_service_status( errno, EAGAIN, "errno EAGAIN");
938  }
939}
940
941void verify_notify(void)
942{
943  struct sigevent event;
944  int             status;
945  timer_t         timer_id;
946  sigset_t        set;
947
948  Start_Test( "mq_notify"  );
949
950  /* timer create */
951  event.sigev_notify = SIGEV_SIGNAL;
952  event.sigev_signo  = SIGUSR1;
953  if (timer_create (CLOCK_REALTIME, &event, &timer_id) == -1)
954    fatal_posix_service_status( errno, 0,  "errno ETIMEDOUT");
955
956  /* block the timer signal */
957  sigemptyset( &set );
958  sigaddset( &set, SIGUSR1 );
959  pthread_sigmask( SIG_BLOCK, &set, NULL );
960
961  /*
962   * EBADF - Not A Valid Message Queue
963   */
964
965  puts( "Init: mq_notify - Unopened message queue (EBADF)" );
966  status = mq_notify( Test_q[CLOSED].mq, NULL );
967  fatal_posix_service_status( status, -1, "mq_ error return status");
968  fatal_posix_service_status( errno, EBADF, "mq_receive errno EBADF");
969
970  /*
971   * Create ...
972   */
973
974  /*
975   * XXX setup notification
976   */
977  printf( "_____mq_notify - notify when %s gets a message\n",RW_NAME);
978  status = mq_notify( Test_q[RW_QUEUE].mq, &event );
979  fatal_posix_service_status( status, 0, "mq_notify valid status");
980  wait_for_signal( &set, 3, 0 );
981
982  /*
983   * Send and verify signal occurs and registration is removed.
984   */
985
986  puts( "Init: Verify Signal when send" );
987  Show_send_msg_to_que( "Init:", RW_QUEUE, 0 );
988  wait_for_signal( &set, 3, 1 );
989  Read_msg_from_que( RW_QUEUE, 0 );
990
991  puts( "Init: Verify No Signal when send" );
992  Show_send_msg_to_que( "Init:", RW_QUEUE, 0 );
993  wait_for_signal( &set, 3, 0 );
994  Read_msg_from_que( RW_QUEUE, 0 );
995
996  /*
997   * EBUSY - Already Registered
998   */
999
1000  printf( "____mq_notify - notify when %s gets a message\n",RD_NAME);
1001  status = mq_notify( Test_q[RW_QUEUE].mq, &event );
1002  fatal_posix_service_status( status, 0, "mq_notify valid status");
1003  wait_for_signal( &set, 3, 0 );
1004
1005  puts( "Init: mq_notify -  (EBUSY)" );
1006  status = mq_notify( Test_q[RW_QUEUE].mq, &event );
1007  fatal_posix_service_status( status, -1, "mq_notify error return status");
1008  fatal_posix_service_status( errno, EBUSY, "mq_notify errno EBUSY");
1009
1010  /*
1011   * Verify NULL removes registration.
1012   */
1013
1014  puts( "Init: mq_notify - Remove notification with null" );
1015  status = mq_notify( Test_q[RW_QUEUE].mq, NULL );
1016  fatal_posix_service_status( status, 0, "mq_notify valid status");
1017
1018  puts( "Init: Verify No Signal when send" );
1019  Show_send_msg_to_que( "Init:", RW_QUEUE, 0 );
1020  wait_for_signal( &set, 3, 0 );
1021  Read_msg_from_que( RW_QUEUE, 0 );
1022
1023}
1024
1025void verify_with_threads(void)
1026{
1027  int               status;
1028  pthread_t         id;
1029  Test_Message_t   *ptr;
1030#if 0
1031  unsigned int      priority;
1032  char              message[100];
1033#endif
1034
1035
1036#if 0
1037  /*
1038   * Create a task then block until the task sends the message.
1039   * Task tests set attributes so one queue will have a thread
1040   * blocked while attributes are changed.
1041   */
1042
1043  Start_Test( "multi-thread Task 4 Receive Test"  );
1044  status = pthread_create( &id, NULL, Task_4, NULL );
1045  rtems_test_assert( !status );
1046  puts( "Init: mq_receive - Empty queue changes to non-blocking (EAGAIN)" );
1047  status = mq_receive( Test_q[BLOCKING].mq, message, 100, &priority );
1048  fatal_int_service_status( status, -1, "mq_receive error return status");
1049  fatal_posix_service_status( errno, EAGAIN, "mq_receive errno EAGAIN");
1050  print_current_time( "Init: ", "" );
1051#endif
1052  /*
1053   * Create a task then block until the task sends the message.
1054   * Task tests set attributes so one queue will have a thread
1055   * blocked while attributes are changed.
1056   */
1057
1058  Start_Test( "multi-thread Task 1 Test"  );
1059  status = pthread_create( &id, NULL, Task_1, NULL );
1060  rtems_test_assert( !status );
1061  Read_msg_from_que(  BLOCKING, 0 ); /* Block until init writes */
1062  print_current_time( "Init: ", "" );
1063
1064#if 0
1065  /*
1066   * Fill the queue then create a task then block until the task receives a message.
1067   * Task tests set attributes so one queue will have a thread
1068   * blocked while attributes are changed.
1069   */
1070
1071  Start_Test( "multi-thread Task 4 Send Test"  );
1072  fill_message_queues( "Init:" );
1073  status = pthread_create( &id, NULL, Task_4, NULL );
1074  rtems_test_assert( !status );
1075  puts( "Init: mq_send - Full queue changes to non-blocking (EAGAIN)" );
1076  status = mq_send(Test_q[BLOCKING].mq, message, 0, 0 );
1077  fatal_posix_service_status( status, -1, "mq_send error return status");
1078  fatal_posix_service_status( errno, EAGAIN, "mq_send errno EAGAIN");
1079  verify_queues_full( "Init:" );
1080  empty_message_queues( "Init:" );
1081#endif
1082  /*
1083   * Create a task then block until the task reads a message.
1084   */
1085
1086  Start_Test( "multi-thread Task 2 Test"  );
1087  fill_message_queues( "Init:" );
1088  status = pthread_create( &id, NULL, Task_2, NULL );
1089  rtems_test_assert( !status );
1090  Show_send_msg_to_que( "Init:", BLOCKING, Priority_Order[0] );
1091  print_current_time( "Init: ", "" );
1092  verify_queues_full( "Init:" );
1093  empty_message_queues( "Init:" );
1094
1095  /*
1096   * Create a task then block until it deletes and closes all queues.
1097   *     EBADF - Queue unlinked and closed while blocked
1098   */
1099
1100  Start_Test( "multi-thread Task 3 Test"  );
1101  fill_message_queues( "Init:" );
1102  status = pthread_create( &id, NULL, Task_3, NULL );
1103  rtems_test_assert( !status );
1104  puts( "Init: mq_send - Block while thread deletes queue (EBADF)" );
1105  ptr = &Predefined_Msgs[0];
1106  status = mq_send( Test_q[BLOCKING].mq, ptr->msg, ptr->size , ptr->priority );
1107  fatal_posix_service_status( status, -1, "mq_send error return status");
1108  fatal_posix_service_status( errno, EBADF, "mq_send errno EBADF");
1109
1110}
1111
1112void validate_mq_setattr(void)
1113{
1114  struct mq_attr  attr;
1115  struct mq_attr  save_attr[ NUMBER_OF_TEST_QUEUES ];
1116  int             status;
1117  int            i;
1118
1119  /*
1120   * EBADF - Get the attributes from a closed queue.
1121   */
1122
1123  puts( "Task1:mq_setattr - unopened queue (EBADF)" );
1124  status = mq_setattr( Test_q[CLOSED].mq, &attr, NULL );
1125  fatal_posix_service_status( status, -1, "mq_setattr error return status");
1126  fatal_posix_service_status( errno, EBADF, "mq_setattr errno EBADF");
1127
1128  /*
1129   * XXX - The following are not listed in the POSIX manual but
1130   *       may occur.
1131   */
1132
1133  /*
1134   * EINVAL - NULL attributes
1135   */
1136
1137  puts( "Task1:mq_setattr - NULL attributes (EINVAL)" );
1138  status = mq_setattr( Test_q[RW_QUEUE].mq, NULL, NULL );
1139  fatal_posix_service_status( status, -1, "mq_setattr error return status");
1140  fatal_posix_service_status( errno, EINVAL, "mq_setattr errno EINVAL");
1141
1142  /*
1143   * Verify change queues to blocking, by verifying all queues block
1144   * for a timed receive.
1145   */
1146
1147  puts( "Init: set_attr all queues to blocking" );
1148  for(i=0; i<CLOSED; i++) {
1149    attr.mq_flags =  Test_q[i].oflag & (~O_NONBLOCK );
1150    status = mq_setattr( Test_q[i].mq, &attr, &save_attr[i] );
1151    fatal_int_service_status( status, 0, "mq_setattr valid return status");
1152    Validate_attributes( Test_q[i].mq, attr.mq_flags, 0 );
1153  }
1154  for( i = RW_QUEUE; i < CLOSED; i++ ) {
1155    verify_timed_receive_queue( "Init:", i, 1 );
1156  }
1157
1158  /*
1159   * Restore restore all queues to their old attribute.
1160   */
1161
1162  for(i=0; i<CLOSED; i++) {
1163    status = mq_setattr( Test_q[i].mq, &save_attr[i], NULL );
1164    fatal_int_service_status( status, 0, "mq_setattr valid return status");
1165    Validate_attributes( Test_q[i].mq, Test_q[i].oflag, 0 );
1166  }
1167}
1168
1169void verify_timedout_mq_timedreceive(
1170  char *task_name,
1171  int   que,
1172  int   is_blocking
1173)
1174{
1175  char             message[ 100 ];
1176  struct timespec  tm;
1177  struct timeval   tv1, tv2, tv3;
1178  struct timezone  tz1, tz2;
1179  int              status;
1180
1181  printf(
1182    "Init: %s verify_timedout_mq_timedreceive - on queue %s ",
1183    task_name,
1184    Test_q[que].name
1185  );
1186
1187  gettimeofday( &tv1, &tz1 );
1188  tm.tv_sec  = tv1.tv_sec - 1;
1189  tm.tv_nsec = tv1.tv_usec * 1000;
1190
1191  status = mq_timedreceive( Test_q[ que ].mq, message, 100, NULL, &tm );
1192
1193  gettimeofday( &tv2, &tz2 );
1194  tv3.tv_sec  = tv2.tv_sec - tv1.tv_sec;
1195  tv3.tv_usec = tv2.tv_usec - tv1.tv_usec;
1196
1197  fatal_int_service_status( status, -1, "mq_timedreceive status");
1198
1199/* FIXME: This is wrong. */
1200  printf( "Init: %ld sec %ld us\n", (long)tv3.tv_sec, (long)tv3.tv_usec );
1201}
1202
1203void verify_mq_receive(void)
1204{
1205  int  que;
1206
1207  Start_Test( "mq_timedout_receive"  );
1208
1209  for( que = RW_QUEUE; que < CLOSED; que++ ) {
1210    if (( que == BLOCKING ) || ( que == DEFAULT_RW ))
1211      break;
1212    else
1213      verify_timedout_mq_timedreceive( "Init:", que, 0 );
1214  }
1215}
1216
1217void verify_timedout_mq_timedsend(
1218  int  que,
1219  int  is_blocking
1220)
1221{
1222  struct timespec timeout;
1223  struct timeval  tv1, tv2, tv3;
1224  struct timezone tz1, tz2;
1225  int              len;
1226  char            *msg;
1227
1228  printf( "Init: verify_timedout_mq_timedsend - on queue %s ", Test_q[que].name);
1229  len = Predefined_Msgs[MAXMSG].size;
1230  msg = Predefined_Msgs[MAXMSG].msg;
1231
1232  gettimeofday( &tv1, &tz1 );
1233  timeout.tv_sec  = tv1.tv_sec - 1;
1234  timeout.tv_nsec = tv1.tv_usec * 1000;
1235
1236  (void) mq_timedsend( Test_q[que].mq, msg, len , 0, &timeout );
1237
1238  gettimeofday( &tv2, &tz2 );
1239  tv3.tv_sec  = tv2.tv_sec - tv1.tv_sec;
1240  tv3.tv_usec = tv2.tv_usec - tv1.tv_usec;
1241
1242  printf( "Init: %ld sec %ld us\n", (long)tv3.tv_sec, (long)tv3.tv_usec );
1243
1244  if ( que == DEFAULT_RW )
1245    Test_q[que].count++;
1246}
1247
1248void verify_mq_send(void)
1249{
1250  int              que;
1251
1252  Start_Test( "verify_timedout_mq_timedsend"  );
1253
1254  for( que = RW_QUEUE; que < CLOSED; que++ ) {
1255    if ( que == BLOCKING )
1256      verify_timedout_mq_timedsend( que, 1 );
1257    else
1258      verify_timedout_mq_timedsend( que, 0 );
1259  }
1260}
1261
1262static void *receive_maxmsg_plus_one( void *arg )
1263{
1264  mqd_t                 mq;
1265  const Test_Message_t *m;
1266  int                   i;
1267
1268  mq = Test_q[ BLOCKING ].mq;
1269  m = &Predefined_Msgs[ 0 ];
1270
1271  for ( i = 0; i < MAXMSG + 1; ++i ) {
1272    Test_Message_t a;
1273    unsigned       prio;
1274    ssize_t        n;
1275
1276    n = mq_receive( mq, &a.msg[0], sizeof(a.msg), &prio);
1277    rtems_test_assert( n == m->size );
1278    rtems_test_assert( prio == m->priority );
1279    rtems_test_assert( memcmp( &a.msg[0], &m->msg[0], (size_t) n ) == 0 );
1280  }
1281
1282  return arg;
1283}
1284
1285static void verify_blocking_mq_timedsend( void )
1286{
1287  mqd_t                 mq;
1288  const Test_Message_t *m;
1289  int                   status;
1290  struct timespec       timeout;
1291  pthread_t             thread;
1292  void                 *exit_value;
1293  rtems_status_code     sc;
1294
1295  Start_Test( "verify_blocking_mq_timedsend"  );
1296
1297  mq = Test_q[ BLOCKING ].mq;
1298  m = &Predefined_Msgs[ 0 ];
1299
1300  /*
1301   * Create and suspend the receive thread early so that we don't overwrite the
1302   * ETIMEDOUT in executing->Wait.return_code.  This verifies the succesful
1303   * mq_timedreceive() later.
1304   */
1305
1306  status = pthread_create( &thread, NULL, receive_maxmsg_plus_one, &thread );
1307  fatal_posix_service_status( status, 0, "pthread_create" );
1308
1309  sc = rtems_task_suspend( thread );
1310  fatal_directive_status( sc, RTEMS_SUCCESSFUL, "rtems_task_suspend" );
1311
1312  do {
1313    status = clock_gettime( CLOCK_REALTIME, &timeout );
1314    fatal_posix_service_status( status, 0, "clock_gettime" );
1315    ++timeout.tv_sec;
1316
1317    status = mq_timedsend( mq, m->msg, m->size , m->priority, &timeout );
1318  } while ( status == 0 );
1319
1320  fatal_posix_service_status_errno( status, ETIMEDOUT, "mq_timedsend");
1321
1322  sc = rtems_task_resume( thread );
1323  fatal_directive_status( sc, RTEMS_SUCCESSFUL, "rtems_task_resume" );
1324
1325  status = clock_gettime( CLOCK_REALTIME, &timeout );
1326  fatal_posix_service_status( status, 0, "clock_gettime" );
1327  ++timeout.tv_sec;
1328
1329  status = mq_timedsend( mq, m->msg, m->size , m->priority, &timeout );
1330  fatal_posix_service_status( status, 0, "mq_timedsend" );
1331
1332  exit_value = NULL;
1333  status = pthread_join( thread, &exit_value );
1334  fatal_posix_service_status( status, 0, "pthread_join" );
1335  rtems_test_assert( exit_value == &thread );
1336}
1337
1338void *POSIX_Init(
1339  void *argument
1340)
1341{
1342  TEST_BEGIN();
1343
1344  validate_mq_open_error_codes( );
1345  open_test_queues();
1346  verify_blocking_mq_timedsend();
1347  validate_mq_unlink_error_codes();
1348  validate_mq_close_error_codes();
1349  verify_unlink_functionality();
1350  validate_mq_setattr( );
1351  validate_mq_send_error_codes();
1352  validate_mq_getattr_error_codes();
1353  verify_timed_send();
1354  validate_mq_receive_error_codes();
1355  verify_timed_receive();
1356  verify_open_functionality();
1357  verify_notify();
1358  verify_with_threads();
1359  verify_mq_receive();
1360  verify_mq_send();
1361
1362  TEST_END();
1363  rtems_test_exit( 0 );
1364
1365  return NULL; /* just so the compiler thinks we returned something */
1366}
1367
1368
1369void *Task_1 (
1370  void *argument
1371)
1372{
1373  /* Block Waiting for a message */
1374
1375  print_current_time( "Task_1: ", "" );
1376
1377  Show_send_msg_to_que( "Task_1:", BLOCKING, 0 );
1378
1379  puts( "Task_1: pthread_exit" );
1380  pthread_exit( NULL );
1381
1382  /* switch to Init */
1383
1384  rtems_test_assert( 0 );
1385  return NULL; /* just so the compiler thinks we returned something */
1386}
1387
1388void *Task_2(
1389  void *argument
1390)
1391{
1392  print_current_time( "Task_2: ", "" );
1393
1394
1395  /* Block waiting to send a message */
1396
1397  verify_queues_full( "Task_2:" );
1398  Read_msg_from_que( BLOCKING, Priority_Order[0] ); /* Cause context switch */
1399
1400  puts( "Task_2: pthread_exit" );
1401  pthread_exit( NULL );
1402
1403     /* switch to Init */
1404
1405  return NULL; /* just so the compiler thinks we returned something */
1406}
1407
1408void *Task_3 (
1409  void *argument
1410)
1411{
1412
1413  print_current_time( "Task_3: ", "" );
1414
1415  /*
1416   * close and unlink all queues.
1417   */
1418
1419  verify_close_functionality();
1420  puts( "Task_3: pthread_exit" );
1421  pthread_exit( NULL );
1422
1423     /* switch to Init */
1424
1425  return NULL; /* just so the compiler thinks we returned something */
1426
1427}
1428
1429void *Task_4 (
1430  void *argument
1431)
1432{
1433  struct mq_attr  attr;
1434  int             status;
1435  int             count;
1436
1437  print_current_time( "Task_4: ", "" );
1438
1439  /*
1440   * Set the count to the number of messages in the queue.
1441   */
1442
1443  status = mq_getattr( Test_q[BLOCKING].mq, &attr );
1444  fatal_posix_service_status( status, 0, "mq_getattr valid return status");
1445  count = attr.mq_curmsgs;
1446
1447  puts("Task_4: Set queue to non-blocking");
1448  attr.mq_flags =  Test_q[BLOCKING].oflag | O_NONBLOCK;
1449  status = mq_setattr( Test_q[BLOCKING].mq, &attr, NULL );
1450  fatal_int_service_status( status, 0, "mq_setattr valid return status");
1451  Validate_attributes( Test_q[BLOCKING].mq, attr.mq_flags, count );
1452
1453  puts("Task_4: Return queue to blocking");
1454  attr.mq_flags =  Test_q[BLOCKING].oflag;
1455  status = mq_setattr( Test_q[BLOCKING].mq, &attr, NULL );
1456  fatal_int_service_status( status, 0, "mq_setattr valid return status");
1457  Validate_attributes( Test_q[BLOCKING].mq, attr.mq_flags, count );
1458
1459  puts( "Task_4: pthread_exit" );
1460  pthread_exit( NULL );
1461
1462     /* switch to Init */
1463
1464  return NULL; /* just so the compiler thinks we returned something */
1465
1466}
1467
1468void *Task_5 (
1469  void *argument
1470)
1471{
1472
1473  print_current_time( "Task_5: ", "" );
1474
1475  puts( "Task_5: pthread_exit" );
1476  pthread_exit( NULL );
1477
1478     /* switch to Init */
1479
1480  return NULL; /* just so the compiler thinks we returned something */
1481
1482}
Note: See TracBrowser for help on using the repository browser.