<commit_before>/*
 * This file is part of PAC
 *
 * PAC is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * PAC is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with PAC.  If not, see <http://www.gnu.org/licenses/>.
 *
 */

/*
 * context.hpp
 *
 * Author: Brian Fransioli
 * Created: Mon Mar 10 17:30:53 KST 2014
 * Last modified: Tue Mar 18 17:49:53 KST 2014
 */

#ifndef PAC_CONTEXT_HPP
#define PAC_CONTEXT_HPP

#include "runnable.hpp"
#include "signal.hpp"

#include <memory>
#include <thread>
#include <condition_variable>
#include <mutex>
#include <vector>
#include <map>
#include <list>
#include <algorithm>
#include <atomic>

namespace pac {

class context
{
public:
	using runnable_ptr = std::shared_ptr< runnable >;
	using runnable_cont = std::list< runnable_ptr >;
	using runnable_iter = typename runnable_cont::iterator;

	using context_id = std::size_t;
	using context_ptr = std::shared_ptr< context >;

	using thread_id = std::thread::id;

private:
	runnable_cont runnables;
	context_id cid;
	thread_id tid;

public:
	context()
		: runnables{}, cid{}, tid{}
	{}

	static context_ptr create()
	{
		return std::make_shared<context>();
	}

	runnable_ptr next_runnable()
	{
		if ( runnables.empty() )
			return {};

		auto run = runnables.front();
		runnables.pop_front();

		return run;
	}

	std::size_t runnable_count()
	{
		return runnables.size();
	}

	void add_runnable( runnable_ptr run )
	{
		runnables.push_back( run );
	}

	template<class Callback, class... Args>
	void add_callback( Callback callback, Args&&... args )
	{
		runnable_ptr run =
			std::make_shared<runnable>( callback, std::forward<Args>(args)... );

		run->set_once();
		add_runnable( run );
	}

	void reset()
	{
		runnables.clear();
	}

	void set_thread_id( thread_id id )
	{
		tid = id;
	}

	void set_thread_id()
	{
		tid = std::this_thread::get_id();
	}

	thread_id get_thread_id() const
	{
		return tid;
	}

	static thread_id current_thread_id()
	{
		return std::this_thread::get_id();
	}
};

struct context_invoker
{
	using context_ptr = context::context_ptr;

	context_ptr ctxt;

	context_invoker( context_ptr c )
		: ctxt(c)
	{
		ctxt->set_thread_id();
	}

	bool iterate()
	{
		auto nextrun = ctxt->next_runnable();

		if (!nextrun)
			return false;

		auto res = nextrun->run();

		if ( res == runnable_status::CONTINUING )
			ctxt->add_runnable( nextrun );

		return true;
	}

};

class toe
{
	using context_ptr = context::context_ptr;

	context_ptr ctxt;
	std::mutex mutex;
	std::atomic<bool> pauseme;
	std::atomic<bool> quitme;
	std::condition_variable cond;
	std::thread thr;

	void run()
	{
		context_invoker inv( ctxt );

		for ( bool finished = false;
		      !finished;
		    ) {

			if ( pauseme )
				handle_pause();

			if ( quitme )
				break;

			auto res = inv.iterate();
			if ( !res ) {
				idle( [&](){ return !quitme && ctxt->runnable_count() == 0; } );
			}

		}

		handle_quit();
	}

	bool is_toe_context()
	{
		return ctxt->get_thread_id() == context::current_thread_id();
	}

	void idle()
	{
		std::unique_lock<std::mutex> lock( mutex );
		cond.wait_for( lock, std::chrono::milliseconds(10) );
	}

	template<class Condition>
	void idle( Condition cond )
	{
		while( cond() )
			idle();
	}

	void wake()
	{
		cond.notify_all();
	}

	void handle_pause()
	{
		if ( !is_toe_context() )
			return;

		while( pauseme == true ) {
			idle();
		}
	}

	void handle_resume()
	{
		wake();
	}

	void handle_quit()
	{}

public:
	enum launch_type {
		sync,
		async
	};

public:
	toe() :
		ctxt{ context::create() }, mutex{}, pauseme{false},
		quitme{false}, cond{}, thr{}
	{}

	toe( context_ptr c )
		: ctxt{ c }, mutex{}, pauseme{false}, quitme{false},
		  cond{}, thr{}
	{}

	~toe()
	{
		quit();
		join();
	}

	void set_context( context_ptr c )
	{
		using std::swap;
		swap( ctxt, c );
	}

	void launch( launch_type t = sync )
	{
		if ( t == sync )
			run();
		else if ( t == async )
			thr = std::thread( &toe::run, this );
	}

	void pause()
	{ pauseme = true; handle_pause(); }

	void resume()
	{ pauseme = false; handle_resume(); }

	void quit()
	{ quitme = true; resume(); }

	void join()
	{
		if ( joinable() )
			thr.join();
	}

	bool joinable()
	{
		return thr.joinable();
	}

	void sleep_for( long long time_us )
	{
		if ( is_toe_context() )
			std::this_thread::sleep_for( std::chrono::microseconds( time_us ) );
	}

	template<class Callback, class... Args>
	void add_callback( Callback callback, Args&&... args )
	{
		ctxt->add_callback( callback, std::forward<Args>(args)... );
		wake();
	}
};

template<class Ret, class... Args, class RetGenerator = Ret>
auto toe_callback( toe& toe, pac::callback<Ret(Args...)> cb )
{
	auto stubfunc = [&toe, cb]( Args... args )
		{
			toe.add_callback( cb, std::forward<Args>(args)... );
			return RetGenerator();
		};

	pac::callback<Ret(Args...)> stubcb( stubfunc );
	return stubcb;
}

} // namespace pac

#endif // PAC_CONTEXT_HPP
<commit_msg>Add locking to areas in pac::toe where it accesses context<commit_after>/*
 * This file is part of PAC
 *
 * PAC is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * PAC is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with PAC.  If not, see <http://www.gnu.org/licenses/>.
 *
 */

/*
 * context.hpp
 *
 * Author: Brian Fransioli
 * Created: Mon Mar 10 17:30:53 KST 2014
 * Last modified: Wed Mar 19 16:51:50 KST 2014
 */

#ifndef PAC_CONTEXT_HPP
#define PAC_CONTEXT_HPP

#include "runnable.hpp"
#include "signal.hpp"

#include <memory>
#include <thread>
#include <condition_variable>
#include <mutex>
#include <vector>
#include <map>
#include <list>
#include <algorithm>
#include <atomic>

namespace pac {

class context
{
public:
	using runnable_ptr = std::shared_ptr< runnable >;
	using runnable_cont = std::list< runnable_ptr >;
	using runnable_iter = typename runnable_cont::iterator;

	using context_id = std::size_t;
	using context_ptr = std::shared_ptr< context >;

	using thread_id = std::thread::id;

private:
	runnable_cont runnables;
	context_id cid;
	thread_id tid;

public:
	context()
		: runnables{}, cid{}, tid{}
	{}

	static context_ptr create()
	{
		return std::make_shared<context>();
	}

	runnable_ptr next_runnable()
	{
		if ( runnables.empty() )
			return {};

		auto run = runnables.front();
		runnables.pop_front();

		return run;
	}

	std::size_t runnable_count()
	{
		return runnables.size();
	}

	void add_runnable( runnable_ptr run )
	{
		runnables.push_back( run );
	}

	template<class Callback, class... Args>
	void add_callback( Callback callback, Args&&... args )
	{
		runnable_ptr run =
			std::make_shared<runnable>( callback, std::forward<Args>(args)... );

		run->set_once();
		add_runnable( run );
	}

	void reset()
	{
		runnables.clear();
	}

	void set_thread_id( thread_id id )
	{
		tid = id;
	}

	void set_thread_id()
	{
		tid = std::this_thread::get_id();
	}

	thread_id get_thread_id() const
	{
		return tid;
	}

	static thread_id current_thread_id()
	{
		return std::this_thread::get_id();
	}
};

struct context_invoker
{
	using context_ptr = context::context_ptr;

	context_ptr ctxt;

	context_invoker( context_ptr c )
		: ctxt(c)
	{
		ctxt->set_thread_id();
	}

	bool iterate(std::mutex& mutex)
	{
		std::unique_lock<std::mutex> lock( mutex );
		auto nextrun = ctxt->next_runnable();
		lock.unlock();

		if (!nextrun)
			return false;

		auto res = nextrun->run();

		if ( res == runnable_status::CONTINUING ) {
			lock.lock();
			ctxt->add_runnable( nextrun );
			lock.unlock();
		}

		return true;
	}

};

class toe
{
	using context_ptr = context::context_ptr;

	context_ptr ctxt;
	std::mutex mutex;
	std::atomic<bool> pauseme;
	std::atomic<bool> quitme;
	std::condition_variable cond;
	std::thread thr;

	void run()
	{
		context_invoker inv( ctxt );

		for ( bool finished = false; !finished; ) {

			if ( pauseme )
				handle_pause();

			if ( quitme )
				break;

			auto res = inv.iterate(mutex);
			if ( !res ) {
				idle( [&](){ return !quitme && ctxt->runnable_count() == 0; } );
			}

		}

		handle_quit();
	}

	bool is_toe_context()
	{
		return ctxt->get_thread_id() == context::current_thread_id();
	}

	void idle()
	{
		std::unique_lock<std::mutex> lock( mutex );
		cond.wait_for( lock, std::chrono::milliseconds(10) );
	}

	template<class Condition>
	void idle( Condition cond )
	{
		while( cond() )
			idle();
	}

	void wake()
	{
		std::lock_guard<std::mutex> lock( mutex );
		cond.notify_all();
	}

	void handle_pause()
	{
		if ( !is_toe_context() )
			return;

		while( pauseme == true ) {
			idle();
		}
	}

	void handle_resume()
	{
		wake();
	}

	void handle_quit()
	{}

public:
	enum launch_type {
		sync,
		async
	};

public:
	toe() :
		ctxt{ context::create() }, mutex{}, pauseme{false},
		quitme{false}, cond{}, thr{}
	{}

	toe( context_ptr c )
		: ctxt{ c }, mutex{}, pauseme{false}, quitme{false},
		  cond{}, thr{}
	{}

	~toe()
	{
		quit();
		join();
	}

	void set_context( context_ptr c )
	{
		using std::swap;
		swap( ctxt, c );
	}

	void launch( launch_type t = sync )
	{
		if ( t == sync )
			run();
		else if ( t == async )
			thr = std::thread( &toe::run, this );
	}

	void pause()
	{ pauseme = true; handle_pause(); }

	void resume()
	{ pauseme = false; handle_resume(); }

	void quit()
	{ quitme = true; resume(); }

	void join()
	{
		if ( joinable() )
			thr.join();
	}

	bool joinable()
	{
		return thr.joinable();
	}

	void sleep_for( long long time_us )
	{
		if ( is_toe_context() )
			std::this_thread::sleep_for( std::chrono::microseconds( time_us ) );
	}

	template<class Callback, class... Args>
	void add_callback( Callback callback, Args&&... args )
	{
		{
			std::lock_guard<std::mutex> lock( mutex );
			ctxt->add_callback( callback, std::forward<Args>(args)... );
		}
		wake();
	}
};

template<class Ret, class... Args, class RetGenerator = Ret>
auto toe_callback( toe& toe, pac::callback<Ret(Args...)> cb )
{
	auto stubfunc = [&toe, cb]( Args... args )
		{
			toe.add_callback( cb, std::forward<Args>(args)... );
			return RetGenerator();
		};

	pac::callback<Ret(Args...)> stubcb( stubfunc );
	return stubcb;
}

} // namespace pac

#endif // PAC_CONTEXT_HPP
<|endoftext|>


