Race Conditions in Kodi

Race Conditions in Kodi

I tag and rate my movies quite a bit, which allows me to organize and sort my movies by tags and user ratings. I find the built-in mechanism for tagging or rating a movie cumbersome, so I wrote a small addon called "My Rating & Tags" for Kodi, which exposes a simple submenu in the context menu to allow speedy access to these two features.

When the user opens the context menu and picks a user rating, the addon calls the Python script to update the user rating of the movie. The Python script figures out the idMovie, and issues a xbmc.executeJSONRPC()call to the database to update the user rating.

After lots of trials and errors, I finally got the script to work. But when I started testing the addon, I noticed that user ratings weren't being updated properly.

Turns out there was a race condition in my code.

Inside my Python script, I was doing the following to obtain the idMovie of the selected movie to be rated:

dbid = int(xbmc.getInfoLabel('ListItem.DBID'))
dbtype = xbmc.getInfoLabel('ListItem.DBtype')

The issue is that xbmc.getInfoLabel() gets the InfoLabel of the movie that is currently selected, so if the user navigates to a different movie before the script is run, xbmc.getInfoLabel() would actually obtain the id of the wrong movie, thus applying the rating to the wrong movie.

The correct way is to use sys.listitem, which returns the movie that actually triggers the script:

dbid = sys.listitem.getVideoInfoTag().getDbId()
mediatype = sys.listitem.getVideoInfoTag().getMediaType()

I've noticed this type of race conditions a bit in UI applications. These bugs are sometimes hard to catch and diagnose. Obviously the solution is to always operate on the item that triggers the action, instead of the item that is currently selected in the UI. However, it's not always clear which is which just by reading the API documentation.