<commit_before>/*****************************************************************************************
 *                                                                                *
 * OpenSpace                                                                             *
 *                                                                                *
 * Copyright (c) 2014-2022                                                               *
 *                                                                                *
 * 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 <openspace/rendering/renderable.h>

#include <openspace/camera/camera.h>
#include <openspace/documentation/documentation.h>
#include <openspace/documentation/verifier.h>
#include <openspace/engine/globals.h>
#include <openspace/events/event.h>
#include <openspace/events/eventengine.h>
#include <openspace/navigation/navigationhandler.h>
#include <openspace/scene/scenegraphnode.h>
#include <openspace/util/factorymanager.h>
#include <openspace/util/memorymanager.h>
#include <openspace/util/updatestructures.h>
#include <ghoul/misc/profiling.h>
#include <ghoul/opengl/programobject.h>
#include <optional>

namespace {
    constexpr std::string_view KeyType = "Type";

    constexpr openspace::properties::Property::PropertyInfo EnabledInfo = {
        "Enabled",
        "Is Enabled",
        "This setting determines whether this object will be visible or not"
    };

    constexpr openspace::properties::Property::PropertyInfo OpacityInfo = {
        "Opacity",
        "Opacity",
        "This value determines the opacity of this renderable. A value of 0 means "
        "completely transparent"
    };

    constexpr openspace::properties::Property::PropertyInfo FadeInfo = {
        "Fade",
        "Fade",
        "This value is used by the system to be able to fade out renderables "
        "independently from the Opacity value selected by the user. This value should "
        "not be directly manipulated through a user interface, but instead used by other "
        "components of the system programmatically",
        // The Developer mode should be used once the properties in the UI listen to this
        // openspace::properties::Property::Visibility::Developer
        openspace::properties::Property::Visibility::Hidden
    };

    constexpr openspace::properties::Property::PropertyInfo RenderableTypeInfo = {
        "Type",
        "Renderable Type",
        "This tells the type of the renderable",
        openspace::properties::Property::Visibility::Hidden
    };

    constexpr openspace::properties::Property::PropertyInfo RenderableRenderBinModeInfo =
    {
        "RenderBinMode",
        "Render Bin Mode",
        "This value specifies if the renderable should be rendered in the Background,"
        "Opaque, Pre/PostDeferredTransparency, or Overlay rendering step",
        openspace::properties::Property::Visibility::Developer
    };

    constexpr openspace::properties::Property::PropertyInfo DimInAtmosphereInfo = {
        "DimInAtmosphere",
        "Dim In Atmosphere",
        "Enables/Disables if the object should be dimmed if the camera is in an "
        "atmosphere",
        openspace::properties::Property::Visibility::Developer
    };

    struct [[codegen::Dictionary(Renderable)]] Parameters {
        // [[codegen::verbatim(EnabledInfo.description)]]
        std::optional<bool> enabled;

        // [[codegen::verbatim(OpacityInfo.description)]]
        std::optional<float> opacity [[codegen::inrange(0.0, 1.0)]];

        // A single tag or a list of tags that this renderable will respond to when
        // setting properties
        std::optional<std::variant<std::vector<std::string>, std::string>> tag;

        // [[codegen::verbatim(RenderableTypeInfo.description)]]
        std::optional<std::string> type;

        // Fragile! Keep in sync with documentation
        enum class [[codegen::map(openspace::Renderable::RenderBin)]] RenderBinMode {
            Background,
            Opaque,
            PreDeferredTransparent,
            PostDeferredTransparent,
            Overlay
        };

        // [[codegen::verbatim(RenderableRenderBinModeInfo.description)]]
        std::optional<RenderBinMode> renderBinMode;

        // [[codegen::verbatim(DimInAtmosphereInfo.description)]]
        std::optional<bool> dimInAtmosphere;
    };
#include "renderable_codegen.cpp"
} // namespace

namespace openspace {

documentation::Documentation Renderable::Documentation() {
    return codegen::doc<Parameters>("renderable");
}

ghoul::mm_unique_ptr<Renderable> Renderable::createFromDictionary(
                                                             ghoul::Dictionary dictionary)
{
    if (!dictionary.hasKey(KeyType)) {
        throw ghoul::RuntimeError("Tried to create Renderable but no 'Type' was found");
    }

    // This should be done in the constructor instead with noexhaustive
    documentation::testSpecificationAndThrow(Documentation(), dictionary, "Renderable");

    std::string renderableType = dictionary.value<std::string>(KeyType);
    ghoul::TemplateFactory<Renderable>* factory =
        FactoryManager::ref().factory<Renderable>();
    ghoul_assert(factory, "Renderable factory did not exist");
    Renderable* result = factory->create(
        renderableType,
        dictionary,
        &global::memoryManager->PersistentMemory
    );
    return ghoul::mm_unique_ptr<Renderable>(result);
}

Renderable::Renderable(const ghoul::Dictionary& dictionary)
    : properties::PropertyOwner({ "Renderable" })
    , _enabled(EnabledInfo, true)
    , _opacity(OpacityInfo, 1.f, 0.f, 1.f)
    , _fade(FadeInfo, 1.f, 0.f, 1.f)
    , _renderableType(RenderableTypeInfo, "Renderable")
    , _dimInAtmosphere(DimInAtmosphereInfo, false)
{
    ZoneScoped

    // I can't come up with a good reason not to do this for all renderables
    registerUpdateRenderBinFromOpacity();

    const Parameters p = codegen::bake<Parameters>(dictionary);

    if (p.tag.has_value()) {
        if (std::holds_alternative<std::string>(*p.tag)) {
            if (!std::get<std::string>(*p.tag).empty()) {
                addTag(std::get<std::string>(*p.tag));
            }
        }
        else {
            ghoul_assert(std::holds_alternative<std::vector<std::string>>(*p.tag), "");
            for (std::string tag : std::get<std::vector<std::string>>(*p.tag)) {
                addTag(std::move(tag));
            }
        }
    }

    _enabled = p.enabled.value_or(_enabled);
    addProperty(_enabled);
    _enabled.onChange([this]() {
        if (isEnabled()) {
            global::eventEngine->publishEvent<events::EventRenderableEnabled>(_parent);
        }
        else {
            global::eventEngine->publishEvent<events::EventRenderableDisabled>(_parent);
        }
    });

    _opacity = p.opacity.value_or(_opacity);
    // We don't add the property here as subclasses should decide on their own whether
    // they to expose the opacity or not

    addProperty(_fade);

    // set type for UI
    _renderableType = p.type.value_or(_renderableType);
    addProperty(_renderableType);

    // only used by a few classes such as RenderableTrail and RenderableSphere
    if (p.renderBinMode.has_value()) {
        setRenderBin(codegen::map<Renderable::RenderBin>(*p.renderBinMode));
    }

    _dimInAtmosphere = p.dimInAtmosphere.value_or(_dimInAtmosphere);
    addProperty(_dimInAtmosphere);
}

void Renderable::initialize() {}

void Renderable::initializeGL() {}

void Renderable::deinitialize() {}

void Renderable::deinitializeGL() {}

void Renderable::update(const UpdateData&) {}

void Renderable::render(const RenderData&, RendererTasks&) {}

void Renderable::setBoundingSphere(double boundingSphere) {
    _boundingSphere = boundingSphere;
}

double Renderable::boundingSphere() const {
    return _boundingSphere;
}

void Renderable::setInteractionSphere(double interactionSphere) {
    _interactionSphere = interactionSphere;
}

double Renderable::interactionSphere() const {
    return _interactionSphere;
}

SurfacePositionHandle Renderable::calculateSurfacePositionHandle(
                                                 const glm::dvec3& targetModelSpace) const
{
    const glm::dvec3 directionFromCenterToTarget = glm::normalize(targetModelSpace);
    return {
        directionFromCenterToTarget * _parent->interactionSphere(),
        directionFromCenterToTarget,
        0.0
    };
}

bool Renderable::renderedWithDesiredData() const {
    return true;
}

Renderable::RenderBin Renderable::renderBin() const {
    return _renderBin;
}

void Renderable::setRenderBin(RenderBin bin) {
    _renderBin = bin;
}

bool Renderable::matchesRenderBinMask(int binMask) {
    return binMask & static_cast<int>(renderBin());
}

bool Renderable::isVisible() const {
    return _enabled && _opacity > 0.f && _fade > 0.f;
}

bool Renderable::isReady() const {
    return true;
}

bool Renderable::isEnabled() const {
    return _enabled;
}

bool Renderable::shouldUpdateIfDisabled() const {
    return _shouldUpdateIfDisabled;
}

void Renderable::onEnabledChange(std::function<void(bool)> callback) {
    _enabled.onChange([this, c = std::move(callback)]() {
        c(isEnabled());
    });
}

void Renderable::setRenderBinFromOpacity() {
    if ((_renderBin != Renderable::RenderBin::PostDeferredTransparent) &&
        (_renderBin != Renderable::RenderBin::Overlay))
    {
        const float v = opacity();
        if (v >= 0.f && v < 1.f) {
            setRenderBin(Renderable::RenderBin::PreDeferredTransparent);
        }
        else {
            setRenderBin(Renderable::RenderBin::Opaque);
        }
    }
}

void Renderable::registerUpdateRenderBinFromOpacity() {
    _opacity.onChange([this]() { setRenderBinFromOpacity(); });
    _fade.onChange([this]() { setRenderBinFromOpacity(); });
}

float Renderable::opacity() const {
    // Rendering should depend on if camera is in the atmosphere and if camera is at the
    // dark part of the globe
    return _dimInAtmosphere ?
        _opacity * _fade * global::navigationHandler->camera()->atmosphereDimmingFactor() :
        _opacity * _fade;
}
}  // namespace openspace
<commit_msg>Clarify info for the the Dim In Atmosphere property<commit_after>/*****************************************************************************************
 *                                                                                *
 * OpenSpace                                                                             *
 *                                                                                *
 * Copyright (c) 2014-2022                                                               *
 *                                                                                *
 * 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 <openspace/rendering/renderable.h>

#include <openspace/camera/camera.h>
#include <openspace/documentation/documentation.h>
#include <openspace/documentation/verifier.h>
#include <openspace/engine/globals.h>
#include <openspace/events/event.h>
#include <openspace/events/eventengine.h>
#include <openspace/navigation/navigationhandler.h>
#include <openspace/scene/scenegraphnode.h>
#include <openspace/util/factorymanager.h>
#include <openspace/util/memorymanager.h>
#include <openspace/util/updatestructures.h>
#include <ghoul/misc/profiling.h>
#include <ghoul/opengl/programobject.h>
#include <optional>

namespace {
    constexpr std::string_view KeyType = "Type";

    constexpr openspace::properties::Property::PropertyInfo EnabledInfo = {
        "Enabled",
        "Is Enabled",
        "This setting determines whether this object will be visible or not"
    };

    constexpr openspace::properties::Property::PropertyInfo OpacityInfo = {
        "Opacity",
        "Opacity",
        "This value determines the opacity of this renderable. A value of 0 means "
        "completely transparent"
    };

    constexpr openspace::properties::Property::PropertyInfo FadeInfo = {
        "Fade",
        "Fade",
        "This value is used by the system to be able to fade out renderables "
        "independently from the Opacity value selected by the user. This value should "
        "not be directly manipulated through a user interface, but instead used by other "
        "components of the system programmatically",
        // The Developer mode should be used once the properties in the UI listen to this
        // openspace::properties::Property::Visibility::Developer
        openspace::properties::Property::Visibility::Hidden
    };

    constexpr openspace::properties::Property::PropertyInfo RenderableTypeInfo = {
        "Type",
        "Renderable Type",
        "This tells the type of the renderable",
        openspace::properties::Property::Visibility::Hidden
    };

    constexpr openspace::properties::Property::PropertyInfo RenderableRenderBinModeInfo =
    {
        "RenderBinMode",
        "Render Bin Mode",
        "This value specifies if the renderable should be rendered in the Background,"
        "Opaque, Pre/PostDeferredTransparency, or Overlay rendering step",
        openspace::properties::Property::Visibility::Developer
    };

    constexpr openspace::properties::Property::PropertyInfo DimInAtmosphereInfo = {
        "DimInAtmosphere",
        "Dim In Atmosphere",
        "Enables/Disables if the object should be dimmed when the camera is in the "
        "sunny part of an atmosphere",
        openspace::properties::Property::Visibility::Developer
    };

    struct [[codegen::Dictionary(Renderable)]] Parameters {
        // [[codegen::verbatim(EnabledInfo.description)]]
        std::optional<bool> enabled;

        // [[codegen::verbatim(OpacityInfo.description)]]
        std::optional<float> opacity [[codegen::inrange(0.0, 1.0)]];

        // A single tag or a list of tags that this renderable will respond to when
        // setting properties
        std::optional<std::variant<std::vector<std::string>, std::string>> tag;

        // [[codegen::verbatim(RenderableTypeInfo.description)]]
        std::optional<std::string> type;

        // Fragile! Keep in sync with documentation
        enum class [[codegen::map(openspace::Renderable::RenderBin)]] RenderBinMode {
            Background,
            Opaque,
            PreDeferredTransparent,
            PostDeferredTransparent,
            Overlay
        };

        // [[codegen::verbatim(RenderableRenderBinModeInfo.description)]]
        std::optional<RenderBinMode> renderBinMode;

        // [[codegen::verbatim(DimInAtmosphereInfo.description)]]
        std::optional<bool> dimInAtmosphere;
    };
#include "renderable_codegen.cpp"
} // namespace

namespace openspace {

documentation::Documentation Renderable::Documentation() {
    return codegen::doc<Parameters>("renderable");
}

ghoul::mm_unique_ptr<Renderable> Renderable::createFromDictionary(
                                                             ghoul::Dictionary dictionary)
{
    if (!dictionary.hasKey(KeyType)) {
        throw ghoul::RuntimeError("Tried to create Renderable but no 'Type' was found");
    }

    // This should be done in the constructor instead with noexhaustive
    documentation::testSpecificationAndThrow(Documentation(), dictionary, "Renderable");

    std::string renderableType = dictionary.value<std::string>(KeyType);
    ghoul::TemplateFactory<Renderable>* factory =
        FactoryManager::ref().factory<Renderable>();
    ghoul_assert(factory, "Renderable factory did not exist");
    Renderable* result = factory->create(
        renderableType,
        dictionary,
        &global::memoryManager->PersistentMemory
    );
    return ghoul::mm_unique_ptr<Renderable>(result);
}

Renderable::Renderable(const ghoul::Dictionary& dictionary)
    : properties::PropertyOwner({ "Renderable" })
    , _enabled(EnabledInfo, true)
    , _opacity(OpacityInfo, 1.f, 0.f, 1.f)
    , _fade(FadeInfo, 1.f, 0.f, 1.f)
    , _renderableType(RenderableTypeInfo, "Renderable")
    , _dimInAtmosphere(DimInAtmosphereInfo, false)
{
    ZoneScoped

    // I can't come up with a good reason not to do this for all renderables
    registerUpdateRenderBinFromOpacity();

    const Parameters p = codegen::bake<Parameters>(dictionary);

    if (p.tag.has_value()) {
        if (std::holds_alternative<std::string>(*p.tag)) {
            if (!std::get<std::string>(*p.tag).empty()) {
                addTag(std::get<std::string>(*p.tag));
            }
        }
        else {
            ghoul_assert(std::holds_alternative<std::vector<std::string>>(*p.tag), "");
            for (std::string tag : std::get<std::vector<std::string>>(*p.tag)) {
                addTag(std::move(tag));
            }
        }
    }

    _enabled = p.enabled.value_or(_enabled);
    addProperty(_enabled);
    _enabled.onChange([this]() {
        if (isEnabled()) {
            global::eventEngine->publishEvent<events::EventRenderableEnabled>(_parent);
        }
        else {
            global::eventEngine->publishEvent<events::EventRenderableDisabled>(_parent);
        }
    });

    _opacity = p.opacity.value_or(_opacity);
    // We don't add the property here as subclasses should decide on their own whether
    // they to expose the opacity or not

    addProperty(_fade);

    // set type for UI
    _renderableType = p.type.value_or(_renderableType);
    addProperty(_renderableType);

    // only used by a few classes such as RenderableTrail and RenderableSphere
    if (p.renderBinMode.has_value()) {
        setRenderBin(codegen::map<Renderable::RenderBin>(*p.renderBinMode));
    }

    _dimInAtmosphere = p.dimInAtmosphere.value_or(_dimInAtmosphere);
    addProperty(_dimInAtmosphere);
}

void Renderable::initialize() {}

void Renderable::initializeGL() {}

void Renderable::deinitialize() {}

void Renderable::deinitializeGL() {}

void Renderable::update(const UpdateData&) {}

void Renderable::render(const RenderData&, RendererTasks&) {}

void Renderable::setBoundingSphere(double boundingSphere) {
    _boundingSphere = boundingSphere;
}

double Renderable::boundingSphere() const {
    return _boundingSphere;
}

void Renderable::setInteractionSphere(double interactionSphere) {
    _interactionSphere = interactionSphere;
}

double Renderable::interactionSphere() const {
    return _interactionSphere;
}

SurfacePositionHandle Renderable::calculateSurfacePositionHandle(
                                                 const glm::dvec3& targetModelSpace) const
{
    const glm::dvec3 directionFromCenterToTarget = glm::normalize(targetModelSpace);
    return {
        directionFromCenterToTarget * _parent->interactionSphere(),
        directionFromCenterToTarget,
        0.0
    };
}

bool Renderable::renderedWithDesiredData() const {
    return true;
}

Renderable::RenderBin Renderable::renderBin() const {
    return _renderBin;
}

void Renderable::setRenderBin(RenderBin bin) {
    _renderBin = bin;
}

bool Renderable::matchesRenderBinMask(int binMask) {
    return binMask & static_cast<int>(renderBin());
}

bool Renderable::isVisible() const {
    return _enabled && _opacity > 0.f && _fade > 0.f;
}

bool Renderable::isReady() const {
    return true;
}

bool Renderable::isEnabled() const {
    return _enabled;
}

bool Renderable::shouldUpdateIfDisabled() const {
    return _shouldUpdateIfDisabled;
}

void Renderable::onEnabledChange(std::function<void(bool)> callback) {
    _enabled.onChange([this, c = std::move(callback)]() {
        c(isEnabled());
    });
}

void Renderable::setRenderBinFromOpacity() {
    if ((_renderBin != Renderable::RenderBin::PostDeferredTransparent) &&
        (_renderBin != Renderable::RenderBin::Overlay))
    {
        const float v = opacity();
        if (v >= 0.f && v < 1.f) {
            setRenderBin(Renderable::RenderBin::PreDeferredTransparent);
        }
        else {
            setRenderBin(Renderable::RenderBin::Opaque);
        }
    }
}

void Renderable::registerUpdateRenderBinFromOpacity() {
    _opacity.onChange([this]() { setRenderBinFromOpacity(); });
    _fade.onChange([this]() { setRenderBinFromOpacity(); });
}

float Renderable::opacity() const {
    // Rendering should depend on if camera is in the atmosphere and if camera is at the
    // dark part of the globe
    return _dimInAtmosphere ?
        _opacity * _fade * global::navigationHandler->camera()->atmosphereDimmingFactor() :
        _opacity * _fade;
}
}  // namespace openspace
<|endoftext|>


<commit_before>#include <rendering/texture_2d.h>

#include <unordered_map>

namespace rendering {

namespace {

struct texture_format_traits {
    GLint internalformat;
    GLenum format;
    GLenum type;
};

std::unordered_map<texture_2d::texture_format, texture_format_traits> format_traits = {
    { texture_2d::TEXTURE_FORMAT_RGBA8, {GL_RGBA8, GL_RGBA, GL_BYTE}},
    { texture_2d::TEXTURE_FORMAT_RG16F, {GL_RG16F, GL_RG, GL_HALF_FLOAT}},
};

} // unnamed namespace

texture_2d::texture_2d(const util::extent& extent, texture_format format, const void *data)
{
    glGenTextures(1, &tex);
    glBindTexture(GL_TEXTURE_2D, tex);
    auto traits = format_traits[format];
    glTexImage2D(GL_TEXTURE_2D, 0, format, GLsizei(extent.width), GLsizei(extent.height), 0, traits.format, traits.type, data);
    GL_CHECK();
}

} // namespace rendering
<commit_msg>workaround texture state destruction caused by texture_2d ctor<commit_after>#include <rendering/texture_2d.h>

#include <unordered_map>

namespace rendering {

namespace {

struct texture_format_traits {
    GLint internalformat;
    GLenum format;
    GLenum type;
};

std::unordered_map<texture_2d::texture_format, texture_format_traits> format_traits = {
    { texture_2d::TEXTURE_FORMAT_RGBA8, {GL_RGBA8, GL_RGBA, GL_BYTE}},
    { texture_2d::TEXTURE_FORMAT_RG16F, {GL_RG16F, GL_RG, GL_HALF_FLOAT}},
};

} // unnamed namespace

texture_2d::texture_2d(const util::extent& extent, texture_format format, const void *data)
{
    glGenTextures(1, &tex);
    glActiveTexture(GL_TEXTURE5);
    glBindTexture(GL_TEXTURE_2D, tex);
    auto traits = format_traits[format];
    glTexImage2D(GL_TEXTURE_2D, 0, format, GLsizei(extent.width), GLsizei(extent.height), 0, traits.format, traits.type, data);
    GL_CHECK();
    glActiveTexture(GL_TEXTURE0);
}

} // namespace rendering
<|endoftext|>


<commit_before>#ifndef __REPLICATION_PROTOCOL_HPP__
#define __REPLICATION_PROTOCOL_HPP__

#include "errors.hpp"
#include <boost/function.hpp>

#include "arch/arch.hpp"
#include "concurrency/fifo_checker.hpp"
#include "concurrency/drain_semaphore.hpp"
#include "concurrency/mutex.hpp"
#include "containers/scoped_malloc.hpp"
#include "data_provider.hpp"
#include "replication/multistream.hpp"
#include "replication/net_structs.hpp"
#include "replication/heartbeat_manager.hpp"

namespace replication {

template <class T>
struct stream_pair {
    boost::shared_ptr<buffered_data_provider_t> stream;
    unique_malloc_t<T> data;

    /* The `stream_pair()` constructor takes a buffer that contains the beginning of a multipart
    message. It's guaranteed to contain the entire header and the entire key and probably part of
    the value, but it's not guaranteed to contain the entire value. The network logic will later
    fill in the rest of the value. */
    // This uses key_size, which is completely crap.
    stream_pair(const char *beg, const char *end, ssize_t size = 0) : stream(), data() {
        void *p;
        size_t m = sizeof(T) + reinterpret_cast<const T *>(beg)->key_size;

        const char *cutpoint = beg + m;
        {
            unique_malloc_t<T> tmp(beg, cutpoint);
            data = tmp;
        }

        stream.reset(new buffered_data_provider_t(size == 0 ? end - cutpoint : size, &p));

        memcpy(p, cutpoint, end - cutpoint);
    }

    T *operator->() { return data.get(); }
};

