Blame source/uds/indexSession.c

Packit Service 310c69
/*
Packit Service 310c69
 * %Copyright%
Packit Service 310c69
 *
Packit Service 310c69
 * This program is free software; you can redistribute it and/or
Packit Service 310c69
 * modify it under the terms of the GNU General Public License
Packit Service 310c69
 * as published by the Free Software Foundation; either version 2
Packit Service 310c69
 * of the License, or (at your option) any later version.
Packit Service 310c69
 * 
Packit Service 310c69
 * This program is distributed in the hope that it will be useful,
Packit Service 310c69
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit Service 310c69
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
Packit Service 310c69
 * GNU General Public License for more details.
Packit Service 310c69
 * 
Packit Service 310c69
 * You should have received a copy of the GNU General Public License
Packit Service 310c69
 * along with this program; if not, write to the Free Software
Packit Service 310c69
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
Packit Service 310c69
 * 02110-1301, USA. 
Packit Service 310c69
 *
Packit Service 310c69
 * $Id: //eng/uds-releases/jasper/src/uds/indexSession.c#10 $
Packit Service 310c69
 */
Packit Service 310c69
Packit Service 310c69
#include "indexSession.h"
Packit Service 310c69
Packit Service 310c69
#include "indexCheckpoint.h"
Packit Service 310c69
#include "indexRouter.h"
Packit Service 310c69
#include "logger.h"
Packit Service 310c69
#include "memoryAlloc.h"
Packit Service 310c69
#include "requestQueue.h"
Packit Service 310c69
Packit Service 310c69
/**********************************************************************/
Packit Service 310c69
static void collectStats(const struct uds_index_session *indexSession,
Packit Service 310c69
                         UdsContextStats                *stats)
