text:
#include "constants.h"
#include "color.h"
#include "hittable_list.h"
#include "sphere.h"
#include "moving_sphere.h"
#include "camera.h"
#include "material.h"
#include "texture.h"
#include "bvh.h"
#include "aarect.h"
#include "box.h"
#include "constant_medium.h"

#define STB_IMAGE_WRITE_IMPLEMENTATION // Do not include this line twice in your project!
#include "stb_image_write.h"
#include "utils.h"

#include <iostream>
#include <omp.h>
#include <getopt.h>

// Eigen for matrix operations
#include <Eigen/Dense>
#include <Eigen/Geometry>
using namespace Eigen;

color ray_color(const ray& r, const color& background, const hittable& world, int depth) {
    hit_record rec;

    // If we've exceeded the ray bounce limit, no more light is gathered.
    if (depth <= 0)
        return color(0,0,0);

    // If the ray hits nothing, return the background color.
    if (!world.hit(r, 0.001, infinity, rec))
        return background;

    ray scattered;
    color attenuation;
    color emitted = rec.mat_ptr->emitted(rec.u, rec.v, rec.p);

    if (!rec.mat_ptr->scatter(r, rec, attenuation, scattered))
        return emitted;

    return emitted + attenuation * ray_color(scattered, background, world, depth-1);
}

// Create a scene for render
hittable_list random_scene() {
    hittable_list world;

    auto checker = make_shared<checker_texture>(color(0.2, 0.3, 0.1), color(0.9, 0.9, 0.9));
    world.add(make_shared<sphere>(point3(0,-1000,0), 1000, make_shared<lambertian>(checker)));

    for (int a = -11; a < 11; a++) {
        for (int b = -11; b < 11; b++) {
            auto choose_mat = random_double();
            point3 center(a + 0.9*random_double(), 0.2, b + 0.9*random_double());

            if ((center - point3(4, 0.2, 0)).length() > 0.9) {
                shared_ptr<material> sphere_material;

                if (choose_mat < 0.8) {
                    // diffuse
                    auto albedo = color::random() * color::random();
                    sphere_material = make_shared<lambertian>(albedo);
                    auto center2 = center + vec3(0, random_double(0,.5), 0);
                    world.add(make_shared<moving_sphere>(
                        center, center2, 0.0, 1.0, 0.2, sphere_material));
                } else if (choose_mat < 0.95) {
                    // metal
                    auto albedo = color::random(0.5, 1);
                    auto fuzz = random_double(0, 0.5);
                    sphere_material = make_shared<metal>(albedo, fuzz);
                    world.add(make_shared<sphere>(center, 0.2, sphere_material));
                } else {
                    // glass
                    sphere_material = make_shared<dielectric>(1.5);
                    world.add(make_shared<sphere>(center, 0.2, sphere_material));
                }
            }
        }
    }

    auto material1 = make_shared<dielectric>(1.5);
    world.add(make_shared<sphere>(point3(0, 1, 0), 1.0, material1));

    auto material2 = make_shared<lambertian>(color(0.4, 0.2, 0.1));
    world.add(make_shared<sphere>(point3(-4, 1, 0), 1.0, material2));

    auto material3 = make_shared<metal>(color(0.7, 0.6, 0.5), 0.0);
    world.add(make_shared<sphere>(point3(4, 1, 0), 1.0, material3));

    return hittable_list(make_shared<bvh_node>(world, 0.0, 1.0));
}

// another scene
hittable_list two_spheres() {
    hittable_list objects;

    auto checker = make_shared<checker_texture>(color(0.2, 0.3, 0.1), color(0.9, 0.9, 0.9));

    objects.add(make_shared<sphere>(point3(0,-10, 0), 10, make_shared<lambertian>(checker)));
    objects.add(make_shared<sphere>(point3(0, 10, 0), 10, make_shared<lambertian>(checker)));

    return objects;
}

// a scene with perlin texture
hittable_list two_perlin_spheres() {
    hittable_list objects;

    auto pertext = make_shared<noise_texture>(4);
    objects.add(make_shared<sphere>(point3(0,-1000,0), 1000, make_shared<lambertian>(pertext)));
    objects.add(make_shared<sphere>(point3(0, 2, 0), 2, make_shared<lambertian>(pertext)));

    return objects;
}

hittable_list earth() {
    auto earth_texture = make_shared<image_texture>("../img/earthmap.jpg");
    auto earth_surface = make_shared<lambertian>(earth_texture);
    auto globe = make_shared<sphere>(point3(0,0,0), 2, earth_surface);

    return hittable_list(globe);
}

hittable_list simple_light() {
    hittable_list objects;

    auto pertext = make_shared<noise_texture>(4);
    objects.add(make_shared<sphere>(point3(0,-1000,0), 1000, make_shared<lambertian>(pertext)));
    objects.add(make_shared<sphere>(point3(0,2,0), 2, make_shared<lambertian>(pertext)));

    auto difflight = make_shared<diffuse_light>(color(1,1,1));
    objects.add(make_shared<xy_rect>(3, 5, 1, 3, -2, difflight));

    objects.add(make_shared<sphere>(point3(0,7,0), 2, make_shared<diffuse_light>(color(1,1,1))));

    return objects;
}

hittable_list cornell_box() {
    hittable_list objects;

    auto red   = make_shared<lambertian>(color(.65, .05, .05));
    auto white = make_shared<lambertian>(color(.73, .73, .73));
    auto green = make_shared<lambertian>(color(.12, .45, .15));
    auto light = make_shared<diffuse_light>(color(15, 15, 15));

    objects.add(make_shared<yz_rect>(0, 555, 0, 555, 555, green));
    objects.add(make_shared<yz_rect>(0, 555, 0, 555, 0, red));
    objects.add(make_shared<xz_rect>(213, 343, 227, 332, 554, light));
    objects.add(make_shared<xz_rect>(0, 555, 0, 555, 0, white));
    objects.add(make_shared<xz_rect>(0, 555, 0, 555, 555, white));
    objects.add(make_shared<xy_rect>(0, 555, 0, 555, 555, white));
    shared_ptr<hittable> box1 = make_shared<box>(point3(0, 0, 0), point3(165, 330, 165), white);
    box1 = make_shared<rotate_y>(box1, 15);
    box1 = make_shared<translate>(box1, vec3(265,0,295));
    objects.add(box1);

    shared_ptr<hittable> box2 = make_shared<box>(point3(0,0,0), point3(165,165,165), white);
    box2 = make_shared<rotate_y>(box2, -18);
    box2 = make_shared<translate>(box2, vec3(130,0,65));
    objects.add(box2);

    return objects;
}

