polardbxengine/plugin/innodb_memcached/daemon_memcached/include/memcached/extension.h

264 lines
9.6 KiB
C

/* -*- Mode: C; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */
#ifndef MEMCACHED_EXTENSION_H
#define MEMCACHED_EXTENSION_H
#include <memcached/types.h>
#include <memcached/server_api.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* \defgroup Extension Generic Extensions API
* \addtogroup Extension
* @{
*
* Definition of the generic extension API to memcached.
*/
/**
* Response codes for extension operations.
*/
typedef enum {
/** The command executed successfully */
EXTENSION_SUCCESS = 0x00,
/** A fatal error occurred, and the server should shut down as soon
* as possible */
EXTENSION_FATAL = 0xfe,
/** Generic failure. */
EXTENSION_FAILED = 0xff
} EXTENSION_ERROR_CODE;
typedef enum {
/**
* A generic extention that don't provide a functionality to the
* memcached core, but lives in the memcached address space.
*/
EXTENSION_DAEMON = 0x00,
/**
* A log consumer
*/
EXTENSION_LOGGER,
/**
* Command extension for the ASCII protocol
*/
EXTENSION_ASCII_PROTOCOL
} extension_type_t;
/**
* Deamon extensions should provide the following descriptor when
* they register themselves.
*/
typedef struct extension_daemon_descriptor {
/**
* Get the name of the descriptor. The memory area returned by this
* function has to be valid until the descriptor is unregistered.
*/
const char* (*get_name)(void);
/**
* Deamon descriptors are stored in a linked list in the memcached
* core by using this pointer. Please do not modify this pointer
* by yourself until you have unregistered the descriptor.
* The <b>only</b> time it is safe for an extension to walk this
* list is during initialization of the modules.
*/
struct extension_daemon_descriptor *next;
} EXTENSION_DAEMON_DESCRIPTOR;
typedef enum {
EXTENSION_LOG_DETAIL,
EXTENSION_LOG_DEBUG,
EXTENSION_LOG_INFO,
EXTENSION_LOG_WARNING
} EXTENSION_LOG_LEVEL;
/**
* Log extensions should provide the following rescriptor when
* they register themselves. Please note that if you register a log
* extension it will <u>replace</u> old one. If you want to be nice to
* the user you should allow your logger to be chained.
*
* Please note that the memcached server will <b>not</b> call the log
* function if the verbosity level is too low. This is a perfomance
* optimization from the core to avoid potential formatting of output
* that may be thrown away.
*/
typedef struct {
/**
* Get the name of the descriptor. The memory area returned by this
* function has to be valid until the descriptor is unregistered.
*/
const char* (*get_name)(void);
/**
* Add an entry to the log.
* @param severity the severity for this log entry
* @param client_cookie the client we're serving (may be NULL if not
* known)
* @param fmt format string to add to the log
*/
void (*log)(EXTENSION_LOG_LEVEL severity,
const void* client_cookie,
const char *fmt, ...);
} EXTENSION_LOGGER_DESCRIPTOR;
typedef struct {
EXTENSION_LOGGER_DESCRIPTOR* (*get_logger)(void);
EXTENSION_LOG_LEVEL (*get_level)(void);
void (*set_level)(EXTENSION_LOG_LEVEL severity);
} SERVER_LOG_API;
typedef struct {
char *value;
size_t length;
} token_t;
/**
* ASCII protocol extensions must provide the following descriptor to
* extend the capabilities of the ascii protocol. The memcached core
* will probe each command in the order they are registered, so you should
* register the most likely command to be used first (or you could register
* only one descriptor and do a better dispatch routine inside your own
* implementation of accept / execute).
*/
typedef struct extension_ascii_protocol_descriptor {
/**
* Get the name of the descriptor. The memory area returned by this
* function has to be valid until the descriptor is unregistered.
*
* @param cmd_cookie cookie registered with the command
*/
const char* (*get_name)(const void *cmd_cookie);
/**
* Called by the server to determine if the command in argc, argv should
* be process by this handler.
*
* If the command accepts out-of-band data (like add / append / prepend
* / replace / set), the command must set the datapointer and ndata
* to the number of bytes it want to read (remember to account for
* the trailing "\r\n" ;-))
*
* If you need extra data, you should copy all of the argc/argv info
* you may need to execute the command, because those parameters will
* be 0 and NULL when execute is invoked...
*
* @param cmd_cookie cookie registered with the command
* @param cookie identifying the client connection
* @param argc the number of arguments
* @param argv the argument vector
* @param ndata the number of bytes in out-of-band data (OUT)
* @param ptr where the core shall write the data (OUT)
* @param noreply is this a noreply command or not...
* @return true if the command should be handled by this command handler
*/
bool (*accept)(const void *cmd_cookie,
void *cookie,
int argc,
token_t *argv,
size_t *ndata,
char **ptr);
/**
* execute the command.
*
* @param cmd_cookie cookie registered with the command
* @param cookie identifying the client connection
* @param argc the number of arguments
* @param argv the argument vector
* @param response_handler callback to add data to the return buffer
* @return Error code for the operation
*/
ENGINE_ERROR_CODE (*execute)(const void *cmd_cookie,
const void *cookie,
int argc, token_t *argv,
ENGINE_ERROR_CODE (*response_handler)(const void *cookie,
int nbytes,
const char *dta));
/**
* abort the command.
*
* @param cmd_cookie cookie registered with the command
* @param cookie identifying the client connection
*/
void (*abort)(const void *cmd_cookie, const void *cookie);
/**
* cookie for the command. This is the cookie passed to accept and
* execute, so that you can register the same functions for multiple
* commands (but tell them apart during invokations).
*/
const void *cookie;
/**
* Deamon descriptors are stored in a linked list in the memcached
* core by using this pointer. Please do not modify this pointer
* by yourself until you have unregistered the descriptor.
* The <b>only</b> time it is safe for an extension to walk this
* list is during initialization of the modules.
*/
struct extension_ascii_protocol_descriptor *next;
} EXTENSION_ASCII_PROTOCOL_DESCRIPTOR;
/**
* The signature for the "memcached_extensions_initialize" function
* exported from the loadable module.
*
* @param config configuration for this extension
* @param GET_SERVER_API pointer to a function to get a specific server
* API from. server_extension_api contains functions
* to register extensions.
* @return one of the error codes above.
*/
typedef EXTENSION_ERROR_CODE (*MEMCACHED_EXTENSIONS_INITIALIZE)(const char *config, GET_SERVER_API get_server_api);
/**
* The API provided by the server to manipulate the list of server
* server extensions.
*/
typedef struct {
/**
* Register an extension
*
* @param type The type of extension to register (ex: daemon, logger etc)
* @param extension The extension to register
* @return true if success, false otherwise
*/
bool (*register_extension)(extension_type_t type, void *extension);
/**
* Unregister an extension
*
* @param type The type of extension to unregister
* @param extension The extension to unregister
*/
void (*unregister_extension)(extension_type_t type, void *extension);
/**
* Get the registered extension for a certain type. This is useful
* if you would like to replace one of the handlers with your own
* extension to proxy functionality.
*
* @param type The type of extension to get
* @param extension Pointer to the registered event. Please note that
* if the extension allows for multiple instances of the
* extension there will be a "next" pointer inside the element
* that can be used for object traversal.
*/
void *(*get_extension)(extension_type_t type);
} SERVER_EXTENSION_API;
/**
* @}
*/
#ifdef __cplusplus
}
#endif
#endif