Разделы сайта находятся в разработке.
Материалы могут быть неполными или содержать ошибки. Содержимое сайта будет синхронизировано с реализацией при выходе следующей версии, тогда как текущая (0.6.0) предназначена для прототипирования синтаксиса и создания песочницы.
Менеджер контекста (with)
Одиночный оператор захвата ссылки и синхронизации доступа к объекту (*ref, *ref(...))
выполняется для одного действия. Захват ссылки/объекта синхронизации — относительно медленная
операция, поэтому выполнять её для каждого действия нерационально. Менеджер контекста (with)
однократно захватывает сразу несколько ссылок/объектов и выполняет группу действий под общим локом,
а также служит для автоматического освобождения ресурсов (RAII) при выходе из блока.
В базовом синтаксисе — оператор **( ... ), в DSL ему соответствует макрос @with
(см. Keyword syntax (DSL)). Сравнение форм записи на примере
захвата-блокировки ссылки:
| Макросы DSL | Базовый синтаксис |
|---|---|
| |
Захват и блокировка ссылок
Ссылочные переменные объявляются атрибутами @[reftype("shared")@]/@[reftype("weak")@] и
транслируются в trust::Shared/trust::Weak; оператор take *ref/*^ref захватывает ссылку
(lock/lock_const) и возвращает охраняемый доступ trust::Locker<T>. Подробнее о ссылочных
типах и модели ссылок — в Управлении памятью.
with хранит список пар (замок, привязка) и связывает захваченные ссылки с именами внутри тела:
@with(lock = *ref) { # захват-блокировка ссылки ref
... # критическая секция
} @else { ... }; # ошибка захвата (ref == nullptr) → else
with(lock = *ref)— создаёт временный замокauto __cap = ref.lock();, привязкаlockавтоматически разыменовывается в значение; вызовlock()бросаетIntMinusпри сбое → веткаelse.with(_ = *ref)— захват ссылки на всё тело без привязки значения.with(*ref)— временный лок: снимается сразу, тело выполняется без лока.- Привязка ссылочной переменной без
*/*^(with(v = ref)) — предупреждение компилятора.
Автоматическое освобождение ресурсов (RAII)
Кроме захвата ссылок, менеджер контекста позволяет выделять и освобождать ресурсы: при выходе из
блока вызывается деструктор объекта (для объектов по значению). Освобождение
происходит до попадания в ветку else, если она есть:
@with(name = expr, ...) { # RAII-захват значений
...
} @else { ... }; # при исключении в инициализаторе expr
Это гарантирует закрытие файлов, освобождение захваченных ресурсов и т. п. независимо от того, как завершился вложенный код (штатно, по прерыванию или по ошибке).
Статус реализации
Формы &/&?/&&, параметр __timeout__, межпотоковая синхронизация и типы :Class/:Thread
в текущей версии не реализованы (см. Статус). Работают: ссылочные переменные
@[reftype(...)], захват ссылок with(...) с веткой else и RAII-захват значений with(name=expr).