git.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Michael Haggerty <mhagger@alum.mit.edu>
To: Junio C Hamano <gitster@pobox.com>
Cc: "Johannes Sixt" <j6t@kdbg.org>,
	"Torsten Bögershausen" <tboegi@web.de>,
	"Jeff King" <peff@peff.net>,
	"Ronnie Sahlberg" <sahlberg@google.com>,
	"Jonathan Nieder" <jrnieder@gmail.com>,
	git@vger.kernel.org
Subject: Re: [PATCH v6 02/39] api-lockfile: revise and expand the documentation
Date: Tue, 30 Sep 2014 12:53:04 +0200	[thread overview]
Message-ID: <542A8B90.50507@alum.mit.edu> (raw)
In-Reply-To: <xmqqlhp68c69.fsf@gitster.dls.corp.google.com>

On 09/26/2014 08:33 PM, Junio C Hamano wrote:
> Michael Haggerty <mhagger@alum.mit.edu> writes:
> 
>> Document a couple more functions and the flags argument as used by
>> hold_lock_file_for_update() and hold_lock_file_for_append().
>> Reorganize the document to make it more accessible.
>>
>> Helped-by: Jonathan Nieder <jrnieder@gmail.com>
>> Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
>> ---
>>  Documentation/technical/api-lockfile.txt | 199 ++++++++++++++++++++++---------
>>  1 file changed, 145 insertions(+), 54 deletions(-)
> 
> Nicely done.
> 
>> +* Mutual exclusion and atomic file updates. When we want to change a
>> +  file, we create a lockfile `<filename>.lock`, write the new file
>> +  contents into it, and then rename the lockfile to its final
>> +  destination `<filename>`. We create the `<filename>.lock` file with
>> +  `O_CREAT|O_EXCL` so that we can notice and fail if somebody else has
>> +  already locked the file.
> 
> 
> You may want to say
> 
> 	then atomically rename the lockfile to its final destination
> 	to commit the changes and unlock the file.
> 
> here; that way, your mention of "commit" in the next paragraph would
> become easier to understand.

Good; will change.

>> [...]
>> +Calling sequence
>> +----------------
>> +
>> +The caller:
>> +
>> +* Allocates a variable `struct lock_file lock` in the bss section or
>> +  heap, initialized to zeros. It cannot be an auto variable allocated
>> +  on the stack. Because the `lock_file` structure is used in an
>> +  `atexit(3)` handler, its storage has to stay throughout the life of
>> +  the program, even after the file changes have been committed or
>> +  rolled back.
> 
> It is easier to read if you pushed the second sentence (which is a
> rephrase of the first one) and third sentence (which explains why
> the second sentence is true) out of line as a side-note, I think, or
> probably remove them from here (see below).

I was being repetitive because I didn't want the docs to depend on the
user remembering what the "bss" section is (which, technically, is also
not part of the C standard). I think a better way would be to just not
mention "bss section" at all and reword the rest. Maybe something like

  The caller:

  * Allocates a variable `struct lock_file lock`, initialized to zeros.
    Because the `lock_file` structure is used in an `atexit(3)` handler,
    its storage has to remain valid throughout the life of the program;
    e.g., it should be a static variable or space allocated on the heap.

Better?

>> +* Attempts to create a lockfile by passing that variable and the path
>> +  of the final destination (e.g. `$GIT_DIR/index`) to
>> +  `hold_lock_file_for_update` or `hold_lock_file_for_append`.
>> +
>> +* Writes new content for the destination file by writing to the file
>> +  descriptor returned by those functions (also available via
>> +  `lock->fd`).
>> +
>> +When finished writing, the caller can:
>> +
>> +* Close the file descriptor and rename the lockfile to its final
>> +  destination by calling `commit_lock_file`.
>> +
>> +* Close the file descriptor and remove the lockfile by calling
>> +  `rollback_lock_file`.
>> +
>> +* Close the file descriptor without removing or renaming the lockfile
>> +  by calling `close_lock_file`, and later call `commit_lock_file` or
>> +  `rollback_lock_file`.
>> +
>> +At this point, the `lock_file` object must not be freed or altered,
>> +because it is still registered in the `lock_file_list`. However, it
>> +may be reused; just pass it to another call of
>> +`hold_lock_file_for_update` or `hold_lock_file_for_append`.
> 
> It feels a bit conflicting between "must not be freed or ALTERED"
> and "it may be REUSED".  Drop "or altered" to reduce confusion?  And
> this repeats the third sentence I suggested to remove from the first
> paragraph (above 'see below' refers here).

