1use once_cell::sync::OnceCell;
2use smol::prelude::*;
3use smol::Async;
4use smol::Executor;
5use socket2::{Domain, Socket, Type};
6use std::{
7 convert::TryInto,
8 net::{SocketAddr, UdpSocket},
9};
10
11static USER_EXEC: OnceCell<&'static Executor> = OnceCell::new();
12
13pub(crate) fn spawn<T: Send + 'static>(
20 future: impl Future<Output = T> + Send + 'static,
21) -> smol::Task<T> {
22 if let Some(ex) = USER_EXEC.get() {
23 ex.spawn(future)
24 } else {
25 smolscale::spawn(future)
26 }
27}
28
29pub(crate) fn new_udp_socket_bind(addr: SocketAddr) -> std::io::Result<Async<UdpSocket>> {
31 let socket = Socket::new(
32 match addr {
33 SocketAddr::V4(_) => Domain::ipv4(),
34 SocketAddr::V6(_) => Domain::ipv6(),
35 },
36 Type::dgram(),
37 None,
38 )
39 .unwrap();
40 drop(socket.set_only_v6(false));
41 let _ = socket.set_recv_buffer_size(10 * 1024 * 1024);
42 let _ = socket.set_send_buffer_size(512 * 1024);
43 socket.bind(&addr.into())?;
44 Ok(socket.into_udp_socket().try_into().unwrap())
45}
46
47pub(crate) fn new_udp_socket_bind_sync(addr: SocketAddr) -> std::io::Result<UdpSocket> {
49 let socket = Socket::new(
50 match addr {
51 SocketAddr::V4(_) => Domain::ipv4(),
52 SocketAddr::V6(_) => Domain::ipv6(),
53 },
54 Type::dgram(),
55 None,
56 )
57 .unwrap();
58 drop(socket.set_only_v6(false));
59 let _ = socket.set_recv_buffer_size(10 * 1024 * 1024);
60 let _ = socket.set_send_buffer_size(512 * 1024);
61 socket.bind(&addr.into())?;
62 Ok(socket.into_udp_socket())
63}