1 /* -*- Mode: C; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */ 2 #ifndef BUCKET_ENGINE_INTERNAL_H 3 #define BUCKET_ENGINE_INTERNAL_H 4 #include "config.h" 5 #include <memcached/engine.h> 6 #include "genhash.h" 7 #include "topkeys.h" 8 #include "bucket_engine.h" 9 10 typedef union proxied_engine { 11 ENGINE_HANDLE *v0; 12 ENGINE_HANDLE_V1 *v1; 13 } proxied_engine_t; 14 15 typedef enum { 16 STATE_NULL, 17 STATE_RUNNING, 18 STATE_STOPPING, 19 STATE_STOPPED 20 } bucket_state_t; 21 22 typedef struct proxied_engine_handle { 23 const char *name; 24 size_t name_len; 25 proxied_engine_t pe; 26 void *stats; 27 topkeys_t **topkeys; 28 TAP_ITERATOR tap_iterator; 29 bool tap_iterator_disabled; 30 /* ON_DISCONNECT handling */ 31 volatile bool wants_disconnects; 32 /* Force shutdown flag */ 33 bool force_shutdown; 34 EVENT_CALLBACK cb; 35 const void *cb_data; 36 /* count of connections + 1 for hashtable reference + number of 37 * reserved connections for this bucket + number of temporary 38 * references created by find_bucket & frieds. 39 * 40 * count of connections is count of engine_specific instances 41 * having peh equal to this engine_handle. There's only one 42 * exception which is connections for which on_disconnect callback 43 * was called but which are kept alive by reserved > 0. For those 44 * connections we drop refcount in on_disconnect but keep peh 45 * field so that bucket_engine_release_cookie can decrement peh 46 * refcount. 47 * 48 * Handle itself can be freed when this drops to zero. This can 49 * only happen when bucket is deleted (but can happen later 50 * because some connection can hold pointer longer) */ 51 volatile int refcount; 52 volatile int clients; /* # of clients currently calling functions in the engine */ 53 const void *cookie; 54 void *dlhandle; 55 volatile bucket_state_t state; 56 } proxied_engine_handle_t; 57 58 #define ES_CONNECTED_FLAG 0x1000 59 60 /** 61 * bucket_engine needs to store data specific to a given connection. 62 * In order to do that it utilize the "engine-specific" field for a 63 * cookie. Due to the fact that the underlying engine needs to be able 64 * to use the field as well, we need a holder-structure to contain 65 * the bucket-specific data and the underlying engine-specific data. 66 */ 67 typedef struct engine_specific { 68 /** The engine this cookie is connected to */ 69 proxied_engine_handle_t *peh; 70 /** The userdata stored by the underlying engine */ 71 void *engine_specific; 72 /** The number of times the underlying engine tried to reserve 73 * this connection */ 74 /* 0x1000 is added while we think memcached connection is 75 * alive. We'll decrement it when processing ON_DISCONNECT 76 * callback. */ 77 int reserved; 78 } engine_specific_t; 79 80 81 struct bucket_engine { 82 ENGINE_HANDLE_V1 engine; 83 SERVER_HANDLE_V1 *upstream_server; 84 bool initialized; 85 bool has_default; 86 bool auto_create; 87 char *default_engine_path; 88 char *admin_user; 89 char *default_bucket_name; 90 char *default_bucket_config; 91 proxied_engine_handle_t default_engine; 92 cb_mutex_t engines_mutex; 93 genhash_t *engines; 94 GET_SERVER_API get_server_api; 95 SERVER_HANDLE_V1 server; 96 SERVER_CALLBACK_API callback_api; 97 SERVER_EXTENSION_API extension_api; 98 SERVER_COOKIE_API cookie_api; 99 100 struct { 101 bool in_progress; /* Is the global shutdown in progress */ 102 int bucket_counter; /* Number of treads currently running shutdown */ 103 cb_mutex_t mutex; 104 cb_cond_t cond; 105 /* this condition signals either in_progress being true or 106 * some bucket's refcount being 0. 107 * 108 * This means that under some conditions (lots of buckets 109 * recently deleted but still have connections assigned on 110 * them) we'll have a bit of thundering herd problem, where 111 * too many bucket deletion threads are woken up 112 * needlessly. But that can be improved much later when and if 113 * we actually find this to be a problem. */ 114 cb_cond_t refcount_cond; 115 } shutdown; 116 117 union { 118 engine_info engine_info; 119 char buffer[sizeof(engine_info) + 120 (sizeof(feature_info) * LAST_REGISTERED_ENGINE_FEATURE)]; 121 } info; 122 123 int topkeys; 124 }; 125 126 #endif 127