fix #I9K0TH gsql补全功能被中断导致内存泄露

This commit is contained in:
Ziming Zhang
2024-04-26 18:06:33 +08:00
committed by yaoxin
parent c5e0f61072
commit 71edf8c7ac
4 changed files with 23 additions and 2 deletions

View File

@ -271,6 +271,8 @@ sigjmp_buf sigint_interrupt_jmp;
static PGcancel* volatile cancelConn = NULL;
volatile ReadlineStatus readline_status = WAIT_INPUT;
#ifdef WIN32
static CRITICAL_SECTION cancelConnLock;
#endif
@ -290,7 +292,7 @@ static void handle_sigint(SIGNAL_ARGS)
ResetQueryRetryController();
/* if we are waiting for input, longjmp out of it */
if (sigint_interrupt_enabled) {
if (sigint_interrupt_enabled && readline_status == WAIT_INPUT) {
sigint_interrupt_enabled = false;
siglongjmp(sigint_interrupt_jmp, 1);
}
@ -311,6 +313,10 @@ static void handle_sigint(SIGNAL_ARGS)
}
}
if (readline_status == WAIT_INPUT) {
readline_status = COMPLETE_CANCELLED;
}
errno = save_errno; /* just in case the write changed it */
}

View File

@ -74,6 +74,14 @@ extern volatile bool sigint_interrupt_enabled;
extern sigjmp_buf sigint_interrupt_jmp;
enum ReadlineStatus {
WAIT_INPUT,
COMPLETE_QUERY,
COMPLETE_CANCELLED
};
extern volatile ReadlineStatus readline_status;
extern volatile bool cancel_pressed;
/* Note: cancel_pressed is defined in print.c, see that file for reasons */

View File

@ -55,6 +55,9 @@ char* gets_interactive(const char* prompt, PQExpBuffer query_buf)
/* Enable SIGINT to longjmp to sigint_interrupt_jmp */
sigint_interrupt_enabled = true;
/* Make current input status to WAIT_INPUT */
readline_status = WAIT_INPUT;
/* On some platforms, readline is declared as readline(char *) */
result = readline((char*)prompt);

View File

@ -3173,6 +3173,8 @@ static char *_CompleteFromQuery(int isSchemaQuery, const char *text, int state)
PQclear(result);
result = NULL;
readline_status = COMPLETE_QUERY;
/* Set up suitably-escaped copies of textual inputs */
eText = (char *)pg_malloc(stringLength * 2 + 1);
PQescapeString(eText, text, stringLength);
@ -3300,7 +3302,7 @@ static char *_CompleteFromQuery(int isSchemaQuery, const char *text, int state)
}
/* Find something that matches */
if (result && PQresultStatus(result) == PGRES_TUPLES_OK) {
if (readline_status == COMPLETE_QUERY && result && PQresultStatus(result) == PGRES_TUPLES_OK) {
const char *item = NULL;
while (listIndex < PQntuples(result) && (item = PQgetvalue(result, listIndex++, 0)))
@ -3311,6 +3313,8 @@ static char *_CompleteFromQuery(int isSchemaQuery, const char *text, int state)
/* If nothing matches, free the db structure and return null */
PQclear(result);
result = NULL;
readline_status = WAIT_INPUT;
return NULL;
}