git/list[1] front-page[2] threads[3] people[4] search[5] about
 

Re: [PATCH 4/5] lock_file: make function-local locks non-static

From
Jeff King <peff@peff.net>
Date
May 8, 2018, 18:18 UTC
Message-ID
<20180508181839.GC7210@sigill.intra.peff.net>
In-Reply-To
<CACsJy8DDyrUinwXx1b66DCHB+2DLt1KBmFt_83R1+HWjbzGH2A@mail.gmail.com>
On Mon, May 07, 2018 at 05:24:05PM +0200, Duy Nguyen wrote:
Show 25 quoted lines
> >>>> -       static struct lock_file lock;
> >>>> +       struct lock_file lock = LOCK_INIT;
> >>>
> >>> Is it really safe to do this? I vaguely remember something about
> >>> (global) linked list and signal handling which could trigger any time
> >>> and probably at atexit() time too (i.e. die()). You don't want to
> >>> depend on stack-based variables in that case.
> >>
> >> So I dug in a bit more about this. The original implementation does
> >> not allow stack-based lock files at all in 415e96c8b7 ([PATCH]
> >> Implement git-checkout-cache -u to update stat information in the
> >> cache. - 2005-05-15). The situation has changed since 422a21c6a0
> >> (tempfile: remove deactivated list entries - 2017-09-05). At the end
> >> of that second commit, Jeff mentioned "We can clean them up
> >> individually" which I guess is what these patches do. Though I do not
> >> know if we need to make sure to call "release" function or something/
> >> Either way you need more explanation and assurance than just "we can
> >> drop their staticness" in the commit mesage.
> >
> > Thank you Duy for your comments. How about I write the commit message
> > like so:
> 
> +Jeff. Since he made it possible to remove lock file from the global
> linked list, he probably knows well what to check when switching from
> a static lock file to a stack-local one.

It should be totally safe. If you look at "struct lock_file", it is now simply a pointer to a tempfile allocated on the heap (in fact, I thought about getting rid of lock_file entirely, but the diff is noisy and it actually has some value as an abstraction over a pure tempfile).

If you fail to call a release function, it will just hang around until program exit, which is more or less what the static version would do. The big difference is that if we re-enter the function while still holding the lock, then the static version would BUG() on trying to use the already-active lockfile. Whereas after this series, we'd try to create a new lockfile and say "woah, somebody else is holding the lock".

Show 16 quoted lines
> >   After 076aa2cbd (tempfile: auto-allocate tempfiles on heap, 2017-09-05),
> >   we can have lockfiles on the stack. These `struct lock_file`s are local
> >   to their respective functions and we can drop their staticness.
> >
> >   Each of these users either commits or rolls back the lock in every
> >   codepath, with these possible exceptions:
> >
> >     * We bail using a call to `die()` or `exit()`. The lock will be
> >       cleaned up automatically.
> >
> >     * We return early from a function `cmd_foo()` in builtin/, i.e., we
> >       are just about to exit. The lock will be cleaned up automatically.
> 
> There are also signals which can be caught and run on its own stack (I
> think) so whatever variable on the current stack should be safe, I
> guess.

Yes, the stack variables should all be intact during an exit or a signal.

Show 14 quoted lines
> >   If I have missed some codepath where we do not exit, yet leave a locked
> >   lock around, that was so also before this patch. If we would later
> >   re-enter the same function, then before this patch, we would be retaking
> >   a lock for the very same `struct lock_file`, which feels awkward, but to
> >   the best of my reading has well-defined behavior. Whereas after this
> >   patch, we would attempt to take the lock with a completely fresh `struct
> >   lock_file`. In both cases, the result would simply be that the lock can
> >   not be taken, which is a situation we already handle.
> 
> There is a difference here, if the lock is not released properly,
> previously the lockfile is still untouched. If it's on stack, it may
> be overwritten which can corrupt the linked list to get to the next
> lock file.  (and this is about calling the function in question just
> _once_ not the second time).

The only bits on the stack are just a pointer to the list item. So the linked list is fine if it goes out of scope while the tempfile is still active. That was the point of 076aa2cbd.

-Peff
Previous: Martin ÅgrenNext: Duy Nguyen
Message 7 of 10 in “lock_file: make function-local locks non-static”
  1. 4/5 lock_file: make function-local locks non-staticMartin Ågren, May 6, 2018
  2. Duy NguyenMay 6, 2018
  3. Duy NguyenMay 6, 2018
  4. Martin ÅgrenMay 6, 2018
  5. Duy NguyenMay 7, 2018
  6. Martin ÅgrenMay 7, 2018
  7. Jeff KingMay 8, 2018
  8. Duy NguyenMay 9, 2018
  9. Martin ÅgrenMay 9, 2018
  10. Junio C HamanoMay 10, 2018

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.