|
1 | | -use crate::common::lock::PyRwLock; |
| 1 | +use crate::common::lock::{ |
| 2 | + PyMappedRwLockReadGuard, PyRwLock, PyRwLockReadGuard, PyRwLockUpgradableReadGuard, |
| 3 | + PyRwLockWriteGuard, |
| 4 | +}; |
2 | 5 | use std::collections::{HashMap, HashSet}; |
3 | 6 | use std::fmt; |
4 | 7 |
|
@@ -57,21 +60,23 @@ impl PyValue for PyType { |
57 | 60 | } |
58 | 61 |
|
59 | 62 | impl PyType { |
60 | | - fn tp_name(&self, vm: &VirtualMachine) -> String { |
61 | | - let opt_name = self.slots.name.read().clone(); |
62 | | - opt_name.unwrap_or_else(|| { |
| 63 | + pub fn tp_name<'s>(&'s self) -> PyMappedRwLockReadGuard<'s, str> { |
| 64 | + let opt_name = self.slots.name.upgradable_read(); |
| 65 | + let read_guard = if opt_name.is_some() { |
| 66 | + PyRwLockUpgradableReadGuard::downgrade(opt_name) |
| 67 | + } else { |
| 68 | + let mut opt_name = PyRwLockUpgradableReadGuard::upgrade(opt_name); |
63 | 69 | let module = self.attributes.read().get("__module__").cloned(); |
| 70 | + let module: Option<PyStrRef> = module.and_then(|m| m.downcast().ok()); |
64 | 71 | let new_name = if let Some(module) = module { |
65 | | - // FIXME: "unknown" case is a bug. |
66 | | - let module_str = PyStrRef::try_from_object(vm, module) |
67 | | - .map_or("<unknown>".to_owned(), |m| m.borrow_value().to_owned()); |
68 | | - format!("{}.{}", module_str, &self.name) |
| 72 | + format!("{}.{}", module, &self.name) |
69 | 73 | } else { |
70 | 74 | self.name.clone() |
71 | 75 | }; |
72 | | - *self.slots.name.write() = Some(new_name.clone()); |
73 | | - new_name |
74 | | - }) |
| 76 | + *opt_name = Some(new_name); |
| 77 | + PyRwLockWriteGuard::downgrade(opt_name) |
| 78 | + }; |
| 79 | + PyRwLockReadGuard::map(read_guard, |opt| opt.as_deref().unwrap()) |
75 | 80 | } |
76 | 81 |
|
77 | 82 | pub fn iter_mro(&self) -> impl Iterator<Item = &PyType> + DoubleEndedIterator { |
@@ -272,8 +277,8 @@ impl PyType { |
272 | 277 | } |
273 | 278 |
|
274 | 279 | #[pymethod(magic)] |
275 | | - fn repr(&self, vm: &VirtualMachine) -> String { |
276 | | - format!("<class '{}'>", self.tp_name(vm)) |
| 280 | + fn repr(&self) -> String { |
| 281 | + format!("<class '{}'>", self.tp_name()) |
277 | 282 | } |
278 | 283 |
|
279 | 284 | #[pyproperty(magic)] |
|
0 commit comments