Line data Source code
1 : /*------------------------------------------------------------------------
2 : *
3 : * wait_event_funcs.c
4 : * Functions for accessing wait event data.
5 : *
6 : * Portions Copyright (c) 1996-2026, PostgreSQL Global Development Group
7 : * Portions Copyright (c) 1994, Regents of the University of California
8 : *
9 : *
10 : * IDENTIFICATION
11 : * src/backend/utils/activity/wait_event_funcs.c
12 : *
13 : *------------------------------------------------------------------------
14 : */
15 : #include "postgres.h"
16 :
17 : #include "funcapi.h"
18 : #include "utils/builtins.h"
19 : #include "utils/tuplestore.h"
20 : #include "utils/wait_event.h"
21 :
22 : /*
23 : * Each wait event has one corresponding entry in this structure, fed to
24 : * the SQL function of this file.
25 : */
26 : static const struct
27 : {
28 : const char *type;
29 : const char *name;
30 : const char *description;
31 : }
32 :
33 : waitEventData[] =
34 : {
35 : #include "utils/wait_event_funcs_data.c"
36 : /* end of list */
37 : {NULL, NULL, NULL}
38 : };
39 :
40 :
41 : /*
42 : * pg_get_wait_events
43 : *
44 : * List information about wait events (type, name and description).
45 : */
46 : Datum
47 5 : pg_get_wait_events(PG_FUNCTION_ARGS)
48 : {
49 : #define PG_GET_WAIT_EVENTS_COLS 3
50 5 : ReturnSetInfo *rsinfo = (ReturnSetInfo *) fcinfo->resultinfo;
51 : char **waiteventnames;
52 : int nbwaitevents;
53 :
54 : /* Build tuplestore to hold the result rows */
55 5 : InitMaterializedSRF(fcinfo, 0);
56 :
57 : /* Iterate over the list of wait events */
58 1445 : for (int idx = 0; waitEventData[idx].type != NULL; idx++)
59 : {
60 1440 : Datum values[PG_GET_WAIT_EVENTS_COLS] = {0};
61 1440 : bool nulls[PG_GET_WAIT_EVENTS_COLS] = {0};
62 :
63 1440 : values[0] = CStringGetTextDatum(waitEventData[idx].type);
64 1440 : values[1] = CStringGetTextDatum(waitEventData[idx].name);
65 1440 : values[2] = CStringGetTextDatum(waitEventData[idx].description);
66 :
67 1440 : tuplestore_putvalues(rsinfo->setResult, rsinfo->setDesc, values, nulls);
68 : }
69 :
70 : /* Handle custom wait events for extensions */
71 5 : waiteventnames = GetWaitEventCustomNames(PG_WAIT_EXTENSION,
72 : &nbwaitevents);
73 :
74 6 : for (int idx = 0; idx < nbwaitevents; idx++)
75 : {
76 : StringInfoData buf;
77 1 : Datum values[PG_GET_WAIT_EVENTS_COLS] = {0};
78 1 : bool nulls[PG_GET_WAIT_EVENTS_COLS] = {0};
79 :
80 :
81 1 : values[0] = CStringGetTextDatum("Extension");
82 1 : values[1] = CStringGetTextDatum(waiteventnames[idx]);
83 :
84 1 : initStringInfo(&buf);
85 1 : appendStringInfo(&buf,
86 : "Waiting for custom wait event \"%s\" defined by extension module",
87 1 : waiteventnames[idx]);
88 :
89 1 : values[2] = CStringGetTextDatum(buf.data);
90 :
91 1 : tuplestore_putvalues(rsinfo->setResult, rsinfo->setDesc, values, nulls);
92 : }
93 :
94 : /* Likewise for injection points */
95 5 : waiteventnames = GetWaitEventCustomNames(PG_WAIT_INJECTIONPOINT,
96 : &nbwaitevents);
97 :
98 5 : for (int idx = 0; idx < nbwaitevents; idx++)
99 : {
100 : StringInfoData buf;
101 0 : Datum values[PG_GET_WAIT_EVENTS_COLS] = {0};
102 0 : bool nulls[PG_GET_WAIT_EVENTS_COLS] = {0};
103 :
104 :
105 0 : values[0] = CStringGetTextDatum("InjectionPoint");
106 0 : values[1] = CStringGetTextDatum(waiteventnames[idx]);
107 :
108 0 : initStringInfo(&buf);
109 0 : appendStringInfo(&buf,
110 : "Waiting for injection point \"%s\"",
111 0 : waiteventnames[idx]);
112 :
113 0 : values[2] = CStringGetTextDatum(buf.data);
114 :
115 0 : tuplestore_putvalues(rsinfo->setResult, rsinfo->setDesc, values, nulls);
116 : }
117 :
118 5 : return (Datum) 0;
119 : }
|