Closing the underlying sqlite3 db on object destruction (__del__())
causes funny race conditions when concurrently accessing the object
itself.
When the Garbage Collector tries to free memory, which can happen
when no more references pointing to self are used, by calling __del__()
(which called close()) it is possible to run into troubles if another
thread is inside a method of the same object holding a valid sqlite cursor.
Moreover, no external arbitration is possible if the garbage collection
gets in the middle and calls close() through the destructor on behalf
of a poor random innocent thread.
Solution is simple, destructor is evil and resource leaks have to be
handled where they actually are. Bye bye __del__().
Never unlink() a lock when releasing it. This is quite bad when
used with shared locks.
At the same time, don't write any pid information in it, because
it's not always reliable (see previous commit).
Scenario: Process A is writing to EntropyRepository, adding new
package entries. Process B is reading from EntropyRepository,
querying for the same package entries, for example by using
retrieveKeySlot(). This method uses a dict-based cache to speed
up things, but this should be invalidated also when the mtime()
value changes.
When matching >=dev-lang/python-2.6 having some weird mask, it
can happen to end up having no matches left after the last
checkpoint. Make sure to handle the case even on the very last mile
Entropy Resources Lock file is in the etpConst['etpdatabaseclientdir']
directory. For this reason, it is better to not touch the whole
directory but just the subdirs.
unlocked_sync() works just like sync() but without acquiring the
Entropy Resources Lock. This way it's possible to externally control
the mutual exclusion.
Other cache consumers may still find the cache file valid, even if
for others it's old. So, don't remove the file but just return None.
This way it works more like an "overlay".
Configuring cache aging makes possible to automatically throw away
old metadata, like package votes and number of downloads.
Usually, this information is still valid, from user POV, even if
quite old. But how much old? This can be tuned via enable_cache_aging()
from outside WebService class, depending on the scenario.
Scenario:
dependency = dev-lang/python
SLOT intersection = enabled
available slots = 2.6, 2.7, 3.2
installed slot = 2.7
The SLOT intersection feature worked correctly but in the end
dev-lang/python was added to the unsatisfied set because there
was a dev-lang/python-2.7 update as well. This results in other
dep calculation code to match dev-lang/python against 3.2 instead.
The SLOT intersection feature has to reduce the dependency string
scope by adding a SLOT suffix (in this case: ":2.7"). This way the
correct dependency is eventually pulled in.
Always flush stderr on a newline and also write the number of
active threads as well.
Moreover, always install the dump function at SIGQUIT when --debug
is passed.
This makes possible to have external module packages inside the
sys-kernel/ category, by just adding extra checks. In particular,
we now check against ETYPE ebuild environment variable.
This should guarantee that all the kernel sources, binaries and
headers won't be tagged by Entropy.
Everytime Repository.sync() is triggered, the last sync time
information is updated. This makes possible to figure out when
the last repository update has been run and warn user about it
if they're too old.