diff --git a/libproxy-0.4.12-fix-kde-slowdown.patch b/libproxy-0.4.12-fix-kde-slowdown.patch new file mode 100644 index 0000000..3336ed7 --- /dev/null +++ b/libproxy-0.4.12-fix-kde-slowdown.patch @@ -0,0 +1,167 @@ +From 28620c7aeb3d1b54c83caf84778df8e095490820 Mon Sep 17 00:00:00 2001 +From: Fabian Vogt +Date: Tue, 16 Feb 2016 21:33:40 +0100 +Subject: [PATCH] config_kde: Add a basic cache and invalidation + +After finding out whether to use kreadconfig5 or kreadconfig, +it uses either qtpaths or kde4-config to determine the locations +of the kioslaverc config file, to be able to notice modifications +that require a cache flush. +--- + libproxy/modules/config_kde.cpp | 98 ++++++++++++++++++++++++++++++++++++----- + 1 file changed, 88 insertions(+), 10 deletions(-) + +diff --git a/libproxy/modules/config_kde.cpp b/libproxy/modules/config_kde.cpp +index 2211487..515aaac 100644 +--- a/libproxy/modules/config_kde.cpp ++++ b/libproxy/modules/config_kde.cpp +@@ -18,9 +18,13 @@ + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + ******************************************************************************/ + ++#include ++#include ++ + #include + #include + #include ++#include + + #include "../extension_config.hpp" + using namespace libproxy; +@@ -28,11 +32,18 @@ using namespace libproxy; + class kde_config_extension : public config_extension { + public: + kde_config_extension() ++ : cache_time(0) + { + try { + // Try the KF5 one first + command = "kreadconfig5"; +- kde_config_val("proxyType", "-1"); ++ command_output("kreadconfig5 --key nonexistant"); ++ ++ try { ++ parse_dir_list(command_output("qtpaths --paths GenericConfigLocation")); ++ } ++ catch(...) {} ++ + return; // Worked + } + catch(...) {} +@@ -40,7 +51,13 @@ class kde_config_extension : public config_extension { + try { + // The KDE4 one next + command = "kreadconfig"; +- kde_config_val("proxyType", "-1"); ++ command_output(command); ++ ++ try { ++ parse_dir_list(command_output("kde4-config --path config")); ++ } ++ catch(...) {} ++ + return; // Worked + } + catch(...) {} +@@ -117,11 +134,7 @@ class kde_config_extension : public config_extension { + } + + private: +- // Neither key nor def must contain ' +- string kde_config_val(const string &key, const string &def) throw (runtime_error) { +- string cmdline = +- command + " --file kioslaverc --group 'Proxy Settings' --key '" + key + "' --default '" + def + "'"; +- ++ string command_output(const string &cmdline) throw (runtime_error) { + FILE *pipe = popen(cmdline.c_str(), "r"); + if (!pipe) + throw runtime_error("Unable to run command"); +@@ -129,19 +142,84 @@ class kde_config_extension : public config_extension { + char buffer[128]; + string result = ""; + while (!feof(pipe)) { +- if (fgets(buffer, 128, pipe) != NULL) +- result += buffer; // TODO: If this throws bad_alloc, pipe is leaked ++ if (fgets(buffer, 128, pipe) != NULL) ++ result += buffer; // TODO: If this throws bad_alloc, pipe is leaked + } + +- pclose(pipe); ++ if(pclose(pipe) != 0) ++ throw runtime_error("Command failed"); + + // Trim newlines and whitespace at end + result.erase(result.begin() + (result.find_last_not_of(" \n\t")+1), result.end()); ++ + return result; + } + ++ // Neither key nor def must contain ' ++ string kde_config_val(const string &key, const string &def) throw (runtime_error) { ++ if (cache_needs_refresh()) ++ cache.clear(); ++ else ++ try { ++ // Already in cache? ++ return cache.at(key); ++ } catch(...) {} // Not in cache ++ ++ string result = command_output( ++ command + " --file kioslaverc --group 'Proxy Settings' --key '" + key + "' --default '" + def + "'"); ++ ++ // Add result to cache ++ cache[key] = result; ++ ++ return result; ++ } ++ ++ // Used for cache invalidation ++ struct configfile { ++ string path; ++ time_t mtime; // 0 means it doesn't exist ++ }; ++ ++ // Parses output of qtpaths/kde4-config to fill config_locs ++ void parse_dir_list(const string &dirs) { ++ string config_path; ++ stringstream config_paths_stream(dirs); ++ ++ // Try each of the listed folders, seperated by ':' ++ while (getline(config_paths_stream, config_path, ':')) { ++ configfile config_loc; config_loc.path = config_path + "/kioslaverc"; ++ config_locs.push_back(config_loc); ++ } ++ } ++ ++ // If any of the locations in config_locs changed (different mtime), ++ // update config_locs and return true. ++ bool cache_needs_refresh() { ++ // Play safe here, if we can't determine the location, ++ // don't cache at all. ++ bool needs_refresh = config_locs.empty(); ++ struct stat config_info; ++ ++ for (unsigned int i = 0; i < config_locs.size(); ++i) { ++ configfile &config = config_locs[i]; ++ time_t current_mtime = stat(config.path.c_str(), &config_info) == 0 ? config_info.st_mtime : 0; ++ if (config.mtime != current_mtime) { ++ config.mtime = current_mtime; ++ needs_refresh = true; ++ } ++ } ++ ++ return needs_refresh; ++ } ++ + // Whether to use kreadconfig or kreadconfig5 + string command; ++ // When the cache was flushed last ++ time_t cache_time; ++ // Cache for config values ++ map cache; ++ // State of the config files at the time of the last cache flush ++ vector config_locs; + }; + + MM_MODULE_INIT_EZ(kde_config_extension, getenv("KDE_FULL_SESSION"), NULL, NULL); diff --git a/libproxy.spec b/libproxy.spec index 2662e51..d6528e8 100644 --- a/libproxy.spec +++ b/libproxy.spec @@ -16,6 +16,7 @@ Patch0: 0001-Add-config-module-for-querying-PacRunner-d-mon.patch # Taken from upstream git. Patch1: libproxy-0.4.12-javascriptcoregtk4.patch Patch2: libproxy-0.4.12-use-correct-delete.patch +Patch3: libproxy-0.4.12-fix-kde-slowdown.patch BuildRequires: python2-devel BuildRequires: libmodman-devel >= 2.0.1 @@ -147,6 +148,7 @@ developing applications that use %{name}. %patch0 -p1 %patch1 -p1 %patch2 -p1 +%patch3 -p1 %build %{cmake} \ @@ -226,6 +228,7 @@ make test - Use pkgconfig for BuildRequires - Use javascriptcoregtk-4.0 - Apply an upstream patch to pair new[] with delete[] +- Fix slowdown in KDE plugin * Thu Feb 04 2016 Fedora Release Engineering - 0.4.11-13 - Rebuilt for https://fedoraproject.org/wiki/Fedora_24_Mass_Rebuild