hittable_list cornell_smoke() {
    hittable_list objects;

    auto red   = make_shared<lambertian>(color(.65, .05, .05));
    auto white = make_shared<lambertian>(color(.73, .73, .73));
    auto green = make_shared<lambertian>(color(.12, .45, .15));
    auto light = make_shared<diffuse_light>(color(7, 7, 7));

    objects.add(make_shared<yz_rect>(0, 555, 0, 555, 555, green));
    objects.add(make_shared<yz_rect>(0, 555, 0, 555, 0, red));
    objects.add(make_shared<xz_rect>(113, 443, 127, 432, 554, light));
    objects.add(make_shared<xz_rect>(0, 555, 0, 555, 555, white));
    objects.add(make_shared<xz_rect>(0, 555, 0, 555, 0, white));
    objects.add(make_shared<xy_rect>(0, 555, 0, 555, 555, white));

    shared_ptr<hittable> box1 = make_shared<box>(point3(0,0,0), point3(165,330,165), white);
    box1 = make_shared<rotate_y>(box1, 15);
    box1 = make_shared<translate>(box1, vec3(265,0,295));

    shared_ptr<hittable> box2 = make_shared<box>(point3(0,0,0), point3(165,165,165), white);
    box2 = make_shared<rotate_y>(box2, -18);
    box2 = make_shared<translate>(box2, vec3(130,0,65));

    objects.add(make_shared<constant_medium>(box1, 0.01, color(0,0,0)));
    objects.add(make_shared<constant_medium>(box2, 0.01, color(1,1,1)));

    return objects;
}

hittable_list final_scene() {
    hittable_list boxes1;
    auto ground = make_shared<lambertian>(color(0.48, 0.83, 0.53));

    const int boxes_per_side = 20;
    for (int i = 0; i < boxes_per_side; i++) {
        for (int j = 0; j < boxes_per_side; j++) {
            auto w = 100.0;
            auto x0 = -1000.0 + i*w;
            auto z0 = -1000.0 + j*w;
            auto y0 = 0.0;
            auto x1 = x0 + w;
            auto y1 = random_double(1,101);
            auto z1 = z0 + w;

            boxes1.add(make_shared<box>(point3(x0,y0,z0), point3(x1,y1,z1), ground));
        }
    }

    hittable_list objects;

    objects.add(make_shared<bvh_node>(boxes1, 0, 1));

    auto light = make_shared<diffuse_light>(color(7, 7, 7));
    objects.add(make_shared<xz_rect>(123, 423, 147, 412, 554, light));

    auto center1 = point3(400, 400, 200);
    auto center2 = center1 + vec3(30,0,0);
    auto moving_sphere_material = make_shared<lambertian>(color(0.7, 0.3, 0.1));
    objects.add(make_shared<moving_sphere>(center1, center2, 0, 1, 50, moving_sphere_material));

    objects.add(make_shared<sphere>(point3(260, 150, 45), 50, make_shared<dielectric>(1.5)));
    objects.add(make_shared<sphere>(
        point3(0, 150, 145), 50, make_shared<metal>(color(0.8, 0.8, 0.9), 1.0)
    ));

    auto boundary = make_shared<sphere>(point3(360,150,145), 70, make_shared<dielectric>(1.5));
    objects.add(boundary);
    objects.add(make_shared<constant_medium>(boundary, 0.2, color(0.2, 0.4, 0.9)));
    boundary = make_shared<sphere>(point3(0, 0, 0), 5000, make_shared<dielectric>(1.5));
    objects.add(make_shared<constant_medium>(boundary, .0001, color(1,1,1)));

    auto emat = make_shared<lambertian>(make_shared<image_texture>("../img/earthmap.jpg"));
    objects.add(make_shared<sphere>(point3(400,200,400), 100, emat));
    auto pertext = make_shared<noise_texture>(0.1);
    objects.add(make_shared<sphere>(point3(220,280,300), 80, make_shared<lambertian>(pertext)));

    hittable_list boxes2;
    auto white = make_shared<lambertian>(color(.73, .73, .73));
    int ns = 1000;
    for (int j = 0; j < ns; j++) {
        boxes2.add(make_shared<sphere>(point3::random(0,165), 10, white));
    }

    objects.add(make_shared<translate>(
        make_shared<rotate_y>(
            make_shared<bvh_node>(boxes2, 0.0, 1.0), 15),
            vec3(-100,270,395)
        )
    );

    return objects;
}

