On Tue, Aug 12, 2008 at 11:27 AM, Rick Hoge <[EMAIL PROTECTED]> wrote:
>
> Thanks for the replies - just got them now as my MobileMe email went offline
> for some reason last night...
>
>>> I noticed that there is some useful info relating to this topic in the
>>> documentation on Agents and Daemons at
>>>
>>>
>>> http://developer.apple.com/technotes/tn2005/tn2083.html#SECLIVINGDANGEROUSLY
>>>
>>> It does say that AppKit is not daemon-safe, but my testing suggests that
>>> if
>>> (as suggested in the technote) you avoid sensitive methods it should be
>>> ok
>>> (more info would be welcome).
>>
>> I'm curious as to whether you really read the thing....
>
> I did, I did!  (really)
>
> The fact that some discussion of possible issues *is* provided came of as
> sort of a tacit approval that in some cases this approach might be
> appropriate.

It seems pretty clear that the only cases where this approach might
possibly be appropriate is when you have no alternative whatsoever to
using a daemon-unsafe framework from a daemon, and even then you ought
to look harder for alternatives first. In your case, it sounds like
you're doing this out of convenience, not necessity.

Any C programmer should be familiar with the term "undefined
behavior". For example:

    main() { struct foo *foo; printf("%d", sizeof(struct foo)); }

This is not a legal C program. The foo struct has not been defined,
and so using the sizeof operator on it is forbidden. The behavior of
this undefined. What this means is that, essentially, anything could
happen:

1) The compiler could emit an error.
2) The code could crash at runtime.
3) The code could produce an incorrect value.
4) The compiler causes demons to fly out of your nose
(http://www.catb.org/jargon/html/N/nasal-demons.html).
5) The correct value is displayed.

Pay particular attention to #5: one of the legal possible consequences
of invoking undefined behavior is that the correct thing happens
anyway!

And even more importantly, it's perfectly legal for the behavior to
change between any of these 5 alternatives (and the infinite
possibilities beyond) just because you changed another piece of your
code somewhere else, used a different compiler version, used different
compiler *settings*, merely recompiled your code, or even merely
re-ran code that you already compiled.

The ultimate point of all of this is simple: just because it works
doesn't mean you can rely on it. To the extent that the document in
question explains an approach for reducing risk when using
daemon-unsafe frameworks, it's just that: how to reduce your risk. It
doesn't make it a safe or reasonable thing to do, and you should still
avoid doing it if you have any kind of alternative. Just like how
sometimes you have no choice but to use C code whose behavior is
undefined (but known to do what you want in the case that you need),
but whenever you can avoid doing so then you should.

> To me it comes down to what *methods* you expect to work...

The document you linked to clearly explains that you should never
expect any methods in any daemon-unsafe frameworks to work from such
an environment. To the extent that some methods do work, this is
purely by happenstance and they could stop working in Snow Leopard, or
in 10.5.5, or with the next security update, or the next time you
reboot, or recompile, or relaunch your app, or call the same method
with different arguments, or even just make the same call a second
time.

>    I certainly
> wouldn't expect to be able to instantiate an NSDocumentController and create
> and manage documents with it in an environment with no window server.
>  However if my NSDocument subclass contains a set of ivars (none of which
> use AppKit classes) that constitute a useful data model and implements file
> IO routines that do not, in any way, depend on the window server,  document
> controller, or any AppKit classes, it seems reasonable to expect that this
> subset of functionality could be used even on a headless node.  I can see
> how image decompression routines might be fragile, but the usage case I'm
> describing is a little different.

Yes, it's reasonable to expect that this subset could be used from a
daemon context. It's also reasonable to expect that this subset could
not be used from a daemon context. When you're trying to decide
whether it's allowed, the documentation is what prevails. The
documentation in this case is quite explicit that you can't do this,
and if it happens to work then it's simply by luck and may quit
working (or worse, appear to work but actually provide bad results) at
any time.

As a concrete example, it would be perfectly reasonable for AppKit to
start initializing itself and acquire the window server connection at
framework load time, and call abort() if the connection cannot be
acquired. Suddenly you would be utterly screwed if you had a bunch of
code that relied on using any piece of AppKit, even pieces which seem
like they ought to be perfectly safe, from a daemon.

> One obvious alternative is to create a 'Data Object' class that has no
> AppKit dependencies and stash it as an instance variable in a 'thin'
> NSDocument subclass that just supports tasks relating to a real
> document-based app in a window server environment.  To make my app work, I
> need two layers of subclass for my documents (a general NSDocument subclass
> and several subclasses of this for specific data types) so it's a bit more
> tricky.  I'd need to have a data object class hierarchy and a parallel
> document hierarchy.

If all of the smarts are in your own custom classes, why do you need a
hierarchy of NSDocument subclasses? Have a single NSDocument subclass
that passes all of the important methods on to your custom classes,
and your job should be done.

Mike
_______________________________________________

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

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