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

[PATCH v3 07/12] apply: move lockfile into `apply_state`

From
MÅMartin Ågren <martin.agren@gmail.com>
Date
Oct 6, 2017, 20:12 UTC
Message-ID
<6d058c882643dc45c8d708be98e86c38f25511a9.1507320376.git.martin.agren@gmail.com>
In-Reply-To
<cover.1507320376.git.martin.agren@gmail.com>

We have two users of `struct apply_state` and the related functionality in apply.c. Each user sets up its `apply_state` by handing over a pointer to its static `lock_file`. (Before 076aa2cbd (tempfile: auto-allocate tempfiles on heap, 2017-09-05), we could never free lockfiles, so making them static was a reasonable approach.)

Other than that, they never directly access their `lock_file`s, which are instead handled by the functionality in apply.c.

To make life easier for the caller and to make it less tempting for a future caller to mess with the lock, make apply.c fully responsible for setting up the `lock_file`. As mentioned above, it is now safe to free a `lock_file`, so we can make the `struct apply_state` contain an actual `struct lock_file` instead of a pointer to one.

The user in builtin/apply.c is rather simple. For builtin/am.c, we might worry that the lock state is actually meant to be inherited across calls. But the lock is only taken as `apply_all_patches()` executes, and code inspection shows that it will always be released.

Alternatively, we can observe that the lock itself is never queried directly. When we decide whether we should lock, we check a related variable `newfd`. That variable is not inherited, so from the point of view of apply.c, the state machine really is reset with each call to `init_apply_state()`. (It would be a bug if `newfd` and the lock status were not in sync. The duplication of information in `newfd` and the lock will be addressed in the next patch.)

Signed-off-by: Martin Ågren <martin.agren@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
 apply.c         | 14 +++++---------
 apply.h         |  5 ++---
 builtin/am.c    |  3 +--
 builtin/apply.c |  4 +---
 4 files changed, 9 insertions(+), 17 deletions(-)
diff --git a/apply.c b/apply.c
index c022af53a..5a6ca10a7 100644
--- a/apply.c
+++ b/apply.c
@@ -75,12 +75,10 @@ static int parse_ignorewhitespace_option(struct apply_state *state,
 }
 
 int init_apply_state(struct apply_state *state,
-		     const char *prefix,
-		     struct lock_file *lock_file)
+		     const char *prefix)
 {
 	memset(state, 0, sizeof(*state));
 	state->prefix = prefix;
-	state->lock_file = lock_file;
 	state->newfd = -1;
 	state->apply = 1;
 	state->line_termination = '\n';
@@ -146,8 +144,6 @@ int check_apply_state(struct apply_state *state, int force_apply)
 	}
 	if (state->check_index)
 		state->unsafe_paths = 0;
