While I was hunting down a bug in the UPnP system I found another bug, which looked like it was a bug in SQLiteDatabase, but to me it seams that the code in ClientManager is at least "not ideal" if not wrong.
Steps to reproduce:
1. Start MP2 Server (with SQLiteDatabase)
2. Start MP2 Client
3. Attach the MP2 Client to the MP2 Server
4. Detach the MP2 Client from the MP2 Server
5. press ESC.
Now the client hangs and in the server log you see that SQLiteDatabase uses three more connections and nothing else happens.
The reason can be found here: https://github.com/MediaPortal/Medi...ces/ClientCommunication/ClientManager.cs#L242
We first start one transaction and execute a delete command.
But before we commit this transaction we call
Each of these calls starts another transaction with each another connection to the database in the same thread. Both transactions are "write" transactions because they try to delete. And in the respective delete statements they access the same table as our very first transaction.
This does not work, because the very first transaction holds a write lock to the respective table. This lock is held until a commit is issued to the first transaction. The two calls to media library also try to aquire a write lock on the same table, but they don't get it because we have a dead lock with the first transaction.
In gerenal, this code in ClientManager is IMHO bad because
Any opinions on this? My proposal is easy so I'm happy to implement a patch if there is no objection...
Michael
PS: I also found the UPnP bug by the way. But I couldn't reproduce it due to this bug - so one thing after the other
Steps to reproduce:
1. Start MP2 Server (with SQLiteDatabase)
2. Start MP2 Client
3. Attach the MP2 Client to the MP2 Server
4. Detach the MP2 Client from the MP2 Server
5. press ESC.
Now the client hangs and in the server log you see that SQLiteDatabase uses three more connections and nothing else happens.
The reason can be found here: https://github.com/MediaPortal/Medi...ces/ClientCommunication/ClientManager.cs#L242
We first start one transaction and execute a delete command.
But before we commit this transaction we call
Code:
mediaLibrary.DeleteMediaItemOrPath(clientSystemId, null, true);
mediaLibrary.RemoveSharesOfSystem(clientSystemId);
This does not work, because the very first transaction holds a write lock to the respective table. This lock is held until a commit is issued to the first transaction. The two calls to media library also try to aquire a write lock on the same table, but they don't get it because we have a dead lock with the first transaction.
In gerenal, this code in ClientManager is IMHO bad because
- nested write transaction in the same thread are evil in general (AFAIK we avoid them anywhere else in our code); and
- to my understanding all the database changes which occurr in ClientManager.DetachClientAndRemoveShares should happen in one single transaction - not in three transactions as it is now, because either we remove all the traces of that client from the database or we rollback completely.
Any opinions on this? My proposal is easy so I'm happy to implement a patch if there is no objection...
Michael
PS: I also found the UPnP bug by the way. But I couldn't reproduce it due to this bug - so one thing after the other