just to call off the dogs, in case there are any, I solved the crash by 
re-working the logic a little.
It's cleaner the new way anyway, though I don't know whether the concurrency 
stuff is really fixed 
(or whether it was "really" broken!)

It works, and I'm a tight deadline, so that's all that matters!

J.



On 2010-05-01, at 5:54 PM, James Maxwell wrote:

> Okay, so let me give a little more info.
> 
> Here's the stack trace.
> 
> #0    0x7fff8578693c in __CFTypeCollectionRelease
> #1    0x7fff85783e43 in __CFArrayReleaseValues
> #2    0x7fff85764bc8 in _CFArrayReplaceValues
> #3    0x1000183ad in -[HSMM_Node addCoincidenceToBeliefMemory:] at 
> HSMM_Node.m:229
> #4    0x100017803 in -[HSMM_Node topDown:] at HSMM_Node.m:121
> #5    0x100012a94 in __-[HSMM_NetworkController 
> runNetworkOnInput:]_block_invoke_555 at HSMM_NetworkController.m:225
> #6    0x7fff804f3e68 in _dispatch_apply2
> #7    0x7fff804eb487 in dispatch_apply_f
> #8    0x10001232e in -[HSMM_NetworkController runNetworkOnInput:] at 
> HSMM_NetworkController.m:218
> #9    0x100005050 in __-[OSC_Controller receivedOSCMessage:]_block_invoke_876 
> at OSC_Controller.m:252
> #10   0x7fff804a1e63 in dispatch_sync_f
> #11   0x100004155 in -[OSC_Controller receivedOSCMessage:] at 
> OSC_Controller.m:251
> #12   0x10008a2bc in -[OSCManager receivedOSCMessage:] at OSCManager.m:232
> #13   0x10008af82 in -[OSCInPort handleScratchArray:] at OSCInPort.m:262
> #14   0x10008bc5f in -[OSCInPort OSCThreadProc] at OSCInPort.m:240
> #15   0x100054797 in -[VVThreadLoop threadCallback] at VVThreadLoop.m:76
> #16   0x7fff81943e99 in __NSThread__main__
> #17   0x7fff804a5f8e in _pthread_start
> #18   0x7fff804a5e41 in thread_start
> 
> And the source for the method does does all the work is below. This wraps 
> everything up in a couple of blocks.
> The second loop is the one that's causing the crash and the only way I think 
> this could happen would be if the 
> first loop hadn't completed. My, possibly totally misinformed, opinion was 
> that this method would run the
> first loop to completion, then run the second.  That is, all "aNode" objects 
> would do their thing in the first loop
> **before** the second loop could start. But maybe I'm wrong about that. I 
> have to admit that my grasp
> of GCD is pretty sketchy. If this isn't the case, and the second loop could, 
> in fact, start running before all
> the aNode objects in the first loop had finished their processing, then I can 
> totally understand why it would
> crash. Is there some way to ensure that? How would I make sure that 
> *everything* started in the first
> loop finished before moving on to the second. If I do that, then my crash 
> should be solved.
> 
> - (void)                      runNetworkOnInput:(float *)inputPattern
> {
>       printf("\n\n********* Start Run ************\n\n");
>       int i, numLevels;
>       numLevels = [[[self network] hierarchy] count];
>       
>       dispatch_queue_t hsmm_queue;
>       hsmm_queue = dispatch_get_global_queue(0, 0);
>       
>       [self setPlaybackPossible:YES];
>       
>       for(i=0;i < numLevels;i++)                                              
> // run up the network
>       {
>               NSMutableArray* level = [[[self network] hierarchy] 
> objectAtIndex:i];
>               dispatch_apply([level count],
>                                          hsmm_queue, 
>                                          ^(size_t index) {
>                                                  HSMM_Node* aNode = [level 
> objectAtIndex:index];
>                                                  [aNode setIsPassive:NO];
>                                                  if([aNode nodeLevel] == 1)
>                                                  {
>                                                          [aNode 
> setPredictionRequestsLocked:NO];
>                                                          [aNode 
> setInputCounter:([aNode inputCounter] + 1)]; 
>                                                          [aNode run:nil];
>                                                  } else {
>                                                          BOOL readyToLearn = 
> YES;
>                                                          for(HSMM_Node* child 
> in [aNode childNodes])
>                                                          {
>                                                                  if([child 
> nodeLevel] == 1 && [[child sequencer] predictionAccuracy] < 0.3)
>                                                                  {
>                                                                          
> readyToLearn = NO;
>                                                                          
> break;
>                                                                  }
>                                                          }
>                                                          if(readyToLearn == 
> YES && [aNode predictionRequestsLocked] == YES)   // the child is asking for 
> help! the parent needs to learn
>                                                          {
>                                                                  [aNode 
> setPredictionRequestsLocked:NO];
>                                                                  [aNode 
> setInputCounter:([aNode inputCounter] + 1)]; 
>                                                                  [aNode 
> run:nil];
>                                                          }
>                                                  }
>                                          });
>       }
>       
>       for(i=numLevels - 1;i >= 0;--i)                                 // run 
> back down the network
>       {
>               NSMutableArray* level = [[[self network] hierarchy] 
> objectAtIndex:i];
>               dispatch_apply([level count],
>                                          hsmm_queue, 
>                                          ^(size_t index) {
>                                                  HSMM_Node* aNode;
>                                                  aNode = [level 
> objectAtIndex:index];
>                                                  [aNode 
> getEvidenceFromParents];
>                                                  [aNode topDown:[aNode 
> parentEvidence]];
>                                                  if([aNode nodeLevel] == 1)
>                                                          [[aNode sequencer] 
> predictForward:NO];
>                                          });
>       }
> }
> 
> 
> On 2010-05-01, at 5:17 PM, Kyle Sluder wrote:
> 
>> On May 1, 2010, at 5:04 PM, James Maxwell <[email protected]> wrote:
>> 
>>> I'm having a crash when trying to remove the last item in an NSMutableArray.
>>> The app is a pretty complex system, and runs its two main processes in 
>>> consecutively executed blocks.
>>> The blocks are run using dispatch_apply, on the global queue. The operation 
>>> that's trying to
>>> access the NSArray is, I think, within the first block... but honestly, I 
>>> can't be totally sure, as
>>> I don't know exactly why the app is crashing.
>> 
>> Yes you do. You have a debugger and a stack trace.
>> 
>>> I guess what I'm wondering is whether there's some fool-proof way of 
>>> protecting that NSArray from being read and changed simultaneously?
>>> I tried making the array nonatomic, but that didn't solve the problem.
>>> Of note is the fact that this is directly related to processing load, so 
>>> I'm assuming it has to do
>>> with some timing thing -- as the app gets more loaded down, things get 
>>> sketchy.
>> 
>> The concept you're looking for is thread safety. It is, in general, a Very 
>> Hard Problem.
>> 
>> 
>>> I know this isn't a great description of the problem, but hopefully someone 
>>> has some thoughts to share.
>> 
>> If you have a crash, the only two useful pieces of information are the 
>> source code and the stack trace. Anything else risks misinterpretation and 
>> therefore wasted time.
>> 
>> --Kyle Sluder
> 
> James B Maxwell
> Composer/Doctoral Student
> School for the Contemporary Arts (SCA)
> School for Interactive Arts + Technology (SIAT)
> Simon Fraser University
> [email protected]
> [email protected]
> 
> _______________________________________________
> 
> Cocoa-dev mailing list ([email protected])
> 
> Please do not post admin requests or moderator comments to the list.
> Contact the moderators at cocoa-dev-admins(at)lists.apple.com
> 
> Help/Unsubscribe/Update your Subscription:
> http://lists.apple.com/mailman/options/cocoa-dev/jbmaxwell%40rubato-music.com
> 
> This email sent to [email protected]

James B Maxwell
Composer/Doctoral Student
School for the Contemporary Arts (SCA)
School for Interactive Arts + Technology (SIAT)
Simon Fraser University
[email protected]
[email protected]

_______________________________________________

Cocoa-dev mailing list ([email protected])

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to [email protected]

Reply via email to