From 90b12bd71bb9fc79a4640b9112c13ef529d0196a Mon Sep 17 00:00:00 2001 From: Laurent Bercot Date: Fri, 5 Dec 2014 22:26:11 +0000 Subject: Initial commit --- doc/libs6lock/index.html | 256 ++++++++++++++++++++++++++++++++++++++ doc/libs6lock/s6lockd-helper.html | 52 ++++++++ doc/libs6lock/s6lockd.html | 73 +++++++++++ 3 files changed, 381 insertions(+) create mode 100644 doc/libs6lock/index.html create mode 100644 doc/libs6lock/s6lockd-helper.html create mode 100644 doc/libs6lock/s6lockd.html (limited to 'doc/libs6lock') diff --git a/doc/libs6lock/index.html b/doc/libs6lock/index.html new file mode 100644 index 0000000..3696b41 --- /dev/null +++ b/doc/libs6lock/index.html @@ -0,0 +1,256 @@ + + + + + s6: the s6lock library interface + + + + + + +

+s6
+Software
+skarnet.org +

+ +

The s6lock library interface

+ +

General information

+ +

+ libs6lock is a C interface to timed locks. Unix natively provides +locks, but the locking primitives are synchronous, so either they are +unbounded in execution time or they require polling. libs6lock provides +poll-free locks that can timeout during attempted acquisition. +

+ +

Compiling

+ + + +

Linking

+ + + +

Programming

+ + + +

Starting and ending a session

+ +
+s6lock_t a = S6LOCK_ZERO ;
+struct taia deadline ;
+
+taia_now_g() ;
+taia_addsec_g(&deadline, 2)
+
+char const *path = S6LOCK_IPCPATH ;
+s6lock_start_g(&a, path, &deadline) ;
+// char const *lockdir = "/tmp/lock" ;
+// s6lock_startf_g(&a, lockdir, &deadline) ;
+
+ +

+s6lock_start_g starts a session by connecting to a s6lockd service +listening on path. The working directory is set by the administrator +of the service.
+s6lock_startf_g starts a session with a s6lockd process as a child, +using lockdir as its working directory. +
+a is a s6lock_t structure that must be declared in the stack and +initialized to S6LOCK_ZERO. +If the session initialization fails, the function returns 0 and errno is set; +else the function returns 1. +

+

+If the absolute time deadline is reached and the function +has not returned yet, it immediately returns 0 with errno set to ETIMEDOUT. + +Only local interprocess communications are involved; unless your system is +heavily overloaded, the function should return near-instantly. One or two +seconds of delay between the current time and deadline should be +enough: if the function takes more than that to return, then there is a +problem with the underlying processes. +

+ +

+ You can have more than one session open in parallel, by declaring +several distinct s6lock_t structures and calling +s6lock_startf_g (or s6lock_start_g) more than once. +However, one single session can handle +virtually as many concurrent locks as your application needs, so +opening several sessions is only useful if you need to acquire locks +in various distinct lock directories. +

+ +
+s6lock_end(&a) ;
+
+ +

+s6lock_end frees all the resources used by the session. The +a structure is then reusable for another session. +

+ +

Acquiring and releasing locks

+ +
+uint16 id ;
+char const *file = "lockfile" ;
+struct taia limit ;
+struct taia deadline ;
+
+int r = s6lock_acquire_sh_g (&a, &id, file, &limit, &deadline) ;
+/* int r = s6lock_acquire_ex_g (&a, &id, file, &limit, &deadline) ; */
+r = s6lock_release_g(&a, id, &deadline) ;
+
+ +

+s6lock_acquire_sh_g instructs the +s6lockd daemon, related to the open +session represented by the a handle, to try and acquire a +shared lock on the +file file located under that daemon's working directory +(typically /var/lock). file will be interpreted as +relative to the daemon's working directory even if it starts with a +slash; however, slashes in the middle of file are likely to +result in an error. +

+ +

+limit and deadline are two absolute dates. +deadline is a deadline for the execution of the +function: if by deadline the function has not returned, +then it instantly returns 0 and sets errno to ETIMEDOUT. The +function is normally near-instantaneous, so deadline can +be very close in the future and serves only as a protection against +malicious servers. limit is the acquisition deadline: if +by limit the daemon still has not been able to acquire a lock +on file, then it will report a timeout to the client. +

+ +

+The function returns 1 in case of success, or 0 if an error occurs, +with errno set to a suitable value. If it succeeds, then a 16-bit +number is stored into *id; this number serves as an identifier +for this lock. +

+ +

