Browse Source

把Device trait的set_class改为设置Weak指针,以避免循环引用问题。 (#666)

LoGin 11 months ago
parent
commit
4256da7fb6

+ 1 - 1
kernel/src/driver/base/cpu.rs

@@ -185,7 +185,7 @@ impl Device for CpuSubSystemFakeRootDevice {
         true
     }
 
-    fn set_class(&self, _class: Option<Arc<dyn Class>>) {
+    fn set_class(&self, _class: Option<Weak<dyn Class>>) {
         todo!()
     }
 }

+ 1 - 1
kernel/src/driver/base/device/mod.rs

@@ -165,7 +165,7 @@ pub trait Device: KObject {
     /// 设置当前设备所属的类
     ///
     /// 注意,如果实现了当前方法,那么必须实现`class()`方法
-    fn set_class(&self, class: Option<Arc<dyn Class>>);
+    fn set_class(&self, class: Option<Weak<dyn Class>>);
 
     /// 返回已经与当前设备匹配好的驱动程序
     fn driver(&self) -> Option<Arc<dyn Driver>>;

+ 1 - 1
kernel/src/driver/base/platform/platform_device.rs

@@ -320,7 +320,7 @@ impl Device for PlatformBusDevice {
         todo!()
     }
 
-    fn set_class(&self, _class: Option<Arc<dyn Class>>) {
+    fn set_class(&self, _class: Option<Weak<dyn Class>>) {
         todo!()
     }
 }

+ 7 - 1
kernel/src/driver/base/subsys.rs

@@ -99,7 +99,13 @@ impl SubSysPrivate {
     #[allow(dead_code)]
     #[inline]
     pub fn class(&self) -> Option<Weak<dyn Class>> {
-        return self.class.lock().clone();
+        let mut guard = self.class.lock();
+        if let Some(r) = guard.clone() {
+            return Some(r);
+        } else {
+            *guard = None;
+            return None;
+        }
     }
 
     pub fn set_class(&self, class: Option<Weak<dyn Class>>) {

+ 1 - 1
kernel/src/driver/disk/ahci/ahcidisk.rs

@@ -528,7 +528,7 @@ impl Device for LockedAhciDisk {
         todo!()
     }
 
-    fn set_class(&self, _class: Option<Arc<dyn Class>>) {
+    fn set_class(&self, _class: Option<Weak<dyn Class>>) {
         todo!()
     }
 }

+ 9 - 3
kernel/src/driver/input/ps2_mouse/ps_mouse_device.rs

@@ -412,7 +412,7 @@ impl Ps2MouseDevice {
 #[derive(Debug)]
 struct InnerPs2MouseDevice {
     bus: Option<Weak<dyn Bus>>,
-    class: Option<Arc<dyn Class>>,
+    class: Option<Weak<dyn Class>>,
     driver: Option<Weak<dyn Driver>>,
     kern_inode: Option<Arc<KernFSInode>>,
     parent: Option<Weak<dyn KObject>>,
@@ -447,7 +447,7 @@ impl Device for Ps2MouseDevice {
         self.inner.lock_irqsave().bus = bus;
     }
 
-    fn set_class(&self, class: Option<alloc::sync::Arc<dyn Class>>) {
+    fn set_class(&self, class: Option<alloc::sync::Weak<dyn Class>>) {
         self.inner.lock_irqsave().class = class;
     }
 
@@ -474,7 +474,13 @@ impl Device for Ps2MouseDevice {
     }
 
     fn class(&self) -> Option<Arc<dyn Class>> {
-        self.inner.lock_irqsave().class.clone()
+        let mut guard = self.inner.lock_irqsave();
+        let r = guard.class.clone()?.upgrade();
+        if r.is_none() {
+            guard.class = None;
+        }
+
+        return r;
     }
 }
 

+ 10 - 2
kernel/src/driver/input/serio/i8042/i8042_device.rs

@@ -50,7 +50,7 @@ impl I8042PlatformDevice {
 #[derive(Debug)]
 pub struct InnerI8042PlatformDevice {
     bus: Option<Weak<dyn Bus>>,
-    class: Option<Arc<dyn Class>>,
+    class: Option<Weak<dyn Class>>,
     driver: Option<Weak<dyn Driver>>,
     kern_inode: Option<Arc<KernFSInode>>,
     parent: Option<Weak<dyn KObject>>,
@@ -77,8 +77,16 @@ impl Device for I8042PlatformDevice {
     fn set_bus(&self, bus: Option<Weak<dyn Bus>>) {
         self.inner.lock().bus = bus;
     }
+    fn class(&self) -> Option<Arc<dyn Class>> {
+        let mut guard = self.inner.lock();
+        let r = guard.class.clone()?.upgrade();
+        if r.is_none() {
+            guard.class = None;
+        }
 
-    fn set_class(&self, class: Option<Arc<dyn Class>>) {
+        return r;
+    }
+    fn set_class(&self, class: Option<Weak<dyn Class>>) {
         self.inner.lock().class = class;
     }
 

+ 11 - 2
kernel/src/driver/input/serio/i8042/i8042_ports.rs

@@ -33,7 +33,7 @@ pub struct I8042AuxPort {
 #[derive(Debug)]
 pub struct InnerI8042AuxPort {
     bus: Option<Weak<dyn Bus>>,
-    class: Option<Arc<dyn Class>>,
+    class: Option<Weak<dyn Class>>,
     driver: Option<Weak<dyn Driver>>,
     kern_inode: Option<Arc<KernFSInode>>,
     parent: Option<Weak<dyn KObject>>,
@@ -76,10 +76,19 @@ impl Device for I8042AuxPort {
         self.inner.lock().bus = bus;
     }
 
-    fn set_class(&self, class: Option<Arc<dyn Class>>) {
+    fn set_class(&self, class: Option<Weak<dyn Class>>) {
         self.inner.lock().class = class;
     }
 
+    fn class(&self) -> Option<Arc<dyn Class>> {
+        let mut guard = self.inner.lock();
+        let r = guard.class.clone()?.upgrade();
+        if r.is_none() {
+            guard.class = None;
+        }
+        return r;
+    }
+
     fn driver(&self) -> Option<Arc<dyn Driver>> {
         self.inner.lock().driver.clone()?.upgrade()
     }

+ 1 - 1
kernel/src/driver/serial/serial8250/mod.rs

@@ -249,7 +249,7 @@ impl Device for Serial8250ISADevices {
         true
     }
 
-    fn set_class(&self, _class: Option<Arc<dyn Class>>) {
+    fn set_class(&self, _class: Option<Weak<dyn Class>>) {
         todo!()
     }
 }

+ 1 - 1
kernel/src/driver/tty/tty_device.rs

@@ -425,7 +425,7 @@ impl Device for TtyDevice {
         self.inner.write().bus = bus
     }
 
-    fn set_class(&self, _class: Option<Arc<dyn crate::driver::base::class::Class>>) {
+    fn set_class(&self, _class: Option<Weak<dyn crate::driver::base::class::Class>>) {
         todo!()
     }
 

+ 1 - 1
kernel/src/driver/video/fbdev/base/fbcon/mod.rs

@@ -197,7 +197,7 @@ impl Device for FbConsoleDevice {
         self.inner.lock().bus.clone()
     }
 
-    fn set_class(&self, _class: Option<Arc<dyn Class>>) {
+    fn set_class(&self, _class: Option<Weak<dyn Class>>) {
         // 不允许修改
         kwarn!("fbcon's class can not be changed");
     }

+ 1 - 1
kernel/src/driver/video/fbdev/base/fbmem.rs

@@ -343,7 +343,7 @@ impl Device for FbDevice {
     fn class(&self) -> Option<Arc<dyn Class>> {
         sys_class_graphics_instance().map(|ins| ins.clone() as Arc<dyn Class>)
     }
-    fn set_class(&self, _class: Option<Arc<dyn Class>>) {
+    fn set_class(&self, _class: Option<Weak<dyn Class>>) {
         // do nothing
     }
 

+ 14 - 2
kernel/src/driver/video/fbdev/vesafb.rs

@@ -122,7 +122,7 @@ impl VesaFb {
 #[derive(Debug)]
 struct InnerVesaFb {
     bus: Option<Weak<dyn Bus>>,
-    class: Option<Arc<dyn Class>>,
+    class: Option<Weak<dyn Class>>,
     driver: Option<Weak<dyn Driver>>,
     kern_inode: Option<Arc<KernFSInode>>,
     parent: Option<Weak<dyn KObject>>,
@@ -189,10 +189,22 @@ impl Device for VesaFb {
         self.inner.lock().bus = bus;
     }
 
-    fn set_class(&self, class: Option<Arc<dyn Class>>) {
+    fn set_class(&self, class: Option<Weak<dyn Class>>) {
         self.inner.lock().class = class;
     }
 
+    fn class(&self) -> Option<Arc<dyn Class>> {
+        let mut guard = self.inner.lock();
+
+        let r = guard.class.clone()?.upgrade();
+        if r.is_none() {
+            // 为了让弱引用失效
+            guard.class = None;
+        }
+
+        return r;
+    }
+
     fn driver(&self) -> Option<Arc<dyn Driver>> {
         self.inner.lock().driver.clone()?.upgrade()
     }