Subject: Re: Implementation of POSIX message queue
To: Mindaugas R. <rmind@NetBSD.org>
From: Andrew Doran <ad@netbsd.org>
List: tech-kern
Date: 08/23/2007 11:18:16
On Tue, Aug 21, 2007 at 11:15:13PM +0300, Mindaugas R. wrote:

> Andrew Doran <ad@netbsd.org> wrote:
> > Aside: I was looking at the spec and noticed that the following routines
> > need to be cancellation points:
> > <...>
> > This might be complicated slightly by having them in librt. I'm not sure
> > what the solution is.
> 
> What would be problematic?

The symbols need to be overridden in libpthread, but librt need not be
loaded in order to load libpthread. libc must always be loaded for
libpthread to work, and currently it only overrides symbols from libc. I
don't know what will happen.
 
> > But it doesn't buy you anything. What it tells you is that the system call
> > might fail with EFAULT, or that it may work and not return EFAULT - but
> > that's always going to be the case!
> > <...>
> 
> Understood the point :)
> 
> > I can think of a few options:
> > 
> > o Hold the entire message queue locked while copying out the message. That
> >   sucks, but if the copyout() fails we can leave the message there.
> > 
> > o Have a receiver lock on the queue and hold it while copying out. Again
> >   that's not nice, but it means messages could still be pushed onto the
> >   queue while you're copying out.
> > 
> > o If POSIX does not dictate a strict order for messages pushed onto and
> >   popped off the queue, then if the copyout fails we can re-enqueue the
> >   message at an advantageous spot (so it gets taken off the queue by
> >   another receiver sooner rather than later).
> 
> According to specification: "The mq_receive() function shall receive the
> oldest of the highest priority message(s) <...>". So after the re-enqueue the
> order of messages might change. I tend to think that receiver lock would be a
> better solution.

After giving it some thought I'm of the opinion that if the copyout returns
an error then the message should just be thrown away. There are so many
things that can go wrong once the message has been dequeued that I don't
think it's worth worrying about it. If the message must be seen, then the
application needs to have some sort of transactional capability and that's
beyond the scope of (this) message queue interface. As long as the
application sees EFAULT then I personally don't see a problem with it.

> Jason Thorpe <thorpej@shagadelic.org> wrote:
> > > b) Allocate a file structure and use it for a mqueue. It would be  
> > > good for
> > >    copying the descriptors on fork(), currently it looks quite weird  
> > > for me
> > >    (see mqueue_proc_fork(), FIXME mark). However, this would need some
> > >    workaround for fileops and other calls - is it worth?
> > 
> > Yes, I think (b) is the right choice.
> 
> Reasonable, but in such case a good way to prevent the usage of fileops is
> needed. Few things:
> - Can invention of stubs for fileops be avoided?

There are already a few null operations (fnullop_fcntl and so on). I don't
think it would hurt to add the remaining ones.

> - How about inventing DTYPE_NONE? Actually, most of the system calls will
>   fail if file::f_type != DTYPE_VNODE, and file::f_flag == 0.

Anything wrong with DTYPE_MQUEUE?

Thanks,
Andrew