Esempio n. 1
0
TRI_query_node_t* TRI_ParseQueryContextPop (TRI_query_template_t* const template_) {
  TRI_query_node_t* head;
  size_t i;

  i = template_->_memory._listHeads._length;

  if (i > 0) {
    TRI_RemoveVectorPointer(&template_->_memory._listTails, i - 1);
    head = TRI_RemoveVectorPointer(&template_->_memory._listHeads, i - 1);
    return head;
  } 

  return 0;
}
Esempio n. 2
0
static int RemoveDatafile (TRI_document_collection_t* document,
                           TRI_datafile_t* df) {
  TRI_primary_collection_t* primary;
  TRI_doc_datafile_info_t* dfi;
  size_t i;

  primary = &document->base;

  LOG_TRACE("removing empty datafile '%s'", df->getName(df));
  
  // remove the datafile from the list of datafiles
  TRI_WRITE_LOCK_DATAFILES_DOC_COLLECTION(primary);

  if (! LocateDatafile(&primary->base._datafiles, df->_fid, &i)) {
    TRI_WRITE_UNLOCK_DATAFILES_DOC_COLLECTION(primary);
    
    LOG_ERROR("logic error: could not locate datafile");

    return TRI_ERROR_INTERNAL;
  }
 
  TRI_RemoveVectorPointer(&primary->base._datafiles, i);
  
  // update dfi
  dfi = TRI_FindDatafileInfoPrimaryCollection(primary, df->_fid, false);

  if (dfi != NULL) {
    TRI_RemoveDatafileInfoPrimaryCollection(primary, df->_fid);
    TRI_Free(TRI_UNKNOWN_MEM_ZONE, dfi);
  }

  TRI_WRITE_UNLOCK_DATAFILES_DOC_COLLECTION(primary);

  return TRI_ERROR_NO_ERROR;
}
Esempio n. 3
0
bool TRI_KillExternalProcess (TRI_external_id_t pid) {
  TRI_external_t* external = nullptr;  // just to please the compiler
  size_t i;
  bool ok = true;

  LOG_DEBUG("killing process: %d", (int) pid._pid);

  TRI_LockMutex(&ExternalProcessesLock);

  for (i = 0;  i < ExternalProcesses._length;  ++i) {
    external = static_cast<TRI_external_t*>(TRI_AtVectorPointer(&ExternalProcesses, i));

    if (external->_pid == pid._pid) {
      break;
    }
  }

  if (i == ExternalProcesses._length) {
    TRI_UnlockMutex(&ExternalProcessesLock);
    LOG_DEBUG("kill: process not found: %d", (int) pid._pid);
#ifndef _WIN32
    // Kill just in case:
    if (0 == kill(pid._pid, SIGTERM)) {
      int count;

      // Otherwise we just let it be.
      for (count = 0; count < 10; count++) {
        int loc;
        pid_t p;

        // And wait for it to avoid a zombie:
        sleep(1);
        p = waitpid(pid._pid, &loc, WUNTRACED | WNOHANG);
        if (p == pid._pid) {
          return true;
        }
        if (count == 8) {
          kill(pid._pid, SIGKILL);
        }
      }
    }
    return false;
#else
    return ourKillProcessPID(pid._pid);
#endif
  }

  if (external->_status == TRI_EXT_RUNNING ||
      external->_status == TRI_EXT_STOPPED) {
    ok = ourKillProcess(external);
  }

  TRI_RemoveVectorPointer(&ExternalProcesses, i);
  TRI_UnlockMutex(&ExternalProcessesLock);
  FreeExternal(external);

  return ok;
}
static void RunWalk (TRI_aql_statement_walker_t* const walker) {
    size_t i, n;

    assert(walker);
    n = walker->_statements->_statements._length;

    for (i = 0; i < n; ++i) {
        TRI_aql_node_t* node;
        TRI_aql_node_type_e nodeType;

        node = (TRI_aql_node_t*) TRI_AtVectorPointer(&walker->_statements->_statements, i);

        if (!node) {
            continue;
        }

        nodeType = node->_type;

        // handle scopes
        if (nodeType == TRI_AQL_NODE_SCOPE_START) {
            TRI_PushBackVectorPointer(&walker->_currentScopes, TRI_AQL_NODE_DATA(node));
        }

        // preprocess node
        if (walker->preVisitStatement != NULL) {
            // this might change the node ptr
            VisitStatement(walker, i, walker->preVisitStatement);
            node = walker->_statements->_statements._buffer[i];
        }


        // process node's members
        if (walker->visitMember != NULL) {
            VisitMembers(walker, node);
        }

        // post process node
        if (walker->postVisitStatement != NULL) {
            VisitStatement(walker, i, walker->postVisitStatement);
        }

        if (nodeType == TRI_AQL_NODE_SCOPE_END) {
            size_t len = walker->_currentScopes._length;

            assert(len > 0);
            TRI_RemoveVectorPointer(&walker->_currentScopes, len - 1);
        }
    }
}
Esempio n. 5
0
void TRI_FreeNodeVectorQuery (TRI_vector_pointer_t* const memory) {
  void* nodePtr;
  size_t i;

  i = memory->_length;
  // free all nodes in vector, starting at the end 
  // (prevents copying the remaining elements in vector)
  while (i > 0) {
    i--;
    nodePtr = TRI_RemoveVectorPointer(memory, i);
    TRI_FreeNodeQuery(nodePtr);
    if (i == 0) {
      break;
    }
  }
  TRI_DestroyVectorPointer(memory);
}
static TRI_aql_node_t* FixAttributeAccess (TRI_aql_statement_walker_t* const walker,
                                           TRI_aql_node_t* node) {
  TRI_aql_context_t* context;
  TRI_aql_node_t* valueNode;
  char* stringValue;

  if (node == NULL || 
      node->_type != TRI_AQL_NODE_BOUND_ATTRIBUTE_ACCESS) {
    return node;
  }

  // we found a bound attribute access
  context = (TRI_aql_context_t*) walker->_data;
  assert(context);

  assert(node->_members._length == 2);
  valueNode = TRI_AQL_NODE_MEMBER(node, 1);

  if (valueNode == NULL) {
    TRI_SetErrorContextAql(context, TRI_ERROR_OUT_OF_MEMORY, NULL);
    return node;
  }
  
  if (valueNode->_type != TRI_AQL_NODE_VALUE || valueNode->_value._type != TRI_AQL_TYPE_STRING) {  
    TRI_SetErrorContextAql(context, TRI_ERROR_QUERY_BIND_PARAMETER_TYPE, "(unknown)");
    return node;
  }

  stringValue = TRI_AQL_NODE_STRING(valueNode);

  if (stringValue == NULL || strlen(stringValue) == 0) {
    TRI_SetErrorContextAql(context, TRI_ERROR_QUERY_BIND_PARAMETER_TYPE, "(unknown)");
    return node;
  }

  // remove second node
  TRI_RemoveVectorPointer(&node->_members, 1);

  // set attribute name
  TRI_AQL_NODE_STRING(node) = stringValue;

  // convert node type
  node->_type = TRI_AQL_NODE_ATTRIBUTE_ACCESS;

  return node;
}
Esempio n. 7
0
static int RemoveCompactor (TRI_document_collection_t* document,
                            TRI_datafile_t* compactor) {
  TRI_primary_collection_t* primary;
  size_t i;

  primary = &document->base;

  LOG_TRACE("removing empty compaction file '%s'", compactor->getName(compactor));
  
  // remove the datafile from the list of datafiles
  TRI_WRITE_LOCK_DATAFILES_DOC_COLLECTION(primary);

  // remove the compactor from the list of compactors
  if (! LocateDatafile(&primary->base._compactors, compactor->_fid, &i)) {
    TRI_WRITE_UNLOCK_DATAFILES_DOC_COLLECTION(primary);
    
    LOG_ERROR("logic error: could not locate compactor");

    return TRI_ERROR_INTERNAL;
  }
    
  TRI_RemoveVectorPointer(&primary->base._compactors, i);

  TRI_WRITE_UNLOCK_DATAFILES_DOC_COLLECTION(primary);


  // close the file & remove it
  if (compactor->isPhysical(compactor)) {
    char* filename;

    filename = TRI_DuplicateString(compactor->getName(compactor));
    TRI_CloseDatafile(compactor);
    TRI_FreeDatafile(compactor);

    TRI_UnlinkFile(filename);
    TRI_Free(TRI_CORE_MEM_ZONE, filename);
  }
  else {
    TRI_CloseDatafile(compactor);
    TRI_FreeDatafile(compactor);
  }

  return TRI_ERROR_NO_ERROR;
}
Esempio n. 8
0
void TRI_FreeStringVectorQuery (TRI_vector_pointer_t* const memory) {
  char* stringPtr;
  size_t i;

  i = memory->_length;
  // free all strings in vector, starting at the end 
  // (prevents copying the remaining elements in vector)
  while (i > 0) {
    i--;
    stringPtr = TRI_RemoveVectorPointer(memory, i);
    if (stringPtr) {
      TRI_Free(stringPtr);
      stringPtr = NULL;
    }
    if (i == 0) {
      break;
    }
  }
  TRI_DestroyVectorPointer(memory);
}
Esempio n. 9
0
bool TRI_EndScopeByReturnAql (TRI_aql_context_t* const context) {
  TRI_aql_scope_e type;
  TRI_aql_node_t* node;
  size_t n;

  assert(context);
  type = CurrentType(context);

  if (type == TRI_AQL_SCOPE_MAIN || type == TRI_AQL_SCOPE_SUBQUERY) {
    return true;
  }

  n = context->_currentScopes._length;
  assert(n > 0);

  while (n > 0) {
    TRI_aql_scope_t* scope;

    scope = (TRI_aql_scope_t*) TRI_RemoveVectorPointer(&context->_currentScopes, --n);
    assert(scope);

    LOG_TRACE("closing scope of type %s", TRI_TypeNameScopeAql(scope->_type));

    node = TRI_CreateNodeScopeEndAql(context, scope);
    if (node == NULL) {
      return false;
    }

    if (! TRI_AppendStatementListAql(context->_statements, node)) {
      return false;
    }

    if (scope->_type != TRI_AQL_SCOPE_FOR_NESTED) {
      // removed enough scopes
      break;
    }
  }

  return true;
}
Esempio n. 10
0
static TRI_aql_node_t* OptimiseSort (TRI_aql_statement_walker_t* const walker,
                                     TRI_aql_node_t* node) {
  TRI_aql_node_t* list = TRI_AQL_NODE_MEMBER(node, 0);
  size_t i, n;
    
  if (!list) {
    return node;
  }

  i = 0;
  n = list->_members._length;
  while (i < n) {
    // sort element
    TRI_aql_node_t* element = TRI_AQL_NODE_MEMBER(list, i);
    TRI_aql_node_t* expression = TRI_AQL_NODE_MEMBER(element, 0);

    // check if the sort element is constant
    if (!expression || !TRI_IsConstantValueNodeAql(expression)) {
      ++i;
      continue;
    }

    // sort element is constant so it can be removed
    TRI_RemoveVectorPointer(&list->_members, i);
    --n;

    LOG_TRACE("optimised away sort element");
  }

  if (n == 0) {
    // no members left => sort removed
    LOG_TRACE("optimised away sort");

    return TRI_GetDummyNopNodeAql();
  }

  return node;
}
Esempio n. 11
0
bool TRI_EndScopeAql (TRI_aql_context_t* const context) {
  TRI_aql_scope_t* scope;
  TRI_aql_node_t* node;
  size_t n;

  assert(context);

  n = context->_currentScopes._length;
  assert(n > 0);

  scope = TRI_RemoveVectorPointer(&context->_currentScopes, --n);
  LOG_TRACE("closing scope of type %s", TRI_TypeNameScopeAql(scope->_type));

  node = TRI_CreateNodeScopeEndAql(context, scope);
  if (node == NULL) {
    return false;
  }

  if (! TRI_AppendStatementListAql(context->_statements, node)) {
    return false;
  }

  return true;
}
Esempio n. 12
0
static void RenameDatafileCallback (TRI_datafile_t* datafile,  
                                    void* data) {
  compaction_context_t* context;
  TRI_datafile_t* compactor;
  TRI_primary_collection_t* primary;
  bool ok;
   
  context = data;
  compactor = context->_compactor;
  primary = &context->_document->base;

  ok = false;
  assert(datafile->_fid == compactor->_fid);

  if (datafile->isPhysical(datafile)) {
    char* number;
    char* jname;
    char* tempFilename;
    char* realName;

    realName     = TRI_DuplicateString(datafile->_filename);
    
    // construct a suitable tempname
    number       = TRI_StringUInt64(datafile->_fid);
    jname        = TRI_Concatenate3String("temp-", number, ".db");
    tempFilename = TRI_Concatenate2File(primary->base._directory, jname);

    TRI_FreeString(TRI_CORE_MEM_ZONE, number);
    TRI_FreeString(TRI_CORE_MEM_ZONE, jname);

    if (! TRI_RenameDatafile(datafile, tempFilename)) {
      LOG_ERROR("unable to rename datafile '%s' to '%s'", datafile->getName(datafile), tempFilename);
    }
    else {
      if (! TRI_RenameDatafile(compactor, realName)) {
        LOG_ERROR("unable to rename compaction file '%s' to '%s'", compactor->getName(compactor), realName);
      }
      else {
        ok = true;
      }
    }

    TRI_FreeString(TRI_CORE_MEM_ZONE, tempFilename);
    TRI_FreeString(TRI_CORE_MEM_ZONE, realName);
  }
  else {
    ok = true;
  }

  if (ok) {
    TRI_doc_datafile_info_t* dfi;
    size_t i;
   
    // must acquire a write-lock as we're about to change the datafiles vector 
    TRI_WRITE_LOCK_DATAFILES_DOC_COLLECTION(primary);

    if (! LocateDatafile(&primary->base._datafiles, datafile->_fid, &i)) {
      TRI_WRITE_UNLOCK_DATAFILES_DOC_COLLECTION(primary);

      LOG_ERROR("logic error: could not locate datafile");

      return;
    }

    // put the compactor in place of the datafile
    primary->base._datafiles._buffer[i] = compactor;

    // update dfi
    dfi = TRI_FindDatafileInfoPrimaryCollection(primary, compactor->_fid, false);

    if (dfi != NULL) {
      memcpy(dfi, &context->_dfi, sizeof(TRI_doc_datafile_info_t));
    }
    else {
      LOG_ERROR("logic error: could not find compactor file information");
    }

    if (! LocateDatafile(&primary->base._compactors, compactor->_fid, &i)) {
      TRI_WRITE_UNLOCK_DATAFILES_DOC_COLLECTION(primary);
   
      LOG_ERROR("logic error: could not locate compactor");

      return;
    }

    // remove the compactor from the list of compactors
    TRI_RemoveVectorPointer(&primary->base._compactors, i);
          
    TRI_WRITE_UNLOCK_DATAFILES_DOC_COLLECTION(primary);

    DropDatafileCallback(datafile, primary);
  }

  TRI_Free(TRI_CORE_MEM_ZONE, context);
}
Esempio n. 13
0
static void CompactifyDatafile (TRI_sim_collection_t* sim, TRI_voc_fid_t fid) {
  TRI_datafile_t* df;
  bool ok;
  size_t n;
  size_t i;

  // locate the datafile
  TRI_READ_LOCK_DATAFILES_SIM_COLLECTION(sim);

  n = sim->base.base._datafiles._length;

  for (i = 0;  i < n;  ++i) {
    df = sim->base.base._datafiles._buffer[i];

    if (df->_fid == fid) {
      break;
    }
  }

  TRI_READ_UNLOCK_DATAFILES_SIM_COLLECTION(sim);

  if (i == n) {
    return;
  }

  // now compactify the datafile
  LOG_DEBUG("starting to compactify datafile '%s'", df->_filename);

  ok = TRI_IterateDatafile(df, Compactifier, sim, false);

  if (! ok) {
    LOG_WARNING("failed to compactify the datafile '%s'", df->_filename);
    return;
  }

  // wait for the journals to sync
  WaitCompactSync(sim, df);

  // remove the datafile from the list of datafiles
  TRI_WRITE_LOCK_DATAFILES_SIM_COLLECTION(sim);

  n = sim->base.base._datafiles._length;

  for (i = 0;  i < n;  ++i) {
    df = sim->base.base._datafiles._buffer[i];

    if (df->_fid == fid) {
      TRI_RemoveVectorPointer(&sim->base.base._datafiles, i);
      break;
    }
  }

  TRI_WRITE_UNLOCK_DATAFILES_SIM_COLLECTION(sim);

  if (i == n) {
    LOG_WARNING("failed to locate the datafile '%lu'", (unsigned long) df->_fid);
    return;
  }

  // add a deletion marker to the result set container
  TRI_CreateBarrierDatafile(&sim->base._barrierList, df, RemoveDatafileCallback, &sim->base.base);
}
void* TRI_PopStackParseAql (TRI_aql_context_t* const context) {
  assert(context);
  assert(context->_parser->_stack._length > 0);

  return TRI_RemoveVectorPointer(&context->_parser->_stack, context->_parser->_stack._length - 1);
}
Esempio n. 15
0
static bool CloseJournalPrimaryCollection (TRI_primary_collection_t* primary,
                                           size_t position,
                                           bool compactor) {
  TRI_datafile_t* journal;
  TRI_collection_t* collection;
  TRI_vector_pointer_t* vector;
  int res;

  collection = &primary->base;

  // either use a journal or a compactor
  if (compactor) {
    vector = &collection->_compactors;
  }
  else {
    vector = &collection->_journals;
  }

  // no journal at this position
  if (vector->_length <= position) {
    TRI_set_errno(TRI_ERROR_ARANGO_NO_JOURNAL);
    return false;
  }

  // seal and rename datafile
  journal = vector->_buffer[position];
  res = TRI_SealDatafile(journal);

  if (res != TRI_ERROR_NO_ERROR) {
    LOG_ERROR("failed to seal datafile '%s': %s", journal->getName(journal), TRI_last_error());

    TRI_RemoveVectorPointer(vector, position);
    TRI_PushBackVectorPointer(&collection->_datafiles, journal);

    return false;
  }

  if (journal->isPhysical(journal)) {
    // rename the file
    char* dname;
    char* filename;
    char* number;
    bool ok;

    number = TRI_StringUInt64(journal->_fid);
    dname = TRI_Concatenate3String("datafile-", number, ".db");
    filename = TRI_Concatenate2File(collection->_directory, dname);

    TRI_FreeString(TRI_CORE_MEM_ZONE, dname);
    TRI_FreeString(TRI_CORE_MEM_ZONE, number);

    ok = TRI_RenameDatafile(journal, filename);

    if (! ok) {
      LOG_ERROR("failed to rename datafile '%s' to '%s': %s", journal->getName(journal), filename, TRI_last_error());

      TRI_RemoveVectorPointer(vector, position);
      TRI_PushBackVectorPointer(&collection->_datafiles, journal);
      TRI_FreeString(TRI_CORE_MEM_ZONE, filename);

      return false;
    }

    TRI_FreeString(TRI_CORE_MEM_ZONE, filename);

    LOG_TRACE("closed journal '%s'", journal->getName(journal));
  }

  TRI_RemoveVectorPointer(vector, position);
  TRI_PushBackVectorPointer(&collection->_datafiles, journal);

  return true;
}
Esempio n. 16
0
TRI_external_status_t TRI_CheckExternalProcess (TRI_external_id_t pid,
                                                bool wait) {
  TRI_external_status_t status;
  TRI_external_t* external = nullptr;  // Just to please the compiler
  size_t i;
  
  TRI_LockMutex(&ExternalProcessesLock);

  status._status = TRI_EXT_NOT_FOUND;
  status._exitStatus = 0;

  for (i = 0;  i < ExternalProcesses._length;  ++i) {
    external = static_cast<TRI_external_t*>(TRI_AtVectorPointer(&ExternalProcesses, i));

    if (external->_pid == pid._pid) {
      break;
    }
  }

  if (i == ExternalProcesses._length) {
    TRI_UnlockMutex(&ExternalProcessesLock);
    status._errorMessage =
      std::string("the pid you're looking for is not in our list: ") + 
      triagens::basics::StringUtils::itoa(static_cast<int64_t>(pid._pid));
    status._status = TRI_EXT_NOT_FOUND;
    LOG_WARNING("checkExternal: pid not found: %d", (int) pid._pid);

    return status;
  }

  if (external->_status == TRI_EXT_RUNNING ||
      external->_status == TRI_EXT_STOPPED) {
#ifndef _WIN32
    TRI_pid_t res;
    int opts;
    int loc = 0;

    if (wait) {
      opts = WUNTRACED;
    }
    else {
      opts = WNOHANG | WUNTRACED;
    }

    res = waitpid(external->_pid, &loc, opts);

    if (res == 0) {
      if (wait) {
        status._errorMessage =
          std::string("waitpid returned 0 for pid while it shouldn't ") + 
          triagens::basics::StringUtils::itoa(external->_pid);

        if (WIFEXITED(loc)) {
          external->_status = TRI_EXT_TERMINATED;
          external->_exitStatus = WEXITSTATUS(loc);
        }
        else if (WIFSIGNALED(loc)) {
          external->_status = TRI_EXT_ABORTED;
          external->_exitStatus = WTERMSIG(loc);
        }
        else if (WIFSTOPPED(loc)) {
          external->_status = TRI_EXT_STOPPED;
          external->_exitStatus = 0;
        }
        else {
          external->_status = TRI_EXT_ABORTED;
          external->_exitStatus = 0;
        }
      }
      else {
        external->_exitStatus = 0;
      }
    }
    else if (res == -1) {
      TRI_set_errno(TRI_ERROR_SYS_ERROR);
      LOG_WARNING("waitpid returned error for pid %d (%d): %s", 
                  (int) external->_pid,  
                  (int) wait,
                  TRI_last_error());
      status._errorMessage =
        std::string("waitpid returned error for pid ") + 
        triagens::basics::StringUtils::itoa(external->_pid) + 
        std::string(": ") +        
        std::string(TRI_last_error());
    }
    else if (static_cast<TRI_pid_t>(external->_pid) == static_cast<TRI_pid_t>(res)) {
      if (WIFEXITED(loc)) {
        external->_status = TRI_EXT_TERMINATED;
        external->_exitStatus = WEXITSTATUS(loc);
      }
      else if (WIFSIGNALED(loc)) {
        external->_status = TRI_EXT_ABORTED;
        external->_exitStatus = WTERMSIG(loc);
      }
      else if (WIFSTOPPED(loc)) {
        external->_status = TRI_EXT_STOPPED;
        external->_exitStatus = 0;
      }
      else {
        external->_status = TRI_EXT_ABORTED;
        external->_exitStatus = 0;
      }
    }
    else {
      LOG_WARNING("unexpected waitpid result for pid %d: %d", 
                  (int) external->_pid, 
                  (int) res);
      status._errorMessage =
        std::string("unexpected waitpid result for pid ") + 
        triagens::basics::StringUtils::itoa(external->_pid) + 
        std::string(": ") +
        triagens::basics::StringUtils::itoa(res);
    }
#else
    {
      char windowsErrorBuf[256];
      bool wantGetExitCode = wait;
      if (wait) {
        DWORD result;
        result = WaitForSingleObject(external->_process, INFINITE);
        if (result == WAIT_FAILED) {
          FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM,
                        NULL,
                        GetLastError(),
                        0,
                        windowsErrorBuf,
                        sizeof(windowsErrorBuf), NULL);
          LOG_WARNING("could not wait for subprocess with PID '%ud': %s",
                      (unsigned int) external->_pid, windowsErrorBuf);
          status._errorMessage =
            std::string("could not wait for subprocess with PID '") + 
            triagens::basics::StringUtils::itoa(static_cast<int64_t>(external->_pid)) + 
            std::string("'") + 
            windowsErrorBuf;
          status._exitStatus = GetLastError();
        }
      }
      else {
        DWORD result;
        result = WaitForSingleObject(external->_process, 0);
        switch (result) {
        case WAIT_ABANDONED:
          wantGetExitCode = true;
          LOG_WARNING("WAIT_ABANDONED while waiting for subprocess with PID '%ud'",
                      (unsigned int)external->_pid);
          break;
        case WAIT_OBJECT_0:
          /// this seems to be the exit case - want getExitCodeProcess here.
          wantGetExitCode = true;
          break;
        case WAIT_TIMEOUT:
          // success - everything went well.
          external->_exitStatus = 0;
          break;
        case WAIT_FAILED:
          FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM,
                        NULL,
                        GetLastError(),
                        0,
                        windowsErrorBuf,
                        sizeof(windowsErrorBuf), NULL);
          LOG_WARNING("could not wait for subprocess with PID '%ud': %s",
                      (unsigned int)external->_pid, windowsErrorBuf);
          status._errorMessage =
            std::string("could not wait for subprocess with PID '") +
            triagens::basics::StringUtils::itoa(static_cast<int64_t>(external->_pid)) +
            std::string("'") +
            windowsErrorBuf;
          status._exitStatus = GetLastError();
        default:
          wantGetExitCode = true;
          LOG_WARNING("unexpected status while waiting for subprocess with PID '%ud'",
                      (unsigned int)external->_pid);

        }
      }
      if (wantGetExitCode) {
        DWORD exitCode = STILL_ACTIVE;
        if (!GetExitCodeProcess(external->_process, &exitCode)) {
          LOG_WARNING("exit status could not be determined for PID '%ud'",
                      (unsigned int)external->_pid);
          status._errorMessage =
            std::string("exit status could not be determined for PID '") +
            triagens::basics::StringUtils::itoa(static_cast<int64_t>(external->_pid)) +
            std::string("'");
        }
        else {
          if (exitCode == STILL_ACTIVE) {
            external->_exitStatus = 0;
          }
          else if (exitCode > 255) {
            // this should be one of our signals which we mapped...
            external->_status = TRI_EXT_ABORTED;
            external->_exitStatus = exitCode - 255;            
          }
          else {
            external->_status = TRI_EXT_TERMINATED;
            external->_exitStatus = exitCode;
          }
        }
      }
      else
      {
        external->_status = TRI_EXT_RUNNING;
      }
    }
