It is however true to say that files will always return as readable and
writable but that still means kqueue and poll and hence libevent works
:-).


On Thu, Sep 08, 2011 at 04:44:26PM +0100, Nicholas Marriott wrote:
> On Thu, Sep 08, 2011 at 01:17:22AM -0700, Scott Lamb wrote:
> > On Tue, Sep 6, 2011 at 3:25 AM, Nicholas Marriott
> > <nicholas.marri...@gmail.com> wrote:
> > > OpenBSD is libevent 1.4.13.
> > >
> > > OS X polling mechanisms are pretty bad: their poll() and kqueue() only
> > > support sockets, so you will need to use select (set EVENT_NOPOLL=1
> > > EVENT_NOKQUEUE= in the environment).
> > 
> > This isn't really limited to OS X. My understanding is that there's no
> > Unix or Unix-like system that supports non-blocking IO on regular
> > files except maybe through the special aio interface described in the
> > following link. That interface is often unimplemented, buggy, and/or
> > emulated in userspace with blocking IO done from hidden threads. And
> > it's not supported by libevent, perhaps for these reasons.
> 
> Nonblocking I/O has not much to do with it, you don't necessarily need
> nonblocking I/O if you have working poll(2) or select(2).
> 
> It is a limitation of OS X. Every other platform with kqueue(2) and all
> I am aware of with poll(2) support it on all file descriptors. OS X
> doesn't support it on anything other than sockets - so not on ttys, not
> on files, not anything except sockets.
> 
> This is annoying because it means you can't manage tty file descriptors
> or file descriptors linked to devices such as /dev/null (both of which
> are commonly used for eg stdout) with libevent unless you force it to
> use select.
> 
> Linux epoll doesn't support /dev/null either, but it does support ttys
> and IIRC files too.
> 
> > 
> > http://pubs.opengroup.org/onlinepubs/009695399/basedefs/aio.h.html
> > 
> > In particular, read() and write() on "regular files" will never return
> > EAGAIN, usually use "uninterruptible IO" (meaning even a SIGKILL will
> > not terminate the thread/process doing the IO if the device is hung;
> > you'll just see the dreaded state "D" in ps), and don't really work
> > with any of the notification interfaces used by libevent. They may be
> > reported as always available, simply cause EINVAL or some such error,
> > or do something more strange.
> > 
> > fwiw, if you browse around the aio docs I linked above, you'll see the
> > following rationale:
> > 
> > """
> > Rationale for New Interface
> > 
> > Non-blocking I/O does not satisfy the needs of either realtime or
> > high-performance computing models; these models require that a process
> > overlap program execution and I/O processing. Realtime applications
> > will often make use of direct I/O to or from the address space of the
> > process, or require synchronized (unbuffered) I/O; they also require
> > the ability to overlap this I/O with other computation. In addition,
> > asynchronous I/O allows an application to keep a device busy at all
> > times, possibly achieving greater throughput. Supercomputing and
> > database architectures will often have specialized hardware that can
> > provide true asynchrony underlying the logical asynchrony provided by
> > this interface. In addition, asynchronous I/O should be supported by
> > all types of files and devices in the same manner.
> > """
> > 
> > I don't think that's entirely accurate or an adequate justification
> > for not supporting the existing (and much simpler) non-blocking
> > interfaces, but I wasn't in the room when the decision was made...
> > 
> > libevent works well with sockets (including TCP, UDP, and Unix-domain)
> > and pipes (named and unnamed) but not so well with regular files.
> > 
> > >
> > >
> > > On Thu, Sep 01, 2011 at 11:19:52PM +0100, Bernd Schoeller wrote:
> > >> Dear List,
> > >>
> > >> I am currently taking my first steps in experimenting with libevent.
> > >> To do that, I have written the small example below that should copy
> > >> a file. I am currently trying to restrict myself to the core
> > >> functions, and I know that the buffer handling is too primitive.
> > >>
> > >> I am trying the code on 3 different platforms:
> > >>
> > >> a) On OpenBSD 4.9, the code seems to work and the file is copied. I
> > >> am not sure what version OpenBSD is using and what they changed.
> > >>
> > >> b) On MacOS Lion, using libevent 2.0.10, the program copies the
> > >> file, but seems to never receive the 0 bytes EOF read, thus blocking
> > >> after the last write. Output ends with:
> > >>
> > >> ...
> > >> read callback
> > >> Read: 6, 2 - 81953
> > >> write callback
> > >> Written: 7, 4 - 81953 (81953) of 81953
> > >> Sub read.
> > >>
> > >> c) On Linux (Ubuntu LTS), using libevent 1.4.13, the read operation
> > >> is never triggered and the main loop exits immediately. The output
> > >> printed is:
> > >>
> > >> Starting.
> > >> Opened read file handle 6.
> > >> Opened write file handle 7.
> > >> Exited with 1
> > >>
> > >> With these 3 different behaviors, I am pretty sure that I have not
> > >> understood some fundamental detail of libevent. I do not think the
> > >> different versions are to blame, and it should be possible to create
> > >> some code that runs on all versions, as I am using very basic
> > >> functions that seem to be the same in all versions.
> > >>
> > >> Thanks for your help,
> > >> Bernd
> > >>
> > >>
> > >> ---> c_libevent_test.c <---
> > >>
> > >> #include <event.h>
> > >> #include <stdio.h>
> > >> #include <fcntl.h>
> > >> #include <sys/types.h>
> > >> #include <sys/stat.h>
> > >>
> > >> #define READ_FILE_NAME "in.dat"
> > >> #define WRITE_FILE_NAME "out.dat"
> > >>
> > >> #define BUFFER_SIZE 100000
> > >>
> > >> struct event fd_read;
> > >> struct event fd_write;
> > >>
> > >> int buffer[BUFFER_SIZE];
> > >> int full;
> > >> int written;
> > >>
> > >> void onRead(int fd, short mode, void* data)
> > >> {
> > >> ? printf("read callback\n");
> > >> ? full = read(fd, buffer, BUFFER_SIZE);
> > >> ? printf("Read: %d, %d - %d\n", fd, mode, full);
> > >> ? if (full > 0) {
> > >> ? ? written = 0;
> > >> ? ? event_add(&fd_write, NULL);
> > >> ? }
> > >> }
> > >>
> > >> void onWrite(int fd, short mode, void *data)
> > >> {
> > >> ? printf("write callback\n");
> > >> ? int wr = write(fd, buffer+written, full-written);
> > >> ? written += wr;
> > >> ? printf("Written: %d, %d - %d (%d) of %d\n", fd, mode,
> > >> ? ? ? ? ?wr, written, full);
> > >> ? if (wr >= full) {
> > >> ? ? written = 0;
> > >> ? ? full = 0;
> > >> ? ? printf("Sub read.\n");
> > >> ? ? event_add(&fd_read, NULL);
> > >> ? } else {
> > >> ? ? event_add(&fd_write, NULL);
> > >> ? }
> > >> }
> > >>
> > >> int main(int argc, char** argv)
> > >> {
> > >> ? full = 0;
> > >>
> > >> ? event_init();
> > >>
> > >> ? printf("Starting.\n");
> > >>
> > >> ? int fd;
> > >> ? fd = open(READ_FILE_NAME, O_RDONLY);
> > >> ? printf("Opened read file handle %d.\n", fd);
> > >> ? event_set(&fd_read, fd, EV_READ, onRead, 0);
> > >>
> > >> ? fd = open(WRITE_FILE_NAME, O_WRONLY | O_CREAT, 0600);
> > >> ? printf("Opened write file handle %d.\n", fd);
> > >> ? event_set(&fd_write, fd, EV_WRITE, onWrite, 0);
> > >>
> > >> ? event_add(&fd_read, NULL);
> > >> ? printf("Exited with %d\n", event_dispatch());
> > >> ? return 0;
> > >> }
> > >>
> > >> ***********************************************************************
> > >> To unsubscribe, send an e-mail to majord...@freehaven.net with
> > >> unsubscribe libevent-users ? ?in the body.
> > > ***********************************************************************
> > > To unsubscribe, send an e-mail to majord...@freehaven.net with
> > > unsubscribe libevent-users ? ?in the body.
> > >
> > 
> > 
> > 
> > -- 
> > Scott Lamb <http://www.slamb.org/>
> > ***********************************************************************
> > To unsubscribe, send an e-mail to majord...@freehaven.net with
> > unsubscribe libevent-users    in the body.
> ***********************************************************************
> To unsubscribe, send an e-mail to majord...@freehaven.net with
> unsubscribe libevent-users    in the body.
***********************************************************************
To unsubscribe, send an e-mail to majord...@freehaven.net with
unsubscribe libevent-users    in the body.

Reply via email to