<commit_before>#include "DeviceManager.hpp"
#include "OpenCLManager.hpp"
#include "Exception.hpp"
#include "SimpleWindow.hpp"
#include <QApplication>

#if defined(__APPLE__) || defined(__MACOSX)
#include <OpenCL/cl_gl.h>
#include <OpenGL/OpenGL.h>
#else
#if _WIN32
#include <GL/gl.h>
#include <CL/cl_gl.h>
#else
#include <GL/glx.h>
#include <CL/cl_gl.h>
#endif
#endif

using namespace fast;

DeviceManager& DeviceManager::getInstance() {
    static DeviceManager instance;
    return instance;
}

std::vector<OpenCLDevice::pointer> getDevices(oul::DeviceCriteria criteria, bool enableVisualization) {
    unsigned long * glContext = NULL;
    QGLWidget* widget = NULL;
    if(enableVisualization) {
        // TODO: this can be simplified to just use the QGLContext class instead
        // Create GL context
	std::cout << "trying to create a MAC os X GL context" << std::endl;
    // Make sure only one QApplication is created
    SimpleWindow::initializeQtApp();

    SimpleWindow::mGLContext->makeCurrent();
#if defined(__APPLE__) || defined(__MACOSX)
    CGLContextObj appleContext = CGLGetCurrentContext();
    std::cout << "Initial GL context: " << CGLGetCurrentContext() << std::endl;
    std::cout << "Initial GL share group: " << CGLGetShareGroup(CGLGetCurrentContext()) << std::endl;

    glContext = (unsigned long *)appleContext;
#else
#if _WIN32

		std::cout << "created a drawable" << std::endl;
		HDC    hdc = wglGetCurrentDC();
		std::cout << "HDC in DeviceManager is: " << hdc << std::endl;

        // create a rendering context
        hglrc = wglCreateContext (hdc);
		std::cout << "GL context in DeviceManager is: " << hglrc << std::endl;
        glContext = (unsigned long *)hglrc;

        // make it the calling thread's current rendering context
        bool success = wglMakeCurrent (hdc, hglrc);
		if(!success)
			throw Exception("Failed to set initial windows GL context");
#else
        glContext = (long unsigned int*)glXGetCurrentContext();
        std::cout << "created GLX context " << glContext << std::endl;
#endif
#endif
        criteria.setCapabilityCriteria(oul::DEVICE_CAPABILITY_OPENGL_INTEROP);
    }
    oul::OpenCLManager * manager = oul::OpenCLManager::getInstance();
    std::vector<oul::PlatformDevices> platformDevices = manager->getDevices(criteria);

    std::vector<OpenCLDevice::pointer> executionDevices;
    for(unsigned int i = 0; i < platformDevices.size(); i++) {
    for(unsigned int j = 0; j < platformDevices[i].second.size(); j++) {
        std::vector<cl::Device> deviceVector;
        deviceVector.push_back(platformDevices[i].second[j]);
        OpenCLDevice * device = new OpenCLDevice(deviceVector, glContext);
        executionDevices.push_back(OpenCLDevice::pointer(device));
    }}

    // Cleanup widget, widget has to be alive when creating device
    delete widget;

    return executionDevices;
}

std::vector<OpenCLDevice::pointer> DeviceManager::getAllDevices(
        bool enableVisualization) {

    oul::DeviceCriteria criteria;
    return getDevices(criteria,enableVisualization);
}

std::vector<OpenCLDevice::pointer> DeviceManager::getAllGPUDevices(
        bool enableVisualization) {
    oul::DeviceCriteria criteria;
    criteria.setTypeCriteria(oul::DEVICE_TYPE_GPU);
    return getDevices(criteria,enableVisualization);
}

std::vector<OpenCLDevice::pointer> DeviceManager::getAllCPUDevices(
        bool enableVisualization) {
    oul::DeviceCriteria criteria;
    criteria.setTypeCriteria(oul::DEVICE_TYPE_CPU);
    return getDevices(criteria,enableVisualization);
}

OpenCLDevice::pointer DeviceManager::getOneGPUDevice(
        bool enableVisualization) {

    oul::DeviceCriteria criteria;
    criteria.setTypeCriteria(oul::DEVICE_TYPE_GPU);
    criteria.setDeviceCountCriteria(1);
    std::vector<OpenCLDevice::pointer> devices = getDevices(criteria,enableVisualization);
	if(devices.size() == 0)
		throw Exception("No compatible OpenCL devices found");
    return devices[0];
}

OpenCLDevice::pointer DeviceManager::getOneOpenCLDevice(
        bool enableVisualization) {

    oul::DeviceCriteria criteria;

    // Check if a GPU is available first, if not choose any
    criteria.setTypeCriteria(oul::DEVICE_TYPE_GPU);
    criteria.setDeviceCountCriteria(1);
    std::vector<OpenCLDevice::pointer> devices = getDevices(criteria,enableVisualization);
    if(devices.size() > 0) {
        return devices[0];
    } else {
        criteria.setTypeCriteria(oul::DEVICE_TYPE_ANY);
        std::vector<OpenCLDevice::pointer> devices = getDevices(criteria,enableVisualization);
		if(devices.size() == 0)
			throw Exception("No compatible OpenCL devices found");
        return devices[0];
    }
}

OpenCLDevice::pointer DeviceManager::getOneCPUDevice(
        bool enableVisualization) {
    oul::DeviceCriteria criteria;
    criteria.setTypeCriteria(oul::DEVICE_TYPE_CPU);
    criteria.setDeviceCountCriteria(1);
    std::vector<OpenCLDevice::pointer> devices = getDevices(criteria,enableVisualization);
	if(devices.size() == 0)
		throw Exception("No compatible OpenCL devices found");
    return devices[0];
}

Host::pointer DeviceManager::getHostDevice() {
    return Host::getInstance();
}

void DeviceManager::setDefaultDevice(ExecutionDevice::pointer device) {
    mDefaultComputationDevice = device;
    mDefaultVisualizationDevice = device;
}

void DeviceManager::setDefaultComputationDevice(
        ExecutionDevice::pointer device) {
    mDefaultComputationDevice = device;
}

void DeviceManager::setDefaultVisualizationDevice(
        ExecutionDevice::pointer device) {
    mDefaultVisualizationDevice = device;
}

ExecutionDevice::pointer DeviceManager::getDefaultComputationDevice() {
    return mDefaultComputationDevice;
}

ExecutionDevice::pointer DeviceManager::getDefaultVisualizationDevice() {
    return mDefaultVisualizationDevice;
}

DeviceManager::DeviceManager() {
    // Set one random device as default device
    setDefaultDevice(getOneOpenCLDevice(true));
}

OpenCLDevice::pointer DeviceManager::getDevice(
        DeviceCriteria criteria) const {
    bool interop = false;
    if(criteria.hasCapabilityCriteria(DEVICE_CAPABILITY_OPENGL_INTEROP)) {
        interop = true;
    }
    criteria.setDeviceCountCriteria(1);
    std::vector<OpenCLDevice::pointer> devices = getDevices(criteria, interop);
    if(devices.size() == 0)
        throw Exception("Found no devices which satisfies the device criteria");
    return devices[0];
}

bool DeviceManager::deviceSatisfiesCriteria(OpenCLDevice::pointer device,
        const DeviceCriteria& criteria) const {
    oul::OpenCLManager * manager = oul::OpenCLManager::getInstance();
    return manager->deviceSatisfiesCriteria(criteria, device->getDevice());
}
<commit_msg>Fixed a bug on windows, works now<commit_after>#include "DeviceManager.hpp"
#include "OpenCLManager.hpp"
#include "Exception.hpp"
#include "SimpleWindow.hpp"
#include <QApplication>

#if defined(__APPLE__) || defined(__MACOSX)
#include <OpenCL/cl_gl.h>
#include <OpenGL/OpenGL.h>
#else
#if _WIN32
#include <GL/gl.h>
#include <CL/cl_gl.h>
#else
#include <GL/glx.h>
#include <CL/cl_gl.h>
#endif
#endif

using namespace fast;

DeviceManager& DeviceManager::getInstance() {
    static DeviceManager instance;
    return instance;
}

std::vector<OpenCLDevice::pointer> getDevices(oul::DeviceCriteria criteria, bool enableVisualization) {
    unsigned long * glContext = NULL;
    QGLWidget* widget = NULL;
    if(enableVisualization) {
        // Create GL context

		// Make sure only one QApplication is created
		SimpleWindow::initializeQtApp();

		SimpleWindow::mGLContext->makeCurrent();
#if defined(__APPLE__) || defined(__MACOSX)
		CGLContextObj appleContext = CGLGetCurrentContext();
		std::cout << "Initial GL context: " << CGLGetCurrentContext() << std::endl;
		std::cout << "Initial GL share group: " << CGLGetShareGroup(CGLGetCurrentContext()) << std::endl;

		glContext = (unsigned long *)appleContext;
#elif _WIN32
        glContext = (unsigned long *)wglGetCurrentContext();
		std::cout << "Initial W GL context " << glContext << std::endl;
#else
        glContext = (long unsigned int*)glXGetCurrentContext();
        std::cout << "Initial GLX context " << glContext << std::endl;
#endif
        criteria.setCapabilityCriteria(oul::DEVICE_CAPABILITY_OPENGL_INTEROP);
    }
    oul::OpenCLManager * manager = oul::OpenCLManager::getInstance();
    std::vector<oul::PlatformDevices> platformDevices = manager->getDevices(criteria);

    std::vector<OpenCLDevice::pointer> executionDevices;
    for(unsigned int i = 0; i < platformDevices.size(); i++) {
    for(unsigned int j = 0; j < platformDevices[i].second.size(); j++) {
        std::vector<cl::Device> deviceVector;
        deviceVector.push_back(platformDevices[i].second[j]);
        OpenCLDevice * device = new OpenCLDevice(deviceVector, glContext);
        executionDevices.push_back(OpenCLDevice::pointer(device));
    }}

    // Cleanup widget, widget has to be alive when creating device
    delete widget;

    return executionDevices;
}

std::vector<OpenCLDevice::pointer> DeviceManager::getAllDevices(
        bool enableVisualization) {

    oul::DeviceCriteria criteria;
    return getDevices(criteria,enableVisualization);
}

std::vector<OpenCLDevice::pointer> DeviceManager::getAllGPUDevices(
        bool enableVisualization) {
    oul::DeviceCriteria criteria;
    criteria.setTypeCriteria(oul::DEVICE_TYPE_GPU);
    return getDevices(criteria,enableVisualization);
}

std::vector<OpenCLDevice::pointer> DeviceManager::getAllCPUDevices(
        bool enableVisualization) {
    oul::DeviceCriteria criteria;
    criteria.setTypeCriteria(oul::DEVICE_TYPE_CPU);
    return getDevices(criteria,enableVisualization);
}

OpenCLDevice::pointer DeviceManager::getOneGPUDevice(
        bool enableVisualization) {

    oul::DeviceCriteria criteria;
    criteria.setTypeCriteria(oul::DEVICE_TYPE_GPU);
    criteria.setDeviceCountCriteria(1);
    std::vector<OpenCLDevice::pointer> devices = getDevices(criteria,enableVisualization);
	if(devices.size() == 0)
		throw Exception("No compatible OpenCL devices found");
    return devices[0];
}

OpenCLDevice::pointer DeviceManager::getOneOpenCLDevice(
        bool enableVisualization) {

    oul::DeviceCriteria criteria;

    // Check if a GPU is available first, if not choose any
    criteria.setTypeCriteria(oul::DEVICE_TYPE_GPU);
    criteria.setDeviceCountCriteria(1);
    std::vector<OpenCLDevice::pointer> devices = getDevices(criteria,enableVisualization);
    if(devices.size() > 0) {
        return devices[0];
    } else {
        criteria.setTypeCriteria(oul::DEVICE_TYPE_ANY);
        std::vector<OpenCLDevice::pointer> devices = getDevices(criteria,enableVisualization);
		if(devices.size() == 0)
			throw Exception("No compatible OpenCL devices found");
        return devices[0];
    }
}

