OpenLightingProject/ola — pull request #429 by nomis52 (2014-07-08 16:52:58+00:00)
Title: Make SelectPoller reentrant

There was a bug in SelectPoller that I discovered during E1.33 testing. If you have a ConnectedDescriptor [1] that has been added for reading and call Execute with a callback [2] that will remove and delete the connected descriptor then:

- Execute enqueues the callback [2] and writes data to the internal descriptor.
- SelectPoller::Poll() is called
- The internal descriptor is ready for reading and the connected descriptor is ready for writing
- The internal descriptor is added to the read queue
- The connected descriptor is added to the write queue
- The read queue is processed, and since it contains the internal descriptor the callback [2] is executed
- The callback removes the connected descriptor and deletes it
- The write queue is processed, but by now the connected descriptor has been deleted.
- Segfault.

The more general form of this bug was that adding or removing descriptors from within another descriptor's callback would cause a crash. Since we use an internal descriptor to implement Execute(), callbacks added with Execute() were also susceptible to the bug.

I've added a test to exercise this case.