The purpose of "or altered" is to make sure that users don't imagine
that they should memset() the structure to zeros or something before
reusing it (especially since the "caller" instructions earlier say that
the object should be "initialized to zeros").

Would it help if I change

    s/altered/altered by the caller/

?

I will also drop "because it is still registered in the `lock_file_list`".

> Is it allowed to tell the name of this lock_file to other people and
> let them read from it?  The answer is yes but it is not obvious from
> this description.
> 
> Also mention how the above interact with reopen_lock_file() here?

I'll take a stab at it, though TBH I haven't really studied the use case
for reopen_lock_file(). You might be better able to provide insight into
this topic.

>> +If the program exits before you have called one of `commit_lock_file`,
>> +`rollback_lock_file`, or `close_lock_file`, an `atexit(3)` handler
>> +will close and remove the lockfile, essentially rolling back any
>> +uncommitted changes.
> 
> s/essentially //;

Done.

>> +Error handling
>> +--------------
>> +
>> +The `hold_lock_file_*` functions return a file descriptor on success
>> +or -1 on failure (unless `LOCK_DIE_ON_ERROR` is used; see below). On
>> +errors, `errno` describes the reason for failure. Errors can be
>> +handled by passing `errno` to one of the following helper functions:
> 
> s/handled by/reported by/; probably.  None of these will help you
> "handle" errors in the sense to (attempt to) recover from it.

Done.

Thanks for your suggestions!
Michael

-- 
Michael Haggerty
mhagger@alum.mit.edu

  reply	other threads:[~2014-09-30 10:53 UTC|newest]

