jb@aries5.uucp (11/29/89)
This may seem like a strange question but seeing the discussion on multi-tasking, I have a related question. Is there any reliable way to make the device manager re-entrant. In other words if I do a PBRead() to a device driver can that device driver synchronously do another PBRead() to another device driver? From what I have observed this is non-trivial, because the second PBRead() will block becasue FSBusy is set. Jim Bruyn
Gavin_Eadie@um.cc.umich.edu (Gavin Eadie) (11/29/89)
In article <924@maytag.waterloo.edu> jb@aries5.uucp writes: > In other words if I do a PBRead() to a device driver can that device > driver synchronously do another PBRead() to another device driver? > > From what I have observed this is non-trivial, because the second > PBRead() will block becasue FSBusy is set. > > Jim Bruyn I wrestled with this for a while too. It turns out that, since the file system is not re-entrant, you have to cheat if you want to "call PBRead from inside PBRead". I needed to be able to do this in order to implement a file caching system for the Mac, actually for a Mac implementation of the Andrew File System (AFS), and found it to be impossible with the present Mac file system. Under the AFS, an application would call RBRead to get some file stuff, the AFS would intercept that call (using the external file system mechanism - to be called the foreign file system mechanism in System 7.0), determine if the file was cached locally and if it was, call RBRead AGAIN to actually obtain the file stuff. With the help of clever people in Developer Support at Apple, we managed to concoct a very small program which kinda worked. The trick was to make asynchronous RBRead calls and to call PBRead again in the completion routine. The FSBusy block is released before the completion routine is invoked. This curious program was set up to read one character, then read one more in the completion routine of that read ad nauseam, stack overflow or eof, whichever came first. When run it was quite good at reversing the order of all the characters in a file being read! While fun to build, this has no real utility since it relied on the PBRead calls being asynch and for the mechanism to be generally useful you can't assume all applications do this, in fact most don't. This won't change in System 7.0, but I suggest lobbying for a re-entrant file system/device manager in System 8.0. The Mac file system is due for an overhaul anyway - it doesn't scale up well to very large file systems. An ISO CDROM with a few thousand files on it takes a long time to mount and you should watch my Mac as it struggles to mount a distributed file system that covers the Universities of Michigan, CMU, MIT and Dartmouth, plus a few other sites, as one AppleShare volume! Would you believe 3 minutes on a good day!! --- Gavin Eadie, Associate Director/Software Engineer The University of Michigan Computing Center 535 West William Street, Ann Arbor, Michigan 48109-4943 (313) 936-0816
urlichs@smurf.ira.uka.de (Matthias Urlichs) (11/30/89)
In comp.sys.mac.programmer jb@aries5.UUCP, writes:
< This may seem like a strange question but seeing the discussion on
< multi-tasking, I have a related question.
<
< Is there any reliable way to make the device manager re-entrant.
<
That should be the file manager..?
< In other words if I do a PBRead() to a device driver can that device
< driver synchronously do another PBRead() to another device driver?
<
One simple answer: No. Not even asyncronously.
I assume that you want to do something like what I tried to do a few years
back: the straight-ahead way to partition a disk would of course be to
open a file and then write a "disk driver" which simply does PB{read,write}()
calls on that file.
No such luck. Apart from the obvious (the file manager queue), the file
manager implements its own internal stack for async requests, plus state
variables and (since HFS) two special files which make this even more complex.
My hack of a solution was to allocate the file contiguously (using
AllocContig) and then, after opening the file, calculate its beginning on disk
from the information from GetVolInfo() and from the FCB (_not_ generally
recommended).
You will have to test that the file is still contiguous (if somebody copies
it, it is likely not to be anymore); this is easy because the FCB contains the
first three extents: the last two should be zero. You will also run into the
fact that doing this right (ie. if your driver is called asynchronously; it
may well be) is not easy.
This "solution" (apart from being a hack anyway) only works on local disks
which indicates that there should be a better solution.
<
< Jim Bruyn
I suggest that you post a note describing exactly what you want to do; then
we'll all come up with some better ideas. ;-)
NB: Some rather vague Sytem 7.0 information (reliability level and source
attribution: grapevine) says that the paging file for virtual memory will not
have to be contiguous. I wonder if Apple will do this right (ie. make the
emergency file manager call available for those who need it), or not (ie. hack
it in, using heaps of undocumented file manager features). Based on past
experience I tend to expect the latter. :-(
--
Matthias Urlichs
jb@aries5.uucp (12/01/89)
In article <1258@smurf.ira.uka.de> urlichs@smurf.ira.uka.de (Matthias Urlichs) writes: >In comp.sys.mac.programmer jb@aries5.UUCP, writes: >< This may seem like a strange question but seeing the discussion on >< multi-tasking, I have a related question. >< >< Is there any reliable way to make the device manager re-entrant. >< >That should be the file manager..? > Yes >< In other words if I do a PBRead() to a device driver can that device >< driver synchronously do another PBRead() to another device driver? >< >One simple answer: No. Not even asyncronously. > >I assume that you want to do something like what I tried to do a few years >back: the straight-ahead way to partition a disk would of course be to >open a file and then write a "disk driver" which simply does PB{read,write}() >calls on that file. >No such luck. Apart from the obvious (the file manager queue), the file >manager implements its own internal stack for async requests, plus state >variables and (since HFS) two special files which make this even more complex. Here is what I was trying to do: At the University of Waterloo we have developed a local area network for the Macintosh - MacJANET. This is a disk server, that essentailly partions one or more files on the server (called disk boxes) into volumes. Each user is assigned there own volume, with read/write access. Then there are common read/only volumes, for applications. This way you only need to store one copy of the application on the network. We implemented at the workstation a device driver that sent sector read and write calls for the network disk to the server, and the server would then read from the file that data, and return it to the workstation. Aiming at education, we spent considerable effort on ease of use, particularly in administration of userids etc. This implementation had one problem, it only allowed for one person to have write only access to a network disk, although multiple people could have read access. With the advent of appleshare, we wanted to provide appleshare capbabilities within the same framework. i.e. allow the user to access a network disk as an appleshare volume (where an appleshare disk is a partition in the disk box (file) on the server). The obvious solution (to me at least) was mount that partion of the file, as a volume on the server, and then do file manager calls to that volume (since appleshare calls map very nicely to file manager calls - yes Apple did this right). This means though that I needed a device driver for the disk (file partition) that I mount on the server. This device driver will be called by the file manager, and then subsequently wants to call the real disk driver too actually read from the disk. In other words the problem became how do I write a disk device driver that takes read/write requests and calls the real disk driver - i.e. device manager re-entrancy? This also had one cute side-effect that I never thought of, that if the server is running under multi-finder all the appleshare compatible volumes that I mount multifinder will wish to access also. So in effect I do not have any control over who is calling my device driver. If what I was doing was simpler, the proposed solution of calling the other device driver from the completion routine would work. I have come up with a solution that works but I am interested in hearing if my original idea is feasible and/or suggestions on how it can be done. (By the way, since I enjoy challenges "it can't be done" I don't believe). Jim Bruyn P.S. Information on MacJANET can be obtained from: WATCOM Products 415 Phillip Street Waterloo, Ontario N2L 3X2 (519)-886-3700 MacJANET has other features, like print spooling, tracking number of users running an application, limitting the number of users who can use an application concurrently, etc.