OpenCLDevice::pointer DeviceManager::getOneCPUDevice(
        bool enableVisualization) {
    oul::DeviceCriteria criteria;
    criteria.setTypeCriteria(oul::DEVICE_TYPE_CPU);
    criteria.setDeviceCountCriteria(1);
    std::vector<OpenCLDevice::pointer> devices = getDevices(criteria,enableVisualization);
	if(devices.size() == 0)
		throw Exception("No compatible OpenCL devices found");
    return devices[0];
}

Host::pointer DeviceManager::getHostDevice() {
    return Host::getInstance();
}

void DeviceManager::setDefaultDevice(ExecutionDevice::pointer device) {
    mDefaultComputationDevice = device;
    mDefaultVisualizationDevice = device;
}

void DeviceManager::setDefaultComputationDevice(
        ExecutionDevice::pointer device) {
    mDefaultComputationDevice = device;
}

void DeviceManager::setDefaultVisualizationDevice(
        ExecutionDevice::pointer device) {
    mDefaultVisualizationDevice = device;
}

ExecutionDevice::pointer DeviceManager::getDefaultComputationDevice() {
    return mDefaultComputationDevice;
}

ExecutionDevice::pointer DeviceManager::getDefaultVisualizationDevice() {
    return mDefaultVisualizationDevice;
}

DeviceManager::DeviceManager() {
    // Set one random device as default device
    setDefaultDevice(getOneOpenCLDevice(true));
}

OpenCLDevice::pointer DeviceManager::getDevice(
        DeviceCriteria criteria) const {
    bool interop = false;
    if(criteria.hasCapabilityCriteria(DEVICE_CAPABILITY_OPENGL_INTEROP)) {
        interop = true;
    }
    criteria.setDeviceCountCriteria(1);
    std::vector<OpenCLDevice::pointer> devices = getDevices(criteria, interop);
    if(devices.size() == 0)
        throw Exception("Found no devices which satisfies the device criteria");
    return devices[0];
}

bool DeviceManager::deviceSatisfiesCriteria(OpenCLDevice::pointer device,
        const DeviceCriteria& criteria) const {
    oul::OpenCLManager * manager = oul::OpenCLManager::getInstance();
    return manager->deviceSatisfiesCriteria(criteria, device->getDevice());
}
<|endoftext|>


<commit_before>#include "inner_bc.hpp"
#include "source/newtonian/two_dimensional/simple_flux_calculator.hpp"

namespace {
  double calc_tracer_flux(const Edge& edge,
			  const Tessellation& tess,
			  const vector<ComputationalCell>& cells,
			  const string& name,
			  const Conserved& hf)
  {
    if(hf.Mass>0 &&
       edge.neighbors.first>0 &&
       edge.neighbors.first<tess.GetPointNo()){
      assert(cells.at(static_cast<size_t>(edge.neighbors.first)).tracers.count(name)==1);
      return hf.Mass*
	cells.at(static_cast<size_t>(edge.neighbors.first)).tracers.find(name)->second;
    }
    if(hf.Mass<0 &&
       edge.neighbors.second>0 &&
       edge.neighbors.second<tess.GetPointNo()){
      assert(cells.at(static_cast<size_t>(edge.neighbors.second)).tracers.count(name)==1);
      return hf.Mass*
	cells.at(static_cast<size_t>(edge.neighbors.second)).tracers.find(name)->second;
    }
    return 0;
  }
}

InnerBC::InnerBC(const RiemannSolver& rs,
		 const string& ghost,
		 const double radius):
  rs_(rs), ghost_(ghost), radius_(radius) {}

vector<Extensive> InnerBC::operator()
  (const Tessellation& tess,
   const vector<Vector2D>& point_velocities,
   const vector<ComputationalCell>& cells,
   const vector<Extensive>& /*extensives*/,
   const EquationOfState& eos,
   const double /*time*/,
   const double /*dt*/) const
{
  vector<Extensive> res(tess.getAllEdges().size());
  for(size_t i=0;i<tess.getAllEdges().size();++i){
    const Conserved hydro_flux =
      calcHydroFlux(tess,point_velocities,
		    cells, eos, i);
    res.at(i).mass = hydro_flux.Mass;
    res.at(i).momentum = hydro_flux.Momentum;
    res.at(i).energy = hydro_flux.Energy;
    for(map<string,double>::const_iterator it =
	  cells.front().tracers.begin();
	it!=cells.front().tracers.end();
	++it)
      res.at(i).tracers[it->first] =
	calc_tracer_flux(tess.getAllEdges().at(i),
			 tess,cells,it->first,hydro_flux);
  }
  return res;
}

namespace {

  Primitive boost(const Primitive& origin,
		  const Vector2D& v)
  {
    Primitive res = origin;
    res.Velocity += v;
    return res;
  }

  Conserved support_riemann(const RiemannSolver& rs,
			    const Vector2D& rmp,
			    const Edge& edge,
			    const Primitive& cell,
			    const Vector2D& support,
			    bool left_real)
  {
    const Vector2D& p = Parallel(edge);
    Conserved res = left_real ?
      rotate_solve_rotate_back
      (rs,
       cell,
       boost(reflect(cell,p),support),
       0,
       remove_parallel_component
       (edge.vertices.second-rmp,p),
       p) :
      rotate_solve_rotate_back
      (rs,
       boost(reflect(cell,p),support),
       cell,
       0,
       remove_parallel_component
       (rmp-edge.vertices.second,p),
       p);
    res.Mass = 0;
    res.Energy = 0;
    return res;
  }
}

const Conserved InnerBC::calcHydroFlux
(const Tessellation& tess,
 const vector<Vector2D>& point_velocities,
 const vector<ComputationalCell>& cells,
 const EquationOfState& eos,
 const size_t i) const
{
  const Edge& edge = tess.GetEdge(static_cast<int>(i));
  const pair<bool,bool> flags
    (edge.neighbors.first>=0 && edge.neighbors.first<tess.GetPointNo(),
     edge.neighbors.second>=0 && edge.neighbors.second<tess.GetPointNo());
  assert(flags.first || flags.second);
  if(!flags.first)
    return support_riemann
      (rs_,
       tess.GetMeshPoint(edge.neighbors.second),
       edge,
       convert_to_primitive
       (cells.at
	(static_cast<size_t>(edge.neighbors.second)),
	eos),
       Vector2D(0,0),
       false);
  if(!flags.second)
    return support_riemann
      (rs_,
       tess.GetMeshPoint(edge.neighbors.first),
       edge,
       convert_to_primitive
       (cells.at
	(static_cast<size_t>(edge.neighbors.first)),
	eos),
       Vector2D(0,0),
       true);
  const size_t left_index =
    static_cast<size_t>(edge.neighbors.first);
  const size_t right_index =
    static_cast<size_t>(edge.neighbors.second);
  const ComputationalCell& left_cell = cells.at(left_index);
  const ComputationalCell& right_cell = cells.at(right_index);
  if(left_cell.stickers.find(ghost_)->second &&
     right_cell.stickers.find(ghost_)->second)
    return Conserved();
  const Vector2D p = Parallel(edge);
  const Vector2D n =
    tess.GetMeshPoint(edge.neighbors.second) -
    tess.GetMeshPoint(edge.neighbors.first);
  const double velocity = Projection
    (tess.CalcFaceVelocity
     (point_velocities.at(left_index),
      point_velocities.at(right_index),
      tess.GetCellCM(edge.neighbors.first),
      tess.GetCellCM(edge.neighbors.second),
      calc_centroid(edge)),n);
  if(left_cell.stickers.find(ghost_)->second){
    const Primitive right =
      convert_to_primitive(right_cell, eos);
    const Primitive left =
      (abs(tess.GetMeshPoint(static_cast<int>(left_index)))>radius_) ?
      right : reflect(right,p);
    return rotate_solve_rotate_back
      (rs_,left,right,velocity,n,p);
  }
  if(right_cell.stickers.find(ghost_)->second){
    const Primitive left =
      convert_to_primitive(left_cell, eos);
    const Primitive right =
      (abs(tess.GetMeshPoint(static_cast<int>(right_index)))>radius_) ?
      left : reflect(left,p);
    return rotate_solve_rotate_back
      (rs_,left,right,velocity,n,p);
  }
  const Primitive left =
    convert_to_primitive(left_cell, eos);
  const Primitive right =
    convert_to_primitive(right_cell, eos);
  return rotate_solve_rotate_back
    (rs_,left,right,velocity,n,p);
}
<commit_msg>reduce code in flux calculator<commit_after>#include "inner_bc.hpp"
#include "source/newtonian/two_dimensional/simple_flux_calculator.hpp"
#include "safe_retrieve.hpp"

namespace {
  double calc_tracer_flux(const Edge& edge,
			  const Tessellation& tess,
			  const vector<ComputationalCell>& cells,
			  const string& name,
			  const Conserved& hf)
  {
    if(hf.Mass>0 &&
       edge.neighbors.first>0 &&
       edge.neighbors.first<tess.GetPointNo()){
      assert(cells.at(static_cast<size_t>(edge.neighbors.first)).tracers.count(name)==1);
      return hf.Mass*
	cells.at(static_cast<size_t>(edge.neighbors.first)).tracers.find(name)->second;
    }
    if(hf.Mass<0 &&
       edge.neighbors.second>0 &&
       edge.neighbors.second<tess.GetPointNo()){
      assert(cells.at(static_cast<size_t>(edge.neighbors.second)).tracers.count(name)==1);
      return hf.Mass*
	cells.at(static_cast<size_t>(edge.neighbors.second)).tracers.find(name)->second;
    }
    return 0;
  }
}

InnerBC::InnerBC(const RiemannSolver& rs,
		 const string& ghost,
		 const double radius):
  rs_(rs), ghost_(ghost), radius_(radius)
{
  assert(radius_>0);
}

vector<Extensive> InnerBC::operator()
  (const Tessellation& tess,
   const vector<Vector2D>& point_velocities,
   const vector<ComputationalCell>& cells,
   const vector<Extensive>& /*extensives*/,
   const EquationOfState& eos,
   const double /*time*/,
   const double /*dt*/) const
{
  vector<Extensive> res(tess.getAllEdges().size());
  for(size_t i=0;i<tess.getAllEdges().size();++i){
    const Conserved hydro_flux =
      calcHydroFlux(tess,point_velocities,
		    cells, eos, i);
    res.at(i).mass = hydro_flux.Mass;
    res.at(i).momentum = hydro_flux.Momentum;
    res.at(i).energy = hydro_flux.Energy;
    for(map<string,double>::const_iterator it =
	  cells.front().tracers.begin();
	it!=cells.front().tracers.end();
	++it)
      res.at(i).tracers[it->first] =
	calc_tracer_flux(tess.getAllEdges().at(i),
			 tess,cells,it->first,hydro_flux);
  }
  return res;
}

namespace {

  Primitive boost(const Primitive& origin,
		  const Vector2D& v)
  {
    Primitive res = origin;
    res.Velocity += v;
    return res;
  }

  Conserved support_riemann(const RiemannSolver& rs,
			    const Vector2D& rmp,
			    const Edge& edge,
			    const Primitive& cell,
			    const Vector2D& support,
			    bool left_real)
  {
    const Vector2D& p = Parallel(edge);
    Conserved res = left_real ?
      rotate_solve_rotate_back
      (rs,
       cell,
       boost(reflect(cell,p),support),
       0,
       remove_parallel_component
       (edge.vertices.second-rmp,p),
       p) :
      rotate_solve_rotate_back
      (rs,
       boost(reflect(cell,p),support),
       cell,
       0,
       remove_parallel_component
       (rmp-edge.vertices.second,p),
       p);
    res.Mass = 0;
    res.Energy = 0;
    return res;
  }
}

