The order of arguments is now the same as in Python (with the callable first), sort and priority arguments have been added, and new tasks can be added directly to a chain
init_memory_hook() is no longer required, eliminating static initialization order issues
This required moving the DeletedBufferChain map elsewhere, which now also has a const-initialized array for relatively small allocations.
Also, deletedChain.T has been renamed to deletedChain.I
Fixes#539
A task returning DS_interrupt would only interrupt the current task chain, not the entire task manager. This meant that other tasks might get run with an exception state set, causing the exception state to get stomped on or the Python interpreter to complain.
Fixes#692
This renames acquire/release to lock/unlock in order to be compatible with std::lock_guard and std::unique_lock (which will eventually replace the *MutexHolder classes). It will also allow us to typedef MutexImpl to std::mutex later on.
This introduces AsyncFuture as a new base class of AsyncTask. It's modelled after asyncio's Future class, except that it is thread-safe and you can use result() to block the current thread waiting for the future to finish (of course this is not necessary for use with coroutines).
AsyncFuture should be used for any operation that finishes in the future, to get the benefit of awaitability within coroutines as well as a standard interface for querying status and results of the operation as well as cancelling it. As such, it's been implemented in various places, including texture.prepare() and win.trigger_copy().
Note that AsyncFuture is intended to be used *once*; it cannot be used more than once. As an example of how this works, tex.prepare() will return the same future as long as the prepare isn't complete, but when it is done, subsequent calls to tex.prepare() will return a new future.