Esempio n. 1
0
	void load_struct_from_settings(aux::session_settings const& current, session_settings& ret)
	{
		for (int i = 0; i < settings_pack::num_string_settings; ++i)
		{
			if (str_settings[i].offset == 0) continue;
			std::string& val = *(std::string*)(((char*)&ret) + str_settings[i].offset);
			val = current.get_str(settings_pack::string_type_base + i);
		}

		for (int i = 0; i < settings_pack::num_int_settings; ++i)
		{
			if (int_settings[i].offset == 0) continue;
			int& val = *(int*)(((char*)&ret) + int_settings[i].offset);
			val = current.get_int(settings_pack::int_type_base + i);
		}

		for (int i = 0; i < settings_pack::num_bool_settings; ++i)
		{
			if (bool_settings[i].offset == 0) continue;
			bool& val = *(bool*)(((char*)&ret) + bool_settings[i].offset);
			val = current.get_bool(settings_pack::bool_type_base + i);
		}

		// special case for deprecated float values
		ret.share_ratio_limit = float(current.get_int(settings_pack::share_ratio_limit)) / 100.f;
		ret.seed_time_ratio_limit = float(current.get_int(settings_pack::seed_time_ratio_limit)) / 100.f;
		ret.peer_turnover = float(current.get_int(settings_pack::peer_turnover)) / 100.f;
		ret.peer_turnover_cutoff = float(current.get_int(settings_pack::peer_turnover_cutoff)) / 100.f;
	}
Esempio n. 2
0
	boost::shared_ptr<settings_pack> load_pack_from_struct(
		aux::session_settings const& current, session_settings const& s)
	{
		boost::shared_ptr<settings_pack> p = boost::make_shared<settings_pack>();

		for (int i = 0; i < settings_pack::num_string_settings; ++i)
		{
			if (str_settings[i].offset == 0) continue;
			std::string& val = *(std::string*)(((char*)&s) + str_settings[i].offset);
			int setting_name = settings_pack::string_type_base + i;
			if (val == current.get_str(setting_name)) continue;
			p->set_str(setting_name, val);
		}

		for (int i = 0; i < settings_pack::num_int_settings; ++i)
		{
			if (int_settings[i].offset == 0) continue;
			int& val = *(int*)(((char*)&s) + int_settings[i].offset);
			int setting_name = settings_pack::int_type_base + i;
			if (val == current.get_int(setting_name)) continue;
			p->set_int(setting_name, val);
		}

		for (int i = 0; i < settings_pack::num_bool_settings; ++i)
		{
			if (bool_settings[i].offset == 0) continue;
			bool& val = *(bool*)(((char*)&s) + bool_settings[i].offset);
			int setting_name = settings_pack::bool_type_base + i;
			if (val == current.get_bool(setting_name)) continue;
			p->set_bool(setting_name, val);
		}

		// special case for deprecated float values
		int val = current.get_int(settings_pack::share_ratio_limit);
		if (fabs(s.share_ratio_limit - float(val) / 100.f) > 0.001f)
			p->set_int(settings_pack::share_ratio_limit, s.share_ratio_limit * 100);

		val = current.get_int(settings_pack::seed_time_ratio_limit);
		if (fabs(s.seed_time_ratio_limit - float(val) / 100.f) > 0.001f)
			p->set_int(settings_pack::seed_time_ratio_limit, s.seed_time_ratio_limit * 100);

		val = current.get_int(settings_pack::peer_turnover);
		if (fabs(s.peer_turnover - float(val) / 100.f) > 0.001)
			p->set_int(settings_pack::peer_turnover, s.peer_turnover * 100);

		val = current.get_int(settings_pack::peer_turnover_cutoff);
		if (fabs(s.peer_turnover_cutoff - float(val) / 100.f) > 0.001)
			p->set_int(settings_pack::peer_turnover_cutoff, s.peer_turnover_cutoff * 100);

		return p;
	}