class message_callback_t {
public:
    // These could call .swap on their parameter, taking ownership of the pointee.
    virtual void hello(net_hello_t message) = 0;
    virtual void send(scoped_malloc<net_introduce_t>& message) = 0;
    virtual void send(scoped_malloc<net_backfill_t>& message) = 0;
    virtual void send(scoped_malloc<net_backfill_complete_t>& message) = 0;
    virtual void send(scoped_malloc<net_backfill_delete_everything_t>& message) = 0;
    virtual void send(scoped_malloc<net_backfill_delete_t>& message) = 0;
    virtual void send(stream_pair<net_backfill_set_t>& message) = 0;
    virtual void send(scoped_malloc<net_get_cas_t>& message) = 0;
    virtual void send(stream_pair<net_sarc_t>& message) = 0;
    virtual void send(scoped_malloc<net_incr_t>& message) = 0;
    virtual void send(scoped_malloc<net_decr_t>& message) = 0;
    virtual void send(stream_pair<net_append_t>& message) = 0;
    virtual void send(stream_pair<net_prepend_t>& message) = 0;
    virtual void send(scoped_malloc<net_delete_t>& message) = 0;
    virtual void send(scoped_malloc<net_timebarrier_t>& message) = 0;
    virtual void send(scoped_malloc<net_heartbeat_t>& message) = 0;
    virtual void conn_closed() = 0;
    virtual ~message_callback_t() {}
};

