| 127 | } |
| 128 | |
| 129 | int Variable::expose_impl(const butil::StringPiece& prefix, |
| 130 | const butil::StringPiece& name, |
| 131 | DisplayFilter display_filter) { |
| 132 | if (name.empty()) { |
| 133 | LOG(ERROR) << "Parameter[name] is empty"; |
| 134 | return -1; |
| 135 | } |
| 136 | // NOTE: It's impossible to atomically erase from a submap and insert into |
| 137 | // another submap without a global lock. When the to-be-exposed name |
| 138 | // already exists, there's a chance that we can't insert back previous |
| 139 | // name. But it should be fine generally because users are unlikely to |
| 140 | // expose a variable more than once and calls to expose() are unlikely |
| 141 | // to contend heavily. |
| 142 | |
| 143 | // remove previous pointer from the map if needed. |
| 144 | hide(); |
| 145 | |
| 146 | // Build the name. |
| 147 | _name.clear(); |
| 148 | _name.reserve((prefix.size() + name.size()) * 5 / 4); |
| 149 | if (!prefix.empty()) { |
| 150 | to_underscored_name(&_name, prefix); |
| 151 | if (!_name.empty() && butil::back_char(_name) != '_') { |
| 152 | _name.push_back('_'); |
| 153 | } |
| 154 | } |
| 155 | to_underscored_name(&_name, name); |
| 156 | |
| 157 | VarMapWithLock& m = get_var_map(_name); |
| 158 | { |
| 159 | BAIDU_SCOPED_LOCK(m.mutex); |
| 160 | VarEntry* entry = m.seek(_name); |
| 161 | if (entry == NULL) { |
| 162 | entry = &m[_name]; |
| 163 | entry->var = this; |
| 164 | entry->display_filter = display_filter; |
| 165 | return 0; |
| 166 | } |
| 167 | } |
| 168 | RELEASE_ASSERT_VERBOSE(!FLAGS_bvar_abort_on_same_name, |
| 169 | "Abort due to name conflict"); |
| 170 | if (!s_bvar_may_abort) { |
| 171 | // Mark name conflict occurs, If this conflict happens before |
| 172 | // initialization of bvar_abort_on_same_name, the validator will |
| 173 | // abort the program if needed. |
| 174 | s_bvar_may_abort = true; |
| 175 | } |
| 176 | |
| 177 | LOG(ERROR) << "Already exposed `" << _name << "' whose value is `" |
| 178 | << describe_exposed(_name) << '\''; |
| 179 | _name.clear(); |
| 180 | return -1; |
| 181 | } |
| 182 | |
| 183 | bool Variable::is_hidden() const { |
| 184 | return _name.empty(); |