//////////////////////////////////////////////////////////////////////////////// /// DISCLAIMER /// /// Copyright 2014-2016 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 Dr. Frank Celler //////////////////////////////////////////////////////////////////////////////// #ifndef ARANGODB_UTILS_WORK_MONITOR #define ARANGODB_UTILS_WORK_MONITOR 1 #include "Basics/Thread.h" #include "Basics/WorkItem.h" namespace triagens { namespace rest { class HttpHandler; } } namespace arangodb { namespace velocypack { class Builder; } //////////////////////////////////////////////////////////////////////////////// /// @brief type of the current work //////////////////////////////////////////////////////////////////////////////// enum class WorkType { THREAD, HANDLER, CUSTOM }; //////////////////////////////////////////////////////////////////////////////// /// @brief description of the current work //////////////////////////////////////////////////////////////////////////////// struct WorkDescription { WorkDescription(WorkType, WorkDescription*); WorkType _type; bool _destroy; char _customType[16]; union data { data() {} ~data() {} char text[256]; triagens::basics::Thread* thread; triagens::rest::HttpHandler* handler; } _data; WorkDescription* _prev; }; //////////////////////////////////////////////////////////////////////////////// /// @brief work monitor class //////////////////////////////////////////////////////////////////////////////// class WorkMonitor : public triagens::basics::Thread { public: //////////////////////////////////////////////////////////////////////////////// /// @brief constructors a new monitor //////////////////////////////////////////////////////////////////////////////// WorkMonitor(); public: //////////////////////////////////////////////////////////////////////////////// /// @brief creates an empty WorkDescription //////////////////////////////////////////////////////////////////////////////// static WorkDescription* createWorkDescription(WorkType); //////////////////////////////////////////////////////////////////////////////// /// @brief activates a WorkDescription //////////////////////////////////////////////////////////////////////////////// static void activateWorkDescription(WorkDescription*); //////////////////////////////////////////////////////////////////////////////// /// @brief deactivates a WorkDescription //////////////////////////////////////////////////////////////////////////////// static WorkDescription* deactivateWorkDescription(); //////////////////////////////////////////////////////////////////////////////// /// @brief frees an WorkDescription //////////////////////////////////////////////////////////////////////////////// static void freeWorkDescription(WorkDescription* desc); //////////////////////////////////////////////////////////////////////////////// /// @brief pushes a threads //////////////////////////////////////////////////////////////////////////////// static void pushThread(triagens::basics::Thread* thread); //////////////////////////////////////////////////////////////////////////////// /// @brief pops a threads //////////////////////////////////////////////////////////////////////////////// static void popThread(triagens::basics::Thread* thread); //////////////////////////////////////////////////////////////////////////////// /// @brief pushes a custom task //////////////////////////////////////////////////////////////////////////////// static void pushCustom(const char* type, const char* text, size_t length); static void pushCustom(const char* type, uint64_t id); //////////////////////////////////////////////////////////////////////////////// /// @brief pops a custom task //////////////////////////////////////////////////////////////////////////////// static void popCustom(); //////////////////////////////////////////////////////////////////////////////// /// @brief pushes a handler //////////////////////////////////////////////////////////////////////////////// static void pushHandler(triagens::rest::HttpHandler*); //////////////////////////////////////////////////////////////////////////////// /// @brief pops and releases a handler //////////////////////////////////////////////////////////////////////////////// static WorkDescription* popHandler(triagens::rest::HttpHandler*, bool free); //////////////////////////////////////////////////////////////////////////////// /// @brief handler deleter //////////////////////////////////////////////////////////////////////////////// static void DELETE_HANDLER(WorkDescription* desc); //////////////////////////////////////////////////////////////////////////////// /// @brief handler description string //////////////////////////////////////////////////////////////////////////////// static void VPACK_HANDLER(arangodb::velocypack::Builder*, WorkDescription* desc); protected: //////////////////////////////////////////////////////////////////////////////// /// {@inheritDoc} //////////////////////////////////////////////////////////////////////////////// void run() override; public: //////////////////////////////////////////////////////////////////////////////// /// @brief initiate shutdown //////////////////////////////////////////////////////////////////////////////// void shutdown() { _stopping = true; } //////////////////////////////////////////////////////////////////////////////// /// @brief stopping flag //////////////////////////////////////////////////////////////////////////////// std::atomic _stopping; }; //////////////////////////////////////////////////////////////////////////////// /// @brief auto push and pop for HttpHandler //////////////////////////////////////////////////////////////////////////////// class HandlerWorkStack { HandlerWorkStack(const HandlerWorkStack&) = delete; HandlerWorkStack& operator=(const HandlerWorkStack&) = delete; public: //////////////////////////////////////////////////////////////////////////////// /// @brief constructor //////////////////////////////////////////////////////////////////////////////// explicit HandlerWorkStack(triagens::rest::HttpHandler*); //////////////////////////////////////////////////////////////////////////////// /// @brief constructor //////////////////////////////////////////////////////////////////////////////// explicit HandlerWorkStack(WorkItem::uptr&); //////////////////////////////////////////////////////////////////////////////// /// @brief destructor //////////////////////////////////////////////////////////////////////////////// ~HandlerWorkStack(); public: //////////////////////////////////////////////////////////////////////////////// /// @brief returns the handler //////////////////////////////////////////////////////////////////////////////// triagens::rest::HttpHandler* handler() const { return _handler; } private: //////////////////////////////////////////////////////////////////////////////// /// @brief handler //////////////////////////////////////////////////////////////////////////////// triagens::rest::HttpHandler* _handler; }; //////////////////////////////////////////////////////////////////////////////// /// @brief auto push and pop for HttpHandler //////////////////////////////////////////////////////////////////////////////// class CustomWorkStack { CustomWorkStack(const CustomWorkStack&) = delete; CustomWorkStack& operator=(const CustomWorkStack&) = delete; public: //////////////////////////////////////////////////////////////////////////////// /// @brief constructor //////////////////////////////////////////////////////////////////////////////// CustomWorkStack(const char* type, const char* text, size_t length); CustomWorkStack(const char* type, uint64_t id); //////////////////////////////////////////////////////////////////////////////// /// @brief destructor //////////////////////////////////////////////////////////////////////////////// ~CustomWorkStack(); }; //////////////////////////////////////////////////////////////////////////////// /// @brief starts the work monitor //////////////////////////////////////////////////////////////////////////////// void InitializeWorkMonitor(); //////////////////////////////////////////////////////////////////////////////// /// @brief stops the work monitor //////////////////////////////////////////////////////////////////////////////// void ShutdownWorkMonitor(); } #endif