Junio C Hamano | 3dac504 | 2007-12-15 08:40:54 | [diff] [blame] | 1 | lockfile API |
| 2 | ============ |
| 3 | |
Junio C Hamano | 5bd1d59 | 2008-01-17 02:43:10 | [diff] [blame] | 4 | The lockfile API serves two purposes: |
Junio C Hamano | 3dac504 | 2007-12-15 08:40:54 | [diff] [blame] | 5 | |
Junio C Hamano | 5bd1d59 | 2008-01-17 02:43:10 | [diff] [blame] | 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. |
Junio C Hamano | 3dac504 | 2007-12-15 08:40:54 | [diff] [blame] | 12 | |
Junio C Hamano | 5bd1d59 | 2008-01-17 02:43:10 | [diff] [blame] | 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. Returns 0 upon success, a negative |
| 41 | value on failure to close(2) or rename(2). |
| 42 | |
| 43 | rollback_lock_file:: |
| 44 | |
| 45 | Take a pointer to the `struct lock_file` initialized |
| 46 | with an earlier call to `hold_lock_file_for_update()`, |
| 47 | close the file descriptor and remove the lockfile. |
| 48 | |
| 49 | close_lock_file:: |
| 50 | Take a pointer to the `struct lock_file` initialized |
| 51 | with an earlier call to `hold_lock_file_for_update()`, |
| 52 | and close the file descriptor. Returns 0 upon success, |
| 53 | a negative value on failure to close(2). |
| 54 | |
| 55 | Because the structure is used in an `atexit(3)` handler, its |
| 56 | storage has to stay throughout the life of the program. It |
| 57 | cannot be an auto variable allocated on the stack. |
| 58 | |
| 59 | Call `commit_lock_file()` or `rollback_lock_file()` when you are |
| 60 | done writing to the file descriptor. If you do not call either |
| 61 | and simply `exit(3)` from the program, an `atexit(3)` handler |
| 62 | will close and remove the lockfile. |
| 63 | |
| 64 | If you need to close the file descriptor you obtained from |
| 65 | `hold_lock_file_for_update` function yourself, do so by calling |
| 66 | `close_lock_file()`. You should never call `close(2)` yourself! |
| 67 | Otherwise the `struct |
| 68 | lock_file` structure still remembers that the file descriptor |
| 69 | needs to be closed, and a later call to `commit_lock_file()` or |
| 70 | `rollback_lock_file()` will result in duplicate calls to |
| 71 | `close(2)`. Worse yet, if you `close(2)`, open another file |
| 72 | descriptor for completely different purpose, and then call |
| 73 | `commit_lock_file()` or `rollback_lock_file()`, they may close |
| 74 | that unrelated file descriptor. |