<commit_before>#include "VoiceStickUI.h"

VoiceStickUI::VoiceStickUI(QWidget *parent,
                           const QString& phonemA, const QString& phonemB, const QString& phonemC, const QString& phonemD)
    : QMainWindow(parent)
{
    //Init widgets
    m_menuBar = new QMenuBar(this);
        m_fileMenu = new QMenu("File", this);
            m_openAction                = new QAction("Open...", this);
            m_saveAction                = new QAction("Save", this);
            m_saveAsAction              = new QAction("Save As...", this);
            m_exitAction                = new QAction("Exit", this);
        m_editMenu= new QMenu("Edit", this);
            m_undoAction                = new QAction("Undo...", this);
            m_redoAction                = new QAction("Redo...", this);
            m_undoAllAction             = new QAction("Undo All...", this);
        m_profileMenu= new QMenu("Profile", this);
            m_newProfileAction          = new QAction("New Profile...", this);
            m_deleteProfileAction       = new QAction("Delete Profile...", this);
            m_deleteAllProfilesAction   = new QAction("Delete All Profiles...", this);
        m_helpMenu= new QMenu("Help", this);
            m_userManualAction          = new QAction("User Manual...", this);
            m_aboutVoiceStickAction     = new QAction("About VoiceStick...", this);
            m_aboutQtAction             = new QAction("About Qt...", this);

    m_mainWidget = new QWidget(this);
        m_profileGroupBox = new QGroupBox("Profile",this);
            m_profileComboBox = new QComboBox(this);
            m_newProfileButton = new QPushButton("New...",this);
            m_deleteProfileButton = new QPushButton("Delete...",this);
        m_phonemsGroupBox = new QGroupBox("Phonems",this);
            m_phonemsLabelA = new QLabel(phonemA,this);
            m_phonemsLabelB = new QLabel(phonemB,this);
            m_phonemsLabelC = new QLabel(phonemC,this);
            m_phonemsLabelD = new QLabel(phonemD,this);
            m_phonemsAKeyEdit = new QKeySequenceEdit(this);
            m_phonemsBKeyEdit = new QKeySequenceEdit(this);
            m_phonemsCKeyEdit = new QKeySequenceEdit(this);
            m_phonemsDKeyEdit = new QKeySequenceEdit(this);
        m_testPushButton = new QPushButton("Test",this);
        m_runPushButton = new QPushButton("Run",this);
    m_statusBar = new QStatusBar(this);

    //Init layouts
    m_mainVBoxLayout = new QVBoxLayout(m_mainWidget);
        m_profileHBoxLayout = new QHBoxLayout(m_profileGroupBox);
        m_phonemsFormLayout = new QFormLayout(m_phonemsGroupBox);

    //Arrange actions and menus in menu bar
    m_menuBar->addMenu(m_fileMenu);
        m_fileMenu->addAction(m_openAction);
        m_fileMenu->addSeparator();
        m_fileMenu->addAction(m_saveAction);
        m_fileMenu->addAction(m_saveAsAction);
        m_fileMenu->addSeparator();
        m_fileMenu->addAction(m_exitAction);
    m_menuBar->addMenu(m_editMenu);
        m_editMenu->addAction(m_undoAction);
        m_editMenu->addAction(m_redoAction);
        m_editMenu->addSeparator();
        m_editMenu->addAction(m_undoAllAction);
    m_menuBar->addMenu(m_profileMenu);
        m_profileMenu->addAction(m_newProfileAction);
        m_profileMenu->addSeparator();
        m_profileMenu->addAction(m_deleteProfileAction);
        m_profileMenu->addAction(m_deleteAllProfilesAction);
    m_menuBar->addMenu(m_helpMenu);
        m_helpMenu->addAction(m_userManualAction);
        m_helpMenu->addSeparator();
        m_helpMenu->addAction(m_aboutVoiceStickAction);
        m_helpMenu->addAction(m_aboutQtAction);

    //Arrange widgets in their layouts
    m_mainVBoxLayout->addWidget(m_profileGroupBox);
    m_mainVBoxLayout->addWidget(m_phonemsGroupBox);
    m_mainVBoxLayout->addWidget(m_testPushButton);
    m_mainVBoxLayout->addWidget(m_runPushButton);

    m_profileHBoxLayout->addWidget(m_profileComboBox);
    m_profileHBoxLayout->addWidget(m_newProfileButton);
    m_profileHBoxLayout->addWidget(m_deleteProfileButton);

    m_phonemsFormLayout->addRow(m_phonemsLabelA, m_phonemsAKeyEdit);
    m_phonemsFormLayout->addRow(m_phonemsLabelB, m_phonemsBKeyEdit);
    m_phonemsFormLayout->addRow(m_phonemsLabelC, m_phonemsCKeyEdit);
    m_phonemsFormLayout->addRow(m_phonemsLabelD, m_phonemsDKeyEdit);

    //Arrange main window
    setMenuBar(m_menuBar);
    setCentralWidget(m_mainWidget);
    setStatusBar(m_statusBar);

    //Connect menu actions to slots
    connect(m_openAction, SIGNAL(triggered()), this, SLOT(open()));
    connect(m_saveAction, SIGNAL(triggered()), this, SLOT(save()));
    connect(m_saveAsAction, SIGNAL(triggered()), this, SLOT(saveAs()));
    connect(m_undoAction, SIGNAL(triggered()), this, SLOT(undo()));
    connect(m_redoAction, SIGNAL(triggered()), this, SLOT(redo()));
    connect(m_undoAllAction, SIGNAL(triggered()), this, SLOT(undoAll()));
    connect(m_newProfileAction, SIGNAL(triggered()), this, SLOT(newProfile()));
    connect(m_deleteProfileAction, SIGNAL(triggered()), this, SLOT(deleteProfile()));
    connect(m_deleteAllProfilesAction, SIGNAL(triggered()), this, SLOT(deleteAllProfiles()));
    connect(m_userManualAction, SIGNAL(triggered()), this, SLOT(userManual()));
    connect(m_aboutVoiceStickAction, SIGNAL(triggered()), this, SLOT(aboutVoiceStick()));
    connect(m_aboutQtAction, SIGNAL(triggered()), this, SLOT(aboutQt()));

    //Connect buttons to slots
    connect(m_newProfileButton, SIGNAL(clicked()), this, SLOT(newProfile()));
    connect(m_deleteProfileButton, SIGNAL(clicked()), this, SLOT(deleteProfile()));
    connect(m_testPushButton, SIGNAL(clicked()), this, SLOT(test()));
    connect(m_runPushButton, SIGNAL(clicked()), this, SLOT(run()));
}

VoiceStickUI::~VoiceStickUI()
{
    //QMainWindow will take care of deleting all of its children
}

int VoiceStickUI::currentProfile()
{
    return m_profileComboBox->currentIndex();
}

void VoiceStickUI::comingSoonInfoPopup()
{
    QMessageBox::information(this, "Coming soon", "The action that you are trying to do is not currently implemented.");
}

void VoiceStickUI::open()
{
    comingSoonInfoPopup();
}

void VoiceStickUI::save()
{
    comingSoonInfoPopup();
}

void VoiceStickUI::saveAs()
{
    comingSoonInfoPopup();
}

void VoiceStickUI::exit()
{
    comingSoonInfoPopup();
}

void VoiceStickUI::undo()
{
    comingSoonInfoPopup();
}

void VoiceStickUI::redo()
{
    comingSoonInfoPopup();
}

void VoiceStickUI::undoAll()
{
    comingSoonInfoPopup();
}

void VoiceStickUI::newProfile()
{
    comingSoonInfoPopup();
}

void VoiceStickUI::deleteProfile()
{
    comingSoonInfoPopup();
}

void VoiceStickUI::deleteAllProfiles()
{
    comingSoonInfoPopup();
}

void VoiceStickUI::userManual()
{
    comingSoonInfoPopup();
}

void VoiceStickUI::aboutVoiceStick()
{
    comingSoonInfoPopup();
}

void VoiceStickUI::aboutQt()
{
    comingSoonInfoPopup();
}

void VoiceStickUI::test()
{
    comingSoonInfoPopup();
}

void VoiceStickUI::run()
{
    comingSoonInfoPopup();
}
<commit_msg>To follow the standard<commit_after>#include "VoiceStickUI.h"

VoiceStickUI::VoiceStickUI(QWidget *parent,
                           const QString& phonemA, const QString& phonemB, const QString& phonemC, const QString& phonemD)
    : QMainWindow(parent)
{
    //Init widgets
    m_menuBar = new QMenuBar(this);
        m_fileMenu = new QMenu("File", this);
            m_openAction                = new QAction("Open...", this);
            m_saveAction                = new QAction("Save", this);
            m_saveAsAction              = new QAction("Save As...", this);
            m_exitAction                = new QAction("Exit", this);
        m_editMenu= new QMenu("Edit", this);
            m_undoAction                = new QAction("Undo", this);
            m_redoAction                = new QAction("Redo", this);
            m_undoAllAction             = new QAction("Undo All...", this);
        m_profileMenu= new QMenu("Profile", this);
            m_newProfileAction          = new QAction("New Profile...", this);
            m_deleteProfileAction       = new QAction("Delete Profile...", this);
            m_deleteAllProfilesAction   = new QAction("Delete All Profiles...", this);
        m_helpMenu= new QMenu("Help", this);
            m_userManualAction          = new QAction("User Manual...", this);
            m_aboutVoiceStickAction     = new QAction("About VoiceStick...", this);
            m_aboutQtAction             = new QAction("About Qt...", this);

    m_mainWidget = new QWidget(this);
        m_profileGroupBox = new QGroupBox("Profile",this);
            m_profileComboBox = new QComboBox(this);
            m_newProfileButton = new QPushButton("New...",this);
            m_deleteProfileButton = new QPushButton("Delete...",this);
        m_phonemsGroupBox = new QGroupBox("Phonems",this);
            m_phonemsLabelA = new QLabel(phonemA,this);
            m_phonemsLabelB = new QLabel(phonemB,this);
            m_phonemsLabelC = new QLabel(phonemC,this);
            m_phonemsLabelD = new QLabel(phonemD,this);
            m_phonemsAKeyEdit = new QKeySequenceEdit(this);
            m_phonemsBKeyEdit = new QKeySequenceEdit(this);
            m_phonemsCKeyEdit = new QKeySequenceEdit(this);
            m_phonemsDKeyEdit = new QKeySequenceEdit(this);
        m_testPushButton = new QPushButton("Test",this);
        m_runPushButton = new QPushButton("Run",this);
    m_statusBar = new QStatusBar(this);

    //Init layouts
    m_mainVBoxLayout = new QVBoxLayout(m_mainWidget);
        m_profileHBoxLayout = new QHBoxLayout(m_profileGroupBox);
        m_phonemsFormLayout = new QFormLayout(m_phonemsGroupBox);

    //Arrange actions and menus in menu bar
    m_menuBar->addMenu(m_fileMenu);
        m_fileMenu->addAction(m_openAction);
        m_fileMenu->addSeparator();
        m_fileMenu->addAction(m_saveAction);
        m_fileMenu->addAction(m_saveAsAction);
        m_fileMenu->addSeparator();
        m_fileMenu->addAction(m_exitAction);
    m_menuBar->addMenu(m_editMenu);
        m_editMenu->addAction(m_undoAction);
        m_editMenu->addAction(m_redoAction);
        m_editMenu->addSeparator();
        m_editMenu->addAction(m_undoAllAction);
    m_menuBar->addMenu(m_profileMenu);
        m_profileMenu->addAction(m_newProfileAction);
        m_profileMenu->addSeparator();
        m_profileMenu->addAction(m_deleteProfileAction);
        m_profileMenu->addAction(m_deleteAllProfilesAction);
    m_menuBar->addMenu(m_helpMenu);
        m_helpMenu->addAction(m_userManualAction);
        m_helpMenu->addSeparator();
        m_helpMenu->addAction(m_aboutVoiceStickAction);
        m_helpMenu->addAction(m_aboutQtAction);

    //Arrange widgets in their layouts
    m_mainVBoxLayout->addWidget(m_profileGroupBox);
    m_mainVBoxLayout->addWidget(m_phonemsGroupBox);
    m_mainVBoxLayout->addWidget(m_testPushButton);
    m_mainVBoxLayout->addWidget(m_runPushButton);

    m_profileHBoxLayout->addWidget(m_profileComboBox);
    m_profileHBoxLayout->addWidget(m_newProfileButton);
    m_profileHBoxLayout->addWidget(m_deleteProfileButton);

    m_phonemsFormLayout->addRow(m_phonemsLabelA, m_phonemsAKeyEdit);
    m_phonemsFormLayout->addRow(m_phonemsLabelB, m_phonemsBKeyEdit);
    m_phonemsFormLayout->addRow(m_phonemsLabelC, m_phonemsCKeyEdit);
    m_phonemsFormLayout->addRow(m_phonemsLabelD, m_phonemsDKeyEdit);

    //Arrange main window
    setMenuBar(m_menuBar);
    setCentralWidget(m_mainWidget);
    setStatusBar(m_statusBar);

    //Connect menu actions to slots
    connect(m_openAction, SIGNAL(triggered()), this, SLOT(open()));
    connect(m_saveAction, SIGNAL(triggered()), this, SLOT(save()));
    connect(m_saveAsAction, SIGNAL(triggered()), this, SLOT(saveAs()));
    connect(m_undoAction, SIGNAL(triggered()), this, SLOT(undo()));
    connect(m_redoAction, SIGNAL(triggered()), this, SLOT(redo()));
    connect(m_undoAllAction, SIGNAL(triggered()), this, SLOT(undoAll()));
    connect(m_newProfileAction, SIGNAL(triggered()), this, SLOT(newProfile()));
    connect(m_deleteProfileAction, SIGNAL(triggered()), this, SLOT(deleteProfile()));
    connect(m_deleteAllProfilesAction, SIGNAL(triggered()), this, SLOT(deleteAllProfiles()));
    connect(m_userManualAction, SIGNAL(triggered()), this, SLOT(userManual()));
    connect(m_aboutVoiceStickAction, SIGNAL(triggered()), this, SLOT(aboutVoiceStick()));
    connect(m_aboutQtAction, SIGNAL(triggered()), this, SLOT(aboutQt()));

    //Connect buttons to slots
    connect(m_newProfileButton, SIGNAL(clicked()), this, SLOT(newProfile()));
    connect(m_deleteProfileButton, SIGNAL(clicked()), this, SLOT(deleteProfile()));
    connect(m_testPushButton, SIGNAL(clicked()), this, SLOT(test()));
    connect(m_runPushButton, SIGNAL(clicked()), this, SLOT(run()));
}

