[comp.sys.mac.programmer] DA loses resource file on accRun

sund@tde.lth.se (Lars Sundstr|m) (07/17/89)

I'm developing a desk accessory which reads a resource
file continuously. When the DA is running as a foreground
task it periodically receives accCursor events which
is used for reading a couple of resources. So far so good.

However when running in the background the DA only receives
accRun events and the DA can't reach the resource file because
UseResFile(myResFile) gives ResError=-193 "resource file not found".
It seems to me that when the DA receives accRun events its called
without a context switching but I don't know for sure.

Does anyone know what's the problem here?

Thanks in advance


Lars Sundstroem

sund@tde.lth.se (Lars Sundstr|m) (07/17/89)

Newsgroups: comp.sys.mac.programmer
Subject: DA loses resource file on accRun
Expires: 
References: 
Sender: 
Reply-To: sund@tde.lth.se (Lars Sundstr|m)
Followup-To: 
Distribution: world
Organization: Dept. of Applied Electronics, University of Lund, Keywords: 


I'm developing a desk accessory which reads a resource
file continuously. When the DA is running as a foreground
task it periodically receives accCursor events which
is used for reading a couple of resources. So far so good.

However when running in the background the DA only receives
accRun events and the DA can't reach the resource file because
UseResFile(myResFile) gives ResError=-193 "resource file not found".
It seems to me that when the DA receives accRun events its called
without a context switching but I don't know for sure.

Does anyone know what's the problem here?

Thanks in advance


Lars Sundstroem

time@oxtrap.sendai.ann-arbor.mi.us (Tim Endres) (07/20/89)

In article <1989Jul17.045641.20314@lth.se> sund@tde.lth.se (Lars Sundstr|m) writes:

   I'm developing a desk accessory which reads a resource
   file continuously. When the DA is running as a foreground
   task it periodically receives accCursor events which
   is used for reading a couple of resources. So far so good.

   However when running in the background the DA only receives
   accRun events and the DA can't reach the resource file because
   UseResFile(myResFile) gives ResError=-193 "resource file not found".
   It seems to me that when the DA receives accRun events its called
   without a context switching but I don't know for sure.

   Does anyone know what's the problem here?

Assuming you are under MultiFinder...

You do not mention where myResFile came from, but lets assume for the
moment that you open it in the DA w/ OpenResFile(). The difference
between accCursor and accRun is that accCursor *only* happens when the
DA Manager is active. accRun, on the other hand, can come any the time.

Now, I do know that the opened resource file gets a table entry in the
FCB table. And that this is NOT ties to the running application. So,
unless someone is closing that file, it should still be valid. The
only possibilities for it to not be valid are:

1) Your "myResFile" is wrong.
   I assume you checked this.
2) The file somehow got closed.
   Difficult to check (walk the FCB table by hand), but I assume this
   is not the problem.
3) The resource file chain does not include myResFile
   I have to beleive, that for sanity reasons, MultiFinder keeps
   seperate chains of resource files. I would think this in that many
   applications depend on a "well defined" resource chain. I.e. I
   expect that the resource I am asking for will come from my
   application's resource fork, and not some other's. If this is the
   case, then I would tend to beleive that you have two different
   resource file chains, the one you get in the foreground, and the
   one you get in the background. Thus, accRun gets a chain without
   the file that you are looking for.

   The fix: 
	* Migrate the resources to the system file.
	* Keep resources in memory.
	  I assume you can't, thus the reason for the problem.
	* Open and Close the resource file around the reads.
	  Boy, here's a performance beast.
	* Don't use resources. Use an open file and struct's.

BTW: I would use accRun for ALL cases. accCursor is very unreliable
for periodic action, and too much overhead when the cursor is flying
about the DA's window. Of course, you may have very good interface
reasons for this approach.

So, this was a lot of rambling. Hope it contains a good pointer.

Tim.

sund@tde.lth.se (Lars Sundstr|m) (07/20/89)

In article <TIME.89Jul19143726@oxtrap.sendai.ann-arbor.mi.us> time@oxtrap.UUCP writes:
>In article <1989Jul17.045641.20314@lth.se> sund@tde.lth.se (Lars Sundstr|m) writes:
>>
>>   I'm developing a desk accessory which reads a resource
>>   file continuously. When the DA is running as a foreground
>>   task it periodically receives accCursor events which
>>   is used for reading a couple of resources. So far so good.
>>
>>   However when running in the background the DA only receives
>>   accRun events and the DA can't reach the resource file because
>>   UseResFile(myResFile) gives ResError=-193 "resource file not found".
>>   It seems to me that when the DA receives accRun events its called
>>   without a context switching but I don't know for sure.
>>
>>   Does anyone know what's the problem here?
>>
>Assuming you are under MultiFinder...

Yes

>1) Your "myResFile" is wrong.
>   I assume you checked this.

As soon as the DA runs in the foreground everything works fine.

