Структура RawWakerVTable

Описание

Таблица виртуальных функций (vtable), которая определяет поведение RawWaker.

Указатель, передаваемый во все функции внутри vtable, является указателем данных из содержащего объекта RawWaker.

Функции внутри этой структуры предназначены только для вызова на указателе данных правильно сконструированного объекта RawWaker из реализации RawWaker. Вызов одной из содержащихся функций с использованием любого другого указателя данных вызовет неопределенное поведение.

Примечание: хотя этот тип реализует PartialEq, сравнение указателей функций (и, следовательно, сравнение структур, содержащих указатели функций) ненадежно: указатели на одну и ту же функцию могут сравниваться как неравные (поскольку функции дублируются в нескольких единицах кодогенерации), а указатели на разные функции могут сравниваться как равные (поскольку идентичные функции могут быть дедуплицированы в пределах одной единицы кодогенерации).

Потокобезопасность

Если RawWaker будет использоваться для создания Waker, то все эти функции должны быть потокобезопасными (даже несмотря на то, что RawWaker является !Send + !Sync). Это связано с тем, что Waker является Send + Sync, и он может быть перемещен в произвольные потоки или вызван по ссылке &. Например, это означает, что если функции clone и drop управляют счетчиком ссылок, они должны делать это атомарно.

Однако, если RawWaker будет использоваться для создания LocalWaker, то эти функции не обязательно должны быть потокобезопасными. Это означает, что данные !Send + !Sync могут храниться в указателе данных, и подсчет ссылок не требует атомарной синхронизации. Это связано с тем, что LocalWaker сам по себе не является потокобезопасным, поэтому его нельзя передавать между потоками.

Синтаксис

#![allow(unused)]
fn main() {
pub struct RawWakerVTable { /* приватные поля */ }
}

Методы

new

#![allow(unused)]
fn main() {
pub const fn new(
    clone: unsafe fn(*const ()) -> RawWaker,
    wake: unsafe fn(*const ()),
    wake_by_ref: unsafe fn(*const ()),
    drop: unsafe fn(*const ()),
) -> RawWakerVTable
}

Создает новый RawWakerVTable из предоставленных функций clone, wake, wake_by_ref и drop.

Доступность: 1.36.0 (const: 1.36.0)

Параметры

  • clone - функция, вызываемая при клонировании RawWaker
  • wake - функция, вызываемая при пробуждении задачи (потребляет данные)
  • wake_by_ref - функция, вызываемая при пробуждении задачи (не потребляет данные)
  • drop - функция, вызываемая при удалении RawWaker

Безопасность

Все функции должны быть небезопасными (unsafe fn), так как они работают с сырыми указателями.

Описание функций vtable

clone

Эта функция вызывается, когда RawWaker клонируется, например, когда Waker/LocalWaker, в котором хранится RawWaker, клонируется.

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

wake

Эта функция вызывается, когда wake вызывается на Waker. Она должна пробуждать задачу, связанную с этим RawWaker.

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

wake_by_ref

Эта функция вызывается, когда wake_by_ref вызывается на Waker. Она должна пробуждать задачу, связанную с этим RawWaker.

Эта функция похожа на wake, но не должна потреблять предоставленный указатель данных.

drop

Эта функция вызывается, когда Waker/LocalWaker удаляется.

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

Реализации трейтов

Clone

#![allow(unused)]
fn main() {
impl Clone for RawWakerVTable
}

Позволяет клонирование RawWakerVTable.

Debug

#![allow(unused)]
fn main() {
impl Debug for RawWakerVTable
}

Позволяет форматирование RawWakerVTable для отладки.

PartialEq

#![allow(unused)]
fn main() {
impl PartialEq for RawWakerVTable
}

Реализует проверку на равенство для RawWakerVTable.

Copy

#![allow(unused)]
fn main() {
impl Copy for RawWakerVTable
}

Позволяет копирование RawWakerVTable по значению.

Автоматические реализации трейтов

  • Freeze for RawWakerVTable - может быть заморожен
  • RefUnwindSafe for RawWakerVTable - безопасен для паники
  • Send for RawWakerVTable - может быть передан между потоками
  • Sync for RawWakerVTable - может быть разделен между потоками
  • Unpin for RawWakerVTable - может быть безопасно перемещено
  • UnwindSafe for RawWakerVTable - безопасен для паники

Пример использования

#![allow(unused)]
fn main() {
use std::task::{RawWaker, RawWakerVTable};

unsafe fn clone(data: *const ()) -> RawWaker {
    // Реализация клонирования
}

unsafe fn wake(data: *const ()) {
    // Реализация пробуждения (потребляет данные)
}

unsafe fn wake_by_ref(data: *const ()) {
    // Реализация пробуждения (не потребляет данные)
}

unsafe fn drop(data: *const ()) {
    // Реализация очистки
}

static VTABLE: RawWakerVTable = RawWakerVTable::new(clone, wake, wake_by_ref, drop);
}

Назначение

RawWakerVTable используется для:

  • Определения кастомного поведения пробуждения задач
  • Интеграции с внешними системами событий
  • Создания специализированных исполнителей задач

Предупреждения

  • Неправильная реализация может привести к неопределенному поведению
  • Необходимо обеспечить корректность всех функций vtable
  • Следует учитывать требования потокобезопасности в зависимости от типа создаваемого Waker