21

I'm seeing such code in nginx:

if(fcntl(ngx_processes[s].channel[0], F_SETFL, fcntl(s, F_GETFL) | O_NONBLOCK) == -1) {
...
if (ioctl(ngx_processes[s].channel[0], FIOASYNC, &on) == -1) {
...

Anyone can tell me what's the difference between fcntl(s, F_SETFL, fcntl(s, F_GETFL) | O_NONBLOCK) and ioctl(s, FIOASYNC, &on) ,aren't async and nonblocking the same thing??

cpuer
  • 7,413
  • 14
  • 35
  • 39

1 Answers1

23

FIOASYNC toggles the O_ASYNC flag (which is usually set in open(2) or fcntl(2)) for a file descriptor, which will ask the kernel to send SIGIO or SIGPOLL to the process when the file descriptor is ready for IO.

O_ASYNC is not used often:

  • it is extremely difficult to properly handle IO in signal handlers; they are best left as tiny as possible
  • because signals interrupt the control flow of the program, they 'cost more' to run than standard system calls, such as select(2) or poll(2)
  • signals provide less information than other calls: they only report one fd ready vs many fds that might be ready.

The O_NONBLOCK doesn't provide any notification to the user process that a fd is ready for read(2) or write(2) -- instead, it changes the behavior of read(2) and write(2) and similar calls to return immediately if the file descriptor isn't ready for reading or writing. O_NONBLOCK is typically used in conjunction with select(2) or poll(2) or similar calls to guarantee that the main loop of a client or server won't block on one specific peer, and thus starve all its peers.

sarnold
  • 102,305
  • 22
  • 181
  • 238
  • @sarnold,so you mean both are the same thing? – cpuer Jun 07 '11 at 02:45
  • Also `FIOASYNC` is a completely nonstandard/legacy way to do the equivalent of `O_ASYNC` with `open` or `fcntl`. – R.. GitHub STOP HELPING ICE Jun 07 '11 at 02:47
  • 5
    @cpuer: No, async and nonblocking are completely different concepts. – R.. GitHub STOP HELPING ICE Jun 07 '11 at 02:47
  • 1
    @cpuer: It may have a good reason to set the flag, but it should do so in the standards-sanctioned way, using `fcntl` with `O_ASYNC`, not some ancient 1980s-style `ioctl`. – R.. GitHub STOP HELPING ICE Jun 07 '11 at 02:48
  • @sarnold,I saw your change. When using `ASYNC` and notification callback is invoked,1.will the process stop its current routine ? 2. or both the current routine and the callback routine are running the same time? – cpuer Jun 07 '11 at 02:51
  • @R..,can you describe the situation when `ASYNC` callbacks are invoked? Will it block the original process routine ? – cpuer Jun 07 '11 at 03:09
  • It's not a callback but a signal. If a signal handler for the signal has been installed, it will asynchronously stop execution of the thread the signal was delivered to and execute the signal handler until it returns. After the signal handler returns, the interrupted thread will continue. Being asynchronous, signal handlers are rather dangerous, and there are mildly complex rules for what you can and cannot do from a signal handler. Breaking those rules results in undefined behavior and may *appear to work* but suddenly crash, deadlock, or corrupt memory in timing-specific ways. – R.. GitHub STOP HELPING ICE Jun 07 '11 at 03:25
  • @R: Can you cite the standard that specifies `fcntl` with `O_ASYNC` (or indeed mentions `O_ASYNC` at all)? – Nemo Jun 07 '11 at 04:19