/src/brpc/src/butil/reloadable_flags.h
Line | Count | Source |
1 | | // Licensed to the Apache Software Foundation (ASF) under one |
2 | | // or more contributor license agreements. See the NOTICE file |
3 | | // distributed with this work for additional information |
4 | | // regarding copyright ownership. The ASF licenses this file |
5 | | // to you under the Apache License, Version 2.0 (the |
6 | | // "License"); you may not use this file except in compliance |
7 | | // with the License. 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, |
12 | | // software distributed under the License is distributed on an |
13 | | // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
14 | | // KIND, either express or implied. See the License for the |
15 | | // specific language governing permissions and limitations |
16 | | // under the License. |
17 | | |
18 | | |
19 | | #ifndef BUTIL_RELOADABLE_FLAGS_H |
20 | | #define BUTIL_RELOADABLE_FLAGS_H |
21 | | |
22 | | #include <stdint.h> |
23 | | #include <unistd.h> // write, _exit |
24 | | #include <gflags/gflags.h> |
25 | | #include "butil/macros.h" |
26 | | #include "butil/type_traits.h" |
27 | | |
28 | | // Register an always-true valiator to a gflag so that the gflag is treated as |
29 | | // reloadable by brpc. If a validator exists, abort the program. |
30 | | // You should call this macro within global scope. for example: |
31 | | // |
32 | | // DEFINE_int32(foo, 0, "blah blah"); |
33 | | // BRPC_VALIDATE_GFLAG(foo, brpc::PassValidate); |
34 | | // |
35 | | // This macro does not work for string-flags because they're thread-unsafe to |
36 | | // modify directly. To emphasize this, you have to write the validator by |
37 | | // yourself and use GFLAGS_NAMESPACE::GetCommandLineOption() to acess the flag. |
38 | | #define BUTIL_VALIDATE_GFLAG(flag, validate_fn) \ |
39 | | namespace butil_flags {} \ |
40 | | const int ALLOW_UNUSED register_FLAGS_ ## flag ## _dummy = \ |
41 | | ::butil::RegisterFlagValidatorOrDieImpl< \ |
42 | 0 | decltype(FLAGS_##flag)>(&FLAGS_##flag, (validate_fn)) |
43 | | |
44 | | |
45 | | namespace butil { |
46 | | |
47 | | template <typename T> |
48 | 0 | bool PassValidate(const char*, T) { |
49 | 0 | return true; |
50 | 0 | } |
51 | | |
52 | | template <typename T> |
53 | | bool PositiveInteger(const char*, T v) { |
54 | | return v > 0; |
55 | | } |
56 | | |
57 | | template <typename T> |
58 | 0 | bool NonNegativeInteger(const char*, T v) { |
59 | 0 | return v >= 0; |
60 | 0 | } |
61 | | |
62 | | template <typename T> |
63 | | bool RegisterFlagValidatorOrDieImpl( |
64 | 110 | const T* flag, bool (*validate_fn)(const char*, T val)) { |
65 | 110 | static_assert(!butil::is_same<std::string, T>::value, |
66 | 110 | "Not support string flags"); |
67 | 110 | if (::GFLAGS_NAMESPACE::RegisterFlagValidator(flag, validate_fn)) { |
68 | 110 | return true; |
69 | 110 | } |
70 | | // Error printed by gflags does not have newline. Add one to it. |
71 | 0 | char newline = '\n'; |
72 | 0 | butil::ignore_result(write(2, &newline, 1)); |
73 | 0 | _exit(1); |
74 | 110 | } bool butil::RegisterFlagValidatorOrDieImpl<bool>(bool const*, bool (*)(char const*, bool)) Line | Count | Source | 64 | 40 | const T* flag, bool (*validate_fn)(const char*, T val)) { | 65 | 40 | static_assert(!butil::is_same<std::string, T>::value, | 66 | 40 | "Not support string flags"); | 67 | 40 | if (::GFLAGS_NAMESPACE::RegisterFlagValidator(flag, validate_fn)) { | 68 | 40 | return true; | 69 | 40 | } | 70 | | // Error printed by gflags does not have newline. Add one to it. | 71 | 0 | char newline = '\n'; | 72 | 0 | butil::ignore_result(write(2, &newline, 1)); | 73 | 0 | _exit(1); | 74 | 40 | } |
bool butil::RegisterFlagValidatorOrDieImpl<int>(int const*, bool (*)(char const*, int)) Line | Count | Source | 64 | 64 | const T* flag, bool (*validate_fn)(const char*, T val)) { | 65 | 64 | static_assert(!butil::is_same<std::string, T>::value, | 66 | 64 | "Not support string flags"); | 67 | 64 | if (::GFLAGS_NAMESPACE::RegisterFlagValidator(flag, validate_fn)) { | 68 | 64 | return true; | 69 | 64 | } | 70 | | // Error printed by gflags does not have newline. Add one to it. | 71 | 0 | char newline = '\n'; | 72 | 0 | butil::ignore_result(write(2, &newline, 1)); | 73 | 0 | _exit(1); | 74 | 64 | } |
bool butil::RegisterFlagValidatorOrDieImpl<long>(long const*, bool (*)(char const*, long)) Line | Count | Source | 64 | 2 | const T* flag, bool (*validate_fn)(const char*, T val)) { | 65 | 2 | static_assert(!butil::is_same<std::string, T>::value, | 66 | 2 | "Not support string flags"); | 67 | 2 | if (::GFLAGS_NAMESPACE::RegisterFlagValidator(flag, validate_fn)) { | 68 | 2 | return true; | 69 | 2 | } | 70 | | // Error printed by gflags does not have newline. Add one to it. | 71 | 0 | char newline = '\n'; | 72 | 0 | butil::ignore_result(write(2, &newline, 1)); | 73 | 0 | _exit(1); | 74 | 2 | } |
bool butil::RegisterFlagValidatorOrDieImpl<unsigned long>(unsigned long const*, bool (*)(char const*, unsigned long)) Line | Count | Source | 64 | 2 | const T* flag, bool (*validate_fn)(const char*, T val)) { | 65 | 2 | static_assert(!butil::is_same<std::string, T>::value, | 66 | 2 | "Not support string flags"); | 67 | 2 | if (::GFLAGS_NAMESPACE::RegisterFlagValidator(flag, validate_fn)) { | 68 | 2 | return true; | 69 | 2 | } | 70 | | // Error printed by gflags does not have newline. Add one to it. | 71 | 0 | char newline = '\n'; | 72 | 0 | butil::ignore_result(write(2, &newline, 1)); | 73 | 0 | _exit(1); | 74 | 2 | } |
Unexecuted instantiation: bool butil::RegisterFlagValidatorOrDieImpl<double>(double const*, bool (*)(char const*, double)) bool butil::RegisterFlagValidatorOrDieImpl<unsigned int>(unsigned int const*, bool (*)(char const*, unsigned int)) Line | Count | Source | 64 | 2 | const T* flag, bool (*validate_fn)(const char*, T val)) { | 65 | 2 | static_assert(!butil::is_same<std::string, T>::value, | 66 | 2 | "Not support string flags"); | 67 | 2 | if (::GFLAGS_NAMESPACE::RegisterFlagValidator(flag, validate_fn)) { | 68 | 2 | return true; | 69 | 2 | } | 70 | | // Error printed by gflags does not have newline. Add one to it. | 71 | 0 | char newline = '\n'; | 72 | 0 | butil::ignore_result(write(2, &newline, 1)); | 73 | 0 | _exit(1); | 74 | 2 | } |
|
75 | | |
76 | | } // namespace butil |
77 | | |
78 | | |
79 | | #endif // BUTIL_RELOADABLE_FLAGS_H |