VoiceStickUI::~VoiceStickUI()
{
    //QMainWindow will take care of deleting all of its children
}

int VoiceStickUI::currentProfile()
{
    return m_profileComboBox->currentIndex();
}

void VoiceStickUI::comingSoonInfoPopup()
{
    QMessageBox::information(this, "Coming soon", "The action that you are trying to do is not currently implemented.");
}

void VoiceStickUI::open()
{
    comingSoonInfoPopup();
}

void VoiceStickUI::save()
{
    comingSoonInfoPopup();
}

void VoiceStickUI::saveAs()
{
    comingSoonInfoPopup();
}

void VoiceStickUI::exit()
{
    comingSoonInfoPopup();
}

void VoiceStickUI::undo()
{
    comingSoonInfoPopup();
}

void VoiceStickUI::redo()
{
    comingSoonInfoPopup();
}

void VoiceStickUI::undoAll()
{
    comingSoonInfoPopup();
}

void VoiceStickUI::newProfile()
{
    comingSoonInfoPopup();
}

void VoiceStickUI::deleteProfile()
{
    comingSoonInfoPopup();
}

void VoiceStickUI::deleteAllProfiles()
{
    comingSoonInfoPopup();
}

void VoiceStickUI::userManual()
{
    comingSoonInfoPopup();
}

void VoiceStickUI::aboutVoiceStick()
{
    comingSoonInfoPopup();
}

void VoiceStickUI::aboutQt()
{
    comingSoonInfoPopup();
}

void VoiceStickUI::test()
{
    comingSoonInfoPopup();
}

void VoiceStickUI::run()
{
    comingSoonInfoPopup();
}
<|endoftext|>


<commit_before>/*******************************************************************************
 * Copyright (c) 2015-2018 Skymind, Inc.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Apache License, Version 2.0 which is available at
 * https://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.
 *
 * SPDX-License-Identifier: Apache-2.0
 ******************************************************************************/

//
// @author George Shulinok <sgazeos@gmail.com>, created on 08.10.2019
//

#include <op_boilerplate.h>
#if NOT_EXCLUDED(OP_fake_quant_with_min_max_vars_per_channel)

#include <ops/declarable/CustomOperations.h>
#include <ops/declarable/helpers/fake_quantization.h>
namespace nd4j {
    namespace ops {
        CONFIGURABLE_OP_IMPL(fake_quant_with_min_max_vars_per_channel, 1, 1, true, 0, 0) {

            auto x = INPUT_VARIABLE(0);
            auto min = INPUT_VARIABLE(1);
            auto max = INPUT_VARIABLE(2);

            REQUIRE_TRUE(block.width() == 3 || block.getTArguments()->size() == 2, 0, "fake_quant_with_min_max_vars_per_channel: No minimum/maximum values provided by either input arrays or TArgs");
            auto depth = x->sizeAt(-1);
            REQUIRE_TRUE(min->rankOf() == 1 && max->rankOf() == 1 && min->lengthOf() == max->lengthOf(), 0,
                    "fake_quant_with_min_max_vars_per_channel: Min and Max should be 1D tensors with the same length");
            REQUIRE_TRUE(depth == min->lengthOf(), 0, "fake_quant_with_min_max_vars_per_channel: Min length should be"
                                                      " %lld, but %lld occurs.", depth, min->lengthOf());

            REQUIRE_TRUE(depth == max->lengthOf(), 0, "fake_quant_with_min_max_vars_per_channel: Max length should be"
                                                      "%lld, but %lld occurs.", depth, max->lengthOf());
            if(block.width() == 3) {
            }
            auto output  = OUTPUT_VARIABLE(0);
            int numBits = 8;
            if (block.getIArguments() && block.getIArguments()->size())
                numBits = INT_ARG(0);
            bool narrowed = false;
            //INT_ARG(1);
            if (block.getIArguments()->size() == 2) {
                numBits = INT_ARG(0);
                narrowed = INT_ARG(1);
                REQUIRE_TRUE(numBits > 1 && numBits < 17, 0, "fake_quant_with_min_max_vars_per_channel: Number of bits"
                                                             " for quatization should be in between 2 and 16, but %i "
                                                             "was given.", numBits);
            }
            helpers::fakeQuantWithMinMaxVarsPerChannel(block.launchContext(), x, min, max, numBits, narrowed, output);
            return ND4J_STATUS_OK;
        }

        DECLARE_TYPES(fake_quant_with_min_max_vars_per_channel) {
            getOpDescriptor()
            -> setAllowedOutputTypes({ALL_FLOATS})
            -> setAllowedInputTypes({ALL_INTS, ALL_FLOATS});
        }

        DECLARE_SYN(fake_quant_with_min_max_args_per_channel, fake_quant_with_min_max_vars_per_channel);
    }
}

#endif<commit_msg>Eliminated waste operator.<commit_after>/*******************************************************************************
 * Copyright (c) 2015-2018 Skymind, Inc.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Apache License, Version 2.0 which is available at
 * https://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.
 *
 * SPDX-License-Identifier: Apache-2.0
 ******************************************************************************/

//
// @author George Shulinok <sgazeos@gmail.com>, created on 08.10.2019
//

#include <op_boilerplate.h>
#if NOT_EXCLUDED(OP_fake_quant_with_min_max_vars_per_channel)

#include <ops/declarable/CustomOperations.h>
#include <ops/declarable/helpers/fake_quantization.h>
namespace nd4j {
    namespace ops {
        CONFIGURABLE_OP_IMPL(fake_quant_with_min_max_vars_per_channel, 1, 1, true, 0, 0) {

            auto x = INPUT_VARIABLE(0);
            auto min = INPUT_VARIABLE(1);
            auto max = INPUT_VARIABLE(2);

            REQUIRE_TRUE(block.width() == 3 || block.getTArguments()->size() == 2, 0, "fake_quant_with_min_max_vars_per_channel: No minimum/maximum values provided by either input arrays or TArgs");
            auto depth = x->sizeAt(-1);
            REQUIRE_TRUE(min->rankOf() == 1 && max->rankOf() == 1 && min->lengthOf() == max->lengthOf(), 0,
                    "fake_quant_with_min_max_vars_per_channel: Min and Max should be 1D tensors with the same length");
            REQUIRE_TRUE(depth == min->lengthOf(), 0, "fake_quant_with_min_max_vars_per_channel: Min length should be"
                                                      " %lld, but %lld occurs.", depth, min->lengthOf());

            REQUIRE_TRUE(depth == max->lengthOf(), 0, "fake_quant_with_min_max_vars_per_channel: Max length should be"
                                                      "%lld, but %lld occurs.", depth, max->lengthOf());

            auto output  = OUTPUT_VARIABLE(0);
            int numBits = 8;
            if (block.getIArguments() && block.getIArguments()->size())
                numBits = INT_ARG(0);
            bool narrowed = false;
            //INT_ARG(1);
            if (block.getIArguments()->size() == 2) {
                numBits = INT_ARG(0);
                narrowed = INT_ARG(1);
                REQUIRE_TRUE(numBits > 1 && numBits < 17, 0, "fake_quant_with_min_max_vars_per_channel: Number of bits"
                                                             " for quatization should be in between 2 and 16, but %i "
                                                             "was given.", numBits);
            }
            helpers::fakeQuantWithMinMaxVarsPerChannel(block.launchContext(), x, min, max, numBits, narrowed, output);
            return ND4J_STATUS_OK;
        }

        DECLARE_TYPES(fake_quant_with_min_max_vars_per_channel) {
            getOpDescriptor()
            -> setAllowedOutputTypes({ALL_FLOATS})
            -> setAllowedInputTypes({ALL_INTS, ALL_FLOATS});
        }

        DECLARE_SYN(fake_quant_with_min_max_args_per_channel, fake_quant_with_min_max_vars_per_channel);
    }
}

#endif<|endoftext|>


<commit_before>/* <x0/mod_debug.cpp>
 *
 * This file is part of the x0 web server project and is released under LGPL-3.
 *
 * (c) 2009 Chrisitan Parpart <trapni@gentoo.org>
 */

#include <x0/server.hpp>
#include <x0/request.hpp>
#include <x0/response.hpp>
#include <x0/range_def.hpp>
#include <x0/strutils.hpp>
#include <x0/types.hpp>

#include <boost/lexical_cast.hpp>
#include <boost/tokenizer.hpp>
#include <boost/bind.hpp>

#include <sstream>
#include <iostream>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
#include <time.h>

/**
 * \ingroup plugins
 * \brief serves static files from server's local filesystem to client.
 */
class debug_plugin :
	public x0::plugin
{
private:
	x0::server::connection_hook::connection connection_open_;
	x0::server::request_parse_hook::connection pre_process_;
	x0::server::request_post_hook::connection request_done_;
	x0::server::connection_hook::connection connection_close_;

public:
	debug_plugin(x0::server& srv, const std::string& name) :
		x0::plugin(srv, name)
	{
		connection_open_ = server_.connection_open.connect(boost::bind(&debug_plugin::connection_open, this, _1));
		pre_process_ = server_.pre_process.connect(boost::bind(&debug_plugin::pre_process, this, _1));
		request_done_ = server_.request_done.connect(boost::bind(&debug_plugin::request_done, this, _1, _2));
		connection_close_ = server_.connection_close.connect(boost::bind(&debug_plugin::connection_close, this, _1));
	}

	~debug_plugin() {
		server_.connection_open.disconnect(connection_open_);
		server_.pre_process.disconnect(pre_process_);
		server_.request_done.disconnect(request_done_);
		server_.connection_close.disconnect(connection_close_);
	}

	virtual void configure()
	{
	}

private:
	std::string client_hostname(x0::connection *connection)
	{
		std::string name = connection->remote_ip();

		if (name.empty())
			name = "<unknown>";

		name += ":";
		name += boost::lexical_cast<std::string>(connection->remote_port());

		return name;
	}

	void connection_open(x0::connection *connection)
	{
		server_.log(x0::severity::info, "connection opened: %s", client_hostname(connection).c_str());
	}

	void pre_process(x0::request *in)
	{
		server_.log(x0::severity::info, "pre processing request from: %s", client_hostname(&in->connection).c_str());

		std::ostringstream stream;
		stream << "C> " << in->method.str() << ' ' << in->uri.str() << " HTTP/" << in->http_version_major << '.' << in->http_version_minor << std::endl;
		for (auto i = in->headers.begin(), e = in->headers.end(); i != e; ++i)
		{
			stream << "C> " << i->name.str() << ": " << i->value.str() << std::endl;
		}
		std::clog << stream.str();
	}

	void request_done(x0::request *in, x0::response *out)
	{
		//server_.log(x0::severity::info, "post process");

		std::ostringstream stream;

		if (!in->body.empty())
		{
			stream << "C> " << in->body << std::endl;
		}

		stream << "S< " << out->status() << ' ' << x0::response::status_str(out->status()) << std::endl;
		for (auto i = out->headers.begin(), e = out->headers.end(); i != e; ++i)
		{
			stream << "S< " << i->name << ": " << i->value << std::endl;
		}

		std::clog << stream.str();
	}

	void connection_close(x0::connection *connection)
	{
		server_.log(x0::severity::info, "connection closed: %s", client_hostname(connection).c_str());
	}
};

X0_EXPORT_PLUGIN(debug);
<commit_msg>debug: added (per connection) performance timer<commit_after>/* <x0/mod_debug.cpp>
 *
 * This file is part of the x0 web server project and is released under LGPL-3.
 *
 * (c) 2009 Chrisitan Parpart <trapni@gentoo.org>
 */

#include <x0/server.hpp>
#include <x0/request.hpp>
#include <x0/response.hpp>
#include <x0/range_def.hpp>
#include <x0/strutils.hpp>
#include <x0/types.hpp>

#include <boost/lexical_cast.hpp>
#include <boost/tokenizer.hpp>
#include <boost/bind.hpp>

#include <sstream>
#include <iostream>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
#include <time.h>
#include <ev++.h>

/**
 * \ingroup plugins
 * \brief serves static files from server's local filesystem to client.
 */
class debug_plugin :
	public x0::plugin
{
private:
	x0::server::connection_hook::connection connection_open_;
	x0::server::request_parse_hook::connection pre_process_;
	x0::server::request_post_hook::connection request_done_;
	x0::server::connection_hook::connection connection_close_;

public:
	debug_plugin(x0::server& srv, const std::string& name) :
		x0::plugin(srv, name)
	{
		connection_open_ = server_.connection_open.connect(boost::bind(&debug_plugin::connection_open, this, _1));
		pre_process_ = server_.pre_process.connect(boost::bind(&debug_plugin::pre_process, this, _1));
		request_done_ = server_.request_done.connect(boost::bind(&debug_plugin::request_done, this, _1, _2));
		connection_close_ = server_.connection_close.connect(boost::bind(&debug_plugin::connection_close, this, _1));
	}

	~debug_plugin() {
		server_.connection_open.disconnect(connection_open_);
		server_.pre_process.disconnect(pre_process_);
		server_.request_done.disconnect(request_done_);
		server_.connection_close.disconnect(connection_close_);
	}

	virtual void configure()
	{
	}

private:
	std::string client_hostname(x0::connection *connection)
	{
		std::string name = connection->remote_ip();

		if (name.empty())
			name = "<unknown>";

		name += ":";
		name += boost::lexical_cast<std::string>(connection->remote_port());

		return name;
	}

	struct timer :
		public x0::custom_data
	{
		ev::tstamp value_;
		struct ev_loop *loop_;

		explicit timer(struct ev_loop *loop) : value_(ev_now(loop)), loop_(loop) {}

		ev::tstamp diff() const { return ev_now(loop_) - value_; }
	};

	void connection_open(x0::connection *connection)
	{
		server_.log(x0::severity::info, "connection opened: %s", client_hostname(connection).c_str());
		connection->custom_data[this] = std::make_shared<timer>(server_.loop());
	}

	void pre_process(x0::request *in)
	{
		server_.log(x0::severity::info, "pre processing request from: %s", client_hostname(&in->connection).c_str());

		std::ostringstream stream;
		stream << "C> " << in->method.str() << ' ' << in->uri.str() << " HTTP/" << in->http_version_major << '.' << in->http_version_minor << std::endl;
		for (auto i = in->headers.begin(), e = in->headers.end(); i != e; ++i)
		{
			stream << "C> " << i->name.str() << ": " << i->value.str() << std::endl;
		}
		std::clog << stream.str();
	}

	void request_done(x0::request *in, x0::response *out)
	{
		//server_.log(x0::severity::info, "post process");

		std::ostringstream stream;

		if (!in->body.empty())
		{
			stream << "C> " << in->body << std::endl;
		}

		stream << "S< " << out->status() << ' ' << x0::response::status_str(out->status()) << std::endl;
		for (auto i = out->headers.begin(), e = out->headers.end(); i != e; ++i)
		{
			stream << "S< " << i->name << ": " << i->value << std::endl;
		}

		std::clog << stream.str();
	}

	void connection_close(x0::connection *connection)
	{
		if (std::shared_ptr<timer> tm = std::static_pointer_cast<timer>(connection->custom_data[this]))
		{
			server_.log(x0::severity::info, "connection timing: %.4f", tm->diff());
		}

		server_.log(x0::severity::info, "connection closed: %s", client_hostname(connection).c_str());
	}
};

X0_EXPORT_PLUGIN(debug);
<|endoftext|>


<commit_before>/*
 * (C) Copyright 2013 Kurento (http://kurento.org/)
 *
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the GNU Lesser General Public License
 * (LGPL) version 2.1 which accompanies this distribution, and is available at
 * http://www.gnu.org/licenses/lgpl-2.1.html
 *
 * 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.
 *
 */

#include <sys/signalfd.h>
#include <config.h>

#include "media_config.hpp"

#include <glibmm.h>
#include <fstream>
#include <iostream>
#include <boost/filesystem.hpp>
#include <version.hpp>
#include "httpendpointserver.hpp"
#include <ModuleLoader.hpp>
#include <glib/gstdio.h>

#include "services/Service.hpp"
#include "services/ServiceFactory.hpp"

#define GST_CAT_DEFAULT kurento_media_server
GST_DEBUG_CATEGORY_STATIC (GST_CAT_DEFAULT);
#define GST_DEFAULT_NAME "KurentoMediaServer"

#define ENV_VAR "GST_PLUGIN_PATH"
#define CERTTOOL_TEMPLATE "autoCerttool.tmpl"
#define CERT_KEY_PEM_FILE "autoCertkey.pem"

using namespace ::kurento;

using boost::shared_ptr;
using namespace boost::filesystem;

using ::Glib::KeyFile;
using ::Glib::KeyFileFlags;

static Service *service;

GstSDPMessage *sdpPattern;
KmsHttpEPServer *httpepserver;
std::string stunServerAddress, pemCertificate;
gint stunServerPort;

Glib::RefPtr<Glib::MainLoop> loop = Glib::MainLoop::create ();

static gchar *conf_file;
gchar *autogenerated_pem_file, *template_path;

static GOptionEntry entries[] = {
  {
    "conf-file", 'f', 0, G_OPTION_ARG_FILENAME, &conf_file, "Configuration file",
    NULL
  },
  {NULL}
};

Glib::RefPtr<Glib::IOChannel> channel;

static void
check_port (int port)
{
  if (port <= 0 || port > G_MAXUSHORT) {
    throw Glib::KeyFileError (Glib::KeyFileError::PARSE, "Invalid value");
  }
}

static gchar *
read_entire_file (const gchar *file_name)
{
  gchar *data;
  long f_size;
  FILE *fp;

  fp = fopen (file_name, "r");

  if (fp == NULL) {
    return NULL;
  }

  fseek (fp, 0, SEEK_END);
  f_size = ftell (fp);
  fseek (fp, 0, SEEK_SET);
  data = (gchar *) g_malloc0 (f_size + 1);

  if (fread (data, 1, f_size, fp) != (size_t) f_size) {
    GST_ERROR ("Error reading file");
  }

  fclose (fp);

  data[f_size] = '\0';

  return data;
}

static GstSDPMessage *
load_sdp_pattern (Glib::KeyFile &configFile, const std::string &confFileName)
{
  GstSDPResult result;
  GstSDPMessage *sdp_pattern = NULL;
  gchar *sdp_pattern_text;
  std::string sdp_pattern_file_name;

  GST_DEBUG ("Load SDP Pattern");
  result = gst_sdp_message_new (&sdp_pattern);

  if (result != GST_SDP_OK) {
    GST_ERROR ("Error creating sdp message");
    return NULL;
  }

  sdp_pattern_file_name = configFile.get_string (SERVER_GROUP, SDP_PATTERN_KEY);
  boost::filesystem::path p (confFileName.c_str () );
  sdp_pattern_file_name.insert (0, "/");
  sdp_pattern_file_name.insert (0, p.parent_path ().c_str() );
  sdp_pattern_text = read_entire_file (sdp_pattern_file_name.c_str () );

  if (sdp_pattern_text == NULL) {
    GST_ERROR ("Error reading SDP pattern file");
    gst_sdp_message_free (sdp_pattern);
    return NULL;
  }

  result = gst_sdp_message_parse_buffer ( (const guint8 *) sdp_pattern_text, -1,
                                          sdp_pattern);
  g_free (sdp_pattern_text);

  if (result != GST_SDP_OK) {
    GST_ERROR ("Error parsing SDP config pattern");
    gst_sdp_message_free (sdp_pattern);
    return NULL;
  }

  return sdp_pattern;
}

static void
configure_kurento_media_server (KeyFile &configFile,
                                const std::string &file_name)
{
  gchar *sdpMessageText = NULL;

  try {
    sdpPattern = load_sdp_pattern (configFile, file_name);
    GST_DEBUG ("SDP: \n%s", sdpMessageText = gst_sdp_message_as_text (sdpPattern) );
    g_free (sdpMessageText);
  } catch (const Glib::KeyFileError &err) {
    GST_ERROR ("%s", err.what ().c_str () );
    GST_WARNING ("Wrong codec configuration, communication won't be possible");
  }

  service = ServiceFactory::create_service (configFile);
}

