1
0
Fork 0

Merge branch 'devel' of https://github.com/arangodb/arangodb into devel

This commit is contained in:
jsteemann 2016-04-27 19:08:53 +02:00
commit a3fdda19af
8 changed files with 55 additions and 18 deletions

View File

@ -212,9 +212,9 @@ if(UNIX)
# On unix-like platforms the library is almost always called libz # On unix-like platforms the library is almost always called libz
#set_target_properties(zlib zlibstatic PROPERTIES OUTPUT_NAME z) #set_target_properties(zlib zlibstatic PROPERTIES OUTPUT_NAME z)
set_target_properties(zlibstatic PROPERTIES OUTPUT_NAME z) set_target_properties(zlibstatic PROPERTIES OUTPUT_NAME z)
if(NOT APPLE AND NOT SOLARIS) # if(NOT APPLE AND NOT SOLARIS)
set_target_properties(zlib PROPERTIES LINK_FLAGS "-Wl,--version-script,\"${CMAKE_CURRENT_SOURCE_DIR}/zlib.map\"") # set_target_properties(zlib PROPERTIES LINK_FLAGS "-Wl,--version-script,\"${CMAKE_CURRENT_SOURCE_DIR}/zlib.map\"")
endif() # endif()
elseif(BUILD_SHARED_LIBS AND WIN32) elseif(BUILD_SHARED_LIBS AND WIN32)
# Creates zlib1.dll when building shared library version # Creates zlib1.dll when building shared library version
set_target_properties(zlib PROPERTIES SUFFIX "1.dll") set_target_properties(zlib PROPERTIES SUFFIX "1.dll")

View File