const Conserved InnerBC::calcHydroFlux
(const Tessellation& tess,
 const vector<Vector2D>& point_velocities,
 const vector<ComputationalCell>& cells,
 const EquationOfState& eos,
 const size_t i) const
{
  const Edge& edge = tess.GetEdge(static_cast<int>(i));
  const pair<bool,bool> flags
    (edge.neighbors.first>=0 && edge.neighbors.first<tess.GetPointNo(),
     edge.neighbors.second>=0 && edge.neighbors.second<tess.GetPointNo());
  assert(flags.first || flags.second);
  if(!flags.first)
    return support_riemann
      (rs_,
       tess.GetMeshPoint(edge.neighbors.second),
       edge,
       convert_to_primitive
       (cells.at
	(static_cast<size_t>(edge.neighbors.second)),
	eos),
       Vector2D(0,0),
       false);
  if(!flags.second)
    return support_riemann
      (rs_,
       tess.GetMeshPoint(edge.neighbors.first),
       edge,
       convert_to_primitive
       (cells.at
	(static_cast<size_t>(edge.neighbors.first)),
	eos),
       Vector2D(0,0),
       true);
  const size_t left_index =
    static_cast<size_t>(edge.neighbors.first);
  const size_t right_index =
    static_cast<size_t>(edge.neighbors.second);
  const ComputationalCell& left_cell = cells.at(left_index);
  const ComputationalCell& right_cell = cells.at(right_index);
  if(safe_retrieve(left_cell.stickers,ghost_)){
    if(safe_retrieve(right_cell.stickers,ghost_))
      return Conserved();
    return support_riemann
      (rs_,
       tess.GetMeshPoint(edge.neighbors.second),
       edge,
       convert_to_primitive(right_cell,eos),
       Vector2D(0,0),
       false);
  }
  if(safe_retrieve(right_cell.stickers,ghost_))
    return support_riemann
      (rs_,
       tess.GetMeshPoint(edge.neighbors.first),
       edge,
       convert_to_primitive(left_cell,eos),
       Vector2D(0,0),
       true);
  const Vector2D p = Parallel(edge);
  const Vector2D n =
    tess.GetMeshPoint(edge.neighbors.second) -
    tess.GetMeshPoint(edge.neighbors.first);
  const double velocity = Projection
    (tess.CalcFaceVelocity
     (point_velocities.at(left_index),
      point_velocities.at(right_index),
      tess.GetCellCM(edge.neighbors.first),
      tess.GetCellCM(edge.neighbors.second),
      calc_centroid(edge)),n);
  const Primitive left =
    convert_to_primitive(left_cell, eos);
  const Primitive right =
    convert_to_primitive(right_cell, eos);
  return rotate_solve_rotate_back
    (rs_,left,right,velocity,n,p);
}
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: groupproperties.cxx,v $
 *
 *  $Revision: 1.9 $
 *
 *  last change: $Author: ihi $ $Date: 2006-11-14 13:37:12 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 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
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_svx.hxx"

#ifndef _SDR_PROPERTIES_GROUPPROPERTIES_HXX
#include <svx/sdr/properties/groupproperties.hxx>
#endif

#ifndef _SFXITEMSET_HXX
#include <svtools/itemset.hxx>
#endif

#ifndef _SFX_WHITER_HXX
#include <svtools/whiter.hxx>
#endif

#ifndef _SVDDEF_HXX
#include <svddef.hxx>
#endif

#ifndef _EEITEM_HXX
#include <eeitem.hxx>
#endif

#ifndef _SVDOGRP_HXX
#include <svdogrp.hxx>
#endif

#ifndef _SVDPOOL_HXX
#include <svdpool.hxx>
#endif

#ifndef _SVDPAGE_HXX
#include <svdpage.hxx>
#endif

//////////////////////////////////////////////////////////////////////////////

namespace sdr
{
    namespace properties
    {
        // create a new itemset
        SfxItemSet& GroupProperties::CreateObjectSpecificItemSet(SfxItemPool& rPool)
        {
            // Groups have in principle no ItemSet. To support methods like
            // GetMergedItemSet() the local one is used. Thus, all items in the pool
            // may be used and a pool itemset is created.
            return *(new SfxItemSet(rPool));
        }

        GroupProperties::GroupProperties(SdrObject& rObj)
        :   DefaultProperties(rObj)
        {
        }

        GroupProperties::GroupProperties(const GroupProperties& rProps, SdrObject& rObj)
        :   DefaultProperties(rProps, rObj)
        {
        }

        GroupProperties::~GroupProperties()
        {
        }

        BaseProperties& GroupProperties::Clone(SdrObject& rObj) const
        {
            return *(new GroupProperties(*this, rObj));
        }

        const SfxItemSet& GroupProperties::GetObjectItemSet() const
        {
            DBG_ASSERT(sal_False, "GroupProperties::GetObjectItemSet() should never be called (!)");
            return DefaultProperties::GetObjectItemSet();
        }

        const SfxItemSet& GroupProperties::GetMergedItemSet() const
        {
            // prepare ItemSet
            if(mpItemSet)
            {
                // clear local itemset for merge
                mpItemSet->ClearItem();
            }
            else
            {
                // force local itemset
                DefaultProperties::GetObjectItemSet();
            }

            // collect all ItemSets in mpItemSet
            const SdrObjList* pSub = ((const SdrObjGroup&)GetSdrObject()).GetSubList();
            const sal_uInt32 nCount(pSub->GetObjCount());

            for(sal_uInt32 a(0L); a < nCount; a++)
            {
                const SfxItemSet& rSet = pSub->GetObj(a)->GetMergedItemSet();
                SfxWhichIter aIter(rSet);
                sal_uInt16 nWhich(aIter.FirstWhich());

                while(nWhich)
                {
                    if(SFX_ITEM_DONTCARE == rSet.GetItemState(nWhich, FALSE))
                    {
                        mpItemSet->InvalidateItem(nWhich);
                    }
                    else
                    {
                        mpItemSet->MergeValue(rSet.Get(nWhich), TRUE);
                    }

                    nWhich = aIter.NextWhich();
                }
            }

            // For group proerties, do not call parent since groups do
            // not have local ItemSets.
            return *mpItemSet;
        }

        void GroupProperties::SetMergedItemSet(const SfxItemSet& rSet, sal_Bool bClearAllItems)
        {
            // iterate over contained SdrObjects
            const SdrObjList* pSub = ((const SdrObjGroup&)GetSdrObject()).GetSubList();
            const sal_uInt32 nCount(pSub->GetObjCount());

            for(sal_uInt32 a(0L); a < nCount; a++)
            {
                SdrObject* pObj = pSub->GetObj(a);

                if(pObj)
                {
                    // Set merged ItemSet at contained object
                    pObj->SetMergedItemSet(rSet, bClearAllItems);
                }
            }

            // Do not call parent here. Group objects do not have local ItemSets
            // where items need to be set.
            // DefaultProperties::SetMergedItemSet(rSet, bClearAllItems);
        }

        void GroupProperties::SetObjectItem(const SfxPoolItem& /*rItem*/)
        {
            DBG_ASSERT(sal_False, "GroupProperties::SetObjectItem() should never be called (!)");
        }

        void GroupProperties::SetObjectItemDirect(const SfxPoolItem& /*rItem*/)
        {
            DBG_ASSERT(sal_False, "GroupProperties::SetObjectItemDirect() should never be called (!)");
        }

        void GroupProperties::ClearObjectItem(const sal_uInt16 /*nWhich*/)
        {
            DBG_ASSERT(sal_False, "GroupProperties::ClearObjectItem() should never be called (!)");
        }

        void GroupProperties::ClearObjectItemDirect(const sal_uInt16 /*nWhich*/)
        {
            DBG_ASSERT(sal_False, "GroupProperties::ClearObjectItemDirect() should never be called (!)");
        }

        void GroupProperties::SetMergedItem(const SfxPoolItem& rItem)
        {
            const SdrObjList* pSub = ((const SdrObjGroup&)GetSdrObject()).GetSubList();
            const sal_uInt32 nCount(pSub->GetObjCount());

            for(sal_uInt32 a(0L); a < nCount; a++)
            {
                pSub->GetObj(a)->GetProperties().SetMergedItem(rItem);
            }
        }

        void GroupProperties::ClearMergedItem(const sal_uInt16 nWhich)
        {
            const SdrObjList* pSub = ((const SdrObjGroup&)GetSdrObject()).GetSubList();
            const sal_uInt32 nCount(pSub->GetObjCount());

            for(sal_uInt32 a(0L); a < nCount; a++)
            {
                pSub->GetObj(a)->GetProperties().ClearMergedItem(nWhich);
            }
        }

        void GroupProperties::SetObjectItemSet(const SfxItemSet& /*rSet*/)
        {
            DBG_ASSERT(sal_False, "GroupProperties::SetObjectItemSet() should never be called (!)");
        }

        void GroupProperties::ItemSetChanged(const SfxItemSet& /*rSet*/)
        {
            DBG_ASSERT(sal_False, "GroupProperties::ItemSetChanged() should never be called (!)");
        }

        sal_Bool GroupProperties::AllowItemChange(const sal_uInt16 /*nWhich*/, const SfxPoolItem* /*pNewItem*/) const
        {
            DBG_ASSERT(sal_False, "GroupProperties::AllowItemChange() should never be called (!)");
            return sal_False;
        }

        void GroupProperties::ItemChange(const sal_uInt16 /*nWhich*/, const SfxPoolItem* /*pNewItem*/)
        {
            DBG_ASSERT(sal_False, "GroupProperties::ItemChange() should never be called (!)");
        }

        void GroupProperties::PostItemChange(const sal_uInt16 /*nWhich*/)
        {
            DBG_ASSERT(sal_False, "GroupProperties::PostItemChange() should never be called (!)");
        }

        SfxStyleSheet* GroupProperties::GetStyleSheet() const
        {
            SfxStyleSheet* pRetval = 0L;

            const SdrObjList* pSub = ((const SdrObjGroup&)GetSdrObject()).GetSubList();
            const sal_uInt32 nCount(pSub->GetObjCount());

            for(sal_uInt32 a(0L); a < nCount; a++)
            {
                SfxStyleSheet* pCandidate = pSub->GetObj(a)->GetStyleSheet();

                if(pRetval)
                {
                    if(pCandidate != pRetval)
                    {
                        // different StyleSheelts, return none
                        return 0L;
                    }
                }
                else
                {
                    pRetval = pCandidate;
                }
            }

            return pRetval;
        }

        void GroupProperties::SetStyleSheet(SfxStyleSheet* pNewStyleSheet, sal_Bool bDontRemoveHardAttr)
        {
            const SdrObjList* pSub = ((const SdrObjGroup&)GetSdrObject()).GetSubList();
            const sal_uInt32 nCount(pSub->GetObjCount());

            for(sal_uInt32 a(0L); a < nCount; a++)
            {
                pSub->GetObj(a)->SetStyleSheet(pNewStyleSheet, bDontRemoveHardAttr);
            }
        }

        void GroupProperties::ForceDefaultAttributes()
        {
            // nothing to do here, groups have no items and thus no default items, too.
        }

        void GroupProperties::MoveToItemPool(SfxItemPool* pSrcPool, SfxItemPool* pDestPool, SdrModel* pNewModel)
        {
            if(pSrcPool && pDestPool && (pSrcPool != pDestPool))
            {
                const SdrObjList* pSub = ((const SdrObjGroup&)GetSdrObject()).GetSubList();
                const sal_uInt32 nCount(pSub->GetObjCount());

                for(sal_uInt32 a(0L); a < nCount; a++)
                {
                    pSub->GetObj(a)->GetProperties().MoveToItemPool(pSrcPool, pDestPool, pNewModel);
                }

                // also clear local ItemSet, it's only temporary for group objects anyways.
                if(mpItemSet)
                {
                    // #121905#
                    // copy/paste is still using clone operators and MoveToItemPool functionality.
                    // Since SfxItemSet contains a pool pointer, ClearItem is not enough here.
                    // The ItemSet for merge is constructed on demand, so it's enough here to
                    // just delete it and set to 0L.
                    // mpItemSet->ClearItem();
                    delete mpItemSet;
                    mpItemSet = 0L;
                }
            }
        }

        void GroupProperties::ForceStyleToHardAttributes(sal_Bool bPseudoSheetsOnly)
        {
            const SdrObjList* pSub = ((const SdrObjGroup&)GetSdrObject()).GetSubList();
            const sal_uInt32 nCount(pSub->GetObjCount());

            for(sal_uInt32 a(0L); a < nCount; a++)
            {
                pSub->GetObj(a)->GetProperties().ForceStyleToHardAttributes(bPseudoSheetsOnly);
            }
        }
    } // end of namespace properties
} // end of namespace sdr