static gchar *
generate_certkey_pem_file (const gchar *dir)
{
  gchar *cmd, *pem_path;
  int ret;

  if (dir == NULL) {
    return NULL;
  }

  pem_path = g_strdup_printf ("%s/%s", dir, CERT_KEY_PEM_FILE);
  cmd =
    g_strconcat ("/bin/sh -c \"certtool --generate-privkey --outfile ",
                 pem_path, "\"", NULL);
  ret = system (cmd);
  g_free (cmd);

  if (ret == -1) {
    goto err;
  }

  template_path = g_strdup_printf ("%s/%s", dir, CERTTOOL_TEMPLATE);
  cmd =
    g_strconcat
    ("/bin/sh -c \"echo 'organization = kurento' > ", template_path,
     " && certtool --generate-self-signed --load-privkey ", pem_path,
     " --template ", template_path, " >> ", pem_path, " 2>/dev/null\"", NULL);
  ret = system (cmd);
  g_free (cmd);

  if (ret == -1) {
    goto err;
  }

  return pem_path;

err:

  GST_ERROR ("Error while generating certificate file");

  g_free (pem_path);
  return NULL;
}

static void
configure_web_rtc_end_point (KeyFile &configFile, const std::string &file_name)
{
  gint port;
  std::string pem_certificate_file_name;

  try {
    stunServerAddress = configFile.get_string (WEB_RTC_END_POINT_GROUP,
                        WEB_RTC_END_POINT_STUN_SERVER_ADDRESS_KEY);
  } catch (const Glib::KeyFileError &err) {
    GST_ERROR ("%s", err.what ().c_str () );
    GST_WARNING ("Setting default address %s to stun server",
                 STUN_SERVER_ADDRESS);
    stunServerAddress = STUN_SERVER_ADDRESS;
  }

  try {
    port = configFile.get_integer (WEB_RTC_END_POINT_GROUP,
                                   WEB_RTC_END_POINT_STUN_SERVER_PORT_KEY);
    check_port (port);
    stunServerPort = port;
  } catch (const Glib::KeyFileError &err) {
    GST_ERROR ("%s", err.what ().c_str () );
    GST_WARNING ("Setting default port %d to stun server",
                 STUN_SERVER_PORT);
    stunServerPort = STUN_SERVER_PORT;
  }

  try {
    pem_certificate_file_name = configFile.get_string (WEB_RTC_END_POINT_GROUP,
                                WEB_RTC_END_POINT_PEM_CERTIFICATE_KEY);
    boost::filesystem::path p (file_name.c_str () );
    pem_certificate_file_name.insert (0, "/");
    pem_certificate_file_name.insert (0, p.parent_path ().c_str() );
    pemCertificate = pem_certificate_file_name.c_str();

  } catch (const Glib::KeyFileError &err) {
    //generate a valid pem certificate
    autogenerated_pem_file = generate_certkey_pem_file ("/tmp/");

    if (autogenerated_pem_file == NULL ) {
      pemCertificate = "";
      GST_ERROR ("%s", err.what ().c_str () );
      GST_WARNING ("Could not create Pem Certificate or Pem Certificate not found");
    } else {
      pemCertificate = autogenerated_pem_file;
    }
  }
}

static void
load_config (const std::string &file_name)
{
  KeyFile configFile;

  GST_INFO ("Reading configuration from: %s", file_name.c_str () );

  try {
    configFile.load_from_file (file_name,
                               KeyFileFlags::KEY_FILE_KEEP_COMMENTS |
                               KeyFileFlags::KEY_FILE_KEEP_TRANSLATIONS);
  } catch (const Glib::Error &ex) {
    GST_ERROR ("Error loading configuration: %s", ex.what ().c_str () );
    throw ex;
  }

  /* parse options so as to configure services */
  configure_kurento_media_server (configFile, file_name);
  configure_web_rtc_end_point (configFile, file_name);

  GST_INFO ("Configuration loaded successfully");
}

static bool
signal_handler (Glib::IOCondition cond)
{
  static unsigned int __terminated = 0;
  struct signalfd_siginfo si;
  gsize bytes_read, count = sizeof (si);
  Glib::IOStatus status;

  if (cond & (Glib::IO_NVAL | Glib::IO_ERR | Glib::IO_HUP) ) {
    return false;
  }

  /* Read signal info */
  status = channel->read ( (char *) &si, count, bytes_read);

  switch (status) {
  case Glib::IO_STATUS_ERROR:
    GST_ERROR ("Error occurred.");
    return false;

  case Glib::IO_STATUS_EOF:
    GST_DEBUG ("End of file.");
    return false;

  case Glib::IO_STATUS_AGAIN:
    GST_DEBUG ("Resource temporarily unavailable.");
    return false;

  case Glib::IO_STATUS_NORMAL:
    if (bytes_read != count) {
      GST_DEBUG ("Could not read siginfo structure");
      return false;
    }

    break;
  }

  /* Manage signal */
  switch (si.ssi_signo) {
  case SIGINT:
  case SIGTERM:
    if (__terminated == 0) {
      GST_DEBUG ("Terminating.");
      loop->quit ();
    }

    __terminated = 1;
    break;

  case SIGPIPE:
    GST_DEBUG ("Ignore sigpipe signal");
    return false;

  case SIGSEGV:
    GST_DEBUG ("Segmentation fault. Aborting process execution");
    abort ();

  default:
    break;
  }

  return true;
}

static Glib::RefPtr<Glib::IOSource>
setup_signalfd ()
{
  Glib::RefPtr<Glib::IOSource> source;
  sigset_t mask;
  int fd;

  sigemptyset (&mask);
  sigaddset (&mask, SIGINT);
  sigaddset (&mask, SIGTERM);
  sigaddset (&mask, SIGSEGV);
  sigaddset (&mask, SIGPIPE);

  if (sigprocmask (SIG_BLOCK, &mask, NULL) < 0) {
    throw "Failed to set signal mask";
  }

  fd = signalfd (-1, &mask, 0);

  if (fd < 0) {
    throw "Failed to create signal descriptor";
  }

  channel = Glib::IOChannel::create_from_fd (fd);
  channel->set_close_on_unref (true);
  channel->set_encoding ("");
  channel->set_buffered (false);

  source = channel->create_watch (Glib::IO_IN | Glib::IO_HUP | Glib::IO_ERR |
                                  Glib::IO_NVAL);
  source->connect (sigc::ptr_fun (&signal_handler) );

  return source;
}

static void
deleteCertificate ()
{
  //delete pem certificate
  if (autogenerated_pem_file != NULL) {
    int rv = g_remove (autogenerated_pem_file);

    if (rv) {
      GST_WARNING ("Error deleting file: %s. %s", autogenerated_pem_file,
                   strerror (errno) );
    }

    g_free (autogenerated_pem_file);
  }

  if (template_path != NULL) {
    int rv = g_remove (template_path);

    if (rv) {
      GST_WARNING ("Error deleting file: %s. %s", template_path, strerror (errno) );
    }

    g_free (template_path);
  }
}

static void
check_if_plugins_are_available ()
{
  GstPlugin *plugin = gst_plugin_load_by_name ("kurento");

  if (plugin == NULL) {
    g_printerr ("Kurento plugin not found, try adding the plugins route with "
                "--gst-plugin-path parameter. See help (--help-gst) "
                "for more info\n");
    exit (1);
  }

  g_clear_object (&plugin);
}

int
main (int argc, char **argv)
{
  Glib::RefPtr<Glib::Source> source;
  GError *error = NULL;
  GOptionContext *context;
  gchar *oldEnv, *newEnv;

  Glib::init();
  gst_init (&argc, &argv);
  GST_DEBUG_CATEGORY_INIT (GST_CAT_DEFAULT, GST_DEFAULT_NAME, 0,
                           GST_DEFAULT_NAME);

  oldEnv = getenv (ENV_VAR);

  if (oldEnv == NULL) {
    newEnv = g_strdup_printf ("%s", PLUGIN_PATH);
  } else {
    newEnv = g_strdup_printf ("%s:%s", oldEnv, PLUGIN_PATH);
  }

  setenv (ENV_VAR, newEnv, 1);
  g_free (newEnv);

  check_if_plugins_are_available ();

  context = g_option_context_new ("");
  g_option_context_add_main_entries (context, entries, NULL);
  g_option_context_add_group (context, gst_init_get_option_group () );

  if (!g_option_context_parse (context, &argc, &argv, &error) ) {
    g_printerr ("option parsing failed: %s\n", error->message);
    g_option_context_free (context);
    g_error_free (error);
    exit (1);
  }

  g_option_context_free (context);

  /* Install our signal handler */
  source = setup_signalfd();
  source->attach (Glib::MainContext::get_default() );

  GST_INFO ("Kmsc version: %s", get_version () );

  if (!conf_file) {
    load_config (DEFAULT_CONFIG_FILE);
  } else {
    load_config ( (std::string) conf_file);
  }

  /* Start service */
  service->start ();

  loop->run ();

  source->destroy();

  deleteCertificate ();

  service->stop();

  delete service;

  return 0;
}
<commit_msg>main: Gracefully catch exceptions and print an error message before exit if service cannot start<commit_after>/*
 * (C) Copyright 2013 Kurento (http://kurento.org/)
 *
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the GNU Lesser General Public License
 * (LGPL) version 2.1 which accompanies this distribution, and is available at
 * http://www.gnu.org/licenses/lgpl-2.1.html
 *
 * 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.
 *
 */

#include <sys/signalfd.h>
#include <config.h>

#include "media_config.hpp"

#include <glibmm.h>
#include <fstream>
#include <iostream>
#include <boost/filesystem.hpp>
#include <version.hpp>
#include "httpendpointserver.hpp"
#include <ModuleLoader.hpp>
#include <glib/gstdio.h>

#include "services/Service.hpp"
#include "services/ServiceFactory.hpp"

#define GST_CAT_DEFAULT kurento_media_server
GST_DEBUG_CATEGORY_STATIC (GST_CAT_DEFAULT);
#define GST_DEFAULT_NAME "KurentoMediaServer"

#define ENV_VAR "GST_PLUGIN_PATH"
#define CERTTOOL_TEMPLATE "autoCerttool.tmpl"
#define CERT_KEY_PEM_FILE "autoCertkey.pem"

using namespace ::kurento;

using boost::shared_ptr;
using namespace boost::filesystem;

using ::Glib::KeyFile;
using ::Glib::KeyFileFlags;

static Service *service;

GstSDPMessage *sdpPattern;
KmsHttpEPServer *httpepserver;
std::string stunServerAddress, pemCertificate;
gint stunServerPort;

Glib::RefPtr<Glib::MainLoop> loop = Glib::MainLoop::create ();

static gchar *conf_file;
gchar *autogenerated_pem_file, *template_path;

static GOptionEntry entries[] = {
  {
    "conf-file", 'f', 0, G_OPTION_ARG_FILENAME, &conf_file, "Configuration file",
    NULL
  },
  {NULL}
};

Glib::RefPtr<Glib::IOChannel> channel;

static void
check_port (int port)
{
  if (port <= 0 || port > G_MAXUSHORT) {
    throw Glib::KeyFileError (Glib::KeyFileError::PARSE, "Invalid value");
  }
}

