// Close is idempotent and thread safe. bool file_storage::close() { std::string error_name; ////if (!closed_) //// log_unmapping(); // Critical Section /////////////////////////////////////////////////////////////////////////// mutex_.lock_upgrade(); if (closed_) { mutex_.unlock_upgrade(); //--------------------------------------------------------------------- return true; } mutex_.unlock_upgrade_and_lock(); //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ closed_ = true; if (logical_size_ > file_size_) error_name = "fit"; else if (msync(data_, logical_size_, MS_SYNC) == FAIL) error_name = "msync"; else if (munmap(data_, file_size_) == FAIL) error_name = "munmap"; else if (ftruncate(file_handle_, logical_size_) == FAIL) error_name = "ftruncate"; else if (fsync(file_handle_) == FAIL) error_name = "fsync"; else if (::close(file_handle_) == FAIL) error_name = "close"; mutex_.unlock(); /////////////////////////////////////////////////////////////////////////// // Keep logging out of the critical section. if (!error_name.empty()) return handle_error(error_name, filename_); log_unmapped(); return true; }
void Nes_Core::write_io( nes_addr_t addr, int data ) { // sprite dma if ( addr == 0x4014 ) { ppu.dma_sprites( clock(), cpu::get_code( data * 0x100 ) ); cpu_adjust_time( 513 ); return; } // joypad strobe if ( addr == 0x4016 ) { // if strobe goes low, latch data if ( joypad.w4016 & 1 & ~data ) { joypad_read_count++; joypad.joypad_latches [0] = current_joypad [0]; joypad.joypad_latches [1] = current_joypad [1]; } joypad.w4016 = data; return; } // apu if ( unsigned (addr - impl->apu.start_addr) <= impl->apu.end_addr - impl->apu.start_addr ) { impl->apu.write_register( clock(), addr, data ); if ( wait_states_enabled ) { if ( addr == 0x4010 || (addr == 0x4015 && (data & 0x10)) ) { impl->apu.run_until( clock() + 1 ); event_changed(); } } return; } #ifndef NDEBUG log_unmapped( addr, data ); #endif }