On Mon, Feb 24 2020 10:42:22 +0100, Martin Pieuchot wrote:
> On 24/02/20(Mon) 11:29, Lauri Tirkkonen wrote:
> > On Mon, Feb 24 2020 10:24:53 +0100, Martin Pieuchot wrote:
> > > On 23/02/20(Sun) 14:48, Lauri Tirkkonen wrote:
> > > > I was working on a make jobserver implementation that uses POSIX
> > > > semaphores as job tokens instead of a complicated socket-based approach.
> > > > Initially I used named semaphores, which work fine, except if child
> > > > processes with less privileges need to also open the named semaphore
> > > > (eg. 'make build' as root executing 'su build -c make'). For that reason
> > > > I wanted to use an unnamed semaphore (sem_init()) which is stored in shm
> > > > -- that way I could leave the shm fd open and pass it to children.
> > > > 
> > > > But unfortunately, sem_t is currently just a pointer to the opaque
> > > > struct __sem, and sem_int() always calloc()s the storage for the struct.
> > > 
> > > That's by design.
> > 
> > Ok - could you elaborate what the design is?
> 
> If the size of a descriptor change, because some fields are added and/or
> removed, it doesn't matter for the application because it only manipulates
> pointers.  That means we can change the data types without creating an ABI
> break.

I understand this, that's why I bumped the major and build-tested it.

What I don't understand is how an application could ever share a
semaphore with another process without sharing the userspace structure
that contains the important bits. As I mentioned, NetBSD works around
that in the pshared case by stuffing a kernel semaphore identifier into
the sem_t* returned by sem_init -- essentially, that identifier becomes
the only important bit and no storage is allocated, but from the
application point of view, sem_t must still be shared with another
process through shm otherwise (only now it's only a pointer that is used
to hold an integer value).

> > > > This means the application cannot control where unnamed semaphores are
> > > > stored, so I can't put it in shm.
> > > 
> > > Are you trying to use semaphore shared between process?  Did you called
> > > sem_init() with pshared=1?  Have you seen that the current implementation
> > > doesn't support them?
> > 
> > Yes, that's what I'm trying to do. Yes, I've seen the current
> > implementation -- that's why I started this thread, in an attempt to
> > make them supported. :)
> > 
> > See the followup patch -- sharing the semaphore between processes does
> > work with it.
> 
> Well ignoring the `pshared' argument is questionable.  Why don't you
> remove the "#if notyet" and start playing with the existing code and
> try to figure out if something is missing for your use case?

I did read the existing code behind the #ifdef notyet, and even found a
commit from 2013 disabling the code (by adding the #ifdef) "until it
really works". It seems to me that time has not come.

I don't understand how the pshared case under #ifdef notyet was even
supposed to work. It seems to just turn an unnamed semaphore into a
randomly-named semaphore, but provides no way for the application to
share it with another process; if the application puts sem_t in shm,
only a pointer is now in shm -- the struct __sem is not. Named
semaphores at least can be opened by other processes if they know the
name, but randomly-named semaphores that are unlinked after creation can
certainly not.

-- 
Lauri Tirkkonen | lotheac @ IRCnet

Reply via email to