static gchar *
read_entire_file (const gchar *file_name)
{
  gchar *data;
  long f_size;
  FILE *fp;

  fp = fopen (file_name, "r");

  if (fp == NULL) {
    return NULL;
  }

  fseek (fp, 0, SEEK_END);
  f_size = ftell (fp);
  fseek (fp, 0, SEEK_SET);
  data = (gchar *) g_malloc0 (f_size + 1);

  if (fread (data, 1, f_size, fp) != (size_t) f_size) {
    GST_ERROR ("Error reading file");
  }

  fclose (fp);

  data[f_size] = '\0';

  return data;
}

static GstSDPMessage *
load_sdp_pattern (Glib::KeyFile &configFile, const std::string &confFileName)
{
  GstSDPResult result;
  GstSDPMessage *sdp_pattern = NULL;
  gchar *sdp_pattern_text;
  std::string sdp_pattern_file_name;

  GST_DEBUG ("Load SDP Pattern");
  result = gst_sdp_message_new (&sdp_pattern);

  if (result != GST_SDP_OK) {
    GST_ERROR ("Error creating sdp message");
    return NULL;
  }

  sdp_pattern_file_name = configFile.get_string (SERVER_GROUP, SDP_PATTERN_KEY);
  boost::filesystem::path p (confFileName.c_str () );
  sdp_pattern_file_name.insert (0, "/");
  sdp_pattern_file_name.insert (0, p.parent_path ().c_str() );
  sdp_pattern_text = read_entire_file (sdp_pattern_file_name.c_str () );

  if (sdp_pattern_text == NULL) {
    GST_ERROR ("Error reading SDP pattern file");
    gst_sdp_message_free (sdp_pattern);
    return NULL;
  }

  result = gst_sdp_message_parse_buffer ( (const guint8 *) sdp_pattern_text, -1,
                                          sdp_pattern);
  g_free (sdp_pattern_text);

  if (result != GST_SDP_OK) {
    GST_ERROR ("Error parsing SDP config pattern");
    gst_sdp_message_free (sdp_pattern);
    return NULL;
  }

  return sdp_pattern;
}

static void
configure_kurento_media_server (KeyFile &configFile,
                                const std::string &file_name)
{
  gchar *sdpMessageText = NULL;

  try {
    sdpPattern = load_sdp_pattern (configFile, file_name);
    GST_DEBUG ("SDP: \n%s", sdpMessageText = gst_sdp_message_as_text (sdpPattern) );
    g_free (sdpMessageText);
  } catch (const Glib::KeyFileError &err) {
    GST_ERROR ("%s", err.what ().c_str () );
    GST_WARNING ("Wrong codec configuration, communication won't be possible");
  }

  try {
    service = ServiceFactory::create_service (configFile);
  } catch (std::exception &e) {
    GST_ERROR ("Error creating service: %s", e.what() );
    exit (1);
  } catch (Glib::Exception &e) {
    GST_ERROR ("Error creating service: %s", e.what().c_str() );
    exit (1);
  }
}

static gchar *
generate_certkey_pem_file (const gchar *dir)
{
  gchar *cmd, *pem_path;
  int ret;

  if (dir == NULL) {
    return NULL;
  }

  pem_path = g_strdup_printf ("%s/%s", dir, CERT_KEY_PEM_FILE);
  cmd =
    g_strconcat ("/bin/sh -c \"certtool --generate-privkey --outfile ",
                 pem_path, "\"", NULL);
  ret = system (cmd);
  g_free (cmd);

  if (ret == -1) {
    goto err;
  }

  template_path = g_strdup_printf ("%s/%s", dir, CERTTOOL_TEMPLATE);
  cmd =
    g_strconcat
    ("/bin/sh -c \"echo 'organization = kurento' > ", template_path,
     " && certtool --generate-self-signed --load-privkey ", pem_path,
     " --template ", template_path, " >> ", pem_path, " 2>/dev/null\"", NULL);
  ret = system (cmd);
  g_free (cmd);

  if (ret == -1) {
    goto err;
  }

  return pem_path;

err:

  GST_ERROR ("Error while generating certificate file");

  g_free (pem_path);
  return NULL;
}

static void
configure_web_rtc_end_point (KeyFile &configFile, const std::string &file_name)
{
  gint port;
  std::string pem_certificate_file_name;

  try {
    stunServerAddress = configFile.get_string (WEB_RTC_END_POINT_GROUP,
                        WEB_RTC_END_POINT_STUN_SERVER_ADDRESS_KEY);
  } catch (const Glib::KeyFileError &err) {
    GST_ERROR ("%s", err.what ().c_str () );
    GST_WARNING ("Setting default address %s to stun server",
                 STUN_SERVER_ADDRESS);
    stunServerAddress = STUN_SERVER_ADDRESS;
  }

  try {
    port = configFile.get_integer (WEB_RTC_END_POINT_GROUP,
                                   WEB_RTC_END_POINT_STUN_SERVER_PORT_KEY);
    check_port (port);
    stunServerPort = port;
  } catch (const Glib::KeyFileError &err) {
    GST_ERROR ("%s", err.what ().c_str () );
    GST_WARNING ("Setting default port %d to stun server",
                 STUN_SERVER_PORT);
    stunServerPort = STUN_SERVER_PORT;
  }

  try {
    pem_certificate_file_name = configFile.get_string (WEB_RTC_END_POINT_GROUP,
                                WEB_RTC_END_POINT_PEM_CERTIFICATE_KEY);
    boost::filesystem::path p (file_name.c_str () );
    pem_certificate_file_name.insert (0, "/");
    pem_certificate_file_name.insert (0, p.parent_path ().c_str() );
    pemCertificate = pem_certificate_file_name.c_str();

  } catch (const Glib::KeyFileError &err) {
    //generate a valid pem certificate
    autogenerated_pem_file = generate_certkey_pem_file ("/tmp/");

    if (autogenerated_pem_file == NULL ) {
      pemCertificate = "";
      GST_ERROR ("%s", err.what ().c_str () );
      GST_WARNING ("Could not create Pem Certificate or Pem Certificate not found");
    } else {
      pemCertificate = autogenerated_pem_file;
    }
  }
}

static void
load_config (const std::string &file_name)
{
  KeyFile configFile;

  GST_INFO ("Reading configuration from: %s", file_name.c_str () );

  try {
    configFile.load_from_file (file_name,
                               KeyFileFlags::KEY_FILE_KEEP_COMMENTS |
                               KeyFileFlags::KEY_FILE_KEEP_TRANSLATIONS);
  } catch (const Glib::Error &ex) {
    GST_ERROR ("Error loading configuration: %s", ex.what ().c_str () );
    throw ex;
  }

  /* parse options so as to configure services */
  configure_kurento_media_server (configFile, file_name);
  configure_web_rtc_end_point (configFile, file_name);

  GST_INFO ("Configuration loaded successfully");
}

static bool
signal_handler (Glib::IOCondition cond)
{
  static unsigned int __terminated = 0;
  struct signalfd_siginfo si;
  gsize bytes_read, count = sizeof (si);
  Glib::IOStatus status;

  if (cond & (Glib::IO_NVAL | Glib::IO_ERR | Glib::IO_HUP) ) {
    return false;
  }

  /* Read signal info */
  status = channel->read ( (char *) &si, count, bytes_read);

  switch (status) {
  case Glib::IO_STATUS_ERROR:
    GST_ERROR ("Error occurred.");
    return false;

  case Glib::IO_STATUS_EOF:
    GST_DEBUG ("End of file.");
    return false;

  case Glib::IO_STATUS_AGAIN:
    GST_DEBUG ("Resource temporarily unavailable.");
    return false;

  case Glib::IO_STATUS_NORMAL:
    if (bytes_read != count) {
      GST_DEBUG ("Could not read siginfo structure");
      return false;
    }

    break;
  }

  /* Manage signal */
  switch (si.ssi_signo) {
  case SIGINT:
  case SIGTERM:
    if (__terminated == 0) {
      GST_DEBUG ("Terminating.");
      loop->quit ();
    }

    __terminated = 1;
    break;

  case SIGPIPE:
    GST_DEBUG ("Ignore sigpipe signal");
    return false;

  case SIGSEGV:
    GST_DEBUG ("Segmentation fault. Aborting process execution");
    abort ();

  default:
    break;
  }

  return true;
}

static Glib::RefPtr<Glib::IOSource>
setup_signalfd ()
{
  Glib::RefPtr<Glib::IOSource> source;
  sigset_t mask;
  int fd;

  sigemptyset (&mask);
  sigaddset (&mask, SIGINT);
  sigaddset (&mask, SIGTERM);
  sigaddset (&mask, SIGSEGV);
  sigaddset (&mask, SIGPIPE);

  if (sigprocmask (SIG_BLOCK, &mask, NULL) < 0) {
    throw "Failed to set signal mask";
  }

  fd = signalfd (-1, &mask, 0);

  if (fd < 0) {
    throw "Failed to create signal descriptor";
  }

  channel = Glib::IOChannel::create_from_fd (fd);
  channel->set_close_on_unref (true);
  channel->set_encoding ("");
  channel->set_buffered (false);

  source = channel->create_watch (Glib::IO_IN | Glib::IO_HUP | Glib::IO_ERR |
                                  Glib::IO_NVAL);
  source->connect (sigc::ptr_fun (&signal_handler) );

  return source;
}

static void
deleteCertificate ()
{
  //delete pem certificate
  if (autogenerated_pem_file != NULL) {
    int rv = g_remove (autogenerated_pem_file);

    if (rv) {
      GST_WARNING ("Error deleting file: %s. %s", autogenerated_pem_file,
                   strerror (errno) );
    }

    g_free (autogenerated_pem_file);
  }

  if (template_path != NULL) {
    int rv = g_remove (template_path);

    if (rv) {
      GST_WARNING ("Error deleting file: %s. %s", template_path, strerror (errno) );
    }

    g_free (template_path);
  }
}

static void
check_if_plugins_are_available ()
{
  GstPlugin *plugin = gst_plugin_load_by_name ("kurento");

  if (plugin == NULL) {
    g_printerr ("Kurento plugin not found, try adding the plugins route with "
                "--gst-plugin-path parameter. See help (--help-gst) "
                "for more info\n");
    exit (1);
  }

  g_clear_object (&plugin);
}

int
main (int argc, char **argv)
{
  Glib::RefPtr<Glib::Source> source;
  GError *error = NULL;
  GOptionContext *context;
  gchar *oldEnv, *newEnv;

  Glib::init();
  gst_init (&argc, &argv);
  GST_DEBUG_CATEGORY_INIT (GST_CAT_DEFAULT, GST_DEFAULT_NAME, 0,
                           GST_DEFAULT_NAME);

  oldEnv = getenv (ENV_VAR);

  if (oldEnv == NULL) {
    newEnv = g_strdup_printf ("%s", PLUGIN_PATH);
  } else {
    newEnv = g_strdup_printf ("%s:%s", oldEnv, PLUGIN_PATH);
  }

  setenv (ENV_VAR, newEnv, 1);
  g_free (newEnv);

  check_if_plugins_are_available ();

  context = g_option_context_new ("");
  g_option_context_add_main_entries (context, entries, NULL);
  g_option_context_add_group (context, gst_init_get_option_group () );

  if (!g_option_context_parse (context, &argc, &argv, &error) ) {
    g_printerr ("option parsing failed: %s\n", error->message);
    g_option_context_free (context);
    g_error_free (error);
    exit (1);
  }

  g_option_context_free (context);

  /* Install our signal handler */
  source = setup_signalfd();
  source->attach (Glib::MainContext::get_default() );

  GST_INFO ("Kmsc version: %s", get_version () );

  if (!conf_file) {
    load_config (DEFAULT_CONFIG_FILE);
  } else {
    load_config ( (std::string) conf_file);
  }

  /* Start service */
  service->start ();

  loop->run ();

  source->destroy();

  deleteCertificate ();

  service->stop();

  delete service;

  return 0;
}
<|endoftext|>


