diff options
author | Richard Purdie <rpurdie@linux.intel.com> | 2010-08-20 11:24:02 +0100 |
---|---|---|
committer | Richard Purdie <rpurdie@linux.intel.com> | 2010-08-20 11:24:02 +0100 |
commit | fac06aaf2a2b79adc2fbfc7fbd5e6526ff2b515c (patch) | |
tree | 7010a097ae2814b3318db25787b73386eebdb3e3 /bitbake | |
parent | 604f12722a0ab2e3e16e87c785682bd5f744f94f (diff) | |
download | poky-fac06aaf2a2b79adc2fbfc7fbd5e6526ff2b515c.tar.gz |
bitbake/persist_data: Attempt to fix locking issues
It appears the timeout sometimes has no effect and we see database access failures. Combat
this by wrapping the execute function in all cases and retrying manually ourselves.
Thanks to Kevin Tian for help debugging this.
Signed-off-by: Richard Purdie <rpurdie@linux.intel.com>
Diffstat (limited to 'bitbake')
-rw-r--r-- | bitbake/lib/bb/persist_data.py | 25 |
1 files changed, 17 insertions, 8 deletions
diff --git a/bitbake/lib/bb/persist_data.py b/bitbake/lib/bb/persist_data.py index df0409cd8a..00f4929945 100644 --- a/bitbake/lib/bb/persist_data.py +++ b/bitbake/lib/bb/persist_data.py | |||
@@ -67,20 +67,20 @@ class PersistData: | |||
67 | Should be called before any domain is used | 67 | Should be called before any domain is used |
68 | Creates it if it doesn't exist. | 68 | Creates it if it doesn't exist. |
69 | """ | 69 | """ |
70 | self.cursor.execute("CREATE TABLE IF NOT EXISTS %s(key TEXT, value TEXT);" % domain) | 70 | self._execute("CREATE TABLE IF NOT EXISTS %s(key TEXT, value TEXT);" % domain) |
71 | 71 | ||
72 | def delDomain(self, domain): | 72 | def delDomain(self, domain): |
73 | """ | 73 | """ |
74 | Removes a domain and all the data it contains | 74 | Removes a domain and all the data it contains |
75 | """ | 75 | """ |
76 | self.cursor.execute("DROP TABLE IF EXISTS %s;" % domain) | 76 | self._execute("DROP TABLE IF EXISTS %s;" % domain) |
77 | 77 | ||
78 | def getKeyValues(self, domain): | 78 | def getKeyValues(self, domain): |
79 | """ | 79 | """ |
80 | Return a list of key + value pairs for a domain | 80 | Return a list of key + value pairs for a domain |
81 | """ | 81 | """ |
82 | ret = {} | 82 | ret = {} |
83 | data = self.cursor.execute("SELECT key, value from %s;" % domain) | 83 | data = self._execute("SELECT key, value from %s;" % domain) |
84 | for row in data: | 84 | for row in data: |
85 | ret[str(row[0])] = str(row[1]) | 85 | ret[str(row[0])] = str(row[1]) |
86 | 86 | ||
@@ -90,7 +90,7 @@ class PersistData: | |||
90 | """ | 90 | """ |
91 | Return the value of a key for a domain | 91 | Return the value of a key for a domain |
92 | """ | 92 | """ |
93 | data = self.cursor.execute("SELECT * from %s where key=?;" % domain, [key]) | 93 | data = self._execute("SELECT * from %s where key=?;" % domain, [key]) |
94 | for row in data: | 94 | for row in data: |
95 | return row[1] | 95 | return row[1] |
96 | 96 | ||
@@ -98,7 +98,7 @@ class PersistData: | |||
98 | """ | 98 | """ |
99 | Sets the value of a key for a domain | 99 | Sets the value of a key for a domain |
100 | """ | 100 | """ |
101 | data = self.cursor.execute("SELECT * from %s where key=?;" % domain, [key]) | 101 | data = self._execute("SELECT * from %s where key=?;" % domain, [key]) |
102 | rows = 0 | 102 | rows = 0 |
103 | for row in data: | 103 | for row in data: |
104 | rows = rows + 1 | 104 | rows = rows + 1 |
@@ -113,12 +113,21 @@ class PersistData: | |||
113 | """ | 113 | """ |
114 | self._execute("DELETE from %s where key=?;" % domain, [key]) | 114 | self._execute("DELETE from %s where key=?;" % domain, [key]) |
115 | 115 | ||
116 | # | ||
117 | # We wrap the sqlite execute calls as on contended machines or single threaded | ||
118 | # systems we can have multiple processes trying to access the DB at once and it seems | ||
119 | # sqlite sometimes doesn't wait for the timeout. We therefore loop but put in an | ||
120 | # emergency brake too | ||
121 | # | ||
116 | def _execute(self, *query): | 122 | def _execute(self, *query): |
123 | count = 0 | ||
117 | while True: | 124 | while True: |
118 | try: | 125 | try: |
119 | self.cursor.execute(*query) | 126 | ret = self.cursor.execute(*query) |
120 | return | 127 | #print "Had to retry %s times" % count |
128 | return ret | ||
121 | except sqlite3.OperationalError as e: | 129 | except sqlite3.OperationalError as e: |
122 | if 'database is locked' in str(e): | 130 | if 'database is locked' in str(e) and count < 500: |
131 | count = count + 1 | ||
123 | continue | 132 | continue |
124 | raise | 133 | raise |