osvenskan / posix_ipc

Other
135 stars 24 forks source link

message queue raise exception when receives a signal #30

Closed GreatBahram closed 1 year ago

GreatBahram commented 3 years ago

Hi there,

When I use a signal inside my program, the posix_ipc.MessageQueue object raises a posix_ipc.SignalError exception; I believe this is different from what we normally expect, example program to show this problem:

import os
import signal

import posix_ipc

def receive_handler(signal, stack):
    print(f"Received signal: {signal}")

q = posix_ipc.MessageQueue("/test", flags=posix_ipc.O_CREAT)

signal.signal(signal.SIGUSR1, receive_handler)

print(f'Runing (PID: {os.getpid()}) ...')
q.receive()

After running this program, if you send a signal with another process, let's say with kill command:

 kill -s USR1 5426

You get:

Running (PID: 5426) ...
Received signal: 10
Traceback (most recent call last):
  File "/home/bahram/.virtualenvs/tmp-1237b73b1e1465c/main.py", line 16, in <module>
    q.receive()
posix_ipc.SignalError: The wait was interrupted by a signal

Comparing this to other queues like queue.Queue they catch the signal and after doing the sigaction continue their functionality.

osvenskan commented 2 years ago

Hi @GreatBahram, I'm very sorry for letting this issue sit for so long. I don't think I realized you had opened it.

I didn't know about this behavior of queue.Queue when I wrote this code. It didn't even occur to me to try to make posix_ipc.MessageQueue behave like queue.Queue. In any case, posix_ipc.MessageQueue has behaved this way for 13 years now and I wouldn't want to break anyone's code that relies on this behavior.

In addition, it would be difficult to mimic the queue.Queue behavior. When the user calls mq.receive() with a timeout, the posix_ipc code calls the C function mq_timedreceive(). If a signal occurs, that call ends, and errno is set to EINTR. If I wanted to mimic queue.Queue's behavior, it sounds like I'd have to call mq_timedreceive() again, but I wouldn't know how long the first call had waited so the timing would be wrong.

To summarize, I thank you for the interesting suggestion, but I'm not going to make this change.