Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 74d4dc2a authored by Takaya Saeki's avatar Takaya Saeki
Browse files

ueventd: make DeviceHandler::HandleUevent thread-safe

Towards parallelizing the main loop of ueventd with threads, make
DeviceHandler::HandleUevent thread-safe. This change introduces a
necessary lock to DeviceHandler. Note that initialization part is still
not thread-safe.

Bug: 400592897
Test: Cuttlefish boots
Change-Id: I3df2889a4cc7fa737968e96a16face0142619f54
parent f83c2991
Loading
Loading
Loading
Loading
+7 −1
Original line number Diff line number Diff line
@@ -24,6 +24,7 @@
#include <chrono>
#include <filesystem>
#include <memory>
#include <mutex>
#include <string>
#include <string_view>
#include <thread>
@@ -362,6 +363,7 @@ void DeviceHandler::TrackDeviceUevent(const Uevent& uevent) {
    std::string device;
    if (!Realpath(path, &device)) return;

    std::lock_guard<std::mutex> lock(device_update_lock_);
    tracked_uevents_.emplace_back(uevent, device);
}

@@ -732,10 +734,14 @@ void DeviceHandler::HandleUevent(const Uevent& uevent) {
    }

    if (uevent.action == "bind") {
        std::lock_guard<std::mutex> lock(device_update_lock_);

        bound_drivers_[uevent.path] = uevent.driver;
        HandleBindInternal(uevent.driver, "add", uevent);
        return;
    } else if (uevent.action == "unbind") {
        std::lock_guard<std::mutex> lock(device_update_lock_);

        if (bound_drivers_.count(uevent.path) == 0) return;
        HandleBindInternal(bound_drivers_[uevent.path], "remove", uevent);

@@ -810,8 +816,8 @@ DeviceHandler::DeviceHandler(std::vector<Permissions> dev_permissions,
      sysfs_permissions_(std::move(sysfs_permissions)),
      drivers_(std::move(drivers)),
      subsystems_(std::move(subsystems)),
      boot_devices_(std::move(boot_devices)),
      boot_part_uuid_(boot_part_uuid),
      boot_devices_(std::move(boot_devices)),
      skip_restorecon_(skip_restorecon),
      sysfs_mount_point_("/sys") {
    // If both a boot partition UUID and a list of boot devices are
+16 −10
Original line number Diff line number Diff line
@@ -22,11 +22,13 @@

#include <algorithm>
#include <map>
#include <mutex>
#include <set>
#include <string>
#include <vector>

#include <android-base/file.h>
#include <android-base/thread_annotations.h>
#include <selinux/label.h>

#include "uevent.h"
@@ -135,7 +137,7 @@ class DeviceHandler : public UeventHandler {
    virtual ~DeviceHandler() = default;

    bool CheckUeventForBootPartUuid(const Uevent& uevent);
    void HandleUevent(const Uevent& uevent) override;
    void HandleUevent(const Uevent& uevent) override EXCLUDES(device_update_lock_);

    // `androidboot.partition_map` allows associating a partition name for a raw block device
    // through a comma separated and semicolon deliminated list. For example,
@@ -169,21 +171,25 @@ class DeviceHandler : public UeventHandler {
    void FixupSysPermissions(const std::string& upath, const std::string& subsystem) const;
    void HandleAshmemUevent(const Uevent& uevent);

    void TrackDeviceUevent(const Uevent& uevent);
    void HandleBindInternal(std::string driver_name, std::string action, const Uevent& uevent);
    void TrackDeviceUevent(const Uevent& uevent) EXCLUDES(device_update_lock_);
    void HandleBindInternal(std::string driver_name, std::string action, const Uevent& uevent)
            EXCLUSIVE_LOCKS_REQUIRED(device_update_lock_);

    std::vector<Permissions> dev_permissions_;
    std::vector<SysfsPermissions> sysfs_permissions_;
    std::vector<Subsystem> drivers_;
    std::vector<Subsystem> subsystems_;
    const std::vector<Permissions> dev_permissions_;
    const std::vector<SysfsPermissions> sysfs_permissions_;
    const std::vector<Subsystem> drivers_;
    const std::vector<Subsystem> subsystems_;
    const std::string boot_part_uuid_;

    // These non const members are modified only at initialization or test
    std::set<std::string> boot_devices_;
    std::string boot_part_uuid_;
    bool found_boot_part_uuid_;
    bool skip_restorecon_;
    std::string sysfs_mount_point_;

    std::vector<TrackedUevent> tracked_uevents_;
    std::map<std::string, std::string> bound_drivers_;
    std::mutex device_update_lock_;
    std::vector<TrackedUevent> tracked_uevents_ GUARDED_BY(device_update_lock_);
    std::map<std::string, std::string> bound_drivers_ GUARDED_BY(device_update_lock_);
};

// Exposed for testing