<commit_before>#include "tileWorker.h"

#include "platform.h"
#include "data/dataSource.h"
#include "tile/tile.h"
#include "view/view.h"
#include "scene/scene.h"
#include "tile/tileID.h"
#include "tile/tileTask.h"
#include "tile/tileBuilder.h"
#include "tangram.h"

#include <algorithm>

#define WORKER_NICENESS 10

namespace Tangram {

TileWorker::TileWorker(int _num_worker) {
    m_running = true;
    m_pendingTiles = false;

    for (int i = 0; i < _num_worker; i++) {
        auto worker = std::make_unique<Worker>();
        worker->thread = std::thread(&TileWorker::run, this, worker.get());
        m_workers.push_back(std::move(worker));
    }
}

TileWorker::~TileWorker(){
    if (m_running) {
        stop();
    }
}

void disposeBuilder(std::unique_ptr<TileBuilder> _builder) {
    if (_builder) {
        // Bind _builder to a std::function that will run on the next mainloop
        // iteration and does therefore dispose the TileBuilder, including it's
        // Scene reference with OpenGL resources on the mainloop. This is done
        // in order to ensure that no GL functions are called on
        // the worker-thread.
        auto disposer = std::bind([](auto builder){},
                                  std::shared_ptr<TileBuilder>(std::move(_builder)));

        Tangram::runOnMainLoop(disposer);
    }
}

void TileWorker::run(Worker* instance) {

    setCurrentThreadPriority(WORKER_NICENESS);

    std::unique_ptr<TileBuilder> builder;

    while (true) {

        std::shared_ptr<TileTask> task;
        {
            std::unique_lock<std::mutex> lock(m_mutex);

            m_condition.wait(lock, [&, this]{
                    return !m_running || !m_queue.empty();
                });

            if (instance->tileBuilder) {
                disposeBuilder(std::move(builder));

                builder = std::move(instance->tileBuilder);
                LOG("Passed new TileBuilder to TileWorker");
            }

            // Check if thread should stop
            if (!m_running) {
                disposeBuilder(std::move(builder));
                break;
            }

            if (!builder) {
                LOGE("Missing Scene/StyleContext in TileWorker!");
                continue;
            }

            // Remove all canceled tasks
            auto removes = std::remove_if(m_queue.begin(), m_queue.end(),
                                          [](const auto& a) { return a->isCanceled(); });

            m_queue.erase(removes, m_queue.end());

            if (m_queue.empty()) {
                continue;
            }

            // Pop highest priority tile from queue
            auto it = std::min_element(m_queue.begin(), m_queue.end(),
                [](const auto& a, const auto& b) {
                    if (a->isProxy() != b->isProxy()) {
                        return !a->isProxy();
                    }
                    if (a->source().id() == b->source().id() &&
                        a->sourceGeneration() != b->sourceGeneration()) {
                        return a->sourceGeneration() < b->sourceGeneration();
                    }
                    return a->getPriority() < b->getPriority();
                });

            task = std::move(*it);
            m_queue.erase(it);
        }

        if (task->isCanceled()) {
            continue;
        }

        auto tileData = task->source().parse(*task, *builder->scene().mapProjection());

        // const clock_t begin = clock();

        if (tileData) {

            auto raster = task->source().raster(*task);
            auto tile = builder->build(task->tileId(), *tileData, task->source());

            if (tile) { task->doneBuilding(); }

            // float loadTime = (float(clock() - begin) / CLOCKS_PER_SEC) * 1000;
            // LOG("loadTime %s - %f", task->tile()->getID().toString().c_str(), loadTime);

            std::unique_lock<std::mutex> lock(m_mutex);
            m_condition.wait(lock, [&]() {
                                        if (!m_running) { return true; }
                                        for (auto& raster : task->rasterTasks()) {
                                            if (!raster->hasData()) {
                                                return false;
                                            }
                                        }
                                        return true;
                                    });

            if (!m_running) {
                if (builder) {
                    disposeBuilder(std::move(builder));
                }
                tile.reset();
                m_queue.clear();
                break;
            }

            if (task->isCanceled()) {
                tile.reset();
                continue;
            }

            // first set self texture, if it has one, then go to reference raster textures
            if (raster.isValid()) {
                tile->rasters().push_back(std::move(raster));
            }
            for (auto& rasterTask : task->rasterTasks()) {
                auto rasterTex = rasterTask->source().raster(*rasterTask);
                if (rasterTex.isValid()) {
                    tile->rasters().push_back(std::move(rasterTex));
                }
            }

            // Mark task as ready
            task->setTile(std::move(tile));
        } else {
            task->cancel();
        }

        m_pendingTiles = true;

        requestRender();
    }
}

void TileWorker::setScene(std::shared_ptr<Scene>& _scene) {
    for (auto& worker : m_workers) {
        auto tileBuilder = std::make_unique<TileBuilder>();
        tileBuilder->setScene(_scene);

        worker->tileBuilder = std::move(tileBuilder);
    }
}

void TileWorker::enqueue(std::shared_ptr<TileTask>&& task) {
    {
        std::unique_lock<std::mutex> lock(m_mutex);
        if (!m_running) {
            return;
        }
        if (!task->isBuilt()) {
            m_queue.push_back(std::move(task));
        }
    }
    m_condition.notify_one();
}

void TileWorker::stop() {
    {
        std::unique_lock<std::mutex> lock(m_mutex);
        m_running = false;
    }

    m_condition.notify_all();

    for (auto& worker : m_workers) {
        worker->thread.join();
    }
}

}
<commit_msg>Cancel waiting for rasterTask<commit_after>#include "tileWorker.h"

#include "platform.h"
#include "data/dataSource.h"
#include "tile/tile.h"
#include "view/view.h"
#include "scene/scene.h"
#include "tile/tileID.h"
#include "tile/tileTask.h"
#include "tile/tileBuilder.h"
#include "tangram.h"

#include <algorithm>

#define WORKER_NICENESS 10

namespace Tangram {

TileWorker::TileWorker(int _num_worker) {
    m_running = true;
    m_pendingTiles = false;

    for (int i = 0; i < _num_worker; i++) {
        auto worker = std::make_unique<Worker>();
        worker->thread = std::thread(&TileWorker::run, this, worker.get());
        m_workers.push_back(std::move(worker));
    }
}

TileWorker::~TileWorker(){
    if (m_running) {
        stop();
    }
}

void disposeBuilder(std::unique_ptr<TileBuilder> _builder) {
    if (_builder) {
        // Bind _builder to a std::function that will run on the next mainloop
        // iteration and does therefore dispose the TileBuilder, including it's
        // Scene reference with OpenGL resources on the mainloop. This is done
        // in order to ensure that no GL functions are called on
        // the worker-thread.
        auto disposer = std::bind([](auto builder){},
                                  std::shared_ptr<TileBuilder>(std::move(_builder)));

        Tangram::runOnMainLoop(disposer);
    }
}

void TileWorker::run(Worker* instance) {

    setCurrentThreadPriority(WORKER_NICENESS);

    std::unique_ptr<TileBuilder> builder;

    while (true) {

        std::shared_ptr<TileTask> task;
        {
            std::unique_lock<std::mutex> lock(m_mutex);

            m_condition.wait(lock, [&, this]{
                    return !m_running || !m_queue.empty();
                });

            if (instance->tileBuilder) {
                disposeBuilder(std::move(builder));

                builder = std::move(instance->tileBuilder);
                LOG("Passed new TileBuilder to TileWorker");
            }

            // Check if thread should stop
            if (!m_running) {
                disposeBuilder(std::move(builder));
                break;
            }

            if (!builder) {
                LOGE("Missing Scene/StyleContext in TileWorker!");
                continue;
            }

            // Remove all canceled tasks
            auto removes = std::remove_if(m_queue.begin(), m_queue.end(),
                                          [](const auto& a) { return a->isCanceled(); });

            m_queue.erase(removes, m_queue.end());

            if (m_queue.empty()) {
                continue;
            }

            // Pop highest priority tile from queue
            auto it = std::min_element(m_queue.begin(), m_queue.end(),
                [](const auto& a, const auto& b) {
                    if (a->isProxy() != b->isProxy()) {
                        return !a->isProxy();
                    }
                    if (a->source().id() == b->source().id() &&
                        a->sourceGeneration() != b->sourceGeneration()) {
                        return a->sourceGeneration() < b->sourceGeneration();
                    }
                    return a->getPriority() < b->getPriority();
                });

            task = std::move(*it);
            m_queue.erase(it);
        }

        if (task->isCanceled()) {
            continue;
        }

        auto tileData = task->source().parse(*task, *builder->scene().mapProjection());

        // const clock_t begin = clock();

        if (tileData) {

            auto raster = task->source().raster(*task);
            auto tile = builder->build(task->tileId(), *tileData, task->source());

            if (tile) { task->doneBuilding(); }

            // float loadTime = (float(clock() - begin) / CLOCKS_PER_SEC) * 1000;
            // LOG("loadTime %s - %f", task->tile()->getID().toString().c_str(), loadTime);

            std::unique_lock<std::mutex> lock(m_mutex);
            m_condition.wait(lock, [&]() {
                                        if (!m_running) { return true; }
                                        if (task->isCanceled()) { return true; }
                                        for (auto& raster : task->rasterTasks()) {
                                            if (!raster->hasData()) {
                                                return false;
                                            }
                                        }
                                        return true;
                                    });

            if (!m_running) {
                if (builder) {
                    disposeBuilder(std::move(builder));
                }
                tile.reset();
                m_queue.clear();
                break;
            }

            if (task->isCanceled()) {
                tile.reset();
                continue;
            }

            // first set self texture, if it has one, then go to reference raster textures
            if (raster.isValid()) {
                tile->rasters().push_back(std::move(raster));
            }
            for (auto& rasterTask : task->rasterTasks()) {
                auto rasterTex = rasterTask->source().raster(*rasterTask);
                if (rasterTex.isValid()) {
                    tile->rasters().push_back(std::move(rasterTex));
                }
            }

            // Mark task as ready
            task->setTile(std::move(tile));
        } else {
            task->cancel();
        }

        m_pendingTiles = true;

        requestRender();
    }
}

void TileWorker::setScene(std::shared_ptr<Scene>& _scene) {
    for (auto& worker : m_workers) {
        auto tileBuilder = std::make_unique<TileBuilder>();
        tileBuilder->setScene(_scene);

        worker->tileBuilder = std::move(tileBuilder);
    }
}

void TileWorker::enqueue(std::shared_ptr<TileTask>&& task) {
    {
        std::unique_lock<std::mutex> lock(m_mutex);
        if (!m_running) {
            return;
        }
        if (!task->isBuilt()) {
            m_queue.push_back(std::move(task));
        }
    }
    m_condition.notify_one();
}

void TileWorker::stop() {
    {
        std::unique_lock<std::mutex> lock(m_mutex);
        m_running = false;
    }

    m_condition.notify_all();

    for (auto& worker : m_workers) {
        worker->thread.join();
    }
}

}
<|endoftext|>