Packit Service 310c69
{
Packit Service 310c69
  const SessionStats *sessionStats = &indexSession->stats;
Packit Service 310c69
Packit Service 310c69
  stats->currentTime = asTimeT(currentTime(CLOCK_REALTIME));
Packit Service 310c69
Packit Service 310c69
  stats->postsFound         = READ_ONCE(sessionStats->postsFound);
Packit Service 310c69
  stats->inMemoryPostsFound = READ_ONCE(sessionStats->postsFoundOpenChapter);
Packit Service 310c69
  stats->densePostsFound    = READ_ONCE(sessionStats->postsFoundDense);
Packit Service 310c69
  stats->sparsePostsFound   = READ_ONCE(sessionStats->postsFoundSparse);
Packit Service 310c69
  stats->postsNotFound      = READ_ONCE(sessionStats->postsNotFound);
Packit Service 310c69
  stats->updatesFound       = READ_ONCE(sessionStats->updatesFound);
Packit Service 310c69
  stats->updatesNotFound    = READ_ONCE(sessionStats->updatesNotFound);
Packit Service 310c69
  stats->deletionsFound     = READ_ONCE(sessionStats->deletionsFound);
Packit Service 310c69
  stats->deletionsNotFound  = READ_ONCE(sessionStats->deletionsNotFound);
Packit Service 310c69
  stats->queriesFound       = READ_ONCE(sessionStats->queriesFound);
Packit Service 310c69
  stats->queriesNotFound    = READ_ONCE(sessionStats->queriesNotFound);
Packit Service 310c69
  stats->requests           = READ_ONCE(sessionStats->requests);
Packit Service 310c69
}
Packit Service 310c69
Packit Service 310c69
/**********************************************************************/
Packit Service 310c69
static void handleCallbacks(Request *request)
Packit Service 310c69
{
Packit Service 310c69
  if (request->status == UDS_SUCCESS) {
Packit Service 310c69
    // Measure the turnaround time of this request and include that time,
Packit Service 310c69
    // along with the rest of the request, in the context's StatCounters.
Packit Service 310c69
    updateRequestContextStats(request);
Packit Service 310c69
  }
Packit Service 310c69
Packit Service 310c69
  if (request->callback != NULL) {
Packit Service 310c69
    // The request has specified its own callback and does not expect to be
Packit Service 310c69
    // freed.
Packit Service 310c69
    struct uds_index_session *indexSession = request->session;
Packit Service 310c69
    request->found = (request->location != LOC_UNAVAILABLE);
Packit Service 310c69
    request->callback((UdsRequest *) request);
Packit Service 310c69
    // We do this release after the callback because of the contract of the
Packit Service 310c69
    // udsFlushIndexSession method.
Packit Service 310c69
    releaseIndexSession(indexSession);
Packit Service 310c69
    return;
Packit Service 310c69
  }
Packit Service 310c69
Packit Service 310c69
  // Should not get here, because this is either a control message or it has a
Packit Service 310c69
  // callback method.
Packit Service 310c69
  freeRequest(request);
Packit Service 310c69
}
Packit Service 310c69
Packit Service 310c69
/**********************************************************************/
Packit Service 310c69
int checkIndexSession(struct uds_index_session *indexSession)
Packit Service 310c69
{
Packit Service 310c69
  lockMutex(&indexSession->requestMutex);
Packit Service 310c69
  unsigned int state = indexSession->state;
Packit Service 310c69
  unlockMutex(&indexSession->requestMutex);
Packit Service 310c69
Packit Service 310c69
  if (state == IS_FLAG_LOADED) {
Packit Service 310c69
    return UDS_SUCCESS;
Packit Service 310c69
  } else if (state & IS_FLAG_DISABLED) {
Packit Service 310c69
    return UDS_DISABLED;
Packit Service 310c69
  } else if ((state & IS_FLAG_LOADING)
Packit Service 310c69
             || (state & IS_FLAG_SUSPENDED)
Packit Service 310c69
             || (state & IS_FLAG_WAITING)) {
Packit Service 310c69
    return UDS_SUSPENDED;
Packit Service 310c69
  }
Packit Service 310c69
Packit Service 310c69
   return UDS_NO_INDEXSESSION;
Packit Service 310c69
}
Packit Service 310c69
Packit Service 310c69
/**********************************************************************/
Packit Service 310c69
int getIndexSession(struct uds_index_session *indexSession)
Packit Service 310c69
{
Packit Service 310c69
  lockMutex(&indexSession->requestMutex);
Packit Service 310c69
  indexSession->requestCount++;
Packit Service 310c69
  unlockMutex(&indexSession->requestMutex);
Packit Service 310c69
Packit Service 310c69
  int result = checkIndexSession(indexSession);
Packit Service 310c69
  if (result != UDS_SUCCESS) {
Packit Service 310c69
    releaseIndexSession(indexSession);
Packit Service 310c69
    return result;
Packit Service 310c69
  }
Packit Service 310c69
  return UDS_SUCCESS;
Packit Service 310c69
}
Packit Service 310c69
Packit Service 310c69
/**********************************************************************/
Packit Service 310c69
void releaseIndexSession(struct uds_index_session *indexSession)
Packit Service 310c69
{
Packit Service 310c69
  lockMutex(&indexSession->requestMutex);
Packit Service 310c69
  if (--indexSession->requestCount == 0) {
Packit Service 310c69
    broadcastCond(&indexSession->requestCond);
Packit Service 310c69
  }
Packit Service 310c69
  unlockMutex(&indexSession->requestMutex);
Packit Service 310c69
}
Packit Service 310c69
Packit Service 310c69
/**********************************************************************/
Packit Service 310c69
int startLoadingIndexSession(struct uds_index_session *indexSession)
Packit Service 310c69
{
Packit Service 310c69
  int result;
Packit Service 310c69
  lockMutex(&indexSession->requestMutex);
Packit Service 310c69
  if (indexSession->state & IS_FLAG_SUSPENDED) {
Packit Service 310c69
    result = UDS_SUSPENDED;
Packit Service 310c69
  } else if (indexSession->state != 0) {
Packit Service 310c69
    result = UDS_INDEXSESSION_IN_USE;
Packit Service 310c69
  } else {
Packit Service 310c69
    indexSession->state |= IS_FLAG_LOADING;
Packit Service 310c69
    result = UDS_SUCCESS;
Packit Service 310c69
  }
Packit Service 310c69
  unlockMutex(&indexSession->requestMutex);
Packit Service 310c69
  return result;
Packit Service 310c69
}
Packit Service 310c69
Packit Service 310c69
/**********************************************************************/
Packit Service 310c69
void finishLoadingIndexSession(struct uds_index_session *indexSession,
Packit Service 310c69
                               int                       result)