<commit_before>/*
 * Copyright 2019 Google Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "p2a.hpp"

#include "data.hpp"
#include "flags.hpp"
#include "pci.hpp"
#include "tool_errors.hpp"

#include <fmt/format.h>

#include <ipmiblob/blob_errors.hpp>
#include <stdplus/handle/managed.hpp>

#include <cstdint>
#include <cstring>
#include <memory>
#include <string>

namespace host_tool
{

namespace
{

/** @brief RAII wrapper and its destructor for opening a file descriptor */
static void closeFd(int&& fd, const internal::Sys* const& sys)
{
    sys->close(fd);
}
using Fd = stdplus::Managed<int, const internal::Sys* const>::Handle<closeFd>;

} // namespace

bool P2aDataHandler::sendContents(const std::string& input,
                                  std::uint16_t session)
{
    std::unique_ptr<PciBridgeIntf> bridge;
    ipmi_flash::PciConfigResponse pciResp;
    std::int64_t fileSize;

    try
    {
        bridge = std::make_unique<NuvotonPciBridge>(pci, skipBridgeDisable);
    }
    catch (NotFoundException& e)
    {}

    try
    {
        bridge = std::make_unique<AspeedPciBridge>(pci, skipBridgeDisable);
    }
    catch (NotFoundException& e)
    {}

    if (!bridge)
    {
        throw NotFoundException("supported PCI device");
    }

    /* Read the configuration via blobs metadata (stat). */
    ipmiblob::StatResponse stat = blob->getStat(session);
    if (stat.metadata.size() != sizeof(ipmi_flash::PciConfigResponse))
    {
        throw ToolException("Didn't receive expected size of metadata for "
                            "PCI Configuration response");
    }

    std::memcpy(&pciResp, stat.metadata.data(), sizeof(pciResp));
    bridge->configure(pciResp);

    /* For data blocks in 64kb, stage data, and send blob write command. */
    Fd inputFd(sys->open(input.c_str(), 0), sys);
    if (*inputFd < 0)
    {
        (void)inputFd.release();
        throw internal::errnoException(
            fmt::format("Error opening file '{}'", input));
    }

    fileSize = sys->getSize(input.c_str());
    if (fileSize == 0)
    {
        throw ToolException("Zero-length file, or other file access error");
    }

    progress->start(fileSize);

    std::vector<std::uint8_t> readBuffer(bridge->getDataLength());

    int bytesRead = 0;
    std::uint32_t offset = 0;

    do
    {
        bytesRead = sys->read(*inputFd, readBuffer.data(), readBuffer.size());
        if (bytesRead > 0)
        {
            bridge->write(stdplus::span<const std::uint8_t>(readBuffer.data(),
                                                            bytesRead));

            /* Ok, so the data is staged, now send the blob write with the
             * details.
             */
            struct ipmi_flash::ExtChunkHdr chunk;
            chunk.length = bytesRead;
            std::vector<std::uint8_t> chunkBytes(sizeof(chunk));
            std::memcpy(chunkBytes.data(), &chunk, sizeof(chunk));

            /* This doesn't return anything on success. */
            blob->writeBytes(session, offset, chunkBytes);
            offset += bytesRead;
            progress->updateProgress(bytesRead);
        }
    } while (bytesRead > 0);

    progress->finish();
    return true;
}

} // namespace host_tool
<commit_msg>catch exceptions as const<commit_after>/*
 * Copyright 2019 Google Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "p2a.hpp"

#include "data.hpp"
#include "flags.hpp"
#include "pci.hpp"
#include "tool_errors.hpp"

#include <fmt/format.h>

#include <ipmiblob/blob_errors.hpp>
#include <stdplus/handle/managed.hpp>

#include <cstdint>
#include <cstring>
#include <memory>
#include <string>

namespace host_tool
{

namespace
{

/** @brief RAII wrapper and its destructor for opening a file descriptor */
static void closeFd(int&& fd, const internal::Sys* const& sys)
{
    sys->close(fd);
}
using Fd = stdplus::Managed<int, const internal::Sys* const>::Handle<closeFd>;

} // namespace

bool P2aDataHandler::sendContents(const std::string& input,
                                  std::uint16_t session)
{
    std::unique_ptr<PciBridgeIntf> bridge;
    ipmi_flash::PciConfigResponse pciResp;
    std::int64_t fileSize;

    try
    {
        bridge = std::make_unique<NuvotonPciBridge>(pci, skipBridgeDisable);
    }
    catch (const NotFoundException& e)
    {}

    try
    {
        bridge = std::make_unique<AspeedPciBridge>(pci, skipBridgeDisable);
    }
    catch (const NotFoundException& e)
    {}

    if (!bridge)
    {
        throw NotFoundException("supported PCI device");
    }

    /* Read the configuration via blobs metadata (stat). */
    ipmiblob::StatResponse stat = blob->getStat(session);
    if (stat.metadata.size() != sizeof(ipmi_flash::PciConfigResponse))
    {
        throw ToolException("Didn't receive expected size of metadata for "
                            "PCI Configuration response");
    }

    std::memcpy(&pciResp, stat.metadata.data(), sizeof(pciResp));
    bridge->configure(pciResp);

    /* For data blocks in 64kb, stage data, and send blob write command. */
    Fd inputFd(sys->open(input.c_str(), 0), sys);
    if (*inputFd < 0)
    {
        (void)inputFd.release();
        throw internal::errnoException(
            fmt::format("Error opening file '{}'", input));
    }

    fileSize = sys->getSize(input.c_str());
    if (fileSize == 0)
    {
        throw ToolException("Zero-length file, or other file access error");
    }

    progress->start(fileSize);

    std::vector<std::uint8_t> readBuffer(bridge->getDataLength());

    int bytesRead = 0;
    std::uint32_t offset = 0;

    do
    {
        bytesRead = sys->read(*inputFd, readBuffer.data(), readBuffer.size());
        if (bytesRead > 0)
        {
            bridge->write(stdplus::span<const std::uint8_t>(readBuffer.data(),
                                                            bytesRead));

            /* Ok, so the data is staged, now send the blob write with the
             * details.
             */
            struct ipmi_flash::ExtChunkHdr chunk;
            chunk.length = bytesRead;
            std::vector<std::uint8_t> chunkBytes(sizeof(chunk));
            std::memcpy(chunkBytes.data(), &chunk, sizeof(chunk));

            /* This doesn't return anything on success. */
            blob->writeBytes(session, offset, chunkBytes);
            offset += bytesRead;
            progress->updateProgress(bytesRead);
        }
    } while (bytesRead > 0);

    progress->finish();
    return true;
}

} // namespace host_tool
<|endoftext|>


<commit_before>#include <chrono>
#include <exception>
#include <stdexcept>	// __gnu_cxx::__verbose_terminate_handler
#include <fstream>
#include <iostream>
#include <thread>

#include <libtorrent/add_torrent_params.hpp>
#include <libtorrent/alert_types.hpp>
#include <libtorrent/bencode.hpp>
#include <libtorrent/create_torrent.hpp>
#include <libtorrent/session.hpp>
#include <libtorrent/storage_defs.hpp>	// lt::disabled_storage_constructor
#include <libtorrent/torrent_handle.hpp>
#include <libtorrent/torrent_info.hpp>

namespace lt = libtorrent;
int main(int argc, char *argv[]) {
	std::set_terminate(__gnu_cxx::__verbose_terminate_handler);
	if (argc != 2) {
		std::cerr << "usage: " << argv[0] << " <magnet-url>" <<
			std::endl;
		return 1;
	}

	lt::session ses;
	lt::add_torrent_params atp;
	atp.url = argv[1];
	atp.upload_mode = true;
	atp.auto_managed = false;
	atp.paused = false;
	// Start with "storage == disabled" to avoid pre-allocating any files
	// mentioned in the torrent file on disk:
	atp.storage = lt::disabled_storage_constructor;
	atp.save_path = "."; // save in current dir
	/*
	// .flags duplicate .upload_mode/auto_managed/paused
	// functionality:
	atp.flags = lt::add_torrent_params::flag_update_subscribe
		| lt::add_torrent_params::flag_upload_mode
		| lt::add_torrent_params::flag_apply_ip_filter;
	*/
	lt::torrent_handle torh = ses.add_torrent(atp);
	std::cout << atp.url << ":";
	for (;;) {
		std::deque<lt::alert*> alerts;
		ses.pop_alerts(&alerts);
		for (lt::alert const* a : alerts) {
			std::cout << std::endl << a->message() << std::endl;
			// quit on error/finish:
			if (lt::alert_cast<lt::torrent_finished_alert>(a)
			|| lt::alert_cast<lt::torrent_error_alert>(a)) {
				goto done1;
			};
		}
		if (torh.status().has_metadata) {
			ses.pause();
			lt::torrent_info tinf =
				torh.get_torrent_info();
			std::cout << tinf.name() << std::endl;
			std::cout.flush();
			std::ofstream ofs;
			ofs.exceptions(std::ofstream::failbit
					| std::ofstream::badbit);
			ofs.open(tinf.name() + ".torrent");
			std::ostream_iterator<char> ofsi(ofs);
			lt::bencode(ofsi, lt::create_torrent(tinf)
					.generate());
			ofs.close();
			ses.remove_torrent(torh);
			goto done0;
		};
		std::cout << ".";
		std::cout.flush();
		std::this_thread::sleep_for(
			std::chrono::milliseconds(1000));
	}
done0:
	return 0;
done1:
	return 1;
}

// vi: set sw=8 ts=8 noet tw=77:
<commit_msg>Write .torrent file in binary mode.<commit_after>#include <chrono>
#include <exception>
#include <stdexcept>	// __gnu_cxx::__verbose_terminate_handler
#include <fstream>
#include <iostream>
#include <thread>

#include <libtorrent/add_torrent_params.hpp>
#include <libtorrent/alert_types.hpp>
#include <libtorrent/bencode.hpp>
#include <libtorrent/create_torrent.hpp>
#include <libtorrent/session.hpp>
#include <libtorrent/storage_defs.hpp>	// lt::disabled_storage_constructor
#include <libtorrent/torrent_handle.hpp>
#include <libtorrent/torrent_info.hpp>

namespace lt = libtorrent;
int main(int argc, char *argv[]) {
	std::set_terminate(__gnu_cxx::__verbose_terminate_handler);
	if (argc != 2) {
		std::cerr << "usage: " << argv[0] << " <magnet-url>" <<
			std::endl;
		return 1;
	}

	lt::session ses;
	lt::add_torrent_params atp;
	atp.url = argv[1];
	atp.upload_mode = true;
	atp.auto_managed = false;
	atp.paused = false;
	// Start with "storage == disabled" to avoid pre-allocating any files
	// mentioned in the torrent file on disk:
	atp.storage = lt::disabled_storage_constructor;
	atp.save_path = "."; // save in current dir
	/*
	// .flags duplicate .upload_mode/auto_managed/paused
	// functionality:
	atp.flags = lt::add_torrent_params::flag_update_subscribe
		| lt::add_torrent_params::flag_upload_mode
		| lt::add_torrent_params::flag_apply_ip_filter;
	*/
	lt::torrent_handle torh = ses.add_torrent(atp);
	std::cout << atp.url << ":";
	for (;;) {
		std::deque<lt::alert*> alerts;
		ses.pop_alerts(&alerts);
		for (lt::alert const* a : alerts) {
			std::cout << std::endl << a->message() << std::endl;
			// quit on error/finish:
			if (lt::alert_cast<lt::torrent_finished_alert>(a)
			|| lt::alert_cast<lt::torrent_error_alert>(a)) {
				goto done1;
			};
		}
		if (torh.status().has_metadata) {
			ses.pause();
			lt::torrent_info tinf =
				torh.get_torrent_info();
			std::cout << tinf.name() << std::endl;
			std::cout.flush();
			std::ofstream ofs;
			ofs.exceptions(std::ofstream::failbit
					| std::ofstream::badbit);
			ofs.open(tinf.name() + ".torrent",
					std::ofstream::binary);
			std::ostream_iterator<char> ofsi(ofs);
			lt::bencode(ofsi, lt::create_torrent(tinf)
					.generate());
			ofs.close();
			ses.remove_torrent(torh);
			goto done0;
		};
		std::cout << ".";
		std::cout.flush();
		std::this_thread::sleep_for(
			std::chrono::milliseconds(1000));
	}
done0:
	return 0;
done1:
	return 1;
}

