/* * Copyright (c) 2020 Red Hat, Inc. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. * * $Id: //eng/uds-releases/jasper/src/uds/indexSession.h#6 $ */ #ifndef INDEX_SESSION_H #define INDEX_SESSION_H #include "atomicDefs.h" #include "config.h" #include "cpu.h" #include "opaqueTypes.h" #include "threads.h" #include "uds.h" /** * The bit position of flags used to indicate index session states. **/ typedef enum { IS_FLAG_BIT_START = 8, /** Flag indicating that the session is loading */ IS_FLAG_BIT_LOADING = IS_FLAG_BIT_START, /** Flag indicating that that the session has been loaded */ IS_FLAG_BIT_LOADED, /** Flag indicating that the session is disabled permanently */ IS_FLAG_BIT_DISABLED, /** Flag indicating that the session is suspended */ IS_FLAG_BIT_SUSPENDED, /** Flag indicating that the session is waiting for an index state change */ IS_FLAG_BIT_WAITING, /** Flag indicating that that the session is closing */ IS_FLAG_BIT_CLOSING, /** Flag indicating that that the session is being destroyed */ IS_FLAG_BIT_DESTROYING, } IndexSessionFlagBit; /** * The index session state flags. **/ typedef enum { IS_FLAG_LOADED = (1 << IS_FLAG_BIT_LOADED), IS_FLAG_LOADING = (1 << IS_FLAG_BIT_LOADING), IS_FLAG_DISABLED = (1 << IS_FLAG_BIT_DISABLED), IS_FLAG_SUSPENDED = (1 << IS_FLAG_BIT_SUSPENDED), IS_FLAG_WAITING = (1 << IS_FLAG_BIT_WAITING), IS_FLAG_CLOSING = (1 << IS_FLAG_BIT_CLOSING), IS_FLAG_DESTROYING = (1 << IS_FLAG_BIT_DESTROYING), } IndexSessionFlag; typedef struct __attribute__((aligned(CACHE_LINE_BYTES))) sessionStats { uint64_t postsFound; /* Post calls that found an entry */ uint64_t postsFoundOpenChapter; /* Post calls found in the open chapter */ uint64_t postsFoundDense; /* Post calls found in the dense index */ uint64_t postsFoundSparse; /* Post calls found in the sparse index */ uint64_t postsNotFound; /* Post calls that did not find an entry */ uint64_t updatesFound; /* Update calls that found an entry */ uint64_t updatesNotFound; /* Update calls that did not find an entry */ uint64_t deletionsFound; /* Delete calls that found an entry */ uint64_t deletionsNotFound; /* Delete calls that did not find an entry */ uint64_t queriesFound; /* Query calls that found an entry */ uint64_t queriesNotFound; /* Query calls that did not find an entry */ uint64_t requests; /* Total number of requests */ } SessionStats; /** * States used in the index load context, reflecting the state of the index. **/ typedef enum { /** The index has not been loaded or rebuilt completely */ INDEX_OPENING = 0, /** The index is able to handle requests */ INDEX_READY, /** The index has a pending request to suspend */ INDEX_SUSPENDING, /** The index is suspended in the midst of a rebuild */ INDEX_SUSPENDED, /** The index is being shut down while suspended */ INDEX_FREEING, } IndexSuspendStatus; /** * The CondVar here must be notified when the status changes to * INDEX_SUSPENDED, in order to wake up the waiting udsSuspendIndexSession() * call. It must also be notified when the status changes away from * INDEX_SUSPENDED, to resume rebuild the index from checkForSuspend() in the * index. **/ typedef struct indexLoadContext { Mutex mutex; CondVar cond; IndexSuspendStatus status; // Covered by indexLoadContext.mutex. } IndexLoadContext; /** * The request CondVar here must be notified when IS_FLAG_WAITING is cleared, * in case udsCloseIndex() or udsDestroyIndexSession() is waiting on that flag. * It must also be notified when IS_FLAG_CLOSING is cleared, in case * udsSuspendIndexSession(), udsCloseIndex() or udsDestroyIndexSession() is * waiting on that flag. * Finally, it must also be notified when IS_FLAG_LOADING is cleared, to inform * udsDestroyIndexSession() that the index session can be safely freed. **/ struct uds_index_session { unsigned int state; // Covered by requestMutex. IndexRouter *router; RequestQueue *callbackQueue; struct udsConfiguration userConfig; IndexLoadContext loadContext; // Asynchronous Request synchronization Mutex requestMutex; CondVar requestCond; int requestCount; // Request statistics, all owned by the callback thread SessionStats stats; }; /** * Check that the index session is usable. * * @param indexSession the session to query * * @return UDS_SUCCESS or an error code **/ int checkIndexSession(struct uds_index_session *indexSession) __attribute__((warn_unused_result)); /** * Make sure that the IndexSession is allowed to load an index, and if so, set * its state to indicate that the load has started. * * @param indexSession the session to load with * * @return UDS_SUCCESS, or an error code if an index already exists. **/ int startLoadingIndexSession(struct uds_index_session *indexSession) __attribute__((warn_unused_result)); /** * Update the IndexSession state after attempting to load an index, to indicate * that the load has completed, and whether or not it succeeded. * * @param indexSession the session that was loading * @param result the result of the load operation **/ void finishLoadingIndexSession(struct uds_index_session *indexSession, int result); /** * Disable an index session due to an error. * * @param indexSession the session to be disabled **/ void disableIndexSession(struct uds_index_session *indexSession); /** * Acquire the index session for an asynchronous index request. * * The pointer must eventually be released with a corresponding call to * releaseIndexSession(). * * @param indexSession The index session * * @return UDS_SUCCESS or an error code **/ int getIndexSession(struct uds_index_session *indexSession) __attribute__((warn_unused_result)); /** * Release a pointer to an index session. * * @param indexSession The session to release **/ void releaseIndexSession(struct uds_index_session *indexSession); /** * Construct a new, empty index session. * * @param indexSessionPtr The pointer to receive the new session * * @return UDS_SUCCESS or an error code **/ int makeEmptyIndexSession(struct uds_index_session **indexSessionPtr) __attribute__((warn_unused_result)); /** * Save an index while the session is quiescent. * * During the call to #udsSaveIndex, there should be no other call to * #udsSaveIndex and there should be no calls to #udsStartChunkOperation. * * @param indexSession The session to save * * @return Either #UDS_SUCCESS or an error code **/ int udsSaveIndex(struct uds_index_session *indexSession) __attribute__((warn_unused_result)); /** * Close the index by saving the underlying index. * * @param indexSession The index session to be shut down and freed **/ int saveAndFreeIndex(struct uds_index_session *indexSession); /** * Set the checkpoint frequency of the grid. * * @param session The index session to be modified. * @param frequency New checkpoint frequency. * * @return Either UDS_SUCCESS or an error code. * **/ int udsSetCheckpointFrequency(struct uds_index_session *session, unsigned int frequency) __attribute__((warn_unused_result)); #endif /* INDEX_SESSION_H */