From 047f5a9fa5aafa03ac2015491bfdb9ba64b64aa0 Mon Sep 17 00:00:00 2001
From: Thomas Munro <thomas.munro@gmail.com>
Date: Sun, 3 Aug 2025 12:23:41 +1200
Subject: [PATCH v1 1/4] aio: Provide API support for synchronous fallback.

If an IO method can't submit an IO due to OS or internal limits, it
might choose to fall back to synchronous execution.  Provide a way for
it to set the PGAIO_HF_SYNCHRONOUS flag while advancing to
PGAIO_HS_SUBMITTED status, to make this behavior observable.

A follow-up commit will use this so users can see when io_method=worker
is falling back to synchronous execution, in the pg_aios view.

XXX Why do I seem to need the pg_read_barrier()?  Without it I
occasionally seem to lose the flag sometimes on my Mac under heavy
concurrency with io_method=posix_aio...
---
 src/backend/storage/aio/aio.c      | 15 +++++++++++++++
 src/include/storage/aio_internal.h |  1 +
 2 files changed, 16 insertions(+)

diff --git a/src/backend/storage/aio/aio.c b/src/backend/storage/aio/aio.c
index 3643f27ad6e..88a1991870b 100644
--- a/src/backend/storage/aio/aio.c
+++ b/src/backend/storage/aio/aio.c
@@ -511,6 +511,21 @@ pgaio_io_prepare_submit(PgAioHandle *ioh)
 	dclist_push_tail(&pgaio_my_backend->in_flight_ios, &ioh->node);
 }
 
+/*
+ * Handle IO that will be performed synchronously by IO method.
+ *
+ * Should be called by IO methods falling back to synchronous execution as a
+ * graceful fallback strategy if system resources are exceeded.
+ */
+void
+pgaio_io_prepare_submit_synchronously(PgAioHandle *ioh)
+{
+	pg_read_barrier();
+	ioh->flags |= PGAIO_HF_SYNCHRONOUS;
+
+	pgaio_io_prepare_submit(ioh);
+}
+
 /*
  * Handle IO getting completed by a method.
  *
diff --git a/src/include/storage/aio_internal.h b/src/include/storage/aio_internal.h
index 2d37a243abe..a8e1e442bb3 100644
--- a/src/include/storage/aio_internal.h
+++ b/src/include/storage/aio_internal.h
@@ -330,6 +330,7 @@ extern bool pgaio_io_was_recycled(PgAioHandle *ioh, uint64 ref_generation, PgAio
 extern void pgaio_io_stage(PgAioHandle *ioh, PgAioOp op);
 extern void pgaio_io_process_completion(PgAioHandle *ioh, int result);
 extern void pgaio_io_prepare_submit(PgAioHandle *ioh);
+extern void pgaio_io_prepare_submit_synchronously(PgAioHandle *ioh);
 extern bool pgaio_io_needs_synchronous_execution(PgAioHandle *ioh);
 extern const char *pgaio_io_get_state_name(PgAioHandle *ioh);
 const char *pgaio_result_status_string(PgAioResultStatus rs);
-- 
2.39.5 (Apple Git-154)