//////////////////////////////////////////////////////////////////////////////
// eof
<commit_msg>INTEGRATION: CWS aw036 (1.8.48); FILE MERGED 2006/10/26 15:57:16 aw 1.8.48.1: #i61284#: BurnInStyleSheetAttributes for text corrected; #i70852#: Set/GetLayer cleanup and implementation for FmFormObj<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: groupproperties.cxx,v $
 *
 *  $Revision: 1.10 $
 *
 *  last change: $Author: vg $ $Date: 2006-11-21 16:45:36 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 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
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_svx.hxx"

#ifndef _SDR_PROPERTIES_GROUPPROPERTIES_HXX
#include <svx/sdr/properties/groupproperties.hxx>
#endif

#ifndef _SFXITEMSET_HXX
#include <svtools/itemset.hxx>
#endif

#ifndef _SFX_WHITER_HXX
#include <svtools/whiter.hxx>
#endif

#ifndef _SVDDEF_HXX
#include <svddef.hxx>
#endif

#ifndef _EEITEM_HXX
#include <eeitem.hxx>
#endif

#ifndef _SVDOGRP_HXX
#include <svdogrp.hxx>
#endif

#ifndef _SVDPOOL_HXX
#include <svdpool.hxx>
#endif

#ifndef _SVDPAGE_HXX
#include <svdpage.hxx>
#endif

//////////////////////////////////////////////////////////////////////////////

namespace sdr
{
    namespace properties
    {
        // create a new itemset
        SfxItemSet& GroupProperties::CreateObjectSpecificItemSet(SfxItemPool& rPool)
        {
            // Groups have in principle no ItemSet. To support methods like
            // GetMergedItemSet() the local one is used. Thus, all items in the pool
            // may be used and a pool itemset is created.
            return *(new SfxItemSet(rPool));
        }

        GroupProperties::GroupProperties(SdrObject& rObj)
        :   DefaultProperties(rObj)
        {
        }

        GroupProperties::GroupProperties(const GroupProperties& rProps, SdrObject& rObj)
        :   DefaultProperties(rProps, rObj)
        {
        }

        GroupProperties::~GroupProperties()
        {
        }

        BaseProperties& GroupProperties::Clone(SdrObject& rObj) const
        {
            return *(new GroupProperties(*this, rObj));
        }

        const SfxItemSet& GroupProperties::GetObjectItemSet() const
        {
            DBG_ASSERT(sal_False, "GroupProperties::GetObjectItemSet() should never be called (!)");
            return DefaultProperties::GetObjectItemSet();
        }

        const SfxItemSet& GroupProperties::GetMergedItemSet() const
        {
            // prepare ItemSet
            if(mpItemSet)
            {
                // clear local itemset for merge
                mpItemSet->ClearItem();
            }
            else
            {
                // force local itemset
                DefaultProperties::GetObjectItemSet();
            }

            // collect all ItemSets in mpItemSet
            const SdrObjList* pSub = ((const SdrObjGroup&)GetSdrObject()).GetSubList();
            const sal_uInt32 nCount(pSub->GetObjCount());

            for(sal_uInt32 a(0L); a < nCount; a++)
            {
                const SfxItemSet& rSet = pSub->GetObj(a)->GetMergedItemSet();
                SfxWhichIter aIter(rSet);
                sal_uInt16 nWhich(aIter.FirstWhich());

                while(nWhich)
                {
                    if(SFX_ITEM_DONTCARE == rSet.GetItemState(nWhich, FALSE))
                    {
                        mpItemSet->InvalidateItem(nWhich);
                    }
                    else
                    {
                        mpItemSet->MergeValue(rSet.Get(nWhich), TRUE);
                    }

                    nWhich = aIter.NextWhich();
                }
            }

            // For group proerties, do not call parent since groups do
            // not have local ItemSets.
            return *mpItemSet;
        }

        void GroupProperties::SetMergedItemSet(const SfxItemSet& rSet, sal_Bool bClearAllItems)
        {
            // iterate over contained SdrObjects
            const SdrObjList* pSub = ((const SdrObjGroup&)GetSdrObject()).GetSubList();
            const sal_uInt32 nCount(pSub->GetObjCount());

            for(sal_uInt32 a(0L); a < nCount; a++)
            {
                SdrObject* pObj = pSub->GetObj(a);

                if(pObj)
                {
                    // Set merged ItemSet at contained object
                    pObj->SetMergedItemSet(rSet, bClearAllItems);
                }
            }

            // Do not call parent here. Group objects do not have local ItemSets
            // where items need to be set.
            // DefaultProperties::SetMergedItemSet(rSet, bClearAllItems);
        }

        void GroupProperties::SetObjectItem(const SfxPoolItem& /*rItem*/)
        {
            DBG_ASSERT(sal_False, "GroupProperties::SetObjectItem() should never be called (!)");
        }

        void GroupProperties::SetObjectItemDirect(const SfxPoolItem& /*rItem*/)
        {
            DBG_ASSERT(sal_False, "GroupProperties::SetObjectItemDirect() should never be called (!)");
        }

        void GroupProperties::ClearObjectItem(const sal_uInt16 /*nWhich*/)
        {
            DBG_ASSERT(sal_False, "GroupProperties::ClearObjectItem() should never be called (!)");
        }

        void GroupProperties::ClearObjectItemDirect(const sal_uInt16 /*nWhich*/)
        {
            DBG_ASSERT(sal_False, "GroupProperties::ClearObjectItemDirect() should never be called (!)");
        }

        void GroupProperties::SetMergedItem(const SfxPoolItem& rItem)
        {
            const SdrObjList* pSub = ((const SdrObjGroup&)GetSdrObject()).GetSubList();
            const sal_uInt32 nCount(pSub->GetObjCount());

            for(sal_uInt32 a(0L); a < nCount; a++)
            {
                pSub->GetObj(a)->GetProperties().SetMergedItem(rItem);
            }
        }

        void GroupProperties::ClearMergedItem(const sal_uInt16 nWhich)
        {
            const SdrObjList* pSub = ((const SdrObjGroup&)GetSdrObject()).GetSubList();
            const sal_uInt32 nCount(pSub->GetObjCount());

            for(sal_uInt32 a(0L); a < nCount; a++)
            {
                pSub->GetObj(a)->GetProperties().ClearMergedItem(nWhich);
            }
        }

        void GroupProperties::SetObjectItemSet(const SfxItemSet& /*rSet*/)
        {
            DBG_ASSERT(sal_False, "GroupProperties::SetObjectItemSet() should never be called (!)");
        }

        void GroupProperties::ItemSetChanged(const SfxItemSet& /*rSet*/)
        {
            DBG_ASSERT(sal_False, "GroupProperties::ItemSetChanged() should never be called (!)");
        }

        sal_Bool GroupProperties::AllowItemChange(const sal_uInt16 /*nWhich*/, const SfxPoolItem* /*pNewItem*/) const
        {
            DBG_ASSERT(sal_False, "GroupProperties::AllowItemChange() should never be called (!)");
            return sal_False;
        }

        void GroupProperties::ItemChange(const sal_uInt16 /*nWhich*/, const SfxPoolItem* /*pNewItem*/)
        {
            DBG_ASSERT(sal_False, "GroupProperties::ItemChange() should never be called (!)");
        }

        void GroupProperties::PostItemChange(const sal_uInt16 /*nWhich*/)
        {
            DBG_ASSERT(sal_False, "GroupProperties::PostItemChange() should never be called (!)");
        }

        SfxStyleSheet* GroupProperties::GetStyleSheet() const
        {
            SfxStyleSheet* pRetval = 0L;

            const SdrObjList* pSub = ((const SdrObjGroup&)GetSdrObject()).GetSubList();
            const sal_uInt32 nCount(pSub->GetObjCount());

            for(sal_uInt32 a(0L); a < nCount; a++)
            {
                SfxStyleSheet* pCandidate = pSub->GetObj(a)->GetStyleSheet();

                if(pRetval)
                {
                    if(pCandidate != pRetval)
                    {
                        // different StyleSheelts, return none
                        return 0L;
                    }
                }
                else
                {
                    pRetval = pCandidate;
                }
            }

            return pRetval;
        }

        void GroupProperties::SetStyleSheet(SfxStyleSheet* pNewStyleSheet, sal_Bool bDontRemoveHardAttr)
        {
            const SdrObjList* pSub = ((const SdrObjGroup&)GetSdrObject()).GetSubList();
            const sal_uInt32 nCount(pSub->GetObjCount());

            for(sal_uInt32 a(0L); a < nCount; a++)
            {
                pSub->GetObj(a)->SetStyleSheet(pNewStyleSheet, bDontRemoveHardAttr);
            }
        }

        void GroupProperties::ForceDefaultAttributes()
        {
            // nothing to do here, groups have no items and thus no default items, too.
        }

        void GroupProperties::MoveToItemPool(SfxItemPool* pSrcPool, SfxItemPool* pDestPool, SdrModel* pNewModel)
        {
            if(pSrcPool && pDestPool && (pSrcPool != pDestPool))
            {
                const SdrObjList* pSub = ((const SdrObjGroup&)GetSdrObject()).GetSubList();
                const sal_uInt32 nCount(pSub->GetObjCount());

                for(sal_uInt32 a(0L); a < nCount; a++)
                {
                    pSub->GetObj(a)->GetProperties().MoveToItemPool(pSrcPool, pDestPool, pNewModel);
                }

                // also clear local ItemSet, it's only temporary for group objects anyways.
                if(mpItemSet)
                {
                    // #121905#
                    // copy/paste is still using clone operators and MoveToItemPool functionality.
                    // Since SfxItemSet contains a pool pointer, ClearItem is not enough here.
                    // The ItemSet for merge is constructed on demand, so it's enough here to
                    // just delete it and set to 0L.
                    // mpItemSet->ClearItem();
                    delete mpItemSet;
                    mpItemSet = 0L;
                }
            }
        }

        void GroupProperties::ForceStyleToHardAttributes()
        {
            const SdrObjList* pSub = ((const SdrObjGroup&)GetSdrObject()).GetSubList();
            const sal_uInt32 nCount(pSub->GetObjCount());

            for(sal_uInt32 a(0L); a < nCount; a++)
            {
                pSub->GetObj(a)->GetProperties().ForceStyleToHardAttributes();
            }
        }
    } // end of namespace properties
} // end of namespace sdr

//////////////////////////////////////////////////////////////////////////////
// eof
<|endoftext|>


<commit_before>// Copyright 2015 The Crashpad Authors. All rights reserved.
//
// 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 "handler/handler_main.h"

#include "build/build_config.h"
#include "tools/tool_support.h"

#if defined(OS_WIN)
#include <windows.h>
#endif

#if defined(OS_MACOSX)
int main(int argc, char* argv[]) {
  return crashpad::HandlerMain(argc, argv, nullptr);
}
#elif defined(OS_WIN)
namespace {

int HandlerMainAdaptor(int argc, char* argv[]) {
  return crashpad::HandlerMain(argc, argv, nullptr);
}

}  // namespace

int APIENTRY wWinMain(HINSTANCE, HINSTANCE, wchar_t*, int) {
  return crashpad::ToolSupport::Wmain(__argc, __wargv, HandlerMainAdaptor);
}
#endif  // OS_MACOSX
<commit_msg>win handler: Provide a wmain() entry point<commit_after>// Copyright 2015 The Crashpad Authors. All rights reserved.
//
// 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 "handler/handler_main.h"

#include "build/build_config.h"
#include "tools/tool_support.h"

#if defined(OS_WIN)
#include <windows.h>
#endif

#if defined(OS_MACOSX)

int main(int argc, char* argv[]) {
  return crashpad::HandlerMain(argc, argv, nullptr);
}

#elif defined(OS_WIN)

namespace {

int HandlerMainAdaptor(int argc, char* argv[]) {
  return crashpad::HandlerMain(argc, argv, nullptr);
}

}  // namespace