>   The fix: 
>	* Migrate the resources to the system file.
>	* Keep resources in memory.
>	  I assume you can't, thus the reason for the problem.
>	* Open and Close the resource file around the reads.
>	  Boy, here's a performance beast.
>	* Don't use resources. Use an open file and struct's.
>

The format of the resource file that has to be read is already
defined and all resources together are to big to be kept in memory.
But since the problem only occures when under MultiFinder 
I could use some of the global space provided by the MF Temp. Memory
Allocation in conjuction with Open and Close the resource file.
Thus I could maybe read 10 resources instead of one every time the
file has to be opened. I give it try.

I assume that I can't do a context switch of my own to return to
environment as seen by the DA at all other events except accRun. 

>BTW: I would use accRun for ALL cases. accCursor is very unreliable
>for periodic action, and too much overhead when the cursor is flying
>about the DA's window. Of course, you may have very good interface
>reasons for this approach.
>
>So, this was a lot of rambling. Hope it contains a good pointer.
>
>Tim.

Thanks

Lars

goldman@apple.com (Phil Goldman) (07/20/89)

In article <1989Jul17.045641.20314@lth.se> sund@tde.lth.se (Lars 
Sundstr|m) writes:
> I'm developing a desk accessory which reads a resource
> file continuously. When the DA is running as a foreground
> task it periodically receives accCursor events which
> is used for reading a couple of resources. So far so good.
> 
> However when running in the background the DA only receives
> accRun events and the DA can't reach the resource file because
> UseResFile(myResFile) gives ResError=-193 "resource file not found".
> It seems to me that when the DA receives accRun events its called
> without a context switching but I don't know for sure.
> 

This is correct.  The resource file was originally opened when the DA 
Handler was running.  However, at accRun time some other app may be 
running, and that app has a different resource chain than DA Handler, so 
when the resource manager searches the current chain it never does find 
your map.

The best workaround is to get the resources when you start up, or at some 
other time when you know that the app that opened you (usually DA Handler) 
is running.

-Phil Goldman
Apple Computer

matthews@eleazar.dartmouth.edu (Jim Matthews) (07/21/89)

In article <2932@internal.Apple.COM> goldman@apple.com (Phil Goldman) writes:
> The resource file was originally opened when the DA
>Handler was running.  However, at accRun time some other app may be 
>running, and that app has a different resource chain than DA Handler, so 
>when the resource manager searches the current chain it never does find 
>your map.

This is one more way in which MultiFinder makes DAs second class
citizens.  A more dramatic example of the problem can be seen by having
a DA open a window at accRun time -- it will appear in the foreground
app's layer, not (necessarily) the DA Handler's.

So, how hard would it be to make MultiFinder treat background DAs the
way it treats background apps -- i.e. do a minor switch to DA Handler
before issuing the accRun call?

Jim Matthews
Dartmouth Software Development

keith@Apple.COM (Keith Rollin) (07/22/89)

In article <14573@dartvax.Dartmouth.EDU> matthews@eleazar.dartmouth.edu (Jim Matthews) writes:
>In article <2932@internal.Apple.COM> goldman@apple.com (Phil Goldman) writes:
>> The resource file was originally opened when the DA
>>Handler was running.  However, at accRun time some other app may be 
>>running, and that app has a different resource chain than DA Handler, so 
>>when the resource manager searches the current chain it never does find 
>>your map.
>
>This is one more way in which MultiFinder makes DAs second class
>citizens.  A more dramatic example of the problem can be seen by having
>a DA open a window at accRun time -- it will appear in the foreground
>app's layer, not (necessarily) the DA Handler's.
>
>So, how hard would it be to make MultiFinder treat background DAs the
>way it treats background apps -- i.e. do a minor switch to DA Handler
>before issuing the accRun call?

Not hard at all. However, as I understand it, there was a very conscious
decision to not make that switch. Doing so would have to be done *VERY*
frequently, and - put in technical terms - this slowed down the Mac a bunch.

Background applications get the minor switch because they can be optimized
for background time. First of all, background applications don't get null
events unless the canBackground bit is set. Second, there is the 'sleep'
parameter of WaitNextEvent. Both of these help prevent numerous minor
switches. DA's don't have these options available to them, so saving time had
to be done in this other way.

------------------------------------------------------------------------------
Keith Rollin  ---  Apple Computer, Inc.  ---  Developer Technical Support
INTERNET: keith@apple.com
    UUCP: {decwrl, hoptoad, nsc, sun, amdahl}!apple!keith
"Argue for your Apple, and sure enough, it's yours" - Keith Rollin, Contusions

matthews@eleazar.dartmouth.edu (Jim Matthews) (07/23/89)

In article <33359@apple.Apple.COM> Keith Rollin writes:
>In article <14573@dartvax.Dartmouth.EDU> Jim Matthews writes:
>>So, how hard would it be to make MultiFinder treat background DAs the
>>way it treats background apps -- i.e. do a minor switch to DA Handler
>>before issuing the accRun call?
>
>Background applications get the minor switch because they can be optimized
>for background time. First of all, background applications don't get null
>events unless the canBackground bit is set. Second, there is the 'sleep'
>parameter of WaitNextEvent. Both of these help prevent numerous minor
>switches. DA's don't have these options available to them, so saving time had
>to be done in this other way.

