Merge pull request #1064 from fslongjin:patch-fix-a-locking-problem

fix: 修正IfaceCommon的bounds字段的锁使用问题&调度问题
This commit is contained in:
Samuel Dai 2024-11-28 22:26:17 +08:00 committed by GitHub
commit 0896c3311c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 22 additions and 29 deletions

View File

@ -43,7 +43,7 @@ unsafe extern "C" fn x86_64_do_irq(trap_frame: &mut TrapFrame, vector: u32) {
} }
// 检测当前进程是否可被调度 // 检测当前进程是否可被调度
if (current_pcb_flags().contains(ProcessFlags::NEED_SCHEDULE)) if (current_pcb_flags().contains(ProcessFlags::NEED_SCHEDULE))
&& vector == APIC_TIMER_IRQ_NUM.data() || vector == APIC_TIMER_IRQ_NUM.data()
{ {
__schedule(SchedMode::SM_PREEMPT); __schedule(SchedMode::SM_PREEMPT);
} }

View File

@ -244,11 +244,11 @@ impl IfaceCommon {
self.poll_at_ms.store(0, Ordering::Relaxed); self.poll_at_ms.store(0, Ordering::Relaxed);
} }
self.bounds.read().iter().for_each(|bound_socket| { self.bounds.read_irqsave().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
if has_events { if has_events {
bound_socket.on_iface_events(); bound_socket.on_iface_events();
bound_socket let _woke = bound_socket
.wait_queue() .wait_queue()
.wakeup(Some(ProcessState::Blocked(true))); .wakeup(Some(ProcessState::Blocked(true)));
} }

View File

@ -212,7 +212,10 @@ impl Connecting {
let result = *self.result.read_irqsave(); let result = *self.result.read_irqsave();
match result { match result {
Connecting => (Inner::Connecting(self), Err(EAGAIN_OR_EWOULDBLOCK)), Connecting => (Inner::Connecting(self), Err(EAGAIN_OR_EWOULDBLOCK)),
Connected => (Inner::Established(Established { inner: self.inner }), Ok(())), Connected => (
Inner::Established(Established { inner: self.inner }),
Ok(()),
),
Refused => (Inner::Init(Init::new_bound(self.inner)), Err(ECONNREFUSED)), Refused => (Inner::Init(Init::new_bound(self.inner)), Err(ECONNREFUSED)),
} }
} }

View File

@ -144,7 +144,7 @@ impl TcpSocket {
match result { match result {
Ok(()) | Err(EINPROGRESS) => { Ok(()) | Err(EINPROGRESS) => {
init.iface().unwrap().poll(); init.iface().unwrap().poll();
}, }
_ => {} _ => {}
} }
@ -172,17 +172,15 @@ impl TcpSocket {
let mut write_state = self.inner.write(); let mut write_state = self.inner.write();
let inner = write_state.take().expect("Tcp Inner is None"); let inner = write_state.take().expect("Tcp Inner is None");
let (replace, result) = match inner { let (replace, result) = match inner {
Inner::Connecting(conn) => { Inner::Connecting(conn) => conn.into_result(),
conn.into_result()
}
Inner::Established(es) => { Inner::Established(es) => {
log::warn!("TODO: check new established"); log::warn!("TODO: check new established");
(Inner::Established(es), Ok(())) (Inner::Established(es), Ok(()))
}, // TODO check established } // TODO check established
_ => { _ => {
log::warn!("TODO: connecting socket error options"); log::warn!("TODO: connecting socket error options");
(inner, Err(EINVAL)) (inner, Err(EINVAL))
}, // TODO socket error options } // TODO socket error options
}; };
write_state.replace(replace); write_state.replace(replace);
result result
@ -207,9 +205,7 @@ impl TcpSocket {
pub fn try_send(&self, buf: &[u8]) -> Result<usize, SystemError> { pub fn try_send(&self, buf: &[u8]) -> Result<usize, SystemError> {
// TODO: add nonblock check of connecting socket // TODO: add nonblock check of connecting socket
let sent = match self.inner.read().as_ref().expect("Tcp Inner is None") { let sent = match self.inner.read().as_ref().expect("Tcp Inner is None") {
Inner::Established(inner) => { Inner::Established(inner) => inner.send_slice(buf),
inner.send_slice(buf)
}
_ => Err(EINVAL), _ => Err(EINVAL),
}; };
self.inner.read().as_ref().unwrap().iface().unwrap().poll(); self.inner.read().as_ref().unwrap().iface().unwrap().poll();
@ -219,9 +215,7 @@ impl TcpSocket {
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) => { Inner::Connecting(connecting) => connecting.update_io_events(),
connecting.update_io_events()
},
Inner::Established(established) => { Inner::Established(established) => {
established.update_io_events(&self.pollee); established.update_io_events(&self.pollee);
false false
@ -280,10 +274,10 @@ impl Socket for TcpSocket {
return loop { return loop {
match self.check_connect() { match self.check_connect() {
Err(EAGAIN_OR_EWOULDBLOCK) => {}, Err(EAGAIN_OR_EWOULDBLOCK) => {}
result => break result, result => break result,
} }
} };
} }
fn poll(&self) -> usize { fn poll(&self) -> usize {
@ -301,11 +295,7 @@ impl Socket for TcpSocket {
loop { loop {
match self.try_accept() { match self.try_accept() {
Err(EAGAIN_OR_EWOULDBLOCK) => { Err(EAGAIN_OR_EWOULDBLOCK) => {
wq_wait_event_interruptible!( wq_wait_event_interruptible!(self.wait_queue, self.in_notify(), {})?;
self.wait_queue,
self.in_notify(),
{}
)?;
} }
result => break result, result => break result,
} }
@ -361,9 +351,7 @@ impl Socket for TcpSocket {
} }
fn close(&self) -> Result<(), SystemError> { fn close(&self) -> Result<(), SystemError> {
let inner = self.inner let inner = self.inner.write().take().unwrap();
.write()
.take().unwrap();
match inner { match inner {
// complete connecting socket close logic // complete connecting socket close logic
@ -372,7 +360,7 @@ impl Socket for TcpSocket {
conn.close(); conn.close();
conn.release(); conn.release();
Ok(()) Ok(())
}, }
Inner::Established(es) => { Inner::Established(es) => {
es.close(); es.close();
es.release(); es.release();

View File

@ -17,6 +17,8 @@
#define DEFAULT_PAGE "/index.html" #define DEFAULT_PAGE "/index.html"
static int request_counter = 0;
int security_check(char *path) int security_check(char *path)
{ {
// 检查路径是否包含 .. // 检查路径是否包含 ..
@ -214,7 +216,7 @@ int main(int argc, char const *argv[])
while (1) while (1)
{ {
printf("Waiting for a client...\n"); printf("[#%d] Waiting for a client...\n", request_counter++);
// 等待并接受客户端连接 // 等待并接受客户端连接
if ((new_socket = accept(server_fd, (struct sockaddr *)&address, (socklen_t *)&addrlen)) < 0) if ((new_socket = accept(server_fd, (struct sockaddr *)&address, (socklen_t *)&addrlen)) < 0)