[][src]Crate lv2_worker

Work scheduling library that allows real-time capable LV2 plugins to execute non-real-time actions.

This crate allows plugins to schedule work that must be performed in another thread. Plugins can use this interface to safely perform work that is not real-time safe, and receive the result in the run context. A typical use case is a sampler reading and caching data from disk. You can look at the LV2 Worker Specification for more details.


use std::any::Any;
use lv2_core::feature::*;
use lv2_core::prelude::*;
use urid::*;
use lv2_worker::*;

struct Ports {}

/// Requested features
struct AudioFeatures<'a> {
    ///host feature allowing to schedule some work
    schedule: Schedule<'a, EgWorker>,

//custom datatype
struct WorkMessage {
    cycle: usize,
    task: usize,

/// A plugin that do some work in another thread
struct EgWorker {
    // The schedule handler needs to know the plugin type in order to access the `WorkData` type.
    cycle: usize,
    end_cycle: usize,

/// URI identifier
unsafe impl UriBound for EgWorker {
    const URI: &'static [u8] = b"urn:rust-lv2-more-examples:eg-worker-rs\0";

impl Plugin for EgWorker {
    type Ports = Ports;
    type InitFeatures = ();
    type AudioFeatures = AudioFeatures<'static>;

    fn new(_plugin_info: &PluginInfo, _features: &mut Self::InitFeatures) -> Option<Self> {
        Some(Self {
            cycle: 0,
            end_cycle: 1,

    fn run(&mut self, _ports: &mut Ports, features: &mut Self::AudioFeatures, _: u32) {
        self.cycle += 1;
        let cycle = self.cycle;
        println!("cycle {} started", cycle);
        for task in 0..10 {
            let work = WorkMessage { cycle, task };
            // schedule some work, passing some data and check for error
            if let Err(e) = features.schedule.schedule_work(work) {
                eprintln!("Can't schedule work: {}", e);

    fn extension_data(uri: &Uri) -> Option<&'static dyn Any> {
        match_extensions![uri, WorkerDescriptor<Self>]

/// Implementing the extension.
impl Worker for EgWorker {
    // data type sent by the schedule handler and received by the `work` method.
    type WorkData = WorkMessage;
    // data type sent by the response handler and received by the `work_response` method.
    type ResponseData = String;
    fn work(
        //response handler need to know the plugin type.
        response_handler: &ResponseHandler<Self>,
        data: Self::WorkData,
    ) -> Result<(), WorkerError> {
        println!("work received: cycle {}, task {}", data.cycle, data.task);
        if data.task >= 5 {
            if let Err(e) = response_handler.respond(format!(
                "response to cycle {}, task {}",
                data.cycle, data.task
            )) {
                eprintln!("Can't respond: {}", e);

    fn work_response(
        &mut self,
        data: Self::ResponseData,
        _features: &mut Self::AudioFeatures,
    ) -> Result<(), WorkerError> {
        println!("work_response received: {}", data);

    fn end_run(&mut self, _features: &mut Self::AudioFeatures) -> Result<(), WorkerError> {
        println!("cycle {} ended", self.end_cycle);
        self.end_cycle += 1;



Handler available inside the worker function to send a response to the run() context.


Host feature providing data to build a ScheduleHandler.


Raw wrapper of the Worker extension.



Errors potentially generated by the ResponseHandler::respond method


Errors potentially generated by the Schedule::schedule_work method


Errors potentially generated by Worker methods



The non-realtime working extension for plugins.