Path: utzoo!mnetor!uunet!seismo!sundc!pitstop!sun!decwrl!labrea!agate!ucbvax!CORY.BERKELEY.EDU!dillon From: dillon@CORY.BERKELEY.EDU (Matt Dillon) Newsgroups: comp.sys.amiga Subject: PutMsg and the ln_Type field Message-ID: <8803260947.AA25241@cory.Berkeley.EDU> Date: 26 Mar 88 09:47:07 GMT Sender: daemon@ucbvax.BERKELEY.EDU Lines: 50 I seem to remember somebody commenting that PutMsg() did not always set the ln_Type field in the message to NT_MESSAGE... I looked at the ROM code. The very first thing PutMsg does is: move.b #5,8(A1) Which places NT_MESSAGE on the ln_Type field of the message. Therefore, PutMsg() *always* does this. This means you can write an equivalent for WaitIO() for messages, since ReplyMsg() will modify the ln_Type to NT_REPLYMSG (NT_FREEMSG if there is not replyport). This example works for PA_SIGNAL replyports only. Note that I check the type first. If the type is NT_MESSAGE, than the message has not been replied yet and thus we can use Wait() since we are guarenteed a signal. The Forbid()/Permit() pair is needed for the routine to work properly with tasks which use exception handlers (so the Wait signal is not prematurely removed in the condition loop). The Disable()/Enable() pair is needed for the routine to work in tandem with interrupts (an interrupt decides to send a message to that particular port). In my dealings with signals, I've always thought they should reflect a certain amount of real information. thus, I restore the signal if messages still exist on the port so the rest of the program doesn't have to check the port first before going into its master Wait() loop. WaitMsg(msg) MSG *msg; { register PORT *port = msg->mn_ReplyPort; register long mask = 1 << port->mp_SigBit; Forbid(); while (msg->mn_Node.ln_Type == NT_MESSAGE) Wait(mask); Permit(); Disable(); Remove(msg); Enable(); if (port->mp_MsgList.lh_Head != (NODE *)&port->mp_MsgList.lh_Tail) SetSignal(mask, mask); } This is something one would probably want to do in assembly. -Matt