• Open Menu Close Menu
  • Apple
  • Shopping Bag
  • Apple
  • Mac
  • iPad
  • iPhone
  • Watch
  • TV
  • Music
  • Support
  • Search apple.com
  • Shopping Bag

Lists

Open Menu Close Menu
  • Terms and Conditions
  • Lists hosted on this site
  • Email the Postmaster
  • Tips for posting to public mailing lists
Re: Threads
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Threads


  • Subject: Re: Threads
  • From: Alastair Houghton <email@hidden>
  • Date: Mon, 11 Jul 2016 08:40:57 +0100

On 11 Jul 2016, at 06:35, Gerriet M. Denkmann <email@hidden> 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@hidden)

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:

This email sent to email@hidden


References: 
 >Threads (From: "Gerriet M. Denkmann" <email@hidden>)

  • Prev by Date: Threads
  • Next by Date: Re: Threads
  • Previous by thread: Threads
  • Next by thread: Re: Threads
  • Index(es):
    • Date
    • Thread