int main(int argc, char *argv[]) {

    // Threads Setting
    int threads_count = 0;

    if(argc < 2)
    {
	printf("usage: ./genfile num\n");
	printf("num of threads\n");
 	exit(1);
    }
    threads_count = atoi(argv[1]);

    // default values
    bool SUPER_QUALITY_RENDER = !true;
    bool HIGH_QUALITY_RENDER = !true;
    bool MEDIUM_QUALITY_RENDER = !true;
    bool PROFILE_RENDER = !true;

    // handle command line arguments
    if (argc >= 3) {
        // first command line argument is "PR"?
        if (std::string(argv[2]) == "PR") {
        PROFILE_RENDER = true;
        }
        // first command line argument is "SH"?
        if (std::string(argv[2]) == "SH") {
        SUPER_QUALITY_RENDER = true;
        }
        // first command line argument is "HQ"?
        if (std::string(argv[2]) == "HQ") {
        HIGH_QUALITY_RENDER = true;
        }
        // first command line argument is "MQ"?
        if (std::string(argv[2]) == "MQ") {
        MEDIUM_QUALITY_RENDER = true;
        }
    }

    // Image

    int image_width;
    int image_hight;
    int samples_per_pixel = 100;
    int max_depth = 5;

    if (PROFILE_RENDER) {
        image_width = 400;
        image_hight = 267;
    } else if (SUPER_QUALITY_RENDER) {
        image_width = 1600;
        image_hight = 1067;
    } else if (HIGH_QUALITY_RENDER) {
        image_width = 1200;
        image_hight = 800;
    } else if (MEDIUM_QUALITY_RENDER) {
        image_width = 800;
        image_hight = 533;
    } else {
        image_width = 560;
        image_hight = 373;
    }

    auto aspect_ratio = 1.0 * image_width / image_hight;

    int c;
    static struct option long_options[] = {
        {"width", optional_argument, 0, 'w'},
        {"sample", optional_argument, 0, 's'},
        {"depth", optional_argument, 0, 'd'},};
    while (true)
    {
        int option_index = 0;
        c = getopt_long(argc, argv, "w:s:d",
                        long_options, &option_index);
        if (c == -1)
            break;
        switch (c)
        {
        case 'w':
            image_width = atoi(optarg);
            break;
        case 's':
            samples_per_pixel = atoi(optarg);
            break;
        case 'd':
            max_depth = atoi(optarg);
            break;
        case '?':
            break;
        default:
            printf("?? getopt returned character code 0%o ??\n", c);
        }
    }

    // World

    hittable_list world;

    point3 lookfrom;
    point3 lookat;
    auto vfov = 40.0;
    auto aperture = 0.0;
    color background(0,0,0);

    switch (0) {
	default:
        case 1:
            world = random_scene();
            background = color(0.70, 0.80, 1.00);
            lookfrom = point3(13,2,3);
            lookat = point3(0,0,0);
            vfov = 20.0;
            aperture = 0.1;
            // image_width = 1200;
            aspect_ratio = 3.0 / 2.0;
            break;

        case 2:
            world = two_spheres();
            background = color(0.70, 0.80, 1.00);
            lookfrom = point3(13,2,3);
            lookat = point3(0,0,0);
            vfov = 20.0;
            break;

        case 3:
            world = two_perlin_spheres();
            background = color(0.70, 0.80, 1.00);
            lookfrom = point3(13,2,3);
            lookat = point3(0,0,0);
            vfov = 20.0;
            break;

        case 4:
            world = earth();
            background = color(0.70, 0.80, 1.00);
            lookfrom = point3(0,0,12);
            lookat = point3(0,0,0);
            vfov = 20.0;
            break;

        case 5:
            world = simple_light();
            samples_per_pixel = 400;
            lookfrom = point3(26,3,6);
            lookat = point3(0,2,0);
            vfov = 20.0;
            break;

        case 6:
            world = cornell_box();
            aspect_ratio = 1.0;
            image_width = 600;
            samples_per_pixel = 200;
            lookfrom = point3(278, 278, -800);
            lookat = point3(278, 278, 0);
            vfov = 40.0;
            break;

        case 7:
            world = cornell_smoke();
            aspect_ratio = 1.0;
            image_width = 600;
            samples_per_pixel = 200;
            lookfrom = point3(278, 278, -800);
            lookat = point3(278, 278, 0);
            vfov = 40.0;
            break;

        case 8:
            world = final_scene();
            aspect_ratio = 1.0;
            image_width = 600;
            samples_per_pixel = 10000;
            lookfrom = point3(478, 278, -600);
            lookat = point3(278, 278, 0);
            vfov = 40.0;
            break;
    }

    // Camera

    const vec3 vup(0,1,0);
    const auto dist_to_focus = 10.0;
    const int image_height = static_cast<int>(image_width / aspect_ratio);

    camera cam(lookfrom, lookat, vup, vfov, aspect_ratio, aperture, dist_to_focus, 0.0, 1.0);

    // Render

    MatrixXd R = MatrixXd::Zero(image_width, image_height);
	MatrixXd G = MatrixXd::Zero(image_width, image_height);
	MatrixXd B = MatrixXd::Zero(image_width, image_height);
	MatrixXd A = MatrixXd::Zero(image_width, image_height); // Store the alpha mask

    double t_start, t_end;
    t_start = omp_get_wtime();
    #pragma omp parallel for num_threads(threads_count)
    for (int i = image_width - 1; i >= 0; --i) {
        //std::cerr << "\rScanlines remaining: " << i << ' ' << std::flush;
        for (int j = 0; j < image_height; ++j) {
            color pixel_color(0,0,0);
            for (int s = 0; s < samples_per_pixel; ++s) {
                auto u = (i + random_double()) / (image_width-1);
                auto v = (j + random_double()) / (image_height-1);
                ray r = cam.get_ray(u, v);
                pixel_color += ray_color(r, background, world, max_depth);
            }
            auto scale = 1.0 / samples_per_pixel;
            // gamma = 2.0
            auto r = clamp(sqrt(scale * pixel_color.x()), 0.0, 0.999);
            auto g = clamp(sqrt(scale * pixel_color.y()), 0.0, 0.999);
            auto b = clamp(sqrt(scale * pixel_color.z()), 0.0, 0.999);
            R(i, j) = r;
            G(i, j) = g;
            B(i, j) = b;
            A(i, j) = 1;
        }
    }
    t_end = omp_get_wtime();
    std::cerr << "Time for parallel part is: " << t_end - t_start << "s";
    std::cerr << "\nDone.\n";

	// Save to png
	const std::string filename("raytrace.png");
	write_matrix_to_png(R, G, B, A, filename);
}


text:
/*
 * The MIT License (MIT)
 *
 * Copyright (c) 2018 Sylko Olzscher
 *
 */
#include "test-store-003.h"
#include <iostream>
#include <cyng/table/body.hpp>
#include <cyng/table/meta.hpp>
#include <cyng/store/db.h>
#include <cyng/factory.h>
#include <cyng/value_cast.hpp>
#include <chrono>
#include <future>
#include <boost/test/unit_test.hpp>
#include <boost/uuid/nil_generator.hpp>

namespace cyng
{

	bool test_store_003()
	{

		store::db database;
		BOOST_CHECK(database.create_table(cyng::table::make_meta_table<1, 3>("table-1",
			{ "pk", "field-1", "field-2", "field-2" },
			{ cyng::TC_INT32, cyng::TC_STRING, cyng::TC_STRING, cyng::TC_STRING },
			{ 0, 128, 128, 128 })));

		BOOST_CHECK(database.create_table(cyng::table::make_meta_table<1, 3>("table-2",
			{ "pk", "field-1", "field-2", "field-2" },
			{ cyng::TC_INT32, cyng::TC_STRING, cyng::TC_STRING, cyng::TC_STRING },
			{ 0, 128, 128, 128 })));

		BOOST_CHECK(database.insert("table-1"
			, table::key_generator(1)
			, table::data_generator("a", "a", "a")
			, 1	//	generation
			, boost::uuids::nil_uuid()));
		BOOST_CHECK(database.insert("table-1"
			, table::key_generator(2)
			, table::data_generator("b", "b", "b")
			, 1	//	generation
			, boost::uuids::nil_uuid()));

		//	std::string const& name, cyng::table::key_type const& key, param_t const& param, boost::uuids::uuid source
		BOOST_CHECK(database.multi_modify("table-1"
			, table::key_generator(1)
			, param_factory("field-2", "new")
			, boost::uuids::nil_uuid()
			, [&](cyng::table::key_type const& key, param_t const& param, boost::uuids::uuid source, store::table* t1, const store::table* t2)->bool {

			//
			//	manipulate table t2 at the same time
			//

			//std::cout << t2->meta().get_name() << std::endl;
			return t1->modify(key, param, source);
		}, store::read_access("table-2")));

		database.access([](store::table const* t1, store::table const* t2)->void {
			auto rec = t1->lookup(table::key_generator(1));
			BOOST_CHECK_EQUAL(value_cast<std::string>(rec["field-2"], ""), "new");
		}, store::read_access("table-1"), store::read_access("table-2"));
		return true;
	}

}