#endif
  }
  else {
    LOG_WARNING("unexpected process status %d: %d", 
                (int) external->_status, 
                (int) external->_exitStatus);
    status._errorMessage =
      std::string("unexpected process status ") + 
      triagens::basics::StringUtils::itoa(external->_status) + 
      std::string(": ") +
      triagens::basics::StringUtils::itoa(external->_exitStatus);
  }

  status._status = external->_status;
  status._exitStatus = external->_exitStatus;

  // Do we have to free our data?
  if (external->_status != TRI_EXT_RUNNING &&
      external->_status != TRI_EXT_STOPPED) {
    TRI_RemoveVectorPointer(&ExternalProcesses, i);
    FreeExternal(external);
  }

  TRI_UnlockMutex(&ExternalProcessesLock);
  return status;
}
Esempio n. 17
0
static bool CloseJournal (TRI_shape_collection_t* collection, TRI_datafile_t* journal) {
  int res;
  size_t i;
  size_t n;

  // remove datafile from list of journals
  n = collection->base._journals._length;

  for (i = 0;  i < n;  ++i) {
    TRI_datafile_t* df;

    df = collection->base._journals._buffer[i];

    if (journal == df) {
      break;
    }
  }

  if (i == n) {
    TRI_set_errno(TRI_ERROR_ARANGO_NO_JOURNAL);
    return false;
  }

  // seal datafile
  res = TRI_SealDatafile(journal);

  if (res != TRI_ERROR_NO_ERROR) {
    collection->base._state = TRI_COL_STATE_WRITE_ERROR;
    return false;
  }

  // rename datafile
  if (journal->isPhysical(journal)) {
    char* dname;
    char* filename;
    char* number;
    bool ok;

    number = TRI_StringUInt32(journal->_fid);
    dname = TRI_Concatenate3String("datafile-", number, ".db");
    filename = TRI_Concatenate2File(collection->base._directory, dname);

    TRI_FreeString(TRI_CORE_MEM_ZONE, dname);
    TRI_FreeString(TRI_CORE_MEM_ZONE, number);

    ok = TRI_RenameDatafile(journal, filename);
    TRI_FreeString(TRI_CORE_MEM_ZONE, filename);

    if (! ok) {
      collection->base._state = TRI_COL_STATE_WRITE_ERROR;
      return false;
    }
  }

  LOG_TRACE("closed journal '%s'", journal->getName(journal));

  TRI_RemoveVectorPointer(&collection->base._journals, i);
  TRI_PushBackVectorPointer(&collection->base._datafiles, journal);

  return true;
}