1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
use {
crate::xenbus::{copy_from_ring, mask_xenstore_idx, XENBUS},
alloc::{string::String, vec, vec::Vec},
core::{
mem::{size_of, ManuallyDrop},
slice,
sync::atomic::{fence, Ordering},
},
xen_sys::{xsd_sockmsg, xsd_sockmsg_type_XS_WATCH_EVENT},
};
pub fn task() {
let mut msg = xsd_sockmsg {
type_: 0,
req_id: 0,
tx_id: 0,
len: 0,
};
loop {
let mut xb = XENBUS.lock();
if (xb.interface.rsp_prod - xb.interface.rsp_cons) < size_of::<xsd_sockmsg>() as u32 {
continue;
}
unsafe {
copy_from_ring(
&xb.interface.rsp,
slice::from_raw_parts_mut(&mut msg as *mut _ as *mut _, size_of::<xsd_sockmsg>()),
mask_xenstore_idx(xb.interface.rsp_cons) as usize,
size_of::<xsd_sockmsg>(),
)
};
if xb.interface.rsp_prod - xb.interface.rsp_cons < size_of::<xsd_sockmsg>() as u32 + msg.len
{
continue;
}
if msg.type_ == xsd_sockmsg_type_XS_WATCH_EVENT {
unimplemented!();
} else {
let mut data = vec![0; msg.len as usize];
unsafe {
copy_from_ring(
&xb.interface.rsp,
data.as_mut_slice(),
mask_xenstore_idx(xb.interface.rsp_cons + size_of::<xsd_sockmsg>() as u32)
as usize,
msg.len as usize,
)
};
if let Some(0) = data.last() {
data.truncate(data.len() - 1);
}
let data = {
let mut v = ManuallyDrop::new(data);
let p = v.as_mut_ptr();
let len = v.len();
let cap = v.capacity();
unsafe { Vec::from_raw_parts(p as *mut u8, len, cap) }
};
let contents = String::from_utf8(data).expect("XenBus returned invalid UTF-8");
xb.responses.insert(msg.req_id, (msg.into(), contents));
}
fence(Ordering::SeqCst);
xb.interface.rsp_cons += size_of::<xsd_sockmsg>() as u32 + msg.len;
fence(Ordering::SeqCst);
xb.notify();
return;
}
}