struct tracker_obj_t {
    boost::function<void ()> function;
    char *buf;
    size_t bufsize;

    tracker_obj_t(const boost::function<void ()>& _function, char * _buf, size_t _bufsize)
        : function(_function), buf(_buf), bufsize(_bufsize) { }
};

namespace internal {

struct replication_stream_handler_t : public stream_handler_t {
    replication_stream_handler_t(message_callback_t *receiver, heartbeat_receiver_t *hb_receiver) :
            receiver_(receiver), hb_receiver_(hb_receiver), saw_first_part_(false), tracker_obj_(NULL) { }
    ~replication_stream_handler_t() { if(tracker_obj_) delete tracker_obj_; }
    void stream_part(const char *buf, size_t size);
    void end_of_stream();

private:
    message_callback_t *const receiver_;
    heartbeat_receiver_t *hb_receiver_;
    bool saw_first_part_;
    tracker_obj_t *tracker_obj_;
};

struct replication_connection_handler_t : public connection_handler_t {
    void process_hello_message(net_hello_t msg);
    stream_handler_t *new_stream_handler() { return new replication_stream_handler_t(receiver_, hb_receiver_); }
    replication_connection_handler_t(message_callback_t *receiver, heartbeat_receiver_t *hb_receiver) :
            receiver_(receiver), hb_receiver_(hb_receiver) { }
    void conn_closed() { receiver_->conn_closed(); }
private:
    message_callback_t *receiver_;
    heartbeat_receiver_t *hb_receiver_;
};

}  // namespace internal

class repli_stream_t : public heartbeat_sender_t, public heartbeat_receiver_t, public home_thread_mixin_t {
public:
    repli_stream_t(boost::scoped_ptr<tcp_conn_t>& conn, message_callback_t *recv_callback, int heartbeat_timeout);
    ~repli_stream_t();

    // Call shutdown() when you want the repli_stream to stop. shutdown() causes
    // the connection to be closed and conn_closed() to be called.
    void shutdown() {
        unwatch_heartbeat();
        stop_sending_heartbeats();
        try {
            mutex_acquisition_t ak(&outgoing_mutex_); // flush_buffer() would interfere with active writes
            conn_->flush_buffer();
        } catch (tcp_conn_t::write_closed_exc_t &e) {
	    (void)e;
            // Ignore
        }
        conn_->shutdown_read();
    }

    void send(net_introduce_t *msg);
    void send(net_backfill_t *msg);
    void send(net_backfill_complete_t *msg);
    void send(net_backfill_delete_everything_t msg);
    void send(net_backfill_delete_t *msg);
    void send(net_backfill_set_t *msg, const char *key, boost::shared_ptr<data_provider_t> value);
    void send(net_get_cas_t *msg);
    void send(net_sarc_t *msg, const char *key, boost::shared_ptr<data_provider_t> value);
    void send(net_incr_t *msg);
    void send(net_decr_t *msg);
    void send(net_append_t *msg, const char *key, boost::shared_ptr<data_provider_t> value);
    void send(net_prepend_t *msg, const char *key, boost::shared_ptr<data_provider_t> value);
    void send(net_delete_t *msg);
    void send(net_timebarrier_t msg);
    void send(net_heartbeat_t msg);

    void flush();

protected:
    void send_heartbeat() {
        net_heartbeat_t msg;
        msg.padding = 0;
        send(msg);
    }
    void on_heartbeat_timeout() {
        logINF("Terminating connection due to heartbeat timeout.\n");
        shutdown();
    }

private:

    template <class net_struct_type>
    void sendobj(uint8_t msgcode, net_struct_type *msg);

    template <class net_struct_type>
    void sendobj(uint8_t msgcode, net_struct_type *msg, const char *key, boost::shared_ptr<data_provider_t> data);

    void send_hello(const mutex_acquisition_t& proof_of_acquisition);

    void try_write(const void *data, size_t size);

    internal::replication_connection_handler_t conn_handler_;

    /* outgoing_mutex_ is used to prevent messages from being interlaced on the wire */
    mutex_t outgoing_mutex_;

    /* drain_semaphore_ is used to prevent the repli_stream_t from being destroyed while there
    are active calls to send(). */
    drain_semaphore_t drain_semaphore_;

    boost::scoped_ptr<tcp_conn_t> conn_;
};

}  // namespace replication

#endif  // __REPLICATION_PROTOCOL_HPP__
<commit_msg>Don't try to close a closed connection.<commit_after>#ifndef __REPLICATION_PROTOCOL_HPP__
#define __REPLICATION_PROTOCOL_HPP__

#include "errors.hpp"
#include <boost/function.hpp>

#include "arch/arch.hpp"
#include "concurrency/fifo_checker.hpp"
#include "concurrency/drain_semaphore.hpp"
#include "concurrency/mutex.hpp"
#include "containers/scoped_malloc.hpp"
#include "data_provider.hpp"
#include "replication/multistream.hpp"
#include "replication/net_structs.hpp"
#include "replication/heartbeat_manager.hpp"

namespace replication {

template <class T>
struct stream_pair {
    boost::shared_ptr<buffered_data_provider_t> stream;
    unique_malloc_t<T> data;

    /* The `stream_pair()` constructor takes a buffer that contains the beginning of a multipart
    message. It's guaranteed to contain the entire header and the entire key and probably part of
    the value, but it's not guaranteed to contain the entire value. The network logic will later
    fill in the rest of the value. */
    // This uses key_size, which is completely crap.
    stream_pair(const char *beg, const char *end, ssize_t size = 0) : stream(), data() {
        void *p;
        size_t m = sizeof(T) + reinterpret_cast<const T *>(beg)->key_size;

        const char *cutpoint = beg + m;
        {
            unique_malloc_t<T> tmp(beg, cutpoint);
            data = tmp;
        }

        stream.reset(new buffered_data_provider_t(size == 0 ? end - cutpoint : size, &p));

        memcpy(p, cutpoint, end - cutpoint);
    }

    T *operator->() { return data.get(); }
};

class message_callback_t {
public:
    // These could call .swap on their parameter, taking ownership of the pointee.
    virtual void hello(net_hello_t message) = 0;
    virtual void send(scoped_malloc<net_introduce_t>& message) = 0;
    virtual void send(scoped_malloc<net_backfill_t>& message) = 0;
    virtual void send(scoped_malloc<net_backfill_complete_t>& message) = 0;
    virtual void send(scoped_malloc<net_backfill_delete_everything_t>& message) = 0;
    virtual void send(scoped_malloc<net_backfill_delete_t>& message) = 0;
    virtual void send(stream_pair<net_backfill_set_t>& message) = 0;
    virtual void send(scoped_malloc<net_get_cas_t>& message) = 0;
    virtual void send(stream_pair<net_sarc_t>& message) = 0;
    virtual void send(scoped_malloc<net_incr_t>& message) = 0;
    virtual void send(scoped_malloc<net_decr_t>& message) = 0;
    virtual void send(stream_pair<net_append_t>& message) = 0;
    virtual void send(stream_pair<net_prepend_t>& message) = 0;
    virtual void send(scoped_malloc<net_delete_t>& message) = 0;
    virtual void send(scoped_malloc<net_timebarrier_t>& message) = 0;
    virtual void send(scoped_malloc<net_heartbeat_t>& message) = 0;
    virtual void conn_closed() = 0;
    virtual ~message_callback_t() {}
};

struct tracker_obj_t {
    boost::function<void ()> function;
    char *buf;
    size_t bufsize;

    tracker_obj_t(const boost::function<void ()>& _function, char * _buf, size_t _bufsize)
        : function(_function), buf(_buf), bufsize(_bufsize) { }
};

namespace internal {

struct replication_stream_handler_t : public stream_handler_t {
    replication_stream_handler_t(message_callback_t *receiver, heartbeat_receiver_t *hb_receiver) :
            receiver_(receiver), hb_receiver_(hb_receiver), saw_first_part_(false), tracker_obj_(NULL) { }
    ~replication_stream_handler_t() { if(tracker_obj_) delete tracker_obj_; }
    void stream_part(const char *buf, size_t size);
    void end_of_stream();

private:
    message_callback_t *const receiver_;
    heartbeat_receiver_t *hb_receiver_;
    bool saw_first_part_;
    tracker_obj_t *tracker_obj_;
};

struct replication_connection_handler_t : public connection_handler_t {
    void process_hello_message(net_hello_t msg);
    stream_handler_t *new_stream_handler() { return new replication_stream_handler_t(receiver_, hb_receiver_); }
    replication_connection_handler_t(message_callback_t *receiver, heartbeat_receiver_t *hb_receiver) :
            receiver_(receiver), hb_receiver_(hb_receiver) { }
    void conn_closed() { receiver_->conn_closed(); }
private:
    message_callback_t *receiver_;
    heartbeat_receiver_t *hb_receiver_;
};

}  // namespace internal

class repli_stream_t : public heartbeat_sender_t, public heartbeat_receiver_t, public home_thread_mixin_t {
public:
    repli_stream_t(boost::scoped_ptr<tcp_conn_t>& conn, message_callback_t *recv_callback, int heartbeat_timeout);
    ~repli_stream_t();

    // Call shutdown() when you want the repli_stream to stop. shutdown() causes
    // the connection to be closed and conn_closed() to be called.
    void shutdown() {
        unwatch_heartbeat();
        stop_sending_heartbeats();
        try {
            mutex_acquisition_t ak(&outgoing_mutex_); // flush_buffer() would interfere with active writes
            conn_->flush_buffer();
        } catch (tcp_conn_t::write_closed_exc_t &e) {
	    (void)e;
            // Ignore
        }
        if (conn_->is_read_open()) {
            conn_->shutdown_read();
        }
    }

    void send(net_introduce_t *msg);
    void send(net_backfill_t *msg);
    void send(net_backfill_complete_t *msg);
    void send(net_backfill_delete_everything_t msg);
    void send(net_backfill_delete_t *msg);
    void send(net_backfill_set_t *msg, const char *key, boost::shared_ptr<data_provider_t> value);
    void send(net_get_cas_t *msg);
    void send(net_sarc_t *msg, const char *key, boost::shared_ptr<data_provider_t> value);
    void send(net_incr_t *msg);
    void send(net_decr_t *msg);
    void send(net_append_t *msg, const char *key, boost::shared_ptr<data_provider_t> value);
    void send(net_prepend_t *msg, const char *key, boost::shared_ptr<data_provider_t> value);
    void send(net_delete_t *msg);
    void send(net_timebarrier_t msg);
    void send(net_heartbeat_t msg);

    void flush();

protected:
    void send_heartbeat() {
        net_heartbeat_t msg;
        msg.padding = 0;
        send(msg);
    }
    void on_heartbeat_timeout() {
        logINF("Terminating connection due to heartbeat timeout.\n");
        shutdown();
    }

private:

    template <class net_struct_type>
    void sendobj(uint8_t msgcode, net_struct_type *msg);

