Skip to content

Commit

Permalink
don't use shared resource in t_string
Browse files Browse the repository at this point in the history
this seems to still cause issues related to multithreading.

When this was introduced, config objects stored all its attributes
(inclusing numbers) as t_string objects which made same t_strign object
mocuh more often than it is now.
  • Loading branch information
gfgtdf committed Jun 18, 2016
1 parent fedbd82 commit 58b5e9a
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 56 deletions.
1 change: 1 addition & 0 deletions src/config.hpp
Expand Up @@ -30,6 +30,7 @@

#include "global.hpp"

#include <climits>
#include <ctime>
#include <iosfwd>
#include <iterator>
Expand Down
55 changes: 9 additions & 46 deletions src/tstring.cpp
Expand Up @@ -454,43 +454,44 @@ const std::string& t_string_base::str() const
return translated_value_;
}

t_string::t_string() : super()
t_string::t_string() : val_(new base())
{
}

t_string::~t_string()
{
}

t_string::t_string(const t_string &o) : super(o)
t_string::t_string(const t_string &o) : val_(o.val_)
{
}

t_string::t_string(const base &o) : super(o)
t_string::t_string(const base &o) : val_(new base(o))
{
}

t_string::t_string(const char *o) : super(base(o))
t_string::t_string(const char *o) : val_(new base(o))
{
}

t_string::t_string(const std::string &o) : super(base(o))
t_string::t_string(const std::string &o) : val_(new base(o))
{
}

t_string::t_string(const std::string &o, const std::string &textdomain) : super(base(o, textdomain))
t_string::t_string(const std::string &o, const std::string &textdomain) : val_(new base(o, textdomain))
{
}

t_string &t_string::operator=(const t_string &o)
{
super::operator=(o);
val_ = o.val_;
return *this;
}

t_string &t_string::operator=(const char *o)
{
super::operator=(base(o));
t_string o2(o);
swap(o2);
return *this;
}

Expand All @@ -512,41 +513,3 @@ std::ostream& operator<<(std::ostream& stream, const t_string_base& string)
stream << string.str();
return stream;
}

/**
* shared_object<tstring_base> implementation of hash database
*/

template <typename T, typename node = shared_node<T> >
struct types {
typedef boost::multi_index_container<
node,
boost::multi_index::indexed_by<
boost::multi_index::hashed_unique<
BOOST_MULTI_INDEX_MEMBER(node, T, val)
>
>
> hash_map;

typedef typename hash_map::template nth_index<0>::type hash_index;

};

static types<t_string_base>::hash_map& map() { static types<t_string_base>::hash_map* map = new types<t_string_base>::hash_map; return *map; }
static types<t_string_base>::hash_index& index() { return map().get<0>(); }
static std::mutex& mutex() { static std::mutex* m = new std::mutex(); return *m; }
typedef shared_node<t_string_base> node;

template<>
const node* shared_object<t_string_base>::insert_into_index(const node & n)
{
std::lock_guard<std::mutex> lock(mutex());
return &*index().insert(n).first;
}

template<>
void shared_object<t_string_base>::erase_from_index(const node * ptr)
{
std::lock_guard<std::mutex> lock(mutex());
index().erase(index().find(ptr->val));
}
30 changes: 20 additions & 10 deletions src/tstring.hpp
Expand Up @@ -15,8 +15,7 @@
#ifndef TSTRING_H_INCLUDED
#define TSTRING_H_INCLUDED

#include "utils/shared_object.hpp"

#include <boost/shared_ptr.hpp>
#include <string>

/**
Expand Down Expand Up @@ -111,10 +110,9 @@ class t_string_base
inline size_t hash_value(const t_string_base& str) { return str.hash_value(); }
std::ostream& operator<<(std::ostream&, const t_string_base&);

class t_string :
private shared_object<t_string_base> {
class t_string
{
public:
typedef shared_object<t_string_base> super;
typedef t_string_base base;
typedef t_string_base::walker walker;

Expand Down Expand Up @@ -142,10 +140,18 @@ class t_string :
t_string operator+(const t_string& o) const { return get() + o.get(); }
t_string operator+(const std::string& o) const { return get() + o; }
t_string operator+(const char* o) const { return get() + o; }

t_string& operator+=(const t_string& o) { set(base(get()) += o.get()); return *this; }
t_string& operator+=(const std::string& o) { set(base(get()) += o); return *this; }
t_string& operator+=(const char* o) { set(base(get()) += o); return *this; }
private:
template<typename T>
void increase_impl(const T& other)
{
base * nw = new base(get());
*nw += other;
val_.reset(nw);
}
public:
t_string& operator+=(const t_string& o) { increase_impl(o.get()); return *this; }
t_string& operator+=(const std::string& o) { increase_impl(o); return *this; }
t_string& operator+=(const char* o) { increase_impl(o); return *this; }

bool operator==(const t_string& o) const { return get() == o.get(); }
bool operator==(const std::string& o) const { return get() == o; }
Expand All @@ -170,7 +176,11 @@ class t_string :
static void add_textdomain(const std::string &name, const std::string &path);
static void reset_translations();

const t_string_base& get() const { return super::get(); }
const t_string_base& get() const { return *val_; }
void swap(t_string& other) { val_.swap(other.val_); }
private:
//never null
boost::shared_ptr<const t_string_base> val_;
};
inline std::ostream& operator<<(std::ostream& os, const t_string& str) { return os << str.get(); }
inline bool operator==(const std::string &a, const t_string &b) { return b == a; }
Expand Down

0 comments on commit 58b5e9a

Please sign in to comment.