1 /* Test SIGEV_THREAD handling for POSIX message queues.
2 Copyright (C) 2004 Free Software Foundation, Inc.
3 This file is part of the GNU C Library.
4 Contributed by Ulrich Drepper <drepper@redhat.com>, 2004.
6 The GNU C Library is free software; you can redistribute it and/or
7 modify it under the terms of the GNU Lesser General Public
8 License as published by the Free Software Foundation; either
9 version 2.1 of the License, or (at your option) any later version.
11 The GNU C Library is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Lesser General Public License for more details.
16 You should have received a copy of the GNU Lesser General Public
17 License along with the GNU C Library; if not, write to the Free
18 Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
38 static const char message
[] = "hello";
48 /* Put the mq in non-blocking mode. */
50 if (mq_getattr (m
, &attr
) != 0)
52 printf ("%s: mq_getattr failed: %m\n", __FUNCTION__
);
55 attr
.mq_flags
|= O_NONBLOCK
;
56 if (mq_setattr (m
, &attr
, NULL
) != 0)
58 printf ("%s: mq_setattr failed: %m\n", __FUNCTION__
);
62 /* Check the values. */
63 if (attr
.mq_maxmsg
!= MAXMSG
)
65 printf ("%s: mq_maxmsg wrong: is %ld, expecte %d\n",
66 __FUNCTION__
, attr
.mq_maxmsg
, MAXMSG
);
69 if (attr
.mq_msgsize
!= MAXMSG
)
71 printf ("%s: mq_msgsize wrong: is %ld, expecte %d\n",
72 __FUNCTION__
, attr
.mq_msgsize
, MSGSIZE
);
76 /* Read the message. */
77 char buf
[attr
.mq_msgsize
];
78 ssize_t n
= TEMP_FAILURE_RETRY (mq_receive (m
, buf
, attr
.mq_msgsize
, NULL
));
79 if (n
!= sizeof (message
))
81 printf ("%s: length of message wrong: is %zd, expected %zu\n",
82 __FUNCTION__
, n
, sizeof (message
));
85 if (memcmp (buf
, message
, sizeof (message
)) != 0)
87 printf ("%s: message wrong: is \"%s\", expected \"%s\"\n",
88 __FUNCTION__
, buf
, message
);
99 char tmpfname
[] = "/tmp/tst-mqueue3-barrier.XXXXXX";
100 int fd
= mkstemp (tmpfname
);
103 printf ("cannot open temporary file: %m\n");
107 /* Make sure it is always removed. */
110 /* Create one page of data. */
111 size_t ps
= sysconf (_SC_PAGESIZE
);
113 memset (data
, '\0', ps
);
115 /* Write the data to the file. */
116 if (write (fd
, data
, ps
) != (ssize_t
) ps
)
118 puts ("short write");
122 void *mem
= mmap (NULL
, ps
, PROT_READ
| PROT_WRITE
, MAP_SHARED
, fd
, 0);
123 if (mem
== MAP_FAILED
)
125 printf ("mmap failed: %m\n");
129 pthread_barrier_t
*b
;
130 b
= (pthread_barrier_t
*) (((uintptr_t) mem
+ __alignof (pthread_barrier_t
))
131 & ~(__alignof (pthread_barrier_t
) - 1));
133 pthread_barrierattr_t a
;
134 if (pthread_barrierattr_init (&a
) != 0)
136 puts ("barrierattr_init failed");
140 if (pthread_barrierattr_setpshared (&a
, PTHREAD_PROCESS_SHARED
) != 0)
142 puts ("barrierattr_setpshared failed, could not test");
146 if (pthread_barrier_init (b
, &a
, 2) != 0)
148 puts ("barrier_init failed");
152 if (pthread_barrierattr_destroy (&a
) != 0)
154 puts ("barrierattr_destroy failed");
158 /* Name for the message queue. */
159 char mqname
[sizeof ("/tst-mqueue3-") + 3 * sizeof (pid_t
)];
160 snprintf (mqname
, sizeof (mqname
) - 1, "/tst-mqueue3-%ld",
161 (long int) getpid ());
163 /* Create the message queue. */
164 struct mq_attr attr
= { .mq_maxmsg
= MAXMSG
, .mq_msgsize
= MSGSIZE
};
165 m
= mq_open (mqname
, O_CREAT
| O_EXCL
| O_RDWR
, 0600, &attr
);
170 puts ("not implemented");
174 puts ("mq_open failed");
178 /* Unlink the message queue right away. */
179 if (mq_unlink (mqname
) != 0)
181 puts ("mq_unlink failed");
188 puts ("fork failed");
193 /* Request notification via thread. */
195 ev
.sigev_notify
= SIGEV_THREAD
;
196 ev
.sigev_notify_function
= fct
;
197 ev
.sigev_value
.sival_ptr
= NULL
;
198 ev
.sigev_notify_attributes
= NULL
;
200 /* Tell the kernel. */
201 if (mq_notify (m
,&ev
) != 0)
203 puts ("mq_notify failed");
207 /* Tell the parent we are ready. */
208 (void) pthread_barrier_wait (b
);
210 /* Make sure the process goes away eventually. */
213 /* Do nothing forever. */
218 /* Wait for the child process to register to notification method. */
219 (void) pthread_barrier_wait (b
);
221 /* Send the message. */
222 if (mq_send (m
, message
, sizeof (message
), 1) != 0)
225 puts ("mq_send failed");
230 if (TEMP_FAILURE_RETRY (waitpid (pid
, &r
, 0)) != pid
)
233 puts ("waitpid failed");
237 return WIFEXITED (r
) && WEXITSTATUS (r
) == UNIQUE
? 0 : 1;
239 # define TEST_FUNCTION do_test ()
241 # define TEST_FUNCTION 0
244 #include "../test-skeleton.c"