Blame source/uds/request.h

Packit Service 310c69
/*
Packit Service 310c69
 * Copyright (c) 2020 Red Hat, Inc.
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/request.h#7 $
Packit Service 310c69
 */
Packit Service 310c69
Packit Service 310c69
#ifndef REQUEST_H
Packit Service 310c69
#define REQUEST_H
Packit Service 310c69
Packit Service 310c69
#include "cacheCounters.h"
Packit Service 310c69
#include "common.h"
Packit Service 310c69
#include "compiler.h"
Packit Service 310c69
#include "opaqueTypes.h"
Packit Service 310c69
#include "threads.h"
Packit Service 310c69
#include "timeUtils.h"
Packit Service 310c69
#include "uds.h"
Packit Service 310c69
#include "util/funnelQueue.h"
Packit Service 310c69
Packit Service 310c69
/**
Packit Service 310c69
 * RequestAction values indicate what action, command, or query is to be
Packit Service 310c69
 * performed when processing a Request instance.
Packit Service 310c69
 **/
Packit Service 310c69
typedef enum {
Packit Service 310c69
  // Map the API's UdsCallbackType values directly to a corresponding action.
Packit Service 310c69
  REQUEST_INDEX  = UDS_POST,
Packit Service 310c69
  REQUEST_UPDATE = UDS_UPDATE,
Packit Service 310c69
  REQUEST_DELETE = UDS_DELETE,
Packit Service 310c69
  REQUEST_QUERY  = UDS_QUERY,
Packit Service 310c69
Packit Service 310c69
  REQUEST_CONTROL,
Packit Service 310c69
Packit Service 310c69
  // REQUEST_SPARSE_CACHE_BARRIER is the action for the control request used
Packit Service 310c69
  // by localIndexRouter.
Packit Service 310c69
  REQUEST_SPARSE_CACHE_BARRIER,
Packit Service 310c69
Packit Service 310c69
  // REQUEST_ANNOUNCE_CHAPTER_CLOSED is the action for the control
Packit Service 310c69
  // request used by an indexZone to signal the other zones that it
Packit Service 310c69
  // has closed the current open chapter.
Packit Service 310c69
  REQUEST_ANNOUNCE_CHAPTER_CLOSED,
Packit Service 310c69
} RequestAction;
Packit Service 310c69
Packit Service 310c69
/**
Packit Service 310c69
 * The block's rough location in the index, if any.
Packit Service 310c69
 **/
Packit Service 310c69
typedef enum {
Packit Service 310c69
  /* the block doesn't exist or the location isn't available */
Packit Service 310c69
  LOC_UNAVAILABLE,
Packit Service 310c69
  /* if the block was found in the open chapter */
Packit Service 310c69
  LOC_IN_OPEN_CHAPTER,
Packit Service 310c69
  /* if the block was found in the dense part of the index */
Packit Service 310c69
  LOC_IN_DENSE,
Packit Service 310c69
  /* if the block was found in the sparse part of the index */
Packit Service 310c69
  LOC_IN_SPARSE
Packit Service 310c69
} IndexRegion;
Packit Service 310c69
Packit Service 310c69
/**
Packit Service 310c69
 * Abstract request pipeline stages, which can also be viewed as stages in the
Packit Service 310c69
 * life-cycle of a request.
Packit Service 310c69
 **/
Packit Service 310c69
typedef enum {
Packit Service 310c69
  STAGE_TRIAGE,
Packit Service 310c69
  STAGE_INDEX,
Packit Service 310c69
  STAGE_CALLBACK,
Packit Service 310c69
} RequestStage;
Packit Service 310c69
Packit Service 310c69
/**
Packit Service 310c69
 * Control message fields for the barrier messages used to coordinate the
Packit Service 310c69
 * addition of a chapter to the sparse chapter index cache.
Packit Service 310c69
 **/
Packit Service 310c69
typedef struct barrierMessageData {
Packit Service 310c69
  /** virtual chapter number of the chapter index to add to the sparse cache */
Packit Service 310c69
  uint64_t      virtualChapter;
Packit Service 310c69
} BarrierMessageData;
Packit Service 310c69
Packit Service 310c69
/**
Packit Service 310c69
 * Control message fields for the chapter closed messages used to inform
Packit Service 310c69
 * lagging zones of the first zone to close a given open chapter.
Packit Service 310c69
 **/
