Skip to content

Commit 771bca4

Browse files
committed
feature(fiber): fiber name is set from caller source location
this adds some overhead when creating fibers as now the compiler passes an additional implicit parameter to the fiber creation functions which also call a function for getting the location info. However at some point in the future these functions will become `const` which means that the overhead will disappear automatically. The allocations required for `format` won't probably disappear as soon though :(
1 parent 9c4b374 commit 771bca4

File tree

3 files changed

+55
-1
lines changed

3 files changed

+55
-1
lines changed

tarantool/src/fiber.rs

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -338,7 +338,11 @@ macro_rules! inner_spawn {
338338
($self:expr, $invocation:tt) => {
339339
{
340340
let Self { name, attr, f } = $self;
341-
let name = name.unwrap_or_else(|| "<rust>".into());
341+
let name = if let Some(name) = name {
342+
name
343+
} else {
344+
impl_details::fiber_name_from_caller()
345+
};
342346
Ok(Fyber::$invocation(name, f, attr.as_ref())?.spawn())
343347
}
344348
};
@@ -355,6 +359,7 @@ where
355359
/// to the new fiber immediately.
356360
///
357361
/// See the [`start`] free function for more details.
362+
#[track_caller]
358363
pub fn start(self) -> Result<C::JoinHandle> {
359364
inner_spawn!(self, immediate)
360365
}
@@ -370,6 +375,7 @@ where
370375
/// In the future we are planning to add a correct implementation.
371376
///
372377
/// See the [`defer`] free function for more details.
378+
#[track_caller]
373379
pub fn defer(self) -> Result<C::JoinHandle> {
374380
inner_spawn!(self, deferred)
375381
}
@@ -498,8 +504,11 @@ where
498504
Self { callee }
499505
}
500506

507+
#[track_caller]
501508
pub fn spawn(self) -> Result<C::JoinHandle> {
502509
let Self { callee } = self;
510+
let name = impl_details::fiber_name_from_caller();
511+
503512
let fiber_ref = unsafe {
504513
let l = ffi::luaT_state();
505514
lua::lua_getglobal(l, c_ptr!("require"));
@@ -520,6 +529,17 @@ where
520529
impl_details::guarded_pcall(l, 2, 0)
521530
.map_err(|e| panic!("{}", e))
522531
.unwrap();
532+
533+
lua::lua_getfield(l, -1, c_ptr!("name"));
534+
lua::lua_pushvalue(l, -2);
535+
lua::lua_pushlstring(l, name.as_ptr() as _, name.len());
536+
impl_details::guarded_pcall(l, 2, 0)
537+
.map_err(|e| {
538+
// Pop the fiber module and fiber instance from the stack
539+
lua::lua_pop(l, 2);
540+
e
541+
})?;
542+
523543
let fiber_ref = lua::luaL_ref(l, lua::LUA_REGISTRYINDEX);
524544
// pop the fiber module from the stack
525545
lua::lua_pop(l, 1);
@@ -752,6 +772,12 @@ mod impl_details {
752772
0
753773
}
754774
}
775+
776+
#[track_caller]
777+
pub(super) fn fiber_name_from_caller() -> String {
778+
let loc = std::panic::Location::caller();
779+
format!("<rust:{}:{}:{}>", loc.file(), loc.line(), loc.column())
780+
}
755781
}
756782

757783
////////////////////////////////////////////////////////////////////////////////
@@ -1170,6 +1196,7 @@ impl TrampolineArgs for VaList {
11701196
/// This will create a fiber using default parameters of [`Builder`], if you
11711197
/// want to specify the stack size or the name of the thread, use this API
11721198
/// instead.
1199+
#[track_caller]
11731200
pub fn start<'f, F, T>(f: F) -> JoinHandle<'f, T>
11741201
where
11751202
F: FnOnce() -> T,
@@ -1188,6 +1215,7 @@ where
11881215
/// should always be used instead of the latter.
11891216
///
11901217
/// For more details see: [`start`]
1218+
#[track_caller]
11911219
pub fn start_proc<'f, F>(f: F) -> UnitJoinHandle<'f>
11921220
where
11931221
F: FnOnce(),
@@ -1207,6 +1235,7 @@ where
12071235
///
12081236
/// The new fiber can be joined by calling [`LuaJoinHandle::join`] method on
12091237
/// it's join handle.
1238+
#[track_caller]
12101239
pub fn defer<'f, F, T>(f: F) -> LuaJoinHandle<'f, T>
12111240
where
12121241
F: FnOnce() -> T,
@@ -1226,6 +1255,7 @@ where
12261255
/// it's join handle.
12271256
///
12281257
/// This is an optimized version [`defer`]`<F, ()>`.
1258+
#[track_caller]
12291259
pub fn defer_proc<'f, F>(f: F) -> LuaUnitJoinHandle<'f>
12301260
where
12311261
F: FnOnce(),

tests/src/fiber/mod.rs

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -468,3 +468,26 @@ pub fn lifetime() {
468468
// }.join();
469469
}
470470

471+
fn fiber_name() -> String {
472+
let lua = tarantool::lua_state();
473+
lua.eval("return require 'fiber'.name()").unwrap()
474+
}
475+
476+
pub fn name() {
477+
let name = fiber::start(fiber_name).join();
478+
assert_eq!(name, format!("<rust:{}:{}:{}>", file!(), line!() - 1, 16));
479+
480+
let (tx, rx) = Rc::new(Cell::new(None)).into_clones();
481+
fiber::start_proc(|| tx.set(Some(fiber_name()))).join();
482+
let expected = format!("<rust:{}:{}:{}>", file!(), line!() - 1, 5);
483+
assert_eq!(rx.take().unwrap(), expected);
484+
485+
let name = fiber::defer(fiber_name).join();
486+
assert_eq!(name, format!("<rust:{}:{}:{}>", file!(), line!() - 1, 16));
487+
488+
let (tx, rx) = Rc::new(Cell::new(None)).into_clones();
489+
fiber::defer_proc(|| tx.set(Some(fiber_name()))).join();
490+
let expected = format!("<rust:{}:{}:{}>", file!(), line!() - 1, 5);
491+
assert_eq!(rx.take().unwrap(), expected);
492+
}
493+

tests/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -382,6 +382,7 @@ fn run_tests(cfg: TestConfig) -> Result<bool, io::Error> {
382382
fiber::deferred_with_cond,
383383
fiber::lua_thread,
384384
fiber::lifetime,
385+
fiber::name,
385386

386387
fiber::channel::send_self,
387388
fiber::channel::send_full,

0 commit comments

Comments
 (0)