Skip to content

Commit 6626283

Browse files
committed
Add select built-in module
1 parent 2ea34c8 commit 6626283

File tree

2 files changed

+78
-0
lines changed

2 files changed

+78
-0
lines changed

vm/src/stdlib/mod.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,8 @@ mod os;
4343
#[cfg(all(unix, not(any(target_os = "android", target_os = "redox"))))]
4444
mod pwd;
4545
#[cfg(not(target_arch = "wasm32"))]
46+
mod select;
47+
#[cfg(not(target_arch = "wasm32"))]
4648
pub mod signal;
4749
#[cfg(not(target_arch = "wasm32"))]
4850
mod subprocess;
@@ -106,6 +108,7 @@ pub fn get_module_inits() -> HashMap<String, StdlibInitFunc> {
106108
modules.insert("_os".to_string(), Box::new(os::make_module));
107109
modules.insert("socket".to_string(), Box::new(socket::make_module));
108110
modules.insert("signal".to_string(), Box::new(signal::make_module));
111+
modules.insert("select".to_string(), Box::new(select::make_module));
109112
modules.insert("_subprocess".to_string(), Box::new(subprocess::make_module));
110113
modules.insert("zlib".to_string(), Box::new(zlib::make_module));
111114
}

vm/src/stdlib/select.rs

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
use crate::function::OptionalOption;
2+
use crate::pyobject::{PyObjectRef, PyResult};
3+
use crate::vm::VirtualMachine;
4+
5+
#[cfg(unix)]
6+
fn select_select(
7+
rlist: PyObjectRef,
8+
wlist: PyObjectRef,
9+
xlist: PyObjectRef,
10+
timeout: OptionalOption<f64>,
11+
vm: &VirtualMachine,
12+
) -> PyResult<PyObjectRef> {
13+
use nix::sys::select;
14+
use nix::sys::time::{TimeVal, TimeValLike};
15+
use std::os::unix::io::RawFd;
16+
17+
let seq2set = |list| -> PyResult<(Vec<RawFd>, select::FdSet)> {
18+
let v = vm.extract_elements(list)?;
19+
let mut fds = select::FdSet::new();
20+
for fd in &v {
21+
fds.insert(*fd);
22+
}
23+
Ok((v, fds))
24+
};
25+
26+
let (rlist, mut r) = seq2set(&rlist)?;
27+
let (wlist, mut w) = seq2set(&wlist)?;
28+
let (xlist, mut x) = seq2set(&xlist)?;
29+
30+
let mut timeout = timeout
31+
.flat_option()
32+
.map(|to| TimeVal::nanoseconds((to * 1e9) as i64));
33+
34+
select::select(
35+
None,
36+
Some(&mut r),
37+
Some(&mut w),
38+
Some(&mut x),
39+
timeout.as_mut(),
40+
)
41+
.map_err(|err| super::os::convert_nix_error(vm, err))?;
42+
43+
let set2list = |list: Vec<RawFd>, mut set: select::FdSet| -> PyObjectRef {
44+
vm.ctx.new_list(
45+
list.into_iter()
46+
.filter(|fd| set.contains(*fd))
47+
.map(|fd| vm.new_int(fd))
48+
.collect(),
49+
)
50+
};
51+
52+
let rlist = set2list(rlist, r);
53+
let wlist = set2list(wlist, w);
54+
let xlist = set2list(xlist, x);
55+
56+
Ok(vm.ctx.new_tuple(vec![rlist, wlist, xlist]))
57+
}
58+
59+
#[cfg(not(unix))]
60+
fn select_select(
61+
_rlist: PyObjectRef,
62+
_wlist: PyObjectRef,
63+
_xlist: PyObjectRef,
64+
_timeout: OptionalOption<f64>,
65+
_vm: &VirtualMachine,
66+
) {
67+
// TODO: select.select on windows
68+
unimplemented!("select.select")
69+
}
70+
71+
pub fn make_module(vm: &VirtualMachine) -> PyObjectRef {
72+
py_module!(vm, "select", {
73+
"select" => vm.ctx.new_rustfunc(select_select),
74+
})
75+
}

0 commit comments

Comments
 (0)