picture.datatype: gi_RastPort should not be directly accessed
[AROS.git] / rom / exec / putmsg.c
blob7f4d0f09f17b321b7e78c953adadb2e919e62e79
1 /*
2 Copyright © 1995-2011, The AROS Development Team. All rights reserved.
3 $Id$
5 Desc: Send a message to a port.
6 Lang: english
7 */
9 #include <aros/debug.h>
10 #include <aros/libcall.h>
11 #include <exec/ports.h>
12 #include <proto/exec.h>
14 #include "exec_intern.h"
15 #include "exec_util.h"
17 /*****************************************************************************
19 NAME */
21 AROS_LH2(void, PutMsg,
23 /* SYNOPSIS */
24 AROS_LHA(struct MsgPort *, port, A0),
25 AROS_LHA(struct Message *, message, A1),
27 /* LOCATION */
28 struct ExecBase *, SysBase, 61, Exec)
30 /* FUNCTION
31 Sends a message to a given message port. Messages are not copied
32 from one task to another but must lie in shared memory instead.
33 Therefore the owner of the message may generally not reuse it before
34 it is returned. But this depends on the two tasks sharing the message.
36 INPUTS
37 port - Pointer to messageport.
38 message - Pointer to message.
40 RESULT
42 NOTES
43 It is legal to send a message from within interrupts.
45 Messages may either trigger a signal at the owner of the messageport
46 or raise a software interrupt, depending on port->mp_Flags&PF_ACTION.
48 EXAMPLE
50 BUGS
52 SEE ALSO
53 WaitPort(), GetMsg()
55 INTERNALS
57 ******************************************************************************/
59 AROS_LIBFUNC_INIT
60 ASSERT_VALID_PTR(message);
61 ASSERT_VALID_PTR(port);
63 /* FASTCALL is a special case that operates without the message list
64 * locked, so we have to check it before anything */
65 if (port->mp_Flags & PA_FASTCALL)
67 FastPutMsg(port, message, SysBase);
68 return;
72 Messages may be sent from interrupts. Therefore the message list
73 of the message port must be protected with Disable().
75 Disable();
77 /* Set the node type to NT_MESSAGE == sent message. */
78 message->mn_Node.ln_Type=NT_MESSAGE;
80 InternalPutMsg(port, message, SysBase);
82 /* All done. */
83 Enable();
84 AROS_LIBFUNC_EXIT
85 } /* PutMsg() */
87 void FastPutMsg(struct MsgPort *port, struct Message *message, struct ExecBase *SysBase)
89 if (port->mp_SoftInt == NULL || ((struct Interrupt *) port->mp_SoftInt)->is_Code == NULL)
90 return;
92 ASSERT_VALID_PTR(port->mp_SoftInt);
93 ASSERT_VALID_PTR(((struct Interrupt *) port->mp_SoftInt)->is_Code);
95 /* call the "interrupt" with the message as an argument */
96 AROS_UFC4NR(void, ((struct Interrupt *) port->mp_SoftInt)->is_Code,
97 AROS_UFCA(APTR, ((struct Interrupt *) port->mp_SoftInt)->is_Data, A1),
98 AROS_UFCA(ULONG_FUNC, (ULONG_FUNC)((struct Interrupt *) port->mp_SoftInt)->is_Code, A5),
99 AROS_UFCA(struct Message *, message, D0),
100 AROS_UFCA(struct ExecBase *, SysBase, A6));
103 void InternalPutMsg(struct MsgPort *port, struct Message *message, struct ExecBase *SysBase)
105 /* Add it to the message list. */
106 AddTail(&port->mp_MsgList,&message->mn_Node);
108 if (port->mp_SigTask)
110 ASSERT_VALID_PTR(port->mp_SigTask);
112 /* And trigger the action. */
113 switch(port->mp_Flags & PF_ACTION)
115 case PA_SIGNAL:
116 /* Send the signal */
117 Signal((struct Task *)port->mp_SigTask,1<<port->mp_SigBit);
118 break;
120 case PA_SOFTINT:
121 D(bug("PutMsg: PA_SOFTINT, port 0x%p, msg 0x%p, int %s\n", port, message, ((struct Interrupt *)port->mp_SoftInt)->is_Node.ln_Name));
123 /* Raise a software interrupt */
124 Cause((struct Interrupt *)port->mp_SoftInt);
125 break;
127 case PA_IGNORE:
128 /* Do nothing. */
129 break;
131 case PA_CALL:
132 /* Call the function in mp_SigTask. */
133 AROS_UFC2NR(void, port->mp_SigTask,
134 AROS_UFCA(struct MsgPort *, port, D0),
135 AROS_UFCA(struct ExecBase *, SysBase, A6));
136 break;