Opened 17 years ago

Closed 17 years ago

Last modified 17 years ago

#1596 closed bug (invalid)

Semaphore acquisition is not interrupted by a signal in the kernel

Reported by: jackburton Owned by: axeld
Priority: normal Milestone: R1
Component: System/Kernel Version: R1/pre-alpha1
Keywords: Cc:
Blocked By: Blocking:
Platform: All

Description

I'm not sure if my code is incorrect, but I suppose this should work. If a thread is acquiring a semaphore with infinite timeout, and another thread sends a signal to it, shouldn't the semaphore acquisition be interrupted ? If it should, then it's not working correctly. Attached is some code which shows the situation I'm talking about.

Attachments (1)

test.c (419 bytes ) - added by jackburton 17 years ago.

Download all attachments as: .zip

Change History (9)

by jackburton, 17 years ago

Attachment: test.c added

comment:1 by bonefish, 17 years ago

The attached code has a few issues -- maybe you just introduced them when turning this into a postable example? Besides the missing headers and using spawn_kernel_thread() (although it otherwise looks like a userland example), foo_thread() actually waits more than three weeks. When fixing the issues, the test works just fine with hrev22765.

To answer the question in the code: If no SIGINT handler is installed, the main thread will commit suicide before returning from the syscall.

in reply to:  1 comment:2 by jackburton, 17 years ago

Replying to bonefish:

The attached code has a few issues -- maybe you just introduced them when turning this into a postable example?

Indeed. The actual code is very different, but I had to "camouflage" it...

Besides the missing headers and using spawn_kernel_thread() (although it otherwise >looks like a userland example), foo_thread() actually waits more than three weeks. >When fixing the issues, the test works just fine with hrev22765.

I'll post the complete code when I get to the other machine. Thank you for your help.

in reply to:  1 ; comment:3 by jackburton, 17 years ago

Replying to bonefish:

To answer the question in the code: If no SIGINT handler is installed, the main thread will commit suicide before returning from the syscall.

Oh, that's probably what happens in my case, then. Seeing no advancement in the syslog, I thought the thread was blocked, while probably it was simply dead. Is there a way to simply interrupt the semaphore acquisition ? I guess in that case acquire_sem_etc() would return B_INTERRUPTED or B_WOULD_BLOCK ?

comment:4 by axeld, 17 years ago

You can either change the behaviour of SIGINT, or alternatively, just call suspend_thread()/resume_thread(). I guess we can close this ticket?

comment:5 by jackburton, 17 years ago

Resolution: fixed
Status: newclosed

Absolutely! Thank you!

comment:6 by jackburton, 17 years ago

Resolution: fixed
Status: closedreopened

comment:7 by jackburton, 17 years ago

Resolution: invalid
Status: reopenedclosed

in reply to:  3 comment:8 by bonefish, 17 years ago

Replying to jackburton:

Is there a way to simply interrupt the semaphore acquisition ? I guess in that case acquire_sem_etc() would return B_INTERRUPTED or B_WOULD_BLOCK ?

It would return B_INTERRUPTED.

BTW, although Axel says, it's common practice, I don't think I've ever needed to interrupt a thread in such a way. The suspend_thread()/resume_thread() trick might introduce a race condition (if the thread in question is not yet waiting on the semaphore, it will have no effect). A common situation when one needs to wake up a thread potentially blocking on a semaphore or port is a program (or subsystem) termination. But then deleting the semaphore/port usually does the trick. Or set a flag + release it.

In Haiku I introduced the new experimental wait_for_objects(). It can be used to wait for events on multiple semaphores, ports, threads, and FDs. If your case is not just a termination situation, but rather waiting for two events, wait_for_objects() might be exactly what you want to use.

Note: See TracTickets for help on using tickets.