1
0
mirror of https://github.com/postgres/postgres.git synced 2025-11-19 13:42:17 +03:00

Redesign interrupt/cancel API for regex engine.

Previously, a PostgreSQL-specific callback checked by the regex engine
had a way to trigger a special error code REG_CANCEL if it detected that
the next call to CHECK_FOR_INTERRUPTS() would certainly throw via
ereport().

A later proposed bugfix aims to move some complex logic out of signal
handlers, so that it won't run until the next CHECK_FOR_INTERRUPTS(),
which makes the above design impossible unless we split
CHECK_FOR_INTERRUPTS() into two phases, one to run logic and another to
ereport().  We may develop such a system in the future, but for the
regex code it is no longer necessary.

An earlier commit moved regex memory management over to our
MemoryContext system.  Given that the purpose of the two-phase interrupt
checking was to free memory before throwing, something we don't need to
worry about anymore, it seems simpler to inject CHECK_FOR_INTERRUPTS()
directly into cancelation points, and just let it throw.

Since the plan is to keep PostgreSQL-specific concerns separate from the
main regex engine code (with a view to bein able to stay in sync with
other projects), do this with a new macro INTERRUPT(), customizable in
regcustom.h and defaulting to nothing.

Reviewed-by: Tom Lane <tgl@sss.pgh.pa.us>
Discussion: https://postgr.es/m/CA%2BhUKGK3PGKwcKqzoosamn36YW-fsuTdOPPF1i_rtEO%3DnEYKSg%40mail.gmail.com
This commit is contained in:
Thomas Munro
2023-04-08 21:57:46 +12:00
parent 6db75edb2e
commit db4f21e4a3
13 changed files with 18 additions and 104 deletions

View File

@@ -44,7 +44,7 @@
#include "mb/pg_wchar.h"
#include "miscadmin.h" /* needed by rcancelrequested/rstacktoodeep */
#include "miscadmin.h" /* needed by stacktoodeep */
/* overrides for regguts.h definitions, if any */
@@ -52,6 +52,7 @@
#define MALLOC(n) palloc_extended((n), MCXT_ALLOC_NO_OOM)
#define FREE(p) pfree(VS(p))
#define REALLOC(p,n) repalloc_extended(VS(p),(n), MCXT_ALLOC_NO_OOM)
#define INTERRUPT(re) CHECK_FOR_INTERRUPTS()
#define assert(x) Assert(x)
/* internal character type and related */

View File

@@ -81,7 +81,3 @@
{
REG_ECOLORS, "REG_ECOLORS", "too many colors"
},
{
REG_CANCEL, "REG_CANCEL", "operation cancelled"
},

View File

@@ -156,7 +156,6 @@ typedef struct
#define REG_BADOPT 18 /* invalid embedded option */
#define REG_ETOOBIG 19 /* regular expression is too complex */
#define REG_ECOLORS 20 /* too many colors */
#define REG_CANCEL 21 /* operation cancelled */
/* two specials for debugging and testing */
#define REG_ATOI 101 /* convert error-code name to number */
#define REG_ITOA 102 /* convert error-code number to name */

View File

@@ -77,6 +77,11 @@
#define FREE(p) free(VS(p))
#endif
/* interruption */
#ifndef INTERRUPT
#define INTERRUPT(re)
#endif
/* want size of a char in bits, and max value in bounded quantifiers */
#ifndef _POSIX2_RE_DUP_MAX
#define _POSIX2_RE_DUP_MAX 255 /* normally from <limits.h> */
@@ -510,13 +515,9 @@ struct subre
struct fns
{
void FUNCPTR(free, (regex_t *));
int FUNCPTR(cancel_requested, (void));
int FUNCPTR(stack_too_deep, (void));
};
#define CANCEL_REQUESTED(re) \
((*((struct fns *) (re)->re_fns)->cancel_requested) ())
#define STACK_TOO_DEEP(re) \
((*((struct fns *) (re)->re_fns)->stack_too_deep) ())