(&self, args: FuncArgs, vm: &VirtualMachine)
| 129 | |
| 130 | #[pymethod] |
| 131 | fn acquire(&self, args: FuncArgs, vm: &VirtualMachine) -> PyResult<bool> { |
| 132 | let blocking: bool = args |
| 133 | .kwargs |
| 134 | .get("block") |
| 135 | .or_else(|| args.args.first()) |
| 136 | .map(|o| o.clone().try_to_bool(vm)) |
| 137 | .transpose()? |
| 138 | .unwrap_or(true); |
| 139 | |
| 140 | let timeout_obj = args |
| 141 | .kwargs |
| 142 | .get("timeout") |
| 143 | .or_else(|| args.args.get(1)) |
| 144 | .cloned(); |
| 145 | |
| 146 | // Calculate timeout in milliseconds |
| 147 | let full_msecs: u32 = if !blocking { |
| 148 | 0 |
| 149 | } else if timeout_obj.as_ref().is_none_or(|o| vm.is_none(o)) { |
| 150 | INFINITE |
| 151 | } else { |
| 152 | let timeout: f64 = timeout_obj.unwrap().try_float(vm)?.to_f64(); |
| 153 | let timeout = timeout * 1000.0; // convert to ms |
| 154 | if timeout < 0.0 { |
| 155 | 0 |
| 156 | } else if timeout >= 0.5 * INFINITE as f64 { |
| 157 | return Err(vm.new_overflow_error("timeout is too large")); |
| 158 | } else { |
| 159 | (timeout + 0.5) as u32 |
| 160 | } |
| 161 | }; |
| 162 | |
| 163 | // Check whether we already own the lock |
| 164 | if self.kind == RECURSIVE_MUTEX && ismine!(self) { |
| 165 | self.count.fetch_add(1, Ordering::Release); |
| 166 | return Ok(true); |
| 167 | } |
| 168 | |
| 169 | // Check whether we can acquire without blocking |
| 170 | match unsafe { WaitForSingleObjectEx(self.handle.as_raw(), 0, 0) } { |
| 171 | WAIT_OBJECT_0 => { |
| 172 | self.last_tid |
| 173 | .store(unsafe { GetCurrentThreadId() }, Ordering::Release); |
| 174 | self.count.fetch_add(1, Ordering::Release); |
| 175 | return Ok(true); |
| 176 | } |
| 177 | WAIT_FAILED => return Err(vm.new_last_os_error()), |
| 178 | _ => {} |
| 179 | } |
| 180 | |
| 181 | // Poll with signal checking (CPython uses WaitForMultipleObjectsEx |
| 182 | // with sigint_event; we poll since RustPython has no sigint event) |
| 183 | let poll_ms: u32 = 100; |
| 184 | let mut elapsed: u32 = 0; |
| 185 | loop { |
| 186 | let wait_ms = if full_msecs == INFINITE { |
| 187 | poll_ms |
| 188 | } else { |
no test coverage detected