<commit_before>/*
 * Copyright (C) 2012 Apple Inc. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE, INC. ``AS IS'' AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE, INC. OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "third_party/compiler/ArrayBoundsClamper.h"

const char* kIntClampBegin = "// BEGIN: Generated code for array bounds clamping\n\n";
const char* kIntClampEnd = "// END: Generated code for array bounds clamping\n\n";
const char* kIntClampDefinition = "int webgl_int_clamp(int value, int minValue, int maxValue) { return ((value < minValue) ? minValue : ((value > maxValue) ? maxValue : value)); }\n\n";

namespace {

class ArrayBoundsClamperMarker : public TIntermTraverser {
public:
    ArrayBoundsClamperMarker()
        : mNeedsClamp(false)
   {
   }

   virtual bool visitBinary(Visit visit, TIntermBinary* node)
   {
       if (node->getOp() == EOpIndexIndirect)
       {
           TIntermTyped* left = node->getLeft();
           if (left->isArray() || left->isVector() || left->isMatrix())
           {
               node->setAddIndexClamp();
               mNeedsClamp = true;
           }
       }
       return true;
   }

    bool GetNeedsClamp() { return mNeedsClamp; }

private:
    bool mNeedsClamp;
};

}  // anonymous namespace

ArrayBoundsClamper::ArrayBoundsClamper()
    : mArrayBoundsClampDefinitionNeeded(false)
{
}

void ArrayBoundsClamper::OutputClampingFunctionDefinition(TInfoSinkBase& out) const
{
    if (!mArrayBoundsClampDefinitionNeeded)
    {
        return;
    }
    out << kIntClampBegin << kIntClampDefinition << kIntClampEnd;
}

void ArrayBoundsClamper::MarkIndirectArrayBoundsForClamping(TIntermNode* root)
{
    ASSERT(root);

    ArrayBoundsClamperMarker clamper;
    root->traverse(&clamper);
    if (clamper.GetNeedsClamp())
    {
        SetArrayBoundsClampDefinitionNeeded();
    }
}

<commit_msg>Add comments to ArrayBoundsClamper about why 'clamp' was not used to do the bounds clamping.<commit_after>/*
 * Copyright (C) 2012 Apple Inc. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE, INC. ``AS IS'' AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE, INC. OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "third_party/compiler/ArrayBoundsClamper.h"

// The built-in 'clamp' instruction only accepts floats and returns a float.  I
// iterated a few times with our driver team who examined the output from our
// compiler - they said the multiple casts generates more code than a single
// function call.  An inline ternary operator might have been better, but since
// the index value might be an expression itself, we'd have to make temporary
// variables to avoid evaluating the expression multiple times.  And making
// temporary variables was difficult because ANGLE would then need to make more
// brutal changes to the expression tree.

const char* kIntClampBegin = "// BEGIN: Generated code for array bounds clamping\n\n";
const char* kIntClampEnd = "// END: Generated code for array bounds clamping\n\n";
const char* kIntClampDefinition = "int webgl_int_clamp(int value, int minValue, int maxValue) { return ((value < minValue) ? minValue : ((value > maxValue) ? maxValue : value)); }\n\n";

namespace {

class ArrayBoundsClamperMarker : public TIntermTraverser {
public:
    ArrayBoundsClamperMarker()
        : mNeedsClamp(false)
   {
   }

   virtual bool visitBinary(Visit visit, TIntermBinary* node)
   {
       if (node->getOp() == EOpIndexIndirect)
       {
           TIntermTyped* left = node->getLeft();
           if (left->isArray() || left->isVector() || left->isMatrix())
           {
               node->setAddIndexClamp();
               mNeedsClamp = true;
           }
       }
       return true;
   }

    bool GetNeedsClamp() { return mNeedsClamp; }

private:
    bool mNeedsClamp;
};

}  // anonymous namespace

ArrayBoundsClamper::ArrayBoundsClamper()
    : mArrayBoundsClampDefinitionNeeded(false)
{
}

void ArrayBoundsClamper::OutputClampingFunctionDefinition(TInfoSinkBase& out) const
{
    if (!mArrayBoundsClampDefinitionNeeded)
    {
        return;
    }
    out << kIntClampBegin << kIntClampDefinition << kIntClampEnd;
}

void ArrayBoundsClamper::MarkIndirectArrayBoundsForClamping(TIntermNode* root)
{
    ASSERT(root);

    ArrayBoundsClamperMarker clamper;
    root->traverse(&clamper);
    if (clamper.GetNeedsClamp())
    {
        SetArrayBoundsClampDefinitionNeeded();
    }
}

<|endoftext|>


<commit_before>/*
 * Copyright (C) 2009, 2012 Google Inc. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
 *
 *     * Redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above
 * copyright notice, this list of conditions and the following disclaimer
 * in the documentation and/or other materials provided with the
 * distribution.
 *     * Neither the name of Google Inc. nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "config.h"

#include "bindings/v8/WorkerScriptController.h"

#include "V8DedicatedWorkerGlobalScope.h"
#include "V8ServiceWorkerGlobalScope.h"
#include "V8SharedWorkerGlobalScope.h"
#include "V8WorkerGlobalScope.h"
#include "bindings/v8/ScriptSourceCode.h"
#include "bindings/v8/ScriptValue.h"
#include "bindings/v8/V8ErrorHandler.h"
#include "bindings/v8/V8GCController.h"
#include "bindings/v8/V8Initializer.h"
#include "bindings/v8/V8ObjectConstructor.h"
#include "bindings/v8/V8ScriptRunner.h"
#include "bindings/v8/WrapperTypeInfo.h"
#include "core/inspector/ScriptCallStack.h"
#include "core/frame/DOMTimer.h"
#include "core/workers/SharedWorkerGlobalScope.h"
#include "core/workers/WorkerGlobalScope.h"
#include "core/workers/WorkerObjectProxy.h"
#include "core/workers/WorkerThread.h"
#include <v8.h>

#include "public/platform/Platform.h"
#include "public/platform/WebWorkerRunLoop.h"

namespace WebCore {

WorkerScriptController::WorkerScriptController(WorkerGlobalScope& workerGlobalScope)
    : m_workerGlobalScope(workerGlobalScope)
    , m_isolateHolder(adoptPtr(new gin::IsolateHolder(v8::Isolate::New())))
    , m_executionForbidden(false)
    , m_executionScheduledToTerminate(false)
{
    isolate()->Enter();
    V8Initializer::initializeWorker(isolate());
    v8::V8::Initialize();
    V8PerIsolateData* data = V8PerIsolateData::create(isolate());
    m_domDataStore = adoptPtr(new DOMDataStore(WorkerWorld));
    data->setWorkerDOMDataStore(m_domDataStore.get());
}

WorkerScriptController::~WorkerScriptController()
{
    m_domDataStore.clear();

    // The corresponding call to didStartWorkerRunLoop is in
    // WorkerThread::workerThread().
    // See http://webkit.org/b/83104#c14 for why this is here.
    blink::Platform::current()->didStopWorkerRunLoop(blink::WebWorkerRunLoop(&m_workerGlobalScope.thread()->runLoop()));

    disposeContext();
    V8PerIsolateData::dispose(isolate());
    v8::Isolate* v8Isolate = isolate();
    v8Isolate->Exit();
    m_isolateHolder.clear();
    v8Isolate->Dispose();
}

void WorkerScriptController::disposeContext()
{
    m_perContextData.clear();
    m_contextHolder.clear();
}

bool WorkerScriptController::initializeContextIfNeeded()
{
    if (m_contextHolder)
        return true;

    v8::Handle<v8::Context> context = v8::Context::New(isolate());
    if (context.IsEmpty())
        return false;

    m_contextHolder = adoptPtr(new gin::ContextHolder(isolate()));
    m_contextHolder->SetContext(context);

    v8::Context::Scope scope(context);

    V8PerContextDataHolder::install(context);

    m_perContextData = V8PerContextData::create(context);
    if (!m_perContextData->init()) {
        disposeContext();
        return false;
    }

    // Set DebugId for the new context.
    context->SetEmbedderData(0, v8AtomicString(isolate(), "worker"));

    // Create a new JS object and use it as the prototype for the shadow global object.
    const WrapperTypeInfo* contextType = &V8DedicatedWorkerGlobalScope::wrapperTypeInfo;
    if (m_workerGlobalScope.isServiceWorkerGlobalScope())
        contextType = &V8ServiceWorkerGlobalScope::wrapperTypeInfo;
    else if (!m_workerGlobalScope.isDedicatedWorkerGlobalScope())
        contextType = &V8SharedWorkerGlobalScope::wrapperTypeInfo;
    v8::Handle<v8::Function> workerGlobalScopeConstructor = m_perContextData->constructorForType(contextType);
    v8::Local<v8::Object> jsWorkerGlobalScope = V8ObjectConstructor::newInstance(workerGlobalScopeConstructor);
    if (jsWorkerGlobalScope.IsEmpty()) {
        disposeContext();
        return false;
    }

    V8DOMWrapper::associateObjectWithWrapper<V8WorkerGlobalScope>(PassRefPtr<WorkerGlobalScope>(m_workerGlobalScope), contextType, jsWorkerGlobalScope, isolate(), WrapperConfiguration::Dependent);

    // Insert the object instance as the prototype of the shadow object.
    v8::Handle<v8::Object> globalObject = v8::Handle<v8::Object>::Cast(m_contextHolder->context()->Global()->GetPrototype());
    globalObject->SetPrototype(jsWorkerGlobalScope);

    return true;
}

ScriptValue WorkerScriptController::evaluate(const String& script, const String& fileName, const TextPosition& scriptStartPosition, WorkerGlobalScopeExecutionState* state)
{
    v8::HandleScope handleScope(isolate());

    if (!initializeContextIfNeeded())
        return ScriptValue();

    v8::Handle<v8::Context> context = m_contextHolder->context();
    if (!m_disableEvalPending.isEmpty()) {
        context->AllowCodeGenerationFromStrings(false);
        context->SetErrorMessageForCodeGenerationFromStrings(v8String(isolate(), m_disableEvalPending));
        m_disableEvalPending = String();
    }

    v8::Context::Scope scope(context);

    v8::TryCatch block;

    v8::Handle<v8::String> scriptString = v8String(isolate(), script);
    v8::Handle<v8::Script> compiledScript = V8ScriptRunner::compileScript(scriptString, fileName, scriptStartPosition, 0, isolate());
    v8::Local<v8::Value> result = V8ScriptRunner::runCompiledScript(compiledScript, &m_workerGlobalScope, isolate());

    if (!block.CanContinue()) {
        m_workerGlobalScope.script()->forbidExecution();
        return ScriptValue();
    }

    if (block.HasCaught()) {
        v8::Local<v8::Message> message = block.Message();
        state->hadException = true;
        state->errorMessage = toCoreString(message->Get());
        state->lineNumber = message->GetLineNumber();
        state->columnNumber = message->GetStartColumn() + 1;
        V8TRYCATCH_FOR_V8STRINGRESOURCE_RETURN(V8StringResource<>, sourceURL, message->GetScriptResourceName(), ScriptValue());
        state->sourceURL = sourceURL;
        state->exception = ScriptValue(block.Exception(), isolate());
        block.Reset();
    } else
        state->hadException = false;

    if (result.IsEmpty() || result->IsUndefined())
        return ScriptValue();

    return ScriptValue(result, isolate());
}

void WorkerScriptController::evaluate(const ScriptSourceCode& sourceCode, RefPtr<ErrorEvent>* errorEvent)
{
    if (isExecutionForbidden())
        return;

    WorkerGlobalScopeExecutionState state;
    evaluate(sourceCode.source(), sourceCode.url().string(), sourceCode.startPosition(), &state);
    if (state.hadException) {
        if (errorEvent) {
            *errorEvent = m_workerGlobalScope.shouldSanitizeScriptError(state.sourceURL, NotSharableCrossOrigin) ?
                ErrorEvent::createSanitizedError(0) : ErrorEvent::create(state.errorMessage, state.sourceURL, state.lineNumber, state.columnNumber, 0);
            V8ErrorHandler::storeExceptionOnErrorEventWrapper(errorEvent->get(), state.exception.v8Value(), isolate());
        } else {
            ASSERT(!m_workerGlobalScope.shouldSanitizeScriptError(state.sourceURL, NotSharableCrossOrigin));
            RefPtr<ErrorEvent> event = m_errorEventFromImportedScript ? m_errorEventFromImportedScript.release() : ErrorEvent::create(state.errorMessage, state.sourceURL, state.lineNumber, state.columnNumber, 0);
            m_workerGlobalScope.reportException(event, 0, NotSharableCrossOrigin);
        }
    }
}

void WorkerScriptController::scheduleExecutionTermination()
{
    // The mutex provides a memory barrier to ensure that once
    // termination is scheduled, isExecutionTerminating will
    // accurately reflect that state when called from another thread.
    {
        MutexLocker locker(m_scheduledTerminationMutex);
        m_executionScheduledToTerminate = true;
    }
    v8::V8::TerminateExecution(isolate());
}

bool WorkerScriptController::isExecutionTerminating() const
{
    // See comments in scheduleExecutionTermination regarding mutex usage.
    MutexLocker locker(m_scheduledTerminationMutex);
    return m_executionScheduledToTerminate;
}

void WorkerScriptController::forbidExecution()
{
    ASSERT(m_workerGlobalScope.isContextThread());
    m_executionForbidden = true;
}

bool WorkerScriptController::isExecutionForbidden() const
{
    ASSERT(m_workerGlobalScope.isContextThread());
    return m_executionForbidden;
}

void WorkerScriptController::disableEval(const String& errorMessage)
{
    m_disableEvalPending = errorMessage;
}

void WorkerScriptController::rethrowExceptionFromImportedScript(PassRefPtr<ErrorEvent> errorEvent)
{
    m_errorEventFromImportedScript = errorEvent;
    throwError(V8ThrowException::createError(v8GeneralError, m_errorEventFromImportedScript->message(), isolate()), isolate());
}

WorkerScriptController* WorkerScriptController::controllerForContext()
{
    v8::Isolate* isolate = v8::Isolate::GetCurrent();
    // Happens on frame destruction, check otherwise GetCurrent() will crash.
    if (!isolate || !isolate->InContext())
        return 0;
    v8::Handle<v8::Context> context = isolate->GetCurrentContext();
    v8::Handle<v8::Object> global = context->Global();
    global = global->FindInstanceInPrototypeChain(V8WorkerGlobalScope::domTemplate(isolate, WorkerWorld));
    // Return 0 if the current executing context is not the worker context.
    if (global.IsEmpty())
        return 0;
    WorkerGlobalScope* workerGlobalScope = V8WorkerGlobalScope::toNative(global);
    return workerGlobalScope->script();
}

} // namespace WebCore
<commit_msg>First initialize the v8::Isolate on workers before passing it to gin<commit_after>/*
 * Copyright (C) 2009, 2012 Google Inc. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
 *
 *     * Redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above
 * copyright notice, this list of conditions and the following disclaimer
 * in the documentation and/or other materials provided with the
 * distribution.
 *     * Neither the name of Google Inc. nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "config.h"

#include "bindings/v8/WorkerScriptController.h"

#include "V8DedicatedWorkerGlobalScope.h"
#include "V8ServiceWorkerGlobalScope.h"
#include "V8SharedWorkerGlobalScope.h"
#include "V8WorkerGlobalScope.h"
#include "bindings/v8/ScriptSourceCode.h"
#include "bindings/v8/ScriptValue.h"
#include "bindings/v8/V8ErrorHandler.h"
#include "bindings/v8/V8GCController.h"
#include "bindings/v8/V8Initializer.h"
#include "bindings/v8/V8ObjectConstructor.h"
#include "bindings/v8/V8ScriptRunner.h"
#include "bindings/v8/WrapperTypeInfo.h"
#include "core/inspector/ScriptCallStack.h"
#include "core/frame/DOMTimer.h"
#include "core/workers/SharedWorkerGlobalScope.h"
#include "core/workers/WorkerGlobalScope.h"
#include "core/workers/WorkerObjectProxy.h"
#include "core/workers/WorkerThread.h"
#include <v8.h>

#include "public/platform/Platform.h"
#include "public/platform/WebWorkerRunLoop.h"

namespace WebCore {

WorkerScriptController::WorkerScriptController(WorkerGlobalScope& workerGlobalScope)
    : m_workerGlobalScope(workerGlobalScope)
    , m_executionForbidden(false)
    , m_executionScheduledToTerminate(false)
{
    v8::Isolate* isolate = v8::Isolate::New();
    isolate->Enter();
    V8Initializer::initializeWorker(isolate);
    v8::V8::Initialize();
    m_isolateHolder = adoptPtr(new gin::IsolateHolder(isolate));
    V8PerIsolateData* data = V8PerIsolateData::create(isolate);
    m_domDataStore = adoptPtr(new DOMDataStore(WorkerWorld));
    data->setWorkerDOMDataStore(m_domDataStore.get());
}

WorkerScriptController::~WorkerScriptController()
{
    m_domDataStore.clear();

    // The corresponding call to didStartWorkerRunLoop is in
    // WorkerThread::workerThread().
    // See http://webkit.org/b/83104#c14 for why this is here.
    blink::Platform::current()->didStopWorkerRunLoop(blink::WebWorkerRunLoop(&m_workerGlobalScope.thread()->runLoop()));

    disposeContext();
    V8PerIsolateData::dispose(isolate());
    v8::Isolate* v8Isolate = isolate();
    v8Isolate->Exit();
    m_isolateHolder.clear();
    v8Isolate->Dispose();
}

void WorkerScriptController::disposeContext()
{
    m_perContextData.clear();
    m_contextHolder.clear();
}

bool WorkerScriptController::initializeContextIfNeeded()
{
    if (m_contextHolder)
        return true;

    v8::Handle<v8::Context> context = v8::Context::New(isolate());
    if (context.IsEmpty())
        return false;

    m_contextHolder = adoptPtr(new gin::ContextHolder(isolate()));
    m_contextHolder->SetContext(context);

    v8::Context::Scope scope(context);

    V8PerContextDataHolder::install(context);

    m_perContextData = V8PerContextData::create(context);
    if (!m_perContextData->init()) {
        disposeContext();
        return false;
    }

    // Set DebugId for the new context.
    context->SetEmbedderData(0, v8AtomicString(isolate(), "worker"));

    // Create a new JS object and use it as the prototype for the shadow global object.
    const WrapperTypeInfo* contextType = &V8DedicatedWorkerGlobalScope::wrapperTypeInfo;
    if (m_workerGlobalScope.isServiceWorkerGlobalScope())
        contextType = &V8ServiceWorkerGlobalScope::wrapperTypeInfo;
    else if (!m_workerGlobalScope.isDedicatedWorkerGlobalScope())
        contextType = &V8SharedWorkerGlobalScope::wrapperTypeInfo;
    v8::Handle<v8::Function> workerGlobalScopeConstructor = m_perContextData->constructorForType(contextType);
    v8::Local<v8::Object> jsWorkerGlobalScope = V8ObjectConstructor::newInstance(workerGlobalScopeConstructor);
    if (jsWorkerGlobalScope.IsEmpty()) {
        disposeContext();
        return false;
    }

    V8DOMWrapper::associateObjectWithWrapper<V8WorkerGlobalScope>(PassRefPtr<WorkerGlobalScope>(m_workerGlobalScope), contextType, jsWorkerGlobalScope, isolate(), WrapperConfiguration::Dependent);

    // Insert the object instance as the prototype of the shadow object.
    v8::Handle<v8::Object> globalObject = v8::Handle<v8::Object>::Cast(m_contextHolder->context()->Global()->GetPrototype());
    globalObject->SetPrototype(jsWorkerGlobalScope);

    return true;
}

ScriptValue WorkerScriptController::evaluate(const String& script, const String& fileName, const TextPosition& scriptStartPosition, WorkerGlobalScopeExecutionState* state)
{
    v8::HandleScope handleScope(isolate());

    if (!initializeContextIfNeeded())
        return ScriptValue();

    v8::Handle<v8::Context> context = m_contextHolder->context();
    if (!m_disableEvalPending.isEmpty()) {
        context->AllowCodeGenerationFromStrings(false);
        context->SetErrorMessageForCodeGenerationFromStrings(v8String(isolate(), m_disableEvalPending));
        m_disableEvalPending = String();
    }

    v8::Context::Scope scope(context);

    v8::TryCatch block;

    v8::Handle<v8::String> scriptString = v8String(isolate(), script);
    v8::Handle<v8::Script> compiledScript = V8ScriptRunner::compileScript(scriptString, fileName, scriptStartPosition, 0, isolate());
    v8::Local<v8::Value> result = V8ScriptRunner::runCompiledScript(compiledScript, &m_workerGlobalScope, isolate());

    if (!block.CanContinue()) {
        m_workerGlobalScope.script()->forbidExecution();
        return ScriptValue();
    }

    if (block.HasCaught()) {
        v8::Local<v8::Message> message = block.Message();
        state->hadException = true;
        state->errorMessage = toCoreString(message->Get());
        state->lineNumber = message->GetLineNumber();
        state->columnNumber = message->GetStartColumn() + 1;
        V8TRYCATCH_FOR_V8STRINGRESOURCE_RETURN(V8StringResource<>, sourceURL, message->GetScriptResourceName(), ScriptValue());
        state->sourceURL = sourceURL;
        state->exception = ScriptValue(block.Exception(), isolate());
        block.Reset();
    } else
        state->hadException = false;

    if (result.IsEmpty() || result->IsUndefined())
        return ScriptValue();

    return ScriptValue(result, isolate());
}

void WorkerScriptController::evaluate(const ScriptSourceCode& sourceCode, RefPtr<ErrorEvent>* errorEvent)
{
    if (isExecutionForbidden())
        return;

    WorkerGlobalScopeExecutionState state;
    evaluate(sourceCode.source(), sourceCode.url().string(), sourceCode.startPosition(), &state);
    if (state.hadException) {
        if (errorEvent) {
            *errorEvent = m_workerGlobalScope.shouldSanitizeScriptError(state.sourceURL, NotSharableCrossOrigin) ?
                ErrorEvent::createSanitizedError(0) : ErrorEvent::create(state.errorMessage, state.sourceURL, state.lineNumber, state.columnNumber, 0);
            V8ErrorHandler::storeExceptionOnErrorEventWrapper(errorEvent->get(), state.exception.v8Value(), isolate());
        } else {
            ASSERT(!m_workerGlobalScope.shouldSanitizeScriptError(state.sourceURL, NotSharableCrossOrigin));
            RefPtr<ErrorEvent> event = m_errorEventFromImportedScript ? m_errorEventFromImportedScript.release() : ErrorEvent::create(state.errorMessage, state.sourceURL, state.lineNumber, state.columnNumber, 0);
            m_workerGlobalScope.reportException(event, 0, NotSharableCrossOrigin);
        }
    }
}

void WorkerScriptController::scheduleExecutionTermination()
{
    // The mutex provides a memory barrier to ensure that once
    // termination is scheduled, isExecutionTerminating will
    // accurately reflect that state when called from another thread.
    {
        MutexLocker locker(m_scheduledTerminationMutex);
        m_executionScheduledToTerminate = true;
    }
    v8::V8::TerminateExecution(isolate());
}

bool WorkerScriptController::isExecutionTerminating() const
{
    // See comments in scheduleExecutionTermination regarding mutex usage.
    MutexLocker locker(m_scheduledTerminationMutex);
    return m_executionScheduledToTerminate;
}

void WorkerScriptController::forbidExecution()
{
    ASSERT(m_workerGlobalScope.isContextThread());
    m_executionForbidden = true;
}

bool WorkerScriptController::isExecutionForbidden() const
{
    ASSERT(m_workerGlobalScope.isContextThread());
    return m_executionForbidden;
}

void WorkerScriptController::disableEval(const String& errorMessage)
{
    m_disableEvalPending = errorMessage;
}

void WorkerScriptController::rethrowExceptionFromImportedScript(PassRefPtr<ErrorEvent> errorEvent)
{
    m_errorEventFromImportedScript = errorEvent;
    throwError(V8ThrowException::createError(v8GeneralError, m_errorEventFromImportedScript->message(), isolate()), isolate());
}

WorkerScriptController* WorkerScriptController::controllerForContext()
{
    v8::Isolate* isolate = v8::Isolate::GetCurrent();
    // Happens on frame destruction, check otherwise GetCurrent() will crash.
    if (!isolate || !isolate->InContext())
        return 0;
    v8::Handle<v8::Context> context = isolate->GetCurrentContext();
    v8::Handle<v8::Object> global = context->Global();
    global = global->FindInstanceInPrototypeChain(V8WorkerGlobalScope::domTemplate(isolate, WorkerWorld));
    // Return 0 if the current executing context is not the worker context.
    if (global.IsEmpty())
        return 0;
    WorkerGlobalScope* workerGlobalScope = V8WorkerGlobalScope::toNative(global);
    return workerGlobalScope->script();
}

} // namespace WebCore
<|endoftext|>


<commit_before>/**************************************************************************
 *
 * Copyright 2011 Jose Fonseca
 * All Rights Reserved.
 *
 * 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 <string.h>
#include <iostream>

#include "os_time.hpp"
#include "trace_dump.hpp"
#include "retrace.hpp"

namespace retrace {

static bool call_dumped = false;

static void dumpCall(trace::Call &call) {
    if (verbosity >= 0 && !call_dumped) {
        std::cout << call;
        std::cout.flush();
        call_dumped = true;
    }
}

std::ostream &warning(trace::Call &call) {
    dumpCall(call);

    std::cerr << call.no << ": ";
    std::cerr << "warning: ";

    return std::cerr;
}

void ignore(trace::Call &call) {
    (void)call;
}

void unsupported(trace::Call &call) {
    warning(call) << "unsupported " << call.name() << " call\n";
}

inline void Retracer::addCallback(const Entry *entry) {
    assert(entry->name);
    assert(entry->callback);
    map[entry->name] = entry->callback;
}

void Retracer::addCallbacks(const Entry *entries) {
    while (entries->name && entries->callback) {
        addCallback(entries++);
    }
}

void Retracer::retrace(trace::Call &call) {
    call_dumped = false;

    Callback callback = 0;

    trace::Id id = call.sig->id;
    if (id >= callbacks.size()) {
        callbacks.resize(id + 1);
        callback = 0;
    } else {
        callback = callbacks[id];
    }

    if (!callback) {
        Map::const_iterator it = map.find(call.name());
        if (it == map.end()) {
            callback = &unsupported;
        } else {
            callback = it->second;
        }
        callbacks[id] = callback;
    }

    assert(callback);
    assert(callbacks[id] == callback);

    if (verbosity >= 1) {
        if (verbosity >= 2 ||
            (!(call.flags & trace::CALL_FLAG_VERBOSE) &&
             callback != &ignore)) {
            dumpCall(call);
        }
    }

    callback(call);
}

} /* namespace retrace */
<commit_msg>Dump thread ids on retrace.<commit_after>/**************************************************************************
 *
 * Copyright 2011 Jose Fonseca
 * All Rights Reserved.
 *
 * 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 <string.h>
#include <iostream>

#include "os_time.hpp"
#include "trace_dump.hpp"
#include "retrace.hpp"

namespace retrace {

static bool call_dumped = false;

static void dumpCall(trace::Call &call) {
    if (verbosity >= 0 && !call_dumped) {
        std::cout << std::hex << call.thread_id << std::dec << " ";
        std::cout << call;
        std::cout.flush();
        call_dumped = true;
    }
}

std::ostream &warning(trace::Call &call) {
    dumpCall(call);

    std::cerr << call.no << ": ";
    std::cerr << "warning: ";

    return std::cerr;
}

void ignore(trace::Call &call) {
    (void)call;
}

void unsupported(trace::Call &call) {
    warning(call) << "unsupported " << call.name() << " call\n";
}

inline void Retracer::addCallback(const Entry *entry) {
    assert(entry->name);
    assert(entry->callback);
    map[entry->name] = entry->callback;
}

void Retracer::addCallbacks(const Entry *entries) {
    while (entries->name && entries->callback) {
        addCallback(entries++);
    }
}

void Retracer::retrace(trace::Call &call) {
    call_dumped = false;

    Callback callback = 0;

    trace::Id id = call.sig->id;
    if (id >= callbacks.size()) {
        callbacks.resize(id + 1);
        callback = 0;
    } else {
        callback = callbacks[id];
    }

    if (!callback) {
        Map::const_iterator it = map.find(call.name());
        if (it == map.end()) {
            callback = &unsupported;
        } else {
            callback = it->second;
        }
        callbacks[id] = callback;
    }

    assert(callback);
    assert(callbacks[id] == callback);

    if (verbosity >= 1) {
        if (verbosity >= 2 ||
            (!(call.flags & trace::CALL_FLAG_VERBOSE) &&
             callback != &ignore)) {
            dumpCall(call);
        }
    }

    callback(call);
}

} /* namespace retrace */
<|endoftext|>


