revert between 56095 -> 55830 in arch
[AROS.git] / rom / oop / unused / proxyclass.c
blobc0458e1c1c256aac3d2698f9fb792fd2a05fef87
1 /*
2 Copyright © 1995-2001, The AROS Development Team. All rights reserved.
3 $Id$
5 Desc: Class for proxy objects.
6 Lang: english
7 */
9 #include <proto/exec.h>
10 #include <exec/memory.h>
11 #include <proto/oop.h>
12 #include <proto/utility.h>
13 #include <oop/oop.h>
14 #include <oop/proxy.h>
15 #include <oop/server.h>
17 #include <string.h>
19 #include "intern.h"
21 #undef DEBUG
22 #undef SDEBUG
23 #define SDEBUG 0
24 #define DEBUG 0
25 #include <aros/debug.h>
27 #define OOPBase (GetOBase(((OOP_Class *)cl)->UserData))
29 /* This proxyclass is used to create a proxy object for
30 another object owned by another process. You can then call
31 methods on the object through the proxy, using IPC.
32 This makes methodcalls threadsafe.
34 Note the API of this class sucks (It's not OS-independent).
35 This implementation is mainly there to show that the idea works.
39 struct ProxyData
41 /* The object this is a proxy for */
42 OOP_Object *RealObject;
44 /* Server's Msgport to which we send requests */
45 struct MsgPort *ServerPort;
47 /* The server replies to this port */
48 struct MsgPort *ReplyPort;
50 /* Mem used for passing the message */
51 struct ProxyMsg *Message;
55 /************
56 ** New() **
57 ************/
58 static OOP_Object *_Root_New(OOP_Class *cl, OOP_Object *o, struct pRoot_New *msg)
60 /* Get the attributes */
61 OOP_Object *realobject;
62 struct MsgPort *serverport;
64 EnterFunc(bug("Proxy::New()\n"));
66 /* Pares params */
68 /* Object from other process which we create a proxy for */
69 realobject = (OOP_Object *)GetTagData(aProxy_RealObject, NULL, msg->attrList);
71 /* MsgPort to pass method invocation throgh.
72 Note that one could very well use a socket or a pipe to pass
73 the methods
76 serverport = (struct MsgPort *)GetTagData(aProxy_Port, NULL, msg->attrList);
78 /* Those two params MUST be supplied */
79 if ( !(realobject && serverport) )
80 return (NULL);
82 o = (OOP_Object *)OOP_DoSuperMethod(cl, o, (OOP_Msg)msg);
83 if (o)
85 struct ProxyData *data;
86 ULONG disp_mid = OOP_GetMethodID(IID_Root, moRoot_Dispose);
88 data = (struct ProxyData *)OOP_INST_DATA(cl, o);
90 /* Clear the instance data */
91 memset(data, 0, sizeof (struct ProxyData));
93 /* This is ugly, as we will soon run out of sigbits */
94 data->ReplyPort = CreateMsgPort();
95 if (data->ReplyPort)
97 /* Allocate MEMF_PUBLIC message struct */
98 data->Message = AllocMem(sizeof (struct ProxyMsg), MEMF_PUBLIC);
99 if (data->Message)
101 struct ProxyMsg *pm = data->Message;
103 /* Save the instance data */
104 data->RealObject = realobject;
105 data->ServerPort = serverport;
107 /* Preinitialize some fields in the message struct */
108 pm->pm_Message.mn_Length = sizeof (struct ProxyMsg);
109 pm->pm_Message.mn_ReplyPort = data->ReplyPort;
110 pm->pm_Object = realobject;
112 ReturnPtr("Proxy::New", OOP_Object *, o);
115 DeleteMsgPort(data->ReplyPort);
119 OOP_CoerceMethod(cl, o, (OOP_Msg)&disp_mid);
122 ReturnPtr("Proxy::New", OOP_Object *, NULL);
125 /****************
126 ** Dispose() **
127 ****************/
128 static VOID _Root_Dispose(OOP_Class *cl, OOP_Object *o, OOP_Msg msg)
130 struct ProxyData *data = OOP_INST_DATA(cl, o);
132 /* Delete the replyport.. */
133 if (data->ReplyPort)
134 DeleteMsgPort(data->ReplyPort);
136 /* .. the message struct.. */
137 if (data->Message)
138 FreeMem(data->Message, sizeof (struct ProxyMsg));
140 /* .. and the object itself. */
141 OOP_DoSuperMethod(cl, o, msg);
143 ReturnVoid("Proxy::Dispose");
146 #undef OOPBase
147 #define OOPBase ((struct Library *)(OOP_OCLASS(o)->UserData))
149 /*****************
150 ** DoMethod() **
151 *****************/
152 /* The proxy has a custom DoMethod() call that
153 handles passing the method on to the server's MsgPort.
156 static IPTR _Proxy_DoMethod(OOP_Object *o, OOP_Msg msg)
158 struct ProxyData *data = OOP_INST_DATA(OOP_OCLASS(o), o);
160 EnterFunc(bug("Proxy_DoMethod()\n"));
162 /* Pass a pointer to the message */
163 data->Message->pm_ObjMsg = msg;
165 /* Send to server */
166 PutMsg(data->ServerPort, (struct Message *)data->Message);
168 /* Wait for server to reply. Note that this is prone to deadlocks,
169 and that this must be fixed. (For example the task calling
170 the remote obj through the proxy, is also server.
171 And the server receiving the call tries to call *us*.
173 WaitPort(data->ReplyPort);
175 /* Get the reply, so we can reuse the memory to send new requests.
177 GetMsg(data->ReplyPort);
179 ReturnInt("Proxy_DoMethod", IPTR, data->Message->pm_RetVal);
183 #undef OOPBase
185 OOP_Class *init_proxyclass(struct Library *OOPBase)
188 struct OOP_MethodDescr root_methods[] =
190 {(IPTR (*)())_Root_New, moRoot_New},
191 {(IPTR (*)())_Root_Dispose, moRoot_Dispose},
192 { NULL, 0UL }
196 struct OOP_InterfaceDescr ifdescr[] =
198 { root_methods, IID_Root, 2},
199 { NULL, 0UL, 0UL}
202 struct TagItem tags[] =
204 {aMeta_SuperID, (IPTR)CLID_Root},
205 {aMeta_InterfaceDescr, (IPTR)ifdescr},
206 {aMeta_ID, (IPTR)CLID_Proxy},
207 {aMeta_InstSize, (IPTR)sizeof (struct ProxyData) },
208 {aMeta_DoMethod, (IPTR)_Proxy_DoMethod},
209 {TAG_DONE, 0UL}
213 OOP_Class *cl;
215 EnterFunc(bug("InitProxyClass()\n"));
217 cl = (OOP_Class *)OOP_NewObject(NULL, CLID_MIMeta, tags);
218 if (cl)
220 cl->UserData = OOPBase;
221 OOP_AddClass(cl);
224 ReturnPtr ("InitProxyClass", OOP_Class *, cl);