Use thread local direct buffer for I/O when the current allocator is unpooled

- Allocating and deallocating a direct buffer for I/O is an expensive
  operation, so we have to at least have a pool of direct buffers if the
  current allocator is not pooled