summaryrefslogtreecommitdiffstats
path: root/man/man3/sem_wait.3
diff options
context:
space:
mode:
Diffstat (limited to 'man/man3/sem_wait.3')
-rw-r--r--man/man3/sem_wait.3251
1 files changed, 251 insertions, 0 deletions
diff --git a/man/man3/sem_wait.3 b/man/man3/sem_wait.3
new file mode 100644
index 0000000..f09f697
--- /dev/null
+++ b/man/man3/sem_wait.3
@@ -0,0 +1,251 @@
+'\" t
+.\" Copyright (C) 2006 Michael Kerrisk <mtk.manpages@gmail.com>
+.\"
+.\" SPDX-License-Identifier: Linux-man-pages-copyleft
+.\"
+.TH sem_wait 3 2024-05-02 "Linux man-pages (unreleased)"
+.SH NAME
+sem_wait, sem_timedwait, sem_trywait \- lock a semaphore
+.SH LIBRARY
+POSIX threads library
+.RI ( libpthread ", " \-lpthread )
+.SH SYNOPSIS
+.nf
+.B #include <semaphore.h>
+.P
+.BI "int sem_wait(sem_t *" sem );
+.BI "int sem_trywait(sem_t *" sem );
+.BI "int sem_timedwait(sem_t *restrict " sem ,
+.BI " const struct timespec *restrict " abs_timeout );
+.fi
+.P
+.RS -4
+Feature Test Macro Requirements for glibc (see
+.BR feature_test_macros (7)):
+.RE
+.P
+.BR sem_timedwait ():
+.nf
+ _POSIX_C_SOURCE >= 200112L
+.fi
+.SH DESCRIPTION
+.BR sem_wait ()
+decrements (locks) the semaphore pointed to by
+.IR sem .
+If the semaphore's value is greater than zero,
+then the decrement proceeds, and the function returns, immediately.
+If the semaphore currently has the value zero,
+then the call blocks until either it becomes possible to perform
+the decrement (i.e., the semaphore value rises above zero),
+or a signal handler interrupts the call.
+.P
+.BR sem_trywait ()
+is the same as
+.BR sem_wait (),
+except that if the decrement cannot be immediately performed,
+then call returns an error
+.RI ( errno
+set to
+.BR EAGAIN )
+instead of blocking.
+.P
+.BR sem_timedwait ()
+is the same as
+.BR sem_wait (),
+except that
+.I abs_timeout
+specifies a limit on the amount of time that the call
+should block if the decrement cannot be immediately performed.
+The
+.I abs_timeout
+argument points to a
+.BR timespec (3)
+structure that specifies an absolute timeout
+in seconds and nanoseconds since the Epoch, 1970-01-01 00:00:00 +0000 (UTC).
+.P
+If the timeout has already expired by the time of the call,
+and the semaphore could not be locked immediately,
+then
+.BR sem_timedwait ()
+fails with a timeout error
+.RI ( errno
+set to
+.BR ETIMEDOUT ).
+.P
+If the operation can be performed immediately, then
+.BR sem_timedwait ()
+never fails with a timeout error, regardless of the value of
+.IR abs_timeout .
+Furthermore, the validity of
+.I abs_timeout
+is not checked in this case.
+.SH RETURN VALUE
+All of these functions return 0 on success;
+on error, the value of the semaphore is left unchanged,
+\-1 is returned, and
+.I errno
+is set to indicate the error.
+.SH ERRORS
+.TP
+.B EAGAIN
+.RB ( sem_trywait ())
+The operation could not be performed without blocking (i.e., the
+semaphore currently has the value zero).
+.TP
+.B EINTR
+The call was interrupted by a signal handler; see
+.BR signal (7).
+.TP
+.B EINVAL
+.I sem
+is not a valid semaphore.
+.TP
+.B EINVAL
+.RB ( sem_timedwait ())
+The value of
+.I abs_timeout.tv_nsecs
+is less than 0, or greater than or equal to 1000 million.
+.TP
+.B ETIMEDOUT
+.RB ( sem_timedwait ())
+The call timed out before the semaphore could be locked.
+.\" POSIX.1-2001 also allows EDEADLK -- "A deadlock condition
+.\" was detected", but this does not occur on Linux(?).
+.SH ATTRIBUTES
+For an explanation of the terms used in this section, see
+.BR attributes (7).
+.TS
+allbox;
+lbx lb lb
+l l l.
+Interface Attribute Value
+T{
+.na
+.nh
+.BR sem_wait (),
+.BR sem_trywait (),
+.BR sem_timedwait ()
+T} Thread safety MT-Safe
+.TE
+.SH STANDARDS
+POSIX.1-2008.
+.SH HISTORY
+POSIX.1-2001.
+.SH EXAMPLES
+The (somewhat trivial) program shown below operates on an
+unnamed semaphore.
+The program expects two command-line arguments.
+The first argument specifies a seconds value that is used to
+set an alarm timer to generate a
+.B SIGALRM
+signal.
+This handler performs a
+.BR sem_post (3)
+to increment the semaphore that is being waited on in
+.I main()
+using
+.BR sem_timedwait ().
+The second command-line argument specifies the length
+of the timeout, in seconds, for
+.BR sem_timedwait ().
+The following shows what happens on two different runs of the program:
+.P
+.in +4n
+.EX
+.RB "$" " ./a.out 2 3"
+About to call sem_timedwait()
+sem_post() from handler
+sem_timedwait() succeeded
+.RB "$" " ./a.out 2 1"
+About to call sem_timedwait()
+sem_timedwait() timed out
+.EE
+.in
+.SS Program source
+\&
+.\" SRC BEGIN (sem_wait.c)
+.EX
+#include <errno.h>
+#include <semaphore.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <time.h>
+#include <unistd.h>
+\&
+#include <assert.h>
+\&
+sem_t sem;
+\&
+#define handle_error(msg) \e
+ do { perror(msg); exit(EXIT_FAILURE); } while (0)
+\&
+static void
+handler(int sig)
+{
+ write(STDOUT_FILENO, "sem_post() from handler\en", 24);
+ if (sem_post(&sem) == \-1) {
+ write(STDERR_FILENO, "sem_post() failed\en", 18);
+ _exit(EXIT_FAILURE);
+ }
+}
+\&
+int
+main(int argc, char *argv[])
+{
+ struct sigaction sa;
+ struct timespec ts;
+ int s;
+\&
+ if (argc != 3) {
+ fprintf(stderr, "Usage: %s <alarm\-secs> <wait\-secs>\en",
+ argv[0]);
+ exit(EXIT_FAILURE);
+ }
+\&
+ if (sem_init(&sem, 0, 0) == \-1)
+ handle_error("sem_init");
+\&
+ /* Establish SIGALRM handler; set alarm timer using argv[1]. */
+\&
+ sa.sa_handler = handler;
+ sigemptyset(&sa.sa_mask);
+ sa.sa_flags = 0;
+ if (sigaction(SIGALRM, &sa, NULL) == \-1)
+ handle_error("sigaction");
+\&
+ alarm(atoi(argv[1]));
+\&
+ /* Calculate relative interval as current time plus
+ number of seconds given argv[2]. */
+\&
+ if (clock_gettime(CLOCK_REALTIME, &ts) == \-1)
+ handle_error("clock_gettime");
+\&
+ ts.tv_sec += atoi(argv[2]);
+\&
+ printf("%s() about to call sem_timedwait()\en", __func__);
+ while ((s = sem_timedwait(&sem, &ts)) == \-1 && errno == EINTR)
+ continue; /* Restart if interrupted by handler. */
+\&
+ /* Check what happened. */
+\&
+ if (s == \-1) {
+ if (errno == ETIMEDOUT)
+ printf("sem_timedwait() timed out\en");
+ else
+ perror("sem_timedwait");
+ } else
+ printf("sem_timedwait() succeeded\en");
+\&
+ exit((s == 0) ? EXIT_SUCCESS : EXIT_FAILURE);
+}
+.EE
+.\" SRC END
+.SH SEE ALSO
+.BR clock_gettime (2),
+.BR sem_getvalue (3),
+.BR sem_post (3),
+.BR timespec (3),
+.BR sem_overview (7),
+.BR time (7)