-	if (!state->lock_file)
-		return error("BUG: state->lock_file should not be NULL");
 
 	if (state->apply_verbosity <= verbosity_silent) {
 		state->saved_error_routine = get_error_routine();
@@ -4711,11 +4707,11 @@ static int apply_patch(struct apply_state *state,
 	state->update_index = state->check_index && state->apply;
 	if (state->update_index && state->newfd < 0) {
 		if (state->index_file)
-			state->newfd = hold_lock_file_for_update(state->lock_file,
+			state->newfd = hold_lock_file_for_update(&state->lock_file,
 								 state->index_file,
 								 LOCK_DIE_ON_ERROR);
 		else
-			state->newfd = hold_locked_index(state->lock_file, LOCK_DIE_ON_ERROR);
+			state->newfd = hold_locked_index(&state->lock_file, LOCK_DIE_ON_ERROR);
 	}
 
 	if (state->check_index && read_apply_cache(state) < 0) {
@@ -4911,7 +4907,7 @@ int apply_all_patches(struct apply_state *state,
 	}
 
 	if (state->update_index) {
-		res = write_locked_index(&the_index, state->lock_file, COMMIT_LOCK);
+		res = write_locked_index(&the_index, &state->lock_file, COMMIT_LOCK);
 		if (res) {
 			error(_("Unable to write new index file"));
 			res = -128;
@@ -4924,7 +4920,7 @@ int apply_all_patches(struct apply_state *state,
 
 end:
 	if (state->newfd >= 0) {
-		rollback_lock_file(state->lock_file);
+		rollback_lock_file(&state->lock_file);
 		state->newfd = -1;
 	}
 
diff --git a/apply.h b/apply.h
index d9b395770..cf00cda17 100644
--- a/apply.h
+++ b/apply.h
@@ -37,7 +37,7 @@ struct apply_state {
 	const char *prefix;
 
 	/* These are lock_file related */
-	struct lock_file *lock_file;
+	struct lock_file lock_file;
 	int newfd;
 
 	/* These control what gets looked at and modified */
@@ -116,8 +116,7 @@ extern int apply_parse_options(int argc, const char **argv,
 			       int *force_apply, int *options,
 			       const char * const *apply_usage);
 extern int init_apply_state(struct apply_state *state,
-			    const char *prefix,
-			    struct lock_file *lock_file);
+			    const char *prefix);
 extern void clear_apply_state(struct apply_state *state);
 extern int check_apply_state(struct apply_state *state, int force_apply);
 
diff --git a/builtin/am.c b/builtin/am.c
index 4e16fd428..40968428d 100644
--- a/builtin/am.c
+++ b/builtin/am.c
@@ -1488,11 +1488,10 @@ static int run_apply(const struct am_state *state, const char *index_file)
 	struct argv_array apply_opts = ARGV_ARRAY_INIT;
 	struct apply_state apply_state;
 	int res, opts_left;
-	static struct lock_file lock_file;
 	int force_apply = 0;
 	int options = 0;
 
-	if (init_apply_state(&apply_state, NULL, &lock_file))
+	if (init_apply_state(&apply_state, NULL))
 		die("BUG: init_apply_state() failed");
 
 	argv_array_push(&apply_opts, "apply");
diff --git a/builtin/apply.c b/builtin/apply.c
index 81b9a61c3..48d398933 100644
--- a/builtin/apply.c
+++ b/builtin/apply.c
@@ -9,8 +9,6 @@ static const char * const apply_usage[] = {
 	NULL
 };
 
-static struct lock_file lock_file;
-
 int cmd_apply(int argc, const char **argv, const char *prefix)
 {
 	int force_apply = 0;
@@ -18,7 +16,7 @@ int cmd_apply(int argc, const char **argv, const char *prefix)
 	int ret;
 	struct apply_state state;
 
-	if (init_apply_state(&state, prefix, &lock_file))
+	if (init_apply_state(&state, prefix))
 		exit(128);
 
 	argc = apply_parse_options(argc, argv,
-- 
2.15.0.rc0
Previous: Martin ÅgrenNext: Martin Ågren
Message 66 of 69 in “various lockfile-leaks and -fixes”
  1. 00/11 various lockfile-leaks and -fixesMartin Ågren, Oct 1, 2017
  2. 01/11 sha1_file: do not leak `lock_file`Martin Ågren, Oct 1, 2017
  3. Jeff KingOct 2, 2017
  4. Martin ÅgrenOct 2, 2017
  5. 02/11 treewide: prefer lockfiles on the stackMartin Ågren, Oct 1, 2017
  6. Junio C HamanoOct 2, 2017
  7. Martin ÅgrenOct 2, 2017
  8. Jeff KingOct 2, 2017
  9. 03/11 lockfile: fix documentation on `close_lock_file_gently()`Martin Ågren, Oct 1, 2017
  10. Jeff KingOct 2, 2017
  11. 04/11 tempfile: fix documentation on `delete_tempfile()`Martin Ågren, Oct 1, 2017
  12. Jeff KingOct 2, 2017
  13. 05/11 cache-tree: simplify locking logicMartin Ågren, Oct 1, 2017
  14. Junio C HamanoOct 2, 2017
  15. Jeff KingOct 2, 2017
  16. 06/11 apply: move lockfile into `apply_state`Martin Ågren, Oct 1, 2017
  17. Jeff KingOct 2, 2017
  18. 07/11 apply: remove `newfd` from `struct apply_state`Martin Ågren, Oct 1, 2017
  19. Jeff KingOct 2, 2017
  20. 08/11 cache.h: document `write_locked_index()`Martin Ågren, Oct 1, 2017
  21. 09/11 read-cache: require flags for `write_locked_index()`Martin Ågren, Oct 1, 2017
  22. Junio C HamanoOct 2, 2017
  23. Martin ÅgrenOct 2, 2017
  24. Martin ÅgrenOct 2, 2017
  25. Jeff KingOct 2, 2017
  26. 10/11 read-cache: don't leave dangling pointer in `do_write_index()`Martin Ågren, Oct 1, 2017
  27. Jeff KingOct 2, 2017
  28. Jeff KingOct 2, 2017
  29. 11/11 read-cache: roll back lock on error with `COMMIT_LOCK`Martin Ågren, Oct 1, 2017
  30. Junio C HamanoOct 2, 2017
  31. Junio C HamanoOct 2, 2017
  32. Jeff KingOct 2, 2017
  33. Junio C HamanoOct 2, 2017
  34. Martin ÅgrenOct 2, 2017
  35. Junio C HamanoOct 3, 2017
  36. 00/12 Re: various lockfile-leaks and -fixesMartin Ågren, Oct 5, 2017
  37. 01/12 sha1_file: do not leak `lock_file`Martin Ågren, Oct 5, 2017
  38. Junio C HamanoOct 6, 2017
  39. 02/12 treewide: prefer lockfiles on the stackMartin Ågren, Oct 5, 2017
  40. 03/12 lockfile: fix documentation on `close_lock_file_gently()`Martin Ågren, Oct 5, 2017
  41. 05/12 checkout-index: simplify locking logicMartin Ågren, Oct 5, 2017
  42. Junio C HamanoOct 6, 2017
  43. 06/12 cache-tree: simplify locking logicMartin Ågren, Oct 5, 2017
  44. 07/12 apply: move lockfile into `apply_state`Martin Ågren, Oct 5, 2017
  45. 08/12 apply: remove `newfd` from `struct apply_state`Martin Ågren, Oct 5, 2017
  46. 10/12 read-cache: drop explicit `CLOSE_LOCK`-flagMartin Ågren, Oct 5, 2017
  47. Junio C HamanoOct 6, 2017
  48. Martin ÅgrenOct 6, 2017
  49. 11/12 read-cache: leave lock in right state in `write_locked_index()`Martin Ågren, Oct 5, 2017
  50. Junio C HamanoOct 6, 2017
  51. Martin ÅgrenOct 6, 2017
  52. Junio C HamanoOct 6, 2017
  53. Martin ÅgrenOct 6, 2017
  54. 00/12 Re: various lockfile-leaks and -fixesMartin Ågren, Oct 6, 2017
  55. 01/12 sha1_file: do not leak `lock_file`Martin Ågren, Oct 6, 2017
  56. 02/12 treewide: prefer lockfiles on the stackMartin Ågren, Oct 6, 2017
  57. 04/12 tempfile: fix documentation on `delete_tempfile()`Martin Ågren, Oct 6, 2017
  58. 06/12 cache-tree: simplify locking logicMartin Ågren, Oct 6, 2017
  59. 05/12 checkout-index: simplify locking logicMartin Ågren, Oct 6, 2017
  60. 08/12 apply: remove `newfd` from `struct apply_state`Martin Ågren, Oct 6, 2017
  61. 09/12 cache.h: document `write_locked_index()`Martin Ågren, Oct 6, 2017
  62. 10/12 read-cache: drop explicit `CLOSE_LOCK`-flagMartin Ågren, Oct 6, 2017
  63. 12/12 read_cache: roll back lock in `update_index_if_able()`Martin Ågren, Oct 6, 2017
  64. 11/12 read-cache: leave lock in right state in `write_locked_index()`Martin Ågren, Oct 6, 2017
  65. 03/12 lockfile: fix documentation on `close_lock_file_gently()`Martin Ågren, Oct 6, 2017
  66. 07/12 apply: move lockfile into `apply_state`Martin Ågren, Oct 6, 2017
  67. 09/12 cache.h: document `write_locked_index()`Martin Ågren, Oct 5, 2017
  68. 12/12 read_cache: roll back lock in `update_index_if_able()`Martin Ågren, Oct 5, 2017
  69. 04/12 tempfile: fix documentation on `delete_tempfile()`Martin Ågren, Oct 5, 2017

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.