dpvc@ur-tut (Davide P. Cervone) (07/07/88)
In article <11752@agate.BERKELEY.EDU> pete@violet.berkeley.edu (Pete Goodeve) writes: > There's a major problem with child tasks in that their code is normally > loaded as part of the main program, so you don't have much flexibility to > change things at load time or later. On the other hand, if for some > reason you wanted to invoke one module process from inside another, this > is pretty easy: simplest is to use the AmigaDOS call > > Execute("run module") > > (You would have to use "run" so you would come back to your invoking > module immediately.) You might LoadSeg() and CreateProc() instead, but I > don't see much advantage in that. Well, I can think of a couple reasons why LoadSeg() and CreateProc() might be better: First, with Execute(), you never know whether the process actually was created. For instance, suppose the program "module" was not found, or there was insufficient memory, or some such thing. You'd never know, and would go on with your own execution expecting it to be there. You might find out later when you tried to send it messages that it was not registered. Second, how can you tell when the other process is ready to run? You could wait for it to send you a message, but if it was never loaded, you'll hang waiting for a messag ehtat will never come. You could set up time-out conditions, but that's a lot of work for what should be a simple operation. (I must admit that I have not spent the time I should reading the PPIPC and OOIPC discussion, so I don't know whether you have a solution for this kind of problem built into the IPC protocols). Finally, once the code is loaded, you have control of it before you call CreateProc. You can use the pointer to the laoded code to initialize variables, call sections of code, etc., before starting the child process. I use this technique in wIconify and vScreen to reduce the size of the child process. All the library opening, error checking, screen and window lookups, and other one-time-only work is done in the loading program, not the child program. Of course, this means the child program can not be run on its own as a separate command, too. > -- Pete -- Davide P. Cervone dpvc@tut.cc.rochester.edu dpvc@ur-tut.UUCP DPVC@UORDBV.BITNET
pete@violet.berkeley.edu (Pete Goodeve) (07/11/88)
In article <2261@ur-tut.UUCP> dpvc@tut.cc.rochester.edu.UUCP (Davide P. Cervone) writes: > >Well, I can think of a couple reasons why LoadSeg() and CreateProc() might >be better: > >First, with Execute(), you never know whether the process actually was created. >For instance, suppose the program "module" was not found, or there was >insufficient memory, or some such thing. You'd never know, and would go >on with your own execution expecting it to be there. You might find out later >when you tried to send it messages that it was not registered. True, but this is the sort of thing that IPC has to handle as a matter of course. The sender has to expect that an attempt to send a message may fail; it'll be informed of this and will have to take whatever action it thinks necessary. (Actually Execute() DOES return a success code, though I have to confess I'm not sure what'd happen if the RUN command failed -- whether it would fail the execute too, or not.) > >Second, how can you tell when the other process is ready to run? You could >wait for it to send you a message, but if it was never loaded, you'll hang >waiting for a messag ehtat will never come. You could set up time-out >conditions, but that's a lot of work for what should be a simple operation. Same thing, basically. You shouldn't actually care whether a process is running until you want to send it something; you can always 'ping' it if you need to know sooner. > >Finally, once the code is loaded, you have control of it before you call >CreateProc. [........] I hope people won't write modules to run under IPC this way. My feeling is that they should be self contained, to be started up like any other program, without special conditions or considerations. If you want a module to change its run-time state -- send it a message to do so. Closely linked processes and tasks like you're suggesting are fine for lots of things, but the idea of IPC I think is to decouple things so that we can mix and match modules more easily. -- Pete --
peter@sugar.UUCP (Peter da Silva) (07/12/88)
One advantage to launching your own tasks with CreateProcess is that you can run them under a Workbench environment... which is much beter defined than the CLI environment (for example, you don't have to puzzle out structures from the AmigaDOS manual). And everyone writes code so it runs in both, don't they? (sigh... please, folks, write code so it runs in both) -- -- `-_-' Peter (have you hugged your wolf today?) da Silva. -- U Mail to ...!uunet!sugar!peter, flames to alt.dev.null. -- "Running OS/2 on a '386 is like pulling your camper with an Indy car"
keithd@cadovax.UUCP (Keith Doyle) (07/14/88)
In article <11752@agate.BERKELEY.EDU> pete@violet.berkeley.edu (Pete Goodeve) writes: >On the other hand, if for some > reason you wanted to invoke one module process from inside another, this > is pretty easy: simplest is to use the AmigaDOS call > > Execute("run module") > > (You would have to use "run" so you would come back to your invoking > module immediately.) You might LoadSeg() and CreateProc() instead, but I > don't see much advantage in that. Both Execute and LoadSeg()/CreateProc() have big problems because they lead to lots of situations that confuse the hell out of novice users. You have to do a Execute("run name:module",0,0); because Execute("run module",0,0); is equivalent to Execute("run df0:module",0,0); or maybe sys:module or something that bears no resemblance to what you are really trying to do. If you *do* do an Execute("run name:module",0,0); then either the novice can't boot off of *his* vanilla workbench disk because the assign name: doesn't get done, or you have to name the disk "name" and if you do that, the novice who forgets after backing up to edit the "copy of " out of the name, thinks the disk is copy protected because it keeps popping up requesters saying "please insert volume 'name' in any drive". You'd be surprised how many novices I've talked to who did edit "copy of" out of the name, but didn't catch the space between "of" and "name". It looks like it's the correct name, but AmigaDos doesn't treat them the same. If you use LoadSeg, you can specify a file without full path name, relative to the current directory which should be the one the original icon was clicked on. As long as all paths are relative to that directory, no assigning or disk-name assumptions have to be made. The problem with LoadSeg though, is if "module" itself want's to open files relative to the directory it is in, unless you can feed to the new CreateProc()'ed process your current directory, it won't work. I haven't yet checked to see if you can feed a created process it's current directory. I'm thinking the only real way to make this all work with a minimum of pain to the novice user, is for the original program to use successive ParentDir()'s to construct its full path name, build and Execute() an 'Assign here: currentdirpath' command and then have everyone use here: to find associated programs and files. Kludgy, but it works. What I'd like to be able to do (if it worked) is this: 1. boot a vanilla workbench, no custom Assigns in startup-sequence required. 2. put application disk in df1: or df2: or ??(and disk can be named anything) 3. click on drawer icon on application disk to open drawer named "appl" which contains subdirectory "stuff". 4. click on application icon in drawer "appl" 5. application does an Execute("run stuff/subpart",0,0); ^^^^^^ note relative to application's current dir, "appl" 6. "subpart" program does an Open("datafile",...). Where datafile is a relative reference (either to "appl" or "stuff", I could work within either constraint). 7. All of this stuff will still work flawlessly if you copy the entire application disk into a subdirectory on a hard disk. Unfortunately, this won't work as step 5 fails with a nonexistant command error reported on the CLI. This would work if run could find the command in the Executing program's current directory. Makes me wonder if a substitute RUN command could be created that would fix the problem. And you can't do an Execute("run :appl/stuff/subpart",0,0);, as that will violate condition 7. If I use the technique I described above constructing an Assign here: command, and the references in 1-7 above become here:stuff/subpart etc. it will work, and only makes the assumption that the Assign command is available. Kinda hate hardcoding Assign commands in programs, but nothing else seems to work, unless I can feed CreateProc it's current directory somehow. I still end up having to ParentDir it up the tree to find out what the complete current directory path is. If anyone can think of another method of meeting the 1-7 criteria above, I'd be glad to hear it. BTW, this also touches on a reason I have a big problem using anybodies *.library for anything useful, as novices don't have the foggiest notion on how to install them. An auto-install program has the problem that the vanilla workbench is too full, requiring something to be deleted. Keith Doyle # {ucbvax,decvax}!trwrb!cadovax!keithd Contel Business Systems 213-323-8170
peter@sugar.UUCP (Peter da Silva) (07/15/88)
In article <2148@cadovax.UUCP>, keithd@cadovax.UUCP writes: > The problem with LoadSeg though, is if "module" itself want's to open files > relative to the directory it is in, unless you can feed to the new > CreateProc()'ed process your current directory, it won't work. I haven't > yet checked to see if you can feed a created process it's current directory. If you send the created process a standard workbench startup message, it will get its current directory from there (assuming it's been set up right). This means you have to hang around until the process dies (see my "click" sample program, published in comp.sources.amiga, or I can send you a copy). There is a way around this, though: write a daemon that just opens up a named port (say, "WBCleanup"), and cleans up WBStartup messages sent to this port (there is enough info in (struct WBStartup) to do this... again, see "click"). Supply this port as the reply port of the WBStartup message. The daemon will happily gobble the messages up and leave you free to exit. You *do* need to be able to run the daemon, but it doesn't have to have any standard startup code, since it never exits. So you just look for your named port. If it's not there, LoadSeg and CreateProc the daemon and sleep a little. Then look for the port again. > If anyone can think of another method of meeting the 1-7 criteria > above, I'd be glad to hear it. See above. > BTW, this also touches on a reason I have a big problem using anybodies > *.library for anything useful, as novices don't have the foggiest notion on > how to install them. An auto-install program has the problem that the > vanilla workbench is too full, requiring something to be deleted. It'd be nice if you could specify a complete path to OpenLibrary. Can you? -- -- `-_-' Peter (have you hugged your wolf today?) da Silva. -- U Mail to ...!uunet!sugar!peter, flames to alt.dev.null. -- "Running OS/2 on a '386 is like pulling your camper with an Indy car"