basho-labs/wterl — pull request #6 by gburd (2013-04-19 16:52:20+00:00)
Title: Execute NIF calls on non-scheduler threads asynchronously

Calls into NIFs which execute on scheduler threads can cause those schedulers to go offline (with is bad). This patch is a re-write of the wterl.c NIF layer that incorporates the async_nif.h method for queuing and dispatching NIF calls on non-scheduler threads.

WiredTiger's "WT_SESSION" and "WT_CURSOR" handles are *not* thread safe and are meant to be used within a single thread. This patch removes from the wterl module the session handle entirely. The WT_SESSIONs now exist solely within the context of the wterl.c NIF code and are carefully used within a single thread context only.

Opening and closing WT_SESSION or WT_CURSOR objects per-operation is a very expensive operation within the WiredTiger library. WiredTiger has to acquire locks on all btree's and perform other stop-(some of)-the-world blocking operations which isn't good for overall performance. WT_SESSION and WT_CURSOR objects are reusable and cheap (in terms of memory) once opened so this patch caches them reusing the handles when appropriate (get/put/delete mostly).

For some operations (drop, truncate, ...) WiredTiger must have only one open WT_SESSION (and related cursors in some cases) or else it will refuse to perform the operation and return EBUSY. This patch will close cached session and/or cursors during these calls and prevent new ones from being acquired until the operation finishes.

This patch is known to have 3 test failures at this time in the truncate tests of wterl.erl, other tests and eqc pass. Valgrind shows no memory is leaked, and the beam exits cleanly after unloading the NIF (which frees all allocated memory). The NIF carefully uses module priv_data as it's handle for state and there is only one static global variable, a mutex, which used to orchestrate startup/init. Unload has been tested, reload and upgrade have not be implemented or tested.