    template <class net_struct_type>
    void sendobj(uint8_t msgcode, net_struct_type *msg, const char *key, boost::shared_ptr<data_provider_t> data);

    void send_hello(const mutex_acquisition_t& proof_of_acquisition);

    void try_write(const void *data, size_t size);

    internal::replication_connection_handler_t conn_handler_;

    /* outgoing_mutex_ is used to prevent messages from being interlaced on the wire */
    mutex_t outgoing_mutex_;

    /* drain_semaphore_ is used to prevent the repli_stream_t from being destroyed while there
    are active calls to send(). */
    drain_semaphore_t drain_semaphore_;

    boost::scoped_ptr<tcp_conn_t> conn_;
};

}  // namespace replication

#endif  // __REPLICATION_PROTOCOL_HPP__
<|endoftext|>


<commit_before>/*
    This file is part of KDE Kontact.

    Copyright (c) 2003 Cornelius Schumacher <schumacher@kde.org>

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 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 General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.

    As a special exception, permission is given to link this program
    with any edition of Qt, and distribute the resulting executable,
    without including the source code for Qt in the source distribution.
*/

#include "aboutdialog.h"
#include "aboutdialog.moc"

#include "core.h"
#include "plugin.h"

#include <klocale.h>
#include <kiconloader.h>
#include <kaboutdata.h>
#include <kactivelabel.h>
#include <ktextbrowser.h>

#include <qlayout.h>
#include <qlabel.h>

#include <kdebug.h>

using namespace Kontact;

AboutDialog::AboutDialog( Kontact::Core *core, const char *name )
  : KDialogBase( IconList, i18n("About Kontact"), Ok, Ok, core, name, false,
                 true ),
    mCore( core )
{
  addAboutData( i18n("Kontact Container Application"), QString( "kontact" ),
                KGlobal::instance()->aboutData() );

  QPtrList<Plugin> plugins = mCore->pluginList();
  uint i;
  for( i = 0; i < plugins.count(); ++i ) {
    addAboutPlugin( plugins.at( i ) );
  }

  addLicenseText( KGlobal::instance()->aboutData() );
}

void AboutDialog::addAboutPlugin( Kontact::Plugin *plugin )
{
  addAboutData( plugin->title(), plugin->icon(), plugin->aboutData() );
}