Packit Service 310c69
{
Packit Service 310c69
  lockMutex(&indexSession->requestMutex);
Packit Service 310c69
  indexSession->state &= ~IS_FLAG_LOADING;
Packit Service 310c69
  if (result == UDS_SUCCESS) {
Packit Service 310c69
    indexSession->state |= IS_FLAG_LOADED;
Packit Service 310c69
  }
Packit Service 310c69
  broadcastCond(&indexSession->requestCond);
Packit Service 310c69
  unlockMutex(&indexSession->requestMutex);
Packit Service 310c69
}
Packit Service 310c69
Packit Service 310c69
/**********************************************************************/
Packit Service 310c69
void disableIndexSession(struct uds_index_session *indexSession)
Packit Service 310c69
{
Packit Service 310c69
  lockMutex(&indexSession->requestMutex);
Packit Service 310c69
  indexSession->state |= IS_FLAG_DISABLED;
Packit Service 310c69
  unlockMutex(&indexSession->requestMutex);
Packit Service 310c69
}
Packit Service 310c69
Packit Service 310c69
/**********************************************************************/
Packit Service 310c69
int makeEmptyIndexSession(struct uds_index_session **indexSessionPtr)
Packit Service 310c69
{
Packit Service 310c69
  struct uds_index_session *session;
Packit Service 310c69
  int result = ALLOCATE(1, struct uds_index_session, __func__, &session);
Packit Service 310c69
  if (result != UDS_SUCCESS) {
Packit Service 310c69
    return result;
Packit Service 310c69
  }
Packit Service 310c69
Packit Service 310c69
  result = initMutex(&session->requestMutex);
Packit Service 310c69
  if (result != UDS_SUCCESS) {
Packit Service 310c69
    FREE(session);
Packit Service 310c69
    return result;
Packit Service 310c69
  }
Packit Service 310c69
Packit Service 310c69
  result = initCond(&session->requestCond);
Packit Service 310c69
  if (result != UDS_SUCCESS) {
Packit Service 310c69
    destroyMutex(&session->requestMutex);
Packit Service 310c69
    FREE(session);
Packit Service 310c69
    return result;
Packit Service 310c69
  }
Packit Service 310c69
Packit Service 310c69
  result = initMutex(&session->loadContext.mutex);
Packit Service 310c69
  if (result != UDS_SUCCESS) {
Packit Service 310c69
    destroyCond(&session->requestCond);
Packit Service 310c69
    destroyMutex(&session->requestMutex);
Packit Service 310c69
    FREE(session);
Packit Service 310c69
    return result;
Packit Service 310c69
  }
Packit Service 310c69
Packit Service 310c69
  result = initCond(&session->loadContext.cond);
Packit Service 310c69
  if (result != UDS_SUCCESS) {
Packit Service 310c69
    destroyMutex(&session->loadContext.mutex);
Packit Service 310c69
    destroyCond(&session->requestCond);
Packit Service 310c69
    destroyMutex(&session->requestMutex);
Packit Service 310c69
    FREE(session);
Packit Service 310c69
    return result;
Packit Service 310c69
  }
Packit Service 310c69
Packit Service 310c69
  result = makeRequestQueue("callbackW", &handleCallbacks,
Packit Service 310c69
                            &session->callbackQueue);
Packit Service 310c69
  if (result != UDS_SUCCESS) {
Packit Service 310c69
    destroyCond(&session->loadContext.cond);
Packit Service 310c69
    destroyMutex(&session->loadContext.mutex);
Packit Service 310c69
    destroyCond(&session->requestCond);
Packit Service 310c69
    destroyMutex(&session->requestMutex);
Packit Service 310c69
    FREE(session);
Packit Service 310c69
    return result;
Packit Service 310c69
  }
Packit Service 310c69
Packit Service 310c69
  *indexSessionPtr = session;
Packit Service 310c69
  return UDS_SUCCESS;
Packit Service 310c69
}
Packit Service 310c69
Packit Service 310c69
/**********************************************************************/
Packit Service 310c69
int udsSuspendIndexSession(struct uds_index_session *session, bool save)
Packit Service 310c69
{
Packit Service 310c69
  int result;
Packit Service 310c69
  bool saveIndex = false;
Packit Service 310c69
  bool suspendIndex = false;
Packit Service 310c69
  lockMutex(&session->requestMutex);
Packit Service 310c69
  // Wait for any pending close operation to complete.
Packit Service 310c69
  while (session->state & IS_FLAG_CLOSING) {
Packit Service 310c69
    waitCond(&session->requestCond, &session->requestMutex);
Packit Service 310c69
  }
Packit Service 310c69
  if ((session->state & IS_FLAG_WAITING)
Packit Service 310c69
      || (session->state & IS_FLAG_DESTROYING)) {
Packit Service 310c69
    result = EBUSY;
Packit Service 310c69
  } else if (session->state & IS_FLAG_SUSPENDED) {
Packit Service 310c69
    result = UDS_SUCCESS;
Packit Service 310c69
  } else if (session->state & IS_FLAG_LOADING) {
Packit Service 310c69
    session->state |= IS_FLAG_WAITING;
Packit Service 310c69
    suspendIndex = true;
Packit Service 310c69
    result = UDS_SUCCESS;
Packit Service 310c69
  } else if (!(session->state & IS_FLAG_LOADED)) {
Packit Service 310c69
    session->state |= IS_FLAG_SUSPENDED;
Packit Service 310c69
    broadcastCond(&session->requestCond);
Packit Service 310c69
    result = UDS_SUCCESS;
Packit Service 310c69
  } else {
Packit Service 310c69
    saveIndex = save;
Packit Service 310c69
    if (saveIndex) {
Packit Service 310c69
      session->state |= IS_FLAG_WAITING;
Packit Service 310c69
    } else {
Packit Service 310c69
      session->state |= IS_FLAG_SUSPENDED;
Packit Service 310c69
      broadcastCond(&session->requestCond);
Packit Service 310c69
    }
Packit Service 310c69
    result = UDS_SUCCESS;
Packit Service 310c69
  }
Packit Service 310c69
  unlockMutex(&session->requestMutex);
Packit Service 310c69
Packit Service 310c69
  if (!saveIndex && !suspendIndex) {
Packit Service 310c69
    return result;
Packit Service 310c69
  }
Packit Service 310c69
Packit Service 310c69
  if (saveIndex) {
Packit Service 310c69
    result = udsSaveIndex(session);
Packit Service 310c69
    lockMutex(&session->requestMutex);
Packit Service 310c69
    session->state &= ~IS_FLAG_WAITING;
Packit Service 310c69
    session->state |= IS_FLAG_SUSPENDED;
Packit Service 310c69
    broadcastCond(&session->requestCond);
Packit Service 310c69
    unlockMutex(&session->requestMutex);
Packit Service 310c69
    return result;
Packit Service 310c69
  }
Packit Service 310c69
Packit Service 310c69
  lockMutex(&session->loadContext.mutex);
Packit Service 310c69
  switch (session->loadContext.status) {
Packit Service 310c69
  case INDEX_OPENING:
Packit Service 310c69
    session->loadContext.status = INDEX_SUSPENDING;
Packit Service 310c69
Packit Service 310c69
    // Wait until the index indicates that it is not replaying.
Packit Service 310c69
    while ((session->loadContext.status != INDEX_SUSPENDED)
Packit Service 310c69
           && (session->loadContext.status != INDEX_READY)) {
Packit Service 310c69
      waitCond(&session->loadContext.cond,
Packit Service 310c69
               &session->loadContext.mutex);
Packit Service 310c69
    }
Packit Service 310c69
    break;
Packit Service 310c69
Packit Service 310c69
  case INDEX_READY:
Packit Service 310c69
    // Index load does not need to be suspended.
Packit Service 310c69
    break;
Packit Service 310c69
Packit Service 310c69
  case INDEX_SUSPENDED:
Packit Service 310c69
  case INDEX_SUSPENDING:
Packit Service 310c69
  case INDEX_FREEING:
Packit Service 310c69
  default:
Packit Service 310c69
    // These cases should not happen.
Packit Service 310c69
    ASSERT_LOG_ONLY(false, "Bad load context state %u",
Packit Service 310c69
                    session->loadContext.status);
Packit Service 310c69
    break;
Packit Service 310c69
  }
Packit Service 310c69
  unlockMutex(&session->loadContext.mutex);
Packit Service 310c69
Packit Service 310c69
  lockMutex(&session->requestMutex);
Packit Service 310c69
  session->state &= ~IS_FLAG_WAITING;
Packit Service 310c69
  session->state |= IS_FLAG_SUSPENDED;
Packit Service 310c69
  broadcastCond(&session->requestCond);
Packit Service 310c69
  unlockMutex(&session->requestMutex);
Packit Service 310c69
  return UDS_SUCCESS;
Packit Service 310c69
}
Packit Service 310c69
Packit Service 310c69
/**********************************************************************/
Packit Service 310c69
int udsResumeIndexSession(struct uds_index_session *session)
Packit Service 310c69
{
Packit Service 310c69
  lockMutex(&session->requestMutex);
Packit Service 310c69
  if (session->state & IS_FLAG_WAITING) {
Packit Service 310c69
    unlockMutex(&session->requestMutex);
Packit Service 310c69
    return EBUSY;
Packit Service 310c69
  }
Packit Service 310c69
Packit Service 310c69
  /* If not suspended, just succeed */
Packit Service 310c69
  if (!(session->state & IS_FLAG_SUSPENDED)) {
Packit Service 310c69
    unlockMutex(&session->requestMutex);
Packit Service 310c69
    return UDS_SUCCESS;
Packit Service 310c69
  }
Packit Service 310c69
Packit Service 310c69
  if (!(session->state & IS_FLAG_LOADING)) {
Packit Service 310c69
    session->state &= ~IS_FLAG_SUSPENDED;
Packit Service 310c69
    unlockMutex(&session->requestMutex);
Packit Service 310c69
    return UDS_SUCCESS;
Packit Service 310c69
  }
Packit Service 310c69
Packit Service 310c69
  session->state |= IS_FLAG_WAITING;
Packit Service 310c69
  unlockMutex(&session->requestMutex);
Packit Service 310c69
Packit Service 310c69
  lockMutex(&session->loadContext.mutex);
Packit Service 310c69
  switch (session->loadContext.status) {
Packit Service 310c69
  case INDEX_SUSPENDED:
Packit Service 310c69
    session->loadContext.status = INDEX_OPENING;
Packit Service 310c69
    // Notify the index to start replaying again.
Packit Service 310c69
    broadcastCond(&session->loadContext.cond);
Packit Service 310c69
    break;
Packit Service 310c69
Packit Service 310c69
  case INDEX_READY:
Packit Service 310c69
    // There is no index rebuild to resume.
Packit Service 310c69
    break;
Packit Service 310c69
Packit Service 310c69
  case INDEX_OPENING:
Packit Service 310c69
  case INDEX_SUSPENDING:
Packit Service 310c69
  case INDEX_FREEING:
Packit Service 310c69
  default:
Packit Service 310c69
    // These cases should not happen; do nothing.
Packit Service 310c69
    ASSERT_LOG_ONLY(false, "Bad load context state %u",
Packit Service 310c69
                    session->loadContext.status);
Packit Service 310c69
    break;
Packit Service 310c69
  }
Packit Service 310c69
  unlockMutex(&session->loadContext.mutex);
Packit Service 310c69
Packit Service 310c69
  lockMutex(&session->requestMutex);
Packit Service 310c69
  session->state &= ~IS_FLAG_WAITING;
Packit Service 310c69
  session->state &= ~IS_FLAG_SUSPENDED;
Packit Service 310c69
  broadcastCond(&session->requestCond);
Packit Service 310c69
  unlockMutex(&session->requestMutex);
Packit Service 310c69
  return UDS_SUCCESS;
Packit Service 310c69
}
Packit Service 310c69
Packit Service 310c69
/**********************************************************************/
Packit Service 310c69
static void waitForNoRequestsInProgress(struct uds_index_session *indexSession)
Packit Service 310c69
{
Packit Service 310c69
  lockMutex(&indexSession->requestMutex);
Packit Service 310c69
  while (indexSession->requestCount > 0) {
Packit Service 310c69
    waitCond(&indexSession->requestCond, &indexSession->requestMutex);
Packit Service 310c69
  }
Packit Service 310c69
  unlockMutex(&indexSession->requestMutex);
Packit Service 310c69
}
Packit Service 310c69
Packit Service 310c69
/**********************************************************************/
Packit Service 310c69
int saveAndFreeIndex(struct uds_index_session *indexSession)
Packit Service 310c69
{
Packit Service 310c69
  int result = UDS_SUCCESS;
Packit Service 310c69
  IndexRouter *router = indexSession->router;
Packit Service 310c69
  if (router != NULL) {
Packit Service 310c69
    lockMutex(&indexSession->requestMutex);
Packit Service 310c69
    bool suspended = (indexSession->state & IS_FLAG_SUSPENDED);
Packit Service 310c69
    unlockMutex(&indexSession->requestMutex);
Packit Service 310c69
    if (!suspended) {
Packit Service 310c69
      result = saveIndexRouter(router);
Packit Service 310c69
      if (result != UDS_SUCCESS) {
Packit Service 310c69
        logWarningWithStringError(result, "ignoring error from saveIndexRouter");
Packit Service 310c69
      }
Packit Service 310c69
    }
Packit Service 310c69
    freeIndexRouter(router);
Packit Service 310c69
    indexSession->router = NULL;
Packit Service 310c69
Packit Service 310c69
    // Reset all index state that happens to be in the index session, so it
Packit Service 310c69
    // doesn't affect any future index.
Packit Service 310c69
    lockMutex(&indexSession->loadContext.mutex);
Packit Service 310c69
    indexSession->loadContext.status = INDEX_OPENING;
Packit Service 310c69
    unlockMutex(&indexSession->loadContext.mutex);
Packit Service 310c69
Packit Service 310c69
    lockMutex(&indexSession->requestMutex);
Packit Service 310c69
    // Only the suspend bit will remain relevant.
Packit Service 310c69
    indexSession->state &= IS_FLAG_SUSPENDED;
Packit Service 310c69
    unlockMutex(&indexSession->requestMutex);
Packit Service 310c69
  }
Packit Service 310c69
Packit Service 310c69
  logDebug("Closed index");
Packit Service 310c69
  return result;
Packit Service 310c69
}
Packit Service 310c69
Packit Service 310c69
/**********************************************************************/
Packit Service 310c69
int udsCloseIndex(struct uds_index_session *indexSession)
Packit Service 310c69
{
Packit Service 310c69
  lockMutex(&indexSession->requestMutex);
Packit Service 310c69
Packit Service 310c69
  // Wait for any pending suspend, resume or close operations to complete.
Packit Service 310c69
  while ((indexSession->state & IS_FLAG_WAITING)
Packit Service 310c69
         || (indexSession->state & IS_FLAG_CLOSING)) {
Packit Service 310c69
    waitCond(&indexSession->requestCond, &indexSession->requestMutex);
Packit Service 310c69
  }
Packit Service 310c69
Packit Service 310c69
  int result = UDS_SUCCESS;
Packit Service 310c69
  if (indexSession->state & IS_FLAG_SUSPENDED) {
Packit Service 310c69
    result = UDS_SUSPENDED;
Packit Service 310c69
  } else if ((indexSession->state & IS_FLAG_DESTROYING)
Packit Service 310c69
             || !(indexSession->state & IS_FLAG_LOADED)) {
Packit Service 310c69
    // The index doesn't exist, hasn't finished loading, or is being destroyed.
Packit Service 310c69
    result = UDS_NO_INDEXSESSION;
Packit Service 310c69
  } else {
Packit Service 310c69
    indexSession->state |= IS_FLAG_CLOSING;
Packit Service 310c69
  }
Packit Service 310c69
  unlockMutex(&indexSession->requestMutex);
Packit Service 310c69
  if (result != UDS_SUCCESS) {
Packit Service 310c69
    return result;
Packit Service 310c69
  }
Packit Service 310c69
Packit Service 310c69
  logDebug("Closing index");
Packit Service 310c69
  waitForNoRequestsInProgress(indexSession);
Packit Service 310c69
  result = saveAndFreeIndex(indexSession);
Packit Service 310c69
Packit Service 310c69
  lockMutex(&indexSession->requestMutex);
Packit Service 310c69
  indexSession->state &= ~IS_FLAG_CLOSING;
Packit Service 310c69
  broadcastCond(&indexSession->requestCond);
Packit Service 310c69
  unlockMutex(&indexSession->requestMutex);
Packit Service 310c69
  return result;
Packit Service 310c69
}
Packit Service 310c69
Packit Service 310c69
/**********************************************************************/
Packit Service 310c69
int udsDestroyIndexSession(struct uds_index_session *indexSession)
Packit Service 310c69
{
Packit Service 310c69
  logDebug("Destroying index session");
Packit Service 310c69
Packit Service 310c69
  bool loadPending = false;
Packit Service 310c69
  lockMutex(&indexSession->requestMutex);
Packit Service 310c69
Packit Service 310c69
  // Wait for any pending suspend, resume, or close operations to complete.
Packit Service 310c69
  while ((indexSession->state & IS_FLAG_WAITING)
Packit Service 310c69
         || (indexSession->state & IS_FLAG_CLOSING)) {
Packit Service 310c69
    waitCond(&indexSession->requestCond, &indexSession->requestMutex);
Packit Service 310c69
  }
Packit Service 310c69
Packit Service 310c69
  if (indexSession->state & IS_FLAG_DESTROYING) {
Packit Service 310c69
    unlockMutex(&indexSession->requestMutex);
Packit Service 310c69
    return EBUSY;
Packit Service 310c69
  }
Packit Service 310c69
Packit Service 310c69
  indexSession->state |= IS_FLAG_DESTROYING;
Packit Service 310c69
  loadPending = ((indexSession->state & IS_FLAG_LOADING)
Packit Service 310c69
                 && (indexSession->state & IS_FLAG_SUSPENDED));
Packit Service 310c69
  unlockMutex(&indexSession->requestMutex);
Packit Service 310c69
Packit Service 310c69
  if (loadPending) {
Packit Service 310c69
    // Tell the index to terminate the rebuild.
Packit Service 310c69
    lockMutex(&indexSession->loadContext.mutex);
Packit Service 310c69
    if (indexSession->loadContext.status == INDEX_SUSPENDED) {
Packit Service 310c69
      indexSession->loadContext.status = INDEX_FREEING;
Packit Service 310c69
      broadcastCond(&indexSession->loadContext.cond);
Packit Service 310c69
    }
Packit Service 310c69
    unlockMutex(&indexSession->loadContext.mutex);
Packit Service 310c69
Packit Service 310c69
    // Wait until the load exits before proceeding.
Packit Service 310c69
    lockMutex(&indexSession->requestMutex);
Packit Service 310c69
    while (indexSession->state & IS_FLAG_LOADING) {
Packit Service 310c69
      waitCond(&indexSession->requestCond, &indexSession->requestMutex);
Packit Service 310c69
    }
Packit Service 310c69
    unlockMutex(&indexSession->requestMutex);
Packit Service 310c69
  }
Packit Service 310c69
Packit Service 310c69
  waitForNoRequestsInProgress(indexSession);
Packit Service 310c69
  int result = saveAndFreeIndex(indexSession);
Packit Service 310c69
  requestQueueFinish(indexSession->callbackQueue);
Packit Service 310c69
  indexSession->callbackQueue = NULL;
Packit Service 310c69
  destroyCond(&indexSession->loadContext.cond);
Packit Service 310c69
  destroyMutex(&indexSession->loadContext.mutex);
Packit Service 310c69
  destroyCond(&indexSession->requestCond);
Packit Service 310c69
  destroyMutex(&indexSession->requestMutex);
Packit Service 310c69
  logDebug("Destroyed index session");
Packit Service 310c69
  FREE(indexSession);
Packit Service 310c69
  return result;
Packit Service 310c69
}
Packit Service 310c69
Packit Service 310c69
/**********************************************************************/
Packit Service 310c69
int udsFlushIndexSession(struct uds_index_session *indexSession)
Packit Service 310c69
{
Packit Service 310c69
  waitForNoRequestsInProgress(indexSession);
Packit Service 310c69
  // Wait until any open chapter writes are complete
Packit Service 310c69
  waitForIdleIndexRouter(indexSession->router);
Packit Service 310c69
  return UDS_SUCCESS;
Packit Service 310c69
}
Packit Service 310c69
Packit Service 310c69
/**********************************************************************/
Packit Service 310c69
int udsSaveIndex(struct uds_index_session *indexSession)
Packit Service 310c69
{
Packit Service 310c69
  waitForNoRequestsInProgress(indexSession);
Packit Service 310c69
  // saveIndexRouter waits for open chapter writes to complete
Packit Service 310c69
  return saveIndexRouter(indexSession->router);
Packit Service 310c69
}
Packit Service 310c69
Packit Service 310c69
/**********************************************************************/
Packit Service 310c69
int udsSetCheckpointFrequency(struct uds_index_session *indexSession,
Packit Service 310c69
                              unsigned int              frequency)