// vi: set sw=8 ts=8 noet tw=77:
<|endoftext|>


<commit_before>#include <gtest/gtest.h>
#include "exp.h"

int main( int argc , char **argv )
{
    testing :: InitGoogleTest( &argc , argv ) ;
    return RUN_ALL_TESTS( ) ;
}
<commit_msg>Delete mainExp.cpp<commit_after><|endoftext|>


<commit_before>/*************************************************************************
 *
 *  $RCSfile: flyincnt.cxx,v $
 *
 *  $Revision: 1.5 $
 *
 *  last change: $Author: vg $ $Date: 2003-04-17 14:12:06 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (the "License"); You may not use this file
 *  except in compliance with the License. You may obtain a copy of the
 *  License at http://www.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#pragma hdrstop

#include "cntfrm.hxx"
#include "doc.hxx"
#include "flyfrm.hxx"
#include "frmtool.hxx"
#include "frmfmt.hxx"
#include "hints.hxx"

#ifndef _FMTORNT_HXX //autogen
#include <fmtornt.hxx>
#endif
#ifndef _FMTFSIZE_HXX //autogen
#include <fmtfsize.hxx>
#endif
#include "txtfrm.hxx"       //fuer IsLocked()
#include "flyfrms.hxx"

//aus FlyCnt.cxx
void DeepCalc( const SwFrm *pFrm );

/*************************************************************************
|*
|*  SwFlyInCntFrm::SwFlyInCntFrm(), ~SwFlyInCntFrm()
|*
|*  Ersterstellung      MA 01. Dec. 92
|*  Letzte Aenderung    MA 09. Apr. 99
|*
|*************************************************************************/
SwFlyInCntFrm::SwFlyInCntFrm( SwFlyFrmFmt *pFmt, SwFrm *pAnch ) :
    SwFlyFrm( pFmt, pAnch )
{
    bInCnt = bInvalidLayout = bInvalidCntnt = TRUE;
    SwTwips nRel = pFmt->GetVertOrient().GetPos();
#ifdef VERTICAL_LAYOUT
    if( pAnch && pAnch->IsVertical() )
        aRelPos.X() = pAnch->IsReverse() ? nRel : -nRel;
    else
#endif
    aRelPos.Y() = nRel;
}

SwFlyInCntFrm::~SwFlyInCntFrm()
{
    //und Tschuess.
    if ( !GetFmt()->GetDoc()->IsInDtor() && GetAnchor() )
    {
        SwRect aTmp( AddSpacesToFrm() );
        SwFlyInCntFrm::NotifyBackground( FindPageFrm(), aTmp, PREP_FLY_LEAVE );
    }
}

/*************************************************************************
|*
|*  SwFlyInCntFrm::SetRefPoint(),
|*
|*  Ersterstellung      MA 01. Dec. 92
|*  Letzte Aenderung    MA 06. Aug. 95
|*
|*************************************************************************/
void SwFlyInCntFrm::SetRefPoint( const Point& rPoint, const Point& rRelAttr,
    const Point& rRelPos )
{
    ASSERT( rPoint != aRef || rRelAttr != aRelPos, "SetRefPoint: no change" );
    SwFlyNotify *pNotify = NULL;
    // No notify at a locked fly frame, if a fly frame is locked, there's
    // already a SwFlyNotify object on the stack (MakeAll).
    if( !IsLocked() )
        pNotify = new SwFlyNotify( this );
    aRef = rPoint;
    aRelPos = rRelAttr;
#ifdef VERTICAL_LAYOUT
    SWRECTFN( GetAnchor() )
    (Frm().*fnRect->fnSetPos)( rPoint + rRelPos );
#else
    Frm().Pos( rPoint + rRelPos );
#endif
/*
    //Kein InvalidatePos hier, denn das wuerde dem Cntnt ein Prepare
    //senden - dieser hat uns aber gerade gerufen.
    //Da der Frm aber durchaus sein Position wechseln kann, muss hier
    //der von ihm abdeckte Window-Bereich invalidiert werden damit keine
    //Reste stehenbleiben.
    //Fix: Nicht fuer PreView-Shells, dort ist es nicht notwendig und
    //fuehrt zu fiesen Problemen (Der Absatz wird nur formatiert weil
    //er gepaintet wird und der Cache uebergelaufen ist, beim Paint durch
    //das Invalidate wird der Absatz formatiert weil...)
    if ( Frm().HasArea() && GetShell()->ISA(SwCrsrShell) )
        GetShell()->InvalidateWindows( Frm() );
*/
    if( pNotify )
    {
        InvalidatePage();
        bValidPos = FALSE;
        bInvalid  = TRUE;
        Calc();
        delete pNotify;
    }
}

