Changeset 105:fcdb9fd5b2bc in rrlib_logging


Ignore:
Timestamp:
03.09.2013 10:45:16 (7 years ago)
Author:
Tobias Föhst <foehst@…>
Branch:
default
Phase:
public
Message:

Added double checked locking to make domain creation thread-safe

Location:
configuration
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • configuration/tConfiguration.cpp

    r104 r105  
    191191  if (!delimiter) 
    192192  { 
    193     return this->LookupChild(default_context, domain_name, std::strlen(domain_name)); 
    194   } 
    195  
    196   return this->LookupChild(default_context, domain_name, delimiter - domain_name).GetConfigurationByName(default_context, delimiter + 1); 
     193    return this->GetChild(default_context, domain_name, std::strlen(domain_name)); 
     194  } 
     195 
     196  return this->GetChild(default_context, domain_name, delimiter - domain_name).GetConfigurationByName(default_context, delimiter + 1); 
    197197} 
    198198 
     
    211211  } 
    212212 
    213   return this->LookupChild(default_context, filename, delimiter - filename).GetConfigurationByFilename(default_context, delimiter + 1); 
    214 } 
    215  
    216 //---------------------------------------------------------------------- 
    217 // tConfiguration LookupChild 
    218 //---------------------------------------------------------------------- 
    219 const tConfiguration &tConfiguration::LookupChild(const tDefaultConfigurationContext &default_context, const char *name, size_t length) const 
    220 { 
    221   tConfiguration *configuration = 0; 
    222   auto insertion_point = this->children.end(); 
    223  
     213  return this->GetChild(default_context, filename, delimiter - filename).GetConfigurationByFilename(default_context, delimiter + 1); 
     214} 
     215 
     216//---------------------------------------------------------------------- 
     217// tConfiguration GetChild 
     218//---------------------------------------------------------------------- 
     219const tConfiguration &tConfiguration::GetChild(const tDefaultConfigurationContext &default_context, const char *name, size_t length) const 
     220{ 
     221  tConfiguration *configuration = this->FindChild(name, length); 
     222  if (!configuration) 
     223  { 
     224    std::lock_guard<std::mutex> lock(this->children_mutex); 
     225    configuration = this->FindChild(name, length); 
     226 
     227    // Add child if needed 
     228    if (!configuration) 
     229    { 
     230      configuration = new tConfiguration(default_context, this, std::string(name, length)); 
     231      const tConfiguration *parent = configuration->parent; 
     232      size_t full_name_length = 0; 
     233      while (parent) 
     234      { 
     235        full_name_length += parent->Name().length() + 1; 
     236        parent = parent->parent; 
     237      } 
     238      tDomainRegistry::Instance().UpdateMaxDomainNameLength(full_name_length + configuration->Name().length()); 
     239      this->children.insert(this->FindInsertionPoint(length), configuration); 
     240    } 
     241  } 
     242 
     243  return *configuration; 
     244} 
     245 
     246//---------------------------------------------------------------------- 
     247// tConfiguration FindChild 
     248//---------------------------------------------------------------------- 
     249tConfiguration *tConfiguration::FindChild(const char *name, size_t length) const 
     250{ 
    224251  // Iterate over sorted list of children (must be sorted longest name first to work) 
    225252  for (auto it = this->children.begin(); it != this->children.end(); ++it) 
     
    233260    } 
    234261 
    235     // Compare matching names 
     262    // Compare names of matching length 
    236263    if (current_length == length) 
    237264    { 
    238265      if (std::strncmp(name, (*it)->Name().c_str(), length) == 0) 
    239266      { 
    240         configuration = *it; 
    241         break; 
     267        return *it; 
    242268      } 
    243269      continue; 
    244270    } 
    245271 
     272    // Shorter names start -> can not be found anymore 
     273    break; 
     274  } 
     275  return NULL; 
     276} 
     277 
     278//---------------------------------------------------------------------- 
     279// tConfiguration FindInsertionPoint 
     280//---------------------------------------------------------------------- 
     281std::list<tConfiguration *>::iterator tConfiguration::FindInsertionPoint(size_t length) const 
     282{ 
     283  // Iterate over sorted list of children (must be sorted longest name first to work) 
     284  for (auto it = this->children.begin(); it != this->children.end(); ++it) 
     285  { 
     286    const size_t current_length = (*it)->Name().length(); 
     287 
    246288    // Shorter names start -> insert new configuration before 
    247     insertion_point = it; 
    248     break; 
    249   } 
    250  
    251   // Add child if needed 
    252   if (!configuration) 
    253   { 
    254     configuration = new tConfiguration(default_context, this, std::string(name, length)); 
    255     const tConfiguration *parent = configuration->parent; 
    256     size_t full_name_length = 0; 
    257     while (parent) 
    258     { 
    259       full_name_length += parent->Name().length() + 1; 
    260       parent = parent->parent; 
    261     } 
    262     tDomainRegistry::Instance().UpdateMaxDomainNameLength(full_name_length + configuration->Name().length()); 
    263     this->children.insert(insertion_point, configuration); 
    264   } 
    265  
    266   return *configuration; 
     289    if (current_length < length) 
     290    { 
     291      return it; 
     292    } 
     293  } 
     294  return this->children.end(); 
    267295} 
    268296 
  • configuration/tConfiguration.h

    r101 r105  
    6767#include <list> 
    6868#include <fstream> 
     69#include <mutex> 
    6970 
    7071//---------------------------------------------------------------------- 
     
    223224 
    224225  mutable std::list<tConfiguration *> children; 
     226  mutable std::mutex children_mutex; 
    225227 
    226228  tConfiguration(const tDefaultConfigurationContext &default_context, const tConfiguration *parent, const std::string &name); 
     
    234236  const tConfiguration &GetConfigurationByFilename(const tDefaultConfigurationContext &default_context, const char *filename) const; 
    235237 
    236   const tConfiguration &LookupChild(const tDefaultConfigurationContext &default_context, const char *name, size_t length) const; 
     238  const tConfiguration &GetChild(const tDefaultConfigurationContext &default_context, const char *name, size_t length) const; 
     239 
     240  tConfiguration *FindChild(const char *name, size_t length) const; 
     241 
     242  std::list<tConfiguration *>::iterator FindInsertionPoint(size_t length) const; 
    237243 
    238244  void PrepareStreamBuffer() const; 
Note: See TracChangeset for help on using the changeset viewer.