<commit_before>/* IBM_PROLOG_BEGIN_TAG                                                   */
/* This is an automatically generated prolog.                             */
/*                                                                        */
/* $Source: src/import/chips/p9/common/scominfo/p9_scominfo.H $           */
/*                                                                        */
/* OpenPOWER HostBoot Project                                             */
/*                                                                        */
/* Contributors Listed Below - COPYRIGHT 2015,2019                        */
/* [+] International Business Machines Corp.                              */
/*                                                                        */
/*                                                                        */
/* 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.                         */
/*                                                                        */
/* IBM_PROLOG_END_TAG                                                     */
///
/// @file p9_scominfo.H
/// @brief P9 chip unit SCOM address platform translation code
///
/// HWP HWP Owner: jmcgill@us.ibm.com
/// HWP FW Owner: dcrowell@us.ibm.com
/// HWP Team: Infrastructure
/// HWP Level: 1
/// HWP Consumed by: FSP/HB
///

#ifndef P9_SCOMINFO_H
#define P9_SCOMINFO_H

// includes
#include <stdint.h>
#include <vector>
#include "p9_cu.H"

extern "C"
{

    static const uint32_t PPE_MODE = 1;

    typedef enum
    {
        STANDARD_MODE = 0
    } p9TranslationMode_t;

    typedef enum
    {
        FAILED_TRANSLATION = 0xFFFFFFFFFFFFFFF1ull
    } p9TranslationResult_t;

    /// @brief Creates the actual SCOM address based on the chip unit type, instance, and the input SCOM address (relative to chip unit instance 0)
    /// @param[in] i_p9CU Enumeration of the chip unit type
    /// @param[in] i_chipUnitNum Instance number of the chip unit
    /// @param[in] i_scomAddr The input SCOM address associated with the chip unit type
    /// @param[in] i_mode Used for special purposes, default to 0
    /// @retval uint64_t Actual SCOM address for the chip unit instance passed in
    uint64_t p9_scominfo_createChipUnitScomAddr(const p9ChipUnits_t i_p9CU, const uint8_t i_chipUnitNum,
            const uint64_t i_scomAddr, const uint32_t i_mode = 0);

    /// @brief Determine if the provided SCOM address correlates to any chip units (if so creates a list of chipUnitPairing structures which correspond)
    /// @param[in] i_scomAddr SCOM address to be tested
    /// @param[out] o_chipUnitRelated Returns true if SCOM address is associated with any chip units
    /// @param[out] o_chipUnitPairing Collection of chipUnitPairing enums
    /// @param[in] i_mode Used for special purposes, default to 0
    /// @retval uint32_t Return non-zero for error
    uint32_t p9_scominfo_isChipUnitScom(const uint64_t i_scomAddr, bool& o_chipUnitRelated,
                                        std::vector<p9_chipUnitPairing_t>& o_chipUnitPairing, const uint32_t i_mode = 0);

} // extern "C"

#endif /* P9_SCOMINFO_H */
<commit_msg>Adding prototype for fixChipUnitScomAddrOrTarget to scominfo.<commit_after>/* IBM_PROLOG_BEGIN_TAG                                                   */
/* This is an automatically generated prolog.                             */
/*                                                                        */
/* $Source: src/import/chips/p9/common/scominfo/p9_scominfo.H $           */
/*                                                                        */
/* OpenPOWER HostBoot Project                                             */
/*                                                                        */
/* Contributors Listed Below - COPYRIGHT 2015,2019                        */
/* [+] International Business Machines Corp.                              */
/*                                                                        */
/*                                                                        */
/* 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.                         */
/*                                                                        */
/* IBM_PROLOG_END_TAG                                                     */
///
/// @file p9_scominfo.H
/// @brief P9 chip unit SCOM address platform translation code
///
/// HWP HWP Owner: jmcgill@us.ibm.com
/// HWP FW Owner: dcrowell@us.ibm.com
/// HWP Team: Infrastructure
/// HWP Level: 1
/// HWP Consumed by: FSP/HB
///

#ifndef P9_SCOMINFO_H
#define P9_SCOMINFO_H

// includes
#include <stdint.h>
#include <vector>
#include "p9_cu.H"

extern "C"
{

    static const uint32_t PPE_MODE = 1;

    typedef enum
    {
        STANDARD_MODE = 0
    } p9TranslationMode_t;

    typedef enum
    {
        FAILED_TRANSLATION = 0xFFFFFFFFFFFFFFF1ull
    } p9TranslationResult_t;

    /// @brief Creates the actual SCOM address based on the chip unit type, instance, and the input SCOM address (relative to chip unit instance 0)
    /// @param[in] i_p9CU Enumeration of the chip unit type
    /// @param[in] i_chipUnitNum Instance number of the chip unit
    /// @param[in] i_scomAddr The input SCOM address associated with the chip unit type
    /// @param[in] i_mode Used for special purposes, default to 0
    /// @retval uint64_t Actual SCOM address for the chip unit instance passed in
    uint64_t p9_scominfo_createChipUnitScomAddr(const p9ChipUnits_t i_p9CU, const uint8_t i_chipUnitNum,
            const uint64_t i_scomAddr, const uint32_t i_mode = 0);

    /// @brief Determine if the provided SCOM address correlates to any chip units (if so creates a list of chipUnitPairing structures which correspond)
    /// @param[in] i_scomAddr SCOM address to be tested
    /// @param[out] o_chipUnitRelated Returns true if SCOM address is associated with any chip units
    /// @param[out] o_chipUnitPairing Collection of chipUnitPairing enums
    /// @param[in] i_mode Used for special purposes, default to 0
    /// @retval uint32_t Return non-zero for error
    uint32_t p9_scominfo_isChipUnitScom(const uint64_t i_scomAddr, bool& o_chipUnitRelated,
                                        std::vector<p9_chipUnitPairing_t>& o_chipUnitPairing, const uint32_t i_mode = 0);

    /// @brief Alter the unit/unitnum of a target for spys where the clocks-on vs clocks-off targets are different.
    /// @param[in] i_p9CU target used for the spy request
    /// @param[in] i_targetChipUnitNum the instance number of the target used for the spy request
    /// @param[in] i_scomaddr the scom from the clocks-on portion of the spy
    /// @param[out] o_modifiedScomAddr the translated scom address (none may be needed)
    /// @param[out] o_p9CU the translated target type
    /// @param[out] o_modifiedChipUnitNum the translated target instance number
    /// @param[in] i_mode Could be used in the future to indicate if the translation is from clocks-on or clocks-off state
    /// @retval uint32_t Return non-zero for error
    uint32_t p9_scominfo_fixChipUnitScomAddrOrTarget(const p9ChipUnits_t i_p9CU, const uint32_t i_targetChipUnitNum,
            const uint64_t i_scomaddr, uint64_t& o_modifiedScomAddr, p9ChipUnits_t& o_p9CU,
            uint32_t& o_modifiedChipUnitNum, const uint32_t i_mode = 0);

} // extern "C"

#endif /* P9_SCOMINFO_H */
<|endoftext|>


<commit_before>// Copyright 2015 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.

#include "flutter/shell/common/platform_view.h"

#include <utility>

#include "flutter/common/threads.h"
#include "flutter/lib/ui/painting/resource_context.h"
#include "flutter/shell/common/rasterizer.h"
#include "flutter/shell/common/vsync_waiter_fallback.h"
#include "lib/ftl/functional/make_copyable.h"
#include "third_party/skia/include/gpu/GrContextOptions.h"
#include "third_party/skia/include/gpu/gl/GrGLInterface.h"