<commit_before>/*
  Last update: 26/03/2012, vzero branch, in PbPb macro execute the vzero code, a bug was fixed
  New modifications: 08/10/2014 - more modularity
*/

AliAnalysisTaskHighPtDeDx* AddTaskHighPtDeDx(Bool_t AnalysisMC, const Char_t* taskname, Int_t typerun, Float_t minc, Float_t maxc )
{
  // Creates a pid task and adds it to the analysis manager
  UInt_t kTriggerInt[2] = { AliVEvent::kMB, AliVEvent::kCentral + AliVEvent::kSemiCentral };

  // Get the pointer to the existing analysis manager via the static
  //access method
  //=========================================================================
  AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
  if (!mgr) {
    Error("AddTaskHighPtDeDx", "No analysis manager to connect to.");
    return NULL;
  }

  // Check the analysis type using the event handlers connected to the
  // analysis manager The availability of MC handler can also be
  // checked here.
  // =========================================================================
  if (!mgr->GetInputEventHandler()) {
    Error("AddTaskHighPtDeDx", "This task requires an input event handler");
    return NULL;
  }

  //
  // Add track filters, with Golden Cuts
  //
  /*
  AliAnalysisFilter* trackFilterGolden = new AliAnalysisFilter("trackFilter");
  AliESDtrackCuts* esdTrackCutsGolden =
    AliESDtrackCuts::GetStandardITSTPCTrackCuts2010(kTRUE);
  trackFilterGolden->AddCuts(esdTrackCutsGolden);
  */

  AliAnalysisFilter* trackFilterGolden = new AliAnalysisFilter("trackFilter");
  AliESDtrackCuts* esdTrackCutsGolden = AliESDtrackCuts::GetStandardITSTPCTrackCuts2010(kTRUE,1);
  esdTrackCutsGolden->SetMinNCrossedRowsTPC(120);
  esdTrackCutsGolden->SetMinRatioCrossedRowsOverFindableClustersTPC(0.8);
  esdTrackCutsGolden->SetMaxChi2PerClusterITS(36);
  esdTrackCutsGolden->SetMaxFractionSharedTPCClusters(0.4);
  esdTrackCutsGolden->SetMaxChi2TPCConstrainedGlobal(36);
  esdTrackCutsGolden->SetMaxDCAToVertexXY(3.0);

  trackFilterGolden->AddCuts(esdTrackCutsGolden);

  //old cuts without golden cut
  AliAnalysisFilter* trackFilter0 = new AliAnalysisFilter("trackFilter");
  Bool_t clusterCut=0;
  Bool_t selPrimaries=kTRUE;
  AliESDtrackCuts* esdTrackCutsL0 = new AliESDtrackCuts;
 // TPC
  if(clusterCut == 0)  esdTrackCutsL0->SetMinNClustersTPC(70);
  else if (clusterCut == 1) {
    esdTrackCutsL0->SetMinNCrossedRowsTPC(70);
    esdTrackCutsL0->SetMinRatioCrossedRowsOverFindableClustersTPC(0.8);
  }
  else {
    AliWarningClass(Form("Wrong value of the clusterCut parameter (%d), using cut on Nclusters",clusterCut));
    esdTrackCutsL0->SetMinNClustersTPC(70);
  }
  esdTrackCutsL0->SetMaxChi2PerClusterTPC(4);
  esdTrackCutsL0->SetAcceptKinkDaughters(kFALSE);
  esdTrackCutsL0->SetRequireTPCRefit(kTRUE);
  // ITS
  esdTrackCutsL0->SetRequireITSRefit(kTRUE);
  esdTrackCutsL0->SetClusterRequirementITS(AliESDtrackCuts::kSPD,
					 AliESDtrackCuts::kAny);
  if(selPrimaries) {
    // 7*(0.0026+0.0050/pt^1.01)
    esdTrackCutsL0->SetMaxDCAToVertexXYPtDep("0.0182+0.0350/pt^1.01");
  }
  esdTrackCutsL0->SetMaxDCAToVertexZ(2);
  esdTrackCutsL0->SetDCAToVertex2D(kFALSE);
  esdTrackCutsL0->SetRequireSigmaToVertex(kFALSE);
  esdTrackCutsL0->SetMaxChi2PerClusterITS(1e10);
  esdTrackCutsL0->SetMaxChi2TPCConstrainedGlobal(1e10);

  trackFilter0->AddCuts(esdTrackCutsL0);

  AliAnalysisFilter* trackFilterTPC = new AliAnalysisFilter("trackFilterTPC");
  AliESDtrackCuts* esdTrackCutsTPC =
  AliESDtrackCuts::GetStandardTPCOnlyTrackCuts();
  trackFilterTPC->AddCuts(esdTrackCutsTPC);

  // Create the task and configure it
  //========================================================================
  if(typerun==2){//heavy ion analysis

    AliAnalysisTaskHighPtDeDx* taskHighPtDeDx;
    taskHighPtDeDx=0;
    Char_t TaskName[256]={0};
    sprintf(TaskName,"%s_%1.0f_%1.0f",taskname,minc,maxc);

    taskHighPtDeDx = new AliAnalysisTaskHighPtDeDx(TaskName);
    TString type = mgr->GetInputEventHandler()->GetDataType(); // can be "ESD" or "AOD"
    taskHighPtDeDx->SetAnalysisType(type);
    taskHighPtDeDx->SetAnalysisMC(AnalysisMC);
    taskHighPtDeDx->SetAnalysisPbPb(kTRUE);
    taskHighPtDeDx->SetProduceVZEROBranch(kTRUE);
    taskHighPtDeDx->SetProduceTPCBranch(kFALSE);
    taskHighPtDeDx->SetDebugLevel(0);
    taskHighPtDeDx->SetEtaCut(0.8);
    taskHighPtDeDx->SetVtxCut(10.0);
    taskHighPtDeDx->SetMinPt(0.0); // default 2.0
    taskHighPtDeDx->SetLowPtFraction(0.01); // keep 1% of tracks below min pt
    taskHighPtDeDx->SetTreeOption(1);
    taskHighPtDeDx->SetTrigger1(kTriggerInt[0]);
    taskHighPtDeDx->SetTrigger2(kTriggerInt[1]);
    taskHighPtDeDx->SetMinCent(minc);
    taskHighPtDeDx->SetMaxCent(maxc);
    //Set Filtesr
    taskHighPtDeDx->SetTrackFilterGolden(trackFilterGolden);
    taskHighPtDeDx->SetTrackFilter(trackFilter0);
    taskHighPtDeDx->SetTrackFilterTPC(trackFilterTPC);

    //V0's cuts
    taskHighPtDeDx->SetMassCut(0.1);         // def: 0.03
    taskHighPtDeDx->SetRequireRecV0(kTRUE); // def: kTRUE
    taskHighPtDeDx->SetStoreMcIn(kTRUE);     // def: kFALSE

    mgr->AddTask(taskHighPtDeDx);

    // Create ONLY the output containers for the data produced by the
    // task.  Get and connect other common input/output containers via
    // the manager as below
    //=======================================================================
    AliAnalysisDataContainer *cout_hist;
    cout_hist=0;

    TString outputFileName = AliAnalysisManager::GetCommonFileName();

    //Arrangements for subdirectories (not implemented yet)
    //outputFileName += ":PWGLF_StrVsMult";
    //if (mgr->GetMCtruthEventHandler()) outputFileName += "_MC";

    cout_hist = mgr->CreateContainer(Form("output_%1.0f_%1.0f",minc,maxc), TList::Class(), AliAnalysisManager::kOutputContainer, outputFileName);
    mgr->ConnectInput (taskHighPtDeDx, 0, mgr->GetCommonInputContainer());
    mgr->ConnectOutput(taskHighPtDeDx, 1, cout_hist);

    // Return task pointer at the end
    return taskHighPtDeDx;
  }
}
<commit_msg>Some test changes<commit_after>/*
  Last update: 26/03/2012, vzero branch, in PbPb macro execute the vzero code, a bug was fixed
*/

