Path: utzoo!utgpu!jarvis.csri.toronto.edu!mailrus!csd4.milw.wisc.edu!lll-winken!uunet!mcvax!kth!draken!tut!router!fintuvm.bitnet!lk-kari From: LK-KARI@FINTUVM.BITNET (Kari Sutela) Newsgroups: comp.sys.amiga.tech Subject: CreateTask() problems... Message-ID: <740LK-KARI@FINTUVM> Date: 12 Apr 89 14:35:17 GMT Organization: University of Turku, Finland Lines: 119 Sorry, this is a bit long. For most part of the week now, I have been seriously confused about creating a new task. I have looked on other peoples' source and I can understand them just fine but they are not quite what I need to do. I have managed to locate source code for tasks that end before their parent, only. BUT I need to create a task that *outlives* its parent and I haven't managed to do this in a reliable manner. What I need to do is start a task which will initialize a public message port and waits for messages to arrive there. The task should remove itself when a special 'kill yourself' message appears in its message port. The code goes something like this: (Please note, due to EBCDIC-ASCII translation, square and curly brackets might appear as some other characters, so the code might look a bit strange) /* GLOBALS */ struct RxsLib *RexxSysBase; struct IntuitionBase *IntuitionBase; /* The task needs these libraries */ char PORTNAME#$ "MyPublicPort"; extern void the_task(); void main() { struct Task *MyTask; OpenLibraries(); /* And other initializations */ MyTask = CreateTask( "MyTask", 0L, the_task, 4000L ); /* Hope I got the parameters right */ if( mytask == NULL ) error( "Couldn't create the task" ); /* error() will release resources, too */ return; } void the_task() { struct MsgPort *MyPort; struct Message *mymsg; BOOL quit; geta4(); /* For Manx small code memory model */ MyPort = CreatePort( PORTNAME ); /* Perhaps some other parameters as well*/ if( MyPort == NULL ) cleanup(); /* Perhaps I remember the semantics of CreatePort() incorrectly, did it * return the signal bit? Any way, I'm typing this from memory */ /* Make it public */ AddPort( MyPort ); /* Now wait */ for(;;) { WaitPort( MyPort ); mymsg = GetMsg( MyPort ); if( quit = handle_msg( mymsg ) ) { ExhaustPort( MyPort ); RemPort( MyPort ); /* Not public anymore */ DeletePort( MyPort ); /* delete it entirely */ cleanup(); } } } BOOL handle_msg( msg ) struct Message *msg; { /* Handles the message - returns true if it was 'kill yourself' */ } void ExhaustPort( port ) struct MsgPort *port; { /* replies to all pending messages */ } void cleanup() { CloseLibs(); RemTask( 0L ); } /* End of example */ I am using Aztec C, if it makes any difference. I seem to be able to launch the new task allright, but the message port won't open properly most of the time. What especially confuses me is that, if I run the program through SDB, I'll get a proper message port with the name I wanted. And most of the time my tests indicate that the messages are correctly handled. But if I invoke the command straight from the command line, a message port will open but its name is garbage. This is really confusing, why should a program behave differently if it's being debugged (have I created a monster program that's aware of monitoring :-)??? BTW, has anyone found a way to use SDB on tasks? BTW, if I leave out the task creation and just 'run' the program (or use Manx's detach.o) everything works absolutely fine. But these methods create a process and this program doesn't actually need it - I'd really like to make it a task. Any hints on this? Have I completely misunderstood the semantics of CreateTask and task behaviour in general? Am I mistaken in assuming that a task can use resources opened by its parent (even after the parent has died) and close the resources when it exits? The Exec manual isn't too clear on this. - Kari Sutela - lk-kari@fintuvm.utu.fi (internet) OR lk-kari@fintuvm.bitnet (bitnet)