@ -35,10 +35,7 @@ using namespace arangodb::options;
ApplicationServer* ApplicationServer::server = nullptr; ApplicationServer* ApplicationServer::server = nullptr;
ApplicationServer::ApplicationServer(std::shared_ptr<ProgramOptions> options) ApplicationServer::ApplicationServer(std::shared_ptr<ProgramOptions> options)
: _options(options), : _options(options), _stopping(false) {
_stopping(false),
_privilegesDropped(false),
_dumpDependencies(false) {
if (ApplicationServer::server != nullptr) { if (ApplicationServer::server != nullptr) {
LOG(ERR) << "ApplicationServer initialized twice"; LOG(ERR) << "ApplicationServer initialized twice";
} }
@ -155,6 +152,7 @@ void ApplicationServer::run(int argc, char* argv[]) {
// collect options from all features // collect options from all features
// in this phase, all features are order-independent // in this phase, all features are order-independent
_state = ServerState::IN_COLLECT_OPTIONS;
collectOptions(); collectOptions();
// setup dependency, but ignore any failure for now // setup dependency, but ignore any failure for now
@ -168,6 +166,7 @@ void ApplicationServer::run(int argc, char* argv[]) {
_options->seal(); _options->seal();
// validate options of all features // validate options of all features
_state = ServerState::IN_VALIDATE_OPTIONS;
validateOptions(); validateOptions();
// enable automatic features // enable automatic features
@ -184,6 +183,7 @@ void ApplicationServer::run(int argc, char* argv[]) {
// furthermore, they must not write any files under elevated privileges // furthermore, they must not write any files under elevated privileges
// if they want other features to access them, or if they want to access // if they want other features to access them, or if they want to access
// these files with dropped privileges // these files with dropped privileges
_state = ServerState::IN_PREPARE;
prepare(); prepare();
// permanently drop the privileges // permanently drop the privileges
@ -193,13 +193,18 @@ void ApplicationServer::run(int argc, char* argv[]) {
Thread::allowThreadCreation(); Thread::allowThreadCreation();
// start features. now features are allowed to start threads, write files etc. // start features. now features are allowed to start threads, write files etc.
_state = ServerState::IN_START;
start(); start();
// wait until we get signaled the shutdown request // wait until we get signaled the shutdown request
wait(); wait();
// stop all features // stop all features
_state = ServerState::IN_STOP;
stop(); stop();
// stopped
_state = ServerState::STOPPED;
} }
// signal the server to shut down // signal the server to shut down

View File

@ -91,10 +91,15 @@ class ApplicationServer {
ApplicationServer& operator=(ApplicationServer const&) = delete; ApplicationServer& operator=(ApplicationServer const&) = delete;
public: public:
static ApplicationServer* server; enum class ServerState {
static bool isStopping() { UNINITIALIZED,
return server != nullptr && server->_stopping.load(); IN_COLLECT_OPTIONS,
} IN_VALIDATE_OPTIONS,
IN_PREPARE,
IN_START,
IN_STOP,
STOPPED
};
enum class FeatureState { enum class FeatureState {
UNINITIALIZED, UNINITIALIZED,
@ -105,6 +110,15 @@ class ApplicationServer {
STOPPED STOPPED
}; };
static ApplicationServer* server;
static bool isStopping() {
return server != nullptr && server->_stopping.load();
}
static bool isPrepared() {
return server != nullptr && (server->_state == ServerState::IN_START ||
server->_state == ServerState::IN_STOP);
}
// returns the feature with the given name if known // returns the feature with the given name if known
// throws otherwise // throws otherwise
template <typename T> template <typename T>
@ -172,6 +186,9 @@ class ApplicationServer {
// return VPack options // return VPack options
VPackBuilder options(std::unordered_set<std::string> const& excludes) const; VPackBuilder options(std::unordered_set<std::string> const& excludes) const;
// return the server state
ServerState state() const { return _state; }
private: private:
// look up a feature and return a pointer to it. may be nullptr // look up a feature and return a pointer to it. may be nullptr
static ApplicationFeature* lookupFeature(std::string const&); static ApplicationFeature* lookupFeature(std::string const&);
@ -228,6 +245,9 @@ class ApplicationServer {
void dropPrivilegesPermanently(); void dropPrivilegesPermanently();
private: private:
// the current state
ServerState _state = ServerState::UNINITIALIZED;
// the shared program options // the shared program options
std::shared_ptr<options::ProgramOptions> _options; std::shared_ptr<options::ProgramOptions> _options;
@ -241,10 +261,10 @@ class ApplicationServer {
std::atomic<bool> _stopping; std::atomic<bool> _stopping;
// whether or not privileges have been dropped permanently // whether or not privileges have been dropped permanently
bool _privilegesDropped; bool _privilegesDropped = false;
// whether or not to dump dependencies // whether or not to dump dependencies
bool _dumpDependencies; bool _dumpDependencies = false;
}; };
} }
} }

View File

@ -27,6 +27,7 @@
#include <errno.h> #include <errno.h>
#include <signal.h> #include <signal.h>
#include "ApplicationFeatures/ApplicationServer.h"
#include "Basics/ConditionLocker.h" #include "Basics/ConditionLocker.h"
#include "Basics/Exceptions.h" #include "Basics/Exceptions.h"
#include "Logger/Logger.h" #include "Logger/Logger.h"
@ -36,6 +37,7 @@
#include <velocypack/velocypack-aliases.h> #include <velocypack/velocypack-aliases.h>
using namespace arangodb; using namespace arangodb;
using namespace arangodb::application_features;
using namespace arangodb::basics; using namespace arangodb::basics;
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
@ -282,6 +284,15 @@ bool Thread::isStopping() const {
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
bool Thread::start(ConditionVariable* finishedCondition) { bool Thread::start(ConditionVariable* finishedCondition) {
if (!isSystem() && ! ApplicationServer::isPrepared()) {
LOG(FATAL) << "trying to start a thread '" << _name
<< "' before prepare has finished, current state: "
<< (ApplicationServer::server == nullptr
? -1
: (int)ApplicationServer::server->state());
FATAL_ERROR_EXIT();
}
_finishedCondition = finishedCondition; _finishedCondition = finishedCondition;
if (_state.load() != ThreadState::CREATED) { if (_state.load() != ThreadState::CREATED) {

View File

@ -148,6 +148,9 @@ class Thread {
virtual ~Thread(); virtual ~Thread();
public: public:
// whether or not the thread is allowed to start during prepare
virtual bool isSystem() { return false; }
////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////
/// @brief whether or not the thread is chatty on shutdown /// @brief whether or not the thread is chatty on shutdown
////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////

View File

@ -41,6 +41,7 @@ class LogThread : public Thread {
~LogThread(); ~LogThread();
public: public:
bool isSystem() override { return true; }
bool isSilent() override { return true; } bool isSilent() override { return true; }
void run() override; void run() override;

View File

@ -91,7 +91,8 @@ void LoggerFeature::collectOptions(std::shared_ptr<ProgramOptions> options) {
"append line number and file name", "append line number and file name",
new BooleanParameter(&_lineNumber)); new BooleanParameter(&_lineNumber));
options->addHiddenOption("--log.thread", "show thread identifier in log message", options->addHiddenOption("--log.thread",
"show thread identifier in log message",
new BooleanParameter(&_thread)); new BooleanParameter(&_thread));
options->addHiddenOption("--log.performance", options->addHiddenOption("--log.performance",
@ -170,9 +171,6 @@ void LoggerFeature::prepare() {
} }
} }
void LoggerFeature::start() {
}
void LoggerFeature::stop() { void LoggerFeature::stop() {
Logger::flush(); Logger::flush();
Logger::shutdown(true); Logger::shutdown(true);

View File

@ -35,7 +35,6 @@ class LoggerFeature final : public application_features::ApplicationFeature {
void loadOptions(std::shared_ptr<options::ProgramOptions>) override final; void loadOptions(std::shared_ptr<options::ProgramOptions>) override final;
void validateOptions(std::shared_ptr<options::ProgramOptions>) override final; void validateOptions(std::shared_ptr<options::ProgramOptions>) override final;
void prepare() override final; void prepare() override final;
void start() override final;
void stop() override final; void stop() override final;
public: public: