Skip to content

Commit 115dba7

Browse files
committed
feat(tun): poll thread park only if tx channel is empty
1 parent ea3d333 commit 115dba7

File tree

3 files changed

+47
-11
lines changed

3 files changed

+47
-11
lines changed

crates/shadowsocks-service/src/local/tun/tcp.rs

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -239,6 +239,7 @@ pub struct TcpTun {
239239
balancer: PingBalancer,
240240
iface_rx: mpsc::UnboundedReceiver<Vec<u8>>,
241241
iface_tx: mpsc::UnboundedSender<Vec<u8>>,
242+
iface_tx_avail: Arc<AtomicBool>,
242243
}
243244

244245
impl Drop for TcpTun {
@@ -255,7 +256,7 @@ impl TcpTun {
255256
capabilities.medium = Medium::Ip;
256257
capabilities.max_transmission_unit = mtu as usize;
257258

258-
let (mut device, iface_rx, iface_tx) = VirtTunDevice::new(capabilities);
259+
let (mut device, iface_rx, iface_tx, iface_tx_avail) = VirtTunDevice::new(capabilities);
259260

260261
let mut iface_config = InterfaceConfig::default();
261262
iface_config.random_seed = rand::random();
@@ -444,11 +445,13 @@ impl TcpTun {
444445
socket_set.remove(socket_handle);
445446
}
446447

447-
let next_duration = iface
448-
.poll_delay(before_poll, &socket_set)
449-
.unwrap_or(SmolDuration::from_millis(5));
450-
if next_duration != SmolDuration::ZERO {
451-
thread::park_timeout(Duration::from(next_duration));
448+
if !device.recv_available() {
449+
let next_duration = iface
450+
.poll_delay(before_poll, &socket_set)
451+
.unwrap_or(SmolDuration::from_millis(5));
452+
if next_duration != SmolDuration::ZERO {
453+
thread::park_timeout(Duration::from(next_duration));
454+
}
452455
}
453456
}
454457

@@ -467,6 +470,7 @@ impl TcpTun {
467470
balancer,
468471
iface_rx,
469472
iface_tx,
473+
iface_tx_avail,
470474
}
471475
}
472476

@@ -525,6 +529,7 @@ impl TcpTun {
525529
}
526530

527531
// Wake up and poll the interface.
532+
self.iface_tx_avail.store(true, Ordering::Release);
528533
self.manager_notify.notify();
529534
}
530535

crates/shadowsocks-service/src/local/tun/virt_device.rs

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,12 @@
11
//! Virtual Device for receiving packets from tun
22
3-
use std::marker::PhantomData;
3+
use std::{
4+
marker::PhantomData,
5+
sync::{
6+
atomic::{AtomicBool, Ordering},
7+
Arc,
8+
},
9+
};
410

511
use smoltcp::{
612
phy::{self, Device, DeviceCapabilities},
@@ -12,25 +18,39 @@ pub struct VirtTunDevice {
1218
capabilities: DeviceCapabilities,
1319
in_buf: mpsc::UnboundedReceiver<Vec<u8>>,
1420
out_buf: mpsc::UnboundedSender<Vec<u8>>,
21+
in_buf_avail: Arc<AtomicBool>,
1522
}
1623

1724
impl VirtTunDevice {
1825
pub fn new(
1926
capabilities: DeviceCapabilities,
20-
) -> (Self, mpsc::UnboundedReceiver<Vec<u8>>, mpsc::UnboundedSender<Vec<u8>>) {
27+
) -> (
28+
Self,
29+
mpsc::UnboundedReceiver<Vec<u8>>,
30+
mpsc::UnboundedSender<Vec<u8>>,
31+
Arc<AtomicBool>,
32+
) {
2133
let (iface_tx, iface_output) = mpsc::unbounded_channel();
2234
let (iface_input, iface_rx) = mpsc::unbounded_channel();
35+
let in_buf_avail = Arc::new(AtomicBool::new(false));
2336

2437
(
2538
Self {
2639
capabilities,
2740
in_buf: iface_rx,
2841
out_buf: iface_tx,
42+
in_buf_avail: in_buf_avail.clone(),
2943
},
3044
iface_output,
3145
iface_input,
46+
in_buf_avail,
3247
)
3348
}
49+
50+
#[inline]
51+
pub fn recv_available(&self) -> bool {
52+
self.in_buf_avail.load(Ordering::Acquire)
53+
}
3454
}
3555

3656
impl Device for VirtTunDevice {
@@ -46,6 +66,7 @@ impl Device for VirtTunDevice {
4666
let tx = VirtTxToken(self);
4767
return Some((rx, tx));
4868
}
69+
self.in_buf_avail.store(false, Ordering::Release);
4970
None
5071
}
5172

crates/shadowsocks-service/src/manager/server.rs

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,22 @@ use shadowsocks::{
1111
crypto::CipherKind,
1212
dns_resolver::DnsResolver,
1313
manager::protocol::{
14-
self, AddRequest, AddResponse, ErrorResponse, ListResponse, ManagerRequest, PingResponse, RemoveRequest,
15-
RemoveResponse, ServerUserConfig, StatRequest,
14+
self,
15+
AddRequest,
16+
AddResponse,
17+
ErrorResponse,
18+
ListResponse,
19+
ManagerRequest,
20+
PingResponse,
21+
RemoveRequest,
22+
RemoveResponse,
23+
ServerUserConfig,
24+
StatRequest,
1625
},
1726
net::{AcceptOpts, ConnectOpts},
1827
plugin::PluginConfig,
19-
ManagerListener, ServerAddr,
28+
ManagerListener,
29+
ServerAddr,
2030
};
2131
use tokio::{sync::Mutex, task::JoinHandle};
2232

0 commit comments

Comments
 (0)