Document lockfile API
We have nice set of placeholders, but nobody stepped in to fill the gap in the API documentation, so I am doing it myself. Signed-off-by: Junio C Hamano <gitster@pobox.com>
Junio C Hamano committed
Jan 16, 2008 at 11:00 UTC
0c0478cac87991bd555e81715e9332d11eecd881
1 file changed
+60
-7
Documentation/technical/api-lockfile.txt
+60
-7
@@ -1,12 +1,65 @@
1
lockfile API
2
============
3
4
-Talk about <lockfile.c>, things like:
4
+The lockfile API serves two purposes:
5
6
-* lockfile lifetime -- atexit(3) looks at them, do not put them on the
7
- stack;
8
-* hold_lock_file_for_update()
9
-* commit_lock_file()
10
-* rollback_rock_file()
6
+* Mutual exclusion. When we write out a new index file, first
7
+ we create a new file `$GIT_DIR/index.lock`, write the new
8
+ contents into it, and rename it to the final destination
9
+ `$GIT_DIR/index`. We try to create the `$GIT_DIR/index.lock`
10
+ file with O_EXCL so that we can notice and fail when somebody
11
+ else is already trying to update the index file.
12
12
-(JC, Dscho, Shawn)
13
+* Automatic cruft removal. After we create the "lock" file, we
14
+ may decide to `die()`, and we would want to make sure that we
15
+ remove the file that has not been committed to its final
16
+ destination. This is done by remembering the lockfiles we
17
+ created in a linked list and cleaning them up from an
18
+ `atexit(3)` handler. Outstanding lockfiles are also removed
19
+ when the program dies on a signal.
20
+
21
+
22
+The functions
23
+-------------
24
+
25
+hold_lock_file_for_update::
26
+
27
+ Take a pointer to `struct lock_file`, the filename of
28
+ the final destination (e.g. `$GIT_DIR/index`) and a flag
29
+ `die_on_error`. Attempt to create a lockfile for the
30
+ destination and return the file descriptor for writing
31
+ to the file. If `die_on_error` flag is true, it dies if
32
+ a lock is already taken for the file; otherwise it
33
+ returns a negative integer to the caller on failure.
34
+
35
+commit_lock_file::
36
+
37
+ Take a pointer to the `struct lock_file` initialized
38
+ with an earlier call to `hold_lock_file_for_update()`,
39
+ close the file descriptor and rename the lockfile to its
40
+ final destination.
41
+
42
+rollback_lock_file::
43
+
44
+ Take a pointer to the `struct lock_file` initialized
45
+ with an earlier call to `hold_lock_file_for_update()`,
46
+ close the file descriptor and remove the lockfile.
47
+
48
+Because the structure is used in an `atexit(3)` handler, its
49
+storage has to stay throughout the life of the program. It
50
+cannot be an auto variable allocated on the stack.
51
+
52
+Call `commit_lock_file()` or `rollback_lock_file()` when you are
53
+done writing to the file descriptor. If you do not call either
54
+and simply `exit(3)` from the program, an `atexit(3)` handler
55
+will close and remove the lockfile.
56
+
57
+You should not close the file descriptor you obtained from
58
+`hold_lock_file_for_update` function yourself. The `struct
59
+lock_file` structure still remembers that the file descriptor
60
+needs to be closed, and a later call to `commit_lock_file()` or
61
+`rollback_lock_file()` will result in duplicate calls to
62
+`close(2)`. Worse yet, if you `close(2)`, open another file
63
+descriptor for completely different purpose, and then call
64
+`commit_lock_file()` or `rollback_lock_file()`, they may close
65
+that unrelated file descriptor.