I can believe that the minor switch would be time consuming, but it isn't
true that DAs have no way to control their use of background time -- that's
what the dCtlDelay field is for.

I suppose what I'd like most is to have these decisions documented.  The
programming model for DAs under MultiFinder may be well thought out, but it
isn't very clear.  For example: if a DA under MultiFinder calls ModalDialog,
background apps will continue to get time (since ModalDialog calls either
GetNextEvent or WaitNextEvent).  But DAs and drivers with dNeedTime lit will
not get their periodic time.  We have network protocol drivers that time out
when a DA calls Std File, but *not* when an app does the same thing.  There
may be a reason for this (avoiding re-entrancy is a likely candidate)
but I've never seen it documented, much less justified.

Jim Matthews
Dartmouth Software Development

keith@Apple.COM (Keith Rollin) (07/23/89)

In article <14600@dartvax.Dartmouth.EDU> matthews@eleazar.dartmouth.edu (Jim Matthews) writes:
>
>I suppose what I'd like most is to have these decisions documented.  The
>programming model for DAs under MultiFinder may be well thought out, but it
>isn't very clear.  For example: if a DA under MultiFinder calls ModalDialog,
>background apps will continue to get time (since ModalDialog calls either
>GetNextEvent or WaitNextEvent).  But DAs and drivers with dNeedTime lit will
>not get their periodic time.  We have network protocol drivers that time out
>when a DA calls Std File, but *not* when an app does the same thing.  There
>may be a reason for this (avoiding re-entrancy is a likely candidate)
>but I've never seen it documented, much less justified.

Jim, you're just a little ahead of us. In the next batch of technotes that we
are preparing are some that address these very issues. They're already written,
and are being reviewed right now.

------------------------------------------------------------------------------
Keith Rollin  ---  Apple Computer, Inc.  ---  Developer Technical Support
INTERNET: keith@apple.com
    UUCP: {decwrl, hoptoad, nsc, sun, amdahl}!apple!keith
"Argue for your Apple, and sure enough, it's yours" - Keith Rollin, Contusions

jkjl@cs.mu.oz.au (John Keong-Jin Lim) (07/24/89)

In article <33359@apple.Apple.COM> keith@Apple.COM (Keith Rollin) writes:
>Background applications get the minor switch because they can be optimized
>for background time. First of all, background applications don't get null
>events unless the canBackground bit is set. 

There is a bit you can set in the dCtlFlags that allows you to
control whether accRun is called at all (this is from memory - I
dont have IM here, so i cant guarantee 100% accuracy).

>Second, there is the 'sleep'
>parameter of WaitNextEvent. Both of these help prevent numerous minor

DAs have the dCtlDelay to tell the DA how long to sleep.

>switches. DA's don't have these options available to them, so saving time had
>to be done in this other way.

What you said above just isnt true, Keith. Apple has provided ways of
making background tasks in DAs very friendly. Why not have a resource
in DAs like the sysz resource in inits to inform MF that it is friendly ??

	john lim

keith@Apple.COM (Keith Rollin) (07/24/89)

In article <2808@murtoa.cs.mu.oz.au> jkjl@murtoa.UUCP (John Keong-Jin Lim) writes:
>In article <33359@apple.Apple.COM> keith@Apple.COM (Keith Rollin) writes:
>>Background applications get the minor switch because they can be optimized
>>for background time. First of all, background applications don't get null
>>events unless the canBackground bit is set. 
>
>There is a bit you can set in the dCtlFlags that allows you to
>control whether accRun is called at all (this is from memory - I
>dont have IM here, so i cant guarantee 100% accuracy).
>
>>Second, there is the 'sleep'
>>parameter of WaitNextEvent. Both of these help prevent numerous minor
>
>DAs have the dCtlDelay to tell the DA how long to sleep.
>
>>switches. DA's don't have these options available to them, so saving time had
>>to be done in this other way.
>
>What you said above just isnt true, Keith. Apple has provided ways of
>making background tasks in DAs very friendly. Why not have a resource
>in DAs like the sysz resource in inits to inform MF that it is friendly ??

Hmmm...that's what I get for talking about something I know very little about.
Personally, I've never written a driver or DA. Nasty little things. I believe
you are correct in the things you say. There's the 'drvrDelay' field and the
'dNeedTime' bit. There's even the accCursor message to take the place of 
mouseMoved events.

I just tried forwarding on what I'd heard from someone else. I guess I'd better
stick to answering MPW and MacApp questions...

------------------------------------------------------------------------------
Keith Rollin  ---  Apple Computer, Inc.  ---  Developer Technical Support
INTERNET: keith@apple.com
    UUCP: {decwrl, hoptoad, nsc, sun, amdahl}!apple!keith
"Argue for your Apple, and sure enough, it's yours" - Keith Rollin, Contusions