Path: utzoo!utgpu!news-server.csri.toronto.edu!rpi!usc!cs.utexas.edu!uunet!fernwood!portal!cup.portal.com!phorgan From: phorgan@cup.portal.com (Patrick John Horgan) Newsgroups: comp.sys.amiga.programmer Subject: Re: Message Ports Message-ID: <43040@cup.portal.com> Date: 7 Jun 91 04:24:03 GMT References: <22192@cbmvax.commodore.com> Organization: The Portal System (TM) Lines: 313 In article bart@asgard.pub.uu.oz.au (John Butche r) writes: >Ive been trying to do message ports, but I havent had lots of success, my port s >wont get properly recognized by name. Below small test program I wrote : Here I have an assembler version of a Create/Delete Port pair that fix the problem at the "system" level. The Create gets it's own memory for the string, and Delete frees it up. . It's pretty generic Manx assembler, but it'll need some cludging for other assemblers I'm sure. It's even simpler to do this in C. First is a neccessary include file: stktypes.i ~~~~~~~~~~~~cut here~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ;:ts=8 IFND EXEC_ST_TYPES_I EXEC_ST_TYPES_I SET 1 ST_STRUCTURE MACRO \1 EQU 0 SOFFSET SET \2 ENDM ST_FRAME MACRO \1 EQU 0 SOFFSET SET \2 ENDM ST_BOOL MACRO SOFFSET SET SOFFSET-2 \1 EQU SOFFSET ENDM ST_BYTE MACRO SOFFSET SET SOFFSET-1 \1 EQU SOFFSET ENDM ST_UBYTE MACRO SOFFSET SET SOFFSET-1 \1 EQU SOFFSET ENDM ST_WORD MACRO SOFFSET SET SOFFSET-2 \1 EQU SOFFSET ENDM ST_UWORD MACRO SOFFSET SET SOFFSET-2 \1 EQU SOFFSET ENDM ST_SHORT MACRO SOFFSET SET SOFFSET-2 \1 EQU SOFFSET ENDM ST_USHORT MACRO SOFFSET SET SOFFSET-2 \1 EQU SOFFSET ENDM ST_LONG MACRO SOFFSET SET SOFFSET-4 \1 EQU SOFFSET ENDM ST_ULONG MACRO SOFFSET SET SOFFSET-4 \1 EQU SOFFSET ENDM ST_FLOAT MACRO SOFFSET SET SOFFSET-4 \1 EQU SOFFSET ENDM ST_APTR MACRO SOFFSET SET SOFFSET-4 \1 EQU SOFFSET ENDM ST_CPTR MACRO SOFFSET SET SOFFSET-4 \1 EQU SOFFSET ENDM ST_RPTR MACRO SOFFSET SET SOFFSET-2 \1 EQU SOFFSET ENDM ST_STRUCT MACRO SOFFSET SET SOFFSET-\2 \1 EQU SOFFSET ENDM ST_LABEL MACRO \1 EQU SOFFSET ENDM ENDC EXEC_ST_TYPES_I ~~~~~~~~~~~cut here~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Now the code follows: ~~~~~~~~~~~cut here~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ;:ts=8 *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * CreatePort(char *name, long pri) * * Patrick J. Horgan pjh70@zeus.ras.amdahl.com * * Creates an Amiga MsgPort. This is a reentrant program. The usual * amiga.lib CreatePort doesn't allocate memory for the name of the * port. A consequence of this is that routines that call CreatePort * many times will, at best, have all the ports named the same * as the last one made. The worst case would be if the string * passed for the name was an automatic variable, in which case it * would contain garbage when the stack was reclaimed! * *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ *CreatePort(name, pri) *DeletePort(mp) *register struct MsgPort *mp; NOLIST include 'exec/types.i' include 'stktypes.i' include 'exec/nodes.i' include 'exec/lists.i' include 'exec/memory.i' include 'exec/ports.i' include 'exec/libraries.i' LIST * A useful macro call MACRO CALLLIB _LVO\1 ENDM * Our external references... EXTERN_LIB AddPort EXTERN_LIB AllocMem EXTERN_LIB AllocSignal EXTERN_LIB FindTask EXTERN_LIB FreeMem EXTERN_LIB FreeSignal EXTERN_LIB RemPort ST_FRAME myframe,0 ST_APTR ST_MP ST_LABEL myfrsize *CreatePort(name, pri) * Here's what's on the stack after my initial link. STRUCTURE ARGS,0 ULONG olda5 Contents of a5 before link. APTR retaddr Where we will rts to. APTR name The name of the new port. ULONG priority The priority of the new port. LABEL ARGS_SIZE * Make me visable public _CreatePort far code * And away we go... _CreatePort: link a5,#myfrsize Set up space for the stk-frame. movem.l a2-a3/a6/d3,-(sp) Save registers we trash. move.l 4,a6 move.l #MEMF_PUBLIC+MEMF_CLEAR,d1 We need mem like dis! move.l #MP_SIZE,d0 And it's dis size. call AllocMem Get it. tst.l d0 Did we get it? beq err3 Abort... move.l d0,ST_MP(a5) Save the pointer... movea.l d0,a3 and get a work copy. tst.l name(a5) Is there a name? bne donm Yep...do the name. clr.l LN_NAME(a3) No name. bra nonm Skip the name jazz. * There's a name, so count the chars for the AllocMem. donm clr.l d0 This is our string length counter. move.l name(a5),a1 a1 points at the name. * Set up's done, countem. countem addq.l #1,d0 Count the chars move.b (a1)+,d1 Get the char. bne.s countem If not EOS keep goin'. addq #4,d0 Get memory for the length. move.l d0,d3 Save a copy. * Now allocate that much memory. move.l #MEMF_PUBLIC!MEMF_CLEAR,d1 Dese are da requirements. call AllocMem Get the mem. tst.l d0 Did we get it? beq err2 Nah, go free resources. add.l #4,d0 Skip the length. move.l ST_MP(a5),a3 ReBase the port. move.l d0,LN_NAME(a3) Stash the name. movea.l d0,a0 Base the new string mem. move.l d3,-4(a0) Save the length. movea.l name(a5),a3 Point at the passed name. * We're set up for the copyin' so copy it. copyem move.b (a3)+,(a0)+ Copy from da ol' to da new. bne.s copyem Copy to EOS. nonm move.l ST_MP(a5),a3 Base the new MsgPort in a3. clr.l LN_SUCC(a3) Clear the node links. clr.l LN_PRED(a3) move.b priority+3(a5),LN_PRI(a3) set the node priority. clr.l d0 Get a zero move.b d0,MP_FLAGS(a3) Clear the flags. movea.l d0,a1 a1 is arg for FindTask(0). call FindTask Who are we? move.l d0,MP_SIGTASK(a3) This is who gets the messages. move.l #-1,d0 We don't care which signal. call AllocSignal Get a signal. tst.l d0 bmi err1 Oops no signal, free resources * and abort. move.b d0,MP_SIGBIT(a3) Here's our sigbit. move.l a3,a1 Put the pointer to the port in call AddPort a1 as argument for AddPort. move.l a3,d0 Here's our return value. exit movem.l (sp)+,a2-a3/a6/d3 Restore registers we trash. unlk a5 Set up space for the stk-frame. rts * Free the Memory for the Name... err1 move.l ST_MP(a5),a3 move.l LN_NAME(a3),a1 Point at the name. suba.l #4,a1 Back up to the size. move.l (a1),d0 Got the size. call FreeMem * Free the Memory for the MsgPort... err2 move.l ST_MP(a5),a1 We Free dis move.l #MP_SIZE,d0 and it's dis size. call FreeMem * Return zero for failure. err3 clr.l d0 Return null for failure. bra exit *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * DeletePort(MsgPort *dp_port) * * Patrick J. Horgan pjh70@zeus.ras.amdahl.com * *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ STRUCTURE DP_ARGS,0 ULONG savea3 We stash a3. APTR retadr Where we will rts to. APTR dp_port The port we will delete. LABEL DP_ARGS_SIZE public _DeletePort _DeletePort move.l a3,-(a7) movea.l dp_port(a7),a3 Point at the port. * Remove the port from system lists. movea.l a3,a1 Point at the port. call RemPort * Free the signal. clr.l d0 or.b MP_SIGBIT(a3),d0 Here's our sigbit. call FreeSignal * Free the name... tst.l LN_NAME(a3) Is there a name? beq dp_nonm move.l LN_NAME(a3),a1 Point at the name. suba.l #4,a1 Back up to the size. move.l (a1),d0 Got the size. call FreeMem * Free the Memory for the MsgPort... dp_nonm movea.l a3,a1 Point at the port. move.l #MP_SIZE,d0 and it's dis size. call FreeMem move.l (a7)+,a3 dt_exit rts end