]> git.ipfire.org Git - thirdparty/man-pages.git/blame - man3/sem_wait.3
getcpu.2, sendfile.2, cmsg.3, rtnetlink.3, arp.7, ddp.7, fifo.7, icmp.7, ip.7, ipv6...
[thirdparty/man-pages.git] / man3 / sem_wait.3
CommitLineData
2c731798 1'\" t
c11b1abf 2.\" Copyright (C) 2006 Michael Kerrisk <mtk.manpages@gmail.com>
2c731798 3.\"
4b72fb64 4.\" %%%LICENSE_START(verbatim)
2c731798
MK
5.\" Permission is granted to make and distribute verbatim copies of this
6.\" manual provided the copyright notice and this permission notice are
7.\" preserved on all copies.
8.\"
9.\" Permission is granted to copy and distribute modified versions of this
10.\" manual under the conditions for verbatim copying, provided that the
11.\" entire resulting derived work is distributed under the terms of a
12.\" permission notice identical to this one.
c13182ef 13.\"
2c731798
MK
14.\" Since the Linux kernel and libraries are constantly changing, this
15.\" manual page may be incorrect or out-of-date. The author(s) assume no
16.\" responsibility for errors or omissions, or for damages resulting from
10d76543
MK
17.\" the use of the information contained herein. The author(s) may not
18.\" have taken the same level of care in the production of this manual,
19.\" which is licensed free of charge, as they might when working
20.\" professionally.
c13182ef 21.\"
2c731798
MK
22.\" Formatted or processed versions of this manual, if unaccompanied by
23.\" the source, must acknowledge the copyright and authors of this work.
4b72fb64 24.\" %%%LICENSE_END
2c731798 25.\"
2c5f8c8c 26.TH SEM_WAIT 3 2012-05-13 "Linux" "Linux Programmer's Manual"
2c731798 27.SH NAME
6f4b6fc9 28sem_wait, sem_timedwait, sem_trywait \- lock a semaphore
2c731798
MK
29.SH SYNOPSIS
30.nf
31.B #include <semaphore.h>
32.sp
33.BI "int sem_wait(sem_t *" sem );
5895e7eb 34.sp
2c731798 35.BI "int sem_trywait(sem_t *" sem );
5895e7eb 36.sp
2c731798
MK
37.BI "int sem_timedwait(sem_t *" sem ", const struct timespec *" abs_timeout );
38.fi
cc4615cc 39.sp
2c5f8c8c 40Link with \fI\-pthread\fP.
fce1dd17 41.sp
cc4615cc
MK
42.in -4n
43Feature Test Macro Requirements for glibc (see
44.BR feature_test_macros (7)):
45.in
46.sp
cc4615cc
MK
47.BR sem_timedwait ():
48_POSIX_C_SOURCE\ >=\ 200112L || _XOPEN_SOURCE\ >=\ 600
2c731798
MK
49.SH DESCRIPTION
50.BR sem_wait ()
51decrements (locks) the semaphore pointed to by
52.IR sem .
53If the semaphore's value is greater than zero,
54then the decrement proceeds, and the function returns, immediately.
55If the semaphore currently has the value zero,
c13182ef 56then the call blocks until either it becomes possible to perform
2c731798
MK
57the decrement (i.e., the semaphore value rises above zero),
58or a signal handler interrupts the call.
59
60.BR sem_trywait ()
61is the same as
62.BR sem_wait (),
63except that if the decrement cannot be immediately performed,
c13182ef
MK
64then call returns an error
65.RI ( errno
2c731798
MK
66set to
67.BR EAGAIN )
68instead of blocking.
69
70.BR sem_timedwait ()
c13182ef 71is the same as
2c731798
MK
72.BR sem_wait (),
73except that
74.I abs_timeout
c13182ef 75specifies a limit on the amount of time that the call
2c731798 76should block if the decrement cannot be immediately performed.
c13182ef 77The
2c731798 78.I abs_timeout
c13182ef 79argument points to a structure that specifies an absolute timeout
f49c451a 80in seconds and nanoseconds since the Epoch, 1970-01-01 00:00:00 +0000 (UTC).
2c731798
MK
81This structure is defined as follows:
82
83.nf
a08ea57c 84.in +4n
2c731798
MK
85struct timespec {
86 time_t tv_sec; /* Seconds */
87 long tv_nsec; /* Nanoseconds [0 .. 999999999] */
88};
a08ea57c 89.in
2c731798
MK
90.fi
91.PP
92If the timeout has already expired by the time of the call,
93and the semaphore could not be locked immediately,
c13182ef 94then
2c731798
MK
95.BR sem_timedwait ()
96fails with a timeout error
97.RI ( errno
98set to
99.BR ETIMEDOUT ).
100
101If the operation can be performed immediately, then
102.BR sem_timedwait ()
103never fails with a timeout error, regardless of the value of
104.IR abs_timeout .
c13182ef 105Furthermore, the validity of
2c731798
MK
106.I abs_timeout
107is not checked in this case.
108.SH RETURN VALUE
c13182ef 109All of these functions return 0 on success;
2c731798
MK
110on error, the value of the semaphore is left unchanged,
111\-1 is returned, and
c13182ef 112.I errno
2c731798
MK
113is set to indicate the error.
114.SH ERRORS
115.TP
116.B EINTR
01538d0d
MK
117The call was interrupted by a signal handler; see
118.BR signal (7).
2c731798
MK
119.TP
120.B EINVAL
121.I sem
122is not a valid semaphore.
123.PP
124The following additional error can occur for
125.BR sem_trywait ():
126.TP
127.B EAGAIN
128The operation could not be performed without blocking (i.e., the
129semaphore currently has the value zero).
4509e795 130.PP
2c731798
MK
131The following additional errors can occur for
132.BR sem_timedwait ():
133.TP
134.B EINVAL
135The value of
136.I abs_timeout.tv_nsecs
137is less than 0, or greater than or equal to 1000 million.
138.TP
139.B ETIMEDOUT
140The call timed out before the semaphore could be locked.
c13182ef 141.\" POSIX.1-2001 also allows EDEADLK -- "A deadlock condition
2c731798 142.\" was detected", but this does not occur on Linux(?).
2b2581ee
MK
143.SH CONFORMING TO
144POSIX.1-2001.
2c731798
MK
145.SH NOTES
146A signal handler always interrupts a blocked call to
147one of these functions, regardless of the use of the
148.BR sigaction (2)
149.B SA_RESTART
150flag.
151.\" sem_wait() is always interrupted on most other implementations,
152.\" but on FreeBSD 5.4 SA_RESTART does cause restarting.
2c731798
MK
153.SH EXAMPLE
154.PP
c13182ef 155The (somewhat trivial) program shown below operates on an
2c731798
MK
156unnamed semaphore.
157The program expects two command-line arguments.
158The first argument specifies a seconds value that is used to
159set an alarm timer to generate a
160.B SIGALRM
161signal.
162This handler performs a
fb186734 163.BR sem_post (3)
2c731798
MK
164to increment the semaphore that is being waited on in
165.I main()
c13182ef 166using
2c731798
MK
167.BR sem_timedwait ().
168The second command-line argument specifies the length
c13182ef 169of the timeout, in seconds, for
2c731798
MK
170.BR sem_timedwait ().
171The following shows what happens on two different runs of the program:
172
a08ea57c 173.in +4n
2c731798 174.nf
b43a3b30 175.RB "$" " ./a.out 2 3"
2c731798
MK
176About to call sem_timedwait()
177sem_post() from handler
2c731798 178sem_timedwait() succeeded
b43a3b30 179.RB "$" " ./a.out 2 1"
2c731798
MK
180About to call sem_timedwait()
181sem_timedwait() timed out
182.fi
a08ea57c 183.in
9c330504 184.SS Program source
d84d0300 185\&
2c731798 186.nf
2c731798
MK
187#include <unistd.h>
188#include <stdio.h>
189#include <stdlib.h>
190#include <semaphore.h>
191#include <time.h>
192#include <assert.h>
193#include <errno.h>
194#include <signal.h>
195
2c731798
MK
196sem_t sem;
197
4407d3d8
MK
198#define handle_error(msg) \\
199 do { perror(msg); exit(EXIT_FAILURE); } while (0)
200
2c731798
MK
201static void
202handler(int sig)
203{
6ba73a73
MK
204 write(STDOUT_FILENO, "sem_post() from handler\\n", 24);
205 if (sem_post(&sem) == \-1) {
206 write(STDERR_FILENO, "sem_post() failed\\n", 18);
207 _exit(EXIT_FAILURE);
208 }
209}
2c731798
MK
210
211int
212main(int argc, char *argv[])
213{
214 struct sigaction sa;
215 struct timespec ts;
216 int s;
217
6ba73a73
MK
218 if (argc != 3) {
219 fprintf(stderr, "Usage: %s <alarm\-secs> <wait\-secs>\\n",
220 argv[0]);
221 exit(EXIT_FAILURE);
222 }
2c731798 223
4407d3d8
MK
224 if (sem_init(&sem, 0, 0) == \-1)
225 handle_error("sem_init");
2c731798
MK
226
227 /* Establish SIGALRM handler; set alarm timer using argv[1] */
228
229 sa.sa_handler = handler;
230 sigemptyset(&sa.sa_mask);
231 sa.sa_flags = 0;
5ce7e85e 232 if (sigaction(SIGALRM, &sa, NULL) == \-1)
4407d3d8 233 handle_error("sigaction");
2c731798
MK
234
235 alarm(atoi(argv[1]));
236
237 /* Calculate relative interval as current time plus
238 number of seconds given argv[2] */
239
4407d3d8
MK
240 if (clock_gettime(CLOCK_REALTIME, &ts) == \-1)
241 handle_error("clock_gettime");
242
2c731798
MK
243 ts.tv_sec += atoi(argv[2]);
244
245 printf("main() about to call sem_timedwait()\\n");
29059a65 246 while ((s = sem_timedwait(&sem, &ts)) == \-1 && errno == EINTR)
6ba73a73 247 continue; /* Restart if interrupted by handler */
2c731798
MK
248
249 /* Check what happened */
250
29059a65 251 if (s == \-1) {
2c731798
MK
252 if (errno == ETIMEDOUT)
253 printf("sem_timedwait() timed out\\n");
254 else
6ba73a73 255 perror("sem_timedwait");
2c731798
MK
256 } else
257 printf("sem_timedwait() succeeded\\n");
258
6ba73a73 259 exit((s == 0) ? EXIT_SUCCESS : EXIT_FAILURE);
2c731798
MK
260}
261.fi
47297adb 262.SH SEE ALSO
8b98f282 263.BR clock_gettime (2),
2c731798
MK
264.BR sem_getvalue (3),
265.BR sem_post (3),
1d7c4d16
MK
266.BR sem_overview (7),
267.BR time (7)