Skip to content

Commit 168505c

Browse files
author
Jethro Beekman
committed
Update usercall-extension example to tokio 0.2
1 parent 20a56c4 commit 168505c

File tree

3 files changed

+61
-54
lines changed

3 files changed

+61
-54
lines changed

examples/usercall-extension/app/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,6 @@
22
name = "app"
33
version = "0.1.0"
44
authors = ["Vardhan Thigle <[email protected]>"]
5+
edition = "2018"
56

67
[dependencies]

examples/usercall-extension/runner/Cargo.toml

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,12 @@ name = "runner"
33
version = "0.1.0"
44
authors = ["Fortanix, Inc."]
55
license = "MPL-2.0"
6+
edition = "2018"
67

78
[dependencies]
8-
aesm-client = { version = "0.2.0", features = ["sgxs"], path="../../../aesm-client"}
9-
enclave-runner = { version = "0.2.0", path="../../../enclave-runner"}
10-
sgxs-loaders = { version = "0.3.0", path="../../../sgxs-loaders"}
11-
tokio = "0.1.22" # MIT
9+
aesm-client = { version = "0.5.0", features = ["sgxs"], path="../../../intel-sgx/aesm-client"}
10+
enclave-runner = { version = "0.5.0", path="../../../intel-sgx/enclave-runner"}
11+
sgxs-loaders = { version = "0.3.0", path="../../../intel-sgx/sgxs-loaders"}
12+
futures = "0.3"
13+
tokio = { version = "0.2", features = ["process"] }
14+
pin-utils = "0.1"

examples/usercall-extension/runner/src/main.rs

Lines changed: 53 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -4,93 +4,96 @@
44
* License, v. 2.0. If a copy of the MPL was not distributed with this
55
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
66

7-
extern crate aesm_client;
8-
extern crate enclave_runner;
9-
extern crate sgxs_loaders;
10-
extern crate tokio;
7+
use std::future::Future;
8+
use std::io::Result as IoResult;
9+
use std::pin::Pin;
10+
use std::process::Stdio;
11+
use std::task::{Context, Poll};
12+
13+
use futures::FutureExt;
14+
use tokio::io::{AsyncRead, AsyncWrite};
15+
use tokio::process::{ChildStdin, ChildStdout, Command};
1116

1217
use aesm_client::AesmClient;
1318
use enclave_runner::usercalls::{AsyncStream, UsercallExtension};
1419
use enclave_runner::EnclaveBuilder;
1520
use sgxs_loaders::isgx::Device as IsgxDevice;
16-
use tokio::io::{AsyncRead, AsyncWrite};
17-
use std::io::{Read, Result as IoResult, Write};
18-
use std::process::{Child, Command, Stdio};
19-
use tokio::sync::lock::Lock;
20-
use tokio::prelude::Async;
2121

2222
/// This example demonstrates use of usercall extensions.
2323
/// User call extension allow the enclave code to "connect" to an external service via a customized enclave runner.
2424
/// Here we customize the runner to intercept calls to connect to an address "cat" which actually connects the enclave application to
2525
/// stdin and stdout of `cat` process.
2626
struct CatService {
27-
c: Lock<Child>,
27+
stdin: ChildStdin,
28+
stdout: ChildStdout,
2829
}
2930

3031
impl CatService {
32+
// SAFETY: `Self` doesn't implement `Drop` or `Unpin`, and isn't `repr(packed)`
33+
pin_utils::unsafe_pinned!(stdin: ChildStdin);
34+
pin_utils::unsafe_pinned!(stdout: ChildStdout);
35+
3136
fn new() -> Result<CatService, std::io::Error> {
3237
Command::new("/bin/cat")
3338
.stdout(Stdio::piped())
3439
.stdin(Stdio::piped())
3540
.spawn()
36-
.map(|c| Lock::new(c))
37-
.map(|c| CatService { c })
38-
}
39-
}
40-
41-
macro_rules! poll_lock_wouldblock {
42-
($lock:expr) => {
43-
match $lock.clone().poll_lock() {
44-
Async::NotReady => Err(std::io::ErrorKind::WouldBlock.into()),
45-
Async::Ready(ret) => IoResult::Ok(ret),
46-
}
41+
.map(|mut c| CatService {
42+
stdin: c.stdin.take().unwrap(),
43+
stdout: c.stdout.take().unwrap(),
44+
})
4745
}
4846
}
4947