ext: cpp

max_stars_repo_name: solosTec/cyng

max_issues_repo_name: solosTec/cyng

max_forks_repo_name: solosTec/cyng


text:
// Copyright 2018 Victor Smirnov
//
// 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.

#pragma once

#include <memoria/core/types.hpp>
#include <memoria/core/linked/common/linked_hash.hpp>

#include <boost/utility/string_view.hpp>

#include <unicode/ustring.h>
#include "u_string_capi.hpp"

#include <string>
#include <sstream>
#include <ostream>

namespace memoria {

class U16String;
class U32String;
class UWString;

using U8StringView = boost::string_view;

inline bool is_unicode_space_u8(char codeunit)
{
    switch (codeunit) {
        case '\r':
        case '\n':
        case '\t':
        case 0x20: return true;
    }

    return false;
}

class U8String {
public:
    using CharT = char;
    using value_type = CharT;
private:
    using ContentT = std::basic_string<CharT>;

    ContentT content_;

    friend class U16String;
    friend class U32String;

    template <typename T2>
    friend std::basic_ostream<char, T2>& operator<<(std::basic_ostream<char, T2>&, const U8String&);

public:
    static const size_t NPOS = ContentT::npos;

    U8String() = default;
    U8String(const U8String&) = default;
    U8String(U8String&&) = default;

    U8String(const CharT* data): content_(data){}
    U8String(const CharT* data, size_t size): content_(data, size){}

    U8String(const ContentT& other): content_(other) {}
    U8String(ContentT&& other): content_(std::move(other)) {}

    U8String(size_t size, CharT code_unit): content_(size, code_unit) {}

    U8String(U8StringView str): content_(str.data(), str.size()) {}

    explicit U8String(const U16String& other);

    bool operator==(const U8String& other) const {
        return content_ == other.content_;
    }

    bool operator!=(const U8String& other) const {
        return content_ != other.content_;
    }

    bool operator>(const U8String& other) const {
        return content_ > other.content_;
    }

    bool operator<(const U8String& other) const {
        return content_ < other.content_;
    }

    bool operator>=(const U8String& other) const {
        return content_ >= other.content_;
    }

    bool operator<=(const U8String& other) const {
        return content_ <= other.content_;
    }

    bool operator!=(const CharT* other) const {
        return content_ != other;
    }

    bool operator==(const CharT* other) const {
        return content_ == other;
    }

    bool operator>(const CharT* other) const {
        return content_ > other;
    }

    bool operator==(const U8StringView& other) const {
        return content_ == other;
    }

    bool operator<(const CharT* other) const {
        return content_ < other;
    }

    bool operator>=(const CharT* other) const {
        return content_ >= other;
    }

    bool operator<=(const CharT* other) const {
        return content_ <= other;
    }

    U8String& operator=(const U8String& other) {
        content_ = other.content_;
        return *this;
    }

    U8String& operator=(U8String&& other) {
        content_ = std::move(other.content_);
        return *this;
    }

    U8String& operator+=(const U8String& other)
    {
        content_ += other.content_;
        return *this;
    }

    U8String operator+(const U8String& other) const
    {
        return U8String(content_ + other.content_);
    }

    CharT& operator[](size_t idx) {
        return content_[idx];
    }

    const CharT& operator[](size_t idx) const {
        return content_[idx];
    }

    CharT& code_unit_at(size_t idx) {
        return content_[idx];
    }

    const CharT& code_unit_at(size_t idx) const {
        return content_[idx];
    }

    size_t size() const {
        return content_.size();
    }

    size_t length() const {
        return content_.length();
    }

    int32_t compare(const U8String& other) const {
        return content_.compare(other.content_);
    }

    const U8String& to_u8() const noexcept {return *this;}

    U16String to_u16() const;
    U32String to_u32() const;
    UWString to_uwstring() const;

    const ContentT& to_std_string() const {
        return content_;
    }

    ContentT& to_std_string() {
        return content_;
    }

    operator ContentT&() {
        return content_;
    }

    operator const ContentT&() const {
        return content_;
    }

    operator U8StringView() const
    {
        return U8StringView(content_);
    }

    U8StringView view() const {
        return U8StringView(content_);
    }

    CharT* data() {
        return &content_[0];
    }

    const CharT* data() const {
        return content_.data();
    }

    size_t find_first_of(const U8String& str) const {
        return content_.find_first_of(str.content_);
    }

    size_t find_first_of(const char* str, size_t pos, size_t count) const {
        return content_.find_first_of(str, pos, count);
    }

    size_t find_first_of(const char* str, size_t pos = 0) const {
        return content_.find_first_of(str, pos);
    }

    size_t find_first_of(char codeunit, size_t pos = 0) const {
        return content_.find_first_of(codeunit, pos);
    }

    size_t find_first_not_of(const U8String& str) const {
        return content_.find_first_not_of(str.content_);
    }

    size_t find_first_not_of(const char* str, size_t pos, size_t count) const {
        return content_.find_first_not_of(str, pos, count);
    }

    size_t find_first_not_of(const char* str, size_t pos = 0) const {
        return content_.find_first_not_of(str, pos);
    }

    size_t find_first_not_of(char codeunit, size_t pos = 0) const {
        return content_.find_first_not_of(codeunit, pos);
    }

    size_t find_last_of(const U8String& str) const {
        return content_.find_last_of(str.content_);
    }

    size_t find_last_of(const char* str, size_t pos, size_t count) const {
        return content_.find_last_of(str, pos, count);
    }

    size_t find_last_of(const char* str, size_t pos = 0) const {
        return content_.find_last_of(str, pos);
    }

    size_t find_last_of(char codeunit, size_t pos = 0) const {
        return content_.find_last_of(codeunit, pos);
    }

    size_t find_last_not_of(const U8String& str) const {
        return content_.find_last_not_of(str.content_);
    }

    size_t find_last_not_of(const char* str, size_t pos, size_t count) const {
        return content_.find_last_not_of(str, pos, count);
    }

