Using C poll() on stdin with systemd

Published 12 May 2012 under C, embedded

I recently wrote a C application which uses poll() to wait for interrupts from a GPIO. It worked perfectly until we tried to run the application under systemd on Angstrom at which point it used 100% CPU.

The relevant code is as follows:

int nfds = 2;
struct pollfd fdset[2];
int gpio_fd = gpio_setup();

while (1) {
  memset((void*)fdset, 0, sizeof(fdset));

  fdset[0].fd = gpio_fd;
  fdset[0].events = POLLPRI;

  fdset[1].fd = STDIN_FILENO;
  fdset[1].events = POLLIN;

  poll(fdset, nfds, -1);

  ... handle events ...

We were polling on stdin so that we could debug the program without having it connected to an actual button. Unfortunately, systemd closes stdin and so an event is always fired. This causes poll to fall-through and so the while loop spins as fast as it can, taking up 100% CPU! Oops.

Once we spotted that stdin is closed by systemd, the fix was simply to only poll on stdin when in debug mode using some conditional compilation.


blog comments powered by Disqus