| 140 | } |
| 141 | |
| 142 | Status LibCache::GetSoFunctionPtr(const string& hdfs_lib_file, const string& symbol, |
| 143 | time_t exp_mtime, void** fn_ptr, LibCacheEntry** ent, bool quiet) { |
| 144 | if (hdfs_lib_file.empty()) { |
| 145 | // Just loading a function ptr in the current process. No need to take any locks. |
| 146 | DCHECK(current_process_handle_ != nullptr); |
| 147 | RETURN_IF_ERROR(DynamicLookup(current_process_handle_, symbol.c_str(), fn_ptr, quiet)); |
| 148 | return Status::OK(); |
| 149 | } |
| 150 | |
| 151 | LibCacheEntry* entry = nullptr; |
| 152 | unique_lock<mutex> lock; |
| 153 | if (ent != nullptr && *ent != nullptr) { |
| 154 | // Reuse already-cached entry provided by user |
| 155 | entry = *ent; |
| 156 | unique_lock<mutex> l(entry->lock); |
| 157 | lock.swap(l); |
| 158 | } else { |
| 159 | RETURN_IF_ERROR(GetCacheEntry(hdfs_lib_file, TYPE_SO, exp_mtime, &lock, &entry)); |
| 160 | } |
| 161 | DCHECK(entry != nullptr); |
| 162 | DCHECK_EQ(entry->type, TYPE_SO); |
| 163 | LibCacheEntry::SymbolMap::iterator it = entry->symbol_cache.find(symbol); |
| 164 | if (it != entry->symbol_cache.end()) { |
| 165 | *fn_ptr = it->second; |
| 166 | } else { |
| 167 | RETURN_IF_ERROR( |
| 168 | DynamicLookup(entry->shared_object_handle, symbol.c_str(), fn_ptr, quiet)); |
| 169 | entry->symbol_cache[symbol] = *fn_ptr; |
| 170 | } |
| 171 | |
| 172 | DCHECK(*fn_ptr != nullptr); |
| 173 | if (ent != nullptr && *ent == nullptr) { |
| 174 | // Only set and increment user's entry if it wasn't already cached |
| 175 | *ent = entry; |
| 176 | ++(*ent)->use_count; |
| 177 | } |
| 178 | return Status::OK(); |
| 179 | } |
| 180 | |
| 181 | void LibCache::DecrementUseCount(LibCacheEntry* entry) { |
| 182 | if (entry == nullptr) return; |
no test coverage detected