source: rtems/testsuites/psxtests/psxmsgq01/init.c @ 6c2de60

4.115
Last change on this file since 6c2de60 was 6c2de60, checked in by Joel Sherrill <joel.sherrill@…>, on 05/11/12 at 19:12:11

psxtests - Eliminate missing prototype warnings

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