Introduce thread-safe Entity::retrieveByNameOrCreate()
During DB initialization when multiple resources try to synchronize and insert first item, the mimetypes, parttypes and other similar tables are empty and the entries need to be created. This presents a race condition when multiple threads try to create the new entry at the same time - one of them is succesfull, the others usually abort, which leads to the resource failing the synchronization. retrieveByNameOrCreate() will try to retrieve the item from cache or DB first. If it does not get any result it tries to acquire a lock. If the thread gets a lock it inserts the new entry into DB and cache. Otherwise the thread just waits for the lock (i.e. until the thread that acquired the lock inserts the new entity) and then retrieves the entity from the cache. This isn't really a common situation, which would happen during normal usage of Akonadi. We however see it quite often during unit-test initialization when all three Knut resources start pushing their data into Akonadi at the same time and trigger this race condition.
Showing with 82 additions and 53 deletions