Browse Source

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

fix: 修正IfaceCommon的bounds字段的锁使用问题&调度问题
Samuel Dai 3 months ago
parent
commit
0896c3311c

+ 1 - 1
kernel/src/arch/x86_64/interrupt/handle.rs

@@ -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))
-        && vector == APIC_TIMER_IRQ_NUM.data()
+        || vector == APIC_TIMER_IRQ_NUM.data()
     {
         __schedule(SchedMode::SM_PREEMPT);
     }

+ 2 - 2
kernel/src/driver/net/mod.rs

@@ -244,11 +244,11 @@ impl IfaceCommon {
             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
             if has_events {
                 bound_socket.on_iface_events();
-                bound_socket
+                let _woke = bound_socket
                     .wait_queue()
                     .wakeup(Some(ProcessState::Blocked(true)));
             }

+ 4 - 1
kernel/src/net/socket/inet/stream/inner.rs

@@ -212,7 +212,10 @@ impl Connecting {
         let result = *self.result.read_irqsave();
         match result {
             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)),
         }
     }

+ 12 - 24
kernel/src/net/socket/inet/stream/mod.rs

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

+ 3 - 1
user/apps/http_server/main.c

@@ -17,6 +17,8 @@
 
 #define DEFAULT_PAGE "/index.html"
 
+static int request_counter = 0;
+
 int security_check(char *path)
 {
     // 检查路径是否包含 ..
@@ -214,7 +216,7 @@ int main(int argc, char const *argv[])
 
     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)