// Copyright 2023 The Chromium Authors // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #ifndef BASE_METRICS_HISTOGRAM_SHARED_MEMORY_H_ #define BASE_METRICS_HISTOGRAM_SHARED_MEMORY_H_ #include #include #include "base/base_export.h" #include "base/command_line.h" #include "base/feature_list.h" #include "base/memory/unsafe_shared_memory_region.h" #include "base/metrics/persistent_memory_allocator.h" #include "base/process/launch.h" #include "build/build_config.h" #if BUILDFLAG(IS_POSIX) && !BUILDFLAG(IS_APPLE) #include "base/files/platform_file.h" #include "base/posix/global_descriptors.h" #endif #if !BUILDFLAG(USE_BLINK) #error "This is only intended for platforms that use blink." #endif namespace base { BASE_EXPORT BASE_DECLARE_FEATURE(kPassHistogramSharedMemoryOnLaunch); // Helper structure to create and return a shared memory region and a histogram // allocator over top of it. Once returned it is expected that the caller will // move both the memory regions and the allocator out of the struct and into // it's own appropriate state variables. Note that the memory region must // outlive the allocator. struct BASE_EXPORT HistogramSharedMemory { HistogramSharedMemory() = delete; ~HistogramSharedMemory() = delete; HistogramSharedMemory(HistogramSharedMemory&) = delete; HistogramSharedMemory(HistogramSharedMemory&&) = delete; HistogramSharedMemory& operator=(HistogramSharedMemory&) = delete; HistogramSharedMemory& operator=(HistogramSharedMemory&&) = delete; // Configuration with which to create a histogram shared memory region and // allocator. Note the expectation that this be initialized with static // data for the allocator name (i.e., a string literal or static constant // character array). struct BASE_EXPORT Config { const int process_type; // See: content/public/common/process_type.h const std::string_view allocator_name; const size_t memory_size_bytes; }; // Temporary structure used to return the shared memory region and allocator // created by the |Create| factory function. The caller is expected to move // the returned values out of this struct. struct BASE_EXPORT SharedMemory { UnsafeSharedMemoryRegion region; std::unique_ptr allocator; SharedMemory(UnsafeSharedMemoryRegion, std::unique_ptr); ~SharedMemory(); // Movable SharedMemory(SharedMemory&&); SharedMemory& operator=(SharedMemory&&); // Not copyable SharedMemory(SharedMemory&) = delete; SharedMemory& operator=(SharedMemory&) = delete; }; // Factory to initialize a shared |memory_region| and |allocator| for // |process_id| based on |config|. On success, returns true and updates // the values of |memory_region| and |allocator|. On failure, returns false // and |memory_region| and |allocator| are unchanged. static std::optional Create(int process_id, const Config& config); #if BUILDFLAG(IS_APPLE) // Exposed for testing. static const MachPortsForRendezvous::key_type kRendezvousKey; #endif // Returns true if passing the shared memory handle via command-line arguments // is enabled. static bool PassOnCommandLineIsEnabled(std::string_view process_type); // Updates the launch parameters to share |unsafe_memory_region| to a // child process that is about to be launched. This should be called in the // parent process as a part of setting up the launch conditions of the child. // This call will update the |command_line| and |launch_options|. On posix, // where we prefer to use a zygote instead of using the launch_options to // launch a new process, the platform |descriptor_to_share| is returned. The // caller is expected to transmit the descriptor to the launch flow for the // zygote. static void AddToLaunchParameters( UnsafeSharedMemoryRegion unsafe_memory_region, #if BUILDFLAG(IS_POSIX) && !BUILDFLAG(IS_APPLE) GlobalDescriptors::Key descriptor_key, ScopedFD& descriptor_to_share, #endif CommandLine* command_line, LaunchOptions* launch_options); // Initialize the (global) histogram shared memory from the launch parameters. // This should be called in the child process before any histogram samples are // recorded. static void InitFromLaunchParameters(const CommandLine& command_line); }; } // namespace base #endif // BASE_METRICS_HISTOGRAM_SHARED_MEMORY_H_