void initialize_default_settings(aux::session_settings& s)
{
    for (int i = 0; i < settings_pack::num_string_settings; ++i)
    {
        if (str_settings[i].default_value == nullptr) continue;
        s.set_str(settings_pack::string_type_base + i, str_settings[i].default_value);
        TORRENT_ASSERT(s.get_str(settings_pack::string_type_base + i) == str_settings[i].default_value);
    }

    for (int i = 0; i < settings_pack::num_int_settings; ++i)
    {
        s.set_int(settings_pack::int_type_base + i, int_settings[i].default_value);
        TORRENT_ASSERT(s.get_int(settings_pack::int_type_base + i) == int_settings[i].default_value);
    }

    for (int i = 0; i < settings_pack::num_bool_settings; ++i)
    {
        s.set_bool(settings_pack::bool_type_base + i, bool_settings[i].default_value);
        TORRENT_ASSERT(s.get_bool(settings_pack::bool_type_base + i) == bool_settings[i].default_value);
    }
}
void apply_pack(settings_pack const* pack, aux::session_settings& sett
                , aux::session_impl* ses)
{
    typedef void (aux::session_impl::*fun_t)();
    std::vector<fun_t> callbacks;

    for (auto const& p : pack->m_strings)
    {
        // disregard setting indices that are not string types
        if ((p.first & settings_pack::type_mask) != settings_pack::string_type_base)
            continue;

        // ignore settings that are out of bounds
        int const index = p.first & settings_pack::index_mask;
        TORRENT_ASSERT_PRECOND(index >= 0 && index < settings_pack::num_string_settings);
        if (index < 0 || index >= settings_pack::num_string_settings)
            continue;

        // if the value did not change, don't call the update callback
        if (sett.get_str(p.first) == p.second) continue;

        sett.set_str(p.first, p.second);
        str_setting_entry_t const& sa = str_settings[index];

        if (sa.fun && ses
                && std::find(callbacks.begin(), callbacks.end(), sa.fun) == callbacks.end())
            callbacks.push_back(sa.fun);
    }

    for (auto const& p : pack->m_ints)
    {
        // disregard setting indices that are not int types
        if ((p.first & settings_pack::type_mask) != settings_pack::int_type_base)
            continue;

        // ignore settings that are out of bounds
        int const index = p.first & settings_pack::index_mask;
        TORRENT_ASSERT_PRECOND(index >= 0 && index < settings_pack::num_int_settings);
        if (index < 0 || index >= settings_pack::num_int_settings)
            continue;

        // if the value did not change, don't call the update callback
        if (sett.get_int(p.first) == p.second) continue;

        sett.set_int(p.first, p.second);
        int_setting_entry_t const& sa = int_settings[index];
        if (sa.fun && ses
                && std::find(callbacks.begin(), callbacks.end(), sa.fun) == callbacks.end())
            callbacks.push_back(sa.fun);
    }

    for (auto const& p : pack->m_bools)
    {
        // disregard setting indices that are not bool types
        if ((p.first & settings_pack::type_mask) != settings_pack::bool_type_base)
            continue;

        // ignore settings that are out of bounds
        int const index = p.first & settings_pack::index_mask;
        TORRENT_ASSERT_PRECOND(index >= 0 && index < settings_pack::num_bool_settings);
        if (index < 0 || index >= settings_pack::num_bool_settings)
            continue;

        // if the value did not change, don't call the update callback
        if (sett.get_bool(p.first) == p.second) continue;

        sett.set_bool(p.first, p.second);
        bool_setting_entry_t const& sa = bool_settings[index];
        if (sa.fun && ses
                && std::find(callbacks.begin(), callbacks.end(), sa.fun) == callbacks.end())
            callbacks.push_back(sa.fun);
    }

    // call the callbacks once all the settings have been applied, and
    // only once per callback
    for (auto const& f : callbacks)
    {
        (ses->*f)();
    }
}
Esempio n. 5
0
	void disk_buffer_pool::set_settings(aux::session_settings const& sett)
	{
		mutex::scoped_lock l(m_pool_mutex);

		// 0 cache_buffer_chunk_size means 'automatic' (i.e.
		// proportional to the total disk cache size)
		m_cache_buffer_chunk_size = sett.get_int(settings_pack::cache_buffer_chunk_size);
		m_lock_disk_cache = sett.get_bool(settings_pack::lock_disk_cache);
#ifndef TORRENT_DISABLE_POOL_ALLOCATOR
		m_want_pool_allocator = sett.get_bool(settings_pack::use_disk_cache_pool);
		// if there are no allocated blocks, it's OK to switch allocator
		if (m_in_use == 0)
			m_using_pool_allocator = m_want_pool_allocator;
#endif

#if TORRENT_HAVE_MMAP
		// if we've already allocated an mmap, we can't change
		// anything unless there are no allocations in use
		if (m_cache_pool && m_in_use > 0) return;
#endif

		// only allow changing size if we're not using mmapped
		// cache, or if we're just about to turn it off
		if (
#if TORRENT_HAVE_MMAP
			m_cache_pool == 0 ||
#endif
			sett.get_str(settings_pack::mmap_cache).empty())
		{
			int cache_size = sett.get_int(settings_pack::cache_size);
			if (cache_size < 0)
			{
				boost::uint64_t phys_ram = physical_ram();
				if (phys_ram == 0) m_max_use = 1024;
				else m_max_use = phys_ram / 8 / m_block_size;
			}
			else
			{
				m_max_use = cache_size;
			}
			m_low_watermark = m_max_use - (std::max)(16, sett.get_int(settings_pack::max_queued_disk_bytes) / 0x4000);
			if (m_low_watermark < 0) m_low_watermark = 0;
			if (m_in_use >= m_max_use && !m_exceeded_max_size)
			{
				m_exceeded_max_size = true;
				m_trigger_cache_trim();
			}
		}

#if TORRENT_USE_ASSERTS
		m_settings_set = true;
#endif

#if TORRENT_HAVE_MMAP
		// #error support resizing the map
		if (m_cache_pool && sett.get_str(settings_pack::mmap_cache).empty())
		{
			TORRENT_ASSERT(m_in_use == 0);
			munmap(m_cache_pool, boost::uint64_t(m_max_use) * 0x4000);
			m_cache_pool = 0;
			// attempt to make MacOS not flush this to disk, making close()
			// block for a long time
			ftruncate(m_cache_fd, 0);
			close(m_cache_fd);
			m_cache_fd = -1;
			std::vector<int>().swap(m_free_list);
		}
		else if (m_cache_pool == 0 && !sett.get_str(settings_pack::mmap_cache).empty())
		{
			// O_TRUNC here is because we don't actually care about what's
			// in the file now, there's no need to ever read that into RAM
#ifndef O_EXLOCK
#define O_EXLOCK 0
#endif
			m_cache_fd = open(sett.get_str(settings_pack::mmap_cache).c_str(), O_RDWR | O_CREAT | O_EXLOCK | O_TRUNC, 0700);
			if (m_cache_fd < 0)
			{
				if (m_post_alert)
				{
					error_code ec(errno, boost::system::generic_category());
					m_ios.post(boost::bind(alert_callback, m_post_alert, new mmap_cache_alert(ec)));
				}
			}
			else
			{
#ifndef MAP_NOCACHE
#define MAP_NOCACHE 0
#endif
				ftruncate(m_cache_fd, boost::uint64_t(m_max_use) * 0x4000);
				m_cache_pool = (char*)mmap(0, boost::uint64_t(m_max_use) * 0x4000, PROT_READ | PROT_WRITE
					, MAP_SHARED | MAP_NOCACHE, m_cache_fd, 0);
				if (intptr_t(m_cache_pool) == -1)
				{
					if (m_post_alert)
					{
						error_code ec(errno, boost::system::generic_category());
						m_ios.post(boost::bind(alert_callback, m_post_alert, new mmap_cache_alert(ec)));
					}
					m_cache_pool = 0;
					// attempt to make MacOS not flush this to disk, making close()
					// block for a long time
					ftruncate(m_cache_fd, 0);
					close(m_cache_fd);
					m_cache_fd = -1;
				}
				else
				{
					TORRENT_ASSERT((size_t(m_cache_pool) & 0xfff) == 0);
					m_free_list.reserve(m_max_use);
					for (int i = 0; i < m_max_use; ++i)
						m_free_list.push_back(i);
				}
			}
		}
#endif
	}