Skip to content

Commit 6c8b103

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 98c2a09 commit 6c8b103

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 */
@@ -579,6 +580,7 @@ pg_show_plans(PG_FUNCTION_ARGS)
579580
pgsp_ctx = (pgspCtx *)palloc(sizeof(pgspCtx));
580581
pgsp_ctx->is_done = true;
581582
pgsp_ctx->curr_nest = 0;
583+
pgsp_ctx->n_plans = 0;
582584
pgsp_ctx->hash_seq = (HASH_SEQ_STATUS *)palloc(sizeof(HASH_SEQ_STATUS));
583585
hash_seq_init(pgsp_ctx->hash_seq, pgsp_hash);
584586
funcctx->user_fctx = (void *)pgsp_ctx;
@@ -631,6 +633,8 @@ pg_show_plans(PG_FUNCTION_ARGS)
631633
call_cntr++;
632634
}
633635
SpinLockAcquire(&pgsp_tmp_entry->mutex);
636+
pgsp_ctx->n_plans = pgsp_tmp_entry->n_plans;
637+
SpinLockRelease(&pgsp_tmp_entry->mutex);
634638
}
635639

636640
/* A single hash entry may store multiple (nested) plans, so
@@ -647,15 +651,15 @@ pg_show_plans(PG_FUNCTION_ARGS)
647651
values[4] = CStringGetTextDatum(pgsp_tmp_entry->plan + offset);
648652
htup = heap_form_tuple(funcctx->tuple_desc, values, nulls);
649653

650-
if (curr_nest < pgsp_tmp_entry->n_plans-1)
654+
if (curr_nest < pgsp_ctx->n_plans - 1)
651655
{ /* Still have nested plans. */
652656
curr_nest++;
653657
call_cntr--; /* May not be legal, but it works. */
654658
is_done = false;
655659
} else { /* No more nested plans, get a new entry. */
656660
curr_nest = 0;
657661
is_done = true;
658-
SpinLockRelease(&pgsp_tmp_entry->mutex);
662+
pgsp_ctx->n_plans = 0;
659663
}
660664
/* Save values back to the context. */
661665
pgsp_ctx->is_done = is_done;

0 commit comments

Comments
 (0)