Packit Service 310c69
{
Packit Service 310c69
  setIndexCheckpointFrequency(indexSession->router->index->checkpoint,
Packit Service 310c69
                              frequency);
Packit Service 310c69
  return UDS_SUCCESS;
Packit Service 310c69
}
Packit Service 310c69
Packit Service 310c69
/**********************************************************************/
Packit Service 310c69
int udsGetIndexConfiguration(struct uds_index_session *indexSession,
Packit Service 310c69
                             UdsConfiguration         *conf)
Packit Service 310c69
{
Packit Service 310c69
  if (conf == NULL) {
Packit Service 310c69
    return logErrorWithStringError(UDS_CONF_PTR_REQUIRED,
Packit Service 310c69
                                   "received a NULL config pointer");
Packit Service 310c69
  }
Packit Service 310c69
  int result = ALLOCATE(1, struct udsConfiguration, __func__, conf);
Packit Service 310c69
  if (result == UDS_SUCCESS) {
Packit Service 310c69
    **conf = indexSession->userConfig;
Packit Service 310c69
  }
Packit Service 310c69
  return result;
Packit Service 310c69
}
Packit Service 310c69
Packit Service 310c69
/**********************************************************************/
Packit Service 310c69
int udsGetIndexStats(struct uds_index_session *indexSession,
Packit Service 310c69
                     UdsIndexStats            *stats)
Packit Service 310c69
{
Packit Service 310c69
  if (stats == NULL) {
Packit Service 310c69
    return logErrorWithStringError(UDS_INDEX_STATS_PTR_REQUIRED,
Packit Service 310c69
                                   "received a NULL index stats pointer");
Packit Service 310c69
  }
Packit Service 310c69
  getIndexStats(indexSession->router->index, stats);
Packit Service 310c69
  return UDS_SUCCESS;
Packit Service 310c69
}
Packit Service 310c69
Packit Service 310c69
/**********************************************************************/
Packit Service 310c69
int udsGetIndexSessionStats(struct uds_index_session *indexSession,
Packit Service 310c69
                            UdsContextStats          *stats)
Packit Service 310c69
{
Packit Service 310c69
  if (stats == NULL) {
Packit Service 310c69
    return logWarningWithStringError(UDS_CONTEXT_STATS_PTR_REQUIRED,
Packit Service 310c69
                                     "received a NULL context stats pointer");
Packit Service 310c69
  }
Packit Service 310c69
  collectStats(indexSession, stats);
Packit Service 310c69
  return UDS_SUCCESS;
Packit Service 310c69
}