=== Правила использования мьютексов ===

Мьютекс - основной примитив синхронизации, поддерживающий две операции: захват
(aquire) и освобождение (release).

Операция aquire - это:
	* compiler barrier - инстркуции, следующие после aquire, не будут
	  помещаться компилятором перед aquire;
	* aquire memory barrier - инструкции, следующие после aquire, не будут
	  исполняться процессором до выполнения aquire;
	* синхронизация по отношению к мьютексу.
Операция release - это:
	* compiler barrier - инстркуции, следующие перед release, не будут
	  помещаться компилятором после release;
	* release memory barrier - инструкции, следующие перед release, не будут
	  исполняться процессором после выполнения release;
	* синхронизация по отношению к мьютексу.

Основная форма использования мьютекса - защита состояния некоторого объекта.
Рассмотрим наиболее распространённый тип мьютексов - мьютексы состояния
(Object::mutex).

Можно выделить три основных этапа во времени жизни объекта:
    1. Инициализация. Память под объект выделена, но о существовании объекта
       известно пока только в потоке, создавшем его. Выполняется конструктор
       и вспомогательные функции инициализации. Этап завершается началом
       использования объекта по назначению (в частности, передачей ук-ля на
       объект другому потоку;
    2. Использование. Объект асинхронно используется несколькими потоками;
    3. Удаление. Точно известно, что доступ к объекту теперь будет
       осуществляться только одним потоком. Этот поток занимается удалением
       объекта (вызывается деструктор).

Во время инициализации захватывать мьютекс необязательно. Перед тем, как
передать ук-ль на объект другому потоку, потребуется синхронизировать эти
потоки парами aquire/release. Важно знать, что установка атомарного указателя
на только что сконструированный объект не делает содержимое этого объекта
видимым другим потокам (хотя в glib атомарные операции сопровождаются full
memory barrier, в общем случае на это не нужно рассчитывать). Исполнение
aquire/release на произвольном мьютексе сделает результат инициализации объекта
видимым другим потокам.

Перед деинициализацией потоку, разрушающему объект, должны стать видимы все
изменения состояния объекта, произведённые другими потоками. Для этого
разрушающий поток должен захватить мьютекс состояния объекта, т.к. мьютекс
считается единственным доступным примитивом синхронизации. Перед удалением
мьютекса состояния его нужно осовободить, т.к. в общем случае для корректного
удаления мьютекс должен находиться в освобождённом состоянии.

