Path: utzoo!utgpu!jarvis.csri.toronto.edu!mailrus!purdue!decwrl!ucbvax!POSTGRES.BERKELEY.EDU!dillon From: dillon@POSTGRES.BERKELEY.EDU (Matt Dillon) Newsgroups: comp.sys.amiga.tech Subject: Re: Ultimate Wait-GetMsg strategy (?) Message-ID: <8902100658.AA16049@postgres.Berkeley.EDU> Date: 10 Feb 89 06:58:49 GMT Sender: daemon@ucbvax.BERKELEY.EDU Lines: 85 :Every time using a Wait-GetMsg-pair I thought how to do it :best way. Now I think I got it: : :while (1) { : while (!(imsg= GetMsg(win->UserPort))) : Wait (1<UserPort->mp_SigBit); : ... select imsg->Class and break when ended ... : :} : :I think that should ship around all "oddities" like multiple :Messages arriving or NULL-msges arriving?! : :Any comments? : :Markus Yes, that's probably the worse way to do it. Well, not the worse, but it's not the best coding style I've seen (you asked for comments!). Use something like this if you are handling only a single source of events (i.e. one window's IDCMP): Note that since all messages are processed before the next Wait(), you can safely do the Wait(). while (notquit) { Wait(1 << win->UserPort->mp_SigBit); while (mess = GetMsg(win->UserPort)) { /* process message */ ReplyMsg(mess); } } On the otherhand, if you are waiting for multiple events, the logical extension works as well. Again, the assumption is that you handle *everything* related to the signal bits in question before going back to the Wait(). while (notquit) { mask = Wait(mask1 | mask2 | mask3); if (mask & mask1) { /* say this is for your intuition window */ register struct IntuiMessage *mess; while (mess = GetMsg(win->UserPort)) { /* process all messages */ ReplyMsg(mess); } } if (mask & mask2) { /* etc... */ } if (mask & mask3) { /* etc... */ } } The above works fine in the worst case: (1) A message comes in while we are in the GetMsg() loop, causing a (harmless) spurious signal, and (2) A message comes in just after we exit the GetMsg() loop but before the Wait(), in which case we still get a signal. Also, note that the construction of the code fragment allows you to easily declare very-local variables within each if() block ... a much more modular coding practice as well as helpful to the compiler's code generation. An example of INCORRECT code: while (notquit) { /* INCORRECT CODE */ Wait(1 << win->UserPort->mp_SigBit); msg = GetMsg(win->UserPort); /* process */ ReplyMsg(msg); } Will NOT work because it is possible to get into two crash situations. (1) Several messages get queued to you quickly (before Wait() can clear the signal bit), then Wait() clears the signal bit, you process just one of the messages and go back to the Wait() ... the Wait() locks up the computer until the next message comes in even though there is already one left on the port. (2) You get a spurious signal and GetMsg() returns NULL (no messages on the port). You must always check that GetMsg() returns a non-null message pointer. In the examples of correct code, I have a while (mess = GetMsg...) and thus the while() takes care of this check. -Matt