    size_t find_last_not_of(const char* str, size_t pos = 0) const {
        return content_.find_last_not_of(str, pos);
    }

    size_t find_last_not_of(char codeunit, size_t pos = 0) const {
        return content_.find_last_not_of(codeunit, pos);
    }

    U8String& trim()
    {
        trim_end();
        trim_start();

        return *this;
    }

    U8String trim_copy() const
    {
        U8String copy = *this;

        copy.trim_end();
        copy.trim_start();

        return copy;
    }

    U8String& trim_start()
    {
        size_t length = content_.size();
        size_t start_idx = 0;

        while (start_idx < length)
        {
            if (!is_unicode_space_u8(content_[start_idx])) {
                break;
            }
            ++start_idx;
        }

        if (start_idx > 0)
        {
            content_.erase(0, start_idx);
        }

        return *this;
    }

    U8String& trim_end()
    {
        size_t length = content_.size();
        int64_t end_idx = length - 1;

        while (end_idx >= 0)
        {
            if (!is_unicode_space_u8(content_[end_idx])) {
                break;
            }
            --end_idx;
        }

        if (end_idx < length - 1){
            content_.erase(end_idx + 1);
        }

        return *this;
    }

    size_t find(const U8String& other, size_t pos = 0) const
    {
        return content_.find(other.content_, pos);
    }

    size_t find(const CharT* other, size_t pos, size_t count) const
    {
        return content_.find(other, pos, count);
    }

    size_t find(const CharT* other, size_t pos = 0) const
    {
        return content_.find(other, pos);
    }

    size_t find(CharT codeunit, size_t pos = 0) const
    {
        return content_.find(codeunit, pos);
    }

    size_t rfind(const U8String& other, size_t pos = 0) const
    {
        return content_.rfind(other.content_, pos);
    }

    size_t rfind(const CharT* other, size_t pos, size_t count) const
    {
        return content_.rfind(other, pos, count);
    }

    size_t rfind(const CharT* other, size_t pos = 0) const
    {
        return content_.rfind(other, pos);
    }

    size_t rfind(CharT codeunit, size_t pos = 0) const
    {
        return content_.rfind(codeunit, pos);
    }

    bool contains(const U8String& other) {
        return find(other) != NPOS;
    }

    bool contains(const CharT* other) {
        return find(other) != NPOS;
    }

    bool contains(CharT other) {
        return find(other) != NPOS;
    }

    U8String substring(size_t start, size_t count = NPOS) const {
        return content_.substr(start, count);
    }

    bool starts_with(const char* str) const
    {
        size_t str_length = std::char_traits<char>::length(str);
        if (size() <= str_length)
        {
            for (size_t c = 0; c < str_length; c++) {
                if (content_[c] != str[c]) {
                    return false;
                }
            }

            return true;
        }
        else {
            return false;
        }
    }

    bool starts_with(const U8String& str) const
    {
        if (size() <= str.size())
        {
            for (size_t c = 0; c < str.size(); c++) {
                if (content_[c] != str.content_[c]) {
                    return false;
                }
            }

            return true;
        }
        else {
            return false;
        }
    }

    bool ends_with(const U8String& str) const
    {
        if (size() <= str.size())
        {
            size_t offset = size() - str.size();
            for (size_t c = 0; c < str.size(); c++) {
                if (content_[c + offset] != str.content_[c]) {
                    return false;
                }
            }

            return true;
        }
        else {
            return false;
        }
    }

    bool ends_with(const char* str) const
    {
        size_t str_length = std::char_traits<char>::length(str);
        if (size() <= str_length)
        {
            size_t offset = size() - str_length;
            for (size_t c = 0; c < str_length; c++) {
                if (content_[c + offset] != str[c]) {
                    return false;
                }
            }

            return true;
        }
        else {
            return false;
        }
    }

    bool is_empty() const {
        return size() == 0;
    }

};

template <typename CharTraits>
inline std::basic_ostream<char, CharTraits>& operator<<(std::basic_ostream<char, CharTraits>& out, const U8String& str)
{
    out << str.content_;
    return out;
}

using U8StringRef = const U8String&;

inline bool compare_gt(const U8StringView& first, const U8StringView& second) {
    return first.compare(second) > 0;
}

inline bool compare_eq(const U8StringView& first, const U8StringView& second) {
    return first.compare(second) == 0;
}

inline bool compare_lt(const U8StringView& first, const U8StringView& second) {
    return first.compare(second) > 0;
}

inline bool compare_ge(const U8StringView& first, const U8StringView& second) {
    return first.compare(second) >= 0;
}

inline bool compare_le(const U8StringView& first, const U8StringView& second) {
    return first.compare(second) <= 0;
}

U8StringView trim_string(U8StringView str);

template <size_t Size, typename Variant>
void append(FNVHasher<Size, Variant>& hasher, const U8String& str)
{
    append(hasher, str.view());
}

inline void swap(memoria::U8String& one, memoria::U8String& two) noexcept {
    std::swap(one.to_std_string(), two.to_std_string());
}

}

namespace std {

template <>
struct hash<memoria::U8String> {
    size_t operator()(const memoria::U8String& str) const noexcept {
        return hash<std::string>()(str.to_std_string());
    }
};

}

ext: hpp

max_stars_repo_name: victor-smirnov/memoria

max_issues_repo_name: victor-smirnov/memoria

max_forks_repo_name: victor-smirnov/memoria


text:
//==================================================================================================
/*!
  @file

  @copyright 2012-2015 NumScale SAS

  Distributed under the Boost Software License, Version 1.0.
  (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
*/
//==================================================================================================
#ifndef BOOST_SIMD_CONSTANT_EPS_HPP_INCLUDED
#define BOOST_SIMD_CONSTANT_EPS_HPP_INCLUDED

#if defined(DOXYGEN_ONLY)
namespace boost { namespace simd
{
  /*!
    @ingroup group-constant
    Generates a value of the chosen type equals to the difference between 1 and the next
    representable value of the chosen type.

    @par Semantic:

    @code
    T r = Eps<T>();
    @endcode

    is equivalent to:

    - if @c T is an integral type:
      @code
      T r = 1;
      @endcode

    - otherwise:
      @code
      T r = std::numeric_limits<boost::dispatch::scalar_of_t<T>>::epsilon();
      @endcode

    @return A value of type @c T equals to the difference between 1 and the next
            representable value of the chosen type.

     @see functional::eps
  **/
  template<typename T> T Eps();

