• 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: Running an NSTask Within an NSThread
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Running an NSTask Within an NSThread


  • Subject: Re: Running an NSTask Within an NSThread
  • From: James Bucanek <email@hidden>
  • Date: Sun, 27 Jan 2008 17:35:02 -0700

Jonathan Dann <mailto:email@hidden> wrote (Sunday, January 27, 2008 12:13 PM -0000):
You were half-right with the over-releasing thing.  All my code for
running the task is in a TaskController object, which was being
autoreleased after the task was run, but before the NSTaskDidTerminate
was sent.  I'd registered the object as an observer for this
notification but not removed is as the observer in the dealloc method
for the class!  It suddenly occurred to me that a notification was
being sent to a dealloc'd object.

Now I have the problem of my taskController being dealloc'd before the
task has finished (whether its in a new thread or not) so the
NSTaskDidTerminateNotification is not being received by the object.  I
*could* call [self autorelease] in the -taskDidTerminate: method, but
that will violate the memory management conventions.  I currently have
a class method that instantiates my TaskController object, this is
called from my NSDocument subclass.  So NSDocument subclass calls:
<clipped>

Jon,

See three possible solutions to this. You can be the judge of which one you like.

The real problem here is that your TaskController is associated with the running NSTask, but really isn't owned by any other object. This is the kind of situation where the typical Obj-C memory management rules break down.

----

1) I don't see any reason why the TaskController can't retain itself until it receives the taskDidTerminate: message. The TaskController is really "owned" by the NSTask, but you can't make the NSTask retain your TaskController until its done. So the TaskController can act as a proxy owner for itself until the NSTask terminates.

2) Take ownership of the TaskController in your NSDocument. Instead of creating an autoreleased TaskController and throwing it to the wind, the document could retain the TaskController until the TaskController was finished (which it could communicate back to the document object using a variety of means). Personally, I find this awkward, but it's "clean."

3) The "elegant" and "non polling" solution would be to spawn a new thread running [TaskController performTask]. In TaskController, create an NSConditionalLock object (let's call it taskDoneLock) with an initial condition of NO. The thread would start the NSTask then perform [taskDoneLock lockWhenCondition:YES];

In the taskDidTerminate: method, perform [taskDoneLock lock]; [taskDoneLock unlockWithCondition:YES];

The performTask basicaly goes to sleep waiting for taskDidTerminate: to "wake it up". performTask then continues executing. It now knows that the task has completed and can perform whatever post-processing it needs to before returning, which terminates the thread.

The "elegant" part of this solution is that [NSTask detachNewThreadSelector:toTarget:withObject:] retains the TaskController object until the thread terminates. By using a semaphore lock to signal when the NSTask is done, the thread exists (suspended) until the NSTask completes.

----

As for you timeout problem, you can start an NSTimer to send a message to another handler if you haven't received the taskDidTerminate: message in a reasonable amount of time. Your taskDidTerminate: would invalidate the timer so if the task ends before the timeout, the timer will never fire.

If you adopt solution #3, you have the added option of using [taskDoneLock lockWhenCondition:YES beforeDate:<NSDate*>]. This will cause performTask to wait until the lock is release OR the time-out time has arrived. You can then decide if you want to keep waiting for the task to finish or do something else.

Good luck,

James
--
James Bucanek

_______________________________________________

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


  • Prev by Date: Re: Running an NSTask Within an NSThread
  • Next by Date: The mouse is where, again?
  • Previous by thread: Re: Running an NSTask Within an NSThread
  • Next by thread: Re: Running an NSTask Within an NSThread
  • Index(es):
    • Date
    • Thread