Skip to content

Commit 79e6d9a

Browse files
committed
Fix possible spinlock leakage
* Spinlock is held longer than it is allowed to be. * `heap_form_tuple()` may raise errors while the lock is being held, which could result in spinlock leakage. Thanks https://github.com/ocean-dot-li Close #46.
1 parent b80c692 commit 79e6d9a

File tree

1 file changed

+6
-2
lines changed

1 file changed

+6
-2
lines changed

pg_show_plans.c

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ typedef struct pgspCtx { /* Used as `funcctx->user_fctx` in pg_show_plans(). */
6868
pgspEntry *pgsp_tmp_entry; /* PGSP entry currently processing. */
6969
int curr_nest; /* Current nest level porcessing. */
7070
bool is_done; /* Done processing current PGSP entry? */
71+
int n_plans;
7172
} pgspCtx;
7273

7374
/* Function Prototypes */
@@ -611,6 +612,7 @@ pg_show_plans(PG_FUNCTION_ARGS)
611612
pgsp_ctx = (pgspCtx *)palloc(sizeof(pgspCtx));
612613
pgsp_ctx->is_done = true;
613614
pgsp_ctx->curr_nest = 0;
615+
pgsp_ctx->n_plans = 0;
614616
pgsp_ctx->hash_seq = (HASH_SEQ_STATUS *)palloc(sizeof(HASH_SEQ_STATUS));
615617
hash_seq_init(pgsp_ctx->hash_seq, pgsp_hash);
616618
funcctx->user_fctx = (void *)pgsp_ctx;
@@ -663,6 +665,8 @@ pg_show_plans(PG_FUNCTION_ARGS)
663665
call_cntr++;
664666
}
665667
SpinLockAcquire(&pgsp_tmp_entry->mutex);
668+
pgsp_ctx->n_plans = pgsp_tmp_entry->n_plans;
669+
SpinLockRelease(&pgsp_tmp_entry->mutex);
666670
}
667671

668672
/* A single hash entry may store multiple (nested) plans, so
@@ -679,15 +683,15 @@ pg_show_plans(PG_FUNCTION_ARGS)
679683
values[4] = CStringGetTextDatum(pgsp_tmp_entry->plan + offset);
680684
htup = heap_form_tuple(funcctx->tuple_desc, values, nulls);
681685

682-
if (curr_nest < pgsp_tmp_entry->n_plans-1)
686+
if (curr_nest < pgsp_ctx->n_plans - 1)
683687
{ /* Still have nested plans. */
684688
curr_nest++;
685689
call_cntr--; /* May not be legal, but it works. */
686690
is_done = false;
687691
} else { /* No more nested plans, get a new entry. */
688692
curr_nest = 0;
689693
is_done = true;
690-
SpinLockRelease(&pgsp_tmp_entry->mutex);
694+
pgsp_ctx->n_plans = 0;
691695
}
692696
/* Save values back to the context. */
693697
pgsp_ctx->is_done = is_done;

0 commit comments

Comments
 (0)