[pgpool-hackers: 3902] Re: sigusr1_interrupt_processor() does not process all pending requests
Tatsuo Ishii
ishii at sraoss.co.jp
Sat May 22 13:06:22 JST 2021
>> Looking into the code of sigusr1_interrupt_processor(), it seems
>> sigusr1_interrupt_processor() is assumed that it processes all the
>> request details in sigalFlags array even if there are multiple details
>> in the array. But actually it's not.
>
> I confirmed that sigusr1_interrupt_processor() can handle multiple
> requests. That's good. However there are race condition which could
> cause this:
>
>> t-ishii$ grep signalFlags pgpool[0-2]/log/pgpool.log
>> pgpool1/log/pgpool.log:2021-05-18 15:25:58: main pid 12696: LOG: signalFlags: 3 is true
>> pgpool2/log/pgpool.log:2021-05-18 15:25:58: main pid 12700: LOG: signalFlags: 3 is true
>> pgpool2/log/pgpool.log:2021-05-18 15:26:04: main pid 12700: LOG: signalFlags: 3 is true
>
> Because while or after execution of sigusr1_interrupt_processor(),
> other process can register new requests into the signalFlags array
> because there is no interlocking mechanism between the signal sender
> signal_user1_to_parent_with_reason() and
> sigusr1_interrupt_processor().
>
>> I don't know if this actually gives some bad effects to pgpool or not
>> but I think at least we need to confirm that.
>
> It does. In CHECK_REQUEST:
>
> if (sigusr1_request) \
> { \
> sigusr1_interrupt_processor(); \
> sigusr1_request = 0; \
>
> If other process sends SIGUSR1 while sigusr1_interrupt_processor() is
> running, sigusr1_request is set to 1 by the signal handler. But after that:
>
> sigusr1_request = 0; \
>
> is executed and sigusr1_interrupt_processor() will not be called until
> the next signal arrives. If the next signal does not arrive or arrives
> after long period, that would be a problem.
>
> To fix it, I think the code fragment above should be changed like
> this:
>
> if (sigusr1_request) \
> { \
> do {\
> sigusr1_request = 0; \
> sigusr1_interrupt_processor(); \
> } while (sigusr1_request == 1); \
> } \
>
> This way, the condition statement (sigusr1_request == 1) will catch
> the arrival of the signal while sigusr1_interrupt_processor() was
> running, and it will be processed next execution of
> sigusr1_interrupt_processor().
>
> Note that similar code fragment also exists in Pgpoolmain. This also
> should be changed to:
>
> if (sigusr1_request)
> {
> do {
> sigusr1_request = 0;
> sigusr1_interrupt_processor();
> } while (sigusr1_request == 1);
> }
>
> Also I have changed some log message level from DEBUG1 to LOG because
> they are important information.
>
> Comments are welcome.
Fix pushed to master and all supported branches.
Best regards,
--
Tatsuo Ishii
SRA OSS, Inc. Japan
English: http://www.sraoss.co.jp/index_en.php
Japanese:http://www.sraoss.co.jp
More information about the pgpool-hackers
mailing list