| #include "tlbmc/hal/shared_mem/server.h" |
| |
| #include <cstdint> |
| #include <filesystem> // NOLINT |
| #include <limits> |
| #include <memory> |
| #include <string> |
| #include <string_view> |
| #include <utility> |
| |
| #include "absl/base/no_destructor.h" |
| #include "absl/log/log.h" |
| #include "absl/status/status.h" |
| #include "absl/status/statusor.h" |
| #include "absl/synchronization/mutex.h" |
| #include "absl/time/time.h" |
| #include "tlbmc/hal/shared_mem/metrics.h" |
| #include "tlbmc/hal/shared_mem/segment_manager.h" |
| #include "tlbmc/hal/shared_mem/sensors.h" |
| |
| namespace milotic_tlbmc { |
| |
| void SharedMemoryServer::Initialize() { return Initialize(""); } |
| |
| void SharedMemoryServer::SetUpInstanceForUnitTest() { |
| // Remove the shared memory object and the initialized file to ensure a clean |
| // state for unit tests. |
| if (!boost::interprocess::shared_memory_object::remove("TlbmcSharedMemory")) { |
| LOG(WARNING) << "Shared memory object not removed successfully."; |
| } else { |
| LOG(INFO) << "Shared memory object removed successfully."; |
| } |
| |
| if (!std::filesystem::remove("/tmp/tlbmc/tlbmc_shared_memory")) { |
| LOG(WARNING) << "Shared memory flag file /tmp/tlbmc/tlbmc_shared_memory " |
| "was not removed successfully."; |
| } else { |
| LOG(INFO) << "Shared memory flag file /tmp/tlbmc/tlbmc_shared_memory was " |
| "removed."; |
| } |
| GetInstance("/tmp/tlbmc/tlbmc_shared_memory"); |
| } |
| |
| void SharedMemoryServer::Initialize(const std::string& initialized_file_path) { |
| SharedMemoryServer::GetInstance(initialized_file_path); |
| } |
| |
| IpcServer& SharedMemoryServer::GetInstance( |
| const std::string& initialized_file_path) { |
| static absl::NoDestructor<SharedMemoryServer> instance( |
| Token(), initialized_file_path, |
| initialized_file_path.empty() |
| ? SegmentManager::Create() |
| : SegmentManager::Create(initialized_file_path)); |
| return *instance; |
| } |
| |
| IpcServer& SharedMemoryServer::GetInstance() { return GetInstance(""); } |
| |
| SharedMemoryServer::SharedMemoryServer( |
| Token token, const std::string& initialized_file_path, |
| std::unique_ptr<SegmentManager> segment_manager) |
| : initialized_file_path_(std::string{initialized_file_path}), |
| segment_manager_(std::move(segment_manager)), |
| metrics_(segment_manager_ == nullptr |
| ? nullptr |
| : segment_manager_->GetOrCreateMetrics()) { |
| if (segment_manager_ == nullptr) { |
| LOG(FATAL) << "SharedMemoryServer segment_manager is nullptr. This should " |
| "never happen in server side. Check the initialization log."; |
| } |
| } |
| |
| SharedMemoryServer::SharedMemoryServer( |
| const std::string& initialized_file_path, |
| std::unique_ptr<SegmentManager> segment_manager) |
| : SharedMemoryServer(Token(), initialized_file_path, |
| std::move(segment_manager)) {} |
| |
| IpcSensor* SharedMemoryServer::GetSensor(const std::string& sensor_name) { |
| absl::MutexLock lock(&sensors_mutex_); |
| auto it = sensors_.find(sensor_name); |
| if (it != sensors_.end()) { |
| return it->second; |
| } |
| DLOG(INFO) << "SharedMemoryServer segment_manager: " |
| << segment_manager_.get(); |
| IpcSensor* sensor = segment_manager_->GetOrCreateSensor(sensor_name.c_str()); |
| DLOG(INFO) << "SharedMemoryServer sensor for " << sensor_name << ": " |
| << sensor; |
| sensors_[sensor_name] = sensor; |
| return sensor; |
| } |
| |
| absl::StatusOr<std::pair<float, uint64_t>> SharedMemoryServer::ReadSensorValue( |
| const std::string& sensor_name) { |
| IpcSensor* sensor = GetSensor(sensor_name); |
| if (sensor == nullptr) { |
| return absl::InternalError( |
| "Failed to get sensor. This normally should not happen."); |
| } |
| |
| std::pair<float, uint64_t> value = sensor->GetValue(); |
| |
| // If the sensor value is not updated by the client, the value will be set to |
| // infinity and the timestamp will be 0. |
| if (value.first == std::numeric_limits<float>::infinity() || |
| value.second == 0) { |
| return absl::UnavailableError( |
| "Sensor value is still invalid due to no update from client."); |
| } |
| return value; |
| } |
| |
| // copybara:strip_begin(g3-shared-libs) |
| void SharedMemoryServer::UpdateMetricsRequestCount(bool is_tlbmc_request) { |
| if (metrics_ == nullptr) { |
| return; |
| } |
| metrics_->UpdateMetricsRequestCount(is_tlbmc_request); |
| } |
| |
| void SharedMemoryServer::UpdateMetricsResponse(absl::Duration response_time, |
| int status_code, |
| std::string_view resource_url) { |
| if (metrics_ == nullptr) { |
| return; |
| } |
| metrics_->UpdateMetricsResponse(response_time, status_code, resource_url); |
| } |
| // copybara:strip_end |
| |
| } // namespace milotic_tlbmc |