Hi guys, I had this in my queue since Easter. to make it short, our current global lock sucks, and it will suck more when we get packagekit, zypper and yast running at the same time :-)
My prototype has passed the two initial test cases.
The idea is a scoped object, that is, to make it work you create it, and once it is out of scope, it releases the lock.
Locks are by name. And you can create writer or readers mutex for a named region. The name you give to the mutex will determine which region it will protect, and if you are entering it as reader or writer, and the behavior: wait until free, wait with timeout, or abort if locked.
The different behaviors are that for example some operations, like enabling or disabling repos are really short, but probably we don't want to wait for the rpm commit lock to end and abort immediately.
So you use like this: process A, the pool creates a reader lock for the pool: InterProcessMutex mutex( "pool", Reader);
The repomanager wants to rewrite the solv files, which would screw up if some process have the global pool (usually zypper for some seconds, or YaST while the user has it opened), so the repomanager could do:
InterProcessMutex mutex( "pool", Writer, 10);
Repomanager will not be able to write while the first mutex is on scope, and will sleep for a total of 10 seconds on 1 seconds intervals, and then will throw if the lock is still there.
However if another process just want to query data from the solv files, like a second process accessing the global pool, it will take a second reader lock on "pool" which will coexist nicely with the first one.
Reference counting, cleaning etc is done by fcntl locks, so the kernel takes care of most stuff. (it is a direct mapping of the named resources over locks on a file per-resource, plus cleaning an waiting logic)
It is not correct, if we for example test a lock for not being locked, and then try to acquire a lock, and just in the middle another process take it first, what we do is we abort mission and re enter the loop to try to acquire again, so it works reasonable, but it does not guarantee order on serving the resource, which is reasonable for the use case I guess.
There are some improvements suggested by Michael Andres already, specially in the code path, and I also need more test cases covering more combinations. But I post it here for review / comments.