50-
impl Read for CatService {
51-
fn read(&mut self, buf: &mut [u8]) -> IoResult<usize> {
52-
poll_lock_wouldblock!(self.c)?.stdout.as_mut().unwrap().read(buf)
48+
impl AsyncRead for CatService {
49+
fn poll_read(
50+
self: Pin<&mut Self>,
51+
cx: &mut Context,
52+
buf: &mut [u8]
53+
) -> Poll<IoResult<usize>> {
54+
self.stdout().poll_read(cx, buf)
5355
}
5456
}
5557

56-
impl Write for CatService {
57-
fn write(&mut self, buf: &[u8]) -> IoResult<usize> {
58-
poll_lock_wouldblock!(self.c)?.stdin.as_mut().unwrap().write(buf)
58+
impl AsyncWrite for CatService {
59+
fn poll_write(
60+
self: Pin<&mut Self>,
61+
cx: &mut Context,
62+
buf: &[u8]
63+
) -> Poll<IoResult<usize>> {
64+
self.stdin().poll_write(cx, buf)
5965
}
6066

61-
fn flush(&mut self) -> IoResult<()> {
62-
poll_lock_wouldblock!(self.c)?.stdin.as_mut().unwrap().flush()
67+
fn poll_flush(self: Pin<&mut Self>, cx: &mut Context) -> Poll<IoResult<()>> {
68+
self.stdin().poll_flush(cx)
6369
}
64-
}
65-
66-
impl AsyncRead for CatService {
67-
}
6870

69-
impl AsyncWrite for CatService {
70-
fn shutdown(&mut self) -> tokio::prelude::Poll<(), std::io::Error> {
71-
Ok(().into())
71+
fn poll_shutdown(self: Pin<&mut Self>, cx: &mut Context) -> Poll<IoResult<()>> {
72+
self.stdin().poll_shutdown(cx)
7273
}
7374
}
7475

7576
#[derive(Debug)]
7677
struct ExternalService;
7778
// Ignoring local_addr and peer_addr, as they are not relavent in the current context.
7879
impl UsercallExtension for ExternalService {
79-
fn connect_stream(
80-
&self,
81-
addr: &str,
82-
_local_addr: Option<&mut String>,
83-
_peer_addr: Option<&mut String>,
84-
) -> IoResult<Option<Box<dyn AsyncStream>>> {
85-
// If the passed address is not "cat", we return none, whereby the passed address gets treated as
86-
// an IP address which is the default behavior.
87-
match &*addr {
88-
"cat" => {
89-
let stream = CatService::new()?;
90-
Ok(Some(Box::new(stream)))
80+
fn connect_stream<'future>(
81+
&'future self,
82+
addr: &'future str,
83+
_local_addr: Option<&'future mut String>,
84+
_peer_addr: Option<&'future mut String>,
85+
) -> std::pin::Pin<Box<dyn Future<Output = IoResult<Option<Box<dyn AsyncStream>>>> +'future>> {
86+
async move {
87+
// If the passed address is not "cat", we return none, whereby the passed address gets treated as
88+
// an IP address which is the default behavior.
89+
match &*addr {
90+
"cat" => {
91+
let stream = CatService::new()?;
92+
Ok(Some(Box::new(stream) as _))
93+
}
94+
_ => Ok(None),
9195
}
92-
_ => Ok(None),
93-
}
96+
}.boxed_local()
9497
}
9598
}
9699

0 commit comments

Comments
 (0)