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