| 226 | } |
| 227 | |
| 228 | error_code sys_event_queue_destroy(ppu_thread &ppu, u32 equeue_id, s32 mode) { |
| 229 | ppu.state += cpu_flag::wait; |
| 230 | |
| 231 | sys_event.warning("sys_event_queue_destroy(equeue_id=0x%x, mode=%d)", |
| 232 | equeue_id, mode); |
| 233 | |
| 234 | if (mode && mode != SYS_EVENT_QUEUE_DESTROY_FORCE) { |
| 235 | return CELL_EINVAL; |
| 236 | } |
| 237 | |
| 238 | std::vector<lv2_event> events; |
| 239 | |
| 240 | std::unique_lock<shared_mutex> qlock; |
| 241 | |
| 242 | cpu_thread *head{}; |
| 243 | |
| 244 | const auto queue = idm::withdraw<lv2_obj, lv2_event_queue>( |
| 245 | equeue_id, [&](lv2_event_queue &queue) -> CellError { |
| 246 | qlock = std::unique_lock{queue.mutex}; |
| 247 | |
| 248 | head = queue.type == SYS_PPU_QUEUE |
| 249 | ? static_cast<cpu_thread *>(+queue.pq) |
| 250 | : +queue.sq; |
| 251 | |
| 252 | if (!mode && head) { |
| 253 | return CELL_EBUSY; |
| 254 | } |
| 255 | |
| 256 | if (!queue.events.empty()) { |
| 257 | // Copy events for logging, does not empty |
| 258 | events.insert(events.begin(), queue.events.begin(), |
| 259 | queue.events.end()); |
| 260 | } |
| 261 | |
| 262 | lv2_obj::on_id_destroy(queue, queue.key); |
| 263 | |
| 264 | if (!head) { |
| 265 | qlock.unlock(); |
| 266 | } else { |
| 267 | for (auto cpu = head; cpu; cpu = cpu->get_next_cpu()) { |
| 268 | if (cpu->state & cpu_flag::again) { |
| 269 | ppu.state += cpu_flag::again; |
| 270 | return CELL_EAGAIN; |
| 271 | } |
| 272 | } |
| 273 | } |
| 274 | |
| 275 | return {}; |
| 276 | }); |
| 277 | |
| 278 | if (!queue) { |
| 279 | return CELL_ESRCH; |
| 280 | } |
| 281 | |
| 282 | if (ppu.state & cpu_flag::again) { |
| 283 | return {}; |
| 284 | } |
| 285 |
no test coverage detected