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

Re: [PATCH 1/4] Introduce a function to lock/unlock file descriptors when appending

From
Johannes Schindelin <johannes.schindelin@gmx.de>
Date
Aug 10, 2018, 18:32 UTC
Message-ID
<nycvar.QRO.7.76.6.1808101843520.71@tvgsbejvaqbjf.bet>
In-Reply-To
<xmqqtvo3bc0g.fsf@gitster-ct.c.googlers.com>
Hi Junio,
On Thu, 9 Aug 2018, Junio C Hamano wrote:
Show 30 quoted lines
> "Johannes Schindelin via GitGitGadget" <gitgitgadget@gmail.com>
> writes:
> 
> > From: Johannes Schindelin <johannes.schindelin@gmx.de>
> >
> > This function will be used to make write accesses in trace_write() a bit
> > safer.
> > ...
> > To set a precedent for a better approach, let's introduce a proper
> > abstraction: a function that says in its name precisely what Git
> > wants it to do (as opposed to *how* it does it on Linux):
> > lock_or_unlock_fd_for_appending().
> >
> > The next commit will provide a Windows-specific implementation of this
> > function/functionality.
> >
> > Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
> >
> > squash! Introduce a function to lock/unlock file descriptors when appending
> 
> If we can keep the custom, narrow and easy-to-port API (like this
> patch introduces) focused and resist feature creep over time, then
> it would be worth spending effort to come up with such a custom
> helper that is easy to port.  So I agree with the approach in
> general but I tend to think "set a precedent for a better approach"
> is a way-too-early and wishful verdict.  We do not know if we can
> really keep that custom API easy-to-port-and-maintain yet.
> 
> In short, even though I agree with the approach, most of the
> verbiage above is unnecessary and mere distraction.

I disagree that it is a distraction, because the commit messages are the very location where I am supposed to detail my rationale, motivation, and considerations that are not obvious from the diff alone.

Of course, I cannot force you to take this commit message, you can overrule me and edit it. But you would do this against my express wish.

Show 39 quoted lines
> > ---
> >  git-compat-util.h |  2 ++
> >  wrapper.c         | 14 ++++++++++++++
> >  2 files changed, 16 insertions(+)
> >
> > diff --git a/git-compat-util.h b/git-compat-util.h
> > index 9a64998b2..13b83bade 100644
> > --- a/git-compat-util.h
> > +++ b/git-compat-util.h
> > @@ -1202,6 +1202,8 @@ struct tm *git_gmtime_r(const time_t *, struct tm *);
> >  #define getc_unlocked(fh) getc(fh)
> >  #endif
> >  
> > +extern int lock_or_unlock_fd_for_appending(int fd, int lock_it);
> > +
> >  /*
> >   * Our code often opens a path to an optional file, to work on its
> >   * contents when we can successfully open it.  We can ignore a failure
> > diff --git a/wrapper.c b/wrapper.c
> > index e4fa9d84c..6c2116272 100644
> > --- a/wrapper.c
> > +++ b/wrapper.c
> > @@ -690,3 +690,17 @@ int xgethostname(char *buf, size_t len)
> >  		buf[len - 1] = 0;
> >  	return ret;
> >  }
> > +
> > +#ifndef GIT_WINDOWS_NATIVE
> > +int lock_or_unlock_fd_for_appending(int fd, int lock_it)
> > +{
> > +	struct flock flock;
> > +
> > +	flock.l_type = lock_it ? F_WRLCK : F_UNLCK;
> > +	flock.l_whence = SEEK_SET;
> > +	flock.l_start = 0;
> > +	flock.l_len = 0xffffffff; /* arbitrary number of bytes */
> 
> If this can be an arbitrary range, do we need to cover this many (or
> only this few, depending on your point of view) bytes?

It can be an arbitrary range, but it does not matter at this point because we expect only appending callers. Therefore any range will do, as long as it covers the range of bytes to be written by the trace functions. And with 0-0xffffffff, I am fairly certain we got it.

Technically, we could even lock the range 0-1, as all of our callers would agree on that, and block each other. Other Git implementations might not, though. So 0-0xffffffff is my best bet and cheap.

> Would it be sufficient to cover just the first one byte instead?

