From d47d002e92cede840b86a3edb91bfc76af4c5388 Mon Sep 17 00:00:00 2001
From: Alexandre MERLIN <alexandre.merlin@inria.fr>
Date: Fri, 4 Dec 2020 14:46:20 +0100
Subject: [PATCH] [server/db] add mutex to prevent simulation accesses on db

---
 lib/kadeploy3/server/db.rb | 57 +++++++++++++++++++++-----------------
 1 file changed, 32 insertions(+), 25 deletions(-)

diff --git a/lib/kadeploy3/server/db.rb b/lib/kadeploy3/server/db.rb
index 00e84050..cc6e20b2 100644
--- a/lib/kadeploy3/server/db.rb
+++ b/lib/kadeploy3/server/db.rb
@@ -130,6 +130,11 @@ module Database
   end
 
   class DbMysql < Db
+    def initialize()
+      super
+      @mutex = Mutex::new # avoid concurrent queries
+    end
+
     def free()
       @dbh.close if (@dbh != nil)
       @dbh = nil
@@ -177,35 +182,37 @@ module Database
     # Output
     # * return a DbResult Object and print an error if the execution failed
     def run_query(query, *args)
-      res = nil
-      begin
-        st = @dbh.prepare(query)
-        res = st.execute(*args)
-        content = nil
-        fields = st.fields
-        unless res.nil?
-          content = []
-          res.each do |r|
-            rescontent = []
-            r.each do |_,row|
-              rescontent << row
+      @mutex.synchronize do
+        res = nil
+        begin
+          st = @dbh.prepare(query)
+          res = st.execute(*args)
+          content = nil
+          fields = st.fields
+          unless res.nil?
+            content = []
+            res.each do |r|
+              rescontent = []
+              r.each do |_,row|
+                rescontent << row
+              end
+              content << rescontent
             end
-            content << rescontent
           end
+          result = DbResult.new(fields,content,st.affected_rows)
+
+          st.close
+        rescue Mysql2::Error => e
+          $stderr.puts "MySQL query: #{query.gsub(/\s+/," ").strip}" if query
+          $stderr.puts "MySQL args: #{args.inspect}" if args
+          $stderr.puts "MySQL error (code): #{e.errno}"
+          $stderr.puts "MySQL error (message): #{e.error}"
+          $stderr.puts e.backtrace
+          raise KadeployError.new(APIError::DATABASE_ERROR,nil,
+            "MySQL error ##{e.errno}: #{e.error.gsub(/\s+/," ").strip}")
         end
-        result = DbResult.new(fields,content,st.affected_rows)
-
-        st.close
-      rescue Mysql2::Error => e
-        $stderr.puts "MySQL query: #{query.gsub(/\s+/," ").strip}" if query
-        $stderr.puts "MySQL args: #{args.inspect}" if args
-        $stderr.puts "MySQL error (code): #{e.errno}"
-        $stderr.puts "MySQL error (message): #{e.error}"
-        $stderr.puts e.backtrace
-        raise KadeployError.new(APIError::DATABASE_ERROR,nil,
-          "MySQL error ##{e.errno}: #{e.error.gsub(/\s+/," ").strip}")
+        return result
       end
-      return result
     end
   end
 end
-- 
GitLab