// The default entry point for /subsystem:windows. In Crashpad’s own build, this
// is used by crashpad_handler.exe. It’s also used by crashpad_handler.com when
// produced by editbin from a copy of crashpad_handler.exe.
int APIENTRY wWinMain(HINSTANCE, HINSTANCE, wchar_t*, int) {
  return crashpad::ToolSupport::Wmain(__argc, __wargv, HandlerMainAdaptor);
}

// The default entry point for /subsystem:console. This is not currently used by
// Crashpad’s own build, but may be used by other builds.
int wmain(int argc, wchar_t* argv[]) {
  return crashpad::ToolSupport::Wmain(argc, argv, HandlerMainAdaptor);
}

#endif  // OS_MACOSX
<|endoftext|>


<commit_before>/***************************************************************************
 *   Copyright (C) 2006 by Till Adam <adam@kde.org>                        *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU Library General Public License as       *
 *   published by the Free Software Foundation; either version 2 of the    *
 *   License, or (at your option) any later version.                       *
 *                                                                         *
 *   This program 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 Library General Public     *
 *   License along with this program; if not, write to the                 *
 *   Free Software Foundation, Inc.,                                       *
 *   51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.             *
 ***************************************************************************/

#include "akonadi.h"
#include "akonadiconnection.h"
#include "serveradaptor.h"
#include "akdebug.h"

#include "cachecleaner.h"
#include "intervalcheck.h"
#include "storage/dbconfig.h"
#include "storage/datastore.h"
#include "notificationmanager.h"
#include "resourcemanager.h"
#include "tracer.h"
#include "debuginterface.h"
#include "storage/itemretrievalthread.h"
#include "preprocessormanager.h"
#include "search/searchmanager.h"

#include "libs/xdgbasedirs_p.h"
#include "libs/protocol_p.h"

#include <QtSql/QSqlQuery>
#include <QtSql/QSqlError>

#include <QtCore/QCoreApplication>
#include <QtCore/QDir>
#include <QtCore/QSettings>
#include <QtCore/QTimer>
#include <QtDBus/QDBusServiceWatcher>

#include <config-akonadi.h>
#ifdef HAVE_UNISTD_H
# include <unistd.h>
#endif
#include <stdlib.h>

using namespace Akonadi;

static AkonadiServer *s_instance = 0;

AkonadiServer::AkonadiServer( QObject* parent )
#ifdef Q_OS_WINCE
    : QTcpServer( parent )
#else
    : QLocalServer( parent )
#endif
    , mCacheCleaner( 0 )
    , mIntervalChecker( 0 )
    , mItemRetrievalThread( 0 )
    , mDatabaseProcess( 0 )
    , mAlreadyShutdown( false )
{
    const QString serverConfigFile = XdgBaseDirs::akonadiServerConfigFile( XdgBaseDirs::ReadWrite );
    QSettings settings( serverConfigFile, QSettings::IniFormat );

    DbConfig::configuredDatabase()->init( settings );

    if ( DbConfig::configuredDatabase()->useInternalServer() )
      startDatabaseProcess();
    else
      createDatabase();

    s_instance = this;

    const QString connectionSettingsFile = XdgBaseDirs::akonadiConnectionConfigFile( XdgBaseDirs::WriteOnly );
    QSettings connectionSettings( connectionSettingsFile, QSettings::IniFormat );

#ifdef Q_OS_WIN
    QString namedPipe = settings.value( QLatin1String( "Connection/NamedPipe" ), QLatin1String( "Akonadi" ) ).toString();
#ifdef Q_OS_WINCE
    if ( !listen( QHostAddress::LocalHost, 31414 ) )
#else
    if ( !listen( namedPipe ) )
#endif
      akFatal() << "Unable to listen on Named Pipe" << namedPipe;

    connectionSettings.setValue( QLatin1String( "Data/Method" ), QLatin1String( "NamedPipe" ) );
    connectionSettings.setValue( QLatin1String( "Data/NamedPipe" ), namedPipe );
#else
    const QString defaultSocketDir = XdgBaseDirs::saveDir( "data", QLatin1String( "akonadi" ) );
    QString socketDir = settings.value( QLatin1String( "Connection/SocketDirectory" ), defaultSocketDir ).toString();
    if ( socketDir[0] != QLatin1Char( '/' ) ) {
      QDir::home().mkdir( socketDir );
      socketDir = QDir::homePath() + QLatin1Char( '/' ) + socketDir;
    }

    const QString socketFile = socketDir + QLatin1String( "/akonadiserver.socket" );
    unlink( socketFile.toUtf8().constData() );
    if ( !listen( socketFile ) )
      akFatal() << "Unable to listen on Unix socket" << socketFile;

    connectionSettings.setValue( QLatin1String( "Data/Method" ), QLatin1String( "UnixPath" ) );
    connectionSettings.setValue( QLatin1String( "Data/UnixPath" ), socketFile );
#endif

    // initialize the database
    DataStore *db = DataStore::self();
    if ( !db->database().isOpen() )
      akFatal() << "Unable to open database" << db->database().lastError().text();
    if ( !db->init() )
      akFatal() << "Unable to initialize database.";

    NotificationManager::self();
    Tracer::self();
    new DebugInterface( this );
    ResourceManager::self();

    // Initialize the preprocessor manager
    PreprocessorManager::init();

    // Forcibly disable it if configuration says so
    if ( settings.value( QLatin1String( "General/DisablePreprocessing" ), false ).toBool() )
      PreprocessorManager::instance()->setEnabled( false );

    if ( settings.value( QLatin1String( "Cache/EnableCleaner" ), true ).toBool() ) {
      mCacheCleaner = new CacheCleaner( this );
      mCacheCleaner->start( QThread::IdlePriority );
    }

    mIntervalChecker = new IntervalCheck( this );
    mIntervalChecker->start( QThread::IdlePriority );

    mItemRetrievalThread = new ItemRetrievalThread( this );
    mItemRetrievalThread->start( QThread::HighPriority );

    const QStringList searchManagers = settings.value( QLatin1String( "Search/Manager" ),
                                                       QStringList() << QLatin1String( "Nepomuk" )
                                                                     << QLatin1String( "Agent" ) ).toStringList();
    mSearchManager = new SearchManager( searchManagers, this );

    new ServerAdaptor( this );
    QDBusConnection::sessionBus().registerObject( QLatin1String( "/Server" ), this );

    const QByteArray dbusAddress = qgetenv( "DBUS_SESSION_BUS_ADDRESS" );
    if ( !dbusAddress.isEmpty() ) {
      connectionSettings.setValue( QLatin1String( "DBUS/Address" ), QLatin1String( dbusAddress ) );
    }

    QDBusServiceWatcher *watcher = new QDBusServiceWatcher( QLatin1String( AKONADI_DBUS_CONTROL_SERVICE ),
                                                            QDBusConnection::sessionBus(),
                                                            QDBusServiceWatcher::WatchForOwnerChange, this );

    connect( watcher, SIGNAL( serviceOwnerChanged( const QString&, const QString&, const QString& ) ),
             this, SLOT( serviceOwnerChanged( const QString&, const QString&, const QString& ) ) );

    // Unhide all the items that are actually hidden.
    // The hidden flag was probably left out after an (abrupt)
    // server quit. We don't attempt to resume preprocessing
    // for the items as we don't actually know at which stage the
    // operation was interrupted...
    db->unhideAllPimItems();
}

AkonadiServer::~AkonadiServer()
{
}

template <typename T> static void quitThread( T & thread )
{
  if ( !thread )
    return;
  thread->quit();
  thread->wait();
  delete thread;
  thread = 0;
}

void AkonadiServer::quit()
{
    if ( mAlreadyShutdown )
      return;
    mAlreadyShutdown = true;

    qDebug() << "terminating service threads";
    quitThread( mCacheCleaner );
    quitThread( mIntervalChecker );
    quitThread( mItemRetrievalThread );

    delete mSearchManager;
    mSearchManager = 0;

    qDebug() << "terminating connection threads";
    for ( int i = 0; i < mConnections.count(); ++i )
      quitThread( mConnections[ i ] );
    mConnections.clear();

    // Terminate the preprocessor manager before the database but after all connections are gone
    PreprocessorManager::done();

    DataStore::self()->close();
    Q_ASSERT( QSqlDatabase::connectionNames().isEmpty() );

    qDebug() << "stopping db process";
    stopDatabaseProcess();

    QSettings settings( XdgBaseDirs::akonadiServerConfigFile(), QSettings::IniFormat );
    const QString connectionSettingsFile = XdgBaseDirs::akonadiConnectionConfigFile( XdgBaseDirs::WriteOnly );

#ifndef Q_OS_WIN
    QSettings connectionSettings( connectionSettingsFile, QSettings::IniFormat );
    const QString defaultSocketDir = XdgBaseDirs::saveDir( "data", QLatin1String( "akonadi" ) );
    const QString socketDir = settings.value( QLatin1String( "Connection/SocketDirectory" ), defaultSocketDir ).toString();

    if ( !QDir::home().remove( socketDir + QLatin1String( "/akonadiserver.socket" ) ) )
        akError() << "Failed to remove Unix socket";
#endif
    if ( !QDir::home().remove( connectionSettingsFile ) )
        akError() << "Failed to remove runtime connection config file";

    QTimer::singleShot( 0, this, SLOT( doQuit() ) );
}

void AkonadiServer::doQuit()
{
    QCoreApplication::exit();
}

#ifdef Q_OS_WINCE
void AkonadiServer::incomingConnection( int socketDescriptor )
#else
void AkonadiServer::incomingConnection( quintptr socketDescriptor )
#endif
{
    if ( mAlreadyShutdown )
      return;
    QPointer<AkonadiConnection> thread = new AkonadiConnection( socketDescriptor, this );
    connect( thread, SIGNAL( finished() ), thread, SLOT( deleteLater() ) );
    mConnections.append( thread );
    thread->start();
}

AkonadiServer * AkonadiServer::instance()
{
    if ( !s_instance )
        s_instance = new AkonadiServer();
    return s_instance;
}

void AkonadiServer::startDatabaseProcess()
{
  if ( !DbConfig::configuredDatabase()->useInternalServer() )
    return;

  // create the database directories if they don't exists
  XdgBaseDirs::saveDir( "data", QLatin1String( "akonadi/" ) );
  XdgBaseDirs::saveDir( "data", QLatin1String( "akonadi/file_db_data" ) );

  DbConfig::configuredDatabase()->startInternalServer();
}

void AkonadiServer::createDatabase()
{
  const QLatin1String initCon( "initConnection" );
  QSqlDatabase db = QSqlDatabase::addDatabase( DbConfig::configuredDatabase()->driverName(), initCon );
  DbConfig::configuredDatabase()->apply( db );
  db.setDatabaseName( DbConfig::configuredDatabase()->databaseName() );
  if ( !db.isValid() )
    akFatal() << "Invalid database object during initial database connection";

  if ( db.open() )
    db.close();
  else {
    akDebug() << "Failed to use database" << DbConfig::configuredDatabase()->databaseName();
    akDebug() << "Database error:" << db.lastError().text();
    akDebug() << "Trying to create database now...";

    db.close();
    db.setDatabaseName( QString() );
    if ( db.open() ) {
      {
        QSqlQuery query( db );
        if ( !query.exec( QLatin1String( "CREATE DATABASE akonadi" ) ) ) {
          akError() << "Failed to create database";
          akError() << "Query error:" << query.lastError().text();
          akFatal() << "Database error:" << db.lastError().text();
        }
      } // make sure query is destroyed before we close the db
      db.close();
    }
  }
  QSqlDatabase::removeDatabase( initCon );
}

void AkonadiServer::stopDatabaseProcess()
{
  if ( !DbConfig::configuredDatabase()->useInternalServer() )
    return;

  DbConfig::configuredDatabase()->stopInternalServer();
}

void AkonadiServer::serviceOwnerChanged( const QString&, const QString&, const QString &newOwner )
{
  if ( newOwner.isEmpty() ) {
    akError() << "Control process died, committing suicide!";
    quit();
  }
}