Packit Service 310c69
typedef struct chapterClosedMessageData {
Packit Service 310c69
  /** virtual chapter number of the chapter which was closed */
Packit Service 310c69
  uint64_t      virtualChapter;
Packit Service 310c69
} ChapterClosedMessageData;
Packit Service 310c69
Packit Service 310c69
/**
Packit Service 310c69
 * Union of the all the zone control message fields. The RequestAction field
Packit Service 310c69
 * (or launch function argument) selects which of the members is valid.
Packit Service 310c69
 **/
Packit Service 310c69
typedef union zoneMessageData {
Packit Service 310c69
  BarrierMessageData barrier;             // for REQUEST_SPARSE_CACHE_BARRIER
Packit Service 310c69
  ChapterClosedMessageData chapterClosed; // for REQUEST_ANNOUNCE_CHAPTER_CLOSED
Packit Service 310c69
} ZoneMessageData;
Packit Service 310c69
Packit Service 310c69
typedef struct zoneMessage {
Packit Service 310c69
  /** the index to which the message is directed */
Packit Service 310c69
  struct index *index;
Packit Service 310c69
  /** the message specific data */
Packit Service 310c69
  ZoneMessageData data;
Packit Service 310c69
} ZoneMessage;
Packit Service 310c69
Packit Service 310c69
/**
Packit Service 310c69
 * Request context for queuing throughout the uds pipeline
Packit Service 310c69
 *
Packit Service 310c69
 * XXX Note that the typedef for this struct defines "Request", and that this
Packit Service 310c69
 *     should therefore be "struct request".  However, this conflicts with the
Packit Service 310c69
 *     Linux kernel which also has a "struct request".  This is a workaround so
Packit Service 310c69
 *     that we can make upstreaming progress.  The real solution is to expose
Packit Service 310c69
 *     this structure as the true "struct uds_request" and do a lot of
Packit Service 310c69
 *     renaming.
Packit Service 310c69
 **/
Packit Service 310c69
struct internalRequest {
Packit Service 310c69
  /*
Packit Service 310c69
   * The first part of this structure must be exactly parallel to the
Packit Service 310c69
   * UdsRequest structure, which is part of the public UDS API.
Packit Service 310c69
   */
Packit Service 310c69
  UdsChunkName      chunkName;    // hash value
Packit Service 310c69
  UdsChunkData      oldMetadata;  // metadata from index
Packit Service 310c69
  UdsChunkData      newMetadata;  // metadata from request
Packit Service 310c69
  UdsChunkCallback *callback;     // callback method when complete
Packit Service 310c69
  struct uds_index_session *session; // The public index session
Packit Service 310c69
  UdsCallbackType   type;            // the type of request
Packit Service 310c69
  int               status;          // success or error code for this request
Packit Service 310c69
  bool              found;           // True if the block was found in index
Packit Service 310c69
  bool              update;          // move record to newest chapter if found
Packit Service 310c69
Packit Service 310c69
  /*
Packit Service 310c69
   * The remainder of this structure is private to the UDS implementation.
Packit Service 310c69
   */
Packit Service 310c69
  FunnelQueueEntry  requestQueueLink; // for lock-free request queue
Packit Service 310c69
  Request          *nextRequest;
Packit Service 310c69
  IndexRouter      *router;
Packit Service 310c69
Packit Service 310c69
  // Data for control message requests
Packit Service 310c69
  ZoneMessage zoneMessage;
Packit Service 310c69
  bool        isControlMessage;
Packit Service 310c69
Packit Service 310c69
  bool          unbatched;      // if true, must wake worker when enqueued
Packit Service 310c69
  bool          requeued;
Packit Service 310c69
  RequestAction action;         // the action for the index to perform
Packit Service 310c69
  unsigned int  zoneNumber;     // the zone for this request to use
Packit Service 310c69
  IndexRegion   location;       // if and where the block was found
Packit Service 310c69
Packit Service 310c69
  bool        slLocationKnown;  // slow lane has determined a location
Packit Service 310c69
  IndexRegion slLocation;       // location determined by slowlane
Packit Service 310c69
};
Packit Service 310c69
Packit Service 310c69
typedef void (*RequestRestarter)(Request *);
Packit Service 310c69
Packit Service 310c69
/**
Packit Service 310c69
 * Make an asynchronous control message for an index zone and enqueue it for
Packit Service 310c69
 * processing.
Packit Service 310c69
 *
Packit Service 310c69
 * @param action   The control action to perform
Packit Service 310c69
 * @param message  The message to send
Packit Service 310c69
 * @param zone     The zone number of the zone to receive the message
Packit Service 310c69
 * @param router   The index router responsible for handling the message
Packit Service 310c69
 *
Packit Service 310c69
 * @return UDS_SUCCESS or an error code
Packit Service 310c69
 **/
