blob: 974469e436f2d7bcf3a7350f43a42379b7d6aa8b [file] [log] [blame]
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -08001/*
2 *
Jan Tattermusch7897ae92017-06-07 22:57:36 +02003 * Copyright 2015 gRPC authors.
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -08004 *
Jan Tattermusch7897ae92017-06-07 22:57:36 +02005 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -08008 *
Jan Tattermusch7897ae92017-06-07 22:57:36 +02009 * http://www.apache.org/licenses/LICENSE-2.0
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080010 *
Jan Tattermusch7897ae92017-06-07 22:57:36 +020011 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080016 *
17 */
18
Craig Tiller9a4dddd2016-03-25 17:08:13 -070019#ifndef GRPC_CORE_LIB_TRANSPORT_METADATA_H
20#define GRPC_CORE_LIB_TRANSPORT_METADATA_H
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080021
Craig Tiller7c70b6c2017-01-23 07:48:42 -080022#include <grpc/grpc.h>
Craig Tillerb37d53e2016-10-26 16:16:35 -070023#include <grpc/slice.h>
ctillerfb93d192014-12-15 10:40:05 -080024#include <grpc/support/useful.h>
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080025
Craig Tiller87a7e1f2016-11-09 09:42:19 -080026#include "src/core/lib/iomgr/exec_ctx.h"
27
ncteisen4b584052017-06-08 16:44:38 -070028#ifndef NDEBUG
29extern grpc_tracer_flag grpc_trace_metadata;
30#endif
31
Mark D. Roth07cd9c92016-06-27 10:14:38 -070032#ifdef __cplusplus
33extern "C" {
34#endif
35
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080036/* This file provides a mechanism for tracking metadata through the grpc stack.
37 It's not intended for consumption outside of the library.
38
39 Metadata is tracked in the context of a grpc_mdctx. For the time being there
40 is one of these per-channel, avoiding cross channel interference with memory
41 use and lock contention.
42
43 The context tracks unique strings (grpc_mdstr) and pairs of strings
44 (grpc_mdelem). Any of these objects can be checked for equality by comparing
45 their pointers. These objects are reference counted.
46
47 grpc_mdelem can additionally store a (non-NULL) user data pointer. This
48 pointer is intended to be used to cache semantic meaning of a metadata
49 element. For example, an OAuth token may cache the credentials it represents
50 and the time at which it expires in the mdelem user data.
51
52 Combining this metadata cache and the hpack compression table allows us to
53 simply lookup complete preparsed objects quickly, incurring a few atomic
54 ops per metadata element on the fast path.
55
56 grpc_mdelem instances MAY live longer than their refcount implies, and are
57 garbage collected periodically, meaning cached data can easily outlive a
Craig Tiller70b080d2015-11-19 08:04:48 -080058 single request.
59
60 STATIC METADATA: in static_metadata.h we declare a set of static metadata.
61 These mdelems and mdstrs are available via pre-declared code generated macros
62 and are available to code anywhere between grpc_init() and grpc_shutdown().
63 They are not refcounted, but can be passed to _ref and _unref functions
64 declared here - in which case those functions are effectively no-ops. */
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080065
66/* Forward declarations */
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080067typedef struct grpc_mdelem grpc_mdelem;
68
Craig Tiller7c70b6c2017-01-23 07:48:42 -080069/* if changing this, make identical changes in:
70 - interned_metadata, allocated_metadata in metadata.c
71 - grpc_metadata in grpc_types.h */
72typedef struct grpc_mdelem_data {
73 const grpc_slice key;
74 const grpc_slice value;
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080075 /* there is a private part to this in metadata.c */
Craig Tiller7c70b6c2017-01-23 07:48:42 -080076} grpc_mdelem_data;
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080077
Craig Tiller7c70b6c2017-01-23 07:48:42 -080078/* GRPC_MDELEM_STORAGE_* enum values that can be treated as interned always have
79 this bit set in their integer value */
80#define GRPC_MDELEM_STORAGE_INTERNED_BIT 1
81
82typedef enum {
83 /* memory pointed to by grpc_mdelem::payload is owned by an external system */
84 GRPC_MDELEM_STORAGE_EXTERNAL = 0,
85 /* memory pointed to by grpc_mdelem::payload is interned by the metadata
86 system */
87 GRPC_MDELEM_STORAGE_INTERNED = GRPC_MDELEM_STORAGE_INTERNED_BIT,
88 /* memory pointed to by grpc_mdelem::payload is allocated by the metadata
89 system */
90 GRPC_MDELEM_STORAGE_ALLOCATED = 2,
91 /* memory is in the static metadata table */
92 GRPC_MDELEM_STORAGE_STATIC = 2 | GRPC_MDELEM_STORAGE_INTERNED_BIT,
93} grpc_mdelem_data_storage;
94
Craig Tiller5e01e2a2017-01-20 18:11:52 -080095struct grpc_mdelem {
Craig Tiller7c70b6c2017-01-23 07:48:42 -080096 /* a grpc_mdelem_data* generally, with the two lower bits signalling memory
97 ownership as per grpc_mdelem_data_storage */
98 uintptr_t payload;
Craig Tiller5e01e2a2017-01-20 18:11:52 -080099};
Craig Tiller9ecadce2016-11-18 14:52:25 -0800100
Craig Tiller7c70b6c2017-01-23 07:48:42 -0800101#define GRPC_MDELEM_DATA(md) \
102 ((grpc_mdelem_data *)((md).payload & ~(uintptr_t)3))
103#define GRPC_MDELEM_STORAGE(md) \
104 ((grpc_mdelem_data_storage)((md).payload & (uintptr_t)3))
105#define GRPC_MAKE_MDELEM(data, storage) \
106 ((grpc_mdelem){((uintptr_t)(data)) | ((uintptr_t)storage)})
107#define GRPC_MDELEM_IS_INTERNED(md) \
108 ((grpc_mdelem_data_storage)((md).payload & \
109 (uintptr_t)GRPC_MDELEM_STORAGE_INTERNED_BIT))
Craig Tiller5e01e2a2017-01-20 18:11:52 -0800110
Julien Boeuf75c9b6f2015-05-29 13:12:12 -0700111/* Unrefs the slices. */
Craig Tiller7c70b6c2017-01-23 07:48:42 -0800112grpc_mdelem grpc_mdelem_from_slices(grpc_exec_ctx *exec_ctx, grpc_slice key,
113 grpc_slice value);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800114
Craig Tiller7c70b6c2017-01-23 07:48:42 -0800115/* Cheaply convert a grpc_metadata to a grpc_mdelem; may use the grpc_metadata
116 object as backing storage (so lifetimes should align) */
117grpc_mdelem grpc_mdelem_from_grpc_metadata(grpc_exec_ctx *exec_ctx,
118 grpc_metadata *metadata);
119
120/* Does not unref the slices; if a new non-interned mdelem is needed, allocates
121 one if compatible_external_backing_store is NULL, or uses
122 compatible_external_backing_store if it is non-NULL (in which case it's the
123 users responsibility to ensure that it outlives usage) */
124grpc_mdelem grpc_mdelem_create(
125 grpc_exec_ctx *exec_ctx, grpc_slice key, grpc_slice value,
126 grpc_mdelem_data *compatible_external_backing_store);
127
128bool grpc_mdelem_eq(grpc_mdelem a, grpc_mdelem b);
129
130size_t grpc_mdelem_get_size_in_hpack_table(grpc_mdelem elem);
yang-gcb7a8022016-03-30 14:58:53 -0700131
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800132/* Mutator and accessor for grpc_mdelem user data. The destructor function
133 is used as a type tag and is checked during user_data fetch. */
Craig Tiller7c70b6c2017-01-23 07:48:42 -0800134void *grpc_mdelem_get_user_data(grpc_mdelem md,
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800135 void (*if_destroy_func)(void *));
Craig Tiller7c70b6c2017-01-23 07:48:42 -0800136void *grpc_mdelem_set_user_data(grpc_mdelem md, void (*destroy_func)(void *),
Craig Tiller738e6db2016-11-15 09:29:44 -0800137 void *user_data);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800138
ncteisen4b584052017-06-08 16:44:38 -0700139#ifndef NDEBUG
Craig Tiller1a65a232015-07-06 10:22:32 -0700140#define GRPC_MDELEM_REF(s) grpc_mdelem_ref((s), __FILE__, __LINE__)
Craig Tillera59c16c2016-10-31 07:25:01 -0700141#define GRPC_MDELEM_UNREF(exec_ctx, s) \
142 grpc_mdelem_unref((exec_ctx), (s), __FILE__, __LINE__)
Craig Tiller7c70b6c2017-01-23 07:48:42 -0800143grpc_mdelem grpc_mdelem_ref(grpc_mdelem md, const char *file, int line);
144void grpc_mdelem_unref(grpc_exec_ctx *exec_ctx, grpc_mdelem md,
Craig Tillera59c16c2016-10-31 07:25:01 -0700145 const char *file, int line);
Craig Tiller1a65a232015-07-06 10:22:32 -0700146#else
Craig Tiller1a65a232015-07-06 10:22:32 -0700147#define GRPC_MDELEM_REF(s) grpc_mdelem_ref((s))
Craig Tillera59c16c2016-10-31 07:25:01 -0700148#define GRPC_MDELEM_UNREF(exec_ctx, s) grpc_mdelem_unref((exec_ctx), (s))
Craig Tiller7c70b6c2017-01-23 07:48:42 -0800149grpc_mdelem grpc_mdelem_ref(grpc_mdelem md);
150void grpc_mdelem_unref(grpc_exec_ctx *exec_ctx, grpc_mdelem md);
Craig Tiller1a65a232015-07-06 10:22:32 -0700151#endif
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800152
Craig Tiller7c70b6c2017-01-23 07:48:42 -0800153#define GRPC_MDKEY(md) (GRPC_MDELEM_DATA(md)->key)
154#define GRPC_MDVALUE(md) (GRPC_MDELEM_DATA(md)->value)
Craig Tiller0160de92016-11-18 08:46:46 -0800155
Craig Tiller7c70b6c2017-01-23 07:48:42 -0800156#define GRPC_MDNULL GRPC_MAKE_MDELEM(NULL, GRPC_MDELEM_STORAGE_EXTERNAL)
157#define GRPC_MDISNULL(md) (GRPC_MDELEM_DATA(md) == NULL)
Craig Tiller0160de92016-11-18 08:46:46 -0800158
Mark D. Rothc2de4522016-04-29 10:25:27 -0700159/* We add 32 bytes of padding as per RFC-7540 section 6.5.2. */
Craig Tiller7c70b6c2017-01-23 07:48:42 -0800160#define GRPC_MDELEM_LENGTH(e) \
161 (GRPC_SLICE_LENGTH(GRPC_MDKEY((e))) + GRPC_SLICE_LENGTH(GRPC_MDVALUE((e))) + \
162 32)
murgatroid99c3910ca2016-01-06 13:14:23 -0800163
ctillerfb93d192014-12-15 10:40:05 -0800164#define GRPC_MDSTR_KV_HASH(k_hash, v_hash) (GPR_ROTL((k_hash), 2) ^ (v_hash))
165
Craig Tiller0e72ede2015-11-19 07:48:53 -0800166void grpc_mdctx_global_init(void);
Craig Tillera59c16c2016-10-31 07:25:01 -0700167void grpc_mdctx_global_shutdown(grpc_exec_ctx *exec_ctx);
Craig Tiller0e72ede2015-11-19 07:48:53 -0800168
Mark D. Roth07cd9c92016-06-27 10:14:38 -0700169#ifdef __cplusplus
170}
171#endif
172
Craig Tiller9a4dddd2016-03-25 17:08:13 -0700173#endif /* GRPC_CORE_LIB_TRANSPORT_METADATA_H */