1 /*
2  *
3  * Copyright 2016 gRPC authors.
4  *
5  * 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
8  *
9  *     http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * 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.
16  *
17  */
18 
19 #ifndef GRPC_CORE_LIB_SURFACE_CHANNEL_INIT_H
20 #define GRPC_CORE_LIB_SURFACE_CHANNEL_INIT_H
21 
22 #include <grpc/support/port_platform.h>
23 
24 #include <functional>
25 #include <vector>
26 
27 #include "src/core/lib/surface/channel_stack_type.h"
28 
29 #define GRPC_CHANNEL_INIT_BUILTIN_PRIORITY 10000
30 
31 /// This module provides a way for plugins (and the grpc core library itself)
32 /// to register mutators for channel stacks.
33 /// It also provides a universal entry path to run those mutators to build
34 /// a channel stack for various subsystems.
35 
36 typedef struct grpc_channel_stack_builder grpc_channel_stack_builder;
37 
38 namespace grpc_core {
39 
40 class ChannelInit {
41  public:
42   /// One stage of mutation: call functions against \a builder to influence the
43   /// finally constructed channel stack
44   using Stage = std::function<bool(grpc_channel_stack_builder* builder)>;
45 
46   class Builder {
47    public:
48     /// Register one stage of mutators.
49     /// Stages are run in priority order (lowest to highest), and then in
50     /// registration order (in the case of a tie).
51     /// Stages are registered against one of the pre-determined channel stack
52     /// types.
53     /// If the channel stack type is GRPC_CLIENT_SUBCHANNEL, the caller should
54     /// ensure that subchannels with different filter lists will always have
55     /// different channel args. This requires setting a channel arg in case the
56     /// registration function relies on some condition other than channel args
57     /// to decide whether to add a filter or not.
58     void RegisterStage(grpc_channel_stack_type type, int priority, Stage stage);
59 
60     /// Finalize registration. No more calls to grpc_channel_init_register_stage
61     /// are allowed.
62     ChannelInit Build();
63 
64    private:
65     struct Slot {
SlotSlot66       Slot(Stage stage, int priority)
67           : stage(std::move(stage)), priority(priority) {}
68       Stage stage;
69       int priority;
70     };
71     std::vector<Slot> slots_[GRPC_NUM_CHANNEL_STACK_TYPES];
72   };
73 
74   /// Construct a channel stack of some sort: see channel_stack.h for details
75   /// \a type is the type of channel stack to create
76   /// \a builder is the channel stack builder to build into.
77   bool CreateStack(grpc_channel_stack_builder* builder,
78                    grpc_channel_stack_type type) const;
79 
80  private:
81   std::vector<Stage> slots_[GRPC_NUM_CHANNEL_STACK_TYPES];
82 };
83 
84 }  // namespace grpc_core
85 
86 #endif /* GRPC_CORE_LIB_SURFACE_CHANNEL_INIT_H */
87