This thing has puzzles us as well during the project. Nazar has used Asserts to check for the right thread during development. 
But I think asserts are not the best way to force this, because the happens only at runtime and are candidates to break a party if a user hits a rare untested usecase. 

A better solution would be to remove all DAO references from the GUI classes. We have already discussed this short, but have not found a solution that was doable in time.  

What about, privatize the DAOs by by introduce the PIMPL idiom to TrackCollection.
The DAOSs should be instantiated in the private Implementation class of  TrackCollection and made accessible in the Lambda by a pointer parameter. 

The code section will look like that then:

---
        m_pTrackCollection->callSync(
                    [this, &playlists] (TrackCollectionPrivate* pTcp) {
            int numPlaylists = pTcp->m_playlistDao.playlistCount();
            for (int i = 0; i < numPlaylists; ++i) {
                int iPlaylistId = pTcp->m_playlistDao.getPlaylistId(i);
                playlists.insert(pTcp->m_playlistDao.getPlaylistName(iPlaylistId), iPlaylistId);
            }
        }, __PRETTY_FUNCTION__);
---

Do you think this will work?