From: Georg Baum Date: Sun, 21 Dec 2014 20:40:25 +0000 (+0100) Subject: Make Format class almost thread-safe X-Git-Tag: 2.2.0alpha1~1442 X-Git-Url: https://git.lyx.org/gitweb/?a=commitdiff_plain;h=0af021878b66dedda445d120b4b81a5568195bea;p=features.git Make Format class almost thread-safe This is needed since all formats are stored in a global list which is shared between threads, but never modfified except from the main thread. The only missing bit is extension_list_, which is not so easy to do. --- diff --git a/src/Format.h b/src/Format.h index 0cb760fe36..13bde5ff1f 100644 --- a/src/Format.h +++ b/src/Format.h @@ -13,6 +13,7 @@ #define FORMAT_H #include "support/docstring.h" +#include "support/trivstring.h" #include "OutputParams.h" @@ -54,11 +55,11 @@ public: /// Name fo the parent format std::string const parentFormat() const; /// - std::string const & name() const { return name_; } + std::string const name() const { return name_; } /// void setName(std::string const & v) { name_ = v; } /// - std::string const & extension() const + std::string const extension() const { return extension_list_.empty() ? empty_string() : extension_list_[0]; } @@ -67,23 +68,23 @@ public: /// void setExtensions(std::string const & v); /// - std::string const & prettyname() const { return prettyname_; } + std::string const prettyname() const { return prettyname_; } /// void setPrettyname(std::string const & v) { prettyname_ = v; } /// - std::string const & shortcut() const { return shortcut_; } + std::string const shortcut() const { return shortcut_; } /// void setShortcut(std::string const & v) { shortcut_ = v; } /// - std::string const & viewer() const { return viewer_; } + std::string const viewer() const { return viewer_; } /// void setViewer(std::string const & v) { viewer_ = v; } /// - std::string const & editor() const { return editor_; } + std::string const editor() const { return editor_; } /// void setEditor(std::string const & v) { editor_ = v; } /// - std::string const & mime() const { return mime_; } + std::string const mime() const { return mime_; } /// void setMime(std::string const & m) { mime_ = m; } /// @@ -101,13 +102,13 @@ public: private: /// Internal name. Needs to be unique. - std::string name_; + trivstring name_; /// Filename extensions, the first one being the default std::vector extension_list_; /// Name presented to the user. Needs to be unique. - std::string prettyname_; + trivstring prettyname_; /// Keyboard shortcut for the View and Export menu. - std::string shortcut_; + trivstring shortcut_; /*! * Viewer for this format. Needs to be in the PATH or an absolute * filename. @@ -115,9 +116,9 @@ private: * If it is \c auto the default viewer of the OS for this format is * used. */ - std::string viewer_; + trivstring viewer_; /// Editor for this format. \sa viewer_. - std::string editor_; + trivstring editor_; /*! * Full MIME type, e.g. "text/x-tex". * Only types listed by the shared MIME database of freedesktop.org @@ -125,7 +126,7 @@ private: * This field may be empty, but it must be unique across all formats * if it is set. */ - std::string mime_; + trivstring mime_; /// int flags_; }; diff --git a/src/support/tests/check_trivstring.cpp b/src/support/tests/check_trivstring.cpp index f2c44e44ad..1b604657f4 100644 --- a/src/support/tests/check_trivstring.cpp +++ b/src/support/tests/check_trivstring.cpp @@ -68,6 +68,13 @@ void test_trivstring() cout << (c == a) << ' ' << (a == c) << endl; // equal strings cout << (a == f) << ' ' << (f == a) << endl; // different strings, same length cout << (a == g) << ' ' << (g == a) << endl; // different strings, different length + // operator[] + cout << d[1] << d[0] << endl; + // substr() + cout << d.substr(1) << endl; // default argument + cout << d.substr(1, 1) << endl; // maximum length + cout << d.substr(1, 2) << endl; // length larger than max + cout << d.substr(2) << endl; // maximum pos } void test_trivdocstring() @@ -129,6 +136,13 @@ void test_trivdocstring() cout << (c == a) << ' ' << (a == c) << endl; // equal strings cout << (a == f) << ' ' << (f == a) << endl; // different strings, same length cout << (a == g) << ' ' << (g == a) << endl; // different strings, different length + // operator[] + cout << static_cast(d[1]) << static_cast(d[0]) << endl; + // substr() + cout << to_ascii(d.substr(1)) << endl; // default argument + cout << to_ascii(d.substr(1, 1)) << endl; // maximum length + cout << to_ascii(d.substr(1, 2)) << endl; // length larger than max + cout << to_ascii(d.substr(2)) << endl; // maximum pos } int main() diff --git a/src/support/tests/regfiles/trivstring b/src/support/tests/regfiles/trivstring index 28b6085730..34e64544b1 100644 --- a/src/support/tests/regfiles/trivstring +++ b/src/support/tests/regfiles/trivstring @@ -57,6 +57,11 @@ something which does not fit into sso 0 0 0 0 0 0 +24 +2 +2 +2 + empty 0 @@ -116,3 +121,8 @@ something which does not fit into sso 0 0 0 0 0 0 +24 +2 +2 +2 + diff --git a/src/support/trivstring.cpp b/src/support/trivstring.cpp index 6fda216674..fad1565c6a 100644 --- a/src/support/trivstring.cpp +++ b/src/support/trivstring.cpp @@ -16,6 +16,7 @@ #ifdef STD_STRING_USES_COW #include #include +#include using namespace std; @@ -31,8 +32,27 @@ trivial_string::trivial_string(trivial_string const & that) : size_(that.s else if (size_ > 0) { data_ = new Char[size_ + 1]; copy(that.data_, that.data_ + size_ + 1, data_); + } else { + // Happens only for really big Char types + data_ = 0; + } +} + + +template +trivial_string::trivial_string(Char const * that, size_t n) : size_(n) +{ + if (use_sso()) { + copy(that, that + size_, data_sso()); + data_sso()[size_] = '\0'; + } else if (size_ > 0) { + data_ = new Char[size_ + 1]; + copy(that, that + size_, data_); + data_[size_] = '\0'; + } else { + // Happens only for really big Char types + data_ = 0; } - // else Happens only for really big Char types } @@ -50,8 +70,10 @@ trivial_string::trivial_string( data_ = new Char[size_ + 1]; copy(that.begin(), that.end(), data_); data_[size_] = '\0'; + } else { + // Happens only for really big Char types + data_ = 0; } - // else Happens only for really big Char types } @@ -138,6 +160,20 @@ int trivial_string::compare(trivial_string const & other) const } +template trivial_string trivial_string::substr(size_t, size_t) const; +template trivial_string trivial_string::substr(size_t, size_t) const; +template +trivial_string trivial_string::substr(size_t pos, size_t n) const +{ + if (pos > length()) + throw out_of_range("trivial_string::substr"); + if (n == basic_string, allocator >::npos) + n = length() - pos; + size_t const l = min(pos + n, length()); + return trivial_string(c_str() + pos, l - pos); +} + + template trivial_string::operator string() const; template trivial_string::operator docstring() const; template @@ -154,8 +190,6 @@ trivial_string::operator basic_string, allocator::c_str() const; -template char_type const * trivial_string::c_str() const; template Char const * trivial_string::c_str() const { if (use_sso()) @@ -168,6 +202,14 @@ template Char const * trivial_string::c_str() const } +template char trivial_string::operator[](size_t) const; +template char_type trivial_string::operator[](size_t) const; +template Char trivial_string::operator[](size_t i) const +{ + return c_str()[i]; +} + + template bool operator<(trivial_string const &, trivial_string const &); template bool operator<(trivial_string const &, diff --git a/src/support/trivstring.h b/src/support/trivstring.h index c83b607d8b..a54889c2d7 100644 --- a/src/support/trivstring.h +++ b/src/support/trivstring.h @@ -44,6 +44,8 @@ public: /// Construct a string from a copy of \p that trivial_string(trivial_string const & that); /// Construct a string from a copy of \p that + trivial_string(Char const * that, size_t n); + /// Construct a string from a copy of \p that trivial_string(std::basic_string, std::allocator > const & that); /// ~trivial_string() { if (!use_sso()) delete[] data_; } @@ -59,11 +61,16 @@ public: bool empty() const { return size_ == 0; } /// Is this string ordered before, at the same position or after \p other? int compare(trivial_string const & other) const; + /// Return substring of length \p n starting at \p pos + trivial_string substr(size_t pos = 0, size_t n = std::basic_string, std::allocator >::npos) const; /// Create a copy as std::basic_string operator std::basic_string, std::allocator >() const; /// Return a C-compatible string, terminated by a 0 character. /// This is never a copy and only valid for the life time of the trivial_string instance. Char const * c_str() const; + /// Return character at position \p i (validity of \i is not checked) + Char operator[](size_t i) const; private: /** * Whether short string optimization is used.