Line data Source code
1 : /*------------------------------------------------------------------------ 2 : * 3 : * wait_event_funcs.c 4 : * Functions for accessing wait event data. 5 : * 6 : * Portions Copyright (c) 1996-2024, 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 "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 8 : pg_get_wait_events(PG_FUNCTION_ARGS) 47 : { 48 : #define PG_GET_WAIT_EVENTS_COLS 3 49 8 : ReturnSetInfo *rsinfo = (ReturnSetInfo *) fcinfo->resultinfo; 50 : char **waiteventnames; 51 : int nbwaitevents; 52 : 53 : /* Build tuplestore to hold the result rows */ 54 8 : InitMaterializedSRF(fcinfo, 0); 55 : 56 : /* Iterate over the list of wait events */ 57 2120 : for (int idx = 0; waitEventData[idx].type != NULL; idx++) 58 : { 59 2112 : Datum values[PG_GET_WAIT_EVENTS_COLS] = {0}; 60 2112 : bool nulls[PG_GET_WAIT_EVENTS_COLS] = {0}; 61 : 62 2112 : values[0] = CStringGetTextDatum(waitEventData[idx].type); 63 2112 : values[1] = CStringGetTextDatum(waitEventData[idx].name); 64 2112 : values[2] = CStringGetTextDatum(waitEventData[idx].description); 65 : 66 2112 : tuplestore_putvalues(rsinfo->setResult, rsinfo->setDesc, values, nulls); 67 : } 68 : 69 : /* Handle custom wait events for extensions */ 70 8 : waiteventnames = GetWaitEventCustomNames(PG_WAIT_EXTENSION, 71 : &nbwaitevents); 72 : 73 10 : for (int idx = 0; idx < nbwaitevents; idx++) 74 : { 75 : StringInfoData buf; 76 2 : Datum values[PG_GET_WAIT_EVENTS_COLS] = {0}; 77 2 : bool nulls[PG_GET_WAIT_EVENTS_COLS] = {0}; 78 : 79 : 80 2 : values[0] = CStringGetTextDatum("Extension"); 81 2 : values[1] = CStringGetTextDatum(waiteventnames[idx]); 82 : 83 2 : initStringInfo(&buf); 84 2 : appendStringInfo(&buf, 85 : "Waiting for custom wait event \"%s\" defined by extension module", 86 2 : waiteventnames[idx]); 87 : 88 2 : values[2] = CStringGetTextDatum(buf.data); 89 : 90 2 : tuplestore_putvalues(rsinfo->setResult, rsinfo->setDesc, values, nulls); 91 : } 92 : 93 : /* Likewise for injection points */ 94 8 : waiteventnames = GetWaitEventCustomNames(PG_WAIT_INJECTIONPOINT, 95 : &nbwaitevents); 96 : 97 8 : 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 8 : return (Datum) 0; 118 : }