When to use CSingleLock?
#1
Please help me understand when CSingleLock should be called.
Consider the 2 functions below. Why is CSingleLock required for function #1 but not for #2? How do I know if the lock is required?

Uses CSingleLock
Code:
bool CFileItemList::UpdateItem(const CFileItem *item)
{
  if (!item) return false;

  CSingleLock lock(m_lock);
  for (unsigned int i = 0; i < m_items.size(); i++)
  {
    CFileItemPtr pItem = m_items[i];
    if (pItem->IsSamePath(item))
    {
      *pItem = *item;
      return true;
    }
  }
  return false;
}

does not use CSingleLock
Code:
void CPlayList::UpdateItem(const CFileItem *item)
{
  if (!item) return;

  for (ivecItems it = m_vecItems.begin(); it != m_vecItems.end(); ++it)
  {
    CFileItemPtr playlistItem = *it;
    if (playlistItem->IsSamePath(item))
    {
      *playlistItem = *item;
      break;
    }
  }
}
Reply
#2
Additionally. Both of these functions seem to serve similar purposes. Yet function #1 returns bool while function #2 returns void.
Reply
#3
the first function protects access to the m_items vector. This allows multiple threads to call this function while m_items is accessed in a atomic way (e.x. another thread can't delete items while first thread is iterating through that vector).

second function may not need this or just isn't threadsafe.
AppleTV4/iPhone/iPod/iPad: HowTo find debug logs and everything else which the devs like so much: click here
HowTo setup NFS for Kodi: NFS (wiki)
HowTo configure avahi (zeroconf): Avahi_Zeroconf (wiki)
READ THE IOS FAQ!: iOS FAQ (wiki)
Reply
#4
CSingleLock locks a CCriticalSection in its constructor, and unlocks it in its destructor, this way the CCriticalSection is always unlocked when the CSingleLock goes out of scope.
CCriticalSection is an XBMC wrapper class for mutex objects provided by the operating system.
Reply
#5
(2012-04-06, 15:45)Memphiz Wrote: second function may not need this or just isn't threadsafe.

Thanks. Is there a way for me to determine if a function does not need it or just isn't thread safe?
Reply
#6
Yes very easy to determine; will the function be called from several threads concurrently?
Reply
#7
(2012-04-08, 18:54)spiff Wrote: Yes very easy to determine; will the function be called from several threads concurrently?

I spent some time tonight to try to make sure I understand how to determine if CSingleLock is required. This may be a really stupid question, but how can I determine that a function can or *may* be called from several threads concurrently?
Reply
#8
in general, a lock is used to protect something. some variable that can be used from several threads at the same time (class members are a common fall trap, as well as globals). or it can be some other resource that cannot be used from several threads at the same time.

whether or not this is an issue, depends on the nature of the function in question..
Reply
#9
(2012-04-10, 09:45)xbmcfanboy0 Wrote:
(2012-04-08, 18:54)spiff Wrote: Yes very easy to determine; will the function be called from several threads concurrently?

I spent some time tonight to try to make sure I understand how to determine if CSingleLock is required. This may be a really stupid question, but how can I determine that a function can or *may* be called from several threads concurrently?

You check that by reading the code, and understanding what it's doing.
A function is always called from somewhere (usually from another function) so you can always trace back where a certain function is called from (as long as you have the sourcecode).

Regarding the lock, you use it to keep the state of variables or other resources consistent among threads, if one thread writes to a variable, and you read that variable from another thread, you want to make sure that thread reads the new value, if you don't use a lock it's possible that the thread reads the old value.

Sometimes keeping state consistent is not important, for example look at m_bStop in class CThread, since most of XBMC's threads run a loop and periodically check m_bStop, there's no need to use a lock there, another thread can just set m_bStop to true and the thread will eventually read that and stop.
This requires that the access to m_bStop is atomic, which means that it either holds the old value, or the new value, no intermediate ones.
Reply

Logout Mark Read Team Forum Stats Members Help
When to use CSingleLock?0