#include "akonadi.moc"
<commit_msg>Don't hardcode database name but use whatever is in the configuration.<commit_after>/***************************************************************************
 *   Copyright (C) 2006 by Till Adam <adam@kde.org>                        *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU Library General Public License as       *
 *   published by the Free Software Foundation; either version 2 of the    *
 *   License, or (at your option) any later version.                       *
 *                                                                         *
 *   This program 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 Library General Public     *
 *   License along with this program; if not, write to the                 *
 *   Free Software Foundation, Inc.,                                       *
 *   51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.             *
 ***************************************************************************/

#include "akonadi.h"
#include "akonadiconnection.h"
#include "serveradaptor.h"
#include "akdebug.h"

#include "cachecleaner.h"
#include "intervalcheck.h"
#include "storage/dbconfig.h"
#include "storage/datastore.h"
#include "notificationmanager.h"
#include "resourcemanager.h"
#include "tracer.h"
#include "debuginterface.h"
#include "storage/itemretrievalthread.h"
#include "preprocessormanager.h"
#include "search/searchmanager.h"

#include "libs/xdgbasedirs_p.h"
#include "libs/protocol_p.h"

#include <QtSql/QSqlQuery>
#include <QtSql/QSqlError>

#include <QtCore/QCoreApplication>
#include <QtCore/QDir>
#include <QtCore/QSettings>
#include <QtCore/QTimer>
#include <QtDBus/QDBusServiceWatcher>

#include <config-akonadi.h>
#ifdef HAVE_UNISTD_H
# include <unistd.h>
#endif
#include <stdlib.h>

using namespace Akonadi;

static AkonadiServer *s_instance = 0;

AkonadiServer::AkonadiServer( QObject* parent )
#ifdef Q_OS_WINCE
    : QTcpServer( parent )
#else
    : QLocalServer( parent )
#endif
    , mCacheCleaner( 0 )
    , mIntervalChecker( 0 )
    , mItemRetrievalThread( 0 )
    , mDatabaseProcess( 0 )
    , mAlreadyShutdown( false )
{
    const QString serverConfigFile = XdgBaseDirs::akonadiServerConfigFile( XdgBaseDirs::ReadWrite );
    QSettings settings( serverConfigFile, QSettings::IniFormat );

    DbConfig::configuredDatabase()->init( settings );

    if ( DbConfig::configuredDatabase()->useInternalServer() )
      startDatabaseProcess();
    else
      createDatabase();

    s_instance = this;

    const QString connectionSettingsFile = XdgBaseDirs::akonadiConnectionConfigFile( XdgBaseDirs::WriteOnly );
    QSettings connectionSettings( connectionSettingsFile, QSettings::IniFormat );

#ifdef Q_OS_WIN
    QString namedPipe = settings.value( QLatin1String( "Connection/NamedPipe" ), QLatin1String( "Akonadi" ) ).toString();
#ifdef Q_OS_WINCE
    if ( !listen( QHostAddress::LocalHost, 31414 ) )
#else
    if ( !listen( namedPipe ) )
#endif
      akFatal() << "Unable to listen on Named Pipe" << namedPipe;

    connectionSettings.setValue( QLatin1String( "Data/Method" ), QLatin1String( "NamedPipe" ) );
    connectionSettings.setValue( QLatin1String( "Data/NamedPipe" ), namedPipe );
#else
    const QString defaultSocketDir = XdgBaseDirs::saveDir( "data", QLatin1String( "akonadi" ) );
    QString socketDir = settings.value( QLatin1String( "Connection/SocketDirectory" ), defaultSocketDir ).toString();
    if ( socketDir[0] != QLatin1Char( '/' ) ) {
      QDir::home().mkdir( socketDir );
      socketDir = QDir::homePath() + QLatin1Char( '/' ) + socketDir;
    }

    const QString socketFile = socketDir + QLatin1String( "/akonadiserver.socket" );
    unlink( socketFile.toUtf8().constData() );
    if ( !listen( socketFile ) )
      akFatal() << "Unable to listen on Unix socket" << socketFile;

    connectionSettings.setValue( QLatin1String( "Data/Method" ), QLatin1String( "UnixPath" ) );
    connectionSettings.setValue( QLatin1String( "Data/UnixPath" ), socketFile );
#endif

    // initialize the database
    DataStore *db = DataStore::self();
    if ( !db->database().isOpen() )
      akFatal() << "Unable to open database" << db->database().lastError().text();
    if ( !db->init() )
      akFatal() << "Unable to initialize database.";

    NotificationManager::self();
    Tracer::self();
    new DebugInterface( this );
    ResourceManager::self();

    // Initialize the preprocessor manager
    PreprocessorManager::init();

    // Forcibly disable it if configuration says so
    if ( settings.value( QLatin1String( "General/DisablePreprocessing" ), false ).toBool() )
      PreprocessorManager::instance()->setEnabled( false );

    if ( settings.value( QLatin1String( "Cache/EnableCleaner" ), true ).toBool() ) {
      mCacheCleaner = new CacheCleaner( this );
      mCacheCleaner->start( QThread::IdlePriority );
    }

    mIntervalChecker = new IntervalCheck( this );
    mIntervalChecker->start( QThread::IdlePriority );

    mItemRetrievalThread = new ItemRetrievalThread( this );
    mItemRetrievalThread->start( QThread::HighPriority );

    const QStringList searchManagers = settings.value( QLatin1String( "Search/Manager" ),
                                                       QStringList() << QLatin1String( "Nepomuk" )
                                                                     << QLatin1String( "Agent" ) ).toStringList();
    mSearchManager = new SearchManager( searchManagers, this );

    new ServerAdaptor( this );
    QDBusConnection::sessionBus().registerObject( QLatin1String( "/Server" ), this );

    const QByteArray dbusAddress = qgetenv( "DBUS_SESSION_BUS_ADDRESS" );
    if ( !dbusAddress.isEmpty() ) {
      connectionSettings.setValue( QLatin1String( "DBUS/Address" ), QLatin1String( dbusAddress ) );
    }

    QDBusServiceWatcher *watcher = new QDBusServiceWatcher( QLatin1String( AKONADI_DBUS_CONTROL_SERVICE ),
                                                            QDBusConnection::sessionBus(),
                                                            QDBusServiceWatcher::WatchForOwnerChange, this );

    connect( watcher, SIGNAL( serviceOwnerChanged( const QString&, const QString&, const QString& ) ),
             this, SLOT( serviceOwnerChanged( const QString&, const QString&, const QString& ) ) );

    // Unhide all the items that are actually hidden.
    // The hidden flag was probably left out after an (abrupt)
    // server quit. We don't attempt to resume preprocessing
    // for the items as we don't actually know at which stage the
    // operation was interrupted...
    db->unhideAllPimItems();
}

AkonadiServer::~AkonadiServer()
{
}

template <typename T> static void quitThread( T & thread )
{
  if ( !thread )
    return;
  thread->quit();
  thread->wait();
  delete thread;
  thread = 0;
}

void AkonadiServer::quit()
{
    if ( mAlreadyShutdown )
      return;
    mAlreadyShutdown = true;

    qDebug() << "terminating service threads";
    quitThread( mCacheCleaner );
    quitThread( mIntervalChecker );
    quitThread( mItemRetrievalThread );

    delete mSearchManager;
    mSearchManager = 0;

    qDebug() << "terminating connection threads";
    for ( int i = 0; i < mConnections.count(); ++i )
      quitThread( mConnections[ i ] );
    mConnections.clear();

    // Terminate the preprocessor manager before the database but after all connections are gone
    PreprocessorManager::done();

    DataStore::self()->close();
    Q_ASSERT( QSqlDatabase::connectionNames().isEmpty() );

    qDebug() << "stopping db process";
    stopDatabaseProcess();

    QSettings settings( XdgBaseDirs::akonadiServerConfigFile(), QSettings::IniFormat );
    const QString connectionSettingsFile = XdgBaseDirs::akonadiConnectionConfigFile( XdgBaseDirs::WriteOnly );

#ifndef Q_OS_WIN
    QSettings connectionSettings( connectionSettingsFile, QSettings::IniFormat );
    const QString defaultSocketDir = XdgBaseDirs::saveDir( "data", QLatin1String( "akonadi" ) );
    const QString socketDir = settings.value( QLatin1String( "Connection/SocketDirectory" ), defaultSocketDir ).toString();

    if ( !QDir::home().remove( socketDir + QLatin1String( "/akonadiserver.socket" ) ) )
        akError() << "Failed to remove Unix socket";
#endif
    if ( !QDir::home().remove( connectionSettingsFile ) )
        akError() << "Failed to remove runtime connection config file";

    QTimer::singleShot( 0, this, SLOT( doQuit() ) );
}

void AkonadiServer::doQuit()
{
    QCoreApplication::exit();
}

#ifdef Q_OS_WINCE
void AkonadiServer::incomingConnection( int socketDescriptor )
#else
void AkonadiServer::incomingConnection( quintptr socketDescriptor )
#endif
{
    if ( mAlreadyShutdown )
      return;
    QPointer<AkonadiConnection> thread = new AkonadiConnection( socketDescriptor, this );
    connect( thread, SIGNAL( finished() ), thread, SLOT( deleteLater() ) );
    mConnections.append( thread );
    thread->start();
}

AkonadiServer * AkonadiServer::instance()
{
    if ( !s_instance )
        s_instance = new AkonadiServer();
    return s_instance;
}

void AkonadiServer::startDatabaseProcess()
{
  if ( !DbConfig::configuredDatabase()->useInternalServer() )
    return;

  // create the database directories if they don't exists
  XdgBaseDirs::saveDir( "data", QLatin1String( "akonadi/" ) );
  XdgBaseDirs::saveDir( "data", QLatin1String( "akonadi/file_db_data" ) );

  DbConfig::configuredDatabase()->startInternalServer();
}

void AkonadiServer::createDatabase()
{
  const QLatin1String initCon( "initConnection" );
  QSqlDatabase db = QSqlDatabase::addDatabase( DbConfig::configuredDatabase()->driverName(), initCon );
  DbConfig::configuredDatabase()->apply( db );
  db.setDatabaseName( DbConfig::configuredDatabase()->databaseName() );
  if ( !db.isValid() )
    akFatal() << "Invalid database object during initial database connection";

  if ( db.open() )
    db.close();
  else {
    akDebug() << "Failed to use database" << DbConfig::configuredDatabase()->databaseName();
    akDebug() << "Database error:" << db.lastError().text();
    akDebug() << "Trying to create database now...";

    db.close();
    db.setDatabaseName( QString() );
    if ( db.open() ) {
      {
        QSqlQuery query( db );
        if ( !query.exec( QString::fromLatin1( "CREATE DATABASE %1" ).arg( DbConfig::configuredDatabase()->databaseName() ) ) ) {
          akError() << "Failed to create database";
          akError() << "Query error:" << query.lastError().text();
          akFatal() << "Database error:" << db.lastError().text();
        }
      } // make sure query is destroyed before we close the db
      db.close();
    }
  }
  QSqlDatabase::removeDatabase( initCon );
}

void AkonadiServer::stopDatabaseProcess()
{
  if ( !DbConfig::configuredDatabase()->useInternalServer() )
    return;

  DbConfig::configuredDatabase()->stopInternalServer();
}

void AkonadiServer::serviceOwnerChanged( const QString&, const QString&, const QString &newOwner )
{
  if ( newOwner.isEmpty() ) {
    akError() << "Control process died, committing suicide!";
    quit();
  }
}

#include "akonadi.moc"
<|endoftext|>


<commit_before>/**
 * @file   MqNodeTest.cpp
 * @brief  MqNode class tester.
 * @author zer0
 * @date   2018-11-11
 */

#include <gtest/gtest.h>
#include <tester/DemoAsset.hpp>
#include <libtbag/mq/MqNode.hpp>
#include <libtbag/log/Log.hpp>

#include <string>
#include <set>

using namespace libtbag;
using namespace libtbag::mq;

