Struct tarantool::fiber::Fiber

source ·
pub struct Fiber<'a, T: 'a> { /* private fields */ }
👎Deprecated: use fiber::start, fiber::defer or fiber::Builder
Expand description

WARNING: This api is deprecated due to a number of issues including safety related ones (See doc-comments in Fiber::cancel for details). Use fiber::start, fiber::defer and/or fiber::Builder (choose the one most suitable for you).

A fiber is a set of instructions which are executed with cooperative multitasking.

Fibers managed by the fiber module are associated with a user-supplied function called the fiber function.

A fiber has three possible states: running, suspended or dead. When a fiber is started with fiber.start(), it is running. When a fiber is created with Fiber::new() (and has not been started yet) or yields control with sleep(), it is suspended. When a fiber ends (because the fiber function ends), it is dead.

A runaway fiber can be stopped with fiber.cancel(). However, fiber.cancel() is advisory — it works only if the runaway fiber calls is_cancelled() occasionally. In practice, a runaway fiber can only become unresponsive if it does many computations and does not check whether it has been cancelled.

The other potential problem comes from fibers which never get scheduled, because they are not subscribed to any events, or because no relevant events occur. Such morphing fibers can be killed with fiber.cancel() at any time, since fiber.cancel() sends an asynchronous wakeup event to the fiber, and is_cancelled() is checked whenever such a wakeup event occurs.

Example:

use tarantool::fiber::Fiber;

let mut f = |_| {
    println!("I'm a fiber");
    0
};
let mut fiber = Fiber::new("test_fiber", &mut f);
fiber.start(());
println!("Fiber started")
I'm a fiber
Fiber started

Implementations§

source§

impl<'a, T> Fiber<'a, T>

source

pub fn new<F>(name: &str, callback: &mut F) -> Self
where F: FnMut(Box<T>) -> i32,

Create a new fiber.

Takes a fiber from fiber cache, if it’s not empty. Can fail only if there is not enough memory for the fiber structure or fiber stack.

The created fiber automatically returns itself to the fiber cache when its main function completes. The initial fiber state is suspended.

Ordinarily Fiber::new() is used in conjunction with fiber.set_joinable() and fiber.join()

  • name - string with fiber name
  • callback - function for run inside fiber

See also: fiber.start()

source

pub fn new_with_attr<F>(name: &str, attr: &FiberAttr, callback: &mut F) -> Self
where F: FnMut(Box<T>) -> i32,

Create a new fiber with defined attributes.

Can fail only if there is not enough memory for the fiber structure or fiber stack.

The created fiber automatically returns itself to the fiber cache if has default stack size when its main function completes. The initial fiber state is suspended.

  • name - string with fiber name
  • fiber_attr - fiber attributes
  • callback - function for run inside fiber

See also: fiber.start()

source

pub fn start(&mut self, arg: T)

Start execution of created fiber.

WARNING: This function is unsafe, because it doesn’t check if fiber creation failed and may cause a crash.

  • arg - argument to start the fiber with

See also: fiber.new()

source

pub fn wakeup(&self)

Interrupt a synchronous wait of a fiber.

WARNING: This function is unsafe actually! If the fiber was non-joinable and has already finished execution tarantool may have recycled it and now the pointer may refer to a completely unrelated fiber, which we will now wake up.

Consider using fiber::start or fiber::Builder instead, because they do not share the same limitations. But if you must use this api, the best course of action is to save the fiber’s id (Self::id_checked) before making the fiber non-joinable and use fiber::wakeup with it, don’t use this function!.

source

pub fn join(&self) -> i32

Wait until the fiber is dead and then move its execution status to the caller.

“Join” a joinable fiber. That is, let the fiber’s function run and wait until the fiber’s status is dead (normally a status becomes dead when the function execution finishes). Joining will cause a yield, therefore, if the fiber is currently in a suspended state, execution of its fiber function will resume.

This kind of waiting is more convenient than going into a loop and periodically checking the status; however, it works only if the fiber was created with fiber.new() and was made joinable with fiber.set_joinable().

The fiber must not be detached (See also: fiber.set_joinable()).

Return: fiber function return code

source

pub fn set_joinable(&mut self, is_joinable: bool)

Set fiber to be joinable (false by default).

WARNING: This api is unsafe, because non-joinalbe fibers get recycled as soon as they finish execution. After this the pointer to the fiber may or may not point to a newly constructed unrelated fiber. For this reason it’s not safe to operate with non-joinalbe fibers using this api. Use fiber::start, fiber::defer and/or fiber::Builder instead, as they don’t share the same limitations.

  • is_joinable - status to set
source

pub fn cancel(&mut self)

Cancel a fiber. (set FIBER_IS_CANCELLED flag)

WARNING: This function is unsafe actually! If the fiber was non-joinable and has already finished execution tarantool may have recycled it and now the pointer may refer to a completely unrelated fiber, which we will now cancel.

Consider using fiber::start or fiber::Builder instead, because they do not share the same limitations. But if you must use this api, the best course of action is to save the fiber’s id (Self::id_checked) before making the fiber non-joinable and use fiber::cancel with it, don’t use this function!.

Running and suspended fibers can be cancelled. After a fiber has been cancelled, attempts to operate on it will cause error: the fiber is dead. But a dead fiber can still report its id and status. Possible errors: cancel is not permitted for the specified fiber object.

If target fiber’s flag FIBER_IS_CANCELLABLE set, then it would be woken up (maybe prematurely). Then current fiber yields until the target fiber is dead (or is woken up by fiber.wakeup()).

source

pub fn id(&self) -> FiberId

Returns the fiber id.

Panicking

This will panic if the current tarantool executable doesn’t support the required api (i.e. has_fiber_id returns false). Consider using Self::id_checked if you want to handle this error.

source

pub fn id_checked(&self) -> Option<FiberId>

Returns the fiber id or None if the current tarantool executable doesn’t support the required api (i.e. has_fiber_id returns false).

Trait Implementations§

source§

impl<'a, T> Debug for Fiber<'a, T>

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more

Auto Trait Implementations§

§

impl<'a, T> RefUnwindSafe for Fiber<'a, T>
where T: RefUnwindSafe,

§

impl<'a, T> !Send for Fiber<'a, T>

§

impl<'a, T> !Sync for Fiber<'a, T>

§

impl<'a, T> Unpin for Fiber<'a, T>

§

impl<'a, T> UnwindSafe for Fiber<'a, T>
where T: RefUnwindSafe,

Blanket Implementations§

source§

impl<T> Any for T
where T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

source§

impl<T, U> Into<U> for T
where U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.