ssize_t vmware3_image_t::write(const void * buf, size_t count) { ssize_t total = 0; while(count > 0) { off_t offset = perform_seek(); if(offset == INVALID_OFFSET) return -1; unsigned bytes_remaining = (unsigned)(tlb_size - offset); unsigned amount = 0; current->synced = false; if(bytes_remaining > count) { memcpy(current->tlb + offset, buf, count); amount = count; } else { memcpy(current->tlb + offset, buf, bytes_remaining); if(!sync()) { BX_DEBUG(("failed to sync when writing %u bytes", (unsigned)count)); return -1; } amount = bytes_remaining; } requested_offset += amount; total += amount; count -= amount; } return total; }
ssize_t vmware3_image_t::read(void * buf, size_t count) { ssize_t total = 0; while(count > 0) { off_t offset = perform_seek(); if(offset == INVALID_OFFSET) { BX_DEBUG(("vmware3 COW read failed on %u bytes", (unsigned)count)); return -1; } unsigned bytes_remaining = (unsigned)(tlb_size - offset); unsigned amount = (bytes_remaining > count) ? count : bytes_remaining; memcpy(buf, current->tlb + offset, amount); requested_offset += amount; total += amount; count -= amount; } return total; }
void Scheduler::run() { avlock.lock(); auto event = next_event(); avlock.unlock(); if (!is_active) { sync_sleep(0.01); return; } show_info(); switch (event) { case EventHandler::Event::Quit: is_active = false; video_thread_active = false; audio_thread_active = false; return; case EventHandler::Event::Pause: pause_toggle(); break; case EventHandler::Event::SeekBack10: perform_seek(-3.0); break; case EventHandler::Event::SeekForward10: perform_seek(3.0); break; case EventHandler::Event::SeekBack60: perform_seek(-30.0); break; case EventHandler::Event::SeekForward60: perform_seek(30.0); break; case EventHandler::Event::Fullscreen: if (video_thread_active) video->toggle_fullscreen(); break; case EventHandler::Event::None: break; default: throw std::runtime_error("Unknown event popped up :V\n"); } if (is_paused) { sync_sleep(0.01); return; } Packet pkt; Packet::Type type = file->packet(pkt); switch(type) { case Packet::Type::Error: is_active = false; // Signal to threads that there won't be any more data. aud_pkt_queue.finalize(); vid_pkt_queue.finalize(); return; case Packet::Type::None: return; case Packet::Type::Audio: while (aud_pkt_queue.size() > 16 && (vid_pkt_queue.size() > 16 || !has_video)) aud_pkt_queue.wait(); aud_pkt_queue.push(std::move(pkt)); break; case Packet::Type::Video: while (vid_pkt_queue.size() > 16 && (aud_pkt_queue.size() > 16 || !has_audio)) vid_pkt_queue.wait(); vid_pkt_queue.push(std::move(pkt)); break; case Packet::Type::Subtitle: while (sub_pkt_queue.size() > 64 && (aud_pkt_queue.size() > 16 || !has_audio) && (vid_pkt_queue.size() > 16 || !has_video)) sub_pkt_queue.wait(); sub_pkt_queue.push(std::move(pkt)); break; default: throw std::runtime_error("What kind of package is this? o.o\n"); } }