1 /* Test SIGEV_THREAD handling for POSIX message queues.
2 Copyright (C) 2004-2016 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, see
18 <http://www.gnu.org/licenses/>. */
37 static const char message
[] = "hello";
47 /* Put the mq in non-blocking mode. */
49 if (mq_getattr (m
, &attr
) != 0)
51 printf ("%s: mq_getattr failed: %m\n", __FUNCTION__
);
54 attr
.mq_flags
|= O_NONBLOCK
;
55 if (mq_setattr (m
, &attr
, NULL
) != 0)
57 printf ("%s: mq_setattr failed: %m\n", __FUNCTION__
);
61 /* Check the values. */
62 if (attr
.mq_maxmsg
!= MAXMSG
)
64 printf ("%s: mq_maxmsg wrong: is %jd, expecte %d\n",
65 __FUNCTION__
, (intmax_t) attr
.mq_maxmsg
, MAXMSG
);
68 if (attr
.mq_msgsize
!= MAXMSG
)
70 printf ("%s: mq_msgsize wrong: is %jd, expecte %d\n",
71 __FUNCTION__
, (intmax_t) attr
.mq_msgsize
, MSGSIZE
);
75 /* Read the message. */
76 char buf
[attr
.mq_msgsize
];
77 ssize_t n
= TEMP_FAILURE_RETRY (mq_receive (m
, buf
, attr
.mq_msgsize
, NULL
));
78 if (n
!= sizeof (message
))
80 printf ("%s: length of message wrong: is %zd, expected %zu\n",
81 __FUNCTION__
, n
, sizeof (message
));
84 if (memcmp (buf
, message
, sizeof (message
)) != 0)
86 printf ("%s: message wrong: is \"%s\", expected \"%s\"\n",
87 __FUNCTION__
, buf
, message
);
98 char tmpfname
[] = "/tmp/tst-mqueue3-barrier.XXXXXX";
99 int fd
= mkstemp (tmpfname
);
102 printf ("cannot open temporary file: %m\n");
106 /* Make sure it is always removed. */
109 /* Create one page of data. */
110 size_t ps
= sysconf (_SC_PAGESIZE
);
112 memset (data
, '\0', ps
);
114 /* Write the data to the file. */
115 if (write (fd
, data
, ps
) != (ssize_t
) ps
)
117 puts ("short write");
121 void *mem
= mmap (NULL
, ps
, PROT_READ
| PROT_WRITE
, MAP_SHARED
, fd
, 0);
122 if (mem
== MAP_FAILED
)
124 printf ("mmap failed: %m\n");
128 pthread_barrier_t
*b
;
129 b
= (pthread_barrier_t
*) (((uintptr_t) mem
+ __alignof (pthread_barrier_t
))
130 & ~(__alignof (pthread_barrier_t
) - 1));
132 pthread_barrierattr_t a
;
133 if (pthread_barrierattr_init (&a
) != 0)
135 puts ("barrierattr_init failed");
139 if (pthread_barrierattr_setpshared (&a
, PTHREAD_PROCESS_SHARED
) != 0)
141 puts ("barrierattr_setpshared failed, could not test");
145 if (pthread_barrier_init (b
, &a
, 2) != 0)
147 puts ("barrier_init failed");
151 if (pthread_barrierattr_destroy (&a
) != 0)
153 puts ("barrierattr_destroy failed");
157 /* Name for the message queue. */
158 char mqname
[sizeof ("/tst-mqueue3-") + 3 * sizeof (pid_t
)];
159 snprintf (mqname
, sizeof (mqname
) - 1, "/tst-mqueue3-%ld",
160 (long int) getpid ());
162 /* Create the message queue. */
163 struct mq_attr attr
= { .mq_maxmsg
= MAXMSG
, .mq_msgsize
= MSGSIZE
};
164 m
= mq_open (mqname
, O_CREAT
| O_EXCL
| O_RDWR
, 0600, &attr
);
169 puts ("not implemented");
173 puts ("mq_open failed");
177 /* Unlink the message queue right away. */
178 if (mq_unlink (mqname
) != 0)
180 puts ("mq_unlink failed");
187 puts ("fork failed");
192 /* Request notification via thread. */
194 ev
.sigev_notify
= SIGEV_THREAD
;
195 ev
.sigev_notify_function
= fct
;
196 ev
.sigev_value
.sival_ptr
= NULL
;
197 ev
.sigev_notify_attributes
= NULL
;
199 /* Tell the kernel. */
200 if (mq_notify (m
,&ev
) != 0)
202 puts ("mq_notify failed");
206 /* Tell the parent we are ready. */
207 (void) pthread_barrier_wait (b
);
209 /* Make sure the process goes away eventually. */
212 /* Do nothing forever. */
217 /* Wait for the child process to register to notification method. */
218 (void) pthread_barrier_wait (b
);
220 /* Send the message. */
221 if (mq_send (m
, message
, sizeof (message
), 1) != 0)
224 puts ("mq_send failed");
229 if (TEMP_FAILURE_RETRY (waitpid (pid
, &r
, 0)) != pid
)
232 puts ("waitpid failed");
236 return WIFEXITED (r
) && WEXITSTATUS (r
) == UNIQUE
? 0 : 1;
238 # define TEST_FUNCTION do_test ()
240 # define TEST_FUNCTION 0
243 #include "../test-skeleton.c"