revert between 56095 -> 55830 in arch
[AROS.git] / rom / oop / unused / serverclass.c
blob22ad6288090ef600d29e49a8f2cc63225bf42202
1 /*
2 Copyright © 1995-2011, The AROS Development Team. All rights reserved.
3 $Id$
5 Desc: Class for server objects.
6 Lang: english
7 */
9 #include <proto/exec.h>
10 #include <exec/lists.h>
11 #include <exec/memory.h>
12 #include <proto/oop.h>
13 #include <oop/oop.h>
14 #include <oop/server.h>
15 #include <oop/proxy.h>
16 #include <string.h>
18 #include "intern.h"
20 #undef DEBUG
21 #define DEBUG 0
22 #include <aros/debug.h>
24 /* The server class, allows you to make objects public,
25 obtain proxy objects for them from other processes.
26 Method calls on the proxies will be transferred
27 to the server using IPC, and will then be executed
28 on the proxied object. This means method invocation
29 will be threadsafe.
33 /* Instance data */
34 struct ServerData
36 /* List of public objects */
37 struct List ObjectList;
39 /* The MsgPort from which the server receives invocation requests */
40 struct MsgPort *ReceivePort;
42 /* The public object list needs protection */
43 struct SignalSemaphore ObjectListLock;
47 /* structure for making a list of objects */
48 struct ServerObjectNode
50 struct Node so_Node;
51 OOP_Object *so_Object;
55 #define OOPBase ((struct Library *)cl->UserData)
57 static OOP_Object *_Root_New(OOP_Class *cl, OOP_Object *o, struct pRoot_New *msg)
59 EnterFunc(bug("Server::New(cl=%s, o=%p, msg=%p)\n",
60 cl->ClassNode.ln_Name, o, msg));
62 D(bug("DoSuperMethod: %p\n", cl->DoSuperMethod));
63 o = (OOP_Object *)OOP_DoSuperMethod(cl, o, (OOP_Msg)msg);
64 D(bug("got obj\n"));
66 if (o)
68 struct ServerData *data;
69 ULONG disp_mid;
70 D(bug("getting instdata\n"));
72 data = OOP_INST_DATA(cl, o);
73 D(bug("got instdata\n"));
75 disp_mid = OOP_GetMethodID(IID_Root, moRoot_Dispose);
76 D(bug("got dispmid\n"));
77 /* Clear so we can test what resources are allocated in Dispose() */
78 D(bug("Object created, o=%p, data=%p\n", o, data));
79 memset(data, 0, sizeof (struct ServerData));
81 D(bug("Object instdata cleared\n"));
82 NEWLIST(&data->ObjectList);
83 InitSemaphore(&data->ObjectListLock);
85 /* Set up port for receiving incoming invocation requests */
86 D(bug("Creating receive msgport\n"));
88 data->ReceivePort = CreateMsgPort();
89 if (data->ReceivePort)
92 ReturnPtr("Server::New", OOP_Object *, o);
94 OOP_CoerceMethod(cl, o, (OOP_Msg)&disp_mid);
97 ReturnPtr ("Server::New", OOP_Object *, NULL);
100 static VOID _Root_Dispose(OOP_Class *cl, OOP_Object *o, OOP_Msg msg)
102 struct Node *node, *nextnode;
103 struct ServerData *data = OOP_INST_DATA(cl, o);
105 EnterFunc(bug("Server::Dispose()\n"));
107 node = data->ObjectList.lh_Head;
109 /* Free all nodes in the list */
110 while ((nextnode = node->ln_Succ))
112 Remove(node);
113 FreeVec(node->ln_Name);
114 FreeMem(node, sizeof (struct ServerObjectNode));
116 node = nextnode;
119 /* Free the invocation request port */
120 if(data->ReceivePort)
121 DeleteMsgPort(data->ReceivePort);
123 ReturnVoid("Server::Dispose");
127 /*****************************
128 ** IServer implementation **
129 *****************************/
131 /* Add an object to the list of public objects. */
133 static BOOL _Server_AddObject(OOP_Class *cl, OOP_Object *o, struct P_Server_AddObject *msg)
135 struct ServerData *data = OOP_INST_DATA(cl, o);
137 struct ServerObjectNode *so;
139 EnterFunc(bug("Server::AddObject(obj=%p, id=%s)\n", msg->Object, msg->ObjectID));
141 /* Allocate list node */
142 so = AllocMem(sizeof (struct ServerObjectNode), MEMF_ANY);
143 if (so)
145 /* Copy the object ID */
146 so->so_Node.ln_Name = AllocVec(strlen(msg->ObjectID) + 1, MEMF_ANY);
147 if (so->so_Node.ln_Name)
149 strcpy(so->so_Node.ln_Name, msg->ObjectID);
150 so->so_Object = msg->Object;
152 /* Add it to the list */
153 ObtainSemaphore(&data->ObjectListLock);
154 AddTail(&data->ObjectList, (struct Node *)so);
155 ReleaseSemaphore(&data->ObjectListLock);
157 ReturnBool ("Server::AddObject", TRUE);
159 FreeMem(so, sizeof (struct ServerObjectNode));
161 ReturnBool ("Server::AddObject", FALSE);
164 /* Remove a previosly added object */
165 static VOID _Server_RemoveObject(OOP_Class *cl, OOP_Object *o, struct P_Server_RemoveObject *msg)
167 struct ServerData *data = OOP_INST_DATA(cl, o);
169 struct ServerObjectNode *so;
171 EnterFunc(bug("Server::RemoveObject(objid=%s)\n", msg->ObjectID));
173 ObtainSemaphore(&data->ObjectListLock);
175 /* Find the object */
176 so = (struct ServerObjectNode *)FindName(&data->ObjectList, msg->ObjectID);
177 if (so)
179 /* ..and remove it */
180 Remove((struct Node *)so);
181 FreeVec(so->so_Node.ln_Name);
182 FreeMem(so, sizeof (struct ServerObjectNode) );
184 ReleaseSemaphore(&data->ObjectListLock);
186 ReturnVoid("Server::RemoveObject");
189 /* Find a public object */
190 static OOP_Object * _Server_FindObject(OOP_Class *cl, OOP_Object *o, struct P_Server_FindObject *msg)
192 struct ServerObjectNode *so;
193 struct ServerData *data = OOP_INST_DATA(cl, o);
195 EnterFunc(bug("Server::FindObject(objid=%s)\n", msg->ObjectID));
197 /* See if the server knows about the object */
198 ObtainSemaphoreShared(&data->ObjectListLock);
199 /* Search for object */
200 so = (struct ServerObjectNode *)FindName(&data->ObjectList, msg->ObjectID);
201 ReleaseSemaphore(&data->ObjectListLock);
203 if (so)
205 /* If found, create a proxy for the object */
206 struct TagItem proxy_tags[] =
208 {aProxy_RealObject, (IPTR)so->so_Object},
209 {aProxy_Port, (IPTR)data->ReceivePort},
210 {TAG_DONE, 0UL}
213 OOP_Object *proxy;
215 proxy = OOP_NewObject(NULL, CLID_Proxy, proxy_tags);
216 if (proxy)
218 ReturnPtr("Server::FindObject", OOP_Object *, proxy);
222 ReturnPtr("Server::FindObject", OOP_Object *, NULL);
224 /* Let the server wait forevere, executing and replying
225 answering to all incoming method invocation requests
227 static VOID _Server_Run(OOP_Class *cl, OOP_Object *o, OOP_Msg msg)
229 struct ServerData *data = OOP_INST_DATA(cl, o);
231 for (;;)
233 struct ProxyMsg *pm;
234 /* Wait for incoming invocation request */
235 WaitPort(data->ReceivePort);
237 while ( (pm = (struct ProxyMsg *)GetMsg(data->ReceivePort)) )
239 /* Execute method */
240 pm->pm_RetVal = OOP_DoMethod(pm->pm_Object, pm->pm_ObjMsg);
242 /* Reply back to task invoking */
243 ReplyMsg((struct Message *)pm);
248 return;
251 #undef OOPBase
253 OOP_Class *init_serverclass(struct Library *OOPBase)
256 struct OOP_MethodDescr root_methods[] =
258 {(IPTR (*)())_Root_New, moRoot_New},
259 {(IPTR (*)())_Root_Dispose, moRoot_Dispose},
260 { NULL, 0UL }
263 struct OOP_MethodDescr server_methods[] =
265 {(IPTR (*)())_Server_AddObject, moServer_AddObject},
266 {(IPTR (*)())_Server_RemoveObject, moServer_RemoveObject},
267 {(IPTR (*)())_Server_FindObject, moServer_FindObject},
268 {(IPTR (*)())_Server_Run, moServer_Run},
269 { NULL, 0UL }
272 struct OOP_InterfaceDescr ifdescr[] =
274 { root_methods, IID_Root, 2},
275 { server_methods, IID_Server, 4},
276 { NULL, 0UL, 0UL}
279 struct TagItem tags[] =
281 {aMeta_SuperID, (IPTR)CLID_Root},
282 {aMeta_InterfaceDescr, (IPTR)ifdescr},
283 {aMeta_ID, (IPTR)CLID_Server},
284 {aMeta_InstSize, (IPTR)sizeof (struct ServerData)},
285 {TAG_DONE, 0UL}
289 OOP_Class *cl;
291 EnterFunc(bug("InitServerClass()\n"));
293 cl = (OOP_Class *)OOP_NewObject(NULL, CLID_MIMeta, tags);
294 if (cl)
296 cl->UserData = OOPBase;
297 OOP_AddClass(cl);
300 ReturnPtr ("InitServerClass", OOP_Class *, cl);