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

4.115
Last change on this file since c499856 was c499856, checked in by Chris Johns <chrisj@…>, on 03/20/14 at 21:10:47

Change all references of rtems.com to rtems.org.

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