1
0
Fork 0

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

This commit is contained in:
Heiko Kernbach 2013-02-15 12:32:27 +01:00
commit c0e930292b
43 changed files with 433 additions and 522 deletions

View File

@ -1,6 +1,10 @@
v1.2.alpha (XXXX-XX-XX)
-----------------------
* fixed issue #405: 1.2 compile warnings
* fixed issue #333: [debian] Group "arangodb" is not used when starting vie init.d script
* added optional parameter 'excludeSystem' to GET /_api/collection
This parameter can be used to disable returning system collections in the list
of all collections.

View File

@ -29,7 +29,7 @@ start() {
ARANGO_PIDDIR=`dirname $pidfile`
test -d $ARANGO_PIDDIR || (mkdir $ARANGO_PIDDIR && chown arangodb $ARANGO_PIDDIR)
$ARANGO_BIN -c $ARANGO_SYSCONFIG --pid-file "$pidfile" --supervisor --uid arangodb $@
$ARANGO_BIN -c $ARANGO_SYSCONFIG --pid-file "$pidfile" --supervisor --uid arangodb --gid arangodb $@
RETVAL=$?
echo

View File

@ -33,7 +33,7 @@ start () {
ARANGO_PIDDIR=`dirname $PIDFILE`
test -d $ARANGO_PIDDIR || (mkdir $ARANGO_PIDDIR && chown arangodb $ARANGO_PIDDIR)
$DAEMON -c $CONF --pid-file "$PIDFILE" --supervisor --uid arangodb $@
$DAEMON -c $CONF --pid-file "$PIDFILE" --supervisor --uid arangodb --gid arangodb $@
log_end_msg $?
}

View File

@ -47,7 +47,7 @@ start () {
ARANGO_PIDDIR=`dirname $ARANGO_PIDFILE`
test -d $ARANGO_PIDDIR || (mkdir $ARANGO_PIDDIR && chown arangodb $ARANGO_PIDDIR)
startproc $ARANGO_BIN -c $ARANGO_SYSCONFIG --pid-file "$ARANGO_PIDFILE" --supervisor --uid arangodb $@
startproc $ARANGO_BIN -c $ARANGO_SYSCONFIG --pid-file "$ARANGO_PIDFILE" --supervisor --uid arangodb --gid arangodb $@
# Remember status and be verbose
rc_status -v

View File

@ -27,7 +27,7 @@ start () {
test -d $PIDDIR || mkdir $PIDDIR
chown arangodb $PIDDIR
$DAEMON -c $CONF --pid-file "$PIDFILE" --supervisor --uid arangodb $@
$DAEMON -c $CONF --pid-file "$PIDFILE" --supervisor --uid arangodb --gid arangodb $@
log_end_msg $?
}

View File

@ -183,11 +183,11 @@ ApplicationMR::MRContext* ApplicationMR::enterContext () {
CONDITION_LOCKER(guard, _contextCondition);
while (_freeContexts.empty()) {
LOGGER_DEBUG << "waiting for unused MRuby context";
LOGGER_DEBUG("waiting for unused MRuby context");
guard.wait();
}
LOGGER_TRACE << "found unused MRuby context";
LOGGER_TRACE("found unused MRuby context");
MRContext* context = _freeContexts.back();
_freeContexts.pop_back();
@ -210,11 +210,11 @@ void ApplicationMR::exitContext (MRContext* context) {
CONDITION_LOCKER(guard, _contextCondition);
if (context->_lastGcStamp + _gcFrequency < lastGc) {
LOGGER_TRACE << "periodic gc interval reached";
LOGGER_TRACE("periodic gc interval reached");
_dirtyContexts.push_back(context);
}
else if (context->_dirt >= _gcInterval) {
LOGGER_TRACE << "maximum number of requests reached";
LOGGER_TRACE("maximum number of requests reached");
_dirtyContexts.push_back(context);
}
else {
@ -224,7 +224,7 @@ void ApplicationMR::exitContext (MRContext* context) {
guard.broadcast();
}
LOGGER_TRACE << "returned dirty MR context";
LOGGER_TRACE("returned dirty MR context");
}
////////////////////////////////////////////////////////////////////////////////
@ -270,7 +270,7 @@ void ApplicationMR::collectGarbage () {
gc->updateGcStamp(lastGc);
if (context != 0) {
LOGGER_TRACE << "collecting MR garbage";
LOGGER_TRACE("collecting MR garbage");
mrb_garbage_collect(context->_mrb);
@ -333,35 +333,31 @@ bool ApplicationMR::prepare () {
// check the startup modules
if (_startupModules.empty()) {
LOGGER_FATAL << "no 'ruby.modules-path' has been supplied, giving up";
TRI_FlushLogging();
exit(EXIT_FAILURE);
LOGGER_FATAL_AND_EXIT("no 'ruby.modules-path' has been supplied, giving up");
}
else {
LOGGER_INFO << "using Ruby modules path '" << _startupModules << "'";
LOGGER_INFO("using Ruby modules path '" << _startupModules << "'");
}
// set up the startup loader
if (_startupPath.empty()) {
LOGGER_INFO << "using built-in Ruby startup files";
LOGGER_INFO("using built-in Ruby startup files");
_startupLoader.defineScript("common/bootstrap/error.rb", MR_common_bootstrap_error);
_startupLoader.defineScript("server/server.rb", MR_server_server);
}
else {
LOGGER_INFO << "using Ruby startup files at '" << _startupPath << "'";
LOGGER_INFO("using Ruby startup files at '" << _startupPath << "'");
_startupLoader.setDirectory(_startupPath);
}
// set up action loader
if (_actionPath.empty()) {
LOGGER_FATAL << "no 'ruby.modules-path' has been supplied, giving up";
TRI_FlushLogging();
exit(EXIT_FAILURE);
LOGGER_FATAL_AND_EXIT("no 'ruby.modules-path' has been supplied, giving up");
}
else {
LOGGER_INFO << "using Ruby action files at '" << _actionPath << "'";
LOGGER_INFO("using Ruby action files at '" << _actionPath << "'");
_actionLoader.setDirectory(_actionPath);
}
@ -435,7 +431,7 @@ bool ApplicationMR::prepareMRInstance (size_t i) {
"server/server.rb"
};
LOGGER_TRACE << "initialising MR context #" << i;
LOGGER_TRACE("initialising MR context #" << i);
MRContext* context = _contexts[i] = new MRContext();
@ -453,9 +449,7 @@ bool ApplicationMR::prepareMRInstance (size_t i) {
bool ok = _startupLoader.loadScript(context->_mrb, files[i]);
if (! ok) {
LOGGER_FATAL << "cannot load Ruby utilities from file '" << files[i] << "'";
return false;
LOGGER_FATAL_AND_EXIT("cannot load Ruby utilities from file '" << files[i] << "'");
}
}
@ -464,16 +458,14 @@ bool ApplicationMR::prepareMRInstance (size_t i) {
bool ok = _actionLoader.executeAllScripts(context->_mrb);
if (! ok) {
LOGGER_FATAL << "cannot load Ruby actions from directory '" << _actionLoader.getDirectory() << "'";
return false;
LOGGER_FATAL_AND_EXIT("cannot load Ruby actions from directory '" << _actionLoader.getDirectory() << "'");
}
}
context->_lastGcStamp = TRI_microtime();
// and return from the context
LOGGER_TRACE << "initialised MR context #" << i;
LOGGER_TRACE("initialised MR context #" << i);
_freeContexts.push_back(context);
@ -485,7 +477,7 @@ bool ApplicationMR::prepareMRInstance (size_t i) {
////////////////////////////////////////////////////////////////////////////////
void ApplicationMR::shutdownMRInstance (size_t i) {
LOGGER_TRACE << "shutting down MR context #" << i;
LOGGER_TRACE("shutting down MR context #" << i);
MRContext* context = _contexts[i];
mrb_state* mrb = context->_mrb;
@ -494,7 +486,7 @@ void ApplicationMR::shutdownMRInstance (size_t i) {
MR_CloseShell(mrb);
LOGGER_TRACE << "closed MR context #" << i;
LOGGER_TRACE("closed MR context #" << i);
}
////////////////////////////////////////////////////////////////////////////////

View File

@ -138,7 +138,7 @@ class mr_action_t : public TRI_action_t {
map< mrb_state*, mrb_value >::iterator i = _callbacks.find(mrb);
if (i == _callbacks.end()) {
LOGGER_WARNING << "no callback function for Ruby action '" << _url.c_str() << "'";
LOGGER_WARNING("no callback function for Ruby action '" << _url.c_str() << "'");
return new HttpResponse(HttpResponse::NOT_FOUND);
}
@ -441,12 +441,12 @@ static mrb_value MR_Mount (mrb_state* mrb, mrb_value self) {
return mrb_false_value();
}
else {
LOGGER_ERROR << "cannot create callback for MRuby action";
LOGGER_ERROR("cannot create callback for MRuby action");
return mrb_true_value();
}
}
else {
LOGGER_ERROR << "cannot define MRuby action";
LOGGER_ERROR("cannot define MRuby action");
return mrb_false_value();
}
}

View File

@ -77,9 +77,9 @@ namespace triagens {
char* searchStart;
char* foundStart;
size_t foundLength;
bool containsMore;
char* contentId;
size_t contentIdLength;
bool containsMore;
};
////////////////////////////////////////////////////////////////////////////////

View File

@ -408,8 +408,8 @@ bool RestDocumentHandler::readSingleDocument (bool generateBody) {
TRI_voc_rid_t ifRid = extractRevision("if-match", "rev");
// split the document reference
string collection = suffix[0];
string key = suffix[1];
const string& collection = suffix[0];
const string& key = suffix[1];
// find and load collection given by name or identifier
SingleCollectionReadOnlyTransaction<StandaloneTransaction<RestTransactionContext> > trx(_vocbase, _resolver, collection);
@ -463,7 +463,7 @@ bool RestDocumentHandler::readSingleDocument (bool generateBody) {
}
else if (ifNoneRid == rid) {
if (ifRid == 0 || ifRid == rid) {
generateNotModified(StringUtils::itoa(rid));
generateNotModified(rid);
}
else {
generatePreconditionFailed(cid, document->_key, rid);
@ -760,8 +760,8 @@ bool RestDocumentHandler::modifyDocument (bool isPatch) {
}
// split the document reference
string collection = suffix[0];
string key = suffix[1];
const string& collection = suffix[0];
const string& key = suffix[1];
// auto-ptr that will free JSON data when scope is left
ResourceHolder holder;
@ -930,8 +930,8 @@ bool RestDocumentHandler::deleteDocument () {
}
// split the document reference
string collection = suffix[0];
string key = suffix[1];
const string& collection = suffix[0];
const string& key = suffix[1];
// extract the revision
TRI_voc_rid_t revision = extractRevision("if-match", "rev");

View File

@ -170,9 +170,14 @@ bool RestVocbaseBaseHandler::checkCreateCollection (const string& name,
const TRI_col_type_e type) {
bool found;
char const* valueStr = _request->value("createCollection", found);
bool create = found ? StringUtils::boolean(valueStr) : false;
if (! create) {
if (! found) {
// "createCollection" parameter not specified
return true;
}
if (! StringUtils::boolean(valueStr)) {
// "createCollection" parameter specified, but with non-true value
return true;
}
@ -191,8 +196,8 @@ bool RestVocbaseBaseHandler::checkCreateCollection (const string& name,
void RestVocbaseBaseHandler::generate20x (const HttpResponse::HttpResponseCode responseCode,
const string& collectionName,
TRI_voc_key_t key,
TRI_voc_rid_t rid) {
const TRI_voc_key_t key,
const TRI_voc_rid_t rid) {
const string handle = DocumentHelper::assembleDocumentId(collectionName, key);
const string rev = StringUtils::itoa(rid);
@ -206,7 +211,7 @@ void RestVocbaseBaseHandler::generate20x (const HttpResponse::HttpResponseCode r
// handle does not need to be RFC 2047-encoded
_response->setHeader("location", DOCUMENT_PATH + "/" + handle);
}
// _id and _key are safe and do not need to be JSON-encoded
_response->body()
.appendText("{\"error\":false,\"_id\":\"")
@ -218,55 +223,6 @@ void RestVocbaseBaseHandler::generate20x (const HttpResponse::HttpResponseCode r
.appendText("\"}");
}
////////////////////////////////////////////////////////////////////////////////
/// @brief generates ok message without content
////////////////////////////////////////////////////////////////////////////////
void RestVocbaseBaseHandler::generateOk () {
_response = createResponse(HttpResponse::NO_CONTENT);
}
////////////////////////////////////////////////////////////////////////////////
/// @brief generates created message
////////////////////////////////////////////////////////////////////////////////
void RestVocbaseBaseHandler::generateCreated (const TRI_voc_cid_t cid,
TRI_voc_key_t key,
TRI_voc_rid_t rid) {
generate20x(HttpResponse::CREATED, _resolver.getCollectionName(cid), key, rid);
}
////////////////////////////////////////////////////////////////////////////////
/// @brief generates accepted message
////////////////////////////////////////////////////////////////////////////////
void RestVocbaseBaseHandler::generateAccepted (const TRI_voc_cid_t cid,
TRI_voc_key_t key,
TRI_voc_rid_t rid) {
generate20x(HttpResponse::ACCEPTED, _resolver.getCollectionName(cid), key, rid);
}
////////////////////////////////////////////////////////////////////////////////
/// @brief generates deleted message
////////////////////////////////////////////////////////////////////////////////
void RestVocbaseBaseHandler::generateDeleted (const TRI_voc_cid_t cid,
TRI_voc_key_t key,
TRI_voc_rid_t rid) {
generate20x(HttpResponse::OK, _resolver.getCollectionName(cid), key, rid);
}
////////////////////////////////////////////////////////////////////////////////
/// @brief generates updated message
////////////////////////////////////////////////////////////////////////////////
void RestVocbaseBaseHandler::generateUpdated (const TRI_voc_cid_t cid,
TRI_voc_key_t key,
TRI_voc_rid_t rid) {
generate20x(HttpResponse::OK, _resolver.getCollectionName(cid), key, rid);
}
////////////////////////////////////////////////////////////////////////////////
/// @brief generates document not found error message
////////////////////////////////////////////////////////////////////////////////
@ -337,9 +293,11 @@ void RestVocbaseBaseHandler::generatePreconditionFailed (const TRI_voc_cid_t cid
/// @brief generates not modified
////////////////////////////////////////////////////////////////////////////////
void RestVocbaseBaseHandler::generateNotModified (const string& etag) {
void RestVocbaseBaseHandler::generateNotModified (const TRI_voc_rid_t rid) {
const string rev = StringUtils::itoa(rid);
_response = createResponse(HttpResponse::NOT_MODIFIED);
_response->setHeader("ETag", "\"" + etag + "\"");
_response->setHeader("ETag", "\"" + rev + "\"");
}
////////////////////////////////////////////////////////////////////////////////

View File

@ -183,46 +183,56 @@ namespace triagens {
void generate20x (const rest::HttpResponse::HttpResponseCode,
const string&,
TRI_voc_key_t,
TRI_voc_rid_t);
const TRI_voc_key_t,
const TRI_voc_rid_t);
////////////////////////////////////////////////////////////////////////////////
/// @brief generates ok message without content
////////////////////////////////////////////////////////////////////////////////
void generateOk ();
void generateOk () {
_response = createResponse(rest::HttpResponse::NO_CONTENT);
}
////////////////////////////////////////////////////////////////////////////////
/// @brief generates created message
////////////////////////////////////////////////////////////////////////////////
void generateCreated (const TRI_voc_cid_t,
TRI_voc_key_t,
TRI_voc_rid_t);
void generateCreated (const TRI_voc_cid_t cid,
TRI_voc_key_t key,
TRI_voc_rid_t rid) {
generate20x(rest::HttpResponse::CREATED, _resolver.getCollectionName(cid), key, rid);
}
////////////////////////////////////////////////////////////////////////////////
/// @brief generates accepted message
////////////////////////////////////////////////////////////////////////////////
void generateAccepted (const TRI_voc_cid_t,
TRI_voc_key_t,
TRI_voc_rid_t);
void generateAccepted (const TRI_voc_cid_t cid,
const TRI_voc_key_t key,
const TRI_voc_rid_t rid) {
generate20x(rest::HttpResponse::ACCEPTED, _resolver.getCollectionName(cid), key, rid);
}
////////////////////////////////////////////////////////////////////////////////
/// @brief generates deleted message
////////////////////////////////////////////////////////////////////////////////
void generateDeleted (const TRI_voc_cid_t,
TRI_voc_key_t,
TRI_voc_rid_t);
void generateDeleted (const TRI_voc_cid_t cid,
const TRI_voc_key_t key,
const TRI_voc_rid_t rid) {
generate20x(rest::HttpResponse::OK, _resolver.getCollectionName(cid), key, rid);
}
////////////////////////////////////////////////////////////////////////////////
/// @brief generates updated message
////////////////////////////////////////////////////////////////////////////////
void generateUpdated (const TRI_voc_cid_t,
TRI_voc_key_t,
TRI_voc_rid_t);
void generateUpdated (const TRI_voc_cid_t cid,
const TRI_voc_key_t key,
const TRI_voc_rid_t rid) {
generate20x(rest::HttpResponse::OK, _resolver.getCollectionName(cid), key, rid);
}
////////////////////////////////////////////////////////////////////////////////
/// @brief generates document not found error message
@ -255,7 +265,7 @@ namespace triagens {
/// @brief generates not modified
////////////////////////////////////////////////////////////////////////////////
void generateNotModified (const string&);
void generateNotModified (const TRI_voc_rid_t);
////////////////////////////////////////////////////////////////////////////////
/// @brief generates first entry from a result set

View File

@ -241,7 +241,6 @@ void ArangoServer::buildApplicationServer () {
_applicationServer->addFeature(_applicationScheduler);
// .............................................................................
// dispatcher
// .............................................................................
@ -249,7 +248,6 @@ void ArangoServer::buildApplicationServer () {
_applicationDispatcher = new ApplicationDispatcher(_applicationScheduler);
_applicationServer->addFeature(_applicationDispatcher);
// .............................................................................
// V8 engine
// .............................................................................
@ -306,7 +304,6 @@ void ArangoServer::buildApplicationServer () {
additional[ApplicationServer::OPTIONS_HIDDEN]
("no-upgrade", "skip a database upgrade")
("show-markers", "show offset and sizes of markers")
;
#ifdef TRI_ENABLE_MRUBY
@ -489,7 +486,7 @@ void ArangoServer::buildApplicationServer () {
if (absoluteFile != 0) {
_pidFile = string(absoluteFile);
TRI_Free(TRI_UNKNOWN_MEM_ZONE, absoluteFile);
TRI_Free(TRI_CORE_MEM_ZONE, absoluteFile);
LOGGER_DEBUG("using absolute pid file '" << _pidFile << "'");
}
@ -497,7 +494,6 @@ void ArangoServer::buildApplicationServer () {
LOGGER_FATAL_AND_EXIT("cannot determine current directory");
}
}
}
////////////////////////////////////////////////////////////////////////////////
@ -580,22 +576,6 @@ int ArangoServer::startupServer () {
TRI_InitialiseStatistics();
// .............................................................................
// show markers
// .............................................................................
if (_applicationServer->programOptions().has("show-markers")) {
LOGGER_INFO("sizeof(TRI_df_marker_t): " << sizeof(TRI_df_marker_t));
LOGGER_INFO("sizeof(TRI_df_header_marker_t): " << sizeof(TRI_df_header_marker_t));
LOGGER_INFO("sizeof(TRI_df_footer_marker_t): " << sizeof(TRI_df_footer_marker_t));
LOGGER_INFO("sizeof(TRI_df_document_marker_t): " << sizeof(TRI_df_document_marker_t));
LOGGER_INFO("sizeof(TRI_df_skip_marker_t): " << sizeof(TRI_df_skip_marker_t));
LOGGER_INFO("sizeof(TRI_doc_document_key_marker_s): " << sizeof(TRI_doc_document_key_marker_s));
LOGGER_INFO("sizeof(TRI_doc_edge_key_marker_s): " << sizeof(TRI_doc_edge_key_marker_s));
LOGGER_INFO("sizeof(TRI_doc_deletion_key_marker_s): " << sizeof(TRI_doc_deletion_key_marker_s));
}
// .............................................................................
// start the main event loop
// .............................................................................
@ -639,11 +619,6 @@ int ArangoServer::startupServer () {
int ArangoServer::executeConsole (OperationMode::server_operation_mode_e mode) {
bool ok;
// only simple logging
TRI_ShutdownLogging();
TRI_InitialiseLogging(false);
TRI_CreateLogAppenderFile("+");
// open the database
openDatabase();
@ -967,11 +942,6 @@ mrb_value MR_ArangoDatabase_Collection (mrb_state* mrb, mrb_value self) {
int ArangoServer::executeRubyConsole () {
bool ok;
// only simple logging
TRI_ShutdownLogging();
TRI_InitialiseLogging(false);
TRI_CreateLogAppenderFile("+");
// open the database
openDatabase();

View File

@ -59,6 +59,7 @@ static void arangodExitFunction (int, void*);
// .............................................................................
// Call this function to do various initialistions for windows only
// .............................................................................
void arangodEntryFunction() {
int maxOpenFiles = 2048; // upper hard limit for windows
int res = 0;
@ -71,16 +72,19 @@ void arangodEntryFunction() {
//res = initialiseWindows(TRI_WIN_INITIAL_SET_DEBUG_FLAG, 0);
res = initialiseWindows(TRI_WIN_INITIAL_SET_INVALID_HANLE_HANDLER, 0);
if (res != 0) {
_exit(1);
}
res = initialiseWindows(TRI_WIN_INITIAL_SET_MAX_STD_IO,(const char*)(&maxOpenFiles));
if (res != 0) {
_exit(1);
}
res = initialiseWindows(TRI_WIN_INITIAL_WSASTARTUP_FUNCTION_CALL, 0);
if (res != 0) {
_exit(1);
}
@ -89,7 +93,7 @@ void arangodEntryFunction() {
}
static void arangodExitFunction(int exitCode, void* data) {
static void arangodExitFunction (int exitCode, void* data) {
int res = 0;
// ...........................................................................
// TODO: need a terminate function for windows to be called and cleanup
@ -104,6 +108,7 @@ static void arangodExitFunction(int exitCode, void* data) {
_exit(exitCode);
}
#else
static void arangodEntryFunction() {

View File

@ -82,13 +82,11 @@ namespace triagens {
static inline string assembleDocumentId (const string& collectionName,
const TRI_voc_key_t key) {
static const string UnknownKey = "_deleted";
if (key == 0) {
return assembleDocumentId(collectionName, UnknownKey);
return collectionName + TRI_DOCUMENT_HANDLE_SEPARATOR_STR + "_deleted";
}
return assembleDocumentId(collectionName, string(key));
return collectionName + TRI_DOCUMENT_HANDLE_SEPARATOR_STR + key;
}
////////////////////////////////////////////////////////////////////////////////

View File

@ -608,20 +608,46 @@ namespace triagens {
void const* data,
const bool forceSync,
const bool lock) {
TRI_voc_key_t key = 0;
// check if _key is present
if (json != NULL && json->_type == TRI_JSON_ARRAY) {
// _key is there
TRI_json_t* k = TRI_LookupArrayJson((TRI_json_t*) json, "_key");
if (k != NULL) {
if (k->_type == TRI_JSON_STRING) {
// _key is there and a string
key = k->_value._string.data;
}
else {
// _key is there but not a string
return TRI_ERROR_ARANGO_DOCUMENT_KEY_BAD;
}
}
}
TRI_shaped_json_t* shaped = TRI_ShapedJsonJson(primary->_shaper, json);
if (shaped == 0) {
return TRI_ERROR_ARANGO_SHAPER_FAILED;
}
TRI_doc_operation_context_t context;
TRI_InitContextPrimaryCollection(&context, primary, TRI_DOC_UPDATE_ERROR, forceSync);
if (lock) {
// WRITE-LOCK START
this->lockExplicit(primary, TRI_TRANSACTION_WRITE);
}
int res = primary->createJson(&context, markerType, mptr, json, data);
int res = primary->create(&context, markerType, mptr, shaped, data, key);
if (lock) {
this->unlockExplicit(primary, TRI_TRANSACTION_WRITE);
// WRITE-LOCK END
}
TRI_FreeShapedJson(primary->_shaper, shaped);
return res;
}
@ -669,6 +695,12 @@ namespace triagens {
TRI_voc_rid_t* actualRevision,
const bool forceSync,
const bool lock) {
TRI_shaped_json_t* shaped = TRI_ShapedJsonJson(primary->_shaper, json);
if (shaped == 0) {
return TRI_ERROR_ARANGO_SHAPER_FAILED;
}
TRI_doc_operation_context_t context;
TRI_InitContextPrimaryCollection(&context, primary, policy, forceSync);
context._expectedRid = expectedRevision;
@ -679,12 +711,14 @@ namespace triagens {
this->lockExplicit(primary, TRI_TRANSACTION_WRITE);
}
int res = primary->updateJson(&context, mptr, json, (TRI_voc_key_t) key.c_str());
int res = primary->update(&context, mptr, shaped, (TRI_voc_key_t) key.c_str());
if (lock) {
this->unlockExplicit(primary, TRI_TRANSACTION_WRITE);
// WRITE-LOCK END
}
TRI_FreeShapedJson(primary->_shaper, shaped);
return res;
}

View File

@ -723,8 +723,7 @@ bool ApplicationV8::prepareV8Instance (const size_t i) {
context->_isolate->Exit();
delete context->_locker;
TRI_ShutdownLogging();
exit(EXIT_SUCCESS);
TRI_EXIT_FUNCTION(EXIT_SUCCESS, NULL);
}
// load all actions

View File

@ -846,79 +846,6 @@ static int DeleteDocument (TRI_doc_operation_context_t* context,
return TRI_ERROR_NO_ERROR;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief creates a new document in the collection from json
////////////////////////////////////////////////////////////////////////////////
static int CreateJson (TRI_doc_operation_context_t* context,
TRI_df_marker_type_e type,
TRI_doc_mptr_t** mptr,
TRI_json_t const* json,
void const* data) {
TRI_shaped_json_t* shaped;
TRI_primary_collection_t* primary;
TRI_voc_key_t key;
int res;
key = 0;
primary = context->_collection;
shaped = TRI_ShapedJsonJson(primary->_shaper, json);
if (shaped == 0) {
return TRI_ERROR_ARANGO_SHAPER_FAILED;
}
if (json != NULL && json->_type == TRI_JSON_ARRAY) {
// _key is there
TRI_json_t* k = TRI_LookupArrayJson((TRI_json_t*) json, "_key");
if (k != NULL) {
if (k->_type == TRI_JSON_STRING) {
// _key is there and a string
key = k->_value._string.data;
}
else {
// _key is there but not a string
TRI_FreeShapedJson(primary->_shaper, shaped);
return TRI_ERROR_ARANGO_DOCUMENT_KEY_BAD;
}
}
}
res = primary->create(context, type, mptr, shaped, data, key);
TRI_FreeShapedJson(primary->_shaper, shaped);
return res;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief updates a document in the collection from json
////////////////////////////////////////////////////////////////////////////////
static int UpdateJson (TRI_doc_operation_context_t* context,
TRI_doc_mptr_t** mptr,
TRI_json_t const* json,
TRI_voc_key_t key) {
TRI_shaped_json_t* shaped;
TRI_primary_collection_t* primary;
int res;
primary = context->_collection;
shaped = TRI_ShapedJsonJson(primary->_shaper, json);
if (shaped == 0) {
return TRI_ERROR_ARANGO_SHAPER_FAILED;
}
res = primary->update(context, mptr, shaped, key);
TRI_FreeShapedJson(primary->_shaper, shaped);
return res;
}
////////////////////////////////////////////////////////////////////////////////
/// @}
////////////////////////////////////////////////////////////////////////////////
@ -1892,9 +1819,6 @@ static bool InitDocumentCollection (TRI_document_collection_t* collection,
collection->base.update = UpdateShapedJson;
collection->base.destroy = DeleteShapedJson;
collection->base.createJson = CreateJson;
collection->base.updateJson = UpdateJson;
collection->cleanupIndexes = CleanupIndexes;
return true;

View File

@ -189,7 +189,7 @@ TRI_doc_collection_info_t;
/// as the object is not deleted.
///
/// It is important to use locks for create, read, update, and delete. The
/// functions @FN{create}, @FN{createJson}, @FN{update}, @FN{updateJson}, and
/// functions @FN{create}, @FN{update}, and
/// @FN{destroy} are only allowed within a @FN{beginWrite} and
/// @FN{endWrite}. The function @FN{read} is only allowed within a
/// @FN{beginRead} and @FN{endRead}. Note that @FN{read} returns a copy of the
@ -230,7 +230,6 @@ TRI_doc_collection_info_t;
/// @LIT{beginWrite}.
///
/// @FUN{TRI_doc_mptr_t const create (TRI_primary_collection_t*, TRI_df_marker_type_e, TRI_shaped_json_t const*, bool @FA{release})}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
///
/// Adds a new document to the collection and returns the master pointer of the
/// newly created entry. In case of an error, the attribute @LIT{_did} of the
@ -238,16 +237,6 @@ TRI_doc_collection_info_t;
/// NOT acquire a write lock. This must be done by the caller. If @FA{release}
/// is true, it will release the write lock as soon as possible.
///
/// @FUN{TRI_doc_mptr_t const createJson (TRI_primary_collection_t*, TRI_df_marker_type_e, TRI_json_t const*, bool @FA{release})}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
///
/// As before, but instead of a shaped json a json object must be given.
///
/// @FUN{TRI_voc_key_t createLock (TRI_primary_collection_t*, TRI_df_marker_type_e, TRI_shaped_json_t const*)}
//////////////////////////////////////////////////////////////////////////////////////////////////////////
///
/// As before, but the function will acquire and release the write lock.
///
/// @FUN{TRI_doc_mptr_t const read (TRI_primary_collection_t*, TRI_voc_key_t)}
//////////////////////////////////////////////////////////////////////////
///
@ -272,16 +261,8 @@ TRI_doc_collection_info_t;
/// performed if the current revision matches the given. In any case the current
/// revision after the updated of the document is returned in @FA{current}.
///
/// @FUN{TRI_doc_mptr_t const updateJson (TRI_primary_collection_t*, TRI_json_t const*, TRI_voc_key_t, TRI_voc_rid_t @FA{rid}, TRI_voc_rid_t* @FA{current}, TRI_doc_update_policy_e, bool @FA{release})}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
///
/// As before, but instead of a shaped json a json object must be given.
///
/// @FUN{int updateLock (TRI_primary_collection_t*, TRI_shaped_json_t const*, TRI_voc_key_t, TRI_voc_rid_t @FA{rid}, TRI_voc_rid_t* @FA{current}, TRI_doc_update_policy_e)}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
///
/// As before, but the function will acquire and release the write lock.
///
/// @FUN{int destroy (TRI_primary_collection_t*, TRI_voc_key_t, TRI_voc_rid_t, TRI_voc_rid_t @FA{rid}, TRI_voc_rid_t* @FA{current}, TRI_doc_update_policy_e, bool @FA{release})}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
///
@ -338,12 +319,9 @@ typedef struct TRI_primary_collection_s {
void (*updateHeader) (struct TRI_primary_collection_s*, TRI_datafile_t*, TRI_df_marker_t const*, size_t, TRI_doc_mptr_t const*, TRI_doc_mptr_t*);
int (*create) (struct TRI_doc_operation_context_s*, TRI_df_marker_type_e, TRI_doc_mptr_t**, TRI_shaped_json_t const*, void const*, TRI_voc_key_t key);
int (*createJson) (struct TRI_doc_operation_context_s*, TRI_df_marker_type_e, TRI_doc_mptr_t**, TRI_json_t const*, void const*);
int (*read) (struct TRI_doc_operation_context_s*, TRI_doc_mptr_t**, TRI_voc_key_t);
int (*update) (struct TRI_doc_operation_context_s*, TRI_doc_mptr_t**, TRI_shaped_json_t const*, TRI_voc_key_t);
int (*updateJson) (struct TRI_doc_operation_context_s*, TRI_doc_mptr_t**, TRI_json_t const*, TRI_voc_key_t);
int (*destroy) (struct TRI_doc_operation_context_s*, TRI_voc_key_t);
TRI_doc_collection_info_t* (*figures) (struct TRI_primary_collection_s* collection);

View File

@ -111,9 +111,8 @@ static bool CreateJournal (TRI_shape_collection_t* collection) {
ok = TRI_RenameDatafile(journal, filename);
if (! ok) {
LOG_WARNING("failed to rename the journal to '%s': %s", filename, TRI_last_error());
// TODO: remove disastrous call to exit() here
exit(1);
LOG_FATAL_AND_EXIT("failed to rename the journal to '%s': %s", filename, TRI_last_error());
}
else {
LOG_TRACE("renamed journal to '%s'", filename);

View File

@ -45,6 +45,7 @@
#include "BasicsC/files.h"
#include "BasicsC/init.h"
#include "BasicsC/logging.h"
#include "BasicsC/shell-colors.h"
#include "BasicsC/strings.h"
#include "BasicsC/terminal-utils.h"
#include "Logger/Logger.h"
@ -206,8 +207,7 @@ static void ParseProgramOptions (int argc, char* argv[]) {
// check module path
if (StartupModules.empty()) {
LOGGER_FATAL << "module path not known, please use '--ruby.modules-path'";
exit(EXIT_FAILURE);
LOGGER_FATAL_AND_EXIT("module path not known, please use '--ruby.modules-path'");
}
}
@ -350,8 +350,7 @@ int main (int argc, char* argv[]) {
BaseClient.createEndpoint();
if (BaseClient.endpointServer() == 0) {
cerr << "invalid value for --server.endpoint ('" << BaseClient.endpointString() << "')" << endl;
exit(EXIT_FAILURE);
LOGGER_FATAL_AND_EXIT("invalid value for --server.endpoint ('" << BaseClient.endpointString() << "')");
}
ClientConnection = createConnection(mrb);
@ -364,9 +363,9 @@ int main (int argc, char* argv[]) {
// http://www.network-science.de/ascii/ Font: ogre
if (! BaseClient.quiet()) {
char const* g = ArangoClient::COLOR_GREEN;
char const* r = ArangoClient::COLOR_RED;
char const* z = ArangoClient::COLOR_RESET;
char const* g = TRI_SHELL_COLOR_GREEN;
char const* r = TRI_SHELL_COLOR_RED;
char const* z = TRI_SHELL_COLOR_RESET;
if (! BaseClient.colors()) {
g = "";
@ -418,7 +417,7 @@ int main (int argc, char* argv[]) {
StartupLoader.defineScript("common/bootstrap/error.rb", MR_common_bootstrap_error);
}
else {
LOGGER_DEBUG << "using Ruby startup files at '" << StartupPath << "'";
LOGGER_DEBUG("using Ruby startup files at '" << StartupPath << "'");
StartupLoader.setDirectory(StartupPath);
}
@ -431,11 +430,10 @@ int main (int argc, char* argv[]) {
bool ok = StartupLoader.loadScript(mrb, files[i]);
if (ok) {
LOGGER_TRACE << "loaded ruby file '" << files[i] << "'";
LOGGER_TRACE("loaded ruby file '" << files[i] << "'");
}
else {
LOGGER_ERROR << "cannot load ruby file '" << files[i] << "'";
exit(EXIT_FAILURE);
LOGGER_FATAL_AND_EXIT("cannot load ruby file '" << files[i] << "'");
}
}

View File

@ -268,8 +268,7 @@ void ArangoClient::parse (ProgramOptions& options,
char* argv[],
string const& initFilename) {
if (! options.parse(description, argc, argv)) {
cerr << options.lastError() << "\n";
exit(EXIT_FAILURE);
LOGGER_FATAL_AND_EXIT(options.lastError());
}
// check for help
@ -277,7 +276,7 @@ void ArangoClient::parse (ProgramOptions& options,
if (! help.empty()) {
cout << description.usage(help) << endl;
exit(EXIT_SUCCESS);
TRI_EXIT_FUNCTION(EXIT_SUCCESS, NULL);
}
// setup the logging
@ -381,19 +380,16 @@ void ArangoClient::parse (ProgramOptions& options,
// check connection args
if (_connectTimeout <= 0) {
cerr << "invalid value for --server.connect-timeout, must be positive" << endl;
exit(EXIT_FAILURE);
LOGGER_FATAL_AND_EXIT("invalid value for --server.connect-timeout, must be positive");
}
if (_requestTimeout <= 0) {
cerr << "invalid value for --server.request-timeout, must be positive" << endl;
exit(EXIT_FAILURE);
LOGGER_FATAL_AND_EXIT("invalid value for --server.request-timeout, must be positive");
}
// must specify a user name
if (_username.size() == 0) {
cerr << "no value specified for --server.username" << endl;
exit(EXIT_FAILURE);
LOGGER_FATAL_AND_EXIT("no value specified for --server.username");
}
// no password given on command-line

View File

@ -454,8 +454,7 @@ int main (int argc, char* argv[]) {
BaseClient.createEndpoint();
if (BaseClient.endpointServer() == 0) {
cerr << "invalid value for --server.endpoint ('" << BaseClient.endpointString() << "')" << endl;
exit(EXIT_FAILURE);
LOGGER_FATAL_AND_EXIT("invalid value for --server.endpoint ('" << BaseClient.endpointString() << "')");
}
BenchmarkOperation* testCase;
@ -470,8 +469,8 @@ int main (int argc, char* argv[]) {
testCase = new CollectionCreationTest();
}
else {
cerr << "invalid test case name " << TestCase << endl;
exit(EXIT_FAILURE);
LOGGER_FATAL_AND_EXIT("invalid test case name " << TestCase);
return EXIT_FAILURE; // will not be reached
}
Status("starting threads...");

View File

@ -954,13 +954,16 @@ static void RunShell (v8::Handle<v8::Context> context, bool promptError) {
string i = triagens::basics::StringUtils::trim(input);
if (i == "exit" || i == "quit" || i == "exit;" || i == "quit;") {
TRI_FreeString(TRI_CORE_MEM_ZONE, input);
TRI_FreeString(TRI_UNKNOWN_MEM_ZONE, input);
break;
}
if (i == "help" || i == "help;") {
TRI_FreeString(TRI_CORE_MEM_ZONE, input);
input = TRI_DuplicateString("help()");
TRI_FreeString(TRI_UNKNOWN_MEM_ZONE, input);
input = TRI_DuplicateStringZ(TRI_UNKNOWN_MEM_ZONE, "help()");
if (input == 0) {
LOGGER_FATAL_AND_EXIT("out of memory");
}
}
console.addHistory(input);
@ -1142,6 +1145,7 @@ static void arangoshExitFunction (int, void*);
// .............................................................................
// Call this function to do various initialistions for windows only
// .............................................................................
void arangoshEntryFunction() {
int maxOpenFiles = 1024;
int res = 0;
@ -1154,16 +1158,19 @@ void arangoshEntryFunction() {
//res = initialiseWindows(TRI_WIN_INITIAL_SET_DEBUG_FLAG, 0);
res = initialiseWindows(TRI_WIN_INITIAL_SET_INVALID_HANLE_HANDLER, 0);
if (res != 0) {
_exit(1);
}
res = initialiseWindows(TRI_WIN_INITIAL_SET_MAX_STD_IO,(const char*)(&maxOpenFiles));
if (res != 0) {
_exit(1);
}
res = initialiseWindows(TRI_WIN_INITIAL_WSASTARTUP_FUNCTION_CALL, 0);
if (res != 0) {
_exit(1);
}

View File

@ -31,6 +31,8 @@ disable-admin-interface = no
disable-authentication = yes
admin-directory= @PKGDATADIR@/html/admin
threads = 5
uid = arangodb
gid = arangodb
[scheduler]
threads = 3

View File

@ -107,6 +107,7 @@ string const ApplicationServer::OPTIONS_SERVER = "Server Options";
////////////////////////////////////////////////////////////////////////////////
#ifdef _WIN32
ApplicationServer::ApplicationServer (std::string const& name, std::string const& title, std::string const& version)
: _options(),
_description(),
@ -142,7 +143,9 @@ ApplicationServer::ApplicationServer (std::string const& name, std::string const
_logLineNumber(false),
_randomGenerator(5) {
}
#else
ApplicationServer::ApplicationServer (std::string const& name, std::string const& title, std::string const& version)
: _options(),
_description(),
@ -177,7 +180,9 @@ ApplicationServer::ApplicationServer (std::string const& name, std::string const
_logThreadId(false),
_logLineNumber(false),
_randomGenerator(3) {
storeRealPrivileges();
}
#endif
////////////////////////////////////////////////////////////////////////////////
@ -247,9 +252,8 @@ string const& ApplicationServer::getName () const {
/// @brief sets up the logging
////////////////////////////////////////////////////////////////////////////////
void ApplicationServer::setupLogging () {
bool threaded = TRI_ShutdownLogging();
void ApplicationServer::setupLogging (bool threaded, bool daemon) {
TRI_ShutdownLogging();
TRI_InitialiseLogging(threaded);
Logger::setApplicationName(_logApplicationName);
@ -279,17 +283,26 @@ void ApplicationServer::setupLogging () {
TRI_SetFileToLog(i->c_str());
}
if (NULL == TRI_CreateLogAppenderFile(_logFile.c_str())) {
if (_logFile.length() > 0) {
// the user specified a log file to use but it could not be created. bail out
LOGGER_FATAL_AND_EXIT("failed to create logfile '" << _logFile << "'. Please check the path and permissions.");
}
}
#ifdef TRI_ENABLE_SYSLOG
if (_logSyslog != "") {
TRI_CreateLogAppenderSyslog(_logPrefix.c_str(), _logSyslog.c_str());
}
#endif
if (_logFile.length() > 0) {
string filename = _logFile;
if (daemon && filename != "+" && filename != "-") {
filename = filename + ".daemon";
}
struct TRI_log_appender_s* appender = TRI_CreateLogAppenderFile(filename.c_str());
// the user specified a log file to use but it could not be created. bail out
if (appender == 0) {
LOGGER_FATAL_AND_EXIT("failed to create logfile '" << filename << "'. Please check the path and permissions.");
}
}
}
////////////////////////////////////////////////////////////////////////////////
@ -369,30 +382,15 @@ bool ApplicationServer::parse (int argc,
if (! help.empty()) {
cout << argv[0] << " " << _title << "\n\n" << _description.usage(help) << endl;
exit(EXIT_SUCCESS);
TRI_EXIT_FUNCTION(EXIT_SUCCESS, NULL);
}
// check for version request
if (_options.has("version")) {
cout << _version << endl;
exit(EXIT_SUCCESS);
TRI_EXIT_FUNCTION(EXIT_SUCCESS, NULL);
}
// .............................................................................
// UID and GID
// .............................................................................
storeRealPrivileges();
extractPrivileges();
dropPrivileges();
// .............................................................................
// setup logging
// .............................................................................
setupLogging();
// .............................................................................
// parse phase 1
// .............................................................................
@ -415,8 +413,18 @@ bool ApplicationServer::parse (int argc,
return false;
}
// re-set logging using the additional config file entries
setupLogging();
// .............................................................................
// UID and GID
// .............................................................................
extractPrivileges();
dropPrivileges();
// .............................................................................
// setup logging
// .............................................................................
setupLogging(false, false);
// .............................................................................
// parse phase 2
@ -718,6 +726,20 @@ void ApplicationServer::dropPrivilegesPermanently () {
#endif
}
////////////////////////////////////////////////////////////////////////////////
/// @brief saves the logging privileges
////////////////////////////////////////////////////////////////////////////////
void ApplicationServer::storeRealPrivileges () {
#ifdef TRI_HAVE_SETGID
_realGid = getgid();
#endif
#ifdef TRI_HAVE_SETUID
_realUid = getuid();
#endif
}
////////////////////////////////////////////////////////////////////////////////
/// @}
////////////////////////////////////////////////////////////////////////////////
@ -746,12 +768,6 @@ void ApplicationServer::setupOptions (map<string, ProgramOptionsDescription>& op
#if defined(TRI_HAVE_SETUID) || defined(TRI_HAVE_SETGID)
options[OPTIONS_CMDLINE + ":help-extended"]
#ifdef TRI_HAVE_SETUID
("uid", &_uid, "switch to user-id after reading config files")
#endif
#ifdef TRI_HAVE_SETGID
("gid", &_gid, "switch to group-id after reading config files")
#endif
#ifdef TRI_HAVE_GETPPID
("exit-on-parent-death", &_exitOnParentDeath, "exit if parent dies")
#endif
@ -784,6 +800,12 @@ void ApplicationServer::setupOptions (map<string, ProgramOptionsDescription>& op
options[OPTIONS_HIDDEN]
("log", &_logLevel, "log level for severity 'human'")
#ifdef TRI_HAVE_SETUID
("uid", &_uid, "switch to user-id after reading config files")
#endif
#ifdef TRI_HAVE_SETGID
("gid", &_gid, "switch to group-id after reading config files")
#endif
;
// .............................................................................
@ -793,6 +815,12 @@ void ApplicationServer::setupOptions (map<string, ProgramOptionsDescription>& op
options[OPTIONS_SERVER + ":help-extended"]
("random.no-seed", "do not seed the random generator")
("random.generator", &_randomGenerator, "1 = mersenne, 2 = random, 3 = urandom, 4 = combined")
#ifdef TRI_HAVE_SETUID
("server.uid", &_uid, "switch to user-id after reading config files")
#endif
#ifdef TRI_HAVE_SETGID
("server.gid", &_gid, "switch to group-id after reading config files")
#endif
;
}
@ -1124,20 +1152,6 @@ void ApplicationServer::extractPrivileges() {
#endif
}
////////////////////////////////////////////////////////////////////////////////
/// @brief saves the logging privileges
////////////////////////////////////////////////////////////////////////////////
void ApplicationServer::storeRealPrivileges () {
#ifdef TRI_HAVE_SETGID
_realGid = getgid();
#endif
#ifdef TRI_HAVE_SETUID
_realUid = getuid();
#endif
}
////////////////////////////////////////////////////////////////////////////////
/// @}
////////////////////////////////////////////////////////////////////////////////

View File

@ -183,7 +183,7 @@ namespace triagens {
/// @brief sets up the logging
////////////////////////////////////////////////////////////////////////////////
void setupLogging ();
void setupLogging (bool thread, bool daemon);
////////////////////////////////////////////////////////////////////////////////
/// @brief returns the command line options

View File

@ -122,6 +122,7 @@ namespace triagens {
: _desc(),
_nrAlloc(0),
_nrUsed(0),
#ifdef TRI_INTERNAL_STATS
_table(0),
_nrFinds(0),
_nrAdds(0),
@ -131,6 +132,9 @@ namespace triagens {
_nrProbesA(0),
_nrProbesD(0),
_nrProbesR(0) {
#else
_table(0) {
#endif
initialise(size);
}
@ -142,6 +146,7 @@ namespace triagens {
_desc(desc),
_nrAlloc(0),
_nrUsed(0),
#ifdef TRI_INTERNAL_STATS
_table(0),
_nrFinds(0),
_nrAdds(0),
@ -151,6 +156,9 @@ namespace triagens {
_nrProbesA(0),
_nrProbesD(0),
_nrProbesR(0) {
#else
_table(0) {
#endif
initialise(size);
}
@ -194,6 +202,7 @@ namespace triagens {
_nrUsed = other->_nrUsed;
other->_nrUsed = tmpInt;
#ifdef TRI_INTERNAL_STATS
tmpInt = _nrFinds;
_nrFinds = other->_nrFinds;
other->_nrFinds = tmpInt;
@ -229,6 +238,7 @@ namespace triagens {
tmpInt = _nrProbesR;
_nrProbesR = other->_nrProbesR;
other->_nrProbesR = tmpInt;
#endif
ELEMENT* tmpTable = _table;
_table = other->_table;
@ -289,9 +299,10 @@ namespace triagens {
ELEMENT const& findKey (KEY const& key) const {
#ifdef TRI_INTERNAL_STATS
// update statistics
_nrFinds++;
#endif
// compute the hash
uint32_t hash = _desc.hashKey(key);
@ -300,7 +311,9 @@ namespace triagens {
while (!_desc.isEmptyElement(_table[i]) && !_desc.isEqualKeyElement(key, _table[i])) {
i = (i + 1) % _nrAlloc;
#ifdef TRI_INTERNAL_STATS
_nrProbesF++;
#endif
}
// return whatever we found
@ -313,9 +326,10 @@ namespace triagens {
ELEMENT const& findElement (ELEMENT const& element) const {
#ifdef TRI_INTERNAL_STATS
// update statistics
_nrFinds++;
#endif
// compute the hash
uint32_t hash = _desc.hashElement(element);
@ -324,7 +338,9 @@ namespace triagens {
while (!_desc.isEmptyElement(_table[i]) && !_desc.isEqualElementElement(element, _table[i])) {
i = (i + 1) % _nrAlloc;
#ifdef TRI_INTERNAL_STATS
_nrProbesF++;
#endif
}
// return whatever we found
@ -337,8 +353,10 @@ namespace triagens {
bool addElement (ELEMENT const& element, bool overwrite = true) {
#ifdef TRI_INTERNAL_STATS
// update statistics
_nrAdds++;
#endif
// search the table
uint32_t hash = _desc.hashElement(element);
@ -346,7 +364,9 @@ namespace triagens {
while (!_desc.isEmptyElement(_table[i]) && !_desc.isEqualElementElement(element, _table[i])) {
i = (i + 1) % _nrAlloc;
#ifdef TRI_INTERNAL_STATS
_nrProbesA++;
#endif
}
// if we found an element, return
@ -373,7 +393,9 @@ namespace triagens {
_nrAlloc = 2 * _nrAlloc + 1;
_nrUsed = 0;
#ifdef TRI_INTERNAL_STATS
_nrResizes++;
#endif
_table = new ELEMENT[_nrAlloc];
@ -399,8 +421,10 @@ namespace triagens {
bool addElement (KEY const& key, ELEMENT const& element, bool overwrite = true) {
#ifdef TRI_INTERNAL_STATS
// update statistics
_nrAdds++;
#endif
// search the table
uint32_t hash = _desc.hashKey(key);
@ -408,7 +432,9 @@ namespace triagens {
while (!_desc.isEmptyElement(_table[i]) && !_desc.isEqualKeyElement(key, _table[i])) {
i = (i + 1) % _nrAlloc;
#ifdef TRI_INTERNAL_STATS
_nrProbesA++;
#endif
}
// if we found an element, return
@ -435,7 +461,9 @@ namespace triagens {
_nrAlloc = 2 * _nrAlloc + 1;
_nrUsed = 0;
#ifdef TRI_INTERNAL_STATS
_nrResizes++;
#endif
_table = new ELEMENT[_nrAlloc];
@ -461,8 +489,10 @@ namespace triagens {
ELEMENT removeKey (KEY const& key) {
#ifdef TRI_INTERNAL_STATS
// update statistics
_nrRems++;
#endif
// search the table
uint32_t hash = _desc.hashKey(key);
@ -470,7 +500,9 @@ namespace triagens {
while (!_desc.isEmptyElement(_table[i]) && !_desc.isEqualKeyElement(key, _table[i])) {
i = (i + 1) % _nrAlloc;
#ifdef TRI_INTERNAL_STATS
_nrProbesD++;
#endif
}
// if we did not find such an item
@ -510,8 +542,10 @@ namespace triagens {
bool removeElement (ELEMENT const& element) {
#ifdef TRI_INTERNAL_STATS
// update statistics
_nrRems++;
#endif
// search the table
uint32_t hash = _desc.hashElement(element);
@ -519,7 +553,9 @@ namespace triagens {
while (!_desc.isEmptyElement(_table[i]) && !_desc.isEqualElementElement(element, _table[i])) {
i = (i + 1) % _nrAlloc;
#ifdef TRI_INTERNAL_STATS
_nrProbesD++;
#endif
}
// if we did not find such an item return false
@ -578,6 +614,7 @@ namespace triagens {
_nrAlloc = size;
_nrUsed = 0;
#ifdef TRI_INTERNAL_STATS
_nrFinds = 0;
_nrAdds = 0;
_nrRems = 0;
@ -586,6 +623,7 @@ namespace triagens {
_nrProbesA = 0;
_nrProbesD = 0;
_nrProbesR = 0;
#endif
}
////////////////////////////////////////////////////////////////////////////////
@ -602,7 +640,9 @@ namespace triagens {
while (!_desc.isEmptyElement(_table[i])) {
i = (i + 1) % _nrAlloc;
#ifdef TRI_INTERNAL_STATS
_nrProbesR++;
#endif
}
// add a new element to the associative array
@ -649,6 +689,8 @@ namespace triagens {
ELEMENT * _table;
#ifdef TRI_INTERNAL_STATS
////////////////////////////////////////////////////////////////////////////////
/// @brief number of executed finds
////////////////////////////////////////////////////////////////////////////////
@ -696,6 +738,8 @@ namespace triagens {
////////////////////////////////////////////////////////////////////////////////
mutable uint64_t _nrProbesR;
#endif
};
}
}

View File

@ -120,6 +120,14 @@ namespace triagens {
TRI_AnnihilateStringBuffer(&_buffer);
}
////////////////////////////////////////////////////////////////////////////////
/// @brief frees the string buffer and cleans the buffer
////////////////////////////////////////////////////////////////////////////////
int reserve (const size_t length) {
return TRI_ReserveStringBuffer(&_buffer, length);
}
////////////////////////////////////////////////////////////////////////////////
/// @}
////////////////////////////////////////////////////////////////////////////////

View File

@ -45,7 +45,7 @@ void defaultExitFunction (int exitCode, void* data) {
_exit(exitCode);
}
void TRI_Application_Exit_SetExit(TRI_ExitFunction_t exitFunction) {
void TRI_Application_Exit_SetExit (TRI_ExitFunction_t exitFunction) {
if (exitFunction != NULL) {
TRI_EXIT_FUNCTION = exitFunction;
}

View File

@ -297,10 +297,8 @@ void TRI_set_errno_string (int error, char const* msg) {
// logic error, error number is redeclared
printf("Error: duplicate declaration of error code %i in %s:%i\n",
error,
__FILE__,
__LINE__);
exit(EXIT_FAILURE);
error, __FILE__, __LINE__);
TRI_EXIT_FUNCTION(EXIT_FAILURE, NULL);
}
entry = (TRI_error_t*) TRI_Allocate(TRI_CORE_MEM_ZONE, sizeof(TRI_error_t), false);

View File

@ -53,7 +53,7 @@ void TRI_InitialiseC (int argc, char* argv[]) {
TRI_InitialiseMemory();
TRI_InitialiseMersenneTwister();
TRI_InitialiseError();
TRI_InitialiseLogging(true);
TRI_InitialiseLogging(false);
TRI_InitialiseHashes();
TRI_InitialiseRandom();
TRI_InitialiseProcess(argc, argv);

View File

@ -666,28 +666,29 @@ TRI_json_t* TRI_SortListJson (TRI_json_t* const list) {
bool TRI_HasDuplicateKeyJson (const TRI_json_t* const object) {
if (object && object->_type == TRI_JSON_ARRAY) {
size_t n;
const size_t n = object->_value._objects._length;
const bool hasMultipleElements = (n > 2);
// if we don't have attributes, we do not need to check for duplicates
// if we only have one attribute, we don't need to check for duplicates in
// the array, but we need to recursively validate the array values (if
// array value itself is an array)
n = object->_value._objects._length;
if (n > 0) {
TRI_associative_pointer_t hash;
size_t i;
TRI_InitAssociativePointer(&hash,
if (hasMultipleElements) {
TRI_InitAssociativePointer(&hash,
TRI_UNKNOWN_MEM_ZONE,
&TRI_HashStringKeyAssociativePointer,
&TRI_HashStringKeyAssociativePointer,
&TRI_EqualStringKeyAssociativePointer,
0);
}
for (i = 0; i < n; i += 2) {
TRI_json_t* key;
TRI_json_t* value;
void* previous;
key = TRI_AtVector(&object->_value._objects, i);
@ -700,21 +701,27 @@ bool TRI_HasDuplicateKeyJson (const TRI_json_t* const object) {
// recursively check sub-array elements
if (value->_type == TRI_JSON_ARRAY && TRI_HasDuplicateKeyJson(value)) {
// duplicate found in sub-array
TRI_DestroyAssociativePointer(&hash);
if (hasMultipleElements) {
TRI_DestroyAssociativePointer(&hash);
}
return true;
}
previous = TRI_InsertKeyAssociativePointer(&hash, key->_value._string.data, key->_value._string.data, false);
if (previous != NULL) {
// duplicate found
TRI_DestroyAssociativePointer(&hash);
if (hasMultipleElements) {
void* previous = TRI_InsertKeyAssociativePointer(&hash, key->_value._string.data, key->_value._string.data, false);
if (previous != NULL) {
// duplicate found
TRI_DestroyAssociativePointer(&hash);
return true;
return true;
}
}
}
TRI_DestroyAssociativePointer(&hash);
if (hasMultipleElements) {
TRI_DestroyAssociativePointer(&hash);
}
}
}

View File

@ -50,8 +50,7 @@ void TRI_InitMutex (TRI_mutex_t* mutex) {
mutex->_mutex = CreateMutex(NULL, FALSE, NULL);
if (mutex->_mutex == NULL) {
LOG_FATAL("cannot create the mutex");
exit(EXIT_FAILURE);
LOG_FATAL_AND_EXIT("cannot create the mutex");
}
}
@ -84,8 +83,7 @@ void TRI_LockMutex (TRI_mutex_t* mutex) {
DWORD result = WaitForSingleObject(mutex->_mutex, INFINITE);
if (result != WAIT_OBJECT_0) {
LOG_FATAL("could not lock the mutex");
exit(EXIT_FAILURE);
LOG_FATAL_AND_EXIT("could not lock the mutex");
}
}
@ -97,8 +95,7 @@ void TRI_UnlockMutex (TRI_mutex_t* mutex) {
BOOL ok = ReleaseMutex(mutex->_mutex);
if (! ok) {
LOG_FATAL("could not unlock the mutex");
exit(EXIT_FAILURE);
LOG_FATAL_AND_EXIT("could not unlock the mutex");
}
}
@ -292,8 +289,7 @@ static void DecrementReaders (TRI_read_write_lock_t* lock) {
SetEvent(lock->_readersEvent);
}
else if (lock->_readers < 0) {
LOG_FATAL("reader count is negative");
exit(EXIT_FAILURE);
LOG_FATAL_AND_EXIT("reader count is negative");
}
}
@ -385,8 +381,7 @@ void TRI_ReadUnlockReadWriteLock (TRI_read_write_lock_t* lock) {
/* this is wrong since it is possible for the write locker to block this event
// a write lock eists
if (WaitForSingleObject(lock->_writerEvent, 0) != WAIT_OBJECT_0) {
LOG_FATAL("write lock, but trying to unlock read");
exit(EXIT_FAILURE);
LOG_FATAL_AND_EXIT("write lock, but trying to unlock read");
}
// at least one reader exists
@ -397,8 +392,7 @@ void TRI_ReadUnlockReadWriteLock (TRI_read_write_lock_t* lock) {
// ups, no writer and no reader
else {
LeaveCriticalSection(&lock->_lockReaders);
LOG_FATAL("no reader and no writer, but trying to unlock");
exit(EXIT_FAILURE);
LOG_FATAL_AND_EXIT("no reader and no writer, but trying to unlock");
}
*/
@ -409,8 +403,7 @@ void TRI_ReadUnlockReadWriteLock (TRI_read_write_lock_t* lock) {
// oops no reader
else {
LeaveCriticalSection(&lock->_lockReaders);
LOG_FATAL("no reader, but trying to unlock read lock");
exit(EXIT_FAILURE);
LOG_FATAL_AND_EXIT("no reader, but trying to unlock read lock");
}
LeaveCriticalSection(&lock->_lockReaders);
@ -555,8 +548,7 @@ void TRI_WriteUnlockReadWriteLock (TRI_read_write_lock_t* lock) {
else if (0 < lock->_readers) {
LeaveCriticalSection(&lock->_lockReaders);
LOG_FATAL("read lock, but trying to unlock write");
exit(EXIT_FAILURE);
LOG_FATAL_AND_EXIT("read lock, but trying to unlock write");
}
@ -567,8 +559,7 @@ void TRI_WriteUnlockReadWriteLock (TRI_read_write_lock_t* lock) {
else {
LeaveCriticalSection(&lock->_lockReaders);
LOG_FATAL("no reader and no writer, but trying to unlock");
exit(EXIT_FAILURE);
LOG_FATAL_AND_EXIT("no reader and no writer, but trying to unlock");
}
@ -855,8 +846,7 @@ void TRI_LockCondition (TRI_condition_t* cond) {
DWORD result = WaitForSingleObject(cond->_mutex, INFINITE);
if (result != WAIT_OBJECT_0) {
LOG_FATAL("could not lock the mutex");
exit(EXIT_FAILURE);
LOG_FATAL_AND_EXIT("could not lock the mutex");
}
}
@ -868,8 +858,7 @@ void TRI_UnlockCondition (TRI_condition_t* cond) {
BOOL ok = ReleaseMutex(cond->_mutex);
if (! ok) {
LOG_FATAL("could not unlock the mutex");
exit(EXIT_FAILURE);
LOG_FATAL_AND_EXIT("could not unlock the mutex");
}
}

View File

@ -254,7 +254,7 @@ static sig_atomic_t ShowFunction = 1;
/// @brief show thread identifier
////////////////////////////////////////////////////////////////////////////////
static sig_atomic_t ShowThreadIdentifier = 1;
static sig_atomic_t ShowThreadIdentifier = 0;
////////////////////////////////////////////////////////////////////////////////
/// @brief output prefix
@ -531,6 +531,25 @@ static int GenerateMessage (char* buffer,
return m + n;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief write to stderr
////////////////////////////////////////////////////////////////////////////////
void writeStderr (char const* line, size_t len) {
ssize_t n;
while (0 < len) {
n = TRI_WRITE(STDERR_FILENO, line, len);
if (n <= 0) {
return;
}
line += n;
len -= n;
}
}
////////////////////////////////////////////////////////////////////////////////
/// @brief outputs a message string to all appenders
////////////////////////////////////////////////////////////////////////////////
@ -541,8 +560,8 @@ static void OutputMessage (TRI_log_level_e level,
size_t length,
bool copy) {
if (! LoggingActive) {
write(2, message, length);
write(2, "\n", 1);
writeStderr(message, length);
writeStderr("\n", 1);
if (! copy) {
TRI_FreeString(TRI_CORE_MEM_ZONE, message);
@ -558,8 +577,8 @@ static void OutputMessage (TRI_log_level_e level,
TRI_LockSpin(&AppendersLock);
if (Appenders._length == 0) {
write(2, message, length);
write(2, "\n", 1);
writeStderr(message, length);
writeStderr("\n", 1);
if (! copy) {
TRI_FreeString(TRI_CORE_MEM_ZONE, message);

View File

@ -204,7 +204,7 @@ void* TRI_Allocate (TRI_memory_zone_t* zone, uint64_t n, bool set) {
(unsigned long long) n,
(int) zone->_zid
ZONE_DEBUG_PARAMS);
exit(EXIT_FAILURE);
TRI_EXIT_FUNCTION(EXIT_FAILURE, NULL);
}
free(CoreReserve);
@ -292,7 +292,7 @@ void* TRI_Reallocate (TRI_memory_zone_t* zone, void* m, uint64_t n) {
(unsigned long long) n,
zone->_zid
ZONE_DEBUG_PARAMS);
exit(EXIT_FAILURE);
TRI_EXIT_FUNCTION(EXIT_FAILURE, NULL);
}
free(CoreReserve);

View File

@ -41,10 +41,6 @@
/// @{
////////////////////////////////////////////////////////////////////////////////
#define TRI_HAVE_GETGRGID 1
#define TRI_HAVE_GETPWNAM 1
#define TRI_HAVE_GETPWUID 1
#define GLOBAL_TIMEZONE timezone
#ifndef __STDC_LIMIT_MACROS
@ -110,6 +106,11 @@
#define TRI_HAVE_SETGID 1
#define TRI_HAVE_SETUID 1
#define TRI_HAVE_GETGRGID 1
#define TRI_HAVE_GETPWNAM 1
#define TRI_HAVE_GETPWUID 1
#define TRI_HAVE_GETGRNAM 1
#define TRI_HAVE_STRTOLL 1
#define TRI_HAVE_STRTOULL 1
@ -332,6 +333,11 @@ typedef int socket_t;
#define TRI_HAVE_SETGID 1
#define TRI_HAVE_SETUID 1
#define TRI_HAVE_GETGRGID 1
#define TRI_HAVE_GETPWNAM 1
#define TRI_HAVE_GETPWUID 1
#define TRI_HAVE_GETGRNAM 1
#define TRI_HAVE_STRTOLL 1
#define TRI_HAVE_STRTOULL 1
@ -395,6 +401,7 @@ typedef int socket_t;
// This directive below suppresses warnings about using the 'new' more secure CRT
// functions.
// ..............................................................................
#define _CRT_SECURE_NO_WARNINGS 1
// ..............................................................................
@ -402,6 +409,7 @@ typedef int socket_t;
// for example, strcpy is automatically converted to strcpy_s. This is enabled
// by default. We have disabled it here.
// ..............................................................................
//#define _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES 1
#include <stdio.h>
@ -479,10 +487,8 @@ typedef unsigned char bool;
#define false 0
#endif
#define va_copy(d,s) ((d) = (s))
// we do not have owner read and owner write under windows
// so map these to global read, global write
// these are used when creating a file
@ -516,6 +522,7 @@ typedef unsigned char bool;
// security identifiers (SID) which is a variable length structure
// which can (should) not be accessed directly.
// ...........................................................................
#define TRI_uid_t void*
#define TRI_gid_t void*
@ -523,11 +530,13 @@ typedef unsigned char bool;
// windows does not like the keyword inline -- but only if it uses the c compiler
// weird. _inline should work for both I hope
// ...........................................................................
#define inline _inline
// ...........................................................................
// windows uses _alloca instead of alloca
// ...........................................................................
#define alloca _alloca
@ -537,7 +546,6 @@ typedef SOCKET socket_t;
#define STDOUT_FILENO 1;
#define STDERR_FILENO 2;
#endif
////////////////////////////////////////////////////////////////////////////////

View File

@ -27,6 +27,10 @@
#include "process-utils.h"
#ifdef TRI_HAVE_SYS_PRCTL_H
#include <sys/prctl.h>
#endif
#include "BasicsC/strings.h"
#include "BasicsC/logging.h"
@ -145,7 +149,17 @@ static char** ARGV = 0;
/// @brief true, if environment has been copied already
////////////////////////////////////////////////////////////////////////////////
#ifdef TRI_TAMPER_WITH_ENVIRON
static bool IsEnvironmentEnlarged = false;
#endif
////////////////////////////////////////////////////////////////////////////////
/// @brief do we need to free the copy of the environ data on shutdown
////////////////////////////////////////////////////////////////////////////////
#ifdef TRI_TAMPER_WITH_ENVIRON
static bool MustFreeEnvironment = false;
#endif
////////////////////////////////////////////////////////////////////////////////
/// @brief maximal size of the process title
@ -153,12 +167,6 @@ static bool IsEnvironmentEnlarged = false;
static size_t MaximalProcessTitleSize = 0;
////////////////////////////////////////////////////////////////////////////////
/// @brief do we need to free the copy of the environ data on shutdown
////////////////////////////////////////////////////////////////////////////////
static bool MustFreeEnvironment = false;
////////////////////////////////////////////////////////////////////////////////
/// @}
////////////////////////////////////////////////////////////////////////////////
@ -322,8 +330,11 @@ uint64_t TRI_ProcessSize (TRI_pid_t pid) {
extern char** environ;
void TRI_SetProcessTitle (char const* title) {
#if TRI_TAMPER_WITH_ENVIRON
if (! IsEnvironmentEnlarged) {
size_t size;
int envLen = -1;
if (environ) {
@ -358,12 +369,22 @@ void TRI_SetProcessTitle (char const* title) {
MaximalProcessTitleSize = size;
}
#else
MaximalProcessTitleSize = ARGV[ARGC - 1] + strlen(ARGV[ARGC - 1]) - ARGV[0];
#endif
if (0 < MaximalProcessTitleSize) {
char* args = ARGV[0];
memset(args, '\0', MaximalProcessTitleSize);
snprintf(args, MaximalProcessTitleSize - 1, "%s", title);
}
#ifdef TRI_HAVE_SYS_PRCTL_H
prctl(PR_SET_NAME, title, 0, 0, 0);
#endif
}
////////////////////////////////////////////////////////////////////////////////
@ -404,6 +425,7 @@ void TRI_InitialiseProcess (int argc, char* argv[]) {
void TRI_ShutdownProcess () {
TRI_FreeString(TRI_CORE_MEM_ZONE, ProcessName);
#ifdef TRI_TAMPER_WITH_ENVIRON
if (MustFreeEnvironment) {
size_t i = 0;
@ -416,6 +438,7 @@ void TRI_ShutdownProcess () {
}
TRI_Free(TRI_CORE_MEM_ZONE, environ);
}
#endif
}
////////////////////////////////////////////////////////////////////////////////

View File

@ -58,7 +58,7 @@ static size_t Remaining (TRI_string_buffer_t * self) {
/// @brief reserve space
////////////////////////////////////////////////////////////////////////////////
static int Reserve (TRI_string_buffer_t * self, size_t size) {
static int Reserve (TRI_string_buffer_t * self, const size_t size) {
char* ptr;
if (size < 1) {
@ -214,6 +214,14 @@ void TRI_FreeStringBuffer (TRI_memory_zone_t* zone, TRI_string_buffer_t * self)
/// @{
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
/// @brief ensure the string buffer has a specific capacity
////////////////////////////////////////////////////////////////////////////////
int TRI_ReserveStringBuffer (TRI_string_buffer_t* self, const size_t length) {
return Reserve(self, length);
}
////////////////////////////////////////////////////////////////////////////////
/// @brief swaps content with another string buffer
////////////////////////////////////////////////////////////////////////////////

View File

@ -134,6 +134,12 @@ void TRI_FreeStringBuffer (TRI_memory_zone_t*, TRI_string_buffer_t *);
/// @{
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
/// @brief ensure the string buffer has a specific capacity
////////////////////////////////////////////////////////////////////////////////
int TRI_ReserveStringBuffer (TRI_string_buffer_t* self, const size_t length);
////////////////////////////////////////////////////////////////////////////////
/// @brief swaps content with another string buffer
////////////////////////////////////////////////////////////////////////////////

View File

@ -77,7 +77,7 @@ bool MRLoader::loadScript (mrb_state* mrb, string const& name) {
map<string, string>::iterator i = _scripts.find(name);
if (i == _scripts.end()) {
LOGGER_ERROR << "unknown script '" << name << "'";
LOGGER_ERROR("unknown script '" << name << "'");
return false;
}

View File

@ -58,14 +58,24 @@ using namespace triagens::rest;
/// @{
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
/// @brief writes a pid file
////////////////////////////////////////////////////////////////////////////////
#ifdef TRI_HAVE_FORK
static void WritePidFile (string const& pidFile, int pid) {
ofstream out(pidFile.c_str(), ios::trunc);
if (! out) {
LOGGER_FATAL_AND_EXIT("cannot write pid-file \"" << pidFile << "\"\n");
}
out << pid;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief checks a pid file
////////////////////////////////////////////////////////////////////////////////
static void CheckPidFile (string const& pidFile) {
// check if the pid-file exists
@ -90,7 +100,12 @@ static void CheckPidFile (string const& pidFile) {
LOGGER_DEBUG("found old pid: " << oldPid);
#ifdef TRI_HAVE_FORK
int r = kill(oldPid, 0);
#else
int r = 0; // TODO for windows use TerminateProcess
#endif
if (r == 0) {
LOGGER_FATAL_AND_EXIT("pid-file '" << pidFile << "' exists and process with pid " << oldPid << " is still running");
}
@ -121,25 +136,13 @@ static void CheckPidFile (string const& pidFile) {
}
}
////////////////////////////////////////////////////////////////////////////////
/// @brief writes a pid file
////////////////////////////////////////////////////////////////////////////////
static void WritePidFile (string const& pidFile, int pid) {
ofstream out(pidFile.c_str(), ios::trunc);
if (! out) {
LOGGER_FATAL_AND_EXIT("cannot write pid-file \"" << pidFile << "\"\n");
}
out << pid;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief forks a new process
////////////////////////////////////////////////////////////////////////////////
static int forkProcess (string const& workingDirectory, string& current, ApplicationServer* applicationServer) {
#ifdef TRI_HAVE_FORK
static int forkProcess (string const& workingDirectory, string& current) {
// fork off the parent process
TRI_pid_t pid = fork();
@ -157,10 +160,6 @@ static int forkProcess (string const& workingDirectory, string& current, Applica
return pid;
}
// reset the logging
TRI_InitialiseLogging(TRI_ShutdownLogging());
applicationServer->setupLogging();
// change the file mode mask
umask(0);
@ -185,7 +184,7 @@ static int forkProcess (string const& workingDirectory, string& current, Applica
LOGGER_FATAL_AND_EXIT("cannot change into working directory '" << workingDirectory << "'");
}
else {
LOGGER_INFO("changed into working directory '" << workingDirectory << "'");
LOGGER_INFO("changed working directory for child process to '" << workingDirectory << "'");
}
}
@ -195,91 +194,11 @@ static int forkProcess (string const& workingDirectory, string& current, Applica
#else
////////////////////////////////////////////////////////////////////////////////
/// @brief checks a pid file
////////////////////////////////////////////////////////////////////////////////
static void CheckPidFile (string const& pidFile) {
// check if the pid-file exists
if (! pidFile.empty()) {
if (FileUtils::isDirectory(pidFile)) {
LOGGER_FATAL_AND_EXIT("pid-file '" << pidFile << "' is a directory");
}
else if (FileUtils::exists(pidFile) && FileUtils::size(pidFile) > 0) {
LOGGER_INFO("pid-file '" << pidFile << "' already exists, verifying pid");
ifstream f(pidFile.c_str());
// file can be opened
if (f) {
TRI_pid_t oldPid;
f >> oldPid;
if (oldPid == 0) {
LOGGER_FATAL_AND_EXIT("pid-file '" << pidFile << "' is unreadable");
}
LOGGER_DEBUG("found old pid: " << oldPid);
int r = 0;
// for windows use TerminateProcess
//int r = kill(oldPid, 0);
if (r == 0) {
LOGGER_FATAL_AND_EXIT("pid-file '" << pidFile << "' exists and process with pid " << oldPid << " is still running");
}
else if (errno == EPERM) {
LOGGER_FATAL_AND_EXIT("pid-file '" << pidFile << "' exists and process with pid " << oldPid << " is still running");
}
else if (errno == ESRCH) {
LOGGER_ERROR("pid-file '" << pidFile << "' exists, but no process with pid " << oldPid << " exists");
if (! FileUtils::remove(pidFile)) {
LOGGER_FATAL_AND_EXIT("pid-file '" << pidFile << "' exists, no process with pid " << oldPid << " exists, but pid-file cannot be removed");
}
LOGGER_INFO("removed stale pid-file '" << pidFile << "'");
}
else {
LOGGER_FATAL_AND_EXIT("pid-file '" << pidFile << "' exists and kill " << oldPid << " failed");
}
}
// failed to open file
else {
LOGGER_FATAL_AND_EXIT("pid-file '" << pidFile << "' exists, but cannot be opened");
}
}
LOGGER_DEBUG("using pid-file '" << pidFile << "'");
}
}
////////////////////////////////////////////////////////////////////////////////
/// @brief writes a pid file
////////////////////////////////////////////////////////////////////////////////
static void WritePidFile (string const& pidFile, int pid) {
ofstream out(pidFile.c_str(), ios::trunc);
if (! out) {
LOGGER_FATAL_AND_EXIT << "cannot write pid-file \"" << pidFile << "\"";
}
out << pid;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief forks a new process
////////////////////////////////////////////////////////////////////////////////
// ..............................................................................
// TODO: use windows API CreateProcess & CreateThread to minic fork()
// ..............................................................................
static int forkProcess (string const& workingDirectory, string& current, ApplicationServer* applicationServer) {
static int forkProcess (string const& workingDirectory, string& current) {
// fork off the parent process
TRI_pid_t pid = -1; // fork();
@ -346,7 +265,6 @@ AnyServer::~AnyServer () {
////////////////////////////////////////////////////////////////////////////////
int AnyServer::start () {
if (_applicationServer == 0) {
buildApplicationServer();
}
@ -358,6 +276,8 @@ int AnyServer::start () {
return startupDaemon();
}
else {
_applicationServer->setupLogging(true, false);
if (! _pidFile.empty()) {
CheckPidFile(_pidFile);
WritePidFile(_pidFile, TRI_CurrentProcessId());
@ -421,8 +341,10 @@ int AnyServer::startupSupervisor () {
CheckPidFile(_pidFile);
_applicationServer->setupLogging(false, true);
string current;
int result = forkProcess(_workingDirectory, current, safe_cast<ApplicationServer*>(_applicationServer));
int result = forkProcess(_workingDirectory, current);
// main process
if (result != 0) {
@ -442,18 +364,13 @@ int AnyServer::startupSupervisor () {
TRI_pid_t pid = fork();
if (pid < 0) {
exit(EXIT_FAILURE);
TRI_EXIT_FUNCTION(EXIT_FAILURE, NULL);
}
// parent
if (0 < pid) {
char const* title = "arangodb [supervisor]";
TRI_SetProcessTitle(title);
#ifdef TRI_HAVE_SYS_PRCTL_H
prctl(PR_SET_NAME, title, 0, 0, 0);
#endif
_applicationServer->setupLogging(false, true);
TRI_SetProcessTitle("arangodb [supervisor]");
int status;
waitpid(pid, &status, 0);
@ -523,14 +440,11 @@ int AnyServer::startupSupervisor () {
// child
else {
_applicationServer->setupLogging(true, false);
// write the pid file
WritePidFile(_pidFile, TRI_CurrentProcessId());
// reset logging
TRI_InitialiseLogging(TRI_ShutdownLogging());
safe_cast<ApplicationServer*>(_applicationServer)->setupLogging();
// force child to stop if supervisor dies
#ifdef TRI_HAVE_PRCTL
prctl(PR_SET_PDEATHSIG, SIGTERM, 0, 0, 0);
@ -546,7 +460,7 @@ int AnyServer::startupSupervisor () {
}
// and stop
exit(result);
TRI_EXIT_FUNCTION(result, NULL);
}
}
}
@ -563,20 +477,20 @@ int AnyServer::startupDaemon () {
CheckPidFile(_pidFile);
_applicationServer->setupLogging(false, true);
string current;
int result = forkProcess(_workingDirectory, current, safe_cast<ApplicationServer*>(_applicationServer));
int result = forkProcess(_workingDirectory, current);
// main process
if (result != 0) {
#ifdef TRI_HAVE_SYS_PRCTL_H
prctl(PR_SET_NAME, "arangodb [daemon]", 0, 0, 0);
#endif
TRI_SetProcessTitle("arangodb [daemon]");
WritePidFile(_pidFile, result);
}
// child process
else {
_applicationServer->setupLogging(true, false);
// and startup server
prepareServer();
@ -609,5 +523,5 @@ int AnyServer::startupDaemon () {
// Local Variables:
// mode: outline-minor
// outline-regexp: "^\\(/// @brief\\|/// {@inheritDoc}\\|/// @addtogroup\\|// --SECTION--\\|/// @\\}\\)"
// outline-regexp: "^/// @brief\\|/// {@inheritDoc}\\|/// @addtogroup\\|// --SECTION--\\|/// @\\}"
// End:

View File

@ -540,6 +540,7 @@ HttpRequest::HttpRequestType HttpRequest::getRequestType (const char* ptr, const
void HttpRequest::parseHeader (char* ptr, size_t length) {
char* start = ptr;
char* end = start + length;
const size_t versionLength = strlen("http/1.x");
// current line number
int lineNum = 0;
@ -628,7 +629,7 @@ void HttpRequest::parseHeader (char* ptr, size_t length) {
++e;
}
if ((size_t)(end - e) > strlen("http/1.x")) {
if ((size_t)(end - e) > versionLength) {
if ((e[0] == 'h' || e[0] == 'H') &&
(e[1] == 't' || e[1] == 'T') &&
(e[2] == 't' || e[2] == 'T') &&
@ -643,7 +644,7 @@ void HttpRequest::parseHeader (char* ptr, size_t length) {
_version = HTTP_1_0;
}
e += strlen("http/1.x");
e += versionLength;
}
}

View File

@ -113,8 +113,7 @@ static SignalTask* localSignalTask;
_server->beginShutdown();
}
else {
LOGGER_INFO("control-c received, terminating");
exit(EXIT_FAILURE);
LOGGER_FATAL_AND_EXIT("control-c received again, terminating");
}
++_seen;
@ -440,7 +439,7 @@ bool ApplicationScheduler::parsePhase1 (triagens::basics::ProgramOptions& option
// show io backends
if (options.has("show-io-backends")) {
cout << "available io backends are: " << SchedulerLibev::availableBackends() << endl;
exit(EXIT_SUCCESS);
TRI_EXIT_FUNCTION(EXIT_SUCCESS, NULL);
}
return true;