tzfile.5, tzselect.8: sync from tzdb upstream
[man-pages.git] / man3 / sem_wait.3
blob788d687a78fa20776da34ce36ee89aecec5feb3c
1 '\" t
2 .\" Copyright (C) 2006 Michael Kerrisk <mtk.manpages@gmail.com>
3 .\"
4 .\" SPDX-License-Identifier: Linux-man-pages-copyleft
5 .\"
6 .TH sem_wait 3 (date) "Linux man-pages (unreleased)"
7 .SH NAME
8 sem_wait, sem_timedwait, sem_trywait \- lock a semaphore
9 .SH LIBRARY
10 POSIX threads library
11 .RI ( libpthread ", " \-lpthread )
12 .SH SYNOPSIS
13 .nf
14 .B #include <semaphore.h>
15 .PP
16 .BI "int sem_wait(sem_t *" sem );
17 .BI "int sem_trywait(sem_t *" sem );
18 .BI "int sem_timedwait(sem_t *restrict " sem ,
19 .BI "                  const struct timespec *restrict " abs_timeout );
20 .fi
21 .PP
22 .RS -4
23 Feature Test Macro Requirements for glibc (see
24 .BR feature_test_macros (7)):
25 .RE
26 .PP
27 .BR sem_timedwait ():
28 .nf
29     _POSIX_C_SOURCE >= 200112L
30 .fi
31 .SH DESCRIPTION
32 .BR sem_wait ()
33 decrements (locks) the semaphore pointed to by
34 .IR sem .
35 If the semaphore's value is greater than zero,
36 then the decrement proceeds, and the function returns, immediately.
37 If the semaphore currently has the value zero,
38 then the call blocks until either it becomes possible to perform
39 the decrement (i.e., the semaphore value rises above zero),
40 or a signal handler interrupts the call.
41 .PP
42 .BR sem_trywait ()
43 is the same as
44 .BR sem_wait (),
45 except that if the decrement cannot be immediately performed,
46 then call returns an error
47 .RI ( errno
48 set to
49 .BR EAGAIN )
50 instead of blocking.
51 .PP
52 .BR sem_timedwait ()
53 is the same as
54 .BR sem_wait (),
55 except that
56 .I abs_timeout
57 specifies a limit on the amount of time that the call
58 should block if the decrement cannot be immediately performed.
59 The
60 .I abs_timeout
61 argument points to a
62 .BR timespec (3)
63 structure that specifies an absolute timeout
64 in seconds and nanoseconds since the Epoch, 1970-01-01 00:00:00 +0000 (UTC).
65 .PP
66 If the timeout has already expired by the time of the call,
67 and the semaphore could not be locked immediately,
68 then
69 .BR sem_timedwait ()
70 fails with a timeout error
71 .RI ( errno
72 set to
73 .BR ETIMEDOUT ).
74 .PP
75 If the operation can be performed immediately, then
76 .BR sem_timedwait ()
77 never fails with a timeout error, regardless of the value of
78 .IR abs_timeout .
79 Furthermore, the validity of
80 .I abs_timeout
81 is not checked in this case.
82 .SH RETURN VALUE
83 All of these functions return 0 on success;
84 on error, the value of the semaphore is left unchanged,
85 \-1 is returned, and
86 .I errno
87 is set to indicate the error.
88 .SH ERRORS
89 .TP
90 .B EAGAIN
91 .RB ( sem_trywait ())
92 The operation could not be performed without blocking (i.e., the
93 semaphore currently has the value zero).
94 .TP
95 .B EINTR
96 The call was interrupted by a signal handler; see
97 .BR signal (7).
98 .TP
99 .B EINVAL
100 .I sem
101 is not a valid semaphore.
103 .B EINVAL
104 .RB ( sem_timedwait ())
105 The value of
106 .I abs_timeout.tv_nsecs
107 is less than 0, or greater than or equal to 1000 million.
109 .B ETIMEDOUT
110 .RB ( sem_timedwait ())
111 The call timed out before the semaphore could be locked.
112 .\" POSIX.1-2001 also allows EDEADLK -- "A deadlock condition
113 .\" was detected", but this does not occur on Linux(?).
114 .SH ATTRIBUTES
115 For an explanation of the terms used in this section, see
116 .BR attributes (7).
117 .ad l
120 allbox;
121 lbx lb lb
122 l l l.
123 Interface       Attribute       Value
125 .BR sem_wait (),
126 .BR sem_trywait (),
127 .BR sem_timedwait ()
128 T}      Thread safety   MT-Safe
132 .sp 1
133 .SH STANDARDS
134 POSIX.1-2001, POSIX.1-2008.
135 .SH EXAMPLES
136 The (somewhat trivial) program shown below operates on an
137 unnamed semaphore.
138 The program expects two command-line arguments.
139 The first argument specifies a seconds value that is used to
140 set an alarm timer to generate a
141 .B SIGALRM
142 signal.
143 This handler performs a
144 .BR sem_post (3)
145 to increment the semaphore that is being waited on in
146 .I main()
147 using
148 .BR sem_timedwait ().
149 The second command-line argument specifies the length
150 of the timeout, in seconds, for
151 .BR sem_timedwait ().
152 The following shows what happens on two different runs of the program:
154 .in +4n
156 .RB "$" " ./a.out 2 3"
157 About to call sem_timedwait()
158 sem_post() from handler
159 sem_timedwait() succeeded
160 .RB "$" " ./a.out 2 1"
161 About to call sem_timedwait()
162 sem_timedwait() timed out
165 .SS Program source
167 .\" SRC BEGIN (sem_wait.c)
169 #include <errno.h>
170 #include <semaphore.h>
171 #include <signal.h>
172 #include <stdio.h>
173 #include <stdlib.h>
174 #include <time.h>
175 #include <unistd.h>
177 #include <assert.h>
179 sem_t sem;
181 #define handle_error(msg) \e
182     do { perror(msg); exit(EXIT_FAILURE); } while (0)
184 static void
185 handler(int sig)
187     write(STDOUT_FILENO, "sem_post() from handler\en", 24);
188     if (sem_post(&sem) == \-1) {
189         write(STDERR_FILENO, "sem_post() failed\en", 18);
190         _exit(EXIT_FAILURE);
191     }
195 main(int argc, char *argv[])
197     struct sigaction sa;
198     struct timespec ts;
199     int s;
201     if (argc != 3) {
202         fprintf(stderr, "Usage: %s <alarm\-secs> <wait\-secs>\en",
203                 argv[0]);
204         exit(EXIT_FAILURE);
205     }
207     if (sem_init(&sem, 0, 0) == \-1)
208         handle_error("sem_init");
210     /* Establish SIGALRM handler; set alarm timer using argv[1]. */
212     sa.sa_handler = handler;
213     sigemptyset(&sa.sa_mask);
214     sa.sa_flags = 0;
215     if (sigaction(SIGALRM, &sa, NULL) == \-1)
216         handle_error("sigaction");
218     alarm(atoi(argv[1]));
220     /* Calculate relative interval as current time plus
221        number of seconds given argv[2]. */
223     if (clock_gettime(CLOCK_REALTIME, &ts) == \-1)
224         handle_error("clock_gettime");
226     ts.tv_sec += atoi(argv[2]);
228     printf("%s() about to call sem_timedwait()\en", __func__);
229     while ((s = sem_timedwait(&sem, &ts)) == \-1 && errno == EINTR)
230         continue;       /* Restart if interrupted by handler. */
232     /* Check what happened. */
234     if (s == \-1) {
235         if (errno == ETIMEDOUT)
236             printf("sem_timedwait() timed out\en");
237         else
238             perror("sem_timedwait");
239     } else
240         printf("sem_timedwait() succeeded\en");
242     exit((s == 0) ? EXIT_SUCCESS : EXIT_FAILURE);
245 .\" SRC END
246 .SH SEE ALSO
247 .BR clock_gettime (2),
248 .BR sem_getvalue (3),
249 .BR sem_post (3),
250 .BR timespec (3),
251 .BR sem_overview (7),
252 .BR time (7)