Release native memory associated with this query, if any.
FIXME This could cause direct buffers to be released back to the pool
before the operator tasks have terminated. That is NOT safe as the
buffers could then be reissued to other threads while existing threads
still have references to the buffers. Really, the same problem exists
with the allocation contexts used for NIO transfers of IBindingSet[]s.
We will have to be very careful to wait until each operator's Future
isDone() before calling clear() on the IMemoryManager to release the
native buffers back to the pool. If we release a buffer while an operator
is still running, then we will get data corruption arising from the
recycling of the buffer to another native buffer user.
AbstractRunningQuery.cancel(...) is where we need to handle this, more
specifically cancelRunningOperators(). Right now it is not waiting for
those operators to terminate.
Making this work is tricky. AbstractRunningQuery is holding a lock. The
operator tasks do not actually require that lock to terminate, but they
are wrapped by a ChunkWrapperTask, which handles reporting back to the
AbstractRunningQuery and *does* need the lock, and also by a
ChunkFutureTask. Since we actually do do ChunkFutureTask.get(), we are
going to deadlock if we invoke that while holding the
AbstractRunningQuery's lock.
The alternative is to handle the tear down of the native buffers for a
query asynchronously after the query has been cancelled, deferring the
release of the native buffers back to the direct buffer pool until all
tasks for the query are known to be done.