aboutsummaryrefslogtreecommitdiff
path: root/src/backend/utils/adt/waitfuncs.c
diff options
context:
space:
mode:
authorNoah Misch <noah@leadboat.com>2024-06-27 19:21:05 -0700
committerNoah Misch <noah@leadboat.com>2024-06-27 19:21:05 -0700
commitc35f419d6efbdf1a050250d84b687e6705917711 (patch)
treeabf864a4f7427a9c0a7db175f83e359582c95e3f /src/backend/utils/adt/waitfuncs.c
parentabfbd13af0e971e8789bc89e7c83ad53a85fa74b (diff)
downloadpostgresql-c35f419d6efbdf1a050250d84b687e6705917711.tar.gz
postgresql-c35f419d6efbdf1a050250d84b687e6705917711.zip
Add an injection_points isolation test suite.
Make the isolation harness recognize injection_points wait events as a type of blocked state. Test an extant inplace-update bug. Reviewed by Robert Haas and Michael Paquier. Discussion: https://postgr.es/m/20240512232923.aa.nmisch@google.com
Diffstat (limited to 'src/backend/utils/adt/waitfuncs.c')
-rw-r--r--src/backend/utils/adt/waitfuncs.c21
1 files changed, 19 insertions, 2 deletions
diff --git a/src/backend/utils/adt/waitfuncs.c b/src/backend/utils/adt/waitfuncs.c
index d9c92c3eee7..e135c9e5e45 100644
--- a/src/backend/utils/adt/waitfuncs.c
+++ b/src/backend/utils/adt/waitfuncs.c
@@ -14,8 +14,13 @@
#include "catalog/pg_type.h"
#include "storage/predicate_internals.h"
+#include "storage/proc.h"
+#include "storage/procarray.h"
#include "utils/array.h"
#include "utils/builtins.h"
+#include "utils/wait_event.h"
+
+#define UINT32_ACCESS_ONCE(var) ((uint32)(*((volatile uint32 *)&(var))))
/*
@@ -23,8 +28,9 @@
*
* Check if specified PID is blocked by any of the PIDs listed in the second
* argument. Currently, this looks for blocking caused by waiting for
- * heavyweight locks or safe snapshots. We ignore blockage caused by PIDs
- * not directly under the isolationtester's control, eg autovacuum.
+ * injection points, heavyweight locks, or safe snapshots. We ignore blockage
+ * caused by PIDs not directly under the isolationtester's control, eg
+ * autovacuum.
*
* This is an undocumented function intended for use by the isolation tester,
* and may change in future releases as required for testing purposes.
@@ -34,6 +40,8 @@ pg_isolation_test_session_is_blocked(PG_FUNCTION_ARGS)
{
int blocked_pid = PG_GETARG_INT32(0);
ArrayType *interesting_pids_a = PG_GETARG_ARRAYTYPE_P(1);
+ PGPROC *proc;
+ const char *wait_event_type;
ArrayType *blocking_pids_a;
int32 *interesting_pids;
int32 *blocking_pids;
@@ -43,6 +51,15 @@ pg_isolation_test_session_is_blocked(PG_FUNCTION_ARGS)
int i,
j;
+ /* Check if blocked_pid is in an injection point. */
+ proc = BackendPidGetProc(blocked_pid);
+ if (proc == NULL)
+ PG_RETURN_BOOL(false); /* session gone: definitely unblocked */
+ wait_event_type =
+ pgstat_get_wait_event_type(UINT32_ACCESS_ONCE(proc->wait_event_info));
+ if (wait_event_type && strcmp("InjectionPoint", wait_event_type) == 0)
+ PG_RETURN_BOOL(true);
+
/* Validate the passed-in array */
Assert(ARR_ELEMTYPE(interesting_pids_a) == INT4OID);
if (array_contains_nulls(interesting_pids_a))