Move nativeFree calls outside of the memory_mutex to avoid deadlock (#2124)
Move nativeFree calls outside of the memory_mutex to avoid deadlock (#2124)

Narrows the scope of the memory_mutex locks to just around the
modification and reading of the internal memory data members and
elements. This means that actual allocations happen outside of this
mutex's lock.

This was done because the CPU backend requires that the free operation
performs a sync before the pointer is freed. This caused deadlocks
when the main thread was waiting on the worker thread and the
worker thread called nativeFree. This scenario happens when a buffer
node is only referenced in the worker thread and it is removed.
umar456/arrayfire,arrayfire/arrayfire,umar456/arrayfire,umar456/arrayfire,arrayfire/arrayfire,9prady9/arrayfire,umar456/arrayfire,9prady9/arrayfire,9prady9/arrayfire,arrayfire/arrayfire,9prady9/arrayfire,arrayfire/arrayfire