Thread overview: 55+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-09-26 10:08 [PATCH v6 00/39] Lockfile correctness and refactoring Michael Haggerty
2014-09-26 10:08 ` [PATCH v6 01/39] unable_to_lock_die(): rename function from unable_to_lock_index_die() Michael Haggerty
2014-09-26 10:08 ` [PATCH v6 02/39] api-lockfile: revise and expand the documentation Michael Haggerty
2014-09-26 18:33   ` Junio C Hamano
2014-09-30 10:53     ` Michael Haggerty [this message]
2014-09-30 17:39       ` Junio C Hamano
2014-10-01  7:37         ` Michael Haggerty
2014-09-26 20:40   ` Junio C Hamano
2014-09-30 13:41     ` Michael Haggerty
2014-09-30 16:15       ` Jeff King
2014-09-30 17:47         ` Junio C Hamano
2014-10-01  8:11           ` Michael Haggerty
2014-09-26 10:08 ` [PATCH v6 03/39] close_lock_file(): exit (successfully) if file is already closed Michael Haggerty
2014-09-26 10:08 ` [PATCH v6 04/39] rollback_lock_file(): do not clear filename redundantly Michael Haggerty
2014-09-26 10:08 ` [PATCH v6 05/39] rollback_lock_file(): exit early if lock is not active Michael Haggerty
2014-09-26 10:08 ` [PATCH v6 06/39] rollback_lock_file(): set fd to -1 Michael Haggerty
2014-09-26 10:08 ` [PATCH v6 07/39] lockfile: unlock file if lockfile permissions cannot be adjusted Michael Haggerty
2014-09-26 10:08 ` [PATCH v6 08/39] hold_lock_file_for_append(): release lock on errors Michael Haggerty
2014-09-26 10:08 ` [PATCH v6 09/39] lock_file(): always initialize and register lock_file object Michael Haggerty
2014-09-26 10:08 ` [PATCH v6 10/39] lockfile.c: document the various states of lock_file objects Michael Haggerty
2014-09-26 10:08 ` [PATCH v6 11/39] cache.h: define constants LOCK_SUFFIX and LOCK_SUFFIX_LEN Michael Haggerty
2014-09-26 10:08 ` [PATCH v6 12/39] delete_ref_loose(): don't muck around in the lock_file's filename Michael Haggerty
2014-09-26 10:08 ` [PATCH v6 13/39] prepare_index(): declare return value to be (const char *) Michael Haggerty
2014-09-26 10:08 ` [PATCH v6 14/39] write_packed_entry_fn(): convert cb_data into a (const int *) Michael Haggerty
2014-09-26 10:08 ` [PATCH v6 15/39] lock_file(): exit early if lockfile cannot be opened Michael Haggerty
2014-09-26 10:08 ` [PATCH v6 16/39] remove_lock_file(): call rollback_lock_file() Michael Haggerty
2014-09-26 10:08 ` [PATCH v6 17/39] commit_lock_file(): inline temporary variable Michael Haggerty
2014-09-26 10:08 ` [PATCH v6 18/39] commit_lock_file(): die() if called for unlocked lockfile object Michael Haggerty
2014-09-26 10:08 ` [PATCH v6 19/39] close_lock_file(): if close fails, roll back Michael Haggerty
2014-09-26 10:08 ` [PATCH v6 20/39] commit_lock_file(): rollback lock file on failure to rename Michael Haggerty
2014-09-26 10:08 ` [PATCH v6 21/39] api-lockfile: document edge cases Michael Haggerty
2014-09-26 10:08 ` [PATCH v6 22/39] dump_marks(): remove a redundant call to rollback_lock_file() Michael Haggerty
2014-09-26 10:08 ` [PATCH v6 23/39] git_config_set_multivar_in_file(): avoid " Michael Haggerty
2014-09-26 10:08 ` [PATCH v6 24/39] lockfile: avoid transitory invalid states Michael Haggerty
2014-09-26 10:08 ` [PATCH v6 25/39] struct lock_file: declare some fields volatile Michael Haggerty
2014-09-26 10:08 ` [PATCH v6 26/39] try_merge_strategy(): remove redundant lock_file allocation Michael Haggerty
2014-09-26 10:08 ` [PATCH v6 27/39] try_merge_strategy(): use a statically-allocated lock_file object Michael Haggerty
2014-09-26 19:00   ` Junio C Hamano
2014-09-30 14:04     ` Michael Haggerty
2014-09-30 18:08       ` Junio C Hamano
2014-09-26 10:08 ` [PATCH v6 28/39] commit_lock_file(): use a strbuf to manage temporary space Michael Haggerty
2014-09-26 10:08 ` [PATCH v6 29/39] Change lock_file::filename into a strbuf Michael Haggerty
2014-09-26 10:08 ` [PATCH v6 30/39] resolve_symlink(): use a strbuf for internal scratch space Michael Haggerty
2014-09-26 10:08 ` [PATCH v6 31/39] resolve_symlink(): take a strbuf parameter Michael Haggerty
2014-09-26 10:08 ` [PATCH v6 32/39] trim_last_path_component(): replace last_path_elm() Michael Haggerty
2014-09-26 10:08 ` [PATCH v6 33/39] Extract a function commit_lock_file_to() Michael Haggerty
2014-09-26 10:08 ` [PATCH v6 34/39] Rename LOCK_NODEREF to LOCK_NO_DEREF Michael Haggerty
2014-09-26 10:08 ` [PATCH v6 35/39] lockfile.c: rename static functions Michael Haggerty
2014-09-26 10:08 ` [PATCH v6 36/39] get_locked_file_path(): new function Michael Haggerty
2014-09-26 10:08 ` [PATCH v6 37/39] hold_lock_file_for_append(): restore errno before returning Michael Haggerty
2014-09-26 10:08 ` [PATCH v6 38/39] Move read_index() definition to read-cache.c Michael Haggerty
2014-09-26 10:08 ` [PATCH v6 39/39] lockfile.h: extract new header file for the functions in lockfile.c Michael Haggerty
2014-09-26 16:31 ` [PATCH v6 00/39] Lockfile correctness and refactoring Junio C Hamano
2014-09-30  9:55   ` Michael Haggerty
2014-09-26 19:10 ` Junio C Hamano

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=542A8B90.50507@alum.mit.edu \
    --to=mhagger@alum.mit.edu \
    --cc=git@vger.kernel.org \
    --cc=gitster@pobox.com \
    --cc=j6t@kdbg.org \
    --cc=jrnieder@gmail.com \
    --cc=peff@peff.net \
    --cc=sahlberg@google.com \
    --cc=tboegi@web.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).