Skip to content

Commit

Permalink
fibers available on 3.1 and greater only
Browse files Browse the repository at this point in the history
below 3.1 Ruby isn't compatible with Magnus' need to wrap everything
with protect(), so while the C API for fibers exists in these older
versions it's not safely usable from Rust
  • Loading branch information
matsadler committed Sep 2, 2023
1 parent 1c52f7f commit 93e4c4d
Show file tree
Hide file tree
Showing 3 changed files with 12 additions and 37 deletions.
3 changes: 2 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@
## [Unreleased]
### Added
- `Thread`, `Ruby::thread_create`/`thread_create_from_fn` and other thread APIs.
- `Fiber`, `Ruby::fiber_new`/`fiber_new_from_fn` and other fiber APIs.
- `Fiber`, `Ruby::fiber_new`/`fiber_new_from_fn` and other fiber APIs
(requires Ruby >= 3.1).
- `Ruby::ary_try_from_iter` is an efficient way to create a Ruby array from a
fallible Rust iterator.
- `Ruby::hash_from_iter` and `Ruby::hash_try_from_iter`.
Expand Down
40 changes: 5 additions & 35 deletions src/fiber.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,23 +5,18 @@ use rb_sys::rb_fiber_new;
#[cfg(ruby_gte_3_2)]
use rb_sys::rb_fiber_new_storage;
use rb_sys::{
rb_data_typed_object_wrap, rb_fiber_alive_p, rb_fiber_current, rb_fiber_resume_kw,
rb_fiber_yield_kw, VALUE,
rb_data_typed_object_wrap, rb_fiber_alive_p, rb_fiber_current, rb_fiber_raise,
rb_fiber_resume_kw, rb_fiber_transfer_kw, rb_fiber_yield_kw, rb_obj_is_fiber, VALUE,
};
#[cfg(ruby_gte_3_1)]
use rb_sys::{rb_fiber_raise, rb_fiber_transfer_kw, rb_obj_is_fiber};

#[cfg(ruby_lt_3_1)]
use crate::class::RClass;
#[cfg(ruby_gte_3_1)]
use crate::exception::Exception;
#[cfg(any(ruby_gte_3_2, docsrs))]
use crate::r_hash::RHash;
use crate::{
api::Ruby,
block::Proc,
data_type_builder,
error::{protect, Error},
exception::Exception,
gc,
into_value::{kw_splat, ArgList, IntoValue},
method::{Block, BlockReturn},
Expand Down Expand Up @@ -53,14 +48,11 @@ impl Ruby {
/// Ok(())
/// })?;
///
/// # #[cfg(ruby_gte_3_1)]
/// # {
/// rb_assert!(ruby, "fib.resume(0, 1) == 1", fib);
/// rb_assert!(ruby, "fib.resume == 2", fib);
/// rb_assert!(ruby, "fib.resume == 3", fib);
/// rb_assert!(ruby, "fib.resume == 5", fib);
/// rb_assert!(ruby, "fib.resume == 8", fib);
/// # }
///
/// Ok(())
/// }
Expand Down Expand Up @@ -123,14 +115,11 @@ impl Ruby {
/// Ok(())
/// })?;
///
/// # #[cfg(ruby_gte_3_1)]
/// # {
/// rb_assert!(ruby, "fib.resume == 1", fib);
/// rb_assert!(ruby, "fib.resume == 2", fib);
/// rb_assert!(ruby, "fib.resume == 3", fib);
/// rb_assert!(ruby, "fib.resume == 5", fib);
/// rb_assert!(ruby, "fib.resume == 8", fib);
/// # }
///
/// Ok(())
/// }
Expand Down Expand Up @@ -213,23 +202,11 @@ pub struct Fiber(RTypedData);
impl Fiber {
#[inline]
pub fn from_value(val: Value) -> Option<Self> {
#[cfg(ruby_lt_3_1)]
let fiber = {
let fiber_class: RClass = Ruby::get_with(val)
.class_object()
.funcall("const_get", ("Fiber",))
.ok()?;
RTypedData::from_value(val)
.filter(|_| val.is_kind_of(fiber_class))
.map(Self)
};
#[cfg(ruby_gte_3_1)]
let fiber = unsafe {
unsafe {
Value::new(rb_obj_is_fiber(val.as_rb_value()))
.to_bool()
.then(|| Self::from_rb_value_unchecked(val.as_rb_value()))
};
fiber
}
}

#[inline]
Expand Down Expand Up @@ -258,14 +235,11 @@ impl Fiber {
/// Ok(())
/// })?;
///
/// # #[cfg(ruby_gte_3_1)]
/// # {
/// assert_eq!(fib.resume::<_, u64>((0, 1))?, 1);
/// assert_eq!(fib.resume::<_, u64>(())?, 2);
/// assert_eq!(fib.resume::<_, u64>(())?, 3);
/// assert_eq!(fib.resume::<_, u64>(())?, 5);
/// assert_eq!(fib.resume::<_, u64>(())?, 8);
/// # }
///
/// Ok(())
/// }
Expand All @@ -292,8 +266,6 @@ impl Fiber {
}
}

#[cfg(any(ruby_gte_3_1, docsrs))]
#[cfg_attr(docsrs, doc(cfg(ruby_gte_3_1)))]
pub fn transfer<A, T>(self, args: A) -> Result<T, Error>
where
A: ArgList,
Expand All @@ -315,8 +287,6 @@ impl Fiber {
}
}

#[cfg(any(ruby_gte_3_1, docsrs))]
#[cfg_attr(docsrs, doc(cfg(ruby_gte_3_1)))]
pub fn raise<T>(self, e: Exception) -> Result<T, Error>
where
T: TryConvert,
Expand Down
6 changes: 5 additions & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1800,6 +1800,8 @@ pub mod encoding;
mod enumerator;
pub mod error;
pub mod exception;
#[cfg(any(ruby_gte_3_1, docsrs))]
#[cfg_attr(docsrs, doc(cfg(ruby_gte_3_1)))]
pub mod fiber;
mod float;
pub mod gc;
Expand Down Expand Up @@ -1850,6 +1852,9 @@ use ::rb_sys::{
};
pub use magnus_macros::{init, wrap, DataTypeFunctions, TypedData};

#[cfg(any(ruby_gte_3_1, docsrs))]
#[cfg_attr(docsrs, doc(cfg(ruby_gte_3_1)))]
pub use crate::fiber::Fiber;
#[cfg(ruby_use_flonum)]
pub use crate::value::Flonum;
pub use crate::{
Expand All @@ -1858,7 +1863,6 @@ pub use crate::{
enumerator::Enumerator,
error::Error,
exception::{Exception, ExceptionClass},
fiber::Fiber,
float::Float,
integer::Integer,
into_value::{ArgList, IntoValue, IntoValueFromNative, KwArgs, RArrayArgList},
Expand Down

0 comments on commit 93e4c4d

Please sign in to comment.