#3975 new enhancement

RTEMS 5 : sem_wait + sem_destroy behavior change

Reported by: andrei.lupas Owned by:
Priority: normal Milestone: 5.2
Component: posix Version: 5
Severity: normal Keywords:
Cc: Blocked By:
Blocking:

Description

Hello,

With previous versions of RTEMS:
a blocking sem_wait() could be broken immediately via a successful sem_destroy done from another thread (sem_wait deblocks with return code -1, and errno == EINVAL).

With latest RTEMS:
sem_destroy doesn't succeed anymore, but returns EBUSY (since another thread executes a wait on it)

This behavior change breaks some of existing code.

Would it be possible to add an RTEMS config to allow user to select between OLD and NEW behavior ? (alternative is to move from POSIX sems to classic API and use rtems_semaphore_flush).

Thanks,
Andrei Lupas.

Change History (8)

comment:1 Changed on May 7, 2020 at 1:02:57 PM by Joel Sherrill

The current behavior is what is specified in the POSIX standard:

https://pubs.opengroup.org/onlinepubs/9699919799.2008edition/functions/sem_destroy.html

[EBUSY]
There are currently processes blocked on the semaphore.

It is a shame that the signature does not have an attribute structure, that would make it easy to at least add the behavior option at the API level. This signature does not give any room for change:

int sem_init(sem_t *sem, int pshared, unsigned value);

Adding a flush operation to the POSIX semaphores could be an option but sem_wait() is not defined to return any errno values which make sense for a flush. But if sem_flush_np() were added, then using another errno to indicate it was flushed by a non-portable (e.g. _np) method is at least an option.

Another option is to add a sem_XXX_np method to set the "allow delete when blocked threads" internal attribute. In this case, the threads unblocked by deleting the semaphore could return EINVAL like other POSIX methods do when the object id is invalid.

I'm just offering options within the space of the POSIX standard. The second seems like a cleaner direct solution to your problem. This is a counting semaphore and there is no concept of a "holder" as with a mutex. Besides threads waiting on a resource, do not hold the resource.

Hoping others will chime in.

comment:2 Changed on May 7, 2020 at 6:25:05 PM by andrei.lupas

Indeed, behavior is according to POSIX spec, but in the "undefined" area
"The effect of destroying a semaphore upon which other threads are currently blocked is undefined."
In this case, the "undefined" behavior changed from SUCCESS to error:EBUSY, and this impacts some existing apps.
On short term, I suppose I need to move to classic API semaphores.
Thanks a lot for the prompt feedback.
Andrei.

comment:3 in reply to:  2 Changed on May 7, 2020 at 6:29:42 PM by Joel Sherrill

Replying to andrei.lupas:

Indeed, behavior is according to POSIX spec, but in the "undefined" area
"The effect of destroying a semaphore upon which other threads are currently blocked is undefined."
In this case, the "undefined" behavior changed from SUCCESS to error:EBUSY, and this impacts some existing apps.

Can you cite where you found that undefined behavior citation? I looked at the Change History section for the methods I thought this would be in and don't see it.

Knowing when the behavior changed and being able to cite something would lend strength to providing a way to get the alternative behavior. I lean to it changing on a per semaphore instance basis rather than a single flag changing it for all.

On short term, I suppose I need to move to classic API semaphores.
Thanks a lot for the prompt feedback.

No problem.

Andrei.

comment:4 Changed on May 8, 2020 at 4:51:39 AM by Sebastian Huber

The "The effect of destroying a semaphore upon which other threads are currently blocked is undefined." is the current sem_destroy() description. The POSIX semaphores are now self-contained. This means the storage space is provided and maintained by the user. Destruction of a semaphore in use could indicate that someone is trying to use an object while it is destroyed (e.g. deallocated).

What we could do (since "The effect of destroying a semaphore upon which other threads are currently blocked is undefined.") is to flush the semaphore so that callers get woken up with EINVAL, we destroy the object and return EBUSY.

comment:5 in reply to:  4 Changed on May 8, 2020 at 6:09:57 AM by andrei.lupas

Replying to Sebastian Huber:
...

What we could do (since "The effect of destroying a semaphore upon which other threads are currently blocked is undefined.") is to flush the semaphore so that callers get woken up with EINVAL, we destroy the object and return EBUSY.

Sounds good to me.
Thanks.

comment:6 Changed on May 8, 2020 at 6:11:51 AM by Sebastian Huber

If you would like to get this changed, then please send a patch to devel@… which includes changes in the test suite.

comment:7 Changed on May 18, 2020 at 6:57:01 AM by Chris Johns

Component: adminposix

Can someone please update the milestone for this ticket?

comment:8 Changed on May 18, 2020 at 7:06:18 AM by Sebastian Huber

Milestone: 5.2
Note: See TracTickets for help on using tickets.