/*************************************************************************
|*
|*  SwFlyInCntFrm::Modify()
|*
|*  Ersterstellung      MA 16. Dec. 92
|*  Letzte Aenderung    MA 02. Sep. 93
|*
|*************************************************************************/
void SwFlyInCntFrm::Modify( SfxPoolItem *pOld, SfxPoolItem *pNew )
{
    BOOL bCallPrepare = FALSE;
    USHORT nWhich = pOld ? pOld->Which() : pNew ? pNew->Which() : 0;
    if( RES_ATTRSET_CHG == nWhich )
    {
        if( SFX_ITEM_SET == ((SwAttrSetChg*)pNew)->GetChgSet()->
            GetItemState( RES_SURROUND, FALSE ) ||
            SFX_ITEM_SET == ((SwAttrSetChg*)pNew)->GetChgSet()->
            GetItemState( RES_FRMMACRO, FALSE ) )
        {
            SwAttrSetChg aOld( *(SwAttrSetChg*)pOld );
            SwAttrSetChg aNew( *(SwAttrSetChg*)pNew );

            aOld.ClearItem( RES_SURROUND );
            aNew.ClearItem( RES_SURROUND );
            aOld.ClearItem( RES_FRMMACRO );
            aNew.ClearItem( RES_FRMMACRO );
            if( aNew.Count() )
            {
                SwFlyFrm::Modify( &aOld, &aNew );
                bCallPrepare = TRUE;
            }
        }
        else if( ((SwAttrSetChg*)pNew)->GetChgSet()->Count())
        {
            SwFlyFrm::Modify( pOld, pNew );
            bCallPrepare = TRUE;
        }
    }
    else if( nWhich != RES_SURROUND && RES_FRMMACRO != nWhich )
    {
        SwFlyFrm::Modify( pOld, pNew );
        bCallPrepare = TRUE;
    }

    if ( bCallPrepare && GetAnchor() )
        GetAnchor()->Prepare( PREP_FLY_ATTR_CHG, GetFmt() );
}
/*************************************************************************
|*
|*  SwFlyInCntFrm::Format()
|*
|*  Beschreibung:       Hier wird der Inhalt initial mit Formatiert.
|*  Ersterstellung      MA 16. Dec. 92
|*  Letzte Aenderung    MA 19. May. 93
|*
|*************************************************************************/
void SwFlyInCntFrm::Format( const SwBorderAttrs *pAttrs )
{
    if ( !Frm().Height() )
    {
        Lock(); //nicht hintenherum den Anker formatieren.
        SwCntntFrm *pCntnt = ContainsCntnt();
        while ( pCntnt )
        {   pCntnt->Calc();
            pCntnt = pCntnt->GetNextCntntFrm();
        }
        Unlock();
    }
    SwFlyFrm::Format( pAttrs );
}
/*************************************************************************
|*
|*  SwFlyInCntFrm::MakeFlyPos()
|*
|*  Beschreibung        Im Unterschied zu anderen Frms wird hier nur die
|*      die RelPos berechnet. Die absolute Position wird ausschliesslich
|*      per SetAbsPos errechnet.
|*  Ersterstellung      MA 03. Dec. 92
|*  Letzte Aenderung    MA 12. Apr. 96
|*
|*************************************************************************/
void SwFlyInCntFrm::MakeFlyPos()
{
    if ( !bValidPos )
    {
        if ( !GetAnchor()->IsTxtFrm() || !((SwTxtFrm*)GetAnchor())->IsLocked() )
            ::DeepCalc( GetAnchor() );
        if( GetAnchor()->IsTxtFrm() )
            ((SwTxtFrm*)GetAnchor())->GetFormatted();
        bValidPos = TRUE;
        SwFlyFrmFmt *pFmt = (SwFlyFrmFmt*)GetFmt();
        const SwFmtVertOrient &rVert = pFmt->GetVertOrient();
        //Und ggf. noch die aktuellen Werte im Format updaten, dabei darf
        //zu diesem Zeitpunkt natuerlich kein Modify verschickt werden.
#ifdef VERTICAL_LAYOUT
        SWRECTFN( GetAnchor() )
        SwTwips nOld = rVert.GetPos();
        SwTwips nAct = bVert ? -aRelPos.X() : aRelPos.Y();
        if( bRev )
            nAct = -nAct;
        if( nAct != nOld )
        {
            SwFmtVertOrient aVert( rVert );
            aVert.SetPos( nAct );
#else
        if ( rVert.GetPos() != aRelPos.Y() )
        {
            SwFmtVertOrient aVert( rVert );
            aVert.SetPos( aRelPos.Y() );
#endif
            pFmt->LockModify();
            pFmt->SetAttr( aVert );
            pFmt->UnlockModify();
        }
    }
}

/*************************************************************************
|*
|*  SwFlyInCntFrm::NotifyBackground()
|*
|*  Ersterstellung      MA 03. Dec. 92
|*  Letzte Aenderung    MA 26. Aug. 93
|*
|*************************************************************************/
void SwFlyInCntFrm::NotifyBackground( SwPageFrm *, const SwRect& rRect,
                                       PrepareHint eHint)
{
    if ( eHint == PREP_FLY_ATTR_CHG )
        GetAnchor()->Prepare( PREP_FLY_ATTR_CHG );
    else
        GetAnchor()->Prepare( eHint, (void*)&rRect );
}

/*************************************************************************
|*
|*  SwFlyInCntFrm::GetRelPos()
|*
|*  Ersterstellung      MA 04. Dec. 92
|*  Letzte Aenderung    MA 04. Dec. 92
|*
|*************************************************************************/
const Point &SwFlyInCntFrm::GetRelPos() const
{
    Calc();
    return GetCurRelPos();
}

/*************************************************************************
|*
|*  SwFlyInCntFrm::RegistFlys()
|*
|*  Ersterstellung      MA 26. Nov. 93
|*  Letzte Aenderung    MA 26. Nov. 93
|*
|*************************************************************************/
void SwFlyInCntFrm::RegistFlys()
{
    // vgl. SwRowFrm::RegistFlys()
    SwPageFrm *pPage = FindPageFrm();
    ASSERT( pPage, "Flys ohne Seite anmelden?" );
    ::RegistFlys( pPage, this );
}

/*************************************************************************
|*
|*  SwFlyInCntFrm::MakeAll()
|*
|*  Ersterstellung      MA 18. Feb. 94
|*  Letzte Aenderung    MA 13. Jun. 96
|*
|*************************************************************************/
void SwFlyInCntFrm::MakeAll()
{
    if ( !GetAnchor() || IsLocked() || IsColLocked() || !FindPageFrm() )
        return;

    Lock(); //Der Vorhang faellt

        //uebernimmt im DTor die Benachrichtigung
    const SwFlyNotify aNotify( this );
    SwBorderAttrAccess aAccess( SwFrm::GetCache(), this );
    const SwBorderAttrs &rAttrs = *aAccess.Get();
    const Size &rSz = rAttrs.GetSize();
    const SwFmtFrmSize &rFrmSz = GetFmt()->GetFrmSize();

    if ( IsClipped() )
        bValidSize = bHeightClipped = bWidthClipped = FALSE;

    while ( !bValidPos || !bValidSize || !bValidPrtArea )
    {
        //Nur einstellen wenn das Flag gesetzt ist!!
        if ( !bValidSize )
        {
            bValidPrtArea = FALSE;
            long nOldWidth = aFrm.Width();
            aFrm.Width( CalcRel( rFrmSz ).Width() );

            if ( aFrm.Width() > nOldWidth )
                //Damit sich der Inhalt anpasst
                aFrm.Height( CalcRel( rFrmSz ).Height() );
        }

        if ( !bValidPrtArea )
            MakePrtArea( rAttrs );

        if ( !bValidSize )
            Format( &rAttrs );

        if ( !bValidPos )
            MakeFlyPos();

        if ( bValidPos && bValidSize )
        {
            SwFrm *pFrm = GetAnchor();
            if (
//MA 03. Apr. 96 fix(26652), Das trifft uns bestimmt nocheinmal
//          !pFrm->IsMoveable() &&
                 Frm().Left() == (pFrm->Frm().Left()+pFrm->Prt().Left()) &&
                 Frm().Width() > pFrm->Prt().Width() )
            {
                Frm().Width( pFrm->Prt().Width() );
                bValidPrtArea = FALSE;
                bWidthClipped = TRUE;
            }
        }
    }
    Unlock();
}

<commit_msg>INTEGRATION: CWS hiddentext (1.5.308); FILE MERGED 2004/01/19 10:09:14 od 1.5.308.1: #110582# - adjustments for hiding objects in hidden paragraphs/text<commit_after>/*************************************************************************
 *
 *  $RCSfile: flyincnt.cxx,v $
 *
 *  $Revision: 1.6 $
 *
 *  last change: $Author: kz $ $Date: 2004-02-26 15:30:13 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (the "License"); You may not use this file
 *  except in compliance with the License. You may obtain a copy of the
 *  License at http://www.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#pragma hdrstop

#include "cntfrm.hxx"
#include "doc.hxx"
#include "flyfrm.hxx"
#include "frmtool.hxx"
#include "frmfmt.hxx"
#include "hints.hxx"

#ifndef _FMTORNT_HXX //autogen
#include <fmtornt.hxx>
#endif
#ifndef _FMTFSIZE_HXX //autogen
#include <fmtfsize.hxx>
#endif
#include "txtfrm.hxx"       //fuer IsLocked()
#include "flyfrms.hxx"
// OD 2004-01-19 #110582#
#ifndef _DFLYOBJ_HXX
#include <dflyobj.hxx>
#endif

//aus FlyCnt.cxx
void DeepCalc( const SwFrm *pFrm );

/*************************************************************************
|*
|*  SwFlyInCntFrm::SwFlyInCntFrm(), ~SwFlyInCntFrm()
|*
|*  Ersterstellung      MA 01. Dec. 92
|*  Letzte Aenderung    MA 09. Apr. 99
|*
|*************************************************************************/
SwFlyInCntFrm::SwFlyInCntFrm( SwFlyFrmFmt *pFmt, SwFrm *pAnch ) :
    SwFlyFrm( pFmt, pAnch )
{
    bInCnt = bInvalidLayout = bInvalidCntnt = TRUE;
    SwTwips nRel = pFmt->GetVertOrient().GetPos();
#ifdef VERTICAL_LAYOUT
    if( pAnch && pAnch->IsVertical() )
        aRelPos.X() = pAnch->IsReverse() ? nRel : -nRel;
    else
#endif
    aRelPos.Y() = nRel;
}

SwFlyInCntFrm::~SwFlyInCntFrm()
{
    //und Tschuess.
    if ( !GetFmt()->GetDoc()->IsInDtor() && GetAnchor() )
    {
        SwRect aTmp( AddSpacesToFrm() );
        SwFlyInCntFrm::NotifyBackground( FindPageFrm(), aTmp, PREP_FLY_LEAVE );
    }
}

/*************************************************************************
|*
|*  SwFlyInCntFrm::SetRefPoint(),
|*
|*  Ersterstellung      MA 01. Dec. 92
|*  Letzte Aenderung    MA 06. Aug. 95
|*
|*************************************************************************/
void SwFlyInCntFrm::SetRefPoint( const Point& rPoint, const Point& rRelAttr,
    const Point& rRelPos )
{
    ASSERT( rPoint != aRef || rRelAttr != aRelPos, "SetRefPoint: no change" );
    SwFlyNotify *pNotify = NULL;
    // No notify at a locked fly frame, if a fly frame is locked, there's
    // already a SwFlyNotify object on the stack (MakeAll).
    if( !IsLocked() )
        pNotify = new SwFlyNotify( this );
    aRef = rPoint;
    aRelPos = rRelAttr;
#ifdef VERTICAL_LAYOUT
    SWRECTFN( GetAnchor() )
    (Frm().*fnRect->fnSetPos)( rPoint + rRelPos );
#else
    Frm().Pos( rPoint + rRelPos );
#endif
/*
    //Kein InvalidatePos hier, denn das wuerde dem Cntnt ein Prepare
    //senden - dieser hat uns aber gerade gerufen.
    //Da der Frm aber durchaus sein Position wechseln kann, muss hier
    //der von ihm abdeckte Window-Bereich invalidiert werden damit keine
    //Reste stehenbleiben.
    //Fix: Nicht fuer PreView-Shells, dort ist es nicht notwendig und
    //fuehrt zu fiesen Problemen (Der Absatz wird nur formatiert weil
    //er gepaintet wird und der Cache uebergelaufen ist, beim Paint durch
    //das Invalidate wird der Absatz formatiert weil...)
    if ( Frm().HasArea() && GetShell()->ISA(SwCrsrShell) )
        GetShell()->InvalidateWindows( Frm() );
*/
    if( pNotify )
    {
        InvalidatePage();
        bValidPos = FALSE;
        bInvalid  = TRUE;
        Calc();
        delete pNotify;
    }
}

/*************************************************************************
|*
|*  SwFlyInCntFrm::Modify()
|*
|*  Ersterstellung      MA 16. Dec. 92
|*  Letzte Aenderung    MA 02. Sep. 93
|*
|*************************************************************************/
void SwFlyInCntFrm::Modify( SfxPoolItem *pOld, SfxPoolItem *pNew )
{
    BOOL bCallPrepare = FALSE;
    USHORT nWhich = pOld ? pOld->Which() : pNew ? pNew->Which() : 0;
    if( RES_ATTRSET_CHG == nWhich )
    {
        if( SFX_ITEM_SET == ((SwAttrSetChg*)pNew)->GetChgSet()->
            GetItemState( RES_SURROUND, FALSE ) ||
            SFX_ITEM_SET == ((SwAttrSetChg*)pNew)->GetChgSet()->
            GetItemState( RES_FRMMACRO, FALSE ) )
        {
            SwAttrSetChg aOld( *(SwAttrSetChg*)pOld );
            SwAttrSetChg aNew( *(SwAttrSetChg*)pNew );

            aOld.ClearItem( RES_SURROUND );
            aNew.ClearItem( RES_SURROUND );
            aOld.ClearItem( RES_FRMMACRO );
            aNew.ClearItem( RES_FRMMACRO );
            if( aNew.Count() )
            {
                SwFlyFrm::Modify( &aOld, &aNew );
                bCallPrepare = TRUE;
            }
        }
        else if( ((SwAttrSetChg*)pNew)->GetChgSet()->Count())
        {
            SwFlyFrm::Modify( pOld, pNew );
            bCallPrepare = TRUE;
        }
    }
    else if( nWhich != RES_SURROUND && RES_FRMMACRO != nWhich )
    {
        SwFlyFrm::Modify( pOld, pNew );
        bCallPrepare = TRUE;
    }

    if ( bCallPrepare && GetAnchor() )
        GetAnchor()->Prepare( PREP_FLY_ATTR_CHG, GetFmt() );
}
/*************************************************************************
|*
|*  SwFlyInCntFrm::Format()
|*
|*  Beschreibung:       Hier wird der Inhalt initial mit Formatiert.
|*  Ersterstellung      MA 16. Dec. 92
|*  Letzte Aenderung    MA 19. May. 93
|*
|*************************************************************************/
void SwFlyInCntFrm::Format( const SwBorderAttrs *pAttrs )
{
    if ( !Frm().Height() )
    {
        Lock(); //nicht hintenherum den Anker formatieren.
        SwCntntFrm *pCntnt = ContainsCntnt();
        while ( pCntnt )
        {   pCntnt->Calc();
            pCntnt = pCntnt->GetNextCntntFrm();
        }
        Unlock();
    }
    SwFlyFrm::Format( pAttrs );
}
/*************************************************************************
|*
|*  SwFlyInCntFrm::MakeFlyPos()
|*
|*  Beschreibung        Im Unterschied zu anderen Frms wird hier nur die
|*      die RelPos berechnet. Die absolute Position wird ausschliesslich
|*      per SetAbsPos errechnet.
|*  Ersterstellung      MA 03. Dec. 92
|*  Letzte Aenderung    MA 12. Apr. 96
|*
|*************************************************************************/
void SwFlyInCntFrm::MakeFlyPos()
{
    if ( !bValidPos )
    {
        if ( !GetAnchor()->IsTxtFrm() || !((SwTxtFrm*)GetAnchor())->IsLocked() )
            ::DeepCalc( GetAnchor() );
        if( GetAnchor()->IsTxtFrm() )
            ((SwTxtFrm*)GetAnchor())->GetFormatted();
        bValidPos = TRUE;
        SwFlyFrmFmt *pFmt = (SwFlyFrmFmt*)GetFmt();
        const SwFmtVertOrient &rVert = pFmt->GetVertOrient();
        //Und ggf. noch die aktuellen Werte im Format updaten, dabei darf
        //zu diesem Zeitpunkt natuerlich kein Modify verschickt werden.
#ifdef VERTICAL_LAYOUT
        SWRECTFN( GetAnchor() )
        SwTwips nOld = rVert.GetPos();
        SwTwips nAct = bVert ? -aRelPos.X() : aRelPos.Y();
        if( bRev )
            nAct = -nAct;
        if( nAct != nOld )
        {
            SwFmtVertOrient aVert( rVert );
            aVert.SetPos( nAct );
#else
        if ( rVert.GetPos() != aRelPos.Y() )
        {
            SwFmtVertOrient aVert( rVert );
            aVert.SetPos( aRelPos.Y() );
#endif
            pFmt->LockModify();
            pFmt->SetAttr( aVert );
            pFmt->UnlockModify();
        }
    }
}

/*************************************************************************
|*
|*  SwFlyInCntFrm::NotifyBackground()
|*
|*  Ersterstellung      MA 03. Dec. 92
|*  Letzte Aenderung    MA 26. Aug. 93
|*
|*************************************************************************/
void SwFlyInCntFrm::NotifyBackground( SwPageFrm *, const SwRect& rRect,
                                       PrepareHint eHint)
{
    if ( eHint == PREP_FLY_ATTR_CHG )
        GetAnchor()->Prepare( PREP_FLY_ATTR_CHG );
    else
        GetAnchor()->Prepare( eHint, (void*)&rRect );
}

/*************************************************************************
|*
|*  SwFlyInCntFrm::GetRelPos()
|*
|*  Ersterstellung      MA 04. Dec. 92
|*  Letzte Aenderung    MA 04. Dec. 92
|*
|*************************************************************************/
const Point &SwFlyInCntFrm::GetRelPos() const
{
    Calc();
    return GetCurRelPos();
}

/*************************************************************************
|*
|*  SwFlyInCntFrm::RegistFlys()
|*
|*  Ersterstellung      MA 26. Nov. 93
|*  Letzte Aenderung    MA 26. Nov. 93
|*
|*************************************************************************/
void SwFlyInCntFrm::RegistFlys()
{
    // vgl. SwRowFrm::RegistFlys()
    SwPageFrm *pPage = FindPageFrm();
    ASSERT( pPage, "Flys ohne Seite anmelden?" );
    ::RegistFlys( pPage, this );
}

/*************************************************************************
|*
|*  SwFlyInCntFrm::MakeAll()
|*
|*  Ersterstellung      MA 18. Feb. 94
|*  Letzte Aenderung    MA 13. Jun. 96
|*
|*************************************************************************/
void SwFlyInCntFrm::MakeAll()
{
    // OD 2004-01-19 #110582#
    if ( !GetFmt()->GetDoc()->IsVisibleLayerId( GetVirtDrawObj()->GetLayer() ) )
    {
        return;
    }

    if ( !GetAnchor() || IsLocked() || IsColLocked() || !FindPageFrm() )
        return;

    Lock(); //Der Vorhang faellt

        //uebernimmt im DTor die Benachrichtigung
    const SwFlyNotify aNotify( this );
    SwBorderAttrAccess aAccess( SwFrm::GetCache(), this );
    const SwBorderAttrs &rAttrs = *aAccess.Get();
    const Size &rSz = rAttrs.GetSize();
    const SwFmtFrmSize &rFrmSz = GetFmt()->GetFrmSize();

    if ( IsClipped() )
        bValidSize = bHeightClipped = bWidthClipped = FALSE;

    while ( !bValidPos || !bValidSize || !bValidPrtArea )
    {
        //Nur einstellen wenn das Flag gesetzt ist!!
        if ( !bValidSize )
        {
            bValidPrtArea = FALSE;
            long nOldWidth = aFrm.Width();
            aFrm.Width( CalcRel( rFrmSz ).Width() );

            if ( aFrm.Width() > nOldWidth )
                //Damit sich der Inhalt anpasst
                aFrm.Height( CalcRel( rFrmSz ).Height() );
        }

        if ( !bValidPrtArea )
            MakePrtArea( rAttrs );

        if ( !bValidSize )
            Format( &rAttrs );

        if ( !bValidPos )
            MakeFlyPos();

        if ( bValidPos && bValidSize )
        {
            SwFrm *pFrm = GetAnchor();
            if (
//MA 03. Apr. 96 fix(26652), Das trifft uns bestimmt nocheinmal
//          !pFrm->IsMoveable() &&
                 Frm().Left() == (pFrm->Frm().Left()+pFrm->Prt().Left()) &&
                 Frm().Width() > pFrm->Prt().Width() )
            {
                Frm().Width( pFrm->Prt().Width() );
                bValidPrtArea = FALSE;
                bWidthClipped = TRUE;
            }
        }
    }
    Unlock();
}

<|endoftext|>


<commit_before>#include <functional>

#include "threading.h"

using namespace std;

namespace base {

struct start_thread_pool_args {
    ThreadPool* thrpool;
    int id_in_pool;
};

void* ThreadPool::start_thread_pool(void* args) {
    start_thread_pool_args* t_args = (start_thread_pool_args *) args;
    t_args->thrpool->run_thread(t_args->id_in_pool);
    delete t_args;
    pthread_exit(NULL);
    return NULL;
}

ThreadPool::ThreadPool(int n /* =... */): n_(n), should_stop_(false) {
    th_ = new pthread_t[n_];
    q_ = new Queue<function<void()>*> [n_];

    for (int i = 0; i < n_; i++) {
        start_thread_pool_args* args = new start_thread_pool_args();
        args->thrpool = this;
        args->id_in_pool = i;
        Pthread_create(&th_[i], NULL, ThreadPool::start_thread_pool, args);
    }
}

ThreadPool::~ThreadPool() {
    should_stop_ = true;
    for (int i = 0; i < n_; i++) {
        q_[i].push(nullptr);  // death pill
    }
    for (int i = 0; i < n_; i++) {
        Pthread_join(th_[i], nullptr);
    }
    // check if there's left over jobs
    for (int i = 0; i < n_; i++) {
        function<void()>* job;
        while (q_[i].try_pop(&job)) {
            if (job != nullptr) {
                (*job)();
            }
        }
    }
    delete[] th_;
    delete[] q_;
}

int ThreadPool::run_async(const std::function<void()>& f) {
    if (should_stop_) {
        return EPERM;
    }
    // Randomly select a thread for the job.
    int queue_id = rand_engine_() % n_;
    q_[queue_id].push(new function<void()>(f));
    return 0;
}

void ThreadPool::run_thread(int id_in_pool) {
    struct timespec sleep_req;
    const int min_sleep_nsec = 1000;  // 1us
    const int max_sleep_nsec = 10 * 1000 * 1000;  // 10ms
    sleep_req.tv_nsec = 200 * 1000;  // 200us
    sleep_req.tv_sec = 0;
    int stage = 0;

    // randomized stealing order
    int* steal_order = new int[n_];
    for (int i = 0; i < n_; i++) {
        steal_order[i] = i;
    }
    Rand r;
    for (int i = 0; i < n_ - 1; i++) {
        int j = r.next(i, n_);
        if (j != i) {
            int t = steal_order[j];
            steal_order[j] = steal_order[i];
            steal_order[i] = t;
        }
    }

    // fallback stages: try_pop -> sleep -> try_pop -> steal -> pop
    // succeed: sleep - 1
    // failure: sleep + 10
    for (;;) {
        function<void()>* job = nullptr;

        switch(stage) {
        case 0:
        case 2:
            if (q_[id_in_pool].try_pop(&job)) {
                stage = 0;
            } else {
                stage++;
            }
            break;
        case 1:
            nanosleep(&sleep_req, NULL);
            stage++;
            break;
        case 3:
            for (int i = 0; i < n_; i++) {
                if (steal_order[i] != id_in_pool) {
                    // just don't steal other thread's death pill, otherwise they won't die
                    if (q_[steal_order[i]].try_pop_but_ignore(&job, nullptr)) {
                        stage = 0;
                        break;
                    }
                }
            }
            if (stage != 0) {
                stage++;
            }
            break;
        case 4:
            job = q_[id_in_pool].pop();
            stage = 0;
            break;
        }

        if (stage == 0) {
            if (job == nullptr) {
                break;
            }
            (*job)();
            delete job;
            sleep_req.tv_nsec = clamp(sleep_req.tv_nsec - 1000, min_sleep_nsec, max_sleep_nsec);
        } else {
            sleep_req.tv_nsec = clamp(sleep_req.tv_nsec + 10 * 1000, min_sleep_nsec, max_sleep_nsec);
        }
    }
    delete[] steal_order;
}

} // namespace base
<commit_msg>change threadpool policy<commit_after>#include <functional>

#include "threading.h"

using namespace std;

namespace base {

struct start_thread_pool_args {
    ThreadPool* thrpool;
    int id_in_pool;
};

void* ThreadPool::start_thread_pool(void* args) {
    start_thread_pool_args* t_args = (start_thread_pool_args *) args;
    t_args->thrpool->run_thread(t_args->id_in_pool);
    delete t_args;
    pthread_exit(NULL);
    return NULL;
}

ThreadPool::ThreadPool(int n /* =... */): n_(n), should_stop_(false) {
    th_ = new pthread_t[n_];
    q_ = new Queue<function<void()>*> [n_];

    for (int i = 0; i < n_; i++) {
        start_thread_pool_args* args = new start_thread_pool_args();
        args->thrpool = this;
        args->id_in_pool = i;
        Pthread_create(&th_[i], NULL, ThreadPool::start_thread_pool, args);
    }
}

ThreadPool::~ThreadPool() {
    should_stop_ = true;
    for (int i = 0; i < n_; i++) {
        q_[i].push(nullptr);  // death pill
    }
    for (int i = 0; i < n_; i++) {
        Pthread_join(th_[i], nullptr);
    }
    // check if there's left over jobs
    for (int i = 0; i < n_; i++) {
        function<void()>* job;
        while (q_[i].try_pop(&job)) {
            if (job != nullptr) {
                (*job)();
            }
        }
    }
    delete[] th_;
    delete[] q_;
}

int ThreadPool::run_async(const std::function<void()>& f) {
    if (should_stop_) {
        return EPERM;
    }
    // Randomly select a thread for the job.
    int queue_id = rand_engine_() % n_;
    q_[queue_id].push(new function<void()>(f));
    return 0;
}

void ThreadPool::run_thread(int id_in_pool) {
    // randomized stealing order
    int* steal_order = new int[n_];
    for (int i = 0; i < n_; i++) {
        steal_order[i] = i;
    }
    Rand r;
    for (int i = 0; i < n_ - 1; i++) {
        int j = r.next(i, n_);
        if (j != i) {
            int t = steal_order[j];
            steal_order[j] = steal_order[i];
            steal_order[i] = t;
        }
    }

    for (;;) {
        // fallback stages: try_pop -> steal -> pop
        function<void()>* job = nullptr;
        bool got_job = q_[id_in_pool].try_pop(&job);
        if (!got_job) {
            for (int i = 0; i < n_; i++) {
                if (steal_order[i] != id_in_pool) {
                    // just don't steal other thread's death pill, otherwise they won't die
                    if (q_[steal_order[i]].try_pop_but_ignore(&job, nullptr)) {
                        got_job = true;
                        break;
                    }
                }
            }
        }
        if (!got_job) {
            job = q_[id_in_pool].pop();
        }
        if (job == nullptr) {
            break;
        }
        (*job)();
        delete job;
    }
    delete[] steal_order;
}

} // namespace base
<|endoftext|>


<commit_before>#include <iostream>
#include <fstream>

#include <sampleflow/producers/metropolis_hastings.h>
#include <sampleflow/filters/take_every_nth.h>
#include <sampleflow/consumers/mean_value.h>

double log_likelihood (const double &x)
{
  return -(x-1)*(x-1);
}

double perturb (const double &x)
{
  static std::mt19937 rng;
  static std::uniform_real_distribution<> uniform_distribution(-0.1,0.1);
  return x + uniform_distribution(rng);
}

int main ()
{
  SampleFlow::Producers::MetropolisHastings<double> mh_sampler;

  SampleFlow::Filters::TakeEveryNth<double> take_every_nth (1);
  take_every_nth.connect_to_producer (mh_sampler);

  SampleFlow::Consumers::MeanValue<double> mean_value;
  mean_value.connect_to_producer (take_every_nth);

  mh_sampler.sample (0,
                     &log_likelihood,
                     &perturb,
                     100000);

  std::cout << "Computed mean value: "
  << mean_value.get() << std::endl;
}
<commit_msg>Update testcase.<commit_after>#include <iostream>
#include <fstream>

#include <sampleflow/producers/metropolis_hastings.h>
#include <sampleflow/filters/take_every_nth.h>
#include <sampleflow/consumers/mean_value.h>
#include <sampleflow/consumers/histogram.h>

double log_likelihood (const double &x)
{
  return -(x-1)*(x-1);
}

double perturb (const double &x)
{
  static std::mt19937 rng;
  static std::uniform_real_distribution<> uniform_distribution(-0.1,0.1);
  return x + uniform_distribution(rng);
}

int main ()
{
  SampleFlow::Producers::MetropolisHastings<double> mh_sampler;

  SampleFlow::Filters::TakeEveryNth<double> take_every_nth (1);
  take_every_nth.connect_to_producer (mh_sampler);

  SampleFlow::Consumers::MeanValue<double> mean_value;
  mean_value.connect_to_producer (take_every_nth);

  SampleFlow::Consumers::Histogram<double> histogram (0.1, 5, 100,
      SampleFlow::Consumers::Histogram<double>::SubdivisionScheme::logarithmic);
  histogram.connect_to_producer (take_every_nth);

  mh_sampler.sample (0,
                     &log_likelihood,
                     &perturb,
                     1000000);

  std::cout << "Computed mean value: "
  << mean_value.get() << std::endl;

  histogram.write_gnuplot (std::ofstream("hist.txt"));
}
<|endoftext|>


<commit_before>using namespace std;
/**
 * Saving Histogram Data
 */
void ExportHistogram(TFile* f,const char* histKey,const char* outputfile){
  // Root Setup
  TH1F* h = (TH1F*) f->Get(histKey);

  // File Setup
  ofstream out;
  out.open(outputfile);
  out<<"Bin,Value,Error"<<endl;
  for (int i = 1; i < h->GetNbinsX()-1; i++){
    out<<h->GetBinCenter(i)<<","<<h->GetBinContent(i)<<","<<h->GetBinError(i)<<endl;
  }
  out.close();
}
/**
 * Runs the GS20 analysis
 *
 * @param fN neutron file pointer
 * @param fG gamma file pointer
 */
void RunGS20(TFile* fN,TFile* fG){

	TH1F* hN = (TH1F*) fN->Get("3");
  hN->Sumw2();
  hN->Scale(1.0/hN->GetIntegral());
	TH1F* hG = (TH1F*) fG->Get("3");
  hG->Sumw2();
  hG->Scale(1.0/hG->GetIntegral());
	TCanvas* c = new TCanvas();
  gStyle->SetOptStat(0);
	hN->Draw();
	hN->SetTitle("Optical Photons Detected");
	hN->GetXaxis()->SetTitle("Number of Photons");
  hN->SetLineColor(1);
	hG->Draw("same");
  hG->SetLineColor(2);
  c->Update();
  c->SaveAs("GS20SimulatedLightOverlap.eps");

  ExportHistogram(fN,"3","GS20NeutronOPDist.csv");
  ExportHistogram(fG,"3","GS20GammaOPDist.csv");

}
/**
 * Main
 *  root[#] .L Analysis.C
 *  root[#] main()
 */
int main(){

	TFile* fN = NULL;
	TFile* fG = NULL;

	/* Runnign the GS20 */
	fN = new TFile("GS20_Neutron.root","r");
  fG = new TFile("GS20_Gamma.root","r");
	if (fN && fG){
		RunGS20(fN,fG);
		fN->Close();
		fG->Close();
	}
}
<commit_msg>Switched to using produced histogram photons<commit_after>using namespace std;
/**
 * Saving Histogram Data
 */
void ExportHistogram(TFile* f,const char* histKey,const char* outputfile){
  // Root Setup
  TH1F* h = (TH1F*) f->Get(histKey);

  // File Setup
  ofstream out;
  out.open(outputfile);
  out<<"Bin,Value,Error"<<endl;
  for (int i = 1; i < h->GetNbinsX()-1; i++){
    out<<h->GetBinCenter(i)<<","<<h->GetBinContent(i)<<","<<h->GetBinError(i)<<endl;
  }
  out.close();
}
/**
 * Runs the GS20 analysis
 *
 * @param fN neutron file pointer
 * @param fG gamma file pointer
 */
void RunGS20(TFile* fN,TFile* fG){

	TH1F* hN = (TH1F*) fN->Get("2");
  hN->Sumw2();
  hN->Scale(1.0/hN->GetIntegral());
	TH1F* hG = (TH1F*) fG->Get("2");
  hG->Sumw2();
  hG->Scale(1.0/hG->GetIntegral());
	TCanvas* c = new TCanvas();
  gStyle->SetOptStat(0);
	hN->Draw();
	hN->SetTitle("Optical Photons Detected");
	hN->GetXaxis()->SetTitle("Number of Photons");
  hN->SetLineColor(1);
	hG->Draw("same");
  hG->SetLineColor(2);
  c->Update();
  c->SaveAs("GS20SimulatedLightOverlap.eps");

  ExportHistogram(fN,"2","GS20NeutronOPDist.csv");
  ExportHistogram(fG,"2","GS20GammaOPDist.csv");

}
/**
 * Main
 *  root[#] .L Analysis.C
 *  root[#] main()
 */
int main(){

	TFile* fN = NULL;
	TFile* fG = NULL;

	/* Runnign the GS20 */
	fN = new TFile("GS20_Neutron.root","r");
  fG = new TFile("GS20_Gamma.root","r");
	if (fN && fG){
		RunGS20(fN,fG);
		fN->Close();
		fG->Close();
	}
}
<|endoftext|>


<commit_before>// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// Declaration of ATL module object for EXE module.

#include <atlbase.h>
#include <atlhost.h>

#include "base/at_exit.h"
#include "base/command_line.h"
#include "base/debug/trace_event.h"
#include "base/logging.h"
#include "base/logging_win.h"
#include "ceee/ie/broker/broker.h"
#include "ceee/ie/broker/broker_rpc_server.h"
#include "ceee/ie/broker/chrome_postman.h"
#include "ceee/ie/broker/executors_manager.h"
#include "ceee/ie/broker/resource.h"
#include "ceee/ie/broker/window_events_funnel.h"
#include "ceee/ie/common/crash_reporter.h"
#include "ceee/common/com_utils.h"
#include "chrome/common/url_constants.h"
#include "chrome_frame/metrics_service.h"

namespace {

const wchar_t kLogFileName[] = L"CeeeBroker.log";

// {6E3D6168-1DD2-4edb-A183-584C2C66E96D}
const GUID kCeeeBrokerLogProviderName =
    { 0x6e3d6168, 0x1dd2, 0x4edb,
        { 0xa1, 0x83, 0x58, 0x4c, 0x2c, 0x66, 0xe9, 0x6d } };

}  // namespace

// Object entries go here instead of with each object, so that we can keep
// the objects in a lib, and also to decrease the amount of magic.
OBJECT_ENTRY_AUTO(__uuidof(CeeeBroker), CeeeBroker)

class CeeeBrokerModule : public CAtlExeModuleT<CeeeBrokerModule> {
 public:
  CeeeBrokerModule();
  ~CeeeBrokerModule();

  DECLARE_LIBID(LIBID_CeeeBrokerLib)
  static HRESULT WINAPI UpdateRegistryAppId(BOOL register) throw();

  // We have our own version so that we can explicitly specify
  // that we want to be in a multi threaded apartment.
  static HRESULT InitializeCom();

  // Prevent COM objects we don't own to control our lock count.
  // To properly manage our lifespan, yet still be able to control the
  // lifespan of the ChromePostman's thread, we must only rely on the
  // CeeeBroker implementation of the IExternalConnection interface
  // as well as the ExecutorsManager map content to decide when to die.
  virtual LONG Lock() {
    return 1;
  }
  virtual LONG Unlock() {
    return 1;
  }

  // We prevent access to the module lock count from objects we don't
  // own by overriding the Un/Lock methods above. But when we want to
  // access the module lock count, we do it from here, and bypass our
  // override. These are the entry points that only our code accesses.
  LONG LockModule() {
    return CAtlExeModuleT<CeeeBrokerModule>::Lock();
  }
  LONG UnlockModule() {
    return CAtlExeModuleT<CeeeBrokerModule>::Unlock();
  }

  HRESULT PostMessageLoop();
  HRESULT PreMessageLoop(int show);
 private:
  // We maintain a postman COM object on the stack so that we can
  // properly initialize and terminate it at the right time.
  CComObjectStackEx<ChromePostman> chrome_postman_;
  CrashReporter crash_reporter_;
  base::AtExitManager at_exit_;
  BrokerRpcServer rpc_server_;
};

CeeeBrokerModule module;

extern "C" int WINAPI _tWinMain(HINSTANCE, HINSTANCE, LPTSTR, int nShowCmd) {
  return module.WinMain(nShowCmd);
}

CeeeBrokerModule::CeeeBrokerModule()
    : crash_reporter_(L"ceee_broker") {
  TRACE_EVENT_BEGIN("ceee.broker", this, "");

  wchar_t logfile_path[MAX_PATH];
  DWORD len = ::GetTempPath(arraysize(logfile_path), logfile_path);
  ::PathAppend(logfile_path, kLogFileName);

  // It seems we're obliged to initialize the current command line
  // before initializing logging.
  CommandLine::Init(0, NULL);

  logging::InitLogging(
      logfile_path,
      logging::LOG_TO_BOTH_FILE_AND_SYSTEM_DEBUG_LOG,
      logging::LOCK_LOG_FILE,
      logging::APPEND_TO_OLD_LOG_FILE);

  // Initialize ETW logging.
  logging::LogEventProvider::Initialize(kCeeeBrokerLogProviderName);

  // Initialize control hosting.
  BOOL initialized = AtlAxWinInit();
  DCHECK(initialized);

  // Needs to be called before we can use GURL.
  chrome::RegisterChromeSchemes();

  crash_reporter_.InitializeCrashReporting(false);
}

HRESULT CeeeBrokerModule::InitializeCom() {
  HRESULT hr = ::CoInitializeEx(NULL, COINIT_MULTITHREADED);
  if (FAILED(hr))
    return hr;

  // We need to initialize security before setting global options.
  hr = ::CoInitializeSecurity(NULL,
                              -1,
                              NULL,
                              NULL,
                              // Clients must identify.
                              RPC_C_IMP_LEVEL_IDENTIFY,
                              // And we identify.
                              RPC_C_IMP_LEVEL_IDENTIFY,
                              NULL,
                              // We don't want low integrity to be able to
                              // instantiate arbitrary objects in our process.
                              EOAC_NO_CUSTOM_MARSHAL,
                              NULL);
  DCHECK(SUCCEEDED(hr));

  // Ensure the marshaling machinery doesn't eat our crashes.
  CComPtr<IGlobalOptions> options;
  hr = options.CoCreateInstance(CLSID_GlobalOptions);
  if (SUCCEEDED(hr)) {
    hr = options->Set(COMGLB_EXCEPTION_HANDLING, COMGLB_EXCEPTION_DONOT_HANDLE);
  }
  DLOG_IF(WARNING, FAILED(hr)) << "IGlobalOptions::Set failed "
                               << com::LogHr(hr);

  // The above is best-effort, don't bail on error.
  return S_OK;
}

HRESULT CeeeBrokerModule::PreMessageLoop(int show) {
  // It's important to initialize the postman BEFORE we make the Broker
  // and the event funnel available, since we may get requests to execute
  // API invocation or Fire events before the postman is ready to handle them.
  chrome_postman_.Init();
  WindowEventsFunnel::Initialize();

  if (!rpc_server_.Start())
    return RPC_E_FAULT;

  // Initialize metrics. We need the rpc_server_ above to be available.
  MetricsService::Start();

  return CAtlExeModuleT<CeeeBrokerModule>::PreMessageLoop(show);
}

HRESULT CeeeBrokerModule::PostMessageLoop() {
  HRESULT hr = CAtlExeModuleT<CeeeBrokerModule>::PostMessageLoop();
  Singleton<ExecutorsManager,
            ExecutorsManager::SingletonTraits>()->Terminate();
  WindowEventsFunnel::Terminate();

  // Upload data if necessary.
  MetricsService::Stop();

  chrome_postman_.Term();
  return hr;
}

CeeeBrokerModule::~CeeeBrokerModule() {
  crash_reporter_.ShutdownCrashReporting();
  logging::CloseLogFile();

  TRACE_EVENT_END("ceee.broker", this, "");
}

HRESULT WINAPI CeeeBrokerModule::UpdateRegistryAppId(BOOL reg) throw() {
  return com::ModuleRegistrationWithoutAppid(IDR_BROKER_MODULE, reg);
}

namespace ceee_module_util {

LONG LockModule() {
  return module.LockModule();
}

LONG UnlockModule() {
  return module.UnlockModule();
}

}  // namespace
<commit_msg>Committing patch http://codereview.chromium.org/5288001/ from vitalybuka@google.com.<commit_after>// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// Declaration of ATL module object for EXE module.

#include <atlbase.h>
#include <atlhost.h>

#include "base/at_exit.h"
#include "base/command_line.h"
#include "base/debug/trace_event.h"
#include "base/logging.h"
#include "base/logging_win.h"
#include "ceee/ie/broker/broker.h"
#include "ceee/ie/broker/broker_rpc_server.h"
#include "ceee/ie/broker/chrome_postman.h"
#include "ceee/ie/broker/executors_manager.h"
#include "ceee/ie/broker/resource.h"
#include "ceee/ie/broker/window_events_funnel.h"
#include "ceee/ie/common/crash_reporter.h"
#include "ceee/common/com_utils.h"
#include "chrome/common/url_constants.h"
#include "chrome_frame/metrics_service.h"

namespace {

const wchar_t kLogFileName[] = L"CeeeBroker.log";

// {6E3D6168-1DD2-4edb-A183-584C2C66E96D}
const GUID kCeeeBrokerLogProviderName =
    { 0x6e3d6168, 0x1dd2, 0x4edb,
        { 0xa1, 0x83, 0x58, 0x4c, 0x2c, 0x66, 0xe9, 0x6d } };

}  // namespace

// Object entries go here instead of with each object, so that we can keep
// the objects in a lib, and also to decrease the amount of magic.
OBJECT_ENTRY_AUTO(__uuidof(CeeeBroker), CeeeBroker)

class CeeeBrokerModule : public CAtlExeModuleT<CeeeBrokerModule> {
 public:
  CeeeBrokerModule();
  ~CeeeBrokerModule();

  DECLARE_LIBID(LIBID_CeeeBrokerLib)
  static HRESULT WINAPI UpdateRegistryAppId(BOOL register) throw();

  // We have our own version so that we can explicitly specify
  // that we want to be in a multi threaded apartment.
  static HRESULT InitializeCom();

  // Prevent COM objects we don't own to control our lock count.
  // To properly manage our lifespan, yet still be able to control the
  // lifespan of the ChromePostman's thread, we must only rely on the
  // CeeeBroker implementation of the IExternalConnection interface
  // as well as the ExecutorsManager map content to decide when to die.
  virtual LONG Lock() {
    return 1;
  }
  virtual LONG Unlock() {
    return 1;
  }

  // We prevent access to the module lock count from objects we don't
  // own by overriding the Un/Lock methods above. But when we want to
  // access the module lock count, we do it from here, and bypass our
  // override. These are the entry points that only our code accesses.
  LONG LockModule() {
    return CAtlExeModuleT<CeeeBrokerModule>::Lock();
  }
  LONG UnlockModule() {
    return CAtlExeModuleT<CeeeBrokerModule>::Unlock();
  }

  HRESULT PostMessageLoop();
  HRESULT PreMessageLoop(int show);
 private:
  void TearDown();

  // We maintain a postman COM object on the stack so that we can
  // properly initialize and terminate it at the right time.
  CComObjectStackEx<ChromePostman> chrome_postman_;
  CrashReporter crash_reporter_;
  base::AtExitManager at_exit_;
  BrokerRpcServer rpc_server_;
};

CeeeBrokerModule module;

extern "C" int WINAPI _tWinMain(HINSTANCE, HINSTANCE, LPTSTR, int nShowCmd) {
  return module.WinMain(nShowCmd);
}

CeeeBrokerModule::CeeeBrokerModule()
    : crash_reporter_(L"ceee_broker") {
  TRACE_EVENT_BEGIN("ceee.broker", this, "");

  wchar_t logfile_path[MAX_PATH];
  DWORD len = ::GetTempPath(arraysize(logfile_path), logfile_path);
  ::PathAppend(logfile_path, kLogFileName);

  // It seems we're obliged to initialize the current command line
  // before initializing logging.
  CommandLine::Init(0, NULL);

  logging::InitLogging(
      logfile_path,
      logging::LOG_TO_BOTH_FILE_AND_SYSTEM_DEBUG_LOG,
      logging::LOCK_LOG_FILE,
      logging::APPEND_TO_OLD_LOG_FILE);

  // Initialize ETW logging.
  logging::LogEventProvider::Initialize(kCeeeBrokerLogProviderName);

  // Initialize control hosting.
  BOOL initialized = AtlAxWinInit();
  DCHECK(initialized);

  // Needs to be called before we can use GURL.
  chrome::RegisterChromeSchemes();

  crash_reporter_.InitializeCrashReporting(false);
}

HRESULT CeeeBrokerModule::InitializeCom() {
  HRESULT hr = ::CoInitializeEx(NULL, COINIT_MULTITHREADED);
  if (FAILED(hr))
    return hr;

  // We need to initialize security before setting global options.
  hr = ::CoInitializeSecurity(NULL,
                              -1,
                              NULL,
                              NULL,
                              // Clients must identify.
                              RPC_C_IMP_LEVEL_IDENTIFY,
                              // And we identify.
                              RPC_C_IMP_LEVEL_IDENTIFY,
                              NULL,
                              // We don't want low integrity to be able to
                              // instantiate arbitrary objects in our process.
                              EOAC_NO_CUSTOM_MARSHAL,
                              NULL);
  DCHECK(SUCCEEDED(hr));

  // Ensure the marshaling machinery doesn't eat our crashes.
  CComPtr<IGlobalOptions> options;
  hr = options.CoCreateInstance(CLSID_GlobalOptions);
  if (SUCCEEDED(hr)) {
    hr = options->Set(COMGLB_EXCEPTION_HANDLING, COMGLB_EXCEPTION_DONOT_HANDLE);
  }
  DLOG_IF(WARNING, FAILED(hr)) << "IGlobalOptions::Set failed "
                               << com::LogHr(hr);

  // The above is best-effort, don't bail on error.
  return S_OK;
}

HRESULT CeeeBrokerModule::PreMessageLoop(int show) {
  // It's important to initialize the postman BEFORE we make the Broker
  // and the event funnel available, since we may get requests to execute
  // API invocation or Fire events before the postman is ready to handle them.
  chrome_postman_.Init();
  WindowEventsFunnel::Initialize();

  // Another instance of broker may be shutting down right now. Do several
  // attempts in hope the process exits and releases endpoint.
  for (int i = 0; i < 10 && !rpc_server_.Start(); ++i)
    Sleep(500);

  // Initialize metrics. We need the rpc_server_ above to be available.
  MetricsService::Start();

  HRESULT hr = rpc_server_.is_started() ? S_OK : RPC_E_FAULT;
  if (SUCCEEDED(hr))
    hr = CAtlExeModuleT<CeeeBrokerModule>::PreMessageLoop(show);
  if (FAILED(hr))
    TearDown();
  return hr;
}

HRESULT CeeeBrokerModule::PostMessageLoop() {
  HRESULT hr = CAtlExeModuleT<CeeeBrokerModule>::PostMessageLoop();
  TearDown();
  return hr;
}

void CeeeBrokerModule::TearDown() {
  rpc_server_.Stop();
  Singleton<ExecutorsManager,
            ExecutorsManager::SingletonTraits>()->Terminate();
  WindowEventsFunnel::Terminate();

  // Upload data if necessary.
  MetricsService::Stop();

  chrome_postman_.Term();
}

CeeeBrokerModule::~CeeeBrokerModule() {
  crash_reporter_.ShutdownCrashReporting();
  logging::CloseLogFile();
  TRACE_EVENT_END("ceee.broker", this, "");
}

HRESULT WINAPI CeeeBrokerModule::UpdateRegistryAppId(BOOL reg) throw() {
  return com::ModuleRegistrationWithoutAppid(IDR_BROKER_MODULE, reg);
}

namespace ceee_module_util {

LONG LockModule() {
  return module.LockModule();
}

LONG UnlockModule() {
  return module.UnlockModule();
}

}  // namespace
<|endoftext|>


<commit_before>#include <numeric>
#include <cstdlib>
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <set>
#include <csignal>
#include <cmath>
#include <ctgmath>

#include "sdd/sdd.hh"
#include "sdd/tools/size.hh"
#include "sdd/tools/nodes.hh"
#include "sdd/tools/arcs.hh"
#include "sdd/tools/sequences.hh"
#include "sdd/tools/dot/sdd.hh"

using namespace std;

static bool finish = false;

void
handler(int s)
{
  finish = true;
}

struct conf
  : public sdd::flat_set_default_configuration
{
  using Identifier = unsigned int;
  using Values     = sdd::values::flat_set<char>;
};
using SDD         = sdd::SDD<conf>;
using values_type = conf::Values;

int
main (int argc, const char** argv)
{
  const auto subsize = 100;
  if (argc == 0)
  {
    cerr << "sdd-stream <min-length> <max-length>" << endl;
    return 1;
  }

  struct sigaction sigIntHandler;
  sigIntHandler.sa_handler = handler;
  sigemptyset (&sigIntHandler.sa_mask);
  sigIntHandler.sa_flags = 0;
  sigaction (SIGINT, &sigIntHandler, NULL);

  size_t min_length = stoi (argv [1]);
  size_t max_length = stoi (argv [2]);

  vector<SDD> collections;
  collections.reserve (subsize);

  conf c;
  c.final_cleanup = false; // don't cleanup memory on manager scope exit.
  c.hom_cache_size = 2; // we don't use homomorphisms.
  c.hom_unique_table_size = 2; // we don't use homomorphisms.
//  c.sdd_intersection_cache_size = 16000000;
//  c.sdd_sum_cache_size = 16000000;
//  c.sdd_difference_cache_size = 16000000;
//  c.sdd_unique_table_size = 10000000;
  auto manager = sdd::init<conf>(c);

  // // Construct the SDD order: we need one level per letter.
  // vector<unsigned int> v (max_length);
  // iota (v.begin(), v.end(), 0);
  sdd::order_builder<conf> ob;
  const sdd::order<conf> order {sdd::order_builder<conf> ()};

  set<char> characters;

  size_t inserted = 0;
  size_t dropped  = 0;
  size_t total    = 0;
  size_t sum_inserted = 0;
  string line;
  line.reserve (80);
  string sequence;
  sequence.reserve (max_length);
  cout << "\033[s" << flush;
  while (getline (cin, line))
  {
    if (line [0] == '>')
    { // starting a new sequence:
      total += 1;
      if (sequence.size () != 0)
      {
        if ((sequence.size() >= min_length) && (sequence.size () <= max_length))
        {
          // cout << endl << sequence << endl;
          SDD word = SDD(0, SDD::eol::flat, sdd::one<conf>());
          for (auto i = 0u; i < sequence.size(); ++i)
          {
            characters.insert (sequence[sequence.size() - i - 1]);
            word = SDD(0, {sequence[sequence.size() - i - 1]}, word);
          }
          collections.emplace_back(word);
          inserted += 1;
          sum_inserted += sequence.size();
        }
        else
          dropped += 1;
        sequence.clear ();
      }
      if (finish)
        break;
    }
    else
      sequence += line;
    if (collections.size () == subsize)
    {
      const auto result = sdd::sum<conf> ( collections.cbegin()
                                         , collections.cend() );
      collections.clear ();
      collections.push_back (result);
    }
    if (total % 200 == 0)
      cout << "\033[u"
           << "inserted: " << inserted
           << " / "
           << "dropped: " << dropped
           << " / "
           << "total: " << total
           << flush;
  }
  if ((sequence.size() >= min_length) && (sequence.size () <= max_length))
  {
    SDD word = SDD(0, SDD::eol::flat, sdd::one<conf>());
    for (auto i = 0u; i < sequence.size(); ++i)
    {
      characters.insert (sequence[sequence.size() - i - 1]);
      word = SDD(0, {sequence[sequence.size() - i - 1]}, word);
    }
    collections.emplace_back(word);
    inserted += 1;
    sum_inserted += sequence.size();
  }
  else
    dropped += 1;
  cout << "\033[u"
       << "inserted: " << inserted
       << " / "
       << "dropped: " << dropped
       << " / "
       << "total: " << total
       << endl;
  const auto result = sdd::sum<conf> ( collections.cbegin()
                                     , collections.cend() );

  cout << "# Words: " << result.size() << endl;
  const auto nodes = sdd::tools::nodes(result).first;
  cout << "# Nodes: " << nodes << endl;
  const auto size = sdd::tools::size(result);
  cout << "Size: " << ceil(static_cast<float>(size) / 1024 / 1024) << " Mbytes" << endl;

  auto frequency = sdd::tools::arcs<conf>(result);
  auto sequences = sdd::tools::sequences<conf>(result);

  size_t max_children = 0;
  for (auto& p : frequency)
  {
    max_children = max_children < p.first
                 ? p.first
                 : max_children;
  }
  size_t expected = 0;
  size_t bitfield_size = ceil(static_cast<float>(characters.size())/8);
  size_t base_size = bitfield_size + 4 + 8 + 1;
  cout << "Bit field size: " << bitfield_size << " bytes" << endl;
  cout << "Base node size: " << base_size << " bytes" << endl;
  const size_t average_length = 100;
  const size_t bitsize = ceil(log2(characters.size()));
  cout << "Bitsize: " << bitsize << endl;
  for (size_t i = 0; i <= max_children; ++i)
  {
    if (frequency[i].first == 0)
      continue;
    cout << left << setw(3) << i
         << " => "
         << left << setw(10) << frequency[i].first
         << right
         << endl;
    size_t subresult = 0;
    size_t subsize   = 0;
    if (i == 1)
    {
      size_t subcount = 0;
      for (const auto& p : sequences)
      {
        size_t size = base_size + 8 + ceil(static_cast<float>(bitsize)* p.first / 8);
        size += size % 8 == 0
              ? 0
              : 8 - (size % 8);

        size *= p.second;
        subresult += size;
        subsize   += p.second;
        subcount  += p.second * p.first;
      }
      subresult += (base_size + 8 + ceil(static_cast<float>(bitsize) / 8)) * (frequency[1].first - subcount);
      size_t average = 150;
      size_t should_size =
        (base_size + 8 + ceil(static_cast<float>(bitsize)*average / 8))
        * frequency[i].first / average;
    }
    else
    {
      size_t size = base_size + i * 8;
      size += size % 8 == 0
            ? 0
            : 8 - (size % 8);
      subresult = size * frequency[i].first;
      subsize   = frequency[i].first;
    }
    expected += subresult;
  }
  cout << "Expected size: " << ceil(static_cast<float>(expected) / 1024 / 1024) << " Mbytes" << endl;
  cout << "Original size: " << ceil(static_cast<float>(sum_inserted) / 1024 / 1024)
       << " Mbytes"
       << endl
       << "Binary size: " << (sum_inserted * bitsize / 8 / 1024 / 1024 + 1)
       << " Mbytes"
       << endl;

  if (nodes <= 5000)
  {
    ofstream of ("machin.dot");
    of << sdd::tools::dot (result, order);
  }

  return 0;
}
<commit_msg>Add more output.<commit_after>#include <numeric>
#include <cstdlib>
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <set>
#include <csignal>
#include <cmath>
#include <ctgmath>

#include "sdd/sdd.hh"
#include "sdd/tools/size.hh"
#include "sdd/tools/nodes.hh"
#include "sdd/tools/arcs.hh"
#include "sdd/tools/sequences.hh"
#include "sdd/tools/dot/sdd.hh"

using namespace std;

static bool finish = false;

void
handler(int s)
{
  finish = true;
}

struct conf
  : public sdd::flat_set_default_configuration
{
  using Identifier = unsigned int;
  using Values     = sdd::values::flat_set<char>;
};
using SDD         = sdd::SDD<conf>;
using values_type = conf::Values;

int
main (int argc, const char** argv)
{
  const auto subsize = 100;
  if (argc == 0)
  {
    cerr << "sdd-stream <min-length> <max-length>" << endl;
    return 1;
  }

  struct sigaction sigIntHandler;
  sigIntHandler.sa_handler = handler;
  sigemptyset (&sigIntHandler.sa_mask);
  sigIntHandler.sa_flags = 0;
  sigaction (SIGINT, &sigIntHandler, NULL);

  size_t min_length = stoi (argv [1]);
  size_t max_length = stoi (argv [2]);

  vector<SDD> collections;
  collections.reserve (subsize);

  conf c;
  c.final_cleanup = false; // don't cleanup memory on manager scope exit.
  c.hom_cache_size = 2; // we don't use homomorphisms.
  c.hom_unique_table_size = 2; // we don't use homomorphisms.
//  c.sdd_intersection_cache_size = 16000000;
//  c.sdd_sum_cache_size = 16000000;
//  c.sdd_difference_cache_size = 16000000;
//  c.sdd_unique_table_size = 10000000;
  auto manager = sdd::init<conf>(c);

  // // Construct the SDD order: we need one level per letter.
  // vector<unsigned int> v (max_length);
  // iota (v.begin(), v.end(), 0);
  sdd::order_builder<conf> ob;
  const sdd::order<conf> order {sdd::order_builder<conf> ()};

  set<char> characters;

  size_t inserted = 0;
  size_t dropped  = 0;
  size_t total    = 0;
  size_t sum_inserted = 0;
  string line;
  line.reserve (80);
  string sequence;
  sequence.reserve (max_length);
  cout << "\033[s" << flush;
  while (getline (cin, line))
  {
    if (line [0] == '>')
    { // starting a new sequence:
      total += 1;
      if (sequence.size () != 0)
      {
        if ((sequence.size() >= min_length) && (sequence.size () <= max_length))
        {
          // cout << endl << sequence << endl;
          SDD word = SDD(0, SDD::eol::flat, sdd::one<conf>());
          for (auto i = 0u; i < sequence.size(); ++i)
          {
            characters.insert (sequence[sequence.size() - i - 1]);
            word = SDD(0, {sequence[sequence.size() - i - 1]}, word);
          }
          collections.emplace_back(word);
          inserted += 1;
          sum_inserted += sequence.size();
        }
        else
          dropped += 1;
        sequence.clear ();
      }
      if (finish)
        break;
    }
    else
      sequence += line;
    if (collections.size () == subsize)
    {
      const auto result = sdd::sum<conf> ( collections.cbegin()
                                         , collections.cend() );
      collections.clear ();
      collections.push_back (result);
    }
    if (total % 200 == 0)
      cout << "\033[u"
           << "inserted: " << inserted
           << " / "
           << "dropped: " << dropped
           << " / "
           << "total: " << total
           << flush;
  }
  if ((sequence.size() >= min_length) && (sequence.size () <= max_length))
  {
    SDD word = SDD(0, SDD::eol::flat, sdd::one<conf>());
    for (auto i = 0u; i < sequence.size(); ++i)
    {
      characters.insert (sequence[sequence.size() - i - 1]);
      word = SDD(0, {sequence[sequence.size() - i - 1]}, word);
    }
    collections.emplace_back(word);
    inserted += 1;
    sum_inserted += sequence.size();
  }
  else
    dropped += 1;
  cout << "\033[u"
       << "inserted: " << inserted
       << " / "
       << "dropped: " << dropped
       << " / "
       << "total: " << total
       << endl;
  const auto result = sdd::sum<conf> ( collections.cbegin()
                                     , collections.cend() );

  cout << "# Words: " << result.size() << endl;
  const auto nodes = sdd::tools::nodes(result).first;
  cout << "# Nodes: " << nodes << endl;
  const auto size = sdd::tools::size(result);
  cout << "Size: " << ceil(static_cast<float>(size) / 1024 / 1024) << " Mbytes" << endl;

  auto frequency = sdd::tools::arcs<conf>(result);
  auto sequences = sdd::tools::sequences<conf>(result);

  cout << "Node width frequency:" << endl;
  for (auto& p : frequency)
  {
    cout << "  "
         << left << setw(3) << p.first
         << " => "
         << left << setw(10) << p.second.first
         << right
         << endl;
  }

  cout << "Sequence size frequency:" << endl;
  for (auto& p : sequences)
  {
    cout << "  "
         << left << setw(3) << p.first
         << " => "
         << left << setw(10) << p.second
         << right
         << endl;
  }

  size_t max_children = 0;
  for (auto& p : frequency)
  {
    max_children = max_children < p.first
                 ? p.first
                 : max_children;
  }
  size_t expected = 0;
  size_t bitfield_size = ceil(static_cast<float>(characters.size())/8);
  size_t base_size = bitfield_size + 4 + 8 + 1;
  cout << "Bit field size: " << bitfield_size << " bytes" << endl;
  cout << "Base node size: " << base_size << " bytes" << endl;
  const size_t average_length = 100;
  const size_t bitsize = ceil(log2(characters.size()));
  cout << "Bitsize: " << bitsize << endl;
  for (size_t i = 0; i <= max_children; ++i)
  {
    if (frequency[i].first == 0)
      continue;
    size_t subresult = 0;
    size_t subsize   = 0;
    if (i == 1)
    {
      size_t subcount = 0;
      for (const auto& p : sequences)
      {
        size_t size = base_size + 8 + ceil(static_cast<float>(bitsize)* p.first / 8);
        size += size % 8 == 0
              ? 0
              : 8 - (size % 8);

        size *= p.second;
        subresult += size;
        subsize   += p.second;
        subcount  += p.second * p.first;
      }
      subresult += (base_size + 8 + ceil(static_cast<float>(bitsize) / 8)) * (frequency[1].first - subcount);
      size_t average = 150;
      size_t should_size =
        (base_size + 8 + ceil(static_cast<float>(bitsize)*average / 8))
        * frequency[i].first / average;
    }
    else
    {
      size_t size = base_size + i * 8;
      size += size % 8 == 0
            ? 0
            : 8 - (size % 8);
      subresult = size * frequency[i].first;
      subsize   = frequency[i].first;
    }
    expected += subresult;
  }
  cout << "Expected size: " << ceil(static_cast<float>(expected) / 1024 / 1024) << " Mbytes" << endl;
  cout << "Original size: " << ceil(static_cast<float>(sum_inserted) / 1024 / 1024)
       << " Mbytes"
       << endl
       << "Binary size: " << (sum_inserted * bitsize / 8 / 1024 / 1024 + 1)
       << " Mbytes"
       << endl;

  if (nodes <= 5000)
  {
    ofstream of ("machin.dot");
    of << sdd::tools::dot (result, order);
  }

  return 0;
}
<|endoftext|>