]> mj.ucw.cz Git - libucw.git/blob - lib/fb-atomic.c
29e7c3039f7c81749b51a3240ebfad0f8294899a
[libucw.git] / lib / fb-atomic.c
1 /*
2  *      UCW Library -- Atomic Buffered Write to Files
3  *
4  *      (c) 2006 Martin Mares <mj@ucw.cz>
5  *
6  *      This software may be freely distributed and used according to the terms
7  *      of the GNU Lesser General Public License.
8  */
9
10 /*
11  *      This fastbuf backend is intended for cases where several threads
12  *      of a single program append records to a single file and while the
13  *      record can mix in an arbitrary way, the bytes inside a single
14  *      record must remain uninterrupted.
15  *
16  *      In case of files with fixed record size, we just allocate the
17  *      buffer to hold a whole number of records and take advantage
18  *      of the atomicity of the write() system call.
19  *
20  *      With variable-sized records, we need another solution: when
21  *      writing a record, we keep the fastbuf in a locked state, which
22  *      prevents buffer flushing (and if the buffer becomes full, we extend it),
23  *      and we wait for an explicit commit operation which write()s the buffer
24  *      if the free space in the buffer falls below the expected maximum record
25  *      length.
26  *
27  *      fbatomic_create() is called with the following parameters:
28  *          name - name of the file to open
29  *          master - fbatomic for the master thread or NULL if it's the first open
30  *          bufsize - initial buffer size
31  *          record_len - record length for fixed-size records;
32  *              or -(expected maximum record length) for variable-sized ones.
33  */
34
35 #include "lib/lib.h"
36 #include "lib/fastbuf.h"
37 #include "lib/lfs.h"
38
39 #include <string.h>
40 #include <fcntl.h>
41 #include <unistd.h>
42
43 struct fb_atomic {
44   struct fastbuf fb;
45   int fd;                               /* File descriptor */
46   uns locked;
47   uns expected_max_len;
48   byte *expected_max_bptr;
49 };
50 #define FB_ATOMIC(f) ((struct fb_atomic *)(f)->is_fastbuf)