lockfile: move documentation to lockfile.h and lockfile.c

Rearrange/rewrite it somewhat to fit its new environment. Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Michael Haggerty committed Aug 10, 2015 at 11:47 UTC 2db69de81deea4682579d0b9e6da40b4e9558c05
3 files changed +283 -280
Documentation/technical/api-lockfile.txt deleted
-220
@@ -1,220 +0,0 @@
1 -lockfile API
2 -============
3 -
4 -The lockfile API serves two purposes:
5 -
6 -* Mutual exclusion and atomic file updates. When we want to change a
7 - file, we create a lockfile `<filename>.lock`, write the new file
8 - contents into it, and then rename the lockfile to its final
9 - destination `<filename>`. We create the `<filename>.lock` file with
10 - `O_CREAT|O_EXCL` so that we can notice and fail if somebody else has
11 - already locked the file, then atomically rename the lockfile to its
12 - final destination to commit the changes and unlock the file.
13 -
14 -* Automatic cruft removal. If the program exits after we lock a file
15 - but before the changes have been committed, we want to make sure
16 - that we remove the lockfile. This is done by remembering the
17 - lockfiles we have created in a linked list and setting up an
18 - `atexit(3)` handler and a signal handler that clean up the
19 - lockfiles. This mechanism ensures that outstanding lockfiles are
20 - cleaned up if the program exits (including when `die()` is called)
21 - or if the program dies on a signal.
22 -
23 -Please note that lockfiles only block other writers. Readers do not
24 -block, but they are guaranteed to see either the old contents of the
25 -file or the new contents of the file (assuming that the filesystem
26 -implements `rename(2)` atomically).
27 -
28 -
29 -Calling sequence
30 -----------------
31 -
32 -The caller:
33 -
34 -* Allocates a `struct lock_file` either as a static variable or on the
35 - heap, initialized to zeros. Once you use the structure to call the
36 - `hold_lock_file_*` family of functions, it belongs to the lockfile
37 - subsystem and its storage must remain valid throughout the life of
38 - the program (i.e. you cannot use an on-stack variable to hold this
39 - structure).
40 -
41 -* Attempts to create a lockfile by passing that variable and the path
42 - of the final destination (e.g. `$GIT_DIR/index`) to
43 - `hold_lock_file_for_update` or `hold_lock_file_for_append`.
44 -
45 -* Writes new content for the destination file by either:
46 -
47 - * writing to the file descriptor returned by the `hold_lock_file_*`
48 - functions (also available via `lock->fd`).
49 -
50 - * calling `fdopen_lock_file` to get a `FILE` pointer for the open
51 - file and writing to the file using stdio.
52 -
53 -When finished writing, the caller can:
54 -
55 -* Close the file descriptor and rename the lockfile to its final
56 - destination by calling `commit_lock_file` or `commit_lock_file_to`.
57 -
58 -* Close the file descriptor and remove the lockfile by calling
59 - `rollback_lock_file`.
60 -
61 -* Close the file descriptor without removing or renaming the lockfile
62 - by calling `close_lock_file`, and later call `commit_lock_file`,
63 - `commit_lock_file_to`, `rollback_lock_file`, or `reopen_lock_file`.
64 -
65 -Even after the lockfile is committed or rolled back, the `lock_file`
66 -object must not be freed or altered by the caller. However, it may be
67 -reused; just pass it to another call of `hold_lock_file_for_update` or
68 -`hold_lock_file_for_append`.
69 -
70 -If the program exits before you have called one of `commit_lock_file`,
71 -`commit_lock_file_to`, `rollback_lock_file`, or `close_lock_file`, an
72 -`atexit(3)` handler will close and remove the lockfile, rolling back
73 -any uncommitted changes.
74 -
75 -If you need to close the file descriptor you obtained from a
76 -`hold_lock_file_*` function yourself, do so by calling
77 -`close_lock_file`. You should never call `close(2)` or `fclose(3)`
78 -yourself! Otherwise the `struct lock_file` structure would still think
79 -that the file descriptor needs to be closed, and a commit or rollback
80 -would result in duplicate calls to `close(2)`. Worse yet, if you close
81 -and then later open another file descriptor for a completely different
82 -purpose, then a commit or rollback might close that unrelated file
83 -descriptor.
84 -
85 -
86 -Error handling
87 ---------------
88 -
89 -The `hold_lock_file_*` functions return a file descriptor on success
90 -or -1 on failure (unless `LOCK_DIE_ON_ERROR` is used; see below). On
91 -errors, `errno` describes the reason for failure. Errors can be
92 -reported by passing `errno` to one of the following helper functions:
93 -
94 -unable_to_lock_message::
95 -
96 - Append an appropriate error message to a `strbuf`.
97 -
98 -unable_to_lock_error::
99 -
100 - Emit an appropriate error message using `error()`.
101 -
102 -unable_to_lock_die::
103 -
104 - Emit an appropriate error message and `die()`.
105 -
106 -Similarly, `commit_lock_file`, `commit_lock_file_to`, and
107 -`close_lock_file` return 0 on success. On failure they set `errno`
108 -appropriately, do their best to roll back the lockfile, and return -1.
109 -
110 -
111 -Flags
112 ------
113 -
114 -The following flags can be passed to `hold_lock_file_for_update` or
115 -`hold_lock_file_for_append`:
116 -
117 -LOCK_NO_DEREF::
118 -
119 - Usually symbolic links in the destination path are resolved
120 - and the lockfile is created by adding ".lock" to the resolved
121 - path. If `LOCK_NO_DEREF` is set, then the lockfile is created
122 - by adding ".lock" to the path argument itself. This option is
123 - used, for example, when locking a symbolic reference, which
124 - for backwards-compatibility reasons can be a symbolic link
125 - containing the name of the referred-to-reference.
126 -
127 -LOCK_DIE_ON_ERROR::
128 -
129 - If a lock is already taken for the file, `die()` with an error
130 - message. If this option is not specified, trying to lock a
131 - file that is already locked returns -1 to the caller.
132 -
133 -
134 -The functions
135 --------------
136 -
137 -hold_lock_file_for_update::
138 -
139 - Take a pointer to `struct lock_file`, the path of the file to
140 - be locked (e.g. `$GIT_DIR/index`) and a flags argument (see
141 - above). Attempt to create a lockfile for the destination and
142 - return the file descriptor for writing to the file.
143 -
144 -hold_lock_file_for_append::
145 -
146 - Like `hold_lock_file_for_update`, but before returning copy
147 - the existing contents of the file (if any) to the lockfile and
148 - position its write pointer at the end of the file.
149 -
150 -fdopen_lock_file::
151 -
152 - Associate a stdio stream with the lockfile. Return NULL
153 - (*without* rolling back the lockfile) on error. The stream is
154 - closed automatically when `close_lock_file` is called or when
155 - the file is committed or rolled back.
156 -
157 -get_locked_file_path::
158 -
159 - Return the path of the file that is locked by the specified
160 - lock_file object. The caller must free the memory.
161 -
162 -commit_lock_file::
163 -
164 - Take a pointer to the `struct lock_file` initialized with an
165 - earlier call to `hold_lock_file_for_update` or
166 - `hold_lock_file_for_append`, close the file descriptor, and
167 - rename the lockfile to its final destination. Return 0 upon
168 - success. On failure, roll back the lock file and return -1,
169 - with `errno` set to the value from the failing call to
170 - `close(2)` or `rename(2)`. It is a bug to call
171 - `commit_lock_file` for a `lock_file` object that is not
172 - currently locked.
173 -
174 -commit_lock_file_to::
175 -
176 - Like `commit_lock_file()`, except that it takes an explicit
177 - `path` argument to which the lockfile should be renamed. The
178 - `path` must be on the same filesystem as the lock file.
179 -
180 -rollback_lock_file::
181 -
182 - Take a pointer to the `struct lock_file` initialized with an
183 - earlier call to `hold_lock_file_for_update` or
184 - `hold_lock_file_for_append`, close the file descriptor and
185 - remove the lockfile. It is a NOOP to call
186 - `rollback_lock_file()` for a `lock_file` object that has
187 - already been committed or rolled back.
188 -
189 -close_lock_file::
190 -
191 - Take a pointer to the `struct lock_file` initialized with an
192 - earlier call to `hold_lock_file_for_update` or
193 - `hold_lock_file_for_append`. Close the file descriptor (and
194 - the file pointer if it has been opened using
195 - `fdopen_lock_file`). Return 0 upon success. On failure to
196 - `close(2)`, return a negative value and roll back the lock
197 - file. Usually `commit_lock_file`, `commit_lock_file_to`, or
198 - `rollback_lock_file` should eventually be called if
199 - `close_lock_file` succeeds.
200 -
201 -reopen_lock_file::
202 -
203 - Re-open a lockfile that has been closed (using
204 - `close_lock_file`) but not yet committed or rolled back. This
205 - can be used to implement a sequence of operations like the
206 - following:
207 -
208 - * Lock file.
209 -
210 - * Write new contents to lockfile, then `close_lock_file` to
211 - cause the contents to be written to disk.
212 -
213 - * Pass the name of the lockfile to another program to allow it
214 - (and nobody else) to inspect the contents you wrote, while
215 - still holding the lock yourself.
216 -
217 - * `reopen_lock_file` to reopen the lockfile. Make further
218 - updates to the contents.
219 -
220 - * `commit_lock_file` to make the final version permanent.
lockfile.c
+53
@@ -1,6 +1,59 @@
1 /*
2 * Copyright (c) 2005, Junio C Hamano
3 */
4 +
5 +/*
6 + * State diagram and cleanup
7 + * -------------------------
8 + *
9 + * This module keeps track of all locked files in `lock_file_list` for
10 + * use at cleanup. This list and the `lock_file` objects that comprise
11 + * it must be kept in self-consistent states at all time, because the
12 + * program can be interrupted any time by a signal, in which case the
13 + * signal handler will walk through the list attempting to clean up
14 + * any open lock files.
15 + *
16 + * The possible states of a `lock_file` object are as follows:
17 + *
18 + * - Uninitialized. In this state the object's `on_list` field must be
19 + * zero but the rest of its contents need not be initialized. As
20 + * soon as the object is used in any way, it is irrevocably
21 + * registered in `lock_file_list`, and `on_list` is set.
22 + *
23 + * - Locked, lockfile open (after `hold_lock_file_for_update()`,
24 + * `hold_lock_file_for_append()`, or `reopen_lock_file()`). In this
25 + * state:
26 + *
27 + * - the lockfile exists
28 + * - `active` is set
29 + * - `filename` holds the filename of the lockfile
30 + * - `fd` holds a file descriptor open for writing to the lockfile
31 + * - `fp` holds a pointer to an open `FILE` object if and only if
32 + * `fdopen_lock_file()` has been called on the object
33 + * - `owner` holds the PID of the process that locked the file
34 + *
35 + * - Locked, lockfile closed (after successful `close_lock_file()`).
36 + * Same as the previous state, except that the lockfile is closed
37 + * and `fd` is -1.
38 + *
39 + * - Unlocked (after `commit_lock_file()`, `commit_lock_file_to()`,
40 + * `rollback_lock_file()`, a failed attempt to lock, or a failed
41 + * `close_lock_file()`). In this state:
42 + *
43 + * - `active` is unset
44 + * - `filename` is empty (usually, though there are transitory
45 + * states in which this condition doesn't hold). Client code should
46 + * *not* rely on the filename being empty in this state.
47 + * - `fd` is -1
48 + * - the object is left registered in the `lock_file_list`, and
49 + * `on_list` is set.
50 + *
51 + * A lockfile is owned by the process that created it. The `lock_file`
52 + * has an `owner` field that records the owner's PID. This field is
53 + * used to prevent a forked process from closing a lockfile created by
54 + * its parent.
55 + */
56 +
57 #include "cache.h"
58 #include "lockfile.h"
59 #include "sigchain.h"
lockfile.h
+230 -60
@@ -4,54 +4,103 @@
4 /*
5 * File write-locks as used by Git.
6 *
7 - * For an overview of how to use the lockfile API, please see
8 - *
9 - * Documentation/technical/api-lockfile.txt
10 - *
11 - * This module keeps track of all locked files in lock_file_list for
12 - * use at cleanup. This list and the lock_file objects that comprise
13 - * it must be kept in self-consistent states at all time, because the
14 - * program can be interrupted any time by a signal, in which case the
15 - * signal handler will walk through the list attempting to clean up
16 - * any open lock files.
17 - *
18 - * A lockfile is owned by the process that created it. The lock_file
19 - * object has an "owner" field that records its owner. This field is
20 - * used to prevent a forked process from closing a lockfile created by
21 - * its parent.
22 - *
23 - * The possible states of a lock_file object are as follows:
24 - *
25 - * - Uninitialized. In this state the object's on_list field must be
26 - * zero but the rest of its contents need not be initialized. As
27 - * soon as the object is used in any way, it is irrevocably
28 - * registered in the lock_file_list, and on_list is set.
29 - *
30 - * - Locked, lockfile open (after hold_lock_file_for_update(),
31 - * hold_lock_file_for_append(), or reopen_lock_file()). In this
32 - * state:
33 - * - the lockfile exists
34 - * - active is set
35 - * - filename holds the filename of the lockfile
36 - * - fd holds a file descriptor open for writing to the lockfile
37 - * - fp holds a pointer to an open FILE object if and only if
38 - * fdopen_lock_file() has been called on the object
39 - * - owner holds the PID of the process that locked the file
40 - *
41 - * - Locked, lockfile closed (after successful close_lock_file()).
42 - * Same as the previous state, except that the lockfile is closed
43 - * and fd is -1.
44 - *
45 - * - Unlocked (after commit_lock_file(), commit_lock_file_to(),
46 - * rollback_lock_file(), a failed attempt to lock, or a failed
47 - * close_lock_file()). In this state:
48 - * - active is unset
49 - * - filename is empty (usually, though there are transitory
50 - * states in which this condition doesn't hold). Client code should
51 - * *not* rely on the filename being empty in this state.
52 - * - fd is -1
53 - * - the object is left registered in the lock_file_list, and
54 - * on_list is set.
7 + * The lockfile API serves two purposes:
8 + *
9 + * * Mutual exclusion and atomic file updates. When we want to change
10 + * a file, we create a lockfile `<filename>.lock`, write the new
11 + * file contents into it, and then rename the lockfile to its final
12 + * destination `<filename>`. We create the `<filename>.lock` file
13 + * with `O_CREAT|O_EXCL` so that we can notice and fail if somebody
14 + * else has already locked the file, then atomically rename the
15 + * lockfile to its final destination to commit the changes and
16 + * unlock the file.
17 + *
18 + * * Automatic cruft removal. If the program exits after we lock a
19 + * file but before the changes have been committed, we want to make
20 + * sure that we remove the lockfile. This is done by remembering the
21 + * lockfiles we have created in a linked list and setting up an
22 + * `atexit(3)` handler and a signal handler that clean up the
23 + * lockfiles. This mechanism ensures that outstanding lockfiles are
24 + * cleaned up if the program exits (including when `die()` is
25 + * called) or if the program is terminated by a signal.
26 + *
27 + * Please note that lockfiles only block other writers. Readers do not
28 + * block, but they are guaranteed to see either the old contents of
29 + * the file or the new contents of the file (assuming that the
30 + * filesystem implements `rename(2)` atomically).
31 + *
32 + *
33 + * Calling sequence
34 + * ----------------
35 + *
36 + * The caller:
37 + *
38 + * * Allocates a `struct lock_file` either as a static variable or on
39 + * the heap, initialized to zeros. Once you use the structure to
40 + * call the `hold_lock_file_for_*()` family of functions, it belongs
41 + * to the lockfile subsystem and its storage must remain valid
42 + * throughout the life of the program (i.e. you cannot use an
43 + * on-stack variable to hold this structure).
44 + *
45 + * * Attempts to create a lockfile by calling
46 + * `hold_lock_file_for_update()` or `hold_lock_file_for_append()`.
47 + *
48 + * * Writes new content for the destination file by either:
49 + *
50 + * * writing to the file descriptor returned by the
51 + * `hold_lock_file_for_*()` functions (also available via
52 + * `lock->fd`).
53 + *
54 + * * calling `fdopen_lock_file()` to get a `FILE` pointer for the
55 + * open file and writing to the file using stdio.
56 + *
57 + * When finished writing, the caller can:
58 + *
59 + * * Close the file descriptor and rename the lockfile to its final
60 + * destination by calling `commit_lock_file()` or
61 + * `commit_lock_file_to()`.
62 + *
63 + * * Close the file descriptor and remove the lockfile by calling
64 + * `rollback_lock_file()`.
65 + *
66 + * * Close the file descriptor without removing or renaming the
67 + * lockfile by calling `close_lock_file()`, and later call
68 + * `commit_lock_file()`, `commit_lock_file_to()`,
69 + * `rollback_lock_file()`, or `reopen_lock_file()`.
70 + *
71 + * Even after the lockfile is committed or rolled back, the
72 + * `lock_file` object must not be freed or altered by the caller.
73 + * However, it may be reused; just pass it to another call of
74 + * `hold_lock_file_for_update()` or `hold_lock_file_for_append()`.
75 + *
76 + * If the program exits before `commit_lock_file()`,
77 + * `commit_lock_file_to()`, or `rollback_lock_file()` is called, an
78 + * `atexit(3)` handler will close and remove the lockfile, thereby
79 + * rolling back any uncommitted changes.
80 + *
81 + * If you need to close the file descriptor you obtained from a
82 + * `hold_lock_file_for_*()` function yourself, do so by calling
83 + * `close_lock_file()`. You should never call `close(2)` or
84 + * `fclose(3)` yourself, otherwise the `struct lock_file` structure
85 + * would still think that the file descriptor needs to be closed, and
86 + * a commit or rollback would result in duplicate calls to `close(2)`.
87 + * Worse yet, if you close and then later open another file descriptor
88 + * for a completely different purpose, then a commit or rollback might
89 + * close that unrelated file descriptor.
90 + *
91 + * Error handling
92 + * --------------
93 + *
94 + * The `hold_lock_file_for_*()` functions return a file descriptor on
95 + * success or -1 on failure (unless `LOCK_DIE_ON_ERROR` is used; see
96 + * "flags" below). On errors, `errno` describes the reason for
97 + * failure. Errors can be reported by passing `errno` to
98 + * `unable_to_lock_message()` or `unable_to_lock_die()`.
99 + *
100 + * Similarly, `commit_lock_file`, `commit_lock_file_to`, and
101 + * `close_lock_file` return 0 on success. On failure they set `errno`
102 + * appropriately, do their best to roll back the lockfile, and return
103 + * -1.
104 */
105
106 struct lock_file {
@@ -68,16 +117,51 @@ struct lock_file {
117 #define LOCK_SUFFIX ".lock"
118 #define LOCK_SUFFIX_LEN 5
119
120 +
121 +/*
122 + * Flags
123 + * -----
124 + *
125 + * The following flags can be passed to `hold_lock_file_for_update()`
126 + * or `hold_lock_file_for_append()`.
127 + */
128 +
129 +/*
130 + * If a lock is already taken for the file, `die()` with an error
131 + * message. If this flag is not specified, trying to lock a file that
132 + * is already locked returns -1 to the caller.
133 + */
134 #define LOCK_DIE_ON_ERROR 1
135 +
136 +/*
137 + * Usually symbolic links in the destination path are resolved. This
138 + * means that (1) the lockfile is created by adding ".lock" to the
139 + * resolved path, and (2) upon commit, the resolved path is
140 + * overwritten. However, if `LOCK_NO_DEREF` is set, then the lockfile
141 + * is created by adding ".lock" to the path argument itself. This
142 + * option is used, for example, when detaching a symbolic reference,
143 + * which for backwards-compatibility reasons, can be a symbolic link
144 + * containing the name of the referred-to-reference.
145 + */
146 #define LOCK_NO_DEREF 2
147
74 -extern void unable_to_lock_message(const char *path, int err,
75 - struct strbuf *buf);
76 -extern NORETURN void unable_to_lock_die(const char *path, int err);
148 +/*
149 + * Attempt to create a lockfile for the file at `path` and return a
150 + * file descriptor for writing to it, or -1 on error. If the file is
151 + * currently locked, retry with quadratic backoff for at least
152 + * timeout_ms milliseconds. If timeout_ms is 0, try exactly once; if
153 + * timeout_ms is -1, retry indefinitely. The flags argument and error
154 + * handling are described above.
155 + */
156 extern int hold_lock_file_for_update_timeout(
157 struct lock_file *lk, const char *path,
158 int flags, long timeout_ms);
159
160 +/*
161 + * Attempt to create a lockfile for the file at `path` and return a
162 + * file descriptor for writing to it, or -1 on error. The flags
163 + * argument and error handling are described above.
164 + */
165 static inline int hold_lock_file_for_update(
166 struct lock_file *lk, const char *path,
167 int flags)
@@ -85,15 +169,101 @@ static inline int hold_lock_file_for_update(
169 return hold_lock_file_for_update_timeout(lk, path, flags, 0);
170 }
171
88 -extern int hold_lock_file_for_append(struct lock_file *lk, const char *path,
89 - int flags);
172 +/*
173 + * Like `hold_lock_file_for_update()`, but before returning copy the
174 + * existing contents of the file (if any) to the lockfile and position
175 + * its write pointer at the end of the file. The flags argument and
176 + * error handling are described above.
177 + */
178 +extern int hold_lock_file_for_append(struct lock_file *lk,
179 + const char *path, int flags);
180 +
181 +/*
182 + * Append an appropriate error message to `buf` following the failure
183 + * of `hold_lock_file_for_update()` or `hold_lock_file_for_append()`
184 + * to lock `path`. `err` should be the `errno` set by the failing
185 + * call.
186 + */
187 +extern void unable_to_lock_message(const char *path, int err,
188 + struct strbuf *buf);
189
91 -extern FILE *fdopen_lock_file(struct lock_file *, const char *mode);
92 -extern char *get_locked_file_path(struct lock_file *);
93 -extern int commit_lock_file_to(struct lock_file *, const char *path);
94 -extern int commit_lock_file(struct lock_file *);
95 -extern int reopen_lock_file(struct lock_file *);
96 -extern int close_lock_file(struct lock_file *);
97 -extern void rollback_lock_file(struct lock_file *);
190 +/*
191 + * Emit an appropriate error message and `die()` following the failure
192 + * of `hold_lock_file_for_update()` or `hold_lock_file_for_append()`
193 + * to lock `path`. `err` should be the `errno` set by the failing
194 + * call.
195 + */
196 +extern NORETURN void unable_to_lock_die(const char *path, int err);
197 +
198 +/*
199 + * Associate a stdio stream with the lockfile (which must still be
200 + * open). Return `NULL` (*without* rolling back the lockfile) on
201 + * error. The stream is closed automatically when `close_lock_file()`
202 + * is called or when the file is committed or rolled back.
203 + */
204 +extern FILE *fdopen_lock_file(struct lock_file *lk, const char *mode);
205 +
206 +/*
207 + * Return the path of the file that is locked by the specified
208 + * lock_file object. The caller must free the memory.
209 + */
210 +extern char *get_locked_file_path(struct lock_file *lk);
211 +
212 +/*
213 + * If the lockfile is still open, close it (and the file pointer if it
214 + * has been opened using `fdopen_lock_file()`) without renaming the
215 + * lockfile over the file being locked. Return 0 upon success. On
216 + * failure to `close(2)`, return a negative value and roll back the
217 + * lock file. Usually `commit_lock_file()`, `commit_lock_file_to()`,
218 + * or `rollback_lock_file()` should eventually be called if
219 + * `close_lock_file()` succeeds.
220 + */
221 +extern int close_lock_file(struct lock_file *lk);
222 +
223 +/*
224 + * Re-open a lockfile that has been closed using `close_lock_file()`
225 + * but not yet committed or rolled back. This can be used to implement
226 + * a sequence of operations like the following:
227 + *
228 + * * Lock file.
229 + *
230 + * * Write new contents to lockfile, then `close_lock_file()` to
231 + * cause the contents to be written to disk.
232 + *
233 + * * Pass the name of the lockfile to another program to allow it (and
234 + * nobody else) to inspect the contents you wrote, while still
235 + * holding the lock yourself.
236 + *
237 + * * `reopen_lock_file()` to reopen the lockfile. Make further updates
238 + * to the contents.
239 + *
240 + * * `commit_lock_file()` to make the final version permanent.
241 + */
242 +extern int reopen_lock_file(struct lock_file *lk);
243 +
244 +/*
245 + * Commit the change represented by `lk`: close the file descriptor
246 + * and/or file pointer if they are still open and rename the lockfile
247 + * to its final destination. Return 0 upon success. On failure, roll
248 + * back the lock file and return -1, with `errno` set to the value
249 + * from the failing call to `close(2)` or `rename(2)`. It is a bug to
250 + * call `commit_lock_file()` for a `lock_file` object that is not
251 + * currently locked.
252 + */
253 +extern int commit_lock_file(struct lock_file *lk);
254 +
255 +/*
256 + * Like `commit_lock_file()`, but rename the lockfile to the provided
257 + * `path`. `path` must be on the same filesystem as the lock file.
258 + */
259 +extern int commit_lock_file_to(struct lock_file *lk, const char *path);
260 +
261 +/*
262 + * Roll back `lk`: close the file descriptor and/or file pointer and
263 + * remove the lockfile. It is a NOOP to call `rollback_lock_file()`
264 + * for a `lock_file` object that has already been committed or rolled
265 + * back.
266 + */
267 +extern void rollback_lock_file(struct lock_file *lk);
268
269 #endif /* LOCKFILE_H */