AliAnalysisTask* AddTask(Bool_t AnalysisMC, const Char_t* taskname, Int_t typerun, UInt_t kTriggerInt[], Float_t minc[], Float_t maxc[] )
{
  // Creates a pid task and adds it to the analysis manager

  // Get the pointer to the existing analysis manager via the static
  //access method
  //=========================================================================
  AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
  if (!mgr) {
    Error("AddTaskHighPtDeDx", "No analysis manager to connect to.");
    return NULL;
  }

  // Check the analysis type using the event handlers connected to the
  // analysis manager The availability of MC handler can also be
  // checked here.
  // =========================================================================
  if (!mgr->GetInputEventHandler()) {
    Error("AddTaskHighPtDeDx", "This task requires an input event handler");
    return NULL;
  }

  //
  // Add track filters, with Golden Cuts
  //
  /*
  AliAnalysisFilter* trackFilterGolden = new AliAnalysisFilter("trackFilter");
  AliESDtrackCuts* esdTrackCutsGolden =
    AliESDtrackCuts::GetStandardITSTPCTrackCuts2010(kTRUE);
  trackFilterGolden->AddCuts(esdTrackCutsGolden);
  */

  AliAnalysisFilter* trackFilterGolden = new AliAnalysisFilter("trackFilter");
  AliESDtrackCuts* esdTrackCutsGolden = AliESDtrackCuts::GetStandardITSTPCTrackCuts2010(kTRUE,1);
  esdTrackCutsGolden->SetMinNCrossedRowsTPC(120);
  esdTrackCutsGolden->SetMinRatioCrossedRowsOverFindableClustersTPC(0.8);
  esdTrackCutsGolden->SetMaxChi2PerClusterITS(36);
  esdTrackCutsGolden->SetMaxFractionSharedTPCClusters(0.4);
  esdTrackCutsGolden->SetMaxChi2TPCConstrainedGlobal(36);
  esdTrackCutsGolden->SetMaxDCAToVertexXY(3.0);

  trackFilterGolden->AddCuts(esdTrackCutsGolden);

  //old cuts without golden cut
  AliAnalysisFilter* trackFilter0 = new AliAnalysisFilter("trackFilter");
  Bool_t clusterCut=0;
  Bool_t selPrimaries=kTRUE;
  AliESDtrackCuts* esdTrackCutsL0 = new AliESDtrackCuts;
 // TPC
  if(clusterCut == 0)  esdTrackCutsL0->SetMinNClustersTPC(70);
  else if (clusterCut == 1) {
    esdTrackCutsL0->SetMinNCrossedRowsTPC(70);
    esdTrackCutsL0->SetMinRatioCrossedRowsOverFindableClustersTPC(0.8);
  }
  else {
    AliWarningClass(Form("Wrong value of the clusterCut parameter (%d), using cut on Nclusters",clusterCut));
    esdTrackCutsL0->SetMinNClustersTPC(70);
  }
  esdTrackCutsL0->SetMaxChi2PerClusterTPC(4);
  esdTrackCutsL0->SetAcceptKinkDaughters(kFALSE);
  esdTrackCutsL0->SetRequireTPCRefit(kTRUE);
  // ITS
  esdTrackCutsL0->SetRequireITSRefit(kTRUE);
  esdTrackCutsL0->SetClusterRequirementITS(AliESDtrackCuts::kSPD,
					 AliESDtrackCuts::kAny);
  if(selPrimaries) {
    // 7*(0.0026+0.0050/pt^1.01)
    esdTrackCutsL0->SetMaxDCAToVertexXYPtDep("0.0182+0.0350/pt^1.01");
  }
  esdTrackCutsL0->SetMaxDCAToVertexZ(2);
  esdTrackCutsL0->SetDCAToVertex2D(kFALSE);
  esdTrackCutsL0->SetRequireSigmaToVertex(kFALSE);
  esdTrackCutsL0->SetMaxChi2PerClusterITS(1e10);
  esdTrackCutsL0->SetMaxChi2TPCConstrainedGlobal(1e10);

  trackFilter0->AddCuts(esdTrackCutsL0);

  AliAnalysisFilter* trackFilterTPC = new AliAnalysisFilter("trackFilterTPC");
  AliESDtrackCuts* esdTrackCutsTPC =
    AliESDtrackCuts::GetStandardTPCOnlyTrackCuts();
  trackFilterTPC->AddCuts(esdTrackCutsTPC);

  // Create the task and configure it
  //========================================================================
  if(typerun==2){//heavy ion analysis

    AliAnalysisTaskHighPtDeDx* taskHighPtDeDx[6];
    for( Int_t i=0; i<6; ++i ){
      taskHighPtDeDx[i]=0;
      Char_t TaskName[256]={0};
      sprintf(TaskName,"%s_%1.0f_%1.0f",taskname,minc[i],maxc[i]);

      taskHighPtDeDx[i] = new AliAnalysisTaskHighPtDeDx(TaskName);
      TString type = mgr->GetInputEventHandler()->GetDataType(); // can be "ESD" or "AOD"
      taskHighPtDeDx[i]->SetAnalysisType(type);
      taskHighPtDeDx[i]->SetAnalysisMC(AnalysisMC);
      taskHighPtDeDx[i]->SetAnalysisPbPb(kTRUE);
      taskHighPtDeDx[i]->SetProduceVZEROBranch(kTRUE);
      taskHighPtDeDx[i]->SetProduceTPCBranch(kFALSE);
      taskHighPtDeDx[i]->SetDebugLevel(0);
      taskHighPtDeDx[i]->SetEtaCut(0.8);
      taskHighPtDeDx[i]->SetVtxCut(10.0);
      taskHighPtDeDx[i]->SetMinPt(0.0); // default 2.0
      taskHighPtDeDx[i]->SetLowPtFraction(0.01); // keep 1% of tracks below min pt
      taskHighPtDeDx[i]->SetTreeOption(1);
      taskHighPtDeDx[i]->SetTrigger1(kTriggerInt[0]);
      taskHighPtDeDx[i]->SetTrigger2(kTriggerInt[1]);
      taskHighPtDeDx[i]->SetMinCent(minc[i]);
      taskHighPtDeDx[i]->SetMaxCent(maxc[i]);
      //Set Filtesr
      taskHighPtDeDx[i]->SetTrackFilterGolden(trackFilterGolden);
      taskHighPtDeDx[i]->SetTrackFilter(trackFilter0);
      taskHighPtDeDx[i]->SetTrackFilterTPC(trackFilterTPC);

      //V0's cuts
      taskHighPtDeDx[i]->SetMassCut(0.1);         // def: 0.03
      taskHighPtDeDx[i]->SetRequireRecV0(kTRUE); // def: kTRUE
      //taskHighPtDeDx[i]->SetStoreMcIn(kFALSE);     // def: kFALSE
      taskHighPtDeDx[i]->SetStoreMcIn(kTRUE);     // def: kFALSE

      mgr->AddTask(taskHighPtDeDx[i]);

    }

    // Create ONLY the output containers for the data produced by the
    // task.  Get and connect other common input/output containers via
    // the manager as below
    //=======================================================================
    AliAnalysisDataContainer *cout_hist[6];
    for( Int_t i=0; i<6; ++i ){

      cout_hist[i]=0;
      Char_t outFileName[256]={0};
      sprintf(outFileName,"%s_Tree_%1.0f_%1.0f.root",taskname,minc[i],maxc[i]);
      //AliAnalysisDataContainer *cout_hist    = 0;

      cout_hist[i] = mgr->CreateContainer(Form("output_%1.0f_%1.0f",minc[i],maxc[i]), TList::Class(), AliAnalysisManager::kOutputContainer, outFileName);
      mgr->ConnectInput (taskHighPtDeDx[i], 0, mgr->GetCommonInputContainer());
      mgr->ConnectOutput(taskHighPtDeDx[i], 1, cout_hist[i]);

    }

    // Return task pointer at the end
    return taskHighPtDeDx[0];
  }
  if(typerun==3){//pp analysis

    AliAnalysisTaskHighPtDeDx* taskHighPtDeDx = new AliAnalysisTaskHighPtDeDx("taskHighPtDeDxpp");
    TString type = mgr->GetInputEventHandler()->GetDataType(); // can be "ESD" or "AOD"
    taskHighPtDeDx->SetAnalysisType(type);
    taskHighPtDeDx->SetAnalysisMC(AnalysisMC);
    taskHighPtDeDx->SetAnalysisPbPb(kFALSE);
    taskHighPtDeDx->SetProduceVZEROBranch(kTRUE);
    taskHighPtDeDx->SetProduceTPCBranch(kFALSE);
    taskHighPtDeDx->SetDebugLevel(0);
    taskHighPtDeDx->SetEtaCut(0.8);
    taskHighPtDeDx->SetVtxCut(10.0);
    taskHighPtDeDx->SetMinPt(0.0); // default 2.0
    taskHighPtDeDx->SetLowPtFraction(0.01); // keep 1% of tracks below min pt
    taskHighPtDeDx->SetTreeOption(1);
    taskHighPtDeDx->SetTrigger1(kTriggerInt[0]);
    taskHighPtDeDx->SetTrigger2(kTriggerInt[1]);
    //Set Filtesr
    taskHighPtDeDx->SetTrackFilterGolden(trackFilterGolden);
    taskHighPtDeDx->SetTrackFilter(trackFilter0);
    taskHighPtDeDx->SetTrackFilterTPC(trackFilterTPC);
    //V0's cuts
    taskHighPtDeDx->SetMassCut(0.1);         // def: 0.03
    taskHighPtDeDx->SetRequireRecV0(kTRUE); // def: kTRUE
    taskHighPtDeDx->SetStoreMcIn(kFALSE);     // def: kFALSE

    mgr->AddTask(taskHighPtDeDx);

    // Create ONLY the output containers for the data produced by the
    // task.  Get and connect other common input/output containers via
    // the manager as below
    //=======================================================================

    AliAnalysisDataContainer *cout_histdedx;

    cout_histdedx=0;
    Char_t outFileName[256]={0};
    sprintf(outFileName,"%s_Tree.root",taskname);
    //AliAnalysisDataContainer *cout_hist    = 0;

    cout_histdedx = mgr->CreateContainer("outputdedx", TList::Class(), AliAnalysisManager::kOutputContainer, outFileName);
    mgr->ConnectInput (taskHighPtDeDx, 0, mgr->GetCommonInputContainer());
    mgr->ConnectOutput(taskHighPtDeDx, 1, cout_histdedx);

    // Return task pointer at the end
    return taskHighPtDeDx;

  }

 if(typerun==4){//pPb analysis
   cout<<"<<<<<<<<<<<<<<<<<<<<<<<<<<                 Runing pPb    <<<<<<<<<<<<<<"<<endl;

    AliAnalysisTaskHighPtDeDx* taskHighPtDeDx = new AliAnalysisTaskHighPtDeDx("taskHighPtDeDxpp");
    TString type = mgr->GetInputEventHandler()->GetDataType(); // can be "ESD" or "AOD"
    taskHighPtDeDx->SetAnalysisType(type);
    taskHighPtDeDx->SetAnalysisMC(AnalysisMC);
    taskHighPtDeDx->SetAnalysisPbPb(kTRUE);
    taskHighPtDeDx->SetMinCent(-200);
    taskHighPtDeDx->SetMaxCent(200);
    taskHighPtDeDx->SetProduceVZEROBranch(kTRUE);
    taskHighPtDeDx->SetProduceTPCBranch(kFALSE);
    taskHighPtDeDx->SetDebugLevel(0);
    taskHighPtDeDx->SetEtaCut(0.8);
    taskHighPtDeDx->SetVtxCut(10.0);
    taskHighPtDeDx->SetMinPt(0.0); // default 2.0
    taskHighPtDeDx->SetLowPtFraction(0.01); // keep 1% of tracks below min pt
    taskHighPtDeDx->SetTreeOption(1);
    taskHighPtDeDx->SetTrigger1(kTriggerInt[0]);
    taskHighPtDeDx->SetTrigger2(kTriggerInt[1]);
    //Set Filtesr
    taskHighPtDeDx->SetTrackFilterGolden(trackFilterGolden);
    taskHighPtDeDx->SetTrackFilter(trackFilter0);
    taskHighPtDeDx->SetTrackFilterTPC(trackFilterTPC);
    //V0's cuts
    taskHighPtDeDx->SetMassCut(0.1);         // def: 0.03
    taskHighPtDeDx->SetRequireRecV0(kTRUE); // def: kTRUE
    taskHighPtDeDx->SetStoreMcIn(kTRUE);     // def: kFALSE

    mgr->AddTask(taskHighPtDeDx);

    // Create ONLY the output containers for the data produced by the
    // task.  Get and connect other common input/output containers via
    // the manager as below
    //=======================================================================

    AliAnalysisDataContainer *cout_histdedx;

    cout_histdedx=0;
    Char_t outFileName[256]={0};
    sprintf(outFileName,"%s_Tree.root",taskname);
    //AliAnalysisDataContainer *cout_hist    = 0;

    cout_histdedx = mgr->CreateContainer("outputdedx", TList::Class(), AliAnalysisManager::kOutputContainer, outFileName);
    mgr->ConnectInput (taskHighPtDeDx, 0, mgr->GetCommonInputContainer());
    mgr->ConnectOutput(taskHighPtDeDx, 1, cout_histdedx);

    // Return task pointer at the end
    return taskHighPtDeDx;

  }

}
<|endoftext|>


