Commit of the code which was suggested by Georg as a fix for:
[cake.git] / rom / exec / replymsg.c
blob37750b168d694ea1c91b461429c519507422fcaa
1 /*
2 Copyright © 1995-2001, The AROS Development Team. All rights reserved.
3 $Id$
5 Desc: Reply a message
6 Lang: english
7 */
8 #include "exec_intern.h"
9 #include <aros/libcall.h>
10 #include <exec/ports.h>
11 #include <proto/exec.h>
13 /*****************************************************************************
15 NAME */
17 AROS_LH1(void, ReplyMsg,
19 /* SYNOPSIS */
20 AROS_LHA(struct Message *, message, A1),
22 /* LOCATION */
23 struct ExecBase *, SysBase, 63, Exec)
25 /* FUNCTION
26 Send a message back to where it came from. It's generally not
27 wise to access the fields of a message after it has been replied.
29 INPUTS
30 message - a message got with GetMsg().
32 RESULT
34 NOTES
36 EXAMPLE
38 BUGS
40 SEE ALSO
41 WaitPort(), GetMsg(), PutMsg()
43 INTERNALS
45 ******************************************************************************/
47 AROS_LIBFUNC_INIT
49 struct MsgPort *port;
51 /* handle FASTCALL before doing locking or anything else. yes, there's a
52 * potential race here if some task was to change mn_ReplyPort before/as
53 * we read it. thats why we fetch it again further down, after Disable().
54 * all bets are of when using FASTCALL */
55 port = message->mn_ReplyPort;
57 if (port != NULL && port->mp_Flags & PA_FASTCALL)
59 if (port->mp_SoftInt == NULL || ((struct Interrupt *) port->mp_SoftInt)->is_Code == NULL)
60 return;
62 ASSERT_VALID_PTR(port->mp_SoftInt);
63 ASSERT_VALID_PTR(((struct Interrupt *) port->mp_SoftInt)->is_Code);
65 message->mn_Node.ln_Type = NT_REPLYMSG;
67 /* call the "interrupt" with the message as an argument */
68 AROS_UFC4(void, ((struct Interrupt *) port->mp_SoftInt)->is_Code,
69 AROS_UFCA(APTR, ((struct Interrupt *) port->mp_SoftInt)->is_Data, A1),
70 AROS_UFCA(ULONG_FUNC, ((struct Interrupt *) port->mp_SoftInt)->is_Code, A5),
71 AROS_UFCA(struct Message *, message, D0),
72 AROS_UFCA(struct ExecBase *, SysBase, A6));
74 return;
77 /* Protect the message against access by other tasks. */
78 Disable();
80 /* Get replyport */
81 port=message->mn_ReplyPort;
83 /* Not set? Only mark the message as no longer sent. */
84 if(port==NULL)
85 message->mn_Node.ln_Type=NT_FREEMSG;
86 else
88 /* Mark the message as replied */
89 message->mn_Node.ln_Type=NT_REPLYMSG;
91 /* Add it to the replyport's list */
92 AddTail(&port->mp_MsgList,&message->mn_Node);
94 if(port->mp_SigTask)
96 /* And trigger the arrival action. */
97 switch(port->mp_Flags&PF_ACTION)
99 case PA_SIGNAL:
100 /* Send a signal */
101 Signal((struct Task *)port->mp_SigTask,1<<port->mp_SigBit);
102 break;
104 case PA_SOFTINT:
105 /* Raise a software interrupt */
106 Cause((struct Interrupt *)port->mp_SoftInt);
107 break;
109 case PA_IGNORE:
110 /* Do nothing */
111 break;
113 case PA_CALL:
114 /* Call the function in mp_SigTask. */
115 AROS_UFC2(void, port->mp_SigTask,
116 AROS_UFCA(struct MsgPort *, port, D0),
117 AROS_UFCA(struct ExecBase *, SysBase, A6));
118 break;
123 /* All done */
124 Enable();
125 AROS_LIBFUNC_EXIT
126 } /* ReplyMsg() */