From baa56ae7ba36040cf2165bb6d4b49d5ec6df6e79 Mon Sep 17 00:00:00 2001
From: pierre-luc <pierre-luc.bacon@savoirfairelinux.com>
Date: Mon, 7 Sep 2009 03:46:25 -0400
Subject: [PATCH] [#1744] Adds thread safety features, compile() and
 setPattern() methods to the Regex class.

---
 sflphone-common/src/sip/Regex.cpp | 35 +++++++++++++++++++--------
 sflphone-common/src/sip/Regex.h   | 39 +++++++++++++++++++++++++++++--
 2 files changed, 62 insertions(+), 12 deletions(-)

diff --git a/sflphone-common/src/sip/Regex.cpp b/sflphone-common/src/sip/Regex.cpp
index ca898b6215..47018fd413 100644
--- a/sflphone-common/src/sip/Regex.cpp
+++ b/sflphone-common/src/sip/Regex.cpp
@@ -24,17 +24,30 @@ namespace sfl {
 
     const int MAX_SUBSTRINGS = 30;
     
-    Regex::Regex(const std::string& pattern) :
+    Regex::Regex(const std::string& pattern = "") :
     _pattern(pattern)
     ,_re(NULL)
     ,_pcreOutputVector(NULL)
+    ,_reMutex(NULL)
     {   
+        compile();
+    }
+
+    Regex::~Regex() 
+    {
+        pcre_free(_re);
+        delete[] _pcreOutputVector;
+    }
+    
+    void Regex::compile(void)
+    {
         // Compile the pattern
         int offset;
         const char * error;
         
+        _reMutex.enterMutex();
         _re = pcre_compile(_pattern.c_str(), 0, &error, &offset, NULL);
-    
+
         if (_re == NULL) {
             std::string offsetStr;
             std::stringstream ss;
@@ -47,23 +60,23 @@ namespace sfl {
         }
         
         // Allocate space for 
-        // the output vector    
+        // the output vector
+        if (_pcreOutputVector != NULL) {
+            delete[] _pcreOutputVector;
+        }
         _pcreOutputVector = new int[MAX_SUBSTRINGS];
-    }
-
-    Regex::~Regex() 
-    {
-        pcre_free(_re);
-        delete[] _pcreOutputVector;
+        _reMutex.leaveMutex();        
     }
     
     const std::vector<std::string>& Regex::findall(const std::string& subject)
     {
         // Execute the PCRE regex
         int status;
-                
+        
+        _reMutex.enterMutex();    
         status = pcre_exec(_re, NULL, subject.c_str(), subject.length(), 
                         0, 0, _pcreOutputVector, MAX_SUBSTRINGS);
+        _reMutex.leaveMutex();                              
 
         // Handle error cases
         if (status < 0) {
@@ -107,6 +120,7 @@ namespace sfl {
         int count = status;      
         const char **stringlist;     
         
+        _reMutex.enterMutex();        
         status = pcre_get_substring_list(subject.c_str(), _pcreOutputVector, count, &stringlist);
         if (status < 0) {
             fprintf(stderr, "Get substring list failed");
@@ -121,6 +135,7 @@ namespace sfl {
             pcre_free_substring_list(stringlist);
 
         }        
+        _reMutex.leaveMutex();
         
         return _outputVector;
     }
diff --git a/sflphone-common/src/sip/Regex.h b/sflphone-common/src/sip/Regex.h
index 8120e5e7c6..6b6769ed0e 100644
--- a/sflphone-common/src/sip/Regex.h
+++ b/sflphone-common/src/sip/Regex.h
@@ -18,10 +18,12 @@
 #ifndef __SFL_REGEX_H__
 #define __SFL_REGEX_H__
 
-#include <stdexcept> 
+#include <stdexcept>
+#include <ostream>
 #include <vector>
 
 #include <pcre.h>
+#include <cc++/thread.h> 
 
 namespace sfl {
     
@@ -82,6 +84,33 @@ namespace sfl {
             
             ~Regex();
             
+            /**
+             * Set the regular expression 
+             * to be used on subject strings
+             * 
+             * @param The new pattern
+             */
+             void setPattern(const std::string& pattern) { 
+                _reMutex.enterMutex();
+                    _pattern = pattern; 
+                _reMutex.leaveMutex();
+             }
+
+            /**
+             * Compile the regular expression
+             * from the pattern that was set for 
+             * this object.
+             */
+            void compile(void);
+             
+            /**
+             * Get the currently set regular expression 
+             * that is used on subject strings
+             * 
+             * @return The currently set pattern
+             */             
+             std::string getPattern(void) { return _pattern; }
+             
             /** 
              * Match the given expression against
              * this pattern and returns a vector of
@@ -112,7 +141,7 @@ namespace sfl {
              *         were matched.
              */             
             range finditer(const std::string& subject);
-            
+                        
         private:
             
             /**
@@ -138,6 +167,12 @@ namespace sfl {
             */
 
             std::vector<std::string> _outputVector;
+            
+            /**
+            * Protects the above data from concurrent
+            * access.
+            */
+            ost::Mutex _reMutex;
     };
     
 }
-- 
GitLab