Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 5 additions & 2 deletions runtime/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -497,11 +497,14 @@ mod async_ {
ReturnStyle::Result => vec![result],
};

let mut call = MyCall::new(results);
func.call_task_return(&mut call);
// `task.return` traps while any borrow lent to this task is still
// outstanding, so drop them first.
if borrows != 0 {
release_borrows(py, *unsafe { Box::from_raw(borrows as *mut Vec<Borrow>) });
}

let mut call = MyCall::new(results);
func.call_task_return(&mut call);
}

#[pyo3::pyfunction]
Expand Down
3 changes: 3 additions & 0 deletions src/test/python_source/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -253,6 +253,9 @@ class Tests(tests.WorldExports):
def test_resource_borrow_import(self, v: int) -> int:
return resource_borrow_import.foo(resource_borrow_import.Thing(v + 1)) + 4

async def test_resource_borrow_import_async(self, t: resource_borrow_import.Thing) -> int:
return resource_borrow_import.foo(t) + 4

def test_resource_alias(self, things: List[imports.resource_alias1.Thing]) -> List[imports.resource_alias1.Thing]:
return things

Expand Down
25 changes: 25 additions & 0 deletions src/test/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -384,6 +384,31 @@ fn resource_borrow_import() -> Result<()> {
})
}

#[test]
fn resource_borrow_import_async_export() -> Result<()> {
// An async export that is lent a borrow of an imported resource must release
// it before `task.return`, or the host traps with "borrow handles still
// remain at the end of the call".
TESTER.test(|world, store, runtime| {
runtime.block_on(async {
let thing = store.data_mut().ctx().table.push(ThingU32(42))?;

assert_eq!(
42 + 3 + 4,
store
.run_concurrent(async |store| {
world
.call_test_resource_borrow_import_async(store, thing)
.await
})
.await??
);

Ok(())
})
})
}

#[test]
fn resource_borrow_export() -> Result<()> {
TESTER.test(|world, store, runtime| {
Expand Down
3 changes: 3 additions & 0 deletions src/test/wit/tests.wit
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,7 @@ interface empty-resource {
world tests {
use resource-alias1.{thing};
use resource-floats.{float};
use resource-borrow-import.{thing as imported-thing};

export simple-export;
import simple-import-and-export;
Expand Down Expand Up @@ -230,6 +231,8 @@ world tests {

export test-resource-borrow-import: func(v: u32) -> u32;

export test-resource-borrow-import-async: async func(t: borrow<imported-thing>) -> u32;

export test-resource-alias: func(things: list<thing>) -> list<thing>;

export add: func(a: borrow<float>, b: borrow<float>) -> own<float>;
Expand Down
Loading