+s6lock_acquire_ex_g works just like s6lock_acquire_sh_g, +except that the daemon tries to acquire an exclusive lock. +

+ +

+s6lock_release_g releases the lock identified by id. +It normally returns 1. It can return 0 with errno set to a suitable +value if it fails. id is not valid after the corresponding +lock has been released. The function normally returns instantly, with +deadline as a safeguard. +

+ +

Asynchronously waiting for locks

+ +

+ (from now on, the functions are listed with their prototypes instead +of usage examples.) +

+ +
+int s6lock_fd (s6lock_t const *a)
+
+ +

+ Returns a file descriptor to select on for reading. Do not +read() it though. +

+ +
+int s6lock_update (s6lock_t *a)
+
+ +

+ Call this function whenever the fd checks readability: it will +update a's internal structures with information from the +s6lockd daemon. It returns -1 if an error +occurs; in case of success, it returns the number of identifiers for +which something happened. +

+ +

+ When s6lock_update returns, +genalloc_s(uint16, &a->list) points to an array of +genalloc_len(uint16, &a->list) 16-bit unsigned +integers. Those integers are ids waiting to be passed to +s6lock_check. +

+ +
+int s6lock_check (s6lock_t *a, uint16 id, char *what)
+
+ +

+ Checks whether the lock identified by id has +been acquired. Use after a call to s6lock_update(). +

+ + + +

Synchronously waiting for locks

+ +

+ int s6lock_wait_or_g (s6lock_t *a, uint16 const *idlist, unsigned int n, struct taia const *deadline)
+Synchronously waits for one of the locks represented by the array pointed to +by idlist of length n to be acquired. Returns -1 if it fails, +or a nonnegative number on success, which is the index in idlist of the +acquired lock's id. If no result has been obtained by deadline, the +function returns -1 ETIMEDOUT. +

+ +

+ int s6lock_wait_and_g (s6lock_t *a, uint16 const *idlist, unsigned int n, struct taia const *deadline)
+Synchronously waits for all of the locks represented by the array pointed to +by idlist of length n to be acquired. Returns -1 if it fails and +0 if it succeeds. If no result has been obtained by deadline, the +function returns -1 ETIMEDOUT. +

+ + + diff --git a/doc/libs6lock/s6lockd-helper.html b/doc/libs6lock/s6lockd-helper.html new file mode 100644 index 0000000..839dce4 --- /dev/null +++ b/doc/libs6lock/s6lockd-helper.html @@ -0,0 +1,52 @@ + + + + + s6: the s6lockd-helper internal program + + + + + + +libs6lock
+s6
+Software
+skarnet.org

+ +

The s6lockd-helper program

+ +

+s6lockd-helper is a helper program for the s6lock daemon. +It just acquires a lock and holds it until it is killed or told to +exit by its parent daemon. +

+ +

Interface

+ +

+ s6lockd-helper is not meant to be invoked directly by the user: +it will be spawned by the +s6lockd program. +

+ +

Notes

+ + + + + diff --git a/doc/libs6lock/s6lockd.html b/doc/libs6lock/s6lockd.html new file mode 100644 index 0000000..726d2f8 --- /dev/null +++ b/doc/libs6lock/s6lockd.html @@ -0,0 +1,73 @@ + + + + + s6: the s6lockd internal program + + + + + + +libs6lock
+s6
+Software
+skarnet.org

+ +

The s6lockd program

+ +

+s6lockd is the s6lock daemon. It is a program that manages +a set of lock files in a given directory, and associated timeouts. +

+ +

Interface

+ +

+ s6lockd does not fork, does not background itself automatically, +and does not use syslog. It is not meant to be run directly by the +user: it will be spawned by the +s6lock client library. +

+ +

+ There are 2 ways to use s6lockd: +

+ +
    +
  1. Use the s6lock_startf() library call. +A s6lockd child will then be spawned from your +calling process, and automatically reaped when you call +s6lock_end(). It requires care with applications that +trap SIGCHLD. It also requires care with lock file permissions: +a s6lockd instance might not be able +to open a lock file created by a former instance run by another +client with different permissions.
  2. +
  3. Use the s6lock_start() library call, together with a +s6lockd service. +For once, this is the recommended setup: s6lockd creates empty +lock files, and having all s6lockd instances run under the same user +simplifies permissions management considerably.
  4. + +
+ +

+When run as a service, s6lockd has no "standalone" mode: it is +designed to work with a Unix +domain superserver, like +s6-ipcserver. +s6lockd follows the UCSPI +interface, it can be directly executed from the superserver. +

+ +

Notes

+ + + + + -- cgit v1.2.3