// 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;
}
Пример #2
0
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
}