Thread safety and NSMutableArray properties

424 views
Skip to first unread message

Robbie Hanson

unread,
Oct 8, 2009, 1:02:14 PM10/8/09
to teleph...@googlegroups.com
In AKSIPAccount, there is a property like this:

@property(readonly, retain) NSMutableArray *calls;

The property is used in various places such as AKSIPAccount's makeCallTo method, and also in AKSIPUserAgent's SIPCallByIdentifier method:

- (AKSIPCall *)SIPCallByIdentifier:(NSInteger)anIdentifier {
  for (AKSIPAccount *anAccount in [[[self accounts] copy] autorelease])
    for (AKSIPCall *aCall in [[[anAccount calls] copy] autorelease])
      if ([aCall identifier] == anIdentifier)
        return [[aCall retain] autorelease];
  
  return nil;
}

I believe this might be a problem.  Even though the property is atomic, this only means that it's atomic for getters and setters.  Modifying the mutable array from multiple threads is still unsafe.

As an alternative, one might consider removing the calls property, and adding thread safe methods to manipulate the array:

- (void)addCall:(AKSIPCall *)call
{
@synchronized(calls)
{
  [calls addObject:call];
}
}

- (AKSIPCall *)callByIdentifier:(NSInteger)callID
{
@synchronized(calls)
{
for(AKSIPCall *call in calls)
{
if([call identifier] == callID)
{
return [[call retain] autorelease];
}
}

return nil;
}
}

- (void)removeCall:(AKSIPCall *)call
{
@synchronized(calls)
{
  [calls removeObject:call];
}
}

- (void)removeAllCalls
{
@synchronized(calls)
{
  [calls removeAllObjects];
}
}

- (NSArray *)allCalls
{
@synchronized(calls)
{
  return [[calls copy] autorelease];
}
}

-Robbie Hanson




Alexei Kuznetsov

unread,
Oct 10, 2009, 7:17:19 PM10/10/09
to teleph...@googlegroups.com
Thank you again, Robbie! Started issue 223.

Alexei
Reply all
Reply to author
Forward
0 new messages