<commit_before>////////////////////////////////////////////////////////////////////////////////
/// @brief general client connection
///
/// @file
///
/// DISCLAIMER
///
/// Copyright 2014 ArangoDB GmbH, Cologne, Germany
/// Copyright 2004-2014 triAGENS GmbH, Cologne, Germany
///
/// 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.
///
/// Copyright holder is ArangoDB GmbH, Cologne, Germany
///
/// @author Jan Steemann
/// @author Copyright 2014, ArangoDB GmbH, Cologne, Germany
/// @author Copyright 2012-2013, triAGENS GmbH, Cologne, Germany
////////////////////////////////////////////////////////////////////////////////

#include "GeneralClientConnection.h"
#include "SimpleHttpClient/ClientConnection.h"
#include "SimpleHttpClient/SslClientConnection.h"

using namespace triagens::basics;
using namespace triagens::rest;
using namespace triagens::httpclient;
using namespace std;

// -----------------------------------------------------------------------------
// --SECTION--                                        constructors / destructors
// -----------------------------------------------------------------------------

////////////////////////////////////////////////////////////////////////////////
/// @brief creates a new client connection
////////////////////////////////////////////////////////////////////////////////

GeneralClientConnection::GeneralClientConnection (Endpoint* endpoint,
                                                  double requestTimeout,
                                                  double connectTimeout,
                                                  size_t connectRetries) :
  _endpoint(endpoint),
  _requestTimeout(requestTimeout),
  _connectTimeout(connectTimeout),
  _connectRetries(connectRetries),
  _numConnectRetries(0),
  _isConnected(false) {

}