TEST(MqNodeTest, Bind)
{
    libtbag::log::SeverityGuard guard;

    tttDir_Automatic_Pipe();
    auto const PIPE_PATH = std::string("pipe://") + tttDir_Pipe_Get() + "?verbose=true";

    MqNode node;
    ASSERT_EQ(Err::E_SUCCESS, node.bind(PIPE_PATH));
}

TEST(MqNodeTest, ClientRel_ServerRel)
{
    // Client release -> Server release!
    tttDir_Automatic_Pipe();
    auto const PIPE_PATH = std::string("pipe://") + tttDir_Pipe_Get() + "?verbose=true";

    auto server = std::make_unique<MqNode>();
    auto client = std::make_unique<MqNode>();

    libtbag::log::SeverityGuard guard;
    ASSERT_EQ(Err::E_SUCCESS, server->bind(PIPE_PATH));
    ASSERT_EQ(Err::E_SUCCESS, client->connect(PIPE_PATH));

    client.reset();
    server.reset();
}

TEST(MqNodeTest, ServerRel_ClientRel)
{
    // Server release -> Client release!
    tttDir_Automatic_Pipe();
    auto const PIPE_PATH = std::string("pipe://") + tttDir_Pipe_Get() + "?verbose=true";

    auto server = std::make_unique<MqNode>();
    auto client = std::make_unique<MqNode>();

    libtbag::log::SeverityGuard guard;
    ASSERT_EQ(Err::E_SUCCESS, server->bind(PIPE_PATH));
    ASSERT_EQ(Err::E_SUCCESS, client->connect(PIPE_PATH));

    server.reset();
    client.reset();
}

TEST(MqNodeTest, ClientToServerMessage)
{
    tttDir_Automatic_Pipe();
    auto const PIPE_PATH = std::string("pipe://") + tttDir_Pipe_Get() + "?verbose=true";

    auto server = std::make_unique<MqNode>();
    auto client = std::make_unique<MqNode>();

    libtbag::log::SeverityGuard guard;
    ASSERT_EQ(Err::E_SUCCESS, server->bind(PIPE_PATH));
    ASSERT_EQ(Err::E_SUCCESS, client->connect(PIPE_PATH));

    std::string const TEST1_VAL = "T1E1ST1";
    std::string const TEST2_VAL = "T2E2ST2";

    MqNode::MqMsg msg_send1(TEST1_VAL);
    MqNode::MqMsg msg_send2(TEST2_VAL);

    ASSERT_EQ(Err::E_SUCCESS, client->send(msg_send1));
    ASSERT_EQ(Err::E_SUCCESS, client->send(msg_send2));

    MqNode::MqMsg msg_recv1;
    MqNode::MqMsg msg_recv2;

    server->recvWait(msg_recv1);
    server->recvWait(msg_recv2);

    std::string const RESULT1_VAL(msg_recv1.begin(), msg_recv1.end());
    std::string const RESULT2_VAL(msg_recv2.begin(), msg_recv2.end());

    server.reset();
    client.reset();

    ASSERT_EQ(TEST1_VAL, RESULT1_VAL);
    ASSERT_EQ(TEST2_VAL, RESULT2_VAL);
}

TEST(MqNodeTest, ServerToClientMessage)
{
    tttDir_Automatic_Pipe();
    auto const PIPE_PATH = std::string("pipe://") + tttDir_Pipe_Get() + "?verbose=true";

    auto server = std::make_unique<MqNode>();
    auto client = std::make_unique<MqNode>();

    libtbag::log::SeverityGuard guard;
    ASSERT_EQ(Err::E_SUCCESS, server->bind(PIPE_PATH));
    ASSERT_EQ(Err::E_SUCCESS, client->connect(PIPE_PATH));

    std::string const TEST1_VAL = "T1E1ST1";
    std::string const TEST2_VAL = "T2E2ST2";

    MqNode::MqMsg msg_send1(TEST1_VAL);
    MqNode::MqMsg msg_send2(TEST2_VAL);

    ASSERT_EQ(Err::E_SUCCESS, server->send(msg_send1));
    ASSERT_EQ(Err::E_SUCCESS, server->send(msg_send2));

    MqNode::MqMsg msg_recv1;
    MqNode::MqMsg msg_recv2;

    client->recvWait(msg_recv1);
    client->recvWait(msg_recv2);

    std::string const RESULT1_VAL(msg_recv1.begin(), msg_recv1.end());
    std::string const RESULT2_VAL(msg_recv2.begin(), msg_recv2.end());

    client.reset();
    server.reset();

    ASSERT_EQ(TEST1_VAL, RESULT1_VAL);
    ASSERT_EQ(TEST2_VAL, RESULT2_VAL);
}

TEST(MqNodeTest, SendAndClose1)
{
    tttDir_Automatic_Pipe();
    auto const PIPE_PATH = std::string("pipe://") + tttDir_Pipe_Get() + "?verbose=true";

    libtbag::log::SeverityGuard guard;
    auto server = std::make_unique<MqNode>();
    auto client = std::make_unique<MqNode>();
    ASSERT_EQ(Err::E_SUCCESS, server->bind(PIPE_PATH));
    ASSERT_EQ(Err::E_SUCCESS, client->connect(PIPE_PATH));
    ASSERT_EQ(Err::E_SUCCESS, server->send(MqNode::MqMsg(std::string("T1E1ST1"))));
    ASSERT_EQ(Err::E_SUCCESS, client->send(MqNode::MqMsg(std::string("T2E2ST2"))));

    // Client release -> Server release!
    client.reset();
    server.reset();
}

TEST(MqNodeTest, SendAndClose2)
{
    tttDir_Automatic_Pipe();
    auto const PIPE_PATH = std::string("pipe://") + tttDir_Pipe_Get() + "?verbose=true";

    libtbag::log::SeverityGuard guard;
    auto server = std::make_unique<MqNode>();
    auto client = std::make_unique<MqNode>();
    ASSERT_EQ(Err::E_SUCCESS, server->bind(PIPE_PATH));
    ASSERT_EQ(Err::E_SUCCESS, client->connect(PIPE_PATH));
    ASSERT_EQ(Err::E_SUCCESS, server->send(MqNode::MqMsg(std::string("T1E1ST1"))));
    ASSERT_EQ(Err::E_SUCCESS, client->send(MqNode::MqMsg(std::string("T2E2ST2"))));

    // Server release -> Client release!
    server.reset();
    client.reset();
}

TEST(MqNodeTest, MultiClient)
{
    tttDir_Automatic_Pipe();
    auto const PIPE_PATH = std::string("pipe://") + tttDir_Pipe_Get() + "?verbose=true";

    auto server  = std::make_unique<MqNode>();
    auto client1 = std::make_unique<MqNode>();
    auto client2 = std::make_unique<MqNode>();

    libtbag::log::SeverityGuard guard;
    ASSERT_EQ(Err::E_SUCCESS, server->bind(PIPE_PATH));
    ASSERT_EQ(Err::E_SUCCESS, client1->connect(PIPE_PATH));
    ASSERT_EQ(Err::E_SUCCESS, client2->connect(PIPE_PATH));

    std::string const TEST1_VAL = "T1E1ST1";
    std::string const TEST2_VAL = "T2E2ST2";
    std::string const TEST3_VAL = "T3E3ST3";
    std::string const TEST4_VAL = "T4E4ST4";
    std::string const TEST5_VAL = "T5E5ST5";
    std::string const TEST6_VAL = "T6E6ST6";

    MqNode::MqMsg msg_send1(TEST1_VAL);
    MqNode::MqMsg msg_send2(TEST2_VAL);
    MqNode::MqMsg msg_send3(TEST3_VAL);
    MqNode::MqMsg msg_send4(TEST4_VAL);
    MqNode::MqMsg msg_send5(TEST5_VAL);
    MqNode::MqMsg msg_send6(TEST6_VAL);

    ASSERT_EQ(Err::E_SUCCESS, client1->send(msg_send1));
    ASSERT_EQ(Err::E_SUCCESS, client2->send(msg_send2));
    ASSERT_EQ(Err::E_SUCCESS, client1->send(msg_send3));
    ASSERT_EQ(Err::E_SUCCESS, client2->send(msg_send4));
    ASSERT_EQ(Err::E_SUCCESS, server->send(msg_send5));
    ASSERT_EQ(Err::E_SUCCESS, server->send(msg_send6));

    MqNode::MqMsg msg_recv1;
    MqNode::MqMsg msg_recv2;
    MqNode::MqMsg msg_recv3;
    MqNode::MqMsg msg_recv4;
    server->recvWait(msg_recv1);
    server->recvWait(msg_recv2);
    server->recvWait(msg_recv3);
    server->recvWait(msg_recv4);

    std::string const RESULT1_VAL(msg_recv1.begin(), msg_recv1.end());
    std::string const RESULT2_VAL(msg_recv2.begin(), msg_recv2.end());
    std::string const RESULT3_VAL(msg_recv3.begin(), msg_recv3.end());
    std::string const RESULT4_VAL(msg_recv4.begin(), msg_recv4.end());

    std::set<std::string> client_to_server_vals;
    ASSERT_TRUE(client_to_server_vals.insert(RESULT1_VAL).second);
    ASSERT_TRUE(client_to_server_vals.insert(RESULT2_VAL).second);
    ASSERT_TRUE(client_to_server_vals.insert(RESULT3_VAL).second);
    ASSERT_TRUE(client_to_server_vals.insert(RESULT4_VAL).second);

    MqNode::MqMsg msg_client1_recv5;
    MqNode::MqMsg msg_client1_recv6;
    client1->recvWait(msg_client1_recv5);
    client1->recvWait(msg_client1_recv6);
    std::string const CLIENT1_RESULT5_VAL(msg_client1_recv5.begin(), msg_client1_recv5.end());
    std::string const CLIENT1_RESULT6_VAL(msg_client1_recv6.begin(), msg_client1_recv6.end());

    MqNode::MqMsg msg_client2_recv5;
    MqNode::MqMsg msg_client2_recv6;
    client2->recvWait(msg_client2_recv5);
    client2->recvWait(msg_client2_recv6);
    std::string const CLIENT2_RESULT5_VAL(msg_client2_recv5.begin(), msg_client2_recv5.end());
    std::string const CLIENT2_RESULT6_VAL(msg_client2_recv6.begin(), msg_client2_recv6.end());

    server.reset();
    client1.reset();
    client2.reset();

    auto itr = client_to_server_vals.find(TEST1_VAL);
    ASSERT_NE(itr, client_to_server_vals.end());
    client_to_server_vals.erase(itr);

    itr = client_to_server_vals.find(TEST2_VAL);
    ASSERT_NE(itr, client_to_server_vals.end());
    client_to_server_vals.erase(itr);

    itr = client_to_server_vals.find(TEST3_VAL);
    ASSERT_NE(itr, client_to_server_vals.end());
    client_to_server_vals.erase(itr);

    itr = client_to_server_vals.find(TEST4_VAL);
    ASSERT_NE(itr, client_to_server_vals.end());
    client_to_server_vals.erase(itr);

    ASSERT_TRUE(client_to_server_vals.empty());

    ASSERT_EQ(TEST5_VAL, CLIENT1_RESULT5_VAL);
    ASSERT_EQ(TEST5_VAL, CLIENT2_RESULT5_VAL);

    ASSERT_EQ(TEST6_VAL, CLIENT1_RESULT6_VAL);
    ASSERT_EQ(TEST6_VAL, CLIENT2_RESULT6_VAL);
}

<commit_msg>Skip MqNodeTest.* in MSVC.<commit_after>/**
 * @file   MqNodeTest.cpp
 * @brief  MqNode class tester.
 * @author zer0
 * @date   2018-11-11
 */

#include <gtest/gtest.h>
#include <tester/DemoAsset.hpp>
#include <libtbag/mq/MqNode.hpp>
#include <libtbag/log/Log.hpp>

#include <string>
#include <set>

using namespace libtbag;
using namespace libtbag::mq;

TEST(MqNodeTest, Bind)
{
    libtbag::log::SeverityGuard guard;

    tttDir_Automatic_Pipe();
    auto const PIPE_PATH = std::string("pipe://") + tttDir_Pipe_Get() + "?verbose=true";

    MqNode node;
    ASSERT_EQ(Err::E_SUCCESS, node.bind(PIPE_PATH));
}

