sononblock()--the function in apr/networkio/unix/sockopt.c that puts sockets in blocking or nonblocking mode--is responsible for a surprisingly large amount of CPU time on Solaris. I used to think that this was inevitable, but upon closer inspection there might be a way to fix it... but I'd like to get some feedback on whether the fix would actually be safe.
The logic for setting the nonblocking state looks like this:
- fcntl(sd, F_GETFL, ...) to get the current flags on the socket descriptor - OR the flags with O_NONBLOCK or O_NDELAY or O_FNDELAY, depending on the OS. - fcntl(sd, F_SETFL, flags) to set the new flags.
According to the profiler data, the F_GETFL fcntl operation is more expensive than the F_SETFL one.
Thus the change that I'm thinking of is: - on the first sononblock() call on a newly accepted socket, skip the F_GETFL operation and assume that the current flags are zero.
By my reading of the man pages, this ought to be safe because the fcntl-set options on the listener socket aren't inherited by the new socket that's created upon accept. But is there any platform (among the UNIXes supported by APR) where it's *not* safe to make this assumption?
Thanks, --Brian