rvagg/node-levelup — pull request #72 by rvagg (2013-02-13 08:08:54+00:00)
Title: Fix iterator/readStream next()+end() race condition segfault

Thanks to @ralphtheninja for picking up the race condition that causes occasional segfaults. It's possible to call an `end()` on an iterator/readStream while a `next()` is in progress; from different threads. And it turns out that LevelDB iterators aren't thread-safe so that's a no-no.

Since we have a master thread under libuv where these operations originate (the main JS thread) we can check for this condition there without the need for mutexes. You'll see my solution in the diff of the src/iterator* files.

Sorry about the other C++ entries in the diff, I did a quick cleanup of unnecessary includes and a also a bit of reorganisation. There's an additional change in levelup.cc to resolve a namespace conflict that happens in Node 0.9.9, an `Init()` is now exposed in node.h which conflicts with our `Init()`.

Also, @ralphtheninja, you might be interested to know that I came up with a way to fairly reliably trigger the race condition, you'll find the test case at the bottom of read-stream-test.js. Basically, if you deal with large data the `next()` operations are slow enough to interrupt with an `end()`.

And as an aside, I fixed a bug in slow-stream that allowed a double `'close'` to be emitted in some situations which lead to a complaint from async that the "Callback has already been called."