Use async nifs technique to avoid blocking the BEAM's schedulers

Running more than a simple amount of code on a scheduler thread turns out to be a very bad idea for R15 and later versions of the BEAM.  Here we use a thread-pool to execute work after being queued on the scheduler thread.  By placing more long-running tasks onto non-scheduler threads we lower the chances of confusing the Erlang scheduler and in so doing hopefully avoid having stalled scheduler threads.