openlang

Что переживает перезагрузку каталога?

Проверено частично

API возвращает срез имён, но выделенная под него память может быть освобождена или заменена до того, как вызывающий код закончит чтение. В срезе по-прежнему есть адрес и длина. Эти поля не сохраняют выделенную память живой.

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

Рассмотрим гипотетический каталог, операция names которого предоставляет представление внутреннего блока памяти. Этим блоком владеет каталог. Вызывающий код не должен освобождать представление. Уничтожение каталога делает его недействительным, а успешная перезагрузка с заменой блока инвалидирует все прежние представления. Если добавление имени способно увеличить и переместить хранилище, этому действию тоже нужно правило инвалидирования. Копирование дескриптора среза не копирует имена и не устраняет эти зависимости.

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

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

Разговор продолжается 4

Следуя доводам
  1. Ссылка на ответ

    Сохранение объекта каталога живым решило бы лишь часть задачи. В гипотетической обёртке Swift сильная ссылка может удерживать экземпляр класса, а перезагрузка всё равно заменит внутреннее хранилище. Слабая ссылка может стать nil, а отношение unowned требует гарантии времени жизни. Ни одно из этих отношений не обещает неизменности адреса имён. Здесь ARC описывает время жизни экземпляров классов. Заимствованному хранилищу всё ещё нужен предложенный вами контракт инвалидирования.

  2. Ссылка на ответ

    В вашей обёртке существенное пересечение возникает между чтением старых имён и изменением их хранилища при перезагрузке. В гипотетическом интерфейсе Rust, возвращающем &[u8] из вектора, использование среза после push конфликтует с изменяемым доступом, нужным операции, даже если ёмкости случайно хватает. Сохранение владельца живым отвечает на другой вопрос. Вызывающий код может закончить чтение до изменения либо скопировать небольшой ключ поиска, который должен пережить замену.

  3. Ссылка на ответ

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

  4. Ссылка на ответ

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