namespace shell {

PlatformView::PlatformView(std::unique_ptr<Rasterizer> rasterizer)
    : rasterizer_(std::move(rasterizer)),
      size_(SkISize::Make(0, 0)),
      weak_factory_(this) {}

PlatformView::~PlatformView() {
  blink::Threads::UI()->PostTask([] { Shell::Shared().PurgePlatformViews(); });

  Rasterizer* rasterizer = rasterizer_.release();
  blink::Threads::Gpu()->PostTask([rasterizer]() { delete rasterizer; });

  Engine* engine = engine_.release();
  blink::Threads::UI()->PostTask([engine]() { delete engine; });
}

void PlatformView::CreateEngine() {
  engine_.reset(new Engine(this));
}

// Add this to the shell's list of PlatformVIews.
// Subclasses should call this after the object is fully constructed.
void PlatformView::PostAddToShellTask() {
  blink::Threads::UI()->PostTask(
      [self = GetWeakPtr()] { Shell::Shared().AddPlatformView(self); });
}

void PlatformView::DispatchPlatformMessage(
    ftl::RefPtr<blink::PlatformMessage> message) {
  blink::Threads::UI()->PostTask(
      [ engine = engine_->GetWeakPtr(), message = std::move(message) ] {
        if (engine) {
          engine->DispatchPlatformMessage(message);
        }
      });
}

void PlatformView::DispatchSemanticsAction(int32_t id,
                                           blink::SemanticsAction action) {
  blink::Threads::UI()->PostTask(
      [ engine = engine_->GetWeakPtr(), id, action ] {
        if (engine) {
          engine->DispatchSemanticsAction(
              id, static_cast<blink::SemanticsAction>(action));
        }
      });
}

void PlatformView::SetSemanticsEnabled(bool enabled) {
  blink::Threads::UI()->PostTask([ engine = engine_->GetWeakPtr(), enabled ] {
    if (engine)
      engine->SetSemanticsEnabled(enabled);
  });
}

void PlatformView::NotifyCreated(std::unique_ptr<Surface> surface) {
  NotifyCreated(std::move(surface), []() {});
}

void PlatformView::NotifyCreated(std::unique_ptr<Surface> surface,
                                 ftl::Closure caller_continuation) {
  ftl::AutoResetWaitableEvent latch;

  auto ui_continuation = ftl::MakeCopyable([
    this,                          //
    surface = std::move(surface),  //
    caller_continuation,           //
    &latch
  ]() mutable {
    auto gpu_continuation = ftl::MakeCopyable([
      this,                          //
      surface = std::move(surface),  //
      caller_continuation,           //
      &latch
    ]() mutable {
      // Runs on the GPU Thread. So does the Caller Continuation.
      surface->Setup();
      rasterizer_->Setup(std::move(surface), caller_continuation, &latch);
    });
    // Runs on the UI Thread.
    engine_->OnOutputSurfaceCreated(std::move(gpu_continuation));
  });

  // Runs on the Platform Thread.
  blink::Threads::UI()->PostTask(std::move(ui_continuation));

  latch.Wait();
}

void PlatformView::NotifyDestroyed() {
  ftl::AutoResetWaitableEvent latch;

  auto engine_continuation = [this, &latch]() {
    rasterizer_->Teardown(&latch);
  };

  blink::Threads::UI()->PostTask([this, engine_continuation]() {
    engine_->OnOutputSurfaceDestroyed(engine_continuation);
  });

  latch.Wait();
}

ftl::WeakPtr<PlatformView> PlatformView::GetWeakPtr() {
  return weak_factory_.GetWeakPtr();
}

VsyncWaiter* PlatformView::GetVsyncWaiter() {
  if (!vsync_waiter_)
    vsync_waiter_ = std::make_unique<VsyncWaiterFallback>();
  return vsync_waiter_.get();
}

void PlatformView::UpdateSemantics(std::vector<blink::SemanticsNode> update) {}

void PlatformView::HandlePlatformMessage(
    ftl::RefPtr<blink::PlatformMessage> message) {
  if (auto response = message->response())
    response->CompleteEmpty();
}

void PlatformView::SetupResourceContextOnIOThread() {
  ftl::AutoResetWaitableEvent latch;

  blink::Threads::IO()->PostTask(
      [this, &latch]() { SetupResourceContextOnIOThreadPerform(&latch); });

  latch.Wait();
}

void PlatformView::SetupResourceContextOnIOThreadPerform(
    ftl::AutoResetWaitableEvent* latch) {
  if (blink::ResourceContext::Get() != nullptr) {
    // The resource context was already setup. This could happen if platforms
    // try to setup a context multiple times, or, if there are multiple platform
    // views. In any case, there is nothing else to do. So just signal the
    // latch.
    latch->Signal();
    return;
  }

  bool current = ResourceContextMakeCurrent();

  if (!current) {
    FTL_LOG(WARNING)
        << "WARNING: Could not setup an OpenGL context on the resource loader.";
    latch->Signal();
    return;
  }

  GrContextOptions options;
  // There is currently a bug with doing GPU YUV to RGB conversions on the IO
  // thread. The necessary work isn't being flushed or synchronized with the
  // other threads correctly, so the textures end up blank.  For now, suppress
  // that feature, which will cause texture uploads to do CPU YUV conversion.
  options.fDisableGpuYUVConversion = true;

  blink::ResourceContext::Set(GrContext::Create(
      GrBackend::kOpenGL_GrBackend,
      reinterpret_cast<GrBackendContext>(GrGLCreateNativeInterface()),
      options));

  // Do not cache textures created by the image decoder.  These textures should
  // be deleted when they are no longer referenced by an SkImage.
  if (blink::ResourceContext::Get())
    blink::ResourceContext::Get()->setResourceCacheLimits(0, 0);

  latch->Signal();
}

}  // namespace shell
<commit_msg>Only log about resource context setup failures on debug builds. (#3601)<commit_after>// Copyright 2015 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.

#include "flutter/shell/common/platform_view.h"

#include <utility>

#include "flutter/common/threads.h"
#include "flutter/lib/ui/painting/resource_context.h"
#include "flutter/shell/common/rasterizer.h"
#include "flutter/shell/common/vsync_waiter_fallback.h"
#include "lib/ftl/functional/make_copyable.h"
#include "third_party/skia/include/gpu/GrContextOptions.h"
#include "third_party/skia/include/gpu/gl/GrGLInterface.h"

namespace shell {

PlatformView::PlatformView(std::unique_ptr<Rasterizer> rasterizer)
    : rasterizer_(std::move(rasterizer)),
      size_(SkISize::Make(0, 0)),
      weak_factory_(this) {}

PlatformView::~PlatformView() {
  blink::Threads::UI()->PostTask([] { Shell::Shared().PurgePlatformViews(); });

  Rasterizer* rasterizer = rasterizer_.release();
  blink::Threads::Gpu()->PostTask([rasterizer]() { delete rasterizer; });

  Engine* engine = engine_.release();
  blink::Threads::UI()->PostTask([engine]() { delete engine; });
}

void PlatformView::CreateEngine() {
  engine_.reset(new Engine(this));
}

// Add this to the shell's list of PlatformVIews.
// Subclasses should call this after the object is fully constructed.
void PlatformView::PostAddToShellTask() {
  blink::Threads::UI()->PostTask(
      [self = GetWeakPtr()] { Shell::Shared().AddPlatformView(self); });
}

void PlatformView::DispatchPlatformMessage(
    ftl::RefPtr<blink::PlatformMessage> message) {
  blink::Threads::UI()->PostTask(
      [ engine = engine_->GetWeakPtr(), message = std::move(message) ] {
        if (engine) {
          engine->DispatchPlatformMessage(message);
        }
      });
}

void PlatformView::DispatchSemanticsAction(int32_t id,
                                           blink::SemanticsAction action) {
  blink::Threads::UI()->PostTask(
      [ engine = engine_->GetWeakPtr(), id, action ] {
        if (engine) {
          engine->DispatchSemanticsAction(
              id, static_cast<blink::SemanticsAction>(action));
        }
      });
}

void PlatformView::SetSemanticsEnabled(bool enabled) {
  blink::Threads::UI()->PostTask([ engine = engine_->GetWeakPtr(), enabled ] {
    if (engine)
      engine->SetSemanticsEnabled(enabled);
  });
}

void PlatformView::NotifyCreated(std::unique_ptr<Surface> surface) {
  NotifyCreated(std::move(surface), []() {});
}

void PlatformView::NotifyCreated(std::unique_ptr<Surface> surface,
                                 ftl::Closure caller_continuation) {
  ftl::AutoResetWaitableEvent latch;

  auto ui_continuation = ftl::MakeCopyable([
    this,                          //
    surface = std::move(surface),  //
    caller_continuation,           //
    &latch
  ]() mutable {
    auto gpu_continuation = ftl::MakeCopyable([
      this,                          //
      surface = std::move(surface),  //
      caller_continuation,           //
      &latch
    ]() mutable {
      // Runs on the GPU Thread. So does the Caller Continuation.
      surface->Setup();
      rasterizer_->Setup(std::move(surface), caller_continuation, &latch);
    });
    // Runs on the UI Thread.
    engine_->OnOutputSurfaceCreated(std::move(gpu_continuation));
  });

  // Runs on the Platform Thread.
  blink::Threads::UI()->PostTask(std::move(ui_continuation));

  latch.Wait();
}

void PlatformView::NotifyDestroyed() {
  ftl::AutoResetWaitableEvent latch;

  auto engine_continuation = [this, &latch]() {
    rasterizer_->Teardown(&latch);
  };

  blink::Threads::UI()->PostTask([this, engine_continuation]() {
    engine_->OnOutputSurfaceDestroyed(engine_continuation);
  });

  latch.Wait();
}

ftl::WeakPtr<PlatformView> PlatformView::GetWeakPtr() {
  return weak_factory_.GetWeakPtr();
}

VsyncWaiter* PlatformView::GetVsyncWaiter() {
  if (!vsync_waiter_)
    vsync_waiter_ = std::make_unique<VsyncWaiterFallback>();
  return vsync_waiter_.get();
}

void PlatformView::UpdateSemantics(std::vector<blink::SemanticsNode> update) {}

void PlatformView::HandlePlatformMessage(
    ftl::RefPtr<blink::PlatformMessage> message) {
  if (auto response = message->response())
    response->CompleteEmpty();
}

void PlatformView::SetupResourceContextOnIOThread() {
  ftl::AutoResetWaitableEvent latch;

  blink::Threads::IO()->PostTask(
      [this, &latch]() { SetupResourceContextOnIOThreadPerform(&latch); });

  latch.Wait();
}

void PlatformView::SetupResourceContextOnIOThreadPerform(
    ftl::AutoResetWaitableEvent* latch) {
  if (blink::ResourceContext::Get() != nullptr) {
    // The resource context was already setup. This could happen if platforms
    // try to setup a context multiple times, or, if there are multiple platform
    // views. In any case, there is nothing else to do. So just signal the
    // latch.
    latch->Signal();
    return;
  }

  bool current = ResourceContextMakeCurrent();

  if (!current) {
    FTL_DLOG(WARNING)
        << "WARNING: Could not setup a context on the resource loader.";
    latch->Signal();
    return;
  }

  GrContextOptions options;
  // There is currently a bug with doing GPU YUV to RGB conversions on the IO
  // thread. The necessary work isn't being flushed or synchronized with the
  // other threads correctly, so the textures end up blank.  For now, suppress
  // that feature, which will cause texture uploads to do CPU YUV conversion.
  options.fDisableGpuYUVConversion = true;

  blink::ResourceContext::Set(GrContext::Create(
      GrBackend::kOpenGL_GrBackend,
      reinterpret_cast<GrBackendContext>(GrGLCreateNativeInterface()),
      options));

  // Do not cache textures created by the image decoder.  These textures should
  // be deleted when they are no longer referenced by an SkImage.
  if (blink::ResourceContext::Get())
    blink::ResourceContext::Get()->setResourceCacheLimits(0, 0);

  latch->Signal();
}

}  // namespace shell
<|endoftext|>


<commit_before><commit_msg>Add some more temporary hardcoded library mappings for DISABLE_DYNLOADING<commit_after><|endoftext|>


<commit_before>// Copyright (c) 2010, Lawrence Livermore National Security, LLC. Produced at
// the Lawrence Livermore National Laboratory. LLNL-CODE-443211. All Rights
// reserved. See file COPYRIGHT for details.
//
// This file is part of the MFEM library. For more information and source code
// availability see http://mfem.org.
//
// MFEM is free software; you can redistribute it and/or modify it under the
// terms of the GNU Lesser General Public License (as published by the Free
// Software Foundation) version 2.1 dated February 1999.

#ifndef MFEM_MM
#define MFEM_MM

#include <list>
#include <cstddef> // for size_t
#include <unordered_map>

using std::size_t;

#include "occa.hpp" // for OccaMemory

namespace mfem
{

// *****************************************************************************
// * Memory Manager Singleton
// *****************************************************************************
class mm
{
public:
   // **************************************************************************
   struct alias;

   // TODO: Change this to ptr
   struct memory
   {
      const size_t bytes;
      void *const h_ptr;
      void *d_ptr;
      OccaMemory o_ptr;
      std::list<const alias *> aliases;
      bool host;
      bool padding[7];
      memory(void* const h, const size_t b):
         bytes(b), h_ptr(h), d_ptr(nullptr), aliases(), host(true) {}
   };

   struct alias
   {
      memory *const mem;
      const long offset;
   };

   // **************************************************************************
   typedef std::unordered_map<const void*, memory> memory_map;
   typedef std::unordered_map<const void*, const alias*> alias_map;

   struct ledger
   {
      memory_map memories;
      alias_map aliases;
   };

   // **************************************************************************
   // * Main malloc template function
   // * Allocates n*size bytes and returns a pointer to the allocated memory
   // **************************************************************************
   template<class T>
   static inline T* malloc(const size_t n, const size_t size = sizeof(T))
   { return static_cast<T*>(MM().Insert(::new T[n], n*size)); }

   // **************************************************************************
   // * Frees the memory space pointed to by ptr, which must have been
   // * returned by a previous call to mm::malloc
   // **************************************************************************
   template<class T>
   static inline void free(void *ptr)
   {
      if (!ptr) { return; }
      ::delete[] static_cast<T*>(ptr);
      mm::MM().Erase(ptr);
   }

   // **************************************************************************
   // * Translates ptr to host or device address,
   // * depending on config::Cuda() and the ptr' state
   // **************************************************************************
   static inline void *ptr(void *a) { return MM().Ptr(a); }
   static inline const void* ptr(const void *a) { return MM().Ptr(a); }
   static inline OccaMemory occaPtr(const void *a) { return MM().Memory(a); }

   // **************************************************************************
   static inline void push(const void *ptr, const size_t bytes = 0)
   {
      return MM().Push(ptr, bytes);
   }

   // **************************************************************************
   static inline void pull(const void *ptr, const size_t bytes = 0)
   {
      return MM().Pull(ptr, bytes);
   }

   // **************************************************************************
   static void* memcpy(void *dst, const void *src,
                       size_t bytes, const bool async = false);

   // **************************************************************************
   static inline bool known(const void *a)
   {
      return MM().Known(a);
   }

private:
   ledger maps;
   mm() {}
   mm(mm const&) = delete;
   void operator=(mm const&) = delete;
   static inline mm& MM() { static mm *singleton = new mm(); return *singleton; }

   // **************************************************************************
   void *Insert(void *ptr, const size_t bytes);
   void *Erase(void *ptr);
   void *Ptr(void *ptr);
   const void *Ptr(const void *ptr);
   bool Known(const void *ptr);
   bool Alias(const void *ptr);
   OccaMemory Memory(const void *ptr);

   // **************************************************************************
   void Push(const void *ptr, const size_t bytes = 0);
   void Pull(const void *ptr, const size_t bytes = 0);

public:
  static inline void PrintPtrs(void)
  {
    for( const auto& n : MM().maps.memories ) {
      printf("key %p, host %p, device %p \n", n.first, n.second.h_ptr, n.second.d_ptr);
    }
  }

  static inline void PullAll(void){
    for( const auto& n : MM().maps.memories ) {
      MM().Pull(n.first,n.second.bytes);
    }
  }

  static inline void PushAll(void){
    for( const auto& n : MM().maps.memories ) {
      MM().Push(n.first,n.second.bytes);
    }
  }

};

} // namespace mfem

#endif
<commit_msg>PullAll->GetAll<commit_after>// Copyright (c) 2010, Lawrence Livermore National Security, LLC. Produced at
// the Lawrence Livermore National Laboratory. LLNL-CODE-443211. All Rights
// reserved. See file COPYRIGHT for details.
//
// This file is part of the MFEM library. For more information and source code
// availability see http://mfem.org.
//
// MFEM is free software; you can redistribute it and/or modify it under the
// terms of the GNU Lesser General Public License (as published by the Free
// Software Foundation) version 2.1 dated February 1999.

#ifndef MFEM_MM
#define MFEM_MM

#include <list>
#include <cstddef> // for size_t
#include <unordered_map>

using std::size_t;

#include "occa.hpp" // for OccaMemory

namespace mfem
{

// *****************************************************************************
// * Memory Manager Singleton
// *****************************************************************************
class mm
{
public:
   // **************************************************************************
   struct alias;

   // TODO: Change this to ptr
   struct memory
   {
      const size_t bytes;
      void *const h_ptr;
      void *d_ptr;
      OccaMemory o_ptr;
      std::list<const alias *> aliases;
      bool host;
      bool padding[7];
      memory(void* const h, const size_t b):
         bytes(b), h_ptr(h), d_ptr(nullptr), aliases(), host(true) {}
   };

   struct alias
   {
      memory *const mem;
      const long offset;
   };

   // **************************************************************************
   typedef std::unordered_map<const void*, memory> memory_map;
   typedef std::unordered_map<const void*, const alias*> alias_map;

   struct ledger
   {
      memory_map memories;
      alias_map aliases;
   };

   // **************************************************************************
   // * Main malloc template function
   // * Allocates n*size bytes and returns a pointer to the allocated memory
   // **************************************************************************
   template<class T>
   static inline T* malloc(const size_t n, const size_t size = sizeof(T))
   { return static_cast<T*>(MM().Insert(::new T[n], n*size)); }

   // **************************************************************************
   // * Frees the memory space pointed to by ptr, which must have been
   // * returned by a previous call to mm::malloc
   // **************************************************************************
   template<class T>
   static inline void free(void *ptr)
   {
      if (!ptr) { return; }
      ::delete[] static_cast<T*>(ptr);
      mm::MM().Erase(ptr);
   }

   // **************************************************************************
   // * Translates ptr to host or device address,
   // * depending on config::Cuda() and the ptr' state
   // **************************************************************************
   static inline void *ptr(void *a) { return MM().Ptr(a); }
   static inline const void* ptr(const void *a) { return MM().Ptr(a); }
   static inline OccaMemory occaPtr(const void *a) { return MM().Memory(a); }

   // **************************************************************************
   static inline void push(const void *ptr, const size_t bytes = 0)
   {
      return MM().Push(ptr, bytes);
   }

   // **************************************************************************
   static inline void pull(const void *ptr, const size_t bytes = 0)
   {
      return MM().Pull(ptr, bytes);
   }

   // **************************************************************************
   static void* memcpy(void *dst, const void *src,
                       size_t bytes, const bool async = false);

   // **************************************************************************
   static inline bool known(const void *a)
   {
      return MM().Known(a);
   }

private:
   ledger maps;
   mm() {}
   mm(mm const&) = delete;
   void operator=(mm const&) = delete;
   static inline mm& MM() { static mm *singleton = new mm(); return *singleton; }

   // **************************************************************************
   void *Insert(void *ptr, const size_t bytes);
   void *Erase(void *ptr);
   void *Ptr(void *ptr);
   const void *Ptr(const void *ptr);
   bool Known(const void *ptr);
   bool Alias(const void *ptr);
   OccaMemory Memory(const void *ptr);

   // **************************************************************************
   void Push(const void *ptr, const size_t bytes = 0);
   void Pull(const void *ptr, const size_t bytes = 0);

public:
   static inline void PrintPtrs(void)
   {
      for( const auto& n : MM().maps.memories ) {
       printf("key %p, host %p, device %p \n", n.first, n.second.h_ptr, n.second.d_ptr);
      }
   }

   static inline void GetAll(void)
   {
      for( const auto& n : MM().maps.memories ) {
         const void *ptr = n.first;
           mm::ptr(ptr);
      }
   }

};

} // namespace mfem

#endif
<|endoftext|>


<commit_before>#include "Compute.h"
#include "VideoSource.h"
#include <iostream>
#include <opencv2/imgproc.hpp>

#define countof(v) (sizeof v / sizeof v[0])

static int redChannel   = 2;
static int greenChannel = 1;
static int blueChannel  = 0;
static int grayChannels = -1;
static int blueHue      = -2;

void Compute::BackgroundLoop() {
    const int    HoughThreshold = cap->imageWidth * cap->imageHeight / 6500;
    const double HoughMinLineLength = cap->imageHeight / 4.;
    const double HoughMaxGap = cap->imageHeight / 50.;
    const double HoughRho = 2.;

#if 0
    const double CannyThreshold1 =  50.;
    const double CannyThreshold2 = 100.;
    const double HoughTheta = 0.05;
    const int colorChannels = blueHue;
#else
    const double CannyThreshold1 = 100.;
    const double CannyThreshold2 = 200.;
    const double HoughTheta = 0.02;
    const int colorChannels = grayChannels;
#endif

    cv::Mat gray(cap->imageHeight, cap->imageWidth, CV_8UC1), whiteLines;

    while (! cap->imagesCaptured.quitting) {
        cv::Mat inp(cap->imagesCaptured.Dequeue());
        if (! inp.empty()) {

            if (colorChannels == grayChannels) {
                cv::cvtColor(inp, gray, cv::COLOR_BGR2GRAY);
            } else if (colorChannels == blueHue) {
                cv::cvtColor(inp, inp, cv::COLOR_BGR2HSV_FULL);
                cv::inRange(inp, cv::Scalar(124, 100, 80), cv::Scalar(174, 255, 255), gray);
                cv::GaussianBlur(gray, gray, cv::Size(5.,5.), 0.);
            } else {
                const int colorFromTo[] = {colorChannels,0};
                cv::mixChannels(&inp, 1, &gray, 1, colorFromTo, countof(colorFromTo)/2);
            }

            cv::Canny(gray, whiteLines, CannyThreshold1, CannyThreshold2);

            OutputData out(cap->imageWidth, cap->imageHeight);
            cv::HoughLinesP(whiteLines, out.lines, HoughRho, HoughTheta, HoughThreshold, HoughMinLineLength, HoughMaxGap);

            static const int grayTo3Ch[] = {0,0, 0,1, 0,2};
            cv::mixChannels(&whiteLines, 1, &out.image, 1, grayTo3Ch, countof(grayTo3Ch)/2);
            SwapOutputData(out);
        }
    }
}

static void* ComputeThread(void* compute) {
    ((Compute*)compute)->BackgroundLoop();
    return 0;
}

void Compute::Start() {
    pthread_create(&thread, NULL, ComputeThread, this);
}

void Compute::Stop() {
    cap->imagesCaptured.Quit();
    pthread_join(thread, NULL);
}

Compute::Compute(VideoSource* c): cap(c) {
    pthread_mutex_init(&dataMutex, NULL);
}

Compute::~Compute() {
    pthread_mutex_destroy(&dataMutex);
}

void Compute::SwapOutputData(OutputData& data) {
    OutputData x = data;

    pthread_mutex_lock(&dataMutex);
    data = outputData;
    outputData = x;
    pthread_mutex_unlock(&dataMutex);
}
<commit_msg>tweaks: still not very good<commit_after>#include "Compute.h"
#include "VideoSource.h"
#include <iostream>
#include <opencv2/imgproc.hpp>

#define countof(v) (sizeof v / sizeof v[0])

static int redChannel   = 2;
static int greenChannel = 1;
static int blueChannel  = 0;
static int grayChannels = -1;
static int blueHue      = -2;

void Compute::BackgroundLoop() {
    const int    HoughThreshold = cap->imageWidth * cap->imageHeight / 6500;
    const double HoughMinLineLength = cap->imageHeight / 4.;
    const double HoughMaxGap = cap->imageHeight / 50.;
    const double HoughRho = 2.;

#if 0
    const double CannyThreshold1 =  50.;
    const double CannyThreshold2 = 100.;
    const double HoughTheta = 0.05;
    const int colorChannels = blueHue;
#else
    const double CannyThreshold1 = 100.;
    const double CannyThreshold2 = 200.;
    const double HoughTheta = 0.02;
    const int colorChannels = grayChannels;
#endif

    cv::Mat gray(cap->imageHeight, cap->imageWidth, CV_8UC1), whiteLines;

    while (! cap->imagesCaptured.quitting) {
        cv::Mat inp(cap->imagesCaptured.Dequeue());
        if (! inp.empty()) {

            if (colorChannels == grayChannels) {
                cv::cvtColor(inp, gray, cv::COLOR_BGR2GRAY);
            } else if (colorChannels == blueHue) {
                cv::cvtColor(inp, inp, cv::COLOR_BGR2HSV_FULL);
                cv::inRange(inp, cv::Scalar(124, 50, 50), cv::Scalar(174, 255, 255), gray);
                cv::GaussianBlur(gray, gray, cv::Size(5.,5.), 50.);
            } else {
                const int colorFromTo[] = {colorChannels,0};
                cv::mixChannels(&inp, 1, &gray, 1, colorFromTo, countof(colorFromTo)/2);
            }

            cv::Canny(gray, whiteLines, CannyThreshold1, CannyThreshold2);

            OutputData out(cap->imageWidth, cap->imageHeight);
            cv::HoughLinesP(whiteLines, out.lines, HoughRho, HoughTheta, HoughThreshold, HoughMinLineLength, HoughMaxGap);

            static const int grayTo3Ch[] = {0,0, 0,1, 0,2};
            cv::mixChannels(&whiteLines, 1, &out.image, 1, grayTo3Ch, countof(grayTo3Ch)/2);
            SwapOutputData(out);
        }
    }
}

static void* ComputeThread(void* compute) {
    ((Compute*)compute)->BackgroundLoop();
    return 0;
}

void Compute::Start() {
    pthread_create(&thread, NULL, ComputeThread, this);
}

void Compute::Stop() {
    cap->imagesCaptured.Quit();
    pthread_join(thread, NULL);
}

Compute::Compute(VideoSource* c): cap(c) {
    pthread_mutex_init(&dataMutex, NULL);
}

Compute::~Compute() {
    pthread_mutex_destroy(&dataMutex);
}

void Compute::SwapOutputData(OutputData& data) {
    OutputData x = data;

    pthread_mutex_lock(&dataMutex);
    data = outputData;
    outputData = x;
    pthread_mutex_unlock(&dataMutex);
}
<|endoftext|>