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__().
The ReadersWritersSemaphore object protects concurrent access
on EntropyRepository objects ensuring that they don't get closed
by RigoServiceController while in use.
There are two issues with Entropy Resources Lock when used in Rigo.
1. Reentrancy: this property is unwanted in Rigo due to the amount
of time Entropy Resources Lock is acquired and released.
It is always wanted to acquire once and release once.
2. Re-acquiring it is costly, this lock should be relased only when
we are really forced to do so.
Now that Entropy Resources are completely handled by RigoDaemon
in its activity code, there is no need to keep pinging clients
unless SIGUSR2 arrived.
SIGUSR2 signal will be later used to force RigoDaemon shutdown
in case of rigo package updates via Entropy, to avoid having incompatible
RigoDaemon versions running.
Completely move the arbitration to RigoDaemon, making Rigo passively
accepting the former requests.
Moreover, complete support for bottom notification area and start
implementing app management events.
- Add User notifications before blocking on semaphores
- Fix several minor glitches related to features introduced the
past week
- Cleanup rigo.enums from Software Center crapcode
- Improve Progress Bar interaction with User
- Introduce Activity states and busy(), unbusy() methods to allocate
and deallocate Daemon activities from the Clients, concurrently.
- Tokenize acquire_resources() and release_resources() to filter out
older events. The same token is returned to Clients via signals whenever
it makes sense (repositories_updated() is one of them).
- Implement Repositories Update Activity resume functionality in Rigo.
It is possible to close Rigo during a repo update and reopen it afterwards.
Multiple Rigo instances are allowed as well.
- Implement the ability for RigoDaemon to kindly request Rigo Clients
to release their locks (either shared or exclusive) due to new activity
being scheduled.
All the races and possible deadlocks should be handled correctly,
but due to the actual complexity, only time will tell.
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).
in Entropy Client library functions, we currently check if current
pid equals the one stored inside .using_resources file if lock
cannot be acquired in blocking mode. This is bad because the information
is not 100% reliable. The trick was there in order to allow equo
to exec*() without releasing the file locks. However, there could
be a race between lock and unlock Entropy Client methods that could
cause the former to unlink() a still valid lock file. This happens
now due to the introduction of non-exclusive locking support.
Get rid of all this shit then!