2002-06-25 16:32:48

by Amos Waterland

[permalink] [raw]
Subject: O_ASYNC question

The man page for fcntl() says:

If you set the O_ASYNC status flag on a file descriptor (either by
providing this flag with the open(2) call, or by using the F_SETFL
command of fcntl), a SIGIO signal is sent whenever input or output
becomes possible on that file descriptor.

On a 2.4.18 kernel, this test program waits forever in sigwaitinfo():

#include <fcntl.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

int main(int argc, char *argv[])
{
const int BYTES = 5000000;
int i, fd;
char buff[BYTES];
char name[] = "/tmp/aio8.XXXXXX";
sigset_t sigset;
siginfo_t siginfo;

if ((fd = open(name, O_CREAT|O_WRONLY|O_NONBLOCK|O_ASYNC, 0600)) < 0 ||
unlink(name)) {
perror("creating temp file"); exit(1);
}

for (i = 0; i < BYTES; i++) buff[i] = 'Z';

if (sigemptyset(&sigset) || sigaddset(&sigset, SIGIO) ||
sigprocmask(SIG_BLOCK, &sigset, NULL)) {
perror("setting up signal mask"); exit(2);
}

if (write(fd, buff, BYTES) < 0) {
perror("writing to temp file"); exit(3);
}

printf("recv sig: %i\n", sigwaitinfo(&sigset, &siginfo));

return 0;
}

Shouldn't SIGIO be raised when the write() completes? (Is O_ASYNC only
valid for sockets, maybe?) Thanks in advance.

Amos Waterland


2002-06-26 21:12:04

by William Lee Irwin III

[permalink] [raw]
Subject: Re: O_ASYNC question

On Tue, Jun 25, 2002 at 11:30:52AM -0500, Amos Waterland wrote:
> The man page for fcntl() says:
> If you set the O_ASYNC status flag on a file descriptor (either by
> providing this flag with the open(2) call, or by using the F_SETFL
> command of fcntl), a SIGIO signal is sent whenever input or output
> becomes possible on that file descriptor.

Not done for files and you need fsetown() for sockets and tty's.


Cheers,
Bill

2002-06-26 21:38:31

by Amos Waterland

[permalink] [raw]
Subject: Re: O_ASYNC question

On Wed, Jun 26, 2002 at 02:11:22PM -0700, William Lee Irwin III wrote:
> On Tue, Jun 25, 2002 at 11:30:52AM -0500, Amos Waterland wrote:
> > The man page for fcntl() says:
> > If you set the O_ASYNC status flag on a file descriptor (either by
> > providing this flag with the open(2) call, or by using the F_SETFL
> > command of fcntl), a SIGIO signal is sent whenever input or output
> > becomes possible on that file descriptor.
>
> Not done for files and you need fsetown() for sockets and tty's.

Thanks for the reply.

The reason that I was interested is that this behavior, if implemented
for all fd types, would be useful for a scalable user-space
implementation of POSIX aio.

When you say that it is 'not done for files', does that mean that it is
not done by design, and no plans exist to implement it for files
(perhaps because completion notification is fundamentally different than
readiness notification?), or that the work just has yet to be done?
Thanks.

Amos W.

2002-06-27 00:57:43

by William Lee Irwin III

[permalink] [raw]
Subject: Re: O_ASYNC question

On Wed, Jun 26, 2002 at 04:37:55PM -0500, Amos Waterland wrote:
> The reason that I was interested is that this behavior, if implemented
> for all fd types, would be useful for a scalable user-space
> implementation of POSIX aio.

Linux implements SIGIO for tty's and sockets only.

On Wed, Jun 26, 2002 at 04:37:55PM -0500, Amos Waterland wrote:
> When you say that it is 'not done for files', does that mean that it is
> not done by design, and no plans exist to implement it for files
> (perhaps because completion notification is fundamentally different than
> readiness notification?), or that the work just has yet to be done?
> Thanks.

It is not done by design. Future plans for async I/O implementations do
not appear to involve the SIGIO mechanism.


Cheers,
Bill

2002-06-27 12:15:55

by Jamie Lokier

[permalink] [raw]
Subject: Re: O_ASYNC question

Amos Waterland wrote:
> When you say that it is 'not done for files', does that mean that it is
> not done by design, and no plans exist to implement it for files
> (perhaps because completion notification is fundamentally different than
> readiness notification?), or that the work just has yet to be done?
> Thanks.

It isn't implemented for files, per POSIX I believe - in the same way
that select() will always return readable and writable on files.

I believe (i.e. I assume in my code ;-) that you should treat a SIGIO as
something which occurs when an fd transitions from "not readable" to
"readable", or from "not writable" to "writable". This applies even to
sockets: if you read only part of the readable data from a socket, then
you won't receive a SIGIO just because there is more unread data.

If the fd is permanently "readable" and "writable", such as with a file,
then there is no transition. Following this logic, you don't actually
need a special case for different kinds of fd -- you just need to check
their status with poll(), select(), or by trying a read/write operation
and checking for EAGAIN.

Please, someone point out if this logic does not hold, thanks :-)

-- Jamie