From 3eede614a445f73633e439d5240077c391a65423 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?S=C3=A9bastien=20Blin?=
 <sebastien.blin@savoirfairelinux.com>
Date: Mon, 4 Jan 2021 14:17:43 -0500
Subject: [PATCH] video_device_monitor: avoid infinite loop

Change-Id: I22362d3335a07f00f3e09598a4902ee8042c50ed
GitLab: #379
---
 .../video/v4l2/video_device_monitor_impl.cpp    | 17 ++++++++---------
 src/media/video/video_device_monitor.cpp        |  9 +++++----
 src/media/video/video_device_monitor.h          |  2 +-
 3 files changed, 14 insertions(+), 14 deletions(-)

diff --git a/src/media/video/v4l2/video_device_monitor_impl.cpp b/src/media/video/v4l2/video_device_monitor_impl.cpp
index c6a4a2e9fb..2bc45d012f 100644
--- a/src/media/video/v4l2/video_device_monitor_impl.cpp
+++ b/src/media/video/v4l2/video_device_monitor_impl.cpp
@@ -148,12 +148,12 @@ VideoDeviceMonitorImpl::VideoDeviceMonitorImpl(VideoDeviceMonitor* monitor)
             try {
                 auto unique_name = getDeviceString(dev);
                 JAMI_DBG("udev: adding device with id %s", unique_name.c_str());
-                monitor_->addDevice(unique_name, {{{"devPath", path}}});
-                currentPathToId_.emplace(path, unique_name);
+                if (monitor_->addDevice(unique_name, {{{"devPath", path}}}))
+                    currentPathToId_.emplace(path, unique_name);
             } catch (const std::exception& e) {
                 JAMI_WARN("udev: %s, fallback on path (your camera may be a fake camera)", e.what());
-                monitor_->addDevice(path, {{{"devPath", path}}});
-                currentPathToId_.emplace(path, path);
+                if (monitor_->addDevice(path, {{{"devPath", path}}}))
+                    currentPathToId_.emplace(path, path);
             }
         }
         udev_device_unref(dev);
@@ -175,10 +175,9 @@ udev_failed:
 
     /* fallback : go through /dev/video* */
     for (int idx = 0;; ++idx) {
-        std::stringstream ss;
-        ss << "/dev/video" << idx;
         try {
-            monitor_->addDevice(ss.str());
+            if (!monitor_->addDevice("/dev/video" + std::to_string(idx)))
+                break;
         } catch (const std::runtime_error& e) {
             JAMI_ERR("%s", e.what());
             return;
@@ -237,8 +236,8 @@ VideoDeviceMonitorImpl::run()
                     const char* action = udev_device_get_action(dev);
                     if (!strcmp(action, "add")) {
                         JAMI_DBG("udev: adding device with id %s", unique_name.c_str());
-                        monitor_->addDevice(unique_name, {{{"devPath", path}}});
-                        currentPathToId_.emplace(path, unique_name);
+                        if (monitor_->addDevice(unique_name, {{{"devPath", path}}}))
+                            currentPathToId_.emplace(path, unique_name);
                     } else if (!strcmp(action, "remove")) {
                         auto it = currentPathToId_.find(path);
                         if (it != currentPathToId_.end()) {
diff --git a/src/media/video/video_device_monitor.cpp b/src/media/video/video_device_monitor.cpp
index f0ab1ef26b..45fe67f4d4 100644
--- a/src/media/video/video_device_monitor.cpp
+++ b/src/media/video/video_device_monitor.cpp
@@ -187,20 +187,20 @@ notify()
     }
 }
 
-void
+bool
 VideoDeviceMonitor::addDevice(const string& id,
                               const std::vector<std::map<std::string, std::string>>& devInfo)
 {
     try {
         std::lock_guard<std::mutex> l(lock_);
         if (findDeviceById(id) != devices_.end())
-            return;
+            return false;
 
         // instantiate a new unique device
         VideoDevice dev {id, devInfo};
 
         if (dev.getChannelList().empty())
-            return;
+            return false;
 
         giveUniqueName(dev, devices_);
 
@@ -220,9 +220,10 @@ VideoDeviceMonitor::addDevice(const string& id,
         devices_.emplace_back(std::move(dev));
     } catch (const std::exception& e) {
         JAMI_ERR("Failed to add device %s: %s", id.c_str(), e.what());
-        return;
+        return false;
     }
     notify();
+    return true;
 }
 
 void
diff --git a/src/media/video/video_device_monitor.h b/src/media/video/video_device_monitor.h
index 8942f2107e..4ea2fb893f 100644
--- a/src/media/video/video_device_monitor.h
+++ b/src/media/video/video_device_monitor.h
@@ -59,7 +59,7 @@ public:
     bool setDefaultDevice(const std::string& name);
     void setDeviceOrientation(const std::string& id, int angle);
 
-    void addDevice(const std::string& node,
+    bool addDevice(const std::string& node,
                    const std::vector<std::map<std::string, std::string>>& devInfo = {});
     void removeDevice(const std::string& node);
     void removeDeviceViaInput(const std::string& path);
-- 
GitLab