void AboutDialog::addAboutData( const QString &title, const QString &icon,
                                const KAboutData *about )
{
  QPixmap pixmap = KGlobal::iconLoader()->loadIcon( icon,
                                                    KIcon::Desktop, 48 );

  QFrame *topFrame = addPage( title, QString::null, pixmap );

  QBoxLayout *topLayout = new QVBoxLayout( topFrame );

  if ( !about ) {
    QLabel *label = new QLabel( i18n("No about information available."),
                                topFrame );
    topLayout->addWidget( label );
  } else {
    QString text;

    text += "
" + about->programName() + "
";

    text += i18n("Version %1
").arg( about->version() );

    if (!about->shortDescription().isEmpty()) {
      text += "
" + about->shortDescription() + "
" +
               about->copyrightStatement() + "
";
    }

    QString home = about->homepage();
    if ( !home.isEmpty() ) {
      text += "" + home + "
";
    }

    text.replace( "\n", "
" );

    KActiveLabel *label = new KActiveLabel( text, topFrame );
	label->setAlignment( AlignTop );
    topLayout->addWidget( label );

    QTextEdit *personView = new QTextEdit( topFrame );
    personView->setReadOnly( true );
    topLayout->addWidget( personView, 1 );

    text = "";

    QValueList<KAboutPerson> authors = about->authors();
    if ( !authors.isEmpty() ) {
      text += i18n("
Authors:
");

      QValueList<KAboutPerson>::ConstIterator it;
      for( it = authors.begin(); it != authors.end(); ++it ) {
        text += formatPerson( (*it).name(), (*it).emailAddress() );
        if (!(*it).task().isEmpty()) text += "" + (*it).task() + "
";
      }
    }

    QValueList<KAboutPerson> credits = about->credits();
    if ( !credits.isEmpty() ) {
      text += i18n("
Thanks to:
");

      QValueList<KAboutPerson>::ConstIterator it;
      for( it = credits.begin(); it != credits.end(); ++it ) {
        text += formatPerson( (*it).name(), (*it).emailAddress() );
        if (!(*it).task().isEmpty()) text += "" + (*it).task() + "
";
      }
    }

    QValueList<KAboutTranslator> translators = about->translators();
    if ( !translators.isEmpty() ) {
      text += i18n("
Translators:
");

      QValueList<KAboutTranslator>::ConstIterator it;
      for( it = translators.begin(); it != translators.end(); ++it ) {
       text += formatPerson( (*it).name(), (*it).emailAddress() );
      }
    }

    personView->setText( text );
  }
}

QString AboutDialog::formatPerson( const QString &name, const QString &email )
{
  QString text = name;
  if ( !email.isEmpty() ) {
    text += " <" + email + ">";
  }
  text += "
";
  return text;
}

void AboutDialog::addLicenseText(const KAboutData *about)
{
  if ( !about || about->license().isEmpty() ) return;

  QPixmap pixmap = KGlobal::iconLoader()->loadIcon( "scripting",
                                                    KIcon::Desktop, 48 );

  QString title = i18n("%1 license").arg(about->programName());

  QFrame *topFrame = addPage( title, QString::null, pixmap );
  QBoxLayout *topLayout = new QVBoxLayout( topFrame );

  KTextBrowser *textBrowser = new KTextBrowser( topFrame );
  textBrowser->setText( QString("
%1
").arg(about->license()) );

  topLayout->addWidget(textBrowser);
}
<commit_msg>Less wide string<commit_after>/*
    This file is part of KDE Kontact.

    Copyright (c) 2003 Cornelius Schumacher <schumacher@kde.org>

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 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 General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.

    As a special exception, permission is given to link this program
    with any edition of Qt, and distribute the resulting executable,
    without including the source code for Qt in the source distribution.
*/

#include "aboutdialog.h"
#include "aboutdialog.moc"

#include "core.h"
#include "plugin.h"

#include <klocale.h>
#include <kiconloader.h>
#include <kaboutdata.h>
#include <kactivelabel.h>
#include <ktextbrowser.h>

#include <qlayout.h>
#include <qlabel.h>

#include <kdebug.h>

using namespace Kontact;

AboutDialog::AboutDialog( Kontact::Core *core, const char *name )
  : KDialogBase( IconList, i18n("About Kontact"), Ok, Ok, core, name, false,
                 true ),
    mCore( core )
{
  addAboutData( i18n("Kontact Container"), QString( "kontact" ),
                KGlobal::instance()->aboutData() );

  QPtrList<Plugin> plugins = mCore->pluginList();
  uint i;
  for( i = 0; i < plugins.count(); ++i ) {
    addAboutPlugin( plugins.at( i ) );
  }

  addLicenseText( KGlobal::instance()->aboutData() );
}

void AboutDialog::addAboutPlugin( Kontact::Plugin *plugin )
{
  addAboutData( plugin->title(), plugin->icon(), plugin->aboutData() );
}

void AboutDialog::addAboutData( const QString &title, const QString &icon,
                                const KAboutData *about )
{
  QPixmap pixmap = KGlobal::iconLoader()->loadIcon( icon,
                                                    KIcon::Desktop, 48 );

  QFrame *topFrame = addPage( title, QString::null, pixmap );

  QBoxLayout *topLayout = new QVBoxLayout( topFrame );

  if ( !about ) {
    QLabel *label = new QLabel( i18n("No about information available."),
                                topFrame );
    topLayout->addWidget( label );
  } else {
    QString text;

    text += "
" + about->programName() + "
";

    text += i18n("Version %1
").arg( about->version() );

    if (!about->shortDescription().isEmpty()) {
      text += "
" + about->shortDescription() + "
" +
               about->copyrightStatement() + "
";
    }

    QString home = about->homepage();
    if ( !home.isEmpty() ) {
      text += "" + home + "
";
    }

    text.replace( "\n", "
" );

    KActiveLabel *label = new KActiveLabel( text, topFrame );
	label->setAlignment( AlignTop );
    topLayout->addWidget( label );

    QTextEdit *personView = new QTextEdit( topFrame );
    personView->setReadOnly( true );
    topLayout->addWidget( personView, 1 );

    text = "";

    QValueList<KAboutPerson> authors = about->authors();
    if ( !authors.isEmpty() ) {
      text += i18n("
Authors:
");

      QValueList<KAboutPerson>::ConstIterator it;
      for( it = authors.begin(); it != authors.end(); ++it ) {
        text += formatPerson( (*it).name(), (*it).emailAddress() );
        if (!(*it).task().isEmpty()) text += "" + (*it).task() + "
";
      }
    }

    QValueList<KAboutPerson> credits = about->credits();
    if ( !credits.isEmpty() ) {
      text += i18n("
Thanks to:
");

      QValueList<KAboutPerson>::ConstIterator it;
      for( it = credits.begin(); it != credits.end(); ++it ) {
        text += formatPerson( (*it).name(), (*it).emailAddress() );
        if (!(*it).task().isEmpty()) text += "" + (*it).task() + "
";
      }
    }

    QValueList<KAboutTranslator> translators = about->translators();
    if ( !translators.isEmpty() ) {
      text += i18n("
Translators:
");

      QValueList<KAboutTranslator>::ConstIterator it;
      for( it = translators.begin(); it != translators.end(); ++it ) {
       text += formatPerson( (*it).name(), (*it).emailAddress() );
      }
    }

    personView->setText( text );
  }
}

QString AboutDialog::formatPerson( const QString &name, const QString &email )
{
  QString text = name;
  if ( !email.isEmpty() ) {
    text += " <" + email + ">";
  }
  text += "
";
  return text;
}

void AboutDialog::addLicenseText(const KAboutData *about)
{
  if ( !about || about->license().isEmpty() ) return;

  QPixmap pixmap = KGlobal::iconLoader()->loadIcon( "scripting",
                                                    KIcon::Desktop, 48 );

  QString title = i18n("%1 license").arg(about->programName());

  QFrame *topFrame = addPage( title, QString::null, pixmap );
  QBoxLayout *topLayout = new QVBoxLayout( topFrame );

  KTextBrowser *textBrowser = new KTextBrowser( topFrame );
  textBrowser->setText( QString("
%1
").arg(about->license()) );

  topLayout->addWidget(textBrowser);
}
<|endoftext|>


<commit_before>/**
 * @file rectifier_function.hpp
 * @author Marcus Edel
 *
 * Definition and implementation of the rectifier function as described by
 * V. Nair and G. E. Hinton.
 *
 * For more information, see the following paper.
 *
 * @code
 * @misc{NairHinton2010,
 *   author = {Vinod Nair, Geoffrey E. Hinton},
 *   title = {Rectified Linear Units Improve Restricted Boltzmann Machines},
 *   year = {2010}
 * }
 * @endcode
 */
#ifndef __MLPACK_METHODS_ANN_ACTIVATION_FUNCTIONS_RECTIFIER_FUNCTION_HPP
#define __MLPACK_METHODS_ANN_ACTIVATION_FUNCTIONS_RECTIFIER_FUNCTION_HPP

#include <mlpack/core.hpp>
#include <algorithm>

namespace mlpack {
namespace ann /** Artificial Neural Network. */ {

/**
 * The rectifier function, defined by
 *
 * @f[
 * f(x) &=& \max(0, x) \\
 * f'(x) &=& \left\{
 *   \begin{array}{lr}
 *     1 & : x > 0 \\
 *     0 & : x \le 0
 *   \end{array}
 * \right
 * @f]
 */
class RectifierFunction
{
 public:
  /**
   * Computes the rectifier function.
   *
   * @param x Input data.
   * @return f(x).
   */
  static double fn(const double x)
  {
    return std::max(0.0, x);
  }

  /**
   * Computes the rectifier function.
   *
   * @param x Input data.
   * @param y The resulting output activation.
   */
  template<typename InputVecType, typename OutputVecType>
  static void fn(const InputVecType& x, OutputVecType& y)
  {
    y = x;
    y = arma::max(arma::zeros<OutputVecType>(x.n_elem), x);
  }

  /**
   * Computes the first derivative of the rectifier function.
   *
   * @param x Input data.
   * @return f'(x)
   */
  static double deriv(const double y)
  {
    return y > 0 ? 1 : 0;
  }

  /**
   * Computes the first derivatives of the rectifier function.
   *
   * @param y Input activations.
   * @param x The resulting derivatives.
   */
  template<typename InputVecType, typename OutputVecType>
  static void deriv(const InputVecType& y, OutputVecType& x)
  {
    x = y;
    x.transform( [](double y) { return deriv(y); } );
  }
}; // class RectifierFunction

}; // namespace ann
}; // namespace mlpack

#endif
<commit_msg>Refactor to support 3rd-order tensors.<commit_after>/**
 * @file rectifier_function.hpp
 * @author Marcus Edel
 *
 * Definition and implementation of the rectifier function as described by
 * V. Nair and G. E. Hinton.
 *
 * For more information, see the following paper.
 *
 * @code
 * @misc{NairHinton2010,
 *   author = {Vinod Nair, Geoffrey E. Hinton},
 *   title = {Rectified Linear Units Improve Restricted Boltzmann Machines},
 *   year = {2010}
 * }
 * @endcode
 */
#ifndef __MLPACK_METHODS_ANN_ACTIVATION_FUNCTIONS_RECTIFIER_FUNCTION_HPP
#define __MLPACK_METHODS_ANN_ACTIVATION_FUNCTIONS_RECTIFIER_FUNCTION_HPP

#include <mlpack/core.hpp>
#include <algorithm>

namespace mlpack {
namespace ann /** Artificial Neural Network. */ {

/**
 * The rectifier function, defined by
 *
 * @f[
 * f(x) &=& \max(0, x) \\
 * f'(x) &=& \left\{
 *   \begin{array}{lr}
 *     1 & : x > 0 \\
 *     0 & : x \le 0
 *   \end{array}
 * \right
 * @f]
 */
class RectifierFunction
{
 public:
  /**
   * Computes the rectifier function.
   *
   * @param x Input data.
   * @return f(x).
   */
  static double fn(const double x)
  {
    return std::max(0.0, x);
  }

  /**
   * Computes the rectifier function using a dense matrix as input.
   *
   * @param x Input data.
   * @param y The resulting output activation.
   */
  template<typename eT>
  static void fn(const arma::Mat<eT>& x, arma::Mat<eT>& y)
  {
    y = arma::max(arma::zeros<arma::Mat<eT> >(x.n_rows, x.n_cols), x);
  }

  /**
   * Computes the rectifier function using a 3rd-order tensor as input.
   *
   * @param x Input data.
   * @param y The resulting output activation.
   */
  template<typename eT>
  static void fn(const arma::Cube<eT>& x, arma::Cube<eT>& y)
  {
    y = x;
    for (size_t s = 0; s < x.n_slices; s++)
      fn(x.slice(s), y.slice(s));
  }

  /**
   * Computes the first derivative of the rectifier function.
   *
   * @param x Input data.
   * @return f'(x)
   */
  static double deriv(const double y)
  {
    return y > 0;
  }

  /**
   * Computes the first derivatives of the rectifier function.
   *
   * @param y Input activations.
   * @param x The resulting derivatives.
   */
  template<typename InputType, typename OutputType>
  static void deriv(const InputType& y, OutputType& x)
  {
    x = y;
    x.transform( [](double y) { return deriv(y); } );
  }
}; // class RectifierFunction

}; // namespace ann
}; // namespace mlpack

#endif
<|endoftext|>


<commit_before>#include "model.h"

Model::Model(const Data& data){
    //initiate the tumour with a homogenous population with the type_p=1 and type_i=1
	int i;
    double n=data.return_initial_cellnumber();
	//define a matrix whose entries is initialized with 0
	double max_num_row=data.return_max_prolif_types();
	double max_num_column=data.return_max_immun_types();
	for(i=0;i<max_num_row;i++)
	{
    std::vector<double> row(max_num_column,0);
    _cells.push_back(row);
    }
	//define the first phenotype:  type_p=1 and type_i=1 with an initial size of n
	_cell[0][0]=n;
}

double Model::return_Ccell_number(int type_p, int type_i) const
{
    return _cells[type_p][type_i];
}

void Model::set_Ccell_number(int type_p, int type_i, double number){
	double max_num_row=data.return_max_prolif_types();
	double max_num_column=data.return_max_immun_types();
	if((type_p>=max_num_row)||(type_i>=max_num_column)) exit(1);
    _cells[type_p][type_i]=number;
}

void output(double dt, std::ostream & os){

}<commit_msg>corret small errors, Weini.<commit_after>#include "model.h"

Model::Model(const Data& data){
    //initiate the tumour with a homogenous population with the type_p=1 and type_i=1
	int i;
    double n=data.return_initial_cellnumber();
	//define a matrix whose entries is initialized with 0
	double max_num_row=data.return_max_prolif_types();
	double max_num_column=data.return_max_immune_types();
	for(i=0;i<max_num_row;i++)
	{
    std::vector<double> row(max_num_column,0);
    _cells.push_back(row);
    }
	//define the first phenotype:  type_p=1 and type_i=1 with an initial size of n
	_cells[0][0]=n;
}

double Model::return_Ccell_number(int type_p, int type_i) const
{
    return _cells[type_p][type_i];
}

void Model::set_Ccell_number(int type_p, int type_i, double number){
	double max_num_row=_cells.size();
	double max_num_column=_cells[0].size();
	if((type_p>=max_num_row)||(type_i>=max_num_column)) exit(1);
    _cells[type_p][type_i]=number;
}

void output(double dt, std::ostream & os){

}<|endoftext|>


<commit_before>/*
    Copyright (C) <2011>  Michael Zanetti <mzanetti@kde.org>

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 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 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 "remotecontrolmanager.h"
#include "remotecontrolmanager_p.h"
#include "ifaces/remotecontrolmanagerinterface.h"
#include "ifaces/remotecontrolinterface.h"

#include <kglobal.h>
#include <kservicetypetrader.h>
#include <kservice.h>
#include <kdebug.h>

K_GLOBAL_STATIC(RemoteControlManagerPrivate, globalRemoteControlManager)

bool RemoteControlManager::connected()
{
    return globalRemoteControlManager->connected();
}

RemoteControlManager::Notifier* RemoteControlManager::notifier()
{
    return globalRemoteControlManager;
}

/***********************************************************************
  RemoteControlManagerPrivate
 ***********************************************************************/

RemoteControlManagerPrivate::RemoteControlManagerPrivate()
{
    loadBackends("KRemoteControlManager");
}

RemoteControlManagerPrivate::~RemoteControlManagerPrivate()
{
    while(!m_backendList.isEmpty()) {
        delete m_backendList.takeFirst();
    }
}

void RemoteControlManagerPrivate::loadBackends(const char *serviceName)
{
    QStringList error_msg;

    KService::List offers = KServiceTypeTrader::self()->query(serviceName, "(Type == 'Service')");

    foreach (const KService::Ptr &ptr, offers) {
        QString error_string;
        QObject *backend = ptr->createInstance<QObject>(0, QVariantList(), &error_string);

        if(backend!=0) {
            if(backend->inherits("Iface::RemoteControlManager")) {
                kDebug() << "Backend loaded: " << ptr->name();
                m_backendList.append(qobject_cast<Iface::RemoteControlManager*>(backend));
                break;
            } else {
                kDebug() << "Failed loading:" << error_string;
                QString error_string = i18n("Backend loaded but wrong type obtained, expected %1",
                                             "Iface::RemoteControlManager");

                kDebug() << "Error loading '" << ptr->name() << "': " << error_string;
                error_msg.append(error_string);

                delete backend;
                backend = 0;
            }
        } else {
            kDebug() << "Error loading '" << ptr->name() << "', KService said: " << error_string;
            error_msg.append(error_string);
        }
    }

    if (m_backendList.isEmpty()) {
        if (offers.size() == 0) {
            kDebug() << "No Backend found";
        } else {
            kDebug() << "could not load any of the backends";
        }
    }
}

bool RemoteControlManagerPrivate::connected()
{
    return m_connected;
}

RemoteControlList RemoteControlManagerPrivate::buildDeviceList(const QStringList &remoteList)
{
    RemoteControlList list;

    foreach (const QString &remote, remoteList) {
        QPair<RemoteControl *, Iface::RemoteControl *> pair = findRegisteredRemoteControl(remote);

        if (pair.first!= 0) {
            list.append(pair.first);
        }
    }

    return list;

}

void RemoteControlManagerPrivate::_k_remoteControlAdded(const QString &name)
{
    Iface::RemoteControlManager *backendManager = qobject_cast<Iface::RemoteControlManager*>(sender());
    if(backendManager == 0) {
        return;
    }
    RemoteControl *rc = new RemoteControl(name);
    Iface::RemoteControl *rcBackend = backendManager->createRemoteControl(name);
    rc->d_ptr->setBackendObject(rcBackend);
    m_remoteControlMap.insert(name, QPair<RemoteControl*, Iface::RemoteControl*>(rc, rcBackend));

    emit remoteControlAdded(name);
}

void RemoteControlManagerPrivate::_k_remoteControlRemoved(const QString &name)
{
    delete m_remoteControlMap[name].first;
    delete m_remoteControlMap[name].second;
    m_remoteControlMap.remove(name);

    emit remoteControlRemoved(name);
}

void RemoteControlManagerPrivate::_k_statusChanged(bool connected)
{
    if(connected == m_connected) {
        return;
    }

    if(!connected) {
        // Is there still another backend connected?
        foreach(Iface::RemoteControlManager* backend, m_backendList) {
            if(backend->connected()) {
                return;
            }
        }
    }

    m_connected = connected;
    emit statusChanged(connected);
    kDebug() << "Remotecontrol backend status has changed to" << connected;
}

RemoteControlList RemoteControlManagerPrivate::allRemotes()
{
    QStringList remoteList;
    foreach(Iface::RemoteControlManager *backend, m_backendList) {
        remoteList.append(backend->remoteNames());
    }

    if (!m_backendList.isEmpty()) {
        return buildDeviceList(remoteList);
    } else {
        return RemoteControlList();
    }
}

RemoteControl* RemoteControlManagerPrivate::findRemoteControl(const QString &name)
{
    return m_remoteControlMap.value(name).first;
}

RemoteControl::RemoteControl(const QString &name): QObject(), d_ptr(new RemoteControlPrivate(this))
{
    Q_D(RemoteControl);

    RemoteControl *other = globalRemoteControlManager->findRemoteControl(name);

    if(other) {
        d->setBackendObject(other->d_ptr->backendObject());
    }
}

QList<RemoteControl*> RemoteControl::allRemotes()
{
    return globalRemoteControlManager->allRemotes();
}

QPair<RemoteControl *, Iface::RemoteControl *>
RemoteControlManagerPrivate::findRegisteredRemoteControl(const QString &remote)
{
    if (m_remoteControlMap.contains(remote)) {
        return m_remoteControlMap[remote];
    } else {
        foreach(Iface::RemoteControlManager *backend, m_backendList) {

            Iface::RemoteControl * iface = backend->createRemoteControl(remote);
            RemoteControl *device = 0;
            if(iface != 0) {
                device = new RemoteControl(iface);
            } else {
                kDebug() << "Unknown Remote: " << remote;
            }
            if (device != 0) {
                QPair<RemoteControl *, Iface::RemoteControl *> pair(device, iface);
                connect(dynamic_cast<QObject*>(iface), SIGNAL(destroyed(QObject *)),
                        this, SLOT(_k_destroyed(QObject *)));
                m_remoteControlMap[remote] = pair;
                return pair;
            } else {
                return QPair<RemoteControl *, Iface::RemoteControl *>(0, 0);
            }
        }
    }
    return QPair<RemoteControl *, Iface::RemoteControl *>(0, 0);
}

void RemoteControlManagerPrivate::_k_destroyed(QObject *object)
{
    Iface::RemoteControl *remote = qobject_cast<Iface::RemoteControl*>(object);
    if(remote) {
        QString name = remote->name();
        QPair<RemoteControl*, Iface::RemoteControl*> pair = m_remoteControlMap.take(name);
        delete pair.first;
    }
}
<commit_msg>SVN_SILENT compile<commit_after>/*
    Copyright (C) <2011>  Michael Zanetti <mzanetti@kde.org>

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 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 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 "remotecontrolmanager.h"
#include "remotecontrolmanager_p.h"
#include "ifaces/remotecontrolmanagerinterface.h"
#include "ifaces/remotecontrolinterface.h"

#include <kglobal.h>
#include <kservicetypetrader.h>
#include <kservice.h>
#include <kdebug.h>

K_GLOBAL_STATIC(RemoteControlManagerPrivate, globalRemoteControlManager)

bool RemoteControlManager::connected()
{
    return globalRemoteControlManager->connected();
}

RemoteControlManager::Notifier* RemoteControlManager::notifier()
{
    return globalRemoteControlManager;
}

/***********************************************************************
  RemoteControlManagerPrivate
 ***********************************************************************/

RemoteControlManagerPrivate::RemoteControlManagerPrivate()
{
    loadBackends("KRemoteControlManager");
}

RemoteControlManagerPrivate::~RemoteControlManagerPrivate()
{
    while(!m_backendList.isEmpty()) {
        delete m_backendList.takeFirst();
    }
}

void RemoteControlManagerPrivate::loadBackends(const char *serviceName)
{
    QStringList error_msg;

    KService::List offers = KServiceTypeTrader::self()->query(serviceName, "(Type == 'Service')");

    foreach (const KService::Ptr &ptr, offers) {
        QString error_string;
        QObject *backend = ptr->createInstance<QObject>(0, QVariantList(), &error_string);

        if(backend!=0) {
            if(backend->inherits("Iface::RemoteControlManager")) {
                kDebug() << "Backend loaded: " << ptr->name();
                m_backendList.append(qobject_cast<Iface::RemoteControlManager*>(backend));
                break;
            } else {
                kDebug() << "Failed loading:" << error_string;
                QString error_string = i18n("Backend loaded but wrong type obtained, expected %1",
                                             QLatin1String("Iface::RemoteControlManager"));

                kDebug() << "Error loading '" << ptr->name() << "': " << error_string;
                error_msg.append(error_string);

                delete backend;
                backend = 0;
            }
        } else {
            kDebug() << "Error loading '" << ptr->name() << "', KService said: " << error_string;
            error_msg.append(error_string);
        }
    }

    if (m_backendList.isEmpty()) {
        if (offers.size() == 0) {
            kDebug() << "No Backend found";
        } else {
            kDebug() << "could not load any of the backends";
        }
    }
}

bool RemoteControlManagerPrivate::connected()
{
    return m_connected;
}

RemoteControlList RemoteControlManagerPrivate::buildDeviceList(const QStringList &remoteList)
{
    RemoteControlList list;

    foreach (const QString &remote, remoteList) {
        QPair<RemoteControl *, Iface::RemoteControl *> pair = findRegisteredRemoteControl(remote);

        if (pair.first!= 0) {
            list.append(pair.first);
        }
    }

    return list;

}

void RemoteControlManagerPrivate::_k_remoteControlAdded(const QString &name)
{
    Iface::RemoteControlManager *backendManager = qobject_cast<Iface::RemoteControlManager*>(sender());
    if(backendManager == 0) {
        return;
    }
    RemoteControl *rc = new RemoteControl(name);
    Iface::RemoteControl *rcBackend = backendManager->createRemoteControl(name);
    rc->d_ptr->setBackendObject(rcBackend);
    m_remoteControlMap.insert(name, QPair<RemoteControl*, Iface::RemoteControl*>(rc, rcBackend));

    emit remoteControlAdded(name);
}

void RemoteControlManagerPrivate::_k_remoteControlRemoved(const QString &name)
{
    delete m_remoteControlMap[name].first;
    delete m_remoteControlMap[name].second;
    m_remoteControlMap.remove(name);

    emit remoteControlRemoved(name);
}

void RemoteControlManagerPrivate::_k_statusChanged(bool connected)
{
    if(connected == m_connected) {
        return;
    }

    if(!connected) {
        // Is there still another backend connected?
        foreach(Iface::RemoteControlManager* backend, m_backendList) {
            if(backend->connected()) {
                return;
            }
        }
    }

    m_connected = connected;
    emit statusChanged(connected);
    kDebug() << "Remotecontrol backend status has changed to" << connected;
}

RemoteControlList RemoteControlManagerPrivate::allRemotes()
{
    QStringList remoteList;
    foreach(Iface::RemoteControlManager *backend, m_backendList) {
        remoteList.append(backend->remoteNames());
    }

    if (!m_backendList.isEmpty()) {
        return buildDeviceList(remoteList);
    } else {
        return RemoteControlList();
    }
}

RemoteControl* RemoteControlManagerPrivate::findRemoteControl(const QString &name)
{
    return m_remoteControlMap.value(name).first;
}

RemoteControl::RemoteControl(const QString &name): QObject(), d_ptr(new RemoteControlPrivate(this))
{
    Q_D(RemoteControl);

    RemoteControl *other = globalRemoteControlManager->findRemoteControl(name);

    if(other) {
        d->setBackendObject(other->d_ptr->backendObject());
    }
}

QList<RemoteControl*> RemoteControl::allRemotes()
{
    return globalRemoteControlManager->allRemotes();
}

QPair<RemoteControl *, Iface::RemoteControl *>
RemoteControlManagerPrivate::findRegisteredRemoteControl(const QString &remote)
{
    if (m_remoteControlMap.contains(remote)) {
        return m_remoteControlMap[remote];
    } else {
        foreach(Iface::RemoteControlManager *backend, m_backendList) {

            Iface::RemoteControl * iface = backend->createRemoteControl(remote);
            RemoteControl *device = 0;
            if(iface != 0) {
                device = new RemoteControl(iface);
            } else {
                kDebug() << "Unknown Remote: " << remote;
            }
            if (device != 0) {
                QPair<RemoteControl *, Iface::RemoteControl *> pair(device, iface);
                connect(dynamic_cast<QObject*>(iface), SIGNAL(destroyed(QObject *)),
                        this, SLOT(_k_destroyed(QObject *)));
                m_remoteControlMap[remote] = pair;
                return pair;
            } else {
                return QPair<RemoteControl *, Iface::RemoteControl *>(0, 0);
            }
        }
    }
    return QPair<RemoteControl *, Iface::RemoteControl *>(0, 0);
}

void RemoteControlManagerPrivate::_k_destroyed(QObject *object)
{
    Iface::RemoteControl *remote = qobject_cast<Iface::RemoteControl*>(object);
    if(remote) {
        QString name = remote->name();
        QPair<RemoteControl*, Iface::RemoteControl*> pair = m_remoteControlMap.take(name);
        delete pair.first;
    }
}
<|endoftext|>


<commit_before><commit_msg>Avoid recursive DisplayDebugMessageInDialog call when an assert is hit on the IO thread<commit_after><|endoftext|>


<commit_before>// Copyright 2010 Google
// 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 "stdio.h"
#include "time.h"

#include "base/logging.h"

namespace operations_research {
DateLogger::DateLogger() {
#if defined(_MSC_VER)
  _tzset();
#endif
}

char* const DateLogger::HumanDate() {
#if defined(_MSC_VER)
  strtime_s(buffer_, 9);
#else
  time_t time_value = time(NULL);
  struct tm* const now = localtime(&time_value);
  sprintf(buffer_, "%02d:%02d:%02d\0", now->tm_hour, now->tm_min, now->tm_sec);
#endif
  return buffer_;
}
}  // namespace operations_research
<commit_msg>fix visual studio compilation<commit_after>// Copyright 2010 Google
// 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 "stdio.h"
#include "time.h"

#include "base/logging.h"

namespace operations_research {
DateLogger::DateLogger() {
#if defined(_MSC_VER)
  _tzset();
#endif
}

char* const DateLogger::HumanDate() {
#if defined(_MSC_VER)
  _strtime_s(buffer_, 9);
#else
  time_t time_value = time(NULL);
  struct tm* const now = localtime(&time_value);
  sprintf(buffer_, "%02d:%02d:%02d\0", now->tm_hour, now->tm_min, now->tm_sec);
#endif
  return buffer_;
}
}  // namespace operations_research
<|endoftext|>


<commit_before>/***************************Copyright-DO-NOT-REMOVE-THIS-LINE**
 * CONDOR Copyright Notice
 *
 * See LICENSE.TXT for additional notices and disclaimers.
 *
 * Copyright (c)1990-1998 CONDOR Team, Computer Sciences Department,
 * University of Wisconsin-Madison, Madison, WI.  All Rights Reserved.
 * No use of the CONDOR Software Program Source Code is authorized
 * without the express consent of the CONDOR Team.  For more information
 * contact: CONDOR Team, Attention: Professor Miron Livny,
 * 7367 Computer Sciences, 1210 W. Dayton St., Madison, WI 53706-1685,
 * (608) 262-0856 or miron@cs.wisc.edu.
 *
 * U.S. Government Rights Restrictions: Use, duplication, or disclosure
 * by the U.S. Government is subject to restrictions as set forth in
 * subparagraph (c)(1)(ii) of The Rights in Technical Data and Computer
 * Software clause at DFARS 252.227-7013 or subparagraphs (c)(1) and
 * (2) of Commercial Computer Software-Restricted Rights at 48 CFR
 * 52.227-19, as applicable, CONDOR Team, Attention: Professor Miron
 * Livny, 7367 Computer Sciences, 1210 W. Dayton St., Madison,
 * WI 53706-1685, (608) 262-0856 or miron@cs.wisc.edu.
****************************Copyright-DO-NOT-REMOVE-THIS-LINE**/

/* This file is the implementation of the RemoteResource class. */

#include "condor_common.h"
#include "remoteresource.h"
#include "exit.h"             // for JOB_BLAH_BLAH exit reasons
#include "condor_debug.h"     // for D_debuglevel #defines
#include "condor_string.h"    // for strnewp()

// for remote syscalls, this is currently in NTreceivers.C.
extern int do_REMOTE_syscall();

// for remote syscalls...
ReliSock *syscall_sock;
RemoteResource *thisRemoteResource;

// 90 seconds to wait for a socket timeout:
const int RemoteResource::SHADOW_SOCK_TIMEOUT = 90;

RemoteResource::RemoteResource( BaseShadow *shad )
{
	executingHost = NULL;
	capability = NULL;
	init( shad );
}

RemoteResource::RemoteResource( BaseShadow * shad,
								const char * eHost,
								const char * cbility )
{
	executingHost = strnewp( eHost );
	capability    = strnewp( cbility );
	init( shad );
}

void RemoteResource::init( BaseShadow *shad ) {
	shadow = shad;
	machineName = NULL;
	starterAddress = NULL;
	jobAd = NULL;
	fs_domain = NULL;
	uid_domain = NULL;
	claimSock = new ReliSock();
	exitReason = exitStatus = -1;
}

RemoteResource::~RemoteResource() {
	if ( executingHost ) delete [] executingHost;
	if ( machineName   ) delete [] machineName;
	if ( capability    ) delete [] capability;
	if ( starterAddress) delete [] starterAddress;
	if ( uid_domain	   ) delete [] uid_domain;
	if ( fs_domain     ) delete [] fs_domain;
	if ( claimSock     ) delete claimSock;
	if ( jobAd         ) delete jobAd;
}

int RemoteResource::requestIt( int starterVersion ) {
/* starterVersion is a default to 2. */

	int reply;

	if ( !executingHost || !capability ) {
		shadow->dprintf ( D_ALWAYS, "executingHost or capability not defined"
				  "in requestIt.\n" );
		setExitReason(JOB_SHADOW_USAGE);  // no better exit reason available
		return -1;
	}

	if ( !jobAd ) {
		shadow->dprintf( D_ALWAYS, "JobAd not defined in RemoteResource\n" );
		return -1;
	}

	claimSock->close();	// make sure ClaimSock is a virgin socket
	claimSock->timeout(SHADOW_SOCK_TIMEOUT);
	if (!claimSock->connect(executingHost, 0)) {
		shadow->dprintf(D_ALWAYS, "failed to connect to execute host %s\n",
				executingHost);
		setExitReason(JOB_NOT_STARTED);
		return -1;
	}

	claimSock->encode();
	if (!claimSock->put(ACTIVATE_CLAIM)  ||
		!claimSock->code(capability)     ||
		!claimSock->code(starterVersion) ||
		!jobAd->put(*claimSock)          ||
		!claimSock->end_of_message())
	{
		shadow->dprintf(D_ALWAYS, "failed to send ACTIVATE_CLAIM "
                        "request to %s\n", executingHost);
		setExitReason(JOB_NOT_STARTED);
		return -1;
	}

	claimSock->decode();
	if (!claimSock->code(reply) || !claimSock->end_of_message()) {
		shadow->dprintf(D_ALWAYS, "failed to receive ACTIVATE_CLAIM "
                        "reply from %s\n", executingHost);
		setExitReason(JOB_NOT_STARTED);
		return -1;
	}

	if (reply != OK) {
		shadow->dprintf(D_ALWAYS, "Request to run on %s was REFUSED.\n",
				executingHost);
		setExitReason(JOB_NOT_STARTED);
		return -1;
	}

	shadow->dprintf(D_ALWAYS, "Request to run on %s was ACCEPTED.\n",
                    executingHost);
	return 0;
}

int RemoteResource::killStarter() {

	ReliSock sock;

	if ( !executingHost ) {
		shadow->dprintf ( D_ALWAYS, "In killStarter, "
                          "executingHost not defined.\n");
		return -1;
	}

	shadow->dprintf( D_ALWAYS, "Removing machine \"%s\".\n",
					 machineName ? machineName : executingHost );

	sock.timeout(SHADOW_SOCK_TIMEOUT);
	if (!sock.connect(executingHost, 0)) {
		shadow->dprintf(D_ALWAYS, "failed to connect to executing host %s\n",
				executingHost );
		return -1;
	}

	sock.encode();
	if (!sock.put(KILL_FRGN_JOB) ||
		!sock.put(capability)    ||
		!sock.end_of_message())
	{
		shadow->dprintf(D_ALWAYS, "failed to send KILL_FRGN_JOB "
                        "to startd %s\n", executingHost );
		return -1;
	}

	return 0;
}

void RemoteResource::dprintfSelf( int debugLevel ) {
	shadow->dprintf ( debugLevel, "RemoteResource::dprintSelf printing "
					  "host info:\n");
	if ( executingHost )
		shadow->dprintf ( debugLevel, "\texecutingHost: %s\n", executingHost);
	if ( capability )
		shadow->dprintf ( debugLevel, "\tcapability:    %s\n", capability);
	if ( machineName )
		shadow->dprintf ( debugLevel, "\tmachineName:   %s\n", machineName);
	if ( starterAddress )
		shadow->dprintf ( debugLevel, "\tstarterAddr:   %s\n", starterAddress);
	shadow->dprintf ( debugLevel, "\texitReason:    %d\n", exitReason);
	shadow->dprintf ( debugLevel, "\texitStatus:    %d\n", exitStatus);
}

void RemoteResource::printExit( FILE *fp ) {

		/* Add more cases to the switch as they develop... */

	switch ( exitReason ) {
	case JOB_EXITED: {
		if ( WIFSIGNALED(exitStatus) ) {
			fprintf ( fp, "died on signal %d.\n",
					  WTERMSIG(exitStatus) );
		}
		else {
			if ( WEXITSTATUS(exitStatus) == ENOEXEC ) {
					/* What has happened here is this:  The starter
					   forked, but the exec failed with ENOEXEC and
					   called exit(ENOEXEC).  The exit appears normal,
					   however, and the status is ENOEXEC - or 8.  If
					   the user job can exit with a status of 8, we're
					   hosed.  A better solution should be found. */
				fprintf( fp, "exited because of an invalid binary.\n" );
			} else {
				fprintf ( fp, "exited normally with status %d.\n",
						  WEXITSTATUS(exitStatus) );
			}
		}

		break;
	}
	case JOB_KILLED: {
		fprintf ( fp, "was forceably removed by condor.\n" );
		break;
	}
	case JOB_NOT_CKPTED: {
		fprintf ( fp, "was removed by condor, without a checkpoint.\n" );
		break;
	}
	case JOB_NOT_STARTED: {
		fprintf ( fp, "was never started.\n" );
		break;
	}
	case JOB_SHADOW_USAGE: {
		fprintf ( fp, "had incorrect arguments to the condor_shadow.\n" );
		fprintf ( fp, "                                    "
				  "This is an internal problem...\n" );
		break;
	}
	default: {
		fprintf ( fp, "has a strange exit reason of %d.\n", exitReason );
	}
	} // switch()
}

int RemoteResource::handleSysCalls( Stream *sock ) {

		// change value of the syscall_sock to correspond with that of
		// this claim sock right before do_REMOTE_syscall().

	syscall_sock = claimSock;
	thisRemoteResource = this;

	if (do_REMOTE_syscall() < 0) {
		shadow->dprintf(D_SYSCALLS,"Shadow: do_REMOTE_syscall returned < 0\n");
			// we call our shadow's shutdown method:
		shadow->shutDown(exitReason, exitStatus);
			// close sock on this end...the starter has gone away.
		return TRUE;
	}

	return KEEP_STREAM;
}

void RemoteResource::getExecutingHost( char *& eHost ) {

	if (!eHost) {
		eHost = strnewp ( executingHost );
	} else {
		if ( executingHost ) {
			strcpy ( eHost, executingHost );
		} else {
			eHost[0] = '\0';
		}
	}
}

void RemoteResource::getMachineName( char *& mName ) {

	if ( !mName ) {
		mName = strnewp( machineName );
	} else {
		if ( machineName ) {
			strcpy( mName, machineName );
		} else {
			mName[0] = '\0';
		}
	}
}

void RemoteResource::getUidDomain( char *& uidDomain ) {

	if ( !uidDomain ) {
		uidDomain = strnewp( uid_domain );
	} else {
		if ( uid_domain ) {
			strcpy( uidDomain, uid_domain );
		} else {
			uidDomain[0] = '\0';
		}
	}
}

void RemoteResource::getFilesystemDomain( char *& filesystemDomain ) {

	if ( !filesystemDomain ) {
		filesystemDomain = strnewp( fs_domain );
	} else {
		if ( fs_domain ) {
			strcpy( filesystemDomain, fs_domain );
		} else {
			filesystemDomain[0] = '\0';
		}
	}
}

void RemoteResource::getCapability( char *& cbility ) {

	if (!cbility) {
		cbility = strnewp( capability );
	} else {
		if ( capability ) {
			strcpy( cbility, capability );
		} else {
			cbility[0] = '\0';
		}
	}
}

void RemoteResource::getStarterAddress( char *& starterAddr ) {

	if (!starterAddr) {
		starterAddr = strnewp( starterAddress );
	} else {
		if ( starterAddress ) {
			strcpy( starterAddr, starterAddress );
		} else {
			starterAddr[0] = '\0';
		}
	}
}

ReliSock* RemoteResource::getClaimSock() {
	return claimSock;
}

int RemoteResource::getExitReason() {
	return exitReason;
}

int RemoteResource::getExitStatus() {
	return exitStatus;
}

void RemoteResource::setExecutingHost( const char * eHost ) {

	if ( executingHost )
		delete [] executingHost;

	executingHost = strnewp( eHost );
}

void RemoteResource::setMachineName( const char * mName ) {

	if ( machineName )
		delete [] machineName;

	machineName = strnewp ( mName );
}

void RemoteResource::setUidDomain( const char * uidDomain ) {

	if ( uid_domain )
		delete [] uid_domain;

	uid_domain = strnewp ( uidDomain );
}

void RemoteResource::setFilesystemDomain( const char * filesystemDomain ) {

	if ( fs_domain )
		delete [] fs_domain;

	fs_domain = strnewp ( filesystemDomain );
}

void RemoteResource::setCapability( const char * cbility ) {

	if ( capability )
		delete [] capability;

	capability = strnewp ( cbility );
}

void RemoteResource::setStarterAddress( const char * starterAddr ) {

	if ( starterAddress )
		delete [] starterAddress;

	starterAddress = strnewp( starterAddr );
}

void RemoteResource::setClaimSock( ReliSock * cSock ) {
	claimSock = cSock;
}

void RemoteResource::setExitReason( int reason ) {
	// Set the exitReason, but not if the reason is JOB_KILLED.
	// This prevents exitReason being reset from JOB_KILLED to
	// JOB_NOT_CKPTED or some such when the starter gets killed
	// and the syscall sock goes away.

	shadow->dprintf ( D_FULLDEBUG, "setting exit reason on %s to %d\n",
					  machineName ? machineName : executingHost, reason );

	if ( exitReason != JOB_KILLED ) {
		exitReason = reason;
	}
}

void RemoteResource::setExitStatus( int status ) {
	shadow->dprintf ( D_FULLDEBUG, "setting exit status on %s to %d\n",
					  machineName ? machineName : "???", status );

	exitStatus = status;
}

<commit_msg>+ clarified and/or made some sense on NT of some of the termination messages + added implementations for bytesSent() and bytesRecvd() methods<commit_after>/***************************Copyright-DO-NOT-REMOVE-THIS-LINE**
 * CONDOR Copyright Notice
 *
 * See LICENSE.TXT for additional notices and disclaimers.
 *
 * Copyright (c)1990-1998 CONDOR Team, Computer Sciences Department,
 * University of Wisconsin-Madison, Madison, WI.  All Rights Reserved.
 * No use of the CONDOR Software Program Source Code is authorized
 * without the express consent of the CONDOR Team.  For more information
 * contact: CONDOR Team, Attention: Professor Miron Livny,
 * 7367 Computer Sciences, 1210 W. Dayton St., Madison, WI 53706-1685,
 * (608) 262-0856 or miron@cs.wisc.edu.
 *
 * U.S. Government Rights Restrictions: Use, duplication, or disclosure
 * by the U.S. Government is subject to restrictions as set forth in
 * subparagraph (c)(1)(ii) of The Rights in Technical Data and Computer
 * Software clause at DFARS 252.227-7013 or subparagraphs (c)(1) and
 * (2) of Commercial Computer Software-Restricted Rights at 48 CFR
 * 52.227-19, as applicable, CONDOR Team, Attention: Professor Miron
 * Livny, 7367 Computer Sciences, 1210 W. Dayton St., Madison,
 * WI 53706-1685, (608) 262-0856 or miron@cs.wisc.edu.
****************************Copyright-DO-NOT-REMOVE-THIS-LINE**/

/* This file is the implementation of the RemoteResource class. */

#include "condor_common.h"
#include "remoteresource.h"
#include "exit.h"             // for JOB_BLAH_BLAH exit reasons
#include "condor_debug.h"     // for D_debuglevel #defines
#include "condor_string.h"    // for strnewp()

// for remote syscalls, this is currently in NTreceivers.C.
extern int do_REMOTE_syscall();

// for remote syscalls...
ReliSock *syscall_sock;
RemoteResource *thisRemoteResource;

// 90 seconds to wait for a socket timeout:
const int RemoteResource::SHADOW_SOCK_TIMEOUT = 90;

RemoteResource::RemoteResource( BaseShadow *shad )
{
	executingHost = NULL;
	capability = NULL;
	init( shad );
}

RemoteResource::RemoteResource( BaseShadow * shad,
								const char * eHost,
								const char * cbility )
{
	executingHost = strnewp( eHost );
	capability    = strnewp( cbility );
	init( shad );
}

void RemoteResource::init( BaseShadow *shad ) {
	shadow = shad;
	machineName = NULL;
	starterAddress = NULL;
	jobAd = NULL;
	fs_domain = NULL;
	uid_domain = NULL;
	claimSock = new ReliSock();
	exitReason = exitStatus = -1;
}

RemoteResource::~RemoteResource() {
	if ( executingHost ) delete [] executingHost;
	if ( machineName   ) delete [] machineName;
	if ( capability    ) delete [] capability;
	if ( starterAddress) delete [] starterAddress;
	if ( uid_domain	   ) delete [] uid_domain;
	if ( fs_domain     ) delete [] fs_domain;
	if ( claimSock     ) delete claimSock;
	if ( jobAd         ) delete jobAd;
}

int RemoteResource::requestIt( int starterVersion ) {
/* starterVersion is a default to 2. */

	int reply;

	if ( !executingHost || !capability ) {
		shadow->dprintf ( D_ALWAYS, "executingHost or capability not defined"
				  "in requestIt.\n" );
		setExitReason(JOB_SHADOW_USAGE);  // no better exit reason available
		return -1;
	}

	if ( !jobAd ) {
		shadow->dprintf( D_ALWAYS, "JobAd not defined in RemoteResource\n" );
		return -1;
	}

	claimSock->close();	// make sure ClaimSock is a virgin socket
	claimSock->timeout(SHADOW_SOCK_TIMEOUT);
	if (!claimSock->connect(executingHost, 0)) {
		shadow->dprintf(D_ALWAYS, "failed to connect to execute host %s\n",
				executingHost);
		setExitReason(JOB_NOT_STARTED);
		return -1;
	}

	claimSock->encode();
	if (!claimSock->put(ACTIVATE_CLAIM)  ||
		!claimSock->code(capability)     ||
		!claimSock->code(starterVersion) ||
		!jobAd->put(*claimSock)          ||
		!claimSock->end_of_message())
	{
		shadow->dprintf(D_ALWAYS, "failed to send ACTIVATE_CLAIM "
                        "request to %s\n", executingHost);
		setExitReason(JOB_NOT_STARTED);
		return -1;
	}

	claimSock->decode();
	if (!claimSock->code(reply) || !claimSock->end_of_message()) {
		shadow->dprintf(D_ALWAYS, "failed to receive ACTIVATE_CLAIM "
                        "reply from %s\n", executingHost);
		setExitReason(JOB_NOT_STARTED);
		return -1;
	}

	if (reply != OK) {
		shadow->dprintf(D_ALWAYS, "Request to run on %s was REFUSED.\n",
				executingHost);
		setExitReason(JOB_NOT_STARTED);
		return -1;
	}

	shadow->dprintf(D_ALWAYS, "Request to run on %s was ACCEPTED.\n",
                    executingHost);
	return 0;
}

int RemoteResource::killStarter() {

	ReliSock sock;

	if ( !executingHost ) {
		shadow->dprintf ( D_ALWAYS, "In killStarter, "
                          "executingHost not defined.\n");
		return -1;
	}

	shadow->dprintf( D_ALWAYS, "Removing machine \"%s\".\n",
					 machineName ? machineName : executingHost );

	sock.timeout(SHADOW_SOCK_TIMEOUT);
	if (!sock.connect(executingHost, 0)) {
		shadow->dprintf(D_ALWAYS, "failed to connect to executing host %s\n",
				executingHost );
		return -1;
	}

	sock.encode();
	if (!sock.put(KILL_FRGN_JOB) ||
		!sock.put(capability)    ||
		!sock.end_of_message())
	{
		shadow->dprintf(D_ALWAYS, "failed to send KILL_FRGN_JOB "
                        "to startd %s\n", executingHost );
		return -1;
	}

	return 0;
}

void RemoteResource::dprintfSelf( int debugLevel ) {
	shadow->dprintf ( debugLevel, "RemoteResource::dprintSelf printing "
					  "host info:\n");
	if ( executingHost )
		shadow->dprintf ( debugLevel, "\texecutingHost: %s\n", executingHost);
	if ( capability )
		shadow->dprintf ( debugLevel, "\tcapability:    %s\n", capability);
	if ( machineName )
		shadow->dprintf ( debugLevel, "\tmachineName:   %s\n", machineName);
	if ( starterAddress )
		shadow->dprintf ( debugLevel, "\tstarterAddr:   %s\n", starterAddress);
	shadow->dprintf ( debugLevel, "\texitReason:    %d\n", exitReason);
	shadow->dprintf ( debugLevel, "\texitStatus:    %d\n", exitStatus);
}

void RemoteResource::printExit( FILE *fp ) {

		/* Add more cases to the switch as they develop... */

	switch ( exitReason ) {
	case JOB_EXITED: {
		if ( WIFSIGNALED(exitStatus) ) {
			fprintf ( fp, "died on %s.\n",
					  daemonCore->GetExceptionString(WTERMSIG(exitStatus)) );
		}
		else {
#ifndef WIN32
			if ( WEXITSTATUS(exitStatus) == ENOEXEC ) {
					/* What has happened here is this:  The starter
					   forked, but the exec failed with ENOEXEC and
					   called exit(ENOEXEC).  The exit appears normal,
					   however, and the status is ENOEXEC - or 8.  If
					   the user job can exit with a status of 8, we're
					   hosed.  A better solution should be found. */
				fprintf( fp, "exited because of an invalid binary.\n" );
			} else
#endif  // of ifndef WIN32
			{
				fprintf ( fp, "exited normally with status %d.\n",
						  WEXITSTATUS(exitStatus) );
			}
		}

		break;
	}
	case JOB_KILLED: {
		fprintf ( fp, "was forceably removed with condor_rm.\n" );
		break;
	}
	case JOB_NOT_CKPTED: {
		fprintf ( fp, "was removed by condor, without a checkpoint.\n" );
		break;
	}
	case JOB_NOT_STARTED: {
		fprintf ( fp, "was never started.\n" );
		break;
	}
	case JOB_SHADOW_USAGE: {
		fprintf ( fp, "had incorrect arguments to the condor_shadow.\n" );
		fprintf ( fp, "                                    "
				  "This is an internal problem...\n" );
		break;
	}
	default: {
		fprintf ( fp, "has a strange exit reason of %d.\n", exitReason );
	}
	} // switch()
}

int RemoteResource::handleSysCalls( Stream *sock ) {

		// change value of the syscall_sock to correspond with that of
		// this claim sock right before do_REMOTE_syscall().

	syscall_sock = claimSock;
	thisRemoteResource = this;

	if (do_REMOTE_syscall() < 0) {
		shadow->dprintf(D_SYSCALLS,"Shadow: do_REMOTE_syscall returned < 0\n");
			// we call our shadow's shutdown method:
		shadow->shutDown(exitReason, exitStatus);
			// close sock on this end...the starter has gone away.
		return TRUE;
	}

	return KEEP_STREAM;
}

void RemoteResource::getExecutingHost( char *& eHost ) {

	if (!eHost) {
		eHost = strnewp ( executingHost );
	} else {
		if ( executingHost ) {
			strcpy ( eHost, executingHost );
		} else {
			eHost[0] = '\0';
		}
	}
}

void RemoteResource::getMachineName( char *& mName ) {

	if ( !mName ) {
		mName = strnewp( machineName );
	} else {
		if ( machineName ) {
			strcpy( mName, machineName );
		} else {
			mName[0] = '\0';
		}
	}
}

void RemoteResource::getUidDomain( char *& uidDomain ) {

	if ( !uidDomain ) {
		uidDomain = strnewp( uid_domain );
	} else {
		if ( uid_domain ) {
			strcpy( uidDomain, uid_domain );
		} else {
			uidDomain[0] = '\0';
		}
	}
}

void RemoteResource::getFilesystemDomain( char *& filesystemDomain ) {

	if ( !filesystemDomain ) {
		filesystemDomain = strnewp( fs_domain );
	} else {
		if ( fs_domain ) {
			strcpy( filesystemDomain, fs_domain );
		} else {
			filesystemDomain[0] = '\0';
		}
	}
}

void RemoteResource::getCapability( char *& cbility ) {

	if (!cbility) {
		cbility = strnewp( capability );
	} else {
		if ( capability ) {
			strcpy( cbility, capability );
		} else {
			cbility[0] = '\0';
		}
	}
}

void RemoteResource::getStarterAddress( char *& starterAddr ) {

	if (!starterAddr) {
		starterAddr = strnewp( starterAddress );
	} else {
		if ( starterAddress ) {
			strcpy( starterAddr, starterAddress );
		} else {
			starterAddr[0] = '\0';
		}
	}
}

ReliSock* RemoteResource::getClaimSock() {
	return claimSock;
}

int RemoteResource::getExitReason() {
	return exitReason;
}

int RemoteResource::getExitStatus() {
	return exitStatus;
}

void RemoteResource::setExecutingHost( const char * eHost ) {

	if ( executingHost )
		delete [] executingHost;

	executingHost = strnewp( eHost );
}

void RemoteResource::setMachineName( const char * mName ) {

	if ( machineName )
		delete [] machineName;

	machineName = strnewp ( mName );
}

void RemoteResource::setUidDomain( const char * uidDomain ) {

	if ( uid_domain )
		delete [] uid_domain;

	uid_domain = strnewp ( uidDomain );
}

void RemoteResource::setFilesystemDomain( const char * filesystemDomain ) {

	if ( fs_domain )
		delete [] fs_domain;

	fs_domain = strnewp ( filesystemDomain );
}

void RemoteResource::setCapability( const char * cbility ) {

	if ( capability )
		delete [] capability;

	capability = strnewp ( cbility );
}

void RemoteResource::setStarterAddress( const char * starterAddr ) {

	if ( starterAddress )
		delete [] starterAddress;

	starterAddress = strnewp( starterAddr );
}

void RemoteResource::setClaimSock( ReliSock * cSock ) {
	claimSock = cSock;
}

void RemoteResource::setExitReason( int reason ) {
	// Set the exitReason, but not if the reason is JOB_KILLED.
	// This prevents exitReason being reset from JOB_KILLED to
	// JOB_NOT_CKPTED or some such when the starter gets killed
	// and the syscall sock goes away.

	shadow->dprintf ( D_FULLDEBUG, "setting exit reason on %s to %d\n",
					  machineName ? machineName : executingHost, reason );

	if ( exitReason != JOB_KILLED ) {
		exitReason = reason;
	}
}

void RemoteResource::setExitStatus( int status ) {
	shadow->dprintf ( D_FULLDEBUG, "setting exit status on %s to %d\n",
					  machineName ? machineName : "???", status );

	exitStatus = status;
}

float RemoteResource::bytesSent()
{
	float bytes = 0.0;

	// add in bytes sent by transferring files
	bytes += filetrans.TotalBytesSent();

	// add in bytes sent via remote system calls

	/*** until the day we support syscalls in the new shadow
	if (syscall_sock) {
		bytes += syscall_sock->get_bytes_sent();
	}
	****/

	return bytes;
}

float RemoteResource::bytesRecvd()
{
	float bytes = 0.0;

	// add in bytes sent by transferring files
	bytes += filetrans.TotalBytesReceived();

	// add in bytes sent via remote system calls

	/*** until the day we support syscalls in the new shadow
	if (syscall_sock) {
		bytes += syscall_sock->get_bytes_recvd();
	}
	****/

	return bytes;
}

<|endoftext|>