As I said, this would depend on no other software trying to append to the trace file, including alternative Git implementations.

In other words: it would be "too clever". Clever, but asking for problems.
> Or perhaps give l_len==0 to cover all no matter how large the file
> grows, which sounds like a better range specification.
I must have overlooked that option in the documentation.
*clicketyclick*

Indeed, http://pubs.opengroup.org/onlinepubs/9699919799/functions/fcntl.html spells it out pretty clearly:

> A lock shall be set to extend to the largest possible value of the file
> offset for that file by setting l_len to 0. If such a lock also has
> l_start set to 0 and l_whence is set to SEEK_SET, the whole file shall
> be locked.
Sorry about missing this. I will change the implementation to this.
> > +	return fcntl(fd, F_SETLKW, &flock);
> > +}
> > +#endif

Thanks for helping me improve the patch, Dscho

Previous: Junio C HamanoNext: Johannes Schindelin via GitGitGadget
Message 4 of 43 in “t5552: fix flakiness by introducing proper locking for GIT_TRACE”
  1. 0/4 t5552: fix flakiness by introducing proper locking for GIT_TRACEJohannes Schindelin via GitGitGadget, Aug 9, 2018
  2. 1/4 Introduce a function to lock/unlock file descriptors when appendingJohannes Schindelin via GitGitGadget, Aug 9, 2018
  3. Junio C HamanoAug 9, 2018
  4. Johannes SchindelinAug 10, 2018
  5. 2/4 mingw: implement lock_or_unlock_fd_for_appending()Johannes Schindelin via GitGitGadget, Aug 9, 2018
  6. 3/4 trace: lock the trace file to avoid racy trace_write() callsJohannes Schindelin via GitGitGadget, Aug 9, 2018
  7. 4/4 trace: verify that locking worksJohannes Schindelin via GitGitGadget, Aug 9, 2018
  8. Jeff KingAug 9, 2018
  9. Junio C HamanoAug 9, 2018
  10. Junio C HamanoAug 9, 2018
  11. Jeff KingAug 9, 2018
  12. Jeff KingAug 10, 2018
  13. Junio C HamanoAug 10, 2018
  14. Junio C HamanoAug 10, 2018
  15. Johannes SchindelinAug 10, 2018
  16. Jeff KingAug 10, 2018
  17. Junio C HamanoAug 10, 2018
  18. Johannes SchindelinAug 10, 2018
  19. Johannes SixtAug 10, 2018
  20. Jeff HostetlerAug 10, 2018
  21. Jeff HostetlerAug 10, 2018
  22. Johannes SixtAug 10, 2018
  23. Junio C HamanoAug 10, 2018
  24. Jeff KingAug 10, 2018
  25. mingw: enable atomic O_APPENDJohannes Sixt, Aug 13, 2018
  26. Junio C HamanoAug 13, 2018
  27. Johannes SixtAug 13, 2018
  28. Ævar Arnfjörð BjarmasonAug 13, 2018
  29. Junio C HamanoAug 13, 2018
  30. Jeff KingAug 13, 2018
  31. Ævar Arnfjörð BjarmasonAug 14, 2018
  32. Jeff KingAug 14, 2018
  33. Johannes SixtAug 14, 2018
  34. Jeff KingAug 14, 2018
  35. Jeff HostetlerAug 14, 2018
  36. Junio C HamanoAug 14, 2018
  37. 0/4 t5552: fix flakiness by introducing proper locking for GIT_TRACEJohannes Schindelin via GitGitGadget, Aug 10, 2018
  38. 1/4 Introduce a function to lock/unlock file descriptors when appendingJohannes Schindelin via GitGitGadget, Aug 10, 2018
  39. Junio C HamanoAug 10, 2018
  40. Johannes SchindelinAug 10, 2018
  41. 2/4 mingw: implement lock_or_unlock_fd_for_appending()Johannes Schindelin via GitGitGadget, Aug 10, 2018
  42. 3/4 trace: lock the trace file to avoid racy trace_write() callsJohannes Schindelin via GitGitGadget, Aug 10, 2018
  43. 4/4 trace: verify that locking worksJohannes Schindelin via GitGitGadget, Aug 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.