TEST(MqNodeTest, ClientRel_ServerRel)
{
#if defined(TBAG_PLATFORM_WINDOWS)
    std::cout << "Skip this test.\n";
    return;
#endif

    // Client release -> Server release!
    tttDir_Automatic_Pipe();
    auto const PIPE_PATH = std::string("pipe://") + tttDir_Pipe_Get() + "?verbose=true";

    auto server = std::make_unique<MqNode>();
    auto client = std::make_unique<MqNode>();

    libtbag::log::SeverityGuard guard;
    ASSERT_EQ(Err::E_SUCCESS, server->bind(PIPE_PATH));
    ASSERT_EQ(Err::E_SUCCESS, client->connect(PIPE_PATH));

    client.reset();
    server.reset();
}

TEST(MqNodeTest, ServerRel_ClientRel)
{
#if defined(TBAG_PLATFORM_WINDOWS)
    std::cout << "Skip this test.\n";
    return;
#endif

    // Server release -> Client release!
    tttDir_Automatic_Pipe();
    auto const PIPE_PATH = std::string("pipe://") + tttDir_Pipe_Get() + "?verbose=true";

    auto server = std::make_unique<MqNode>();
    auto client = std::make_unique<MqNode>();

    libtbag::log::SeverityGuard guard;
    ASSERT_EQ(Err::E_SUCCESS, server->bind(PIPE_PATH));
    ASSERT_EQ(Err::E_SUCCESS, client->connect(PIPE_PATH));

    server.reset();
    client.reset();
}

TEST(MqNodeTest, ClientToServerMessage)
{
#if defined(TBAG_PLATFORM_WINDOWS)
    std::cout << "Skip this test.\n";
    return;
#endif

    tttDir_Automatic_Pipe();
    auto const PIPE_PATH = std::string("pipe://") + tttDir_Pipe_Get() + "?verbose=true";

    auto server = std::make_unique<MqNode>();
    auto client = std::make_unique<MqNode>();

    libtbag::log::SeverityGuard guard;
    ASSERT_EQ(Err::E_SUCCESS, server->bind(PIPE_PATH));
    ASSERT_EQ(Err::E_SUCCESS, client->connect(PIPE_PATH));

    std::string const TEST1_VAL = "T1E1ST1";
    std::string const TEST2_VAL = "T2E2ST2";

    MqNode::MqMsg msg_send1(TEST1_VAL);
    MqNode::MqMsg msg_send2(TEST2_VAL);

    ASSERT_EQ(Err::E_SUCCESS, client->send(msg_send1));
    ASSERT_EQ(Err::E_SUCCESS, client->send(msg_send2));

    MqNode::MqMsg msg_recv1;
    MqNode::MqMsg msg_recv2;

    server->recvWait(msg_recv1);
    server->recvWait(msg_recv2);

    std::string const RESULT1_VAL(msg_recv1.begin(), msg_recv1.end());
    std::string const RESULT2_VAL(msg_recv2.begin(), msg_recv2.end());

    server.reset();
    client.reset();

    ASSERT_EQ(TEST1_VAL, RESULT1_VAL);
    ASSERT_EQ(TEST2_VAL, RESULT2_VAL);
}

TEST(MqNodeTest, ServerToClientMessage)
{
#if defined(TBAG_PLATFORM_WINDOWS)
    std::cout << "Skip this test.\n";
    return;
#endif

    tttDir_Automatic_Pipe();
    auto const PIPE_PATH = std::string("pipe://") + tttDir_Pipe_Get() + "?verbose=true";

    auto server = std::make_unique<MqNode>();
    auto client = std::make_unique<MqNode>();

    libtbag::log::SeverityGuard guard;
    ASSERT_EQ(Err::E_SUCCESS, server->bind(PIPE_PATH));
    ASSERT_EQ(Err::E_SUCCESS, client->connect(PIPE_PATH));

    std::string const TEST1_VAL = "T1E1ST1";
    std::string const TEST2_VAL = "T2E2ST2";

    MqNode::MqMsg msg_send1(TEST1_VAL);
    MqNode::MqMsg msg_send2(TEST2_VAL);

    ASSERT_EQ(Err::E_SUCCESS, server->send(msg_send1));
    ASSERT_EQ(Err::E_SUCCESS, server->send(msg_send2));

    MqNode::MqMsg msg_recv1;
    MqNode::MqMsg msg_recv2;

    client->recvWait(msg_recv1);
    client->recvWait(msg_recv2);

    std::string const RESULT1_VAL(msg_recv1.begin(), msg_recv1.end());
    std::string const RESULT2_VAL(msg_recv2.begin(), msg_recv2.end());

    client.reset();
    server.reset();

    ASSERT_EQ(TEST1_VAL, RESULT1_VAL);
    ASSERT_EQ(TEST2_VAL, RESULT2_VAL);
}

TEST(MqNodeTest, SendAndClose1)
{
#if defined(TBAG_PLATFORM_WINDOWS)
    std::cout << "Skip this test.\n";
    return;
#endif

    tttDir_Automatic_Pipe();
    auto const PIPE_PATH = std::string("pipe://") + tttDir_Pipe_Get() + "?verbose=true";

    libtbag::log::SeverityGuard guard;
    auto server = std::make_unique<MqNode>();
    auto client = std::make_unique<MqNode>();
    ASSERT_EQ(Err::E_SUCCESS, server->bind(PIPE_PATH));
    ASSERT_EQ(Err::E_SUCCESS, client->connect(PIPE_PATH));
    ASSERT_EQ(Err::E_SUCCESS, server->send(MqNode::MqMsg(std::string("T1E1ST1"))));
    ASSERT_EQ(Err::E_SUCCESS, client->send(MqNode::MqMsg(std::string("T2E2ST2"))));

    // Client release -> Server release!
    client.reset();
    server.reset();
}

TEST(MqNodeTest, SendAndClose2)
{
#if defined(TBAG_PLATFORM_WINDOWS)
    std::cout << "Skip this test.\n";
    return;
#endif

    tttDir_Automatic_Pipe();
    auto const PIPE_PATH = std::string("pipe://") + tttDir_Pipe_Get() + "?verbose=true";

    libtbag::log::SeverityGuard guard;
    auto server = std::make_unique<MqNode>();
    auto client = std::make_unique<MqNode>();
    ASSERT_EQ(Err::E_SUCCESS, server->bind(PIPE_PATH));
    ASSERT_EQ(Err::E_SUCCESS, client->connect(PIPE_PATH));
    ASSERT_EQ(Err::E_SUCCESS, server->send(MqNode::MqMsg(std::string("T1E1ST1"))));
    ASSERT_EQ(Err::E_SUCCESS, client->send(MqNode::MqMsg(std::string("T2E2ST2"))));

    // Server release -> Client release!
    server.reset();
    client.reset();
}

TEST(MqNodeTest, MultiClient)
{
#if defined(TBAG_PLATFORM_WINDOWS)
    std::cout << "Skip this test.\n";
    return;
#endif

    tttDir_Automatic_Pipe();
    auto const PIPE_PATH = std::string("pipe://") + tttDir_Pipe_Get() + "?verbose=true";

    auto server  = std::make_unique<MqNode>();
    auto client1 = std::make_unique<MqNode>();
    auto client2 = std::make_unique<MqNode>();

    libtbag::log::SeverityGuard guard;
    ASSERT_EQ(Err::E_SUCCESS, server->bind(PIPE_PATH));
    ASSERT_EQ(Err::E_SUCCESS, client1->connect(PIPE_PATH));
    ASSERT_EQ(Err::E_SUCCESS, client2->connect(PIPE_PATH));

    std::string const TEST1_VAL = "T1E1ST1";
    std::string const TEST2_VAL = "T2E2ST2";
    std::string const TEST3_VAL = "T3E3ST3";
    std::string const TEST4_VAL = "T4E4ST4";
    std::string const TEST5_VAL = "T5E5ST5";
    std::string const TEST6_VAL = "T6E6ST6";

    MqNode::MqMsg msg_send1(TEST1_VAL);
    MqNode::MqMsg msg_send2(TEST2_VAL);
    MqNode::MqMsg msg_send3(TEST3_VAL);
    MqNode::MqMsg msg_send4(TEST4_VAL);
    MqNode::MqMsg msg_send5(TEST5_VAL);
    MqNode::MqMsg msg_send6(TEST6_VAL);

    ASSERT_EQ(Err::E_SUCCESS, client1->send(msg_send1));
    ASSERT_EQ(Err::E_SUCCESS, client2->send(msg_send2));
    ASSERT_EQ(Err::E_SUCCESS, client1->send(msg_send3));
    ASSERT_EQ(Err::E_SUCCESS, client2->send(msg_send4));
    ASSERT_EQ(Err::E_SUCCESS, server->send(msg_send5));
    ASSERT_EQ(Err::E_SUCCESS, server->send(msg_send6));

    MqNode::MqMsg msg_recv1;
    MqNode::MqMsg msg_recv2;
    MqNode::MqMsg msg_recv3;
    MqNode::MqMsg msg_recv4;
    server->recvWait(msg_recv1);
    server->recvWait(msg_recv2);
    server->recvWait(msg_recv3);
    server->recvWait(msg_recv4);

    std::string const RESULT1_VAL(msg_recv1.begin(), msg_recv1.end());
    std::string const RESULT2_VAL(msg_recv2.begin(), msg_recv2.end());
    std::string const RESULT3_VAL(msg_recv3.begin(), msg_recv3.end());
    std::string const RESULT4_VAL(msg_recv4.begin(), msg_recv4.end());

    std::set<std::string> client_to_server_vals;
    ASSERT_TRUE(client_to_server_vals.insert(RESULT1_VAL).second);
    ASSERT_TRUE(client_to_server_vals.insert(RESULT2_VAL).second);
    ASSERT_TRUE(client_to_server_vals.insert(RESULT3_VAL).second);
    ASSERT_TRUE(client_to_server_vals.insert(RESULT4_VAL).second);

    MqNode::MqMsg msg_client1_recv5;
    MqNode::MqMsg msg_client1_recv6;
    client1->recvWait(msg_client1_recv5);
    client1->recvWait(msg_client1_recv6);
    std::string const CLIENT1_RESULT5_VAL(msg_client1_recv5.begin(), msg_client1_recv5.end());
    std::string const CLIENT1_RESULT6_VAL(msg_client1_recv6.begin(), msg_client1_recv6.end());

    MqNode::MqMsg msg_client2_recv5;
    MqNode::MqMsg msg_client2_recv6;
    client2->recvWait(msg_client2_recv5);
    client2->recvWait(msg_client2_recv6);
    std::string const CLIENT2_RESULT5_VAL(msg_client2_recv5.begin(), msg_client2_recv5.end());
    std::string const CLIENT2_RESULT6_VAL(msg_client2_recv6.begin(), msg_client2_recv6.end());

    server.reset();
    client1.reset();
    client2.reset();

    auto itr = client_to_server_vals.find(TEST1_VAL);
    ASSERT_NE(itr, client_to_server_vals.end());
    client_to_server_vals.erase(itr);

    itr = client_to_server_vals.find(TEST2_VAL);
    ASSERT_NE(itr, client_to_server_vals.end());
    client_to_server_vals.erase(itr);

    itr = client_to_server_vals.find(TEST3_VAL);
    ASSERT_NE(itr, client_to_server_vals.end());
    client_to_server_vals.erase(itr);

    itr = client_to_server_vals.find(TEST4_VAL);
    ASSERT_NE(itr, client_to_server_vals.end());
    client_to_server_vals.erase(itr);

    ASSERT_TRUE(client_to_server_vals.empty());

    ASSERT_EQ(TEST5_VAL, CLIENT1_RESULT5_VAL);
    ASSERT_EQ(TEST5_VAL, CLIENT2_RESULT5_VAL);

    ASSERT_EQ(TEST6_VAL, CLIENT1_RESULT6_VAL);
    ASSERT_EQ(TEST6_VAL, CLIENT2_RESULT6_VAL);
}

<|endoftext|>