Re: [exim] data-phase efficiency

Top Page
Delete this message
Reply to this message
Author: Ian FREISLICH
Date:  
To: exim-users
CC: Jeremy Harris
Subject: Re: [exim] data-phase efficiency
Philip Hazel wrote:
> On Wed, 18 May 2005, Ian FREISLICH wrote:
>
> > You need to do the following (non blocking descriptors rule):
> >
> >    fcntl(s, F_SETFL, O_NONBLOCK);

> >
> >    pollfd.fd = s
> >    pollfd.events = POLLWRNORM | POLLERR | POLLHUP | POLLNVAL;

>
> All the man pages I read for poll() say that POLLERR, POLLHUP, and
> POLLNVAL are bits that get set in revents, and are not bits that you set
> in events.


Ok, you got me. I was writing some pseudo code and copying and
pasting from various sources in a hurry.

> The man page on my Linux box says that POLLWRNORM is only available
> "when compiling XPG4.2 source". The man page on Solaris says that
> POLLWRNORM is the same as POLLOUT, so I guess that will do.
>
> However, we know that there are systems that don't implement poll(), or
> implement it badly. (Are there any that don't support O_NONBLOCK?) I'm
> not keen on rocking this particular boat.


You can do much the same with select(). Just replace my use of
poll() with appropriate select() magic. The purpose of this code
snippet was not to demonstrate the use of poll, but non-blocking
IO. When you write to an fd, it may block and you have no idea how
much you can write before it will block. If it's set to O_NONBLOCK,
as soon as poll()/select() says you can write without blocking, you
write() and write() returns at the point it would block with the
number of bytes actually written.

I prefer not to use alarms in this particular case because you
should not do any IO in a signal handler, so it has to set some
global variable which you need to test in conjunction with errno
== EINTR on return from the write. If you don't test errno, you
land up having a race between write() returning and signal delivery
just before the test resulting in erroneous timeouts.

I suppose that we're not particularly interrested in very accurate
timeouts, so the timing issues assciated with alarm() and signal
delivery are not a problem in this particular case.

I've used poll() in this manner to great success on FreeBSD 4.x 5.x
and 6.x, Linux various flavours, Solaris 5? 6 7 and 8, but I guess
that's not a particularly broad sweep of opperating systems. I've
also used non-blocking IO on all these systems as well.

Ian

--
Ian Freislich