(&self, obj: ArgBytesLike, vm: &VirtualMachine)
| 2013 | |
| 2014 | #[pymethod] |
| 2015 | fn write(&self, obj: ArgBytesLike, vm: &VirtualMachine) -> PyResult<usize> { |
| 2016 | // Check if close() is in progress (Issue #31976) |
| 2017 | // If closing, wait for close() to complete by spinning until raw is closed. |
| 2018 | // Note: This spin-wait has no timeout because close() is expected to always |
| 2019 | // complete (flush + fd close). |
| 2020 | if self.writer().closing().load(Ordering::Acquire) { |
| 2021 | loop { |
| 2022 | let raw = { |
| 2023 | let data = self.writer().lock(vm)?; |
| 2024 | match &data.raw { |
| 2025 | Some(raw) => raw.to_owned(), |
| 2026 | None => break, // detached |
| 2027 | } |
| 2028 | }; |
| 2029 | if file_closed(&raw, vm)? { |
| 2030 | break; |
| 2031 | } |
| 2032 | // Yield to other threads |
| 2033 | std::thread::yield_now(); |
| 2034 | } |
| 2035 | return Err(vm.new_value_error("write to closed file")); |
| 2036 | } |
| 2037 | let mut data = self.writer().lock(vm)?; |
| 2038 | let raw = data.check_init(vm)?; |
| 2039 | ensure_unclosed(raw, "write to closed file", vm)?; |
| 2040 | |
| 2041 | data.write(obj, vm) |
| 2042 | } |
| 2043 | |
| 2044 | #[pymethod] |
| 2045 | fn flush(&self, vm: &VirtualMachine) -> PyResult<()> { |
nothing calls this directly
no test coverage detected