When to use CSingleLock?

  Thread Rating:
  • 0 Votes - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Post Reply
xbmcfanboy0 Offline
Junior Member
Posts: 34
Joined: Mar 2012
Reputation: 4
Post: #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;
    }
  }
}
(This post was last modified: 2012-04-06 13:55 by xbmcfanboy0.)
find quote
xbmcfanboy0 Offline
Junior Member
Posts: 34
Joined: Mar 2012
Reputation: 4
Post: #2
Additionally. Both of these functions seem to serve similar purposes. Yet function #1 returns bool while function #2 returns void.
find quote
Memphiz Offline
Team-Kodi Developer
Posts: 11,056
Joined: Feb 2011
Reputation: 113
Location: germany
Post: #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.

AppleTV2/iPhone/iPod: HowTo find debug logs and everything else which the devs like so much: click here
HowTo setup NFS for XBMC: Wiki NFS
HowTo configure avahi (zeroconf): Wiki Avahi
READ THE IOS FAQ!: iOS FAQ
find quote
bobo1on1 Offline
cheapass Team-XBMC Developer
Posts: 2,758
Joined: Dec 2008
Reputation: 22
Post: #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.
find quote
xbmcfanboy0 Offline
Junior Member
Posts: 34
Joined: Mar 2012
Reputation: 4
Post: #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?
find quote
spiff Offline
Retired Developer
Posts: 12,386
Joined: Nov 2003
Post: #6
Yes very easy to determine; will the function be called from several threads concurrently?
find quote
xbmcfanboy0 Offline
Junior Member
Posts: 34
Joined: Mar 2012
Reputation: 4
Post: #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?
find quote
spiff Offline
Retired Developer
Posts: 12,386
Joined: Nov 2003
Post: #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..
find quote
bobo1on1 Offline
cheapass Team-XBMC Developer
Posts: 2,758
Joined: Dec 2008
Reputation: 22
Post: #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.
find quote