extensionSystem: Fix race condition when enabling extensions
When an extension is enabled, it is deleted from the list of
disabled extensions and added to the list of enabled extensions.
This can cause a race condition, because both cases call the
same asynchronous function, resulting in the creation of two
instances of each extension, and the enable method of each
one being called twice, as seen in this capture: the
Desktop Icons NG extension object is created and enabled twice,
without a call to disable in between.
This is possible because, as can be seen in the log, the method
onEnabledExtensionsChanged can be called both from a signal
of a change in the disabled-extensions property (disabled extensions key in the journal), or from
a signal of a change in the enabled-extensions property
(enabled extensions key in the journal).
Since this method is async and does several await calls,
two very close changes to those properties can trigger it
the second time while the first time is in the middle of an
await, and, thus, preempting it while it is in an incomplete state.
This patch defines an asyncMutex object that allows to
ensure that, if an async function is called again while
already processing a call, won't execute until any previous
call has ended and completed their operations. This is, it works
like a mutex semaphore, but designed for Javascript async
functions/methods. GLib mutexes can't be used in this case
because they are tied to the C language and presume threading/
multiprocess, something that doesn't exist in javascript's
asynchronous programming.
