mirror of
https://github.com/DragonOS-Community/DragonOS.git
synced 2025-06-09 07:06:47 +00:00
纸糊忙等tcp connecting,尚不明确连接可用的机制。
This commit is contained in:
parent
bd5f713617
commit
f438808421
@ -104,8 +104,7 @@ pub extern "sysv64" fn syscall_handler(frame: &mut TrapFrame) {
|
|||||||
];
|
];
|
||||||
mfence();
|
mfence();
|
||||||
let pid = ProcessManager::current_pcb().pid();
|
let pid = ProcessManager::current_pcb().pid();
|
||||||
let mut show =
|
let mut show = (syscall_num != SYS_SCHED) && (pid.data() >= 7);
|
||||||
(syscall_num != SYS_SCHED) && (pid.data() >= 7);
|
|
||||||
// false;
|
// false;
|
||||||
|
|
||||||
let to_print = SysCall::try_from(syscall_num);
|
let to_print = SysCall::try_from(syscall_num);
|
||||||
@ -113,24 +112,24 @@ pub extern "sysv64" fn syscall_handler(frame: &mut TrapFrame) {
|
|||||||
use SysCall::*;
|
use SysCall::*;
|
||||||
match to_print {
|
match to_print {
|
||||||
SYS_ACCEPT | SYS_ACCEPT4 | SYS_BIND | SYS_CONNECT | SYS_SHUTDOWN | SYS_LISTEN => {
|
SYS_ACCEPT | SYS_ACCEPT4 | SYS_BIND | SYS_CONNECT | SYS_SHUTDOWN | SYS_LISTEN => {
|
||||||
show &= false;
|
// show &= false;
|
||||||
}
|
}
|
||||||
SYS_RECVFROM | SYS_SENDTO | SYS_SENDMSG | SYS_RECVMSG => {
|
SYS_RECVFROM | SYS_SENDTO | SYS_SENDMSG | SYS_RECVMSG => {
|
||||||
show &= false;
|
// show &= false;
|
||||||
}
|
}
|
||||||
SYS_SOCKET | SYS_GETSOCKNAME | SYS_GETPEERNAME | SYS_SOCKETPAIR | SYS_SETSOCKOPT
|
SYS_SOCKET | SYS_GETSOCKNAME | SYS_GETPEERNAME | SYS_SOCKETPAIR | SYS_SETSOCKOPT
|
||||||
| SYS_GETSOCKOPT => {
|
| SYS_GETSOCKOPT => {
|
||||||
show &= false;
|
// show &= false;
|
||||||
}
|
}
|
||||||
SYS_OPEN | SYS_OPENAT | SYS_CREAT | SYS_CLOSE => {
|
SYS_OPEN | SYS_OPENAT | SYS_CREAT | SYS_CLOSE => {
|
||||||
show &= false;
|
// show &= false;
|
||||||
}
|
}
|
||||||
SYS_READ | SYS_WRITE | SYS_READV | SYS_WRITEV | SYS_PREAD64 | SYS_PWRITE64
|
SYS_READ | SYS_WRITE | SYS_READV | SYS_WRITEV | SYS_PREAD64 | SYS_PWRITE64
|
||||||
| SYS_PREADV | SYS_PWRITEV | SYS_PREADV2 => {
|
| SYS_PREADV | SYS_PWRITEV | SYS_PREADV2 => {
|
||||||
show &= false;
|
show &= false;
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
show &= false;
|
// show &= false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if show {
|
if show {
|
||||||
|
@ -246,8 +246,8 @@ impl IfaceCommon {
|
|||||||
|
|
||||||
self.bounds.read().iter().for_each(|bound_socket| {
|
self.bounds.read().iter().for_each(|bound_socket| {
|
||||||
// incase our inet socket missed the event, we manually notify it each time we poll
|
// incase our inet socket missed the event, we manually notify it each time we poll
|
||||||
bound_socket.on_iface_events();
|
|
||||||
if has_events {
|
if has_events {
|
||||||
|
bound_socket.on_iface_events();
|
||||||
bound_socket
|
bound_socket
|
||||||
.wait_queue()
|
.wait_queue()
|
||||||
.wakeup(Some(ProcessState::Blocked(true)));
|
.wakeup(Some(ProcessState::Blocked(true)));
|
||||||
|
@ -645,6 +645,7 @@ impl Iface for VirtioInterface {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn poll(&self) {
|
fn poll(&self) {
|
||||||
|
// log::debug!("VirtioInterface: poll");
|
||||||
self.iface_common.poll(self.device_inner.force_get_mut())
|
self.iface_common.poll(self.device_inner.force_get_mut())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -42,7 +42,7 @@ pub fn net_init() -> Result<(), SystemError> {
|
|||||||
|
|
||||||
fn dhcp_query() -> Result<(), SystemError> {
|
fn dhcp_query() -> Result<(), SystemError> {
|
||||||
let binding = NET_DEVICES.write_irqsave();
|
let binding = NET_DEVICES.write_irqsave();
|
||||||
log::debug!("binding: {:?}", *binding);
|
// log::debug!("binding: {:?}", *binding);
|
||||||
//由于现在os未实现在用户态为网卡动态分配内存,而lo网卡的id最先分配且ip固定不能被分配
|
//由于现在os未实现在用户态为网卡动态分配内存,而lo网卡的id最先分配且ip固定不能被分配
|
||||||
//所以特判取用id为1的网卡(也就是virtio_net)
|
//所以特判取用id为1的网卡(也就是virtio_net)
|
||||||
let net_face = binding.get(&1).ok_or(SystemError::ENODEV)?.clone();
|
let net_face = binding.get(&1).ok_or(SystemError::ENODEV)?.clone();
|
||||||
@ -63,7 +63,7 @@ fn dhcp_query() -> Result<(), SystemError> {
|
|||||||
// let dhcp_handle = SOCKET_SET.lock_irqsave().add(dhcp_socket);
|
// let dhcp_handle = SOCKET_SET.lock_irqsave().add(dhcp_socket);
|
||||||
let dhcp_handle = sockets().add(dhcp_socket);
|
let dhcp_handle = sockets().add(dhcp_socket);
|
||||||
|
|
||||||
const DHCP_TRY_ROUND: u8 = 10;
|
const DHCP_TRY_ROUND: u8 = 100;
|
||||||
for i in 0..DHCP_TRY_ROUND {
|
for i in 0..DHCP_TRY_ROUND {
|
||||||
log::debug!("DHCP try round: {}", i);
|
log::debug!("DHCP try round: {}", i);
|
||||||
net_face.poll();
|
net_face.poll();
|
||||||
@ -137,8 +137,8 @@ fn dhcp_query() -> Result<(), SystemError> {
|
|||||||
drop(binding);
|
drop(binding);
|
||||||
|
|
||||||
let sleep_time = PosixTimeSpec {
|
let sleep_time = PosixTimeSpec {
|
||||||
tv_sec: 5,
|
tv_sec: 0,
|
||||||
tv_nsec: 0,
|
tv_nsec: 50,
|
||||||
};
|
};
|
||||||
let _ = nanosleep(sleep_time)?;
|
let _ = nanosleep(sleep_time)?;
|
||||||
}
|
}
|
||||||
@ -147,7 +147,7 @@ fn dhcp_query() -> Result<(), SystemError> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn poll_ifaces() {
|
pub fn poll_ifaces() {
|
||||||
// log::debug!("poll_ifaces");
|
log::debug!("poll_ifaces");
|
||||||
let guard: RwLockReadGuard<BTreeMap<usize, Arc<dyn Iface>>> = NET_DEVICES.read_irqsave();
|
let guard: RwLockReadGuard<BTreeMap<usize, Arc<dyn Iface>>> = NET_DEVICES.read_irqsave();
|
||||||
if guard.len() == 0 {
|
if guard.len() == 0 {
|
||||||
warn!("poll_ifaces: No net driver found!");
|
warn!("poll_ifaces: No net driver found!");
|
||||||
|
@ -106,10 +106,8 @@ impl core::convert::TryFrom<u16> for AddressFamily {
|
|||||||
type Error = system_error::SystemError;
|
type Error = system_error::SystemError;
|
||||||
fn try_from(x: u16) -> Result<Self, Self::Error> {
|
fn try_from(x: u16) -> Result<Self, Self::Error> {
|
||||||
use num_traits::FromPrimitive;
|
use num_traits::FromPrimitive;
|
||||||
return <Self as FromPrimitive>::from_u16(x).ok_or({
|
// this will return EINVAL but still works, idk why
|
||||||
log::debug!("AddressFamily::try_from failed: x={}", x);
|
return <Self as FromPrimitive>::from_u16(x).ok_or(Self::Error::EINVAL);
|
||||||
Self::Error::EINVAL
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -84,11 +84,11 @@ impl UdpSocket {
|
|||||||
&self,
|
&self,
|
||||||
buf: &mut [u8],
|
buf: &mut [u8],
|
||||||
) -> Result<(usize, smoltcp::wire::IpEndpoint), SystemError> {
|
) -> Result<(usize, smoltcp::wire::IpEndpoint), SystemError> {
|
||||||
poll_ifaces();
|
|
||||||
let received = match self.inner.read().as_ref().expect("Udp Inner is None") {
|
let received = match self.inner.read().as_ref().expect("Udp Inner is None") {
|
||||||
UdpInner::Bound(bound) => bound.try_recv(buf),
|
UdpInner::Bound(bound) => bound.try_recv(buf),
|
||||||
_ => Err(ENOTCONN),
|
_ => Err(ENOTCONN),
|
||||||
};
|
};
|
||||||
|
poll_ifaces();
|
||||||
return received;
|
return received;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -207,16 +207,20 @@ impl Connecting {
|
|||||||
self.inner.with_mut(f)
|
self.inner.with_mut(f)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn into_result(self) -> (Inner, Option<SystemError>) {
|
pub fn into_result(self) -> (Inner, Result<(), SystemError>) {
|
||||||
use ConnectResult::*;
|
use ConnectResult::*;
|
||||||
let result = *self.result.read_irqsave();
|
let result = *self.result.read_irqsave();
|
||||||
match result {
|
match result {
|
||||||
Connecting => (Inner::Connecting(self), Some(EAGAIN_OR_EWOULDBLOCK)),
|
Connecting => (Inner::Connecting(self), Err(EAGAIN_OR_EWOULDBLOCK)),
|
||||||
Connected => (Inner::Established(Established { inner: self.inner }), None),
|
Connected => (Inner::Established(Established { inner: self.inner }), Ok(())),
|
||||||
Refused => (Inner::Init(Init::new_bound(self.inner)), Some(ECONNREFUSED)),
|
Refused => (Inner::Init(Init::new_bound(self.inner)), Err(ECONNREFUSED)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub unsafe fn into_established(self) -> Established {
|
||||||
|
Established { inner: self.inner }
|
||||||
|
}
|
||||||
|
|
||||||
/// Returns `true` when `conn_result` becomes ready, which indicates that the caller should
|
/// Returns `true` when `conn_result` becomes ready, which indicates that the caller should
|
||||||
/// invoke the `into_result()` method as soon as possible.
|
/// invoke the `into_result()` method as soon as possible.
|
||||||
///
|
///
|
||||||
@ -224,9 +228,9 @@ impl Connecting {
|
|||||||
/// _exactly_ once. The caller is responsible for not missing this event.
|
/// _exactly_ once. The caller is responsible for not missing this event.
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub(super) fn update_io_events(&self) -> bool {
|
pub(super) fn update_io_events(&self) -> bool {
|
||||||
if matches!(*self.result.read_irqsave(), ConnectResult::Connecting) {
|
// if matches!(*self.result.read_irqsave(), ConnectResult::Connecting) {
|
||||||
return false;
|
// return false;
|
||||||
}
|
// }
|
||||||
|
|
||||||
self.inner
|
self.inner
|
||||||
.with_mut(|socket: &mut smoltcp::socket::tcp::Socket| {
|
.with_mut(|socket: &mut smoltcp::socket::tcp::Socket| {
|
||||||
@ -237,11 +241,14 @@ impl Connecting {
|
|||||||
|
|
||||||
// Connected
|
// Connected
|
||||||
if socket.can_send() {
|
if socket.can_send() {
|
||||||
|
log::debug!("can send");
|
||||||
*result = ConnectResult::Connected;
|
*result = ConnectResult::Connected;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
// Connecting
|
// Connecting
|
||||||
if socket.is_open() {
|
if socket.is_open() {
|
||||||
|
log::debug!("connecting");
|
||||||
|
*result = ConnectResult::Connecting;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
// Refused
|
// Refused
|
||||||
@ -309,7 +316,6 @@ impl Listening {
|
|||||||
});
|
});
|
||||||
|
|
||||||
if let Some(position) = position {
|
if let Some(position) = position {
|
||||||
// log::debug!("Can accept!");
|
|
||||||
self.connect
|
self.connect
|
||||||
.store(position, core::sync::atomic::Ordering::Relaxed);
|
.store(position, core::sync::atomic::Ordering::Relaxed);
|
||||||
pollee.fetch_or(
|
pollee.fetch_or(
|
||||||
@ -317,7 +323,6 @@ impl Listening {
|
|||||||
core::sync::atomic::Ordering::Relaxed,
|
core::sync::atomic::Ordering::Relaxed,
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
// log::debug!("Can't accept!");
|
|
||||||
pollee.fetch_and(
|
pollee.fetch_and(
|
||||||
!EPollEventType::EPOLLIN.bits() as usize,
|
!EPollEventType::EPOLLIN.bits() as usize,
|
||||||
core::sync::atomic::Ordering::Relaxed,
|
core::sync::atomic::Ordering::Relaxed,
|
||||||
|
@ -4,7 +4,6 @@ use system_error::SystemError::{self, *};
|
|||||||
|
|
||||||
use crate::libs::rwlock::RwLock;
|
use crate::libs::rwlock::RwLock;
|
||||||
use crate::net::event_poll::EPollEventType;
|
use crate::net::event_poll::EPollEventType;
|
||||||
use crate::net::net_core::poll_ifaces;
|
|
||||||
use crate::net::socket::*;
|
use crate::net::socket::*;
|
||||||
use crate::sched::SchedMode;
|
use crate::sched::SchedMode;
|
||||||
use inet::{InetSocket, UNSPECIFIED_LOCAL_ENDPOINT_V4, UNSPECIFIED_LOCAL_ENDPOINT_V6};
|
use inet::{InetSocket, UNSPECIFIED_LOCAL_ENDPOINT_V4, UNSPECIFIED_LOCAL_ENDPOINT_V6};
|
||||||
@ -29,14 +28,14 @@ pub struct TcpSocket {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl TcpSocket {
|
impl TcpSocket {
|
||||||
pub fn new(nonblock: bool, ver: smoltcp::wire::IpVersion) -> Arc<Self> {
|
pub fn new(_nonblock: bool, ver: smoltcp::wire::IpVersion) -> Arc<Self> {
|
||||||
Arc::new_cyclic(|me| Self {
|
Arc::new_cyclic(|me| Self {
|
||||||
inner: RwLock::new(Some(Inner::Init(Init::new(ver)))),
|
inner: RwLock::new(Some(Inner::Init(Init::new(ver)))),
|
||||||
shutdown: Shutdown::new(),
|
shutdown: Shutdown::new(),
|
||||||
nonblock: AtomicBool::new(nonblock),
|
nonblock: AtomicBool::new(false),
|
||||||
wait_queue: WaitQueue::default(),
|
wait_queue: WaitQueue::default(),
|
||||||
self_ref: me.clone(),
|
self_ref: me.clone(),
|
||||||
pollee: AtomicUsize::new((EP::EPOLLIN.bits() | EP::EPOLLOUT.bits()) as usize),
|
pollee: AtomicUsize::new(0_usize),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -100,7 +99,7 @@ impl TcpSocket {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn try_accept(&self) -> Result<(Arc<TcpSocket>, smoltcp::wire::IpEndpoint), SystemError> {
|
pub fn try_accept(&self) -> Result<(Arc<TcpSocket>, smoltcp::wire::IpEndpoint), SystemError> {
|
||||||
poll_ifaces();
|
// poll_ifaces();
|
||||||
match self.inner.write().as_mut().expect("Tcp Inner is None") {
|
match self.inner.write().as_mut().expect("Tcp Inner is None") {
|
||||||
Inner::Listening(listening) => listening.accept().map(|(stream, remote)| {
|
Inner::Listening(listening) => listening.accept().map(|(stream, remote)| {
|
||||||
(
|
(
|
||||||
@ -112,46 +111,48 @@ impl TcpSocket {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SHOULD refactor
|
||||||
pub fn start_connect(
|
pub fn start_connect(
|
||||||
&self,
|
&self,
|
||||||
remote_endpoint: smoltcp::wire::IpEndpoint,
|
remote_endpoint: smoltcp::wire::IpEndpoint,
|
||||||
) -> Result<(), SystemError> {
|
) -> Result<(), SystemError> {
|
||||||
let mut writer = self.inner.write();
|
let mut writer = self.inner.write();
|
||||||
let inner = writer.take().expect("Tcp Inner is None");
|
let inner = writer.take().expect("Tcp Inner is None");
|
||||||
let (init, err) = match inner {
|
let (init, result) = match inner {
|
||||||
Inner::Init(init) => {
|
Inner::Init(init) => {
|
||||||
let conn_result = init.connect(remote_endpoint);
|
let conn_result = init.connect(remote_endpoint);
|
||||||
match conn_result {
|
match conn_result {
|
||||||
Ok(connecting) => (
|
Ok(connecting) => (
|
||||||
Inner::Connecting(connecting),
|
Inner::Connecting(connecting),
|
||||||
if self.is_nonblock() {
|
if !self.is_nonblock() {
|
||||||
None
|
Ok(())
|
||||||
} else {
|
} else {
|
||||||
Some(EINPROGRESS)
|
Err(EINPROGRESS)
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
Err((init, err)) => (Inner::Init(init), Some(err)),
|
Err((init, err)) => (Inner::Init(init), Err(err)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Inner::Connecting(connecting) if self.is_nonblock() => {
|
Inner::Connecting(connecting) if self.is_nonblock() => {
|
||||||
(Inner::Connecting(connecting), Some(EALREADY))
|
(Inner::Connecting(connecting), Err(EALREADY))
|
||||||
}
|
}
|
||||||
Inner::Connecting(connecting) => (Inner::Connecting(connecting), None),
|
Inner::Connecting(connecting) => (Inner::Connecting(connecting), Ok(())),
|
||||||
Inner::Listening(inner) => (Inner::Listening(inner), Some(EISCONN)),
|
Inner::Listening(inner) => (Inner::Listening(inner), Err(EISCONN)),
|
||||||
Inner::Established(inner) => (Inner::Established(inner), Some(EISCONN)),
|
Inner::Established(inner) => (Inner::Established(inner), Err(EISCONN)),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
match result {
|
||||||
|
Ok(()) | Err(EINPROGRESS) => {
|
||||||
|
init.iface().unwrap().poll();
|
||||||
|
},
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
|
||||||
writer.replace(init);
|
writer.replace(init);
|
||||||
|
return result;
|
||||||
drop(writer);
|
|
||||||
|
|
||||||
poll_ifaces();
|
|
||||||
|
|
||||||
if let Some(err) = err {
|
|
||||||
return Err(err);
|
|
||||||
}
|
|
||||||
return Ok(());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// for irq use
|
||||||
pub fn finish_connect(&self) -> Result<(), SystemError> {
|
pub fn finish_connect(&self) -> Result<(), SystemError> {
|
||||||
let mut writer = self.inner.write();
|
let mut writer = self.inner.write();
|
||||||
let Inner::Connecting(conn) = writer.take().expect("Tcp Inner is None") else {
|
let Inner::Connecting(conn) = writer.take().expect("Tcp Inner is None") else {
|
||||||
@ -159,22 +160,32 @@ impl TcpSocket {
|
|||||||
return Err(EINVAL);
|
return Err(EINVAL);
|
||||||
};
|
};
|
||||||
|
|
||||||
let (inner, err) = conn.into_result();
|
let (inner, result) = conn.into_result();
|
||||||
writer.replace(inner);
|
writer.replace(inner);
|
||||||
drop(writer);
|
drop(writer);
|
||||||
|
|
||||||
if let Some(err) = err {
|
result
|
||||||
return Err(err);
|
|
||||||
}
|
|
||||||
return Ok(());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn check_connect(&self) -> Result<(), SystemError> {
|
pub fn check_connect(&self) -> Result<(), SystemError> {
|
||||||
match self.inner.read().as_ref().expect("Tcp Inner is None") {
|
self.update_events();
|
||||||
Inner::Connecting(_) => Err(EAGAIN_OR_EWOULDBLOCK),
|
let mut write_state = self.inner.write();
|
||||||
Inner::Established(_) => Ok(()), // TODO check established
|
let inner = write_state.take().expect("Tcp Inner is None");
|
||||||
_ => Err(EINVAL), // TODO socket error options
|
let (replace, result) = match inner {
|
||||||
|
Inner::Connecting(conn) => {
|
||||||
|
conn.into_result()
|
||||||
}
|
}
|
||||||
|
Inner::Established(es) => {
|
||||||
|
log::warn!("TODO: check new established");
|
||||||
|
(Inner::Established(es), Ok(()))
|
||||||
|
}, // TODO check established
|
||||||
|
_ => {
|
||||||
|
log::warn!("TODO: connecting socket error options");
|
||||||
|
(inner, Err(EINVAL))
|
||||||
|
}, // TODO socket error options
|
||||||
|
};
|
||||||
|
write_state.replace(replace);
|
||||||
|
result
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn try_recv(&self, buf: &mut [u8]) -> Result<usize, SystemError> {
|
pub fn try_recv(&self, buf: &mut [u8]) -> Result<usize, SystemError> {
|
||||||
@ -194,20 +205,23 @@ impl TcpSocket {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn try_send(&self, buf: &[u8]) -> Result<usize, SystemError> {
|
pub fn try_send(&self, buf: &[u8]) -> Result<usize, SystemError> {
|
||||||
match self.inner.read().as_ref().expect("Tcp Inner is None") {
|
// TODO: add nonblock check of connecting socket
|
||||||
|
let sent = match self.inner.read().as_ref().expect("Tcp Inner is None") {
|
||||||
Inner::Established(inner) => {
|
Inner::Established(inner) => {
|
||||||
let sent = inner.send_slice(buf);
|
inner.send_slice(buf)
|
||||||
poll_ifaces();
|
|
||||||
sent
|
|
||||||
}
|
}
|
||||||
_ => Err(EINVAL),
|
_ => Err(EINVAL),
|
||||||
}
|
};
|
||||||
|
self.inner.read().as_ref().unwrap().iface().unwrap().poll();
|
||||||
|
sent
|
||||||
}
|
}
|
||||||
|
|
||||||
fn update_events(&self) -> bool {
|
fn update_events(&self) -> bool {
|
||||||
match self.inner.read().as_ref().expect("Tcp Inner is None") {
|
match self.inner.read().as_ref().expect("Tcp Inner is None") {
|
||||||
Inner::Init(_) => false,
|
Inner::Init(_) => false,
|
||||||
Inner::Connecting(connecting) => connecting.update_io_events(),
|
Inner::Connecting(connecting) => {
|
||||||
|
connecting.update_io_events()
|
||||||
|
},
|
||||||
Inner::Established(established) => {
|
Inner::Established(established) => {
|
||||||
established.update_io_events(&self.pollee);
|
established.update_io_events(&self.pollee);
|
||||||
false
|
false
|
||||||
@ -219,12 +233,16 @@ impl TcpSocket {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// should only call on accept
|
fn in_notify(&self) -> bool {
|
||||||
fn is_acceptable(&self) -> bool {
|
self.update_events();
|
||||||
// (self.poll() & EP::EPOLLIN.bits() as usize) != 0
|
// shouldn't pollee but just get the status of the socket
|
||||||
self.inner.read().as_ref().unwrap().iface().unwrap().poll();
|
|
||||||
EP::from_bits_truncate(self.poll() as u32).contains(EP::EPOLLIN)
|
EP::from_bits_truncate(self.poll() as u32).contains(EP::EPOLLIN)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn out_notify(&self) -> bool {
|
||||||
|
self.update_events();
|
||||||
|
EP::from_bits_truncate(self.poll() as u32).contains(EP::EPOLLOUT)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Socket for TcpSocket {
|
impl Socket for TcpSocket {
|
||||||
@ -254,10 +272,18 @@ impl Socket for TcpSocket {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn connect(&self, endpoint: Endpoint) -> Result<(), SystemError> {
|
fn connect(&self, endpoint: Endpoint) -> Result<(), SystemError> {
|
||||||
if let Endpoint::Ip(addr) = endpoint {
|
let Endpoint::Ip(endpoint) = endpoint else {
|
||||||
return self.start_connect(addr);
|
log::debug!("TcpSocket::connect: invalid endpoint");
|
||||||
}
|
|
||||||
return Err(EINVAL);
|
return Err(EINVAL);
|
||||||
|
};
|
||||||
|
self.start_connect(endpoint)?; // Only Nonblock or error will return error.
|
||||||
|
|
||||||
|
return loop {
|
||||||
|
match self.check_connect() {
|
||||||
|
Err(EAGAIN_OR_EWOULDBLOCK) => {},
|
||||||
|
result => break result,
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn poll(&self) -> usize {
|
fn poll(&self) -> usize {
|
||||||
@ -269,15 +295,17 @@ impl Socket for TcpSocket {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn accept(&self) -> Result<(Arc<Inode>, Endpoint), SystemError> {
|
fn accept(&self) -> Result<(Arc<Inode>, Endpoint), SystemError> {
|
||||||
// could block io
|
|
||||||
if self.is_nonblock() {
|
if self.is_nonblock() {
|
||||||
self.try_accept()
|
self.try_accept()
|
||||||
} else {
|
} else {
|
||||||
loop {
|
loop {
|
||||||
// log::debug!("TcpSocket::accept: wake up");
|
|
||||||
match self.try_accept() {
|
match self.try_accept() {
|
||||||
Err(EAGAIN_OR_EWOULDBLOCK) => {
|
Err(EAGAIN_OR_EWOULDBLOCK) => {
|
||||||
wq_wait_event_interruptible!(self.wait_queue, self.is_acceptable(), {})?;
|
wq_wait_event_interruptible!(
|
||||||
|
self.wait_queue,
|
||||||
|
self.in_notify(),
|
||||||
|
{}
|
||||||
|
)?;
|
||||||
}
|
}
|
||||||
result => break result,
|
result => break result,
|
||||||
}
|
}
|
||||||
@ -311,11 +339,18 @@ impl Socket for TcpSocket {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn close(&self) -> Result<(), SystemError> {
|
fn close(&self) -> Result<(), SystemError> {
|
||||||
self.inner
|
let inner = self.inner
|
||||||
.read()
|
.write()
|
||||||
.as_ref()
|
.take().unwrap();
|
||||||
.map(|inner| match inner {
|
|
||||||
Inner::Connecting(_) => Err(EINPROGRESS),
|
match inner {
|
||||||
|
// complete connecting socket close logic
|
||||||
|
Inner::Connecting(conn) => {
|
||||||
|
let conn = unsafe { conn.into_established() };
|
||||||
|
conn.close();
|
||||||
|
conn.release();
|
||||||
|
Ok(())
|
||||||
|
},
|
||||||
Inner::Established(es) => {
|
Inner::Established(es) => {
|
||||||
es.close();
|
es.close();
|
||||||
es.release();
|
es.release();
|
||||||
@ -329,8 +364,7 @@ impl Socket for TcpSocket {
|
|||||||
init.close();
|
init.close();
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
})
|
}
|
||||||
.unwrap_or(Ok(()))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_option(&self, level: PSOL, name: usize, val: &[u8]) -> Result<(), SystemError> {
|
fn set_option(&self, level: PSOL, name: usize, val: &[u8]) -> Result<(), SystemError> {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user