On 11 Jul 2016, at 06:35, Gerriet M. Denkmann <[email protected]> wrote:
> 
> I have a subclass of NSThread (called MyThread), which runs a RunLoop in main.
> When it gets cancelled, it leaves the RunLoop and main will exit.
> 
> Some other thread does:
> 
> if ( myThread.isCancelled )
> {
>       //      probably the RunLoop of myThread is no longer running
>       //      adding stuff to a non-running RunLoop would result in [myThread 
> dealloc] never called (some retain circle)
> }
> else
> {
>       [ myThread      performSelector:        @selector(someMethod) 
>                               onThread:               myThread
>                               withObject:             nil
>                               waitUntilDone:  NO 
>       ];
> }
> 
> But what if:
> “Some other thread” tests for isCancelled and sees: “not cancelled”
> Now yet another thread takes over and cancels myThread.
> Then “Some other thread” runs again and does performSelector… (bad)
> 
> How to avoid this scenario?

You need to use locks, I’m afraid; essentially your MyThread needs a 
cancellation lock, which it takes before cancelling the thread and also around 
the code above, such that it can’t be cancelled between the -isCancelled test 
and the -performSelector:onThread:withObject:waitUntilDone: call.

I’d be inclined to override the -cancel method, e.g.

  - (void)cancel {
    [cancellationLock lock];
    [super cancel];
    [cancellationLock unlock];
  }

and then add a -(BOOL)performSelector:withObject:waitUntilDone: method that does

  - (BOOL)performSelector:(SEL)sel withObject:(id)obj waitUntilDone:(BOOL)wait
  {
    [cancellationLock lock];
    if ([self isCancelled]) {
      [cancellationLock unlock];
      return NO;
    }

    // This is your own method, right?  You might just want to paste the code 
in here...
    [self performSelector:sel onThread:self withObject:obj waitUntilDone:wait];

    [cancellationLock unlock];
  }

then you can write

  if (![thread performSelector:@selector(someMethod) withObject:nil 
waitUntilDone:NO]) {
    // Thread was cancelled
  }

To be extra-safe, you might want to put some @try...@finally wrappers in there 
to handle the -unlock.

Kind regards,

Alastair.

--
http://alastairs-place.net


_______________________________________________

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:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to [email protected]

Reply via email to