| 137 | } |
| 138 | |
| 139 | int MVariableBase::expose_impl(const butil::StringPiece& prefix, |
| 140 | const butil::StringPiece& name) { |
| 141 | if (name.empty()) { |
| 142 | LOG(ERROR) << "Parameter[name] is empty"; |
| 143 | return -1; |
| 144 | } |
| 145 | // NOTE: It's impossible to atomically erase from a submap and insert into |
| 146 | // another submap without a global lock. When the to-be-exposed name |
| 147 | // already exists, there's a chance that we can't insert back previous |
| 148 | // name. But it should be fine generally because users are unlikely to |
| 149 | // expose a variable more than once and calls to expose() are unlikely |
| 150 | // to contend heavily. |
| 151 | |
| 152 | // remove previous pointer from the map if needed. |
| 153 | hide(); |
| 154 | |
| 155 | // Build the name. |
| 156 | _name.clear(); |
| 157 | _name.reserve((prefix.size() + name.size()) * 5 / 4); |
| 158 | if (!prefix.empty()) { |
| 159 | to_underscored_name(&_name, prefix); |
| 160 | if (!_name.empty() && butil::back_char(_name) != '_') { |
| 161 | _name.push_back('_'); |
| 162 | } |
| 163 | } |
| 164 | to_underscored_name(&_name, name); |
| 165 | |
| 166 | if (count_exposed() > (size_t)FLAGS_bvar_max_multi_dimension_metric_number) { |
| 167 | LOG(ERROR) << "Too many metric seen, overflow detected, max metric count:" << FLAGS_bvar_max_multi_dimension_metric_number; |
| 168 | return -1; |
| 169 | } |
| 170 | |
| 171 | MVarMapWithLock& m = get_mvar_map(); |
| 172 | { |
| 173 | BAIDU_SCOPED_LOCK(m.mutex); |
| 174 | MVarEntry* entry = m.seek(_name); |
| 175 | if (entry == NULL) { |
| 176 | entry = &m[_name]; |
| 177 | entry->var = this; |
| 178 | return 0; |
| 179 | } |
| 180 | } |
| 181 | |
| 182 | RELEASE_ASSERT_VERBOSE(!FLAGS_bvar_abort_on_same_name, |
| 183 | "Abort due to name conflict"); |
| 184 | if (!s_bvar_may_abort) { |
| 185 | // Mark name conflict occurs, If this conflict happens before |
| 186 | // initialization of bvar_abort_on_same_name, the validator will |
| 187 | // abort the program if needed. |
| 188 | s_bvar_may_abort = true; |
| 189 | } |
| 190 | |
| 191 | LOG(WARNING) << "Already exposed `" << _name << "' whose describe is`" |
| 192 | << get_description() << "'"; |
| 193 | _name.clear(); |
| 194 | return 0; |
| 195 | } |
| 196 | |