summaryrefslogtreecommitdiff
path: root/libproxy/modules
diff options
context:
space:
mode:
authornpmccallum <npmccallum@c587cffe-e639-0410-9787-d7902ae8ed56>2010-03-11 22:07:52 +0000
committernpmccallum <npmccallum@c587cffe-e639-0410-9787-d7902ae8ed56>2010-03-11 22:07:52 +0000
commit2c365a3c5681f434b45bf3caa4b9f1451ab5ac62 (patch)
treebaf11c015647474b0f81f804bed93975b345b6c8 /libproxy/modules
parent9b28cb75ec0474f60eb952fa7b2baecf5b13a485 (diff)
downloadlibproxy-2c365a3c5681f434b45bf3caa4b9f1451ab5ac62.tar.gz
make config_gnome's pipe reading semantics much saner; avoid infinite loops
git-svn-id: http://libproxy.googlecode.com/svn/trunk@615 c587cffe-e639-0410-9787-d7902ae8ed56
Diffstat (limited to 'libproxy/modules')
-rw-r--r--libproxy/modules/config_gnome.cpp45
1 files changed, 15 insertions, 30 deletions
diff --git a/libproxy/modules/config_gnome.cpp b/libproxy/modules/config_gnome.cpp
index 97baa2d..7b1ccf6 100644
--- a/libproxy/modules/config_gnome.cpp
+++ b/libproxy/modules/config_gnome.cpp
@@ -113,6 +113,9 @@ public:
if (popen2(cmd.c_str(), &this->read, &this->write, &this->pid) != 0)
throw runtime_error("Unable to open gconf helper!");
+ // Read in our initial data
+ this->read_data(count);
+
// Set the read pipe to non-blocking
if (fcntl(fileno(this->read), F_SETFL, FNONBLOCK) == -1) {
fclose(this->read);
@@ -120,9 +123,6 @@ public:
kill(this->pid, SIGTERM);
throw runtime_error("Unable to set pipe to non-blocking!");
}
-
- // Read in the first print-out of all our keys
- this->update_data(count);
}
~gnome_config_extension() {
@@ -133,7 +133,12 @@ public:
url get_config(url dest) throw (runtime_error) {
// Check for changes in the config
- this->update_data();
+ fd_set rfds;
+ struct timeval timeout = { 0, 0 };
+ FD_ZERO(&rfds);
+ FD_SET(fileno(this->read), &rfds);
+ if (select(fileno(this->read)+1, &rfds, NULL, NULL, &timeout) > 0)
+ this->read_data();
// Mode is wpad:// or pac+http://...
if (this->data["/system/proxy/mode"] == "auto") {
@@ -209,40 +214,20 @@ private:
pid_t pid;
map<string, string> data;
- // This method attempts to update data
- // If called with no arguments, it will check for new data (sleeping for <=10
- // useconds) and returning true or false depending on if at least one line of
- // data was found.
- // However, if req > 0, we will keep checking for new lines (at 10 usec ivals)
- // until enough lines are found. This allows us to wait for *all* the initial
- // values to be read in before we start processing gconf requests.
- bool update_data(int req=0, int found=0) {
- // If we have collected the correct number of lines, return true
- if (req > 0 && found >= req)
- return true;
-
- // We need the pipe to be open
- if (!this->read) return false;
-
- fd_set rfds;
- struct timeval timeout = { 0, 10 }; // select() for 1/1000th of a second
- FD_ZERO(&rfds);
- FD_SET(fileno(this->read), &rfds);
- if (select(fileno(this->read)+1, &rfds, NULL, NULL, &timeout) < 1)
- return req > 0 ? this->update_data(req, found) : false; // If we still haven't met
- // our req quota, try again
+ bool read_data(int num=-1) {
+ if (num == 0) return true;
+ if (!this->read) return false; // We need the pipe to be open
- bool retval = false;
- for (char l[BUFFERSIZE] ; fgets(l, BUFFERSIZE, this->read) != NULL ; ) {
+ for (char l[BUFFERSIZE] ; num != 0 && fgets(l, BUFFERSIZE, this->read) != NULL ; ) {
string line = l;
line = line.substr(0, line.rfind('\n'));
string key = line.substr(0, line.find("\t"));
string val = line.substr(line.find("\t")+1);
this->data[key] = val;
- retval = ++found >= req;
+ if (num > 0) num--;
}
- return (this->update_data(req, found) || retval);
+ return (num <= 0);
}
};