  namespace functional
  {
    /*!
      @ingroup group-callable-constant
      Generates a value of the chosen type equals to the difference between 1 and the next
      representable value of the chosen type.

      @par Semantic:

      For any value @c x of type @c T:
      @code
      T r = simd::functional::eps( boost::simd::as(x) );
      @endcode

      is equivalent to:

      @code
      T r = simd::Eps<T>();
      @endcode

      @return A value of type @c T equals to the difference between 1 and the next
              representable value of the chosen type.

      @see Eps
    **/
    const boost::dispatch::functor<tag::eps_> eps = {};
  }
} }
#endif

#include <boost/simd/constant/definition/eps.hpp>
#include <boost/simd/arch/common/scalar/constant/constant_value.hpp>
#include <boost/simd/arch/common/simd/constant/constant_value.hpp>

#endif


text:
#include <iostream>
#include <boost/format.hpp>

int main(int argc, char *argv[]) {
    std::cout << "CMAKE Boost -- Hello world" << std::endl;
    std::cout << " - App is built using " << BUILD_TYPE << std::endl;

    std::cout << "Boost.Format: " << boost::format("%1% %2% %3%\n") % "10" % "20" % "30";

    (void)argc;
    (void)argv;

    return 0;
}

ext: cc


text:
/*
 *  Phusion Passenger - http://www.modrails.com/
 *  Copyright (c) 2011, 2012 Phusion
 *
 *  "Phusion Passenger" is a trademark of Hongli Lai & Ninh Bui.
 *
 *  Permission is hereby granted, free of charge, to any person obtaining a copy
 *  of this software and associated documentation files (the "Software"), to deal
 *  in the Software without restriction, including without limitation the rights
 *  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 *  copies of the Software, and to permit persons to whom the Software is
 *  furnished to do so, subject to the following conditions:
 *
 *  The above copyright notice and this permission notice shall be included in
 *  all copies or substantial portions of the Software.
 *
 *  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 *  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 *  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 *  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 *  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 *  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 *  THE SOFTWARE.
 */
#include <typeinfo>
#include <boost/make_shared.hpp>
#include <oxt/backtrace.hpp>
#include <ApplicationPool2/Pool.h>
#include <ApplicationPool2/SuperGroup.h>
#include <ApplicationPool2/Group.h>
#include <ApplicationPool2/PipeWatcher.h>
#include <Exceptions.h>