Packit Service 310c69
int launchZoneControlMessage(RequestAction  action,
Packit Service 310c69
                             ZoneMessage    message,
Packit Service 310c69
                             unsigned int   zone,
Packit Service 310c69
                             IndexRouter   *router)
Packit Service 310c69
  __attribute__((warn_unused_result));
Packit Service 310c69
Packit Service 310c69
/**
Packit Service 310c69
 * Free an index request.
Packit Service 310c69
 *
Packit Service 310c69
 * @param request The request to free
Packit Service 310c69
 **/
Packit Service 310c69
void freeRequest(Request *request);
Packit Service 310c69
Packit Service 310c69
/**
Packit Service 310c69
 * Enqueue a request for the next stage of the pipeline. If there is more than
Packit Service 310c69
 * one possible queue for a stage, this function uses the request to decide
Packit Service 310c69
 * which queue should handle it.
Packit Service 310c69
 *
Packit Service 310c69
 * @param request       The request to enqueue
Packit Service 310c69
 * @param nextStage     The next stage of the pipeline to process the request
Packit Service 310c69
 **/
Packit Service 310c69
void enqueueRequest(Request *request, RequestStage nextStage);
Packit Service 310c69
Packit Service 310c69
/**
Packit Service 310c69
 * A method to restart delayed requests.
Packit Service 310c69
 *
Packit Service 310c69
 * @param request    The request to restart
Packit Service 310c69
 **/
Packit Service 310c69
void restartRequest(Request *request);
Packit Service 310c69
Packit Service 310c69
/**
Packit Service 310c69
 * Set the function pointer which is used to restart requests.
Packit Service 310c69
 * This is needed by albserver code and is used as a test hook by the unit
Packit Service 310c69
 * tests.
Packit Service 310c69
 *
Packit Service 310c69
 * @param restarter   The function to call to restart requests.
Packit Service 310c69
 **/
Packit Service 310c69
void setRequestRestarter(RequestRestarter restarter);
Packit Service 310c69
Packit Service 310c69
/**
Packit Service 310c69
 * Enter the callback stage of processing for a request, notifying the waiting
Packit Service 310c69
 * thread if the request is synchronous, freeing the request if it is an
Packit Service 310c69
 * asynchronous control message, or placing it on the callback queue if it is
Packit Service 310c69
 * an asynchronous client request.
Packit Service 310c69
 *
Packit Service 310c69
 * @param request  the request which has completed execution
Packit Service 310c69
 **/
Packit Service 310c69
void enterCallbackStage(Request *request);
Packit Service 310c69
Packit Service 310c69
/**
Packit Service 310c69
 * Update the context statistics to reflect the successful completion of a
Packit Service 310c69
 * client request.
Packit Service 310c69
 *
Packit Service 310c69
 * @param request  a client request that has successfully completed execution
Packit Service 310c69
 **/
Packit Service 310c69
void updateRequestContextStats(Request *request);
Packit Service 310c69
Packit Service 310c69
/**
Packit Service 310c69
 * Compute the CacheProbeType value reflecting the request and page type.
Packit Service 310c69
 *
Packit Service 310c69
 * @param request      The request being processed, or NULL
Packit Service 310c69
 * @param isIndexPage  Whether the cache probe will be for an index page
Packit Service 310c69
 *
Packit Service 310c69
 * @return the cache probe type enumeration
Packit Service 310c69
 **/
Packit Service 310c69
static INLINE CacheProbeType cacheProbeType(Request *request,
Packit Service 310c69
                                            bool     isIndexPage)
Packit Service 310c69
{
Packit Service 310c69
  if ((request != NULL) && request->requeued) {
Packit Service 310c69
    return isIndexPage ? CACHE_PROBE_INDEX_RETRY : CACHE_PROBE_RECORD_RETRY;
Packit Service 310c69
  } else {
Packit Service 310c69
    return isIndexPage ? CACHE_PROBE_INDEX_FIRST : CACHE_PROBE_RECORD_FIRST;
Packit Service 310c69
  }
Packit Service 310c69
}
Packit Service 310c69
#endif /* REQUEST_H */