-
-
Notifications
You must be signed in to change notification settings - Fork 168
Open
Labels
Description
这段代码中需要创建一个Arc< KernelThreadCreateInfo >类型的结构体 result,其中包含一个self_ref字段,是一个指向自己这个 Arc 的 Weak 引用。
DragonOS/kernel/src/process/kthread.rs
Lines 152 to 171 in 4617e96
| pub fn new(func: KernelThreadClosure, name: String) -> Arc<Self> { | |
| let result = Arc::new(Self { | |
| closure: SpinLock::new(Some(Box::new(func))), | |
| name, | |
| created: AtomicKernelThreadCreateStatus::new(KernelThreadCreateStatus::NotCreated), | |
| result_pcb: SpinLock::new(None), | |
| has_unsafe_arc_instance: AtomicBool::new(false), | |
| self_ref: Weak::new(), | |
| to_mark_sleep: AtomicBool::new(true), | |
| }); | |
| let tmp = result.clone(); | |
| unsafe { | |
| let tmp = Arc::into_raw(tmp) as *mut Self; | |
| (*tmp).self_ref = Arc::downgrade(&result); | |
| Arc::from_raw(tmp); | |
| } | |
| return result; | |
| } | |
当前在 unsafe 块中用操作裸指针的方式修改 self_ref,但有专门的 API Arc::new_cyclic 可以实现往新构造的Arc 结构体中加入一个对自己的 Weak 引用,类似这种写法:
pub fn new(func: KernelThreadClosure, name: String) -> Arc<Self> {
Arc::new_cyclic(|weak_self| Self {
closure: SpinLock::new(Some(Box::new(func))),
name,
created: AtomicKernelThreadCreateStatus::new(KernelThreadCreateStatus::NotCreated),
result_pcb: SpinLock::new(None),
has_unsafe_arc_instance: AtomicBool::new(false),
self_ref: weak_self.clone(),
to_mark_sleep: AtomicBool::new(true),
})
}当然,两种写法在功能上没有区别,但是使用Arc::new_cyclic并避免引入 unsafe 是否是一种更好的实现?还有其它几处有类似的模式,如果需要修改的话我可以新建PR,一并提交 patch
DragonOS/kernel/src/filesystem/vfs/mount.rs
Lines 370 to 384 in 4617e96
| #[deprecated] | |
| fn wrap(self) -> Arc<Self> { | |
| // 创建Arc指针 | |
| let mount_fs: Arc<MountFS> = Arc::new(self); | |
| // 创建weak指针 | |
| let weak: Weak<MountFS> = Arc::downgrade(&mount_fs); | |
| // 将Arc指针转为Raw指针并对其内部的self_ref字段赋值 | |
| let ptr: *mut MountFS = mount_fs.as_ref() as *const Self as *mut Self; | |
| unsafe { | |
| (*ptr).self_ref = weak; | |
| // 返回初始化好的MountFS对象 | |
| return mount_fs; | |
| } | |
| } |
DragonOS/kernel/src/filesystem/vfs/mount.rs
Lines 439 to 456 in 4617e96
| #[deprecated] | |
| fn wrap(self) -> Arc<Self> { | |
| // 创建Arc指针 | |
| let inode: Arc<MountFSInode> = Arc::new(self); | |
| // 创建Weak指针 | |
| let weak: Weak<MountFSInode> = Arc::downgrade(&inode); | |
| // 将Arc指针转为Raw指针并对其内部的self_ref字段赋值 | |
| compiler_fence(Ordering::SeqCst); | |
| let ptr: *mut MountFSInode = inode.as_ref() as *const Self as *mut Self; | |
| compiler_fence(Ordering::SeqCst); | |
| unsafe { | |
| (*ptr).self_ref = weak; | |
| compiler_fence(Ordering::SeqCst); | |
| // 返回初始化好的MountFSInode对象 | |
| return inode; | |
| } | |
| } |