namespace Passenger {
namespace ApplicationPool2 {

using namespace std;
using namespace boost;
using namespace oxt;

template<typename T>
bool
exceptionIsInstanceOf(const tracable_exception &e) {
	try {
		(void) dynamic_cast<T>(e);
		return true;
	} catch (const bad_cast &) {
		return false;
	}
}

#define TRY_COPY_EXCEPTION(klass) \
	do { \
		if (exceptionIsInstanceOf<const klass &>(e)) { \
			return make_shared<klass>( (const klass &) e ); \
		} \
	} while (false)

ExceptionPtr
copyException(const tracable_exception &e) {
	TRY_COPY_EXCEPTION(FileSystemException);
	TRY_COPY_EXCEPTION(TimeRetrievalException);
	TRY_COPY_EXCEPTION(SystemException);

	TRY_COPY_EXCEPTION(FileNotFoundException);
	TRY_COPY_EXCEPTION(EOFException);
	TRY_COPY_EXCEPTION(IOException);

	TRY_COPY_EXCEPTION(ConfigurationException);

	TRY_COPY_EXCEPTION(SpawnException);

	TRY_COPY_EXCEPTION(InvalidModeStringException);
	TRY_COPY_EXCEPTION(ArgumentException);

	TRY_COPY_EXCEPTION(RuntimeException);

	TRY_COPY_EXCEPTION(TimeoutException);

	TRY_COPY_EXCEPTION(NonExistentUserException);
	TRY_COPY_EXCEPTION(NonExistentGroupException);
	TRY_COPY_EXCEPTION(SecurityException);

	TRY_COPY_EXCEPTION(SyntaxError);

	TRY_COPY_EXCEPTION(boost::thread_interrupted);

	return make_shared<tracable_exception>(e);
}

#define TRY_RETHROW_EXCEPTION(klass) \
	do { \
		if (exceptionIsInstanceOf<const klass &>(*e)) { \
			throw klass((const klass &) *e); \
		} \
	} while (false)

void
rethrowException(const ExceptionPtr &e) {
	TRY_RETHROW_EXCEPTION(FileSystemException);
	TRY_RETHROW_EXCEPTION(TimeRetrievalException);
	TRY_RETHROW_EXCEPTION(SystemException);

	TRY_RETHROW_EXCEPTION(FileNotFoundException);
	TRY_RETHROW_EXCEPTION(EOFException);
	TRY_RETHROW_EXCEPTION(IOException);

	TRY_RETHROW_EXCEPTION(ConfigurationException);

	TRY_RETHROW_EXCEPTION(SpawnException);

	TRY_RETHROW_EXCEPTION(InvalidModeStringException);
	TRY_RETHROW_EXCEPTION(ArgumentException);

	TRY_RETHROW_EXCEPTION(RuntimeException);

	TRY_RETHROW_EXCEPTION(TimeoutException);

	TRY_RETHROW_EXCEPTION(NonExistentUserException);
	TRY_RETHROW_EXCEPTION(NonExistentGroupException);
	TRY_RETHROW_EXCEPTION(SecurityException);

	TRY_RETHROW_EXCEPTION(SyntaxError);

	TRY_RETHROW_EXCEPTION(boost::lock_error);
	TRY_RETHROW_EXCEPTION(boost::thread_resource_error);
	TRY_RETHROW_EXCEPTION(boost::unsupported_thread_option);
	TRY_RETHROW_EXCEPTION(boost::invalid_thread_argument);
	TRY_RETHROW_EXCEPTION(boost::thread_permission_error);

	TRY_RETHROW_EXCEPTION(boost::thread_interrupted);
	TRY_RETHROW_EXCEPTION(boost::thread_exception);
	TRY_RETHROW_EXCEPTION(boost::condition_error);

	throw tracable_exception(*e);
}

const SuperGroupPtr
Pool::getSuperGroup(const char *name) {
	return superGroups.get(name);
}

boost::mutex &
SuperGroup::getPoolSyncher(const PoolPtr &pool) {
	return pool->syncher;
}

void
SuperGroup::runAllActions(const vector<Callback> &actions) {
	Pool::runAllActions(actions);
}

string
SuperGroup::generateSecret() const {
	return getPool()->randomGenerator->generateAsciiString(43);
}

void
SuperGroup::createInterruptableThread(const function<void ()> &func, const string &name,
	unsigned int stackSize)
{
	getPool()->interruptableThreads.create_thread(func, name, stackSize);
}

void
SuperGroup::createNonInterruptableThread(const function<void ()> &func, const string &name,
	unsigned int stackSize)
{
	getPool()->nonInterruptableThreads.create_thread(func, name, stackSize);
}

Group::Group(const SuperGroupPtr &_superGroup, const Options &options, const ComponentInfo &info)
	: superGroup(_superGroup),
	  name(_superGroup->name + "#" + info.name),
	  secret(generateSecret(_superGroup)),
	  componentInfo(info)
{
	enabledCount   = 0;
	disablingCount = 0;
	disabledCount  = 0;
	spawner        = getPool()->spawnerFactory->create(options);
	m_spawning     = false;
	m_restarting   = false;
	if (options.restartDir.empty()) {
		restartFile = options.appRoot + "/tmp/restart.txt";
		alwaysRestartFile = options.appRoot + "/always_restart.txt";
	} else {
		restartFile = options.restartDir + "/restart.txt";
		alwaysRestartFile = options.restartDir + "/always_restart.txt";
	}
	resetOptions(options);
}

PoolPtr
Group::getPool() const {
	SuperGroupPtr superGroup = getSuperGroup();
	if (superGroup != NULL) {
		return superGroup->getPool();
	} else {
		return PoolPtr();
	}
}

void
Group::createInterruptableThread(const function<void ()> &func, const string &name,
	unsigned int stackSize)
{
	getPool()->interruptableThreads.create_thread(func, name, stackSize);
}

void
Group::onSessionInitiateFailure(const ProcessPtr &process, Session *session) {
	vector<Callback> actions;

	TRACE_POINT();
	// Standard resource management boilerplate stuff...
	PoolPtr pool = getPool();
	if (OXT_UNLIKELY(pool == NULL)) {
		return;
	}
	unique_lock<boost::mutex> lock(pool->syncher);
	pool = getPool();
	if (OXT_UNLIKELY(pool == NULL) || process->detached()) {
		return;
	}

	UPDATE_TRACE_POINT();
	if (pool->detachProcessUnlocked(process, actions)) {
		P_DEBUG("Could not initiate a session with process " <<
			process->inspect() << ", detached from pool");
	}
	lock.unlock();
	runAllActions(actions);
}

void
Group::onSessionClose(const ProcessPtr &process, Session *session) {
	TRACE_POINT();
	// Standard resource management boilerplate stuff...
	PoolPtr pool = getPool();
	if (OXT_UNLIKELY(pool == NULL)) {
		return;
	}
	unique_lock<boost::mutex> lock(pool->syncher);
	pool = getPool();
	if (OXT_UNLIKELY(pool == NULL) || process->detached()) {
		return;
	}

	P_TRACE(2, "Session closed for process " << process->inspect());
	verifyInvariants();
	UPDATE_TRACE_POINT();

	/* Update statistics. */
	process->sessionClosed(session);
	assert(process->enabled == Process::ENABLED || process->enabled == Process::DISABLING);
	if (process->enabled == Process::ENABLED) {
		pqueue.decrease(process->pqHandle, process->utilization());
	}

	bool maxRequestsReached = options.maxRequests > 0
		&& process->processed >= options.maxRequests;

	/* This group now has a process that's guaranteed to be not at
	 * full utilization...
	 */
	assert(!process->atFullUtilization());
	if (!getWaitlist.empty() && !maxRequestsReached) {
		/* ...so if there are clients waiting for a process to
		 * become available, call them now.
		 */
		UPDATE_TRACE_POINT();
		assignSessionsToGetWaitersQuickly(lock);
	} else if (process->enabled == Process::ENABLED
		&& (!pool->getWaitlist.empty() || maxRequestsReached)
	) {
		/* Someone might be trying to get() a session for a different
		 * group that couldn't be spawned because of lack of pool capacity.
		 * If this group isn't under sufficiently load (as apparent by the
		 * emptiness of the get wait list) then now's a good time to detach
		 * this process or group in order to free capacity.
		 *
		 * TODO: this strategy can cause starvation if all groups are
		 * continuously busy. Yeah if the system is under that much load
		 * it is probably fsck'ed anyway but it may be a good idea in the
		 * future to detach this group even if the wait list is non-empty
		 * in case there's a waiter on the pool's get wait list that's older
		 * than X seconds.
		 *
		 * ---- OR ----
		 *
		 * This process has processed its maximum number of requests,
		 * so we detach it.
		 */
		UPDATE_TRACE_POINT();
		if (!pool->getWaitlist.empty()) {
			P_DEBUG("Process " << process->inspect() << " is no longer at "
				"full capacity; detaching it in order to make room in the pool");
		} else {
			P_DEBUG("Process " << process->inspect() <<
				" has reached its maximum number of requests (" <<
				options.maxRequests << "); detaching it");
		}

		vector<Callback> actions;
		// Will take care of processing pool->getWaitlist.
		pool->detachProcessUnlocked(process, actions);
		pool->verifyInvariants();
		verifyInvariants();
		lock.unlock();
		runAllActions(actions);
	} else if (process->enabled == Process::DISABLING
		&& process->utilization() == 0
		&& enabledCount > 0)
	{
		/* This is a disabling process that is now idle, and there
		 * are enabled processes in the group. Now is a good time
		 * to disable this process.
		 */
		vector<Callback> actions;
		removeProcessFromList(process, disablingProcesses);
		addProcessToList(process, enabledProcesses);
		removeFromDisableWaitlist(process, DR_SUCCESS, actions);
		pool->verifyInvariants();
		verifyInvariants();
		verifyExpensiveInvariants();
		lock.unlock();
		runAllActions(actions);
	}
}

// The 'self' parameter is for keeping the current Group object alive while this thread is running.
void
Group::spawnThreadMain(GroupPtr self, SpawnerPtr spawner, Options options) {
	try {
		spawnThreadRealMain(spawner, options);
	} catch (const thread_interrupted &) {
		// Return.
	}
}

void
Group::spawnThreadRealMain(const SpawnerPtr &spawner, const Options &options) {
	TRACE_POINT();
	this_thread::disable_interruption di;
	this_thread::disable_syscall_interruption dsi;

	bool done = false;
	while (!done) {
		ProcessPtr process;
		ExceptionPtr exception;
		try {
			UPDATE_TRACE_POINT();
			this_thread::restore_interruption ri(di);
			this_thread::restore_syscall_interruption rsi(dsi);
			process = spawner->spawn(options);
		} catch (const thread_interrupted &) {
			return;
		} catch (const tracable_exception &e) {
			exception = copyException(e);
			// Let other (unexpected) exceptions crash the program so
			// gdb can generate a backtrace.
		}
		UPDATE_TRACE_POINT();
		PoolPtr pool = getPool();
		if (pool == NULL) {
			return;
		}
		{
			LockGuard l(pool->debugSyncher);
			pool->spawnLoopIteration++;
			P_TRACE(2, "Entering spawn loop iteration " << pool->spawnLoopIteration);
		}
		unique_lock<boost::mutex> lock(pool->syncher);
		pool = getPool();
		if (pool == NULL) {
			return;
		}

		verifyInvariants();
		assert(m_spawning || m_restarting);

		UPDATE_TRACE_POINT();
		vector<Callback> actions;
		if (process != NULL) {
			attach(process, actions);
			if (getWaitlist.empty()) {
				pool->assignSessionsToGetWaiters(actions);
			} else {
				assignSessionsToGetWaiters(actions);
			}
			P_DEBUG("New process count = " << enabledCount <<
				", remaining get waiters = " << getWaitlist.size());
		} else {
			// TODO: sure this is the best thing? if there are
			// processes currently alive we should just use them.
			P_ERROR("Could not spawn process for group " << name <<
				": " << exception->what());
			if (enabledCount == 0) {
				enableAllDisablingProcesses(actions);
			}
			assignExceptionToGetWaiters(exception, actions);
			pool->assignSessionsToGetWaiters(actions);
			done = true;
		}

		// Temporarily mark this Group as 'not spawning' so
		// that pool->utilization() doesn't take this thread's spawning
		// state into account.
		m_spawning = false;

		done = done
			|| ((unsigned long) enabledCount >= options.minProcesses && getWaitlist.empty())
			|| pool->atFullCapacity(false)
			|| m_restarting;
		m_spawning = !done;
		if (done) {
			if (m_restarting) {
				P_DEBUG("Spawn loop aborted because the group is being restarted");
			} else {
				P_DEBUG("Spawn loop done");
			}
		} else {
			P_DEBUG("Continue spawning");
		}

		UPDATE_TRACE_POINT();
		verifyInvariants();
		verifyExpensiveInvariants();
		lock.unlock();
		runAllActions(actions);
	}
}

bool
Group::shouldSpawn() const {
	return !spawning()
		&& (enabledCount == 0 || pqueue.top()->atFullCapacity())
		&& !getPool()->atFullCapacity(false);
}

void
Group::restart(const Options &options) {
	vector<Callback> actions;

	assert(!m_restarting);
	P_DEBUG("Restarting group " << name);
	m_spawning = false;
	m_restarting = true;
	detachAll(actions);
	getPool()->nonInterruptableThreads.create_thread(
		boost::bind(&Group::finalizeRestart, this, shared_from_this(), options.copyAndPersist(),
			getPool()->spawnerFactory, actions),
		"Group restarter: " + name,
		POOL_HELPER_THREAD_STACK_SIZE
	);
}

// The 'self' parameter is for keeping the current Group object alive while this thread is running.
void
Group::finalizeRestart(GroupPtr self, Options options, SpawnerFactoryPtr spawnerFactory,
	vector<Callback> postLockActions)
{
	TRACE_POINT();

	Pool::runAllActions(postLockActions);
	postLockActions.clear();

	// Create a new spawner.
	SpawnerPtr newSpawner = spawnerFactory->create(options);
	SpawnerPtr oldSpawner;

	// Standard resource management boilerplate stuff...
	UPDATE_TRACE_POINT();
	PoolPtr pool = getPool();
	if (OXT_UNLIKELY(pool == NULL)) {
		return;
	}
	LockGuard l(pool->syncher);
	pool = getPool();
	if (OXT_UNLIKELY(pool == NULL)) {
		return;
	}

	// Run some sanity checks.
	verifyInvariants();
	verifyExpensiveInvariants();
	assert(m_restarting);
	UPDATE_TRACE_POINT();

	// Atomically swap the new spawner with the old one.
	resetOptions(options);
	oldSpawner = spawner;
	spawner    = newSpawner;

	m_restarting = false;
	if (!getWaitlist.empty()) {
		spawn();
	}
	P_DEBUG("Restart of group " << name << " done");
	verifyInvariants();
	Pool::runAllActions(postLockActions);
	// oldSpawner will now be destroyed, outside the lock.
}

string
Group::generateSecret(const SuperGroupPtr &superGroup) {
	return superGroup->getPool()->randomGenerator->generateAsciiString(43);
}

// Thread-safe
SuperGroupPtr
Process::getSuperGroup() const {
	GroupPtr group = getGroup();
	if (group != NULL) {
		return group->getSuperGroup();
	} else {
		return SuperGroupPtr();
	}
}

string
Process::inspect() const {
	stringstream result;
	result << "(pid=";
	result << pid;
	GroupPtr group = getGroup();
	if (group != NULL) {
		result << ", group=";
		result << group->name;
	}
	result << ")";
	return result.str();
}

const string &
Session::getConnectPassword() const {
	return process->connectPassword;
}

pid_t
Session::getPid() const {
	return process->pid;
}

const string &
Session::getGupid() const {
	return process->gupid;
}

PipeWatcher::PipeWatcher(
	const SafeLibevPtr &_libev,
	const FileDescriptor &_fd,
	int _fdToForwardTo)
	: libev(_libev),
	  fd(_fd),
	  fdToForwardTo(_fdToForwardTo)
{
	watcher.set(fd, ev::READ);
	watcher.set<PipeWatcher, &PipeWatcher::onReadable>(this);
}

PipeWatcher::~PipeWatcher() {
	libev->stop(watcher);
}

void
PipeWatcher::start() {
	selfPointer = shared_from_this();
	libev->start(watcher);
}

void
PipeWatcher::onReadable(ev::io &io, int revents) {
	char buf[1024 * 8];
	ssize_t ret;

	ret = read(fd, buf, sizeof(buf));
	if (ret <= 0) {
		if (ret != -1 || errno != EAGAIN) {
			libev->stop(watcher);
			selfPointer.reset();
		}
	} else if (fdToForwardTo != -1) {
		// Don't care about errors.
		write(fdToForwardTo, buf, ret);
	}
}

} // namespace ApplicationPool2
} // namespace Passenger

max_stars_repo_name: pkmiec/passenger

max_issues_repo_name: pkmiec/passenger

max_forks_repo_name: pkmiec/passenger