////////////////////////////////////////////////////////////////////////////////
/// @brief destroys a client connection
////////////////////////////////////////////////////////////////////////////////

GeneralClientConnection::~GeneralClientConnection () {
}

// -----------------------------------------------------------------------------
// --SECTION--                                                    public methods
// -----------------------------------------------------------------------------

////////////////////////////////////////////////////////////////////////////////
/// @brief create a new connection from an endpoint
////////////////////////////////////////////////////////////////////////////////

GeneralClientConnection* GeneralClientConnection::factory (Endpoint* endpoint,
                                                           double requestTimeout,
                                                           double connectTimeout,
                                                           size_t numRetries,
                                                           uint32_t sslProtocol) {
  if (endpoint->getEncryption() == Endpoint::ENCRYPTION_NONE) {
    return new ClientConnection(endpoint, requestTimeout, connectTimeout, numRetries);
  }
  else if (endpoint->getEncryption() == Endpoint::ENCRYPTION_SSL) {
    return new SslClientConnection(endpoint, requestTimeout, connectTimeout, numRetries, sslProtocol);
  }

  return nullptr;
}

////////////////////////////////////////////////////////////////////////////////
/// @brief connect
////////////////////////////////////////////////////////////////////////////////

bool GeneralClientConnection::connect () {
  disconnect();

  if (_numConnectRetries < _connectRetries + 1) {
    _numConnectRetries++;
  }
  else {
    return false;
  }

  _isConnected = connectSocket();

  if (! _isConnected) {
    return false;
  }

  _numConnectRetries = 0;

  return true;
}

////////////////////////////////////////////////////////////////////////////////
/// @brief disconnect
////////////////////////////////////////////////////////////////////////////////

void GeneralClientConnection::disconnect () {
  if (isConnected()) {
    disconnectSocket();
  }

  _isConnected = false;
  _numConnectRetries = 0;
}

////////////////////////////////////////////////////////////////////////////////
/// @brief handleWrite
/// Write data to endpoint, this uses select to block until some
/// data can be written. Then it writes as much as it can without further
/// blocking, not calling select again. What has happened is
/// indicated by the return value and the bytesWritten variable,
/// which is always set by this method. The bytesWritten indicates
/// how many bytes have been written from the buffer
/// (regardless of whether there was an error or not). The return value
/// indicates, whether an error has happened. Note that the other side
/// closing the connection is not considered to be an error! The call to
/// prepare() does a select and the call to readClientConnection does
/// what is described here.
////////////////////////////////////////////////////////////////////////////////

bool GeneralClientConnection::handleWrite (double timeout, void const* buffer, size_t length, size_t* bytesWritten) {
  TRI_ASSERT(this != nullptr);

  *bytesWritten = 0;

  if (prepare(timeout, true)) {
    return this->writeClientConnection(buffer, length, bytesWritten);
  }

  return false;
}

////////////////////////////////////////////////////////////////////////////////
/// @brief handleRead
/// Read data from endpoint, this uses select to block until some
/// data has arrived. Then it reads as much as it can without further
/// blocking, using select multiple times. What has happened is
/// indicated by two flags, the return value and the connectionClosed flag,
/// which is always set by this method. The connectionClosed flag indicates
/// whether or not the connection has been closed by the other side
/// (regardless of whether there was an error or not). The return value
/// indicates, whether an error has happened. Note that the other side
/// closing the connection is not considered to be an error! The call to
/// prepare() does a select and the call to readClientCollection does
/// what is described here.
////////////////////////////////////////////////////////////////////////////////

bool GeneralClientConnection::handleRead (double timeout, StringBuffer& buffer, bool& connectionClosed) {
  connectionClosed = false;

  if (prepare(timeout, false)) {
    return this->readClientConnection(buffer, connectionClosed);
  }

  connectionClosed = true;
  return false;
}

// -----------------------------------------------------------------------------
// --SECTION--                                                       END-OF-FILE
// -----------------------------------------------------------------------------

// Local Variables:
// mode: outline-minor
// outline-regexp: "/// @brief\\|/// {@inheritDoc}\\|/// @page\\|// --SECTION--\\|/// @\\}"
// End:
<commit_msg>removed assert, because a clang<commit_after>////////////////////////////////////////////////////////////////////////////////
/// @brief general client connection
///
/// @file
///
/// DISCLAIMER
///
/// Copyright 2014 ArangoDB GmbH, Cologne, Germany
/// Copyright 2004-2014 triAGENS GmbH, Cologne, Germany
///
/// 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.
///
/// Copyright holder is ArangoDB GmbH, Cologne, Germany
///
/// @author Jan Steemann
/// @author Copyright 2014, ArangoDB GmbH, Cologne, Germany
/// @author Copyright 2012-2013, triAGENS GmbH, Cologne, Germany
////////////////////////////////////////////////////////////////////////////////

#include "GeneralClientConnection.h"
#include "SimpleHttpClient/ClientConnection.h"
#include "SimpleHttpClient/SslClientConnection.h"

using namespace triagens::basics;
using namespace triagens::rest;
using namespace triagens::httpclient;
using namespace std;

// -----------------------------------------------------------------------------
// --SECTION--                                        constructors / destructors
// -----------------------------------------------------------------------------

////////////////////////////////////////////////////////////////////////////////
/// @brief creates a new client connection
////////////////////////////////////////////////////////////////////////////////

GeneralClientConnection::GeneralClientConnection (Endpoint* endpoint,
                                                  double requestTimeout,
                                                  double connectTimeout,
                                                  size_t connectRetries) :
  _endpoint(endpoint),
  _requestTimeout(requestTimeout),
  _connectTimeout(connectTimeout),
  _connectRetries(connectRetries),
  _numConnectRetries(0),
  _isConnected(false) {

}

////////////////////////////////////////////////////////////////////////////////
/// @brief destroys a client connection
////////////////////////////////////////////////////////////////////////////////

GeneralClientConnection::~GeneralClientConnection () {
}

// -----------------------------------------------------------------------------
// --SECTION--                                                    public methods
// -----------------------------------------------------------------------------

////////////////////////////////////////////////////////////////////////////////
/// @brief create a new connection from an endpoint
////////////////////////////////////////////////////////////////////////////////

GeneralClientConnection* GeneralClientConnection::factory (Endpoint* endpoint,
                                                           double requestTimeout,
                                                           double connectTimeout,
                                                           size_t numRetries,
                                                           uint32_t sslProtocol) {
  if (endpoint->getEncryption() == Endpoint::ENCRYPTION_NONE) {
    return new ClientConnection(endpoint, requestTimeout, connectTimeout, numRetries);
  }
  else if (endpoint->getEncryption() == Endpoint::ENCRYPTION_SSL) {
    return new SslClientConnection(endpoint, requestTimeout, connectTimeout, numRetries, sslProtocol);
  }

  return nullptr;
}

////////////////////////////////////////////////////////////////////////////////
/// @brief connect
////////////////////////////////////////////////////////////////////////////////

bool GeneralClientConnection::connect () {
  disconnect();

  if (_numConnectRetries < _connectRetries + 1) {
    _numConnectRetries++;
  }
  else {
    return false;
  }

  _isConnected = connectSocket();

  if (! _isConnected) {
    return false;
  }

  _numConnectRetries = 0;

  return true;
}

////////////////////////////////////////////////////////////////////////////////
/// @brief disconnect
////////////////////////////////////////////////////////////////////////////////

void GeneralClientConnection::disconnect () {
  if (isConnected()) {
    disconnectSocket();
  }

  _isConnected = false;
  _numConnectRetries = 0;
}

////////////////////////////////////////////////////////////////////////////////
/// @brief handleWrite
/// Write data to endpoint, this uses select to block until some
/// data can be written. Then it writes as much as it can without further
/// blocking, not calling select again. What has happened is
/// indicated by the return value and the bytesWritten variable,
/// which is always set by this method. The bytesWritten indicates
/// how many bytes have been written from the buffer
/// (regardless of whether there was an error or not). The return value
/// indicates, whether an error has happened. Note that the other side
/// closing the connection is not considered to be an error! The call to
/// prepare() does a select and the call to readClientConnection does
/// what is described here.
////////////////////////////////////////////////////////////////////////////////

bool GeneralClientConnection::handleWrite (double timeout, void const* buffer, size_t length, size_t* bytesWritten) {
  *bytesWritten = 0;

  if (prepare(timeout, true)) {
    return this->writeClientConnection(buffer, length, bytesWritten);
  }

  return false;
}

////////////////////////////////////////////////////////////////////////////////
/// @brief handleRead
/// Read data from endpoint, this uses select to block until some
/// data has arrived. Then it reads as much as it can without further
/// blocking, using select multiple times. What has happened is
/// indicated by two flags, the return value and the connectionClosed flag,
/// which is always set by this method. The connectionClosed flag indicates
/// whether or not the connection has been closed by the other side
/// (regardless of whether there was an error or not). The return value
/// indicates, whether an error has happened. Note that the other side
/// closing the connection is not considered to be an error! The call to
/// prepare() does a select and the call to readClientCollection does
/// what is described here.
////////////////////////////////////////////////////////////////////////////////

bool GeneralClientConnection::handleRead (double timeout, StringBuffer& buffer, bool& connectionClosed) {
  connectionClosed = false;

  if (prepare(timeout, false)) {
    return this->readClientConnection(buffer, connectionClosed);
  }

  connectionClosed = true;
  return false;
}

// -----------------------------------------------------------------------------
// --SECTION--                                                       END-OF-FILE
// -----------------------------------------------------------------------------

// Local Variables:
// mode: outline-minor
// outline-regexp: "/// @brief\\|/// {@inheritDoc}\\|/// @page\\|// --SECTION--\\|/// @\\}"
// End:
<|endoftext|>


<commit_before>// Copyright 2012 Intel Corporation
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// - Redistributions of source code must retain the above copyright notice, this
//   list of conditions and the following disclaimer.
//
// - Redistributions in binary form must reproduce the above copyright notice,
//   this list of conditions and the following disclaimer in the documentation
//   and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

#if WAFFLE_ANDROID_MAJOR_VERSION >= 4 && \
	WAFFLE_ANDROID_MINOR_VERSION >= 1
#	include <gui/SurfaceComposerClient.h>
#elif WAFFLE_ANROID_MAJOR_VERSION >= 4 && \
	  WAFFLE_ANDROID_MINOR_VERSION == 0
#	include <surfaceflinger/SurfaceComposerClient.h>
#else
#	error "android >= 4.0 is required"
#endif

#include "droid_surfaceflingerlink.h"

extern "C" {
#include "wcore_util.h"
#include "wcore_error.h"
};

using namespace android;

namespace waffle {

struct droid_surfaceflinger_container {
    sp<SurfaceComposerClient> composer_client;
};

struct droid_ANativeWindow_container {
    // it is important ANativeWindow* is the first element in this structure
    ANativeWindow* native_window;
    sp<SurfaceControl> surface_control;
    sp<ANativeWindow> window;
};

const uint32_t droid_magic_surface_width = 32;
const uint32_t droid_magic_surface_height = 32;
const int32_t  droid_magic_surface_z = 0x7FFFFFFF;

void droid_tear_down_surfaceflinger_link(
    droid_surfaceflinger_container* pSFContainer);

droid_surfaceflinger_container*
droid_setup_surfaceflinger_link()
{
    bool bRVal;
    EGLint iRVal;
    droid_surfaceflinger_container* pSFContainer;

    pSFContainer = reinterpret_cast <droid_surfaceflinger_container*>(
       wcore_malloc( size_t(sizeof(droid_surfaceflinger_container))));

    if (pSFContainer == NULL)
        goto error;

    pSFContainer->composer_client = new SurfaceComposerClient;
    iRVal = pSFContainer->composer_client->initCheck();
    if (iRVal != NO_ERROR) {
        wcore_errorf(WAFFLE_ERROR_UNKNOWN,
                     "android::SurfaceComposerClient->initCheck != NO_ERROR");
        goto error;
    }

    return pSFContainer;
error:
    droid_tear_down_surfaceflinger_link(pSFContainer);
    return NULL;
}

droid_ANativeWindow_container*
droid_setup_surface(
    int width,
    int height,
    droid_surfaceflinger_container* pSFContainer)
{
    bool bRVal;
    EGLint iRVal;

    droid_ANativeWindow_container* pANWContainer;

    pANWContainer = reinterpret_cast <droid_ANativeWindow_container*>(
       wcore_malloc( size_t(sizeof(droid_ANativeWindow_container))));

    if (pANWContainer == NULL)
        goto error;

    pANWContainer->surface_control =
            pSFContainer->composer_client->createSurface(
            String8("Waffle Surface"),
            droid_magic_surface_width, droid_magic_surface_height,
            PIXEL_FORMAT_RGB_888, 0);

    if (pANWContainer->surface_control == NULL) {
        wcore_errorf(WAFFLE_ERROR_UNKNOWN,
                     "Unable to get android::SurfaceControl");
        free(static_cast <void*>(pANWContainer));
        goto error;
    }

    bRVal = pANWContainer->surface_control->isValid();
    if (bRVal != true) {
        wcore_errorf(WAFFLE_ERROR_UNKNOWN,
                     "Acquired android::SurfaceControl is invalid");
        free(static_cast <void*>(pANWContainer));
        goto error;
    }

    pSFContainer->composer_client->openGlobalTransaction();
    iRVal = pANWContainer->surface_control->setLayer(droid_magic_surface_z);
    if (iRVal != NO_ERROR) {
        wcore_errorf(WAFFLE_ERROR_UNKNOWN,
                     "Error in android::SurfaceControl->setLayer");
        free(static_cast <void*>(pANWContainer));
        goto error_closeTransaction;
    }

    pSFContainer->composer_client->closeGlobalTransaction();

    pANWContainer->window = pANWContainer->surface_control->getSurface();

    pSFContainer->composer_client->openGlobalTransaction();
    iRVal = pANWContainer->surface_control->setSize(width, height);
    pSFContainer->composer_client->closeGlobalTransaction();

    if (iRVal != NO_ERROR) {
        wcore_errorf(WAFFLE_ERROR_UNKNOWN,
                     "error in android::SurfaceControl->setSize");
        free(static_cast <void*>(pANWContainer));
        goto error;
    }

    pANWContainer->native_window = pANWContainer->window.get();

    return pANWContainer;

error_closeTransaction:
    pSFContainer->composer_client->closeGlobalTransaction();

error:
    droid_tear_down_surfaceflinger_link(pSFContainer);
    return NULL;
}

bool
droid_show_surface(
    droid_surfaceflinger_container* pSFContainer,
    droid_ANativeWindow_container* pANWContainer)
{
    int iRVal;

    pSFContainer->composer_client->openGlobalTransaction();
    iRVal = pANWContainer->surface_control->show();
    pSFContainer->composer_client->closeGlobalTransaction();

    if (iRVal != NO_ERROR) {
        wcore_errorf(WAFFLE_ERROR_UNKNOWN,
                     "Error in android::SurfaceControl->show");
        return false;
    }
    return true;
}

void
droid_destroy_surface(
    droid_surfaceflinger_container* pSFContainer,
    droid_ANativeWindow_container* pANWContainer)
{
    pSFContainer->composer_client->openGlobalTransaction();
    pANWContainer->surface_control->clear();
    pSFContainer->composer_client->closeGlobalTransaction();
    free(static_cast <void*>(pANWContainer));
}

void
droid_tear_down_surfaceflinger_link(
                waffle::droid_surfaceflinger_container* pSFContainer)
{
    if( pSFContainer == NULL)
        return;

    if (pSFContainer->composer_client != NULL) {
        pSFContainer->composer_client->dispose();
        pSFContainer->composer_client = NULL;
    }

    free(static_cast<void*>(pSFContainer));
}

}; // namespace waffle

extern "C" struct droid_surfaceflinger_container*
droid_init_gl()
{
    return reinterpret_cast<droid_surfaceflinger_container*>(
                waffle::droid_setup_surfaceflinger_link());
}
extern "C" bool
droid_deinit_gl(droid_surfaceflinger_container* pSFContainer)
{
    waffle::droid_tear_down_surfaceflinger_link(
                reinterpret_cast<waffle::droid_surfaceflinger_container*>
                (pSFContainer));
    return true;
}

extern "C" droid_ANativeWindow_container*
droid_create_surface(
    int width,
    int height,
    droid_surfaceflinger_container* pSFContainer)
{
    waffle::droid_ANativeWindow_container* container =
        waffle::droid_setup_surface(
            width, height,
            reinterpret_cast<waffle::droid_surfaceflinger_container*> (pSFContainer));
    return reinterpret_cast<droid_ANativeWindow_container*>(container);
}

extern "C" bool
droid_show_surface(
    droid_surfaceflinger_container* pSFContainer,
    droid_ANativeWindow_container* pANWContainer)
{
    return waffle::droid_show_surface(
            reinterpret_cast<waffle::droid_surfaceflinger_container*>
            (pSFContainer),
            reinterpret_cast<waffle::droid_ANativeWindow_container*>
            (pANWContainer));
}

extern "C" void
droid_destroy_surface(
    droid_surfaceflinger_container* pSFContainer,
    droid_ANativeWindow_container* pANWContainer)
{
    return waffle::droid_destroy_surface(
            reinterpret_cast<waffle::droid_surfaceflinger_container*>
            (pSFContainer),
            reinterpret_cast<waffle::droid_ANativeWindow_container*>
            (pANWContainer));
}
<commit_msg>Android: Fix surface setup segfault<commit_after>// Copyright 2012 Intel Corporation
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// - Redistributions of source code must retain the above copyright notice, this
//   list of conditions and the following disclaimer.
//
// - Redistributions in binary form must reproduce the above copyright notice,
//   this list of conditions and the following disclaimer in the documentation
//   and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

#if WAFFLE_ANDROID_MAJOR_VERSION >= 4 && \
	WAFFLE_ANDROID_MINOR_VERSION >= 1
#	include <gui/SurfaceComposerClient.h>
#elif WAFFLE_ANROID_MAJOR_VERSION >= 4 && \
	  WAFFLE_ANDROID_MINOR_VERSION == 0
#	include <surfaceflinger/SurfaceComposerClient.h>
#else
#	error "android >= 4.0 is required"
#endif

#include "droid_surfaceflingerlink.h"

extern "C" {
#include "wcore_util.h"
#include "wcore_error.h"
};

using namespace android;

namespace waffle {

struct droid_surfaceflinger_container {
    sp<SurfaceComposerClient> composer_client;
};

struct droid_ANativeWindow_container {
    // it is important ANativeWindow* is the first element in this structure
    ANativeWindow* native_window;
    sp<SurfaceControl> surface_control;
    sp<ANativeWindow> window;
};

const uint32_t droid_magic_surface_width = 32;
const uint32_t droid_magic_surface_height = 32;
const int32_t  droid_magic_surface_z = 0x7FFFFFFF;

void droid_tear_down_surfaceflinger_link(
    droid_surfaceflinger_container* pSFContainer);

droid_surfaceflinger_container*
droid_setup_surfaceflinger_link()
{
    bool bRVal;
    EGLint iRVal;
    droid_surfaceflinger_container* pSFContainer;

    pSFContainer = new droid_surfaceflinger_container;

    if (pSFContainer == NULL)
        goto error;

    pSFContainer->composer_client = new SurfaceComposerClient;
    iRVal = pSFContainer->composer_client->initCheck();
    if (iRVal != NO_ERROR) {
        wcore_errorf(WAFFLE_ERROR_UNKNOWN,
                     "android::SurfaceComposerClient->initCheck != NO_ERROR");
        goto error;
    }

    return pSFContainer;
error:
    droid_tear_down_surfaceflinger_link(pSFContainer);
    return NULL;
}

droid_ANativeWindow_container*
droid_setup_surface(
    int width,
    int height,
    droid_surfaceflinger_container* pSFContainer)
{
    bool bRVal;
    EGLint iRVal;

    droid_ANativeWindow_container* pANWContainer;

    pANWContainer = new droid_ANativeWindow_container;

    if (pANWContainer == NULL)
        goto error;

    pANWContainer->surface_control =
            pSFContainer->composer_client->createSurface(
            String8("Waffle Surface"),
            droid_magic_surface_width, droid_magic_surface_height,
            PIXEL_FORMAT_RGB_888, 0);

    if (pANWContainer->surface_control == NULL) {
        wcore_errorf(WAFFLE_ERROR_UNKNOWN,
                     "Unable to get android::SurfaceControl");
        delete pANWContainer;
        goto error;
    }

    bRVal = pANWContainer->surface_control->isValid();
    if (bRVal != true) {
        wcore_errorf(WAFFLE_ERROR_UNKNOWN,
                     "Acquired android::SurfaceControl is invalid");
        delete pANWContainer;
        goto error;
    }

    pSFContainer->composer_client->openGlobalTransaction();
    iRVal = pANWContainer->surface_control->setLayer(droid_magic_surface_z);
    if (iRVal != NO_ERROR) {
        wcore_errorf(WAFFLE_ERROR_UNKNOWN,
                     "Error in android::SurfaceControl->setLayer");
        delete pANWContainer;
        goto error_closeTransaction;
    }

    pSFContainer->composer_client->closeGlobalTransaction();

    pANWContainer->window = pANWContainer->surface_control->getSurface();

    pSFContainer->composer_client->openGlobalTransaction();
    iRVal = pANWContainer->surface_control->setSize(width, height);
    pSFContainer->composer_client->closeGlobalTransaction();

    if (iRVal != NO_ERROR) {
        wcore_errorf(WAFFLE_ERROR_UNKNOWN,
                     "error in android::SurfaceControl->setSize");
        delete pANWContainer;
        goto error;
    }

    pANWContainer->native_window = pANWContainer->window.get();

    return pANWContainer;

error_closeTransaction:
    pSFContainer->composer_client->closeGlobalTransaction();

error:
    droid_tear_down_surfaceflinger_link(pSFContainer);
    return NULL;
}

bool
droid_show_surface(
    droid_surfaceflinger_container* pSFContainer,
    droid_ANativeWindow_container* pANWContainer)
{
    int iRVal;

    pSFContainer->composer_client->openGlobalTransaction();
    iRVal = pANWContainer->surface_control->show();
    pSFContainer->composer_client->closeGlobalTransaction();

    if (iRVal != NO_ERROR) {
        wcore_errorf(WAFFLE_ERROR_UNKNOWN,
                     "Error in android::SurfaceControl->show");
        return false;
    }
    return true;
}

void
droid_destroy_surface(
    droid_surfaceflinger_container* pSFContainer,
    droid_ANativeWindow_container* pANWContainer)
{
    pSFContainer->composer_client->openGlobalTransaction();
    pANWContainer->surface_control->clear();
    pSFContainer->composer_client->closeGlobalTransaction();
    delete pANWContainer;
}

void
droid_tear_down_surfaceflinger_link(
                waffle::droid_surfaceflinger_container* pSFContainer)
{
    if( pSFContainer == NULL)
        return;

    if (pSFContainer->composer_client != NULL) {
        pSFContainer->composer_client->dispose();
        pSFContainer->composer_client = NULL;
    }

    delete pSFContainer;
}

}; // namespace waffle

extern "C" struct droid_surfaceflinger_container*
droid_init_gl()
{
    return reinterpret_cast<droid_surfaceflinger_container*>(
                waffle::droid_setup_surfaceflinger_link());
}
extern "C" bool
droid_deinit_gl(droid_surfaceflinger_container* pSFContainer)
{
    waffle::droid_tear_down_surfaceflinger_link(
                reinterpret_cast<waffle::droid_surfaceflinger_container*>
                (pSFContainer));
    return true;
}

extern "C" droid_ANativeWindow_container*
droid_create_surface(
    int width,
    int height,
    droid_surfaceflinger_container* pSFContainer)
{
    waffle::droid_ANativeWindow_container* container =
        waffle::droid_setup_surface(
            width, height,
            reinterpret_cast<waffle::droid_surfaceflinger_container*> (pSFContainer));
    return reinterpret_cast<droid_ANativeWindow_container*>(container);
}

extern "C" bool
droid_show_surface(
    droid_surfaceflinger_container* pSFContainer,
    droid_ANativeWindow_container* pANWContainer)
{
    return waffle::droid_show_surface(
            reinterpret_cast<waffle::droid_surfaceflinger_container*>
            (pSFContainer),
            reinterpret_cast<waffle::droid_ANativeWindow_container*>
            (pANWContainer));
}

extern "C" void
droid_destroy_surface(
    droid_surfaceflinger_container* pSFContainer,
    droid_ANativeWindow_container* pANWContainer)
{
    return waffle::droid_destroy_surface(
            reinterpret_cast<waffle::droid_surfaceflinger_container*>
            (pSFContainer),
            reinterpret_cast<waffle::droid_ANativeWindow_container*>
            (pANWContainer));
}
<|endoftext|>