diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-15 19:40:15 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-15 19:40:15 +0000 |
commit | 399644e47874bff147afb19c89228901ac39340e (patch) | |
tree | 1c4c0b733f4c16b5783b41bebb19194a9ef62ad1 /man3/sem_wait.3 | |
parent | Initial commit. (diff) | |
download | manpages-399644e47874bff147afb19c89228901ac39340e.tar.xz manpages-399644e47874bff147afb19c89228901ac39340e.zip |
Adding upstream version 6.05.01.upstream/6.05.01
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'man3/sem_wait.3')
-rw-r--r-- | man3/sem_wait.3 | 252 |
1 files changed, 252 insertions, 0 deletions
diff --git a/man3/sem_wait.3 b/man3/sem_wait.3 new file mode 100644 index 0000000..b1302ca --- /dev/null +++ b/man3/sem_wait.3 @@ -0,0 +1,252 @@ +'\" t +.\" Copyright (C) 2006 Michael Kerrisk <mtk.manpages@gmail.com> +.\" +.\" SPDX-License-Identifier: Linux-man-pages-copyleft +.\" +.TH sem_wait 3 2023-07-20 "Linux man-pages 6.05.01" +.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> +.PP +.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 +.PP +.RS -4 +Feature Test Macro Requirements for glibc (see +.BR feature_test_macros (7)): +.RE +.PP +.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. +.PP +.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. +.PP +.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). +.PP +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 ). +.PP +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 +.sp 1 +.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: +.PP +.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) |