Subject: Re: [take24 0/6] kevent: Generic event handling mechanism.

From: Ulrich Drepper <[email-masked]>
Date: Thu, 23 Nov 2006 14:23:12 -0800

Evgeniy Polyakov wrote:
> On Wed, Nov 22, 2006 at 02:22:15PM -0800, Ulrich Drepper ([email-masked]) wrote:
> Timeouts are not about AIO or any other event types (there are a lot of
> them already as you can see), it is only about syscall itself.
> Please point me to _any_ syscall out there which uses absolute time
> (except settimeofday() and similar syscalls).

futex(FUTEX_LOCK_PI).

> Btw, do you propose to change all users of wait_event()?

Which users?

> Interface is not restricted, it is just different from what you want it
> to be, and you did not show why it requires changes.

No, it is restricted because I cannot express something like an absolute 
timeout/deadline.  If the parameter would be a struct timespec* then at 
any time we can implement either relative timeouts w/ and w/out 
observance of settimeofday/ntp and absolute timeouts.  This is what 
makes the interface generic and unrestricted while your current version 
cannot be used for the latter.

> kevent signal registering is atomic with respect to other kevent
> syscalls: control syscalls are protected by mutex and waiting syscalls
> work with queue, which is protected by appropriate lock.

It is about atomicity wrt to the signal mask manipulation which would 
have to precede the kevent_wait call and the call itself (and 
registering a signal for kevent delivery).  This is not atomic.

> Let me formulate signal problem here, please point me if it is correct
> or not.

There are a myriad of different scenarios, it makes no sense to pick 
one.  The interface must be generic to cover them all, I don't know how 
often I have to repeat this.

> User registers some async signal notifications and calls poll() waiting
> for some file descriptors to became ready. When it is interrupted there
> is no knowledge about what really happend first - signal was delivered
> or file descriptor was ready.

The order is unimportant.  You change the signal mask, for instance, if 
the time when a thread is waiting in poll() is the only time when a 
signal can be handled.  Or vice versa, it's the time when signals are 
not wanted.  And these are per-thread decisions.

Signal handlers and kevent registrations for signals are process-wide 
decisions.  And furthermore: with kevent delivered signals there is no 
signal mask anymore (at least you seem to not check it).  Even if this 
would be done it doesn't change the fact that you cannot use signals the 
way many programs want to.

Fact is that without a signal queue you cannot implement the above 
cases.  You cannot block/unblock a signal for a specific thread.  You 
also cannot work together with signals which cannot be delivered through 
kevent.  This is the case for existing code in a program which happens 
to use also kevent and it is the case if there is more than one possible 
recipient.  With kevent signals can be attached to one kevent queue only 
but the recipients (different threads or only different parts of a 
program) need not use the same kevent queue.

I've said from the start that you cannot possibly expect that programs 
are not using signal delivery in the current form.  And the complete 
loss of blocking signals for individual threads makes the kevent-based 
signal delivery incomplete (in a non-fixable form) anyway.

> In case it is, let me explain why this situation can not happen with
> kevent: since signals are not delivered in the old way, but instead they
> are queued into the same queue where file descriptors are, and queueing
> is atomic, and pending signal mask is not updated, user will only read
> one event after another, which automatically (since delivery is atomic)
> means that what first was read, that was first happend.

This really has nothing to do with the problem.

> I posted a patch to implement kevent support for posix timers, it is
> quite simple in existing model. No need to remove anything,

Surely you don't suggest keeping your original timer patch?

> I implemented it to return -enosys for the case, when event type is
> smaller than maximum allowed and no subsystem is registered, and -einval 
> for the case, when requested type is higher.

What is the "maximum allowed"?  ENOSYS must be returned for all values 
which could potentially in future be used as a valid type value.  If you 
limit the values which are treated this way you are setting a fixed 
upper limit for the type values which _ever_ can be used.

> It is not about generalization, but about those who do practical work
> and those who prefer to spread theoretical thoughts, which result in
> several month of unused empty discussions.

I've told you, then don't work on these parts.  I'll get the changes I 
think are needed implemented by somebody else or I'll do it myself.  If 
you say that only those you implement something have a say in the way 
this is done then this is fine with me.  But you have to realize that 
you're not the one who will make all the final decisions.

-- 
➧ Ulrich Drepper ➧ Red Hat, Inc. ➧ 444 Castro St ➧ Mountain View, CA ❖