Git development
 help / color / mirror / Atom feed
From: "Michael Montalbo via GitGitGadget" <gitgitgadget@gmail.com>
To: git@vger.kernel.org
Cc: Patrick Steinhardt <ps@pks.im>,
	Michael Montalbo <mmontalbo@gmail.com>,
	Michael Montalbo <mmontalbo@gmail.com>
Subject: [PATCH v3 3/3] t/lib-httpd: document writing concurrency-safe CGI helpers
Date: Thu, 13 Aug 2026 01:05:36 +0000	[thread overview]
Message-ID: <374d148f43036077c31c5a55ddb1b59da4d3a923.1786583137.git.gitgitgadget@gmail.com> (raw)
In-Reply-To: <pull.2171.v3.git.1786583137.gitgitgadget@gmail.com>

From: Michael Montalbo <mmontalbo@gmail.com>

The apply-one-time-script.sh and http-429.sh fixes share a root cause: a
CGI helper assumed it had a file to itself, when Apache can run the
helper for several requests at once. Document the atomic idioms that
avoid this next to where lib-httpd.sh installs the CGI scripts, so the
advice is in front of anyone adding another one.

The note describes the anti-pattern, a "test -f" check followed by a
separate action, and the two atomic alternatives these helpers now use:

 - "mkdir", which fails if the directory exists, to elect the first
   request (http-429.sh); and
 - "rm" without "-f", which fails once the file is gone, to consume a
   one-shot marker (apply-one-time-script.sh).

Signed-off-by: Michael Montalbo <mmontalbo@gmail.com>
---
 t/lib-httpd.sh | 13 +++++++++++++
 1 file changed, 13 insertions(+)

diff --git a/t/lib-httpd.sh b/t/lib-httpd.sh
index fc646447d5..f26e1594ab 100644
--- a/t/lib-httpd.sh
+++ b/t/lib-httpd.sh
@@ -159,6 +159,19 @@ prepare_httpd() {
 	mkdir -p "$HTTPD_DOCUMENT_ROOT_PATH"
 	cp "$TEST_PATH"/passwd "$HTTPD_ROOT_PATH"
 	cp "$TEST_PATH"/proxy-passwd "$HTTPD_ROOT_PATH"
+	# Apache runs each of these CGI scripts once per request. Apache can run one
+	# script for several requests at the same time. A helper that keeps state
+	# between requests must update that state with one atomic operation. A check
+	# and then a separate action is not safe: two requests can both pass the
+	# check before either one acts. Test the exit status of one atomic operation
+	# instead:
+	#   - "mkdir dir" fails if the directory exists, so only one request
+	#     succeeds. http-429.sh selects the first request this way.
+	#   - "rm marker" (without "-f") fails if the marker is gone, so only one
+	#     request consumes it. apply-one-time-script.sh claims its one-shot
+	#     marker this way.
+	# A scratch file name includes the process ID ($$), so concurrent requests
+	# do not overwrite each other's files.
 	install_script incomplete-length-upload-pack-v2-http.sh
 	install_script incomplete-body-upload-pack-v2-http.sh
 	install_script error-no-report.sh
-- 
gitgitgadget

      parent reply	other threads:[~2026-08-13  1:05 UTC|newest]

Thread overview: 25+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-07-08  2:59 [PATCH 0/3] t/lib-httpd: make CGI test helpers concurrency-safe Michael Montalbo via GitGitGadget
2026-07-08  2:59 ` [PATCH 1/3] t/lib-httpd: fix apply-one-time-script race under concurrent requests Michael Montalbo via GitGitGadget
2026-07-08 19:54   ` Junio C Hamano
2026-07-09 17:26     ` Michael Montalbo
2026-07-08  2:59 ` [PATCH 2/3] t/lib-httpd: make http-429 first-request check atomic Michael Montalbo via GitGitGadget
2026-07-08 19:58   ` Junio C Hamano
2026-07-08 20:02   ` Junio C Hamano
2026-07-09 18:10     ` Michael Montalbo
2026-07-08  2:59 ` [PATCH 3/3] t/README: document writing concurrency-safe helpers Michael Montalbo via GitGitGadget
2026-07-08 19:59   ` Junio C Hamano
2026-07-10 17:30 ` [PATCH v2 0/3] t/lib-httpd: make CGI test helpers concurrency-safe Michael Montalbo via GitGitGadget
2026-07-10 17:30   ` [PATCH v2 1/3] t/lib-httpd: fix apply-one-time-script race under concurrent requests Michael Montalbo via GitGitGadget
2026-08-04  8:03     ` Patrick Steinhardt
2026-08-07 16:29       ` Michael Montalbo
2026-07-10 17:30   ` [PATCH v2 2/3] t/lib-httpd: make http-429 first-request check atomic Michael Montalbo via GitGitGadget
2026-07-10 17:30   ` [PATCH v2 3/3] t/README: document writing concurrency-safe helpers Michael Montalbo via GitGitGadget
2026-08-04  8:03     ` Patrick Steinhardt
2026-08-07 16:51       ` Michael Montalbo
2026-08-10  6:06         ` Patrick Steinhardt
2026-08-02  3:02   ` [PATCH v2 0/3] t/lib-httpd: make CGI test helpers concurrency-safe Michael Montalbo
2026-08-03 21:55   ` Junio C Hamano
2026-08-13  1:05 ` [PATCH v3 " Michael Montalbo via GitGitGadget
2026-08-13  1:05   ` [PATCH v3 1/3] t/lib-httpd: fix apply-one-time-script race under concurrent requests Michael Montalbo via GitGitGadget
2026-08-13  1:05   ` [PATCH v3 2/3] t/lib-httpd: make http-429 first-request check atomic Michael Montalbo via GitGitGadget
2026-08-13  1:05   ` Michael Montalbo via GitGitGadget [this message]

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=374d148f43036077c31c5a55ddb1b59da4d3a923.1786583137.git.gitgitgadget@gmail.com \
    --to=gitgitgadget@gmail.com \
    --cc=git@vger.kernel.org \
    --cc=mmontalbo@gmail.com \
    --cc=ps@pks.im \
    /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