all c function implemented, without test. fix warning
[PxpRpc.git] / c / pxprpc / server.c
blob3f2e642ed30902e906b6b3c5846c29b39dd99830
3 #include "def.h"
4 #include "config.h"
5 #include <stdint.h>
6 #include <string.h>
7 #include <stdlib.h>
8 #include <memory.h>
10 #include "server.h"
12 #ifdef USE_PTHREAD_HEADER
13 #include <pthread.h>
14 #endif
16 #define MACRO_TO_STR(x) #x
17 #define MACRO_TO_STR2(s) MACRO_TO_STR(s)
20 static const char *ServerInfo="server name:pxprpc for c\n"
21 "version:1.0\n"
22 "reference slots size:" MACRO_TO_STR2(MAX_REFSLOTS_COUNT)"\n";
24 static uint32_t _pxprpc__ref_AddRef(struct pxprpc_object *ref){
25 ref->count++;
26 return ref->count;
29 static uint32_t _pxprpc__ref_Release(struct pxprpc_object *ref){
30 ref->count--;
31 if(ref->count==0){
32 pxprpc__free(ref);
33 return 0;
34 }else{
35 return ref->count;
39 static uint32_t _pxprpc__ref_bytes_Release(struct pxprpc_object *ref){
40 void *bytes=ref->object1;
41 if(_pxprpc__ref_Release(ref)==0){
42 pxprpc__free(bytes);
48 struct _pxprpc__ServCo{
49 void (*next)(struct _pxprpc__ServCo *self);
50 union{
51 struct{
52 uint32_t session;
53 uint32_t addr1;
54 union{
55 uint32_t addr2;
56 uint32_t length1;
58 } hdr;
59 uint8_t hdrbuf[16];
61 struct pxprpc_abstract_io *io1;
62 struct pxprpc_object **refSlots;
63 int slotMaxHashOffset;
64 int slotsSize;
65 struct pxprpc_object *t1;
66 pthread_mutex_t writeMutex;
67 int lengthOfNamedFuncs;
68 struct pxprpc_namedfunc *namedfuncs;
69 uint32_t status;
72 #define _pxprpc__ServCoIsClosed(self) self->status&0x1
74 static void _pxprpc__step1(struct _pxprpc__ServCo *self);
76 static void _pxprpc__ServCoStart(struct _pxprpc__ServCo *self){
77 self->slotsSize=MAX_REFSLOTS_COUNT;
78 self->refSlots=pxprpc__malloc(sizeof(struct pxprpc_object)*MAX_REFSLOTS_COUNT);
79 memset(self->refSlots,0,sizeof(struct pxprpc_object)*MAX_REFSLOTS_COUNT);
80 pthread_mutex_init(&self->writeMutex,NULL);
81 self->status=0;
84 static void _pxprpc__RefSlotsPut(struct _pxprpc__ServCo *self,uint32_t addr, struct pxprpc_object *ref2){
85 struct pxprpc_object *ref=self->refSlots[addr];
86 if(ref!=NULL){
87 ref->release(ref);
89 if(ref2!=NULL){
90 ref2->addRef(ref2);
92 self->refSlots[addr]=ref2;
96 //Push handler
97 static void _pxprpc__stepPush3(struct _pxprpc__ServCo *self){
98 _pxprpc__RefSlotsPut(self,self->hdr.addr1,self->t1);
99 pthread_mutex_lock(&self->writeMutex);
100 self->io1->write(self->io1,4,(uint8_t *)&self->hdr.session);
101 pthread_mutex_unlock(&self->writeMutex);
103 _pxprpc__step1(self);
105 static void _pxprpc__stepPush2(struct _pxprpc__ServCo *self){
106 self->t1=pxprpc_new_bytes_object(self->hdr.length1);
108 self->io1->read(self->io1,self->hdr.length1,((struct pxprpc_bytes *)self->t1->object1)->data,
109 (void (*)(void *))&_pxprpc__stepPush3,self);
111 static void _pxprpc__stepPush1(struct _pxprpc__ServCo *self){
112 self->io1->read(self->io1,8,(uint8_t*)&self->hdr.addr1,(void (*)(void *))&_pxprpc__stepPush2,self);
115 //Pull handler
116 static void _pxprpc__stepPull2(struct _pxprpc__ServCo *self){
117 int destAddr=self->hdr.addr1;
119 struct pxprpc_bytes *bytes=self->refSlots[destAddr]->object1;
121 pthread_mutex_lock(&self->writeMutex);
122 self->io1->write(self->io1,4,(uint8_t *)&self->hdr.session);
123 self->io1->write(self->io1,4,(uint8_t *)&bytes->length);
124 self->io1->write(self->io1,bytes->length,bytes->data);
125 pthread_mutex_unlock(&self->writeMutex);
127 _pxprpc__step1(self);
129 static void _pxprpc__stepPull1(struct _pxprpc__ServCo *self){
130 self->io1->read(self->io1,4,(uint8_t*)&self->hdr.addr1,(void (*)(void *))&_pxprpc__stepPull2,self);
133 //Assign handler
134 static void _pxprpc__stepAssign2(struct _pxprpc__ServCo *self){
135 _pxprpc__RefSlotsPut(self,self->hdr.addr1,self->refSlots[self->hdr.addr2]);
136 pthread_mutex_lock(&self->writeMutex);
137 self->io1->write(self->io1,4,(uint8_t *)&self->hdr.session);
138 pthread_mutex_unlock(&self->writeMutex);
140 _pxprpc__step1(self);
142 static void _pxprpc__stepAssign1(struct _pxprpc__ServCo *self){
143 self->io1->read(self->io1,8,(uint8_t*)&self->hdr.addr1,(void (*)(void *))&_pxprpc__stepAssign2,self);
147 //Unlink handler
148 static void _pxprpc__stepUnlink2(struct _pxprpc__ServCo *self){
149 _pxprpc__RefSlotsPut(self,self->hdr.addr1,NULL);
150 pthread_mutex_lock(&self->writeMutex);
151 self->io1->write(self->io1,4,(uint8_t *)&self->hdr.session);
152 pthread_mutex_unlock(&self->writeMutex);
154 _pxprpc__step1(self);
156 static void _pxprpc__stepUnlink1(struct _pxprpc__ServCo *self){
157 self->io1->read(self->io1,4,(uint8_t*)&self->hdr.addr1,(void (*)(void *))&_pxprpc__stepUnlink2,self);
161 //Call handler
162 static void _pxprpc__stepCall4(struct pxprpc_request *r, struct pxprpc_object *result){
163 _pxprpc__RefSlotsPut(r->server_context_data,r->dest_addr,result);
164 r->result=result;
165 struct _pxprpc__ServCo *self=r->server_context_data;
166 pthread_mutex_lock(&self->writeMutex);
167 self->io1->write(self->io1,4,(uint8_t *)&self->hdr.session);
168 r->callable->writeResult(r->callable,r);
169 pthread_mutex_unlock(&self->writeMutex);
170 pxprpc__free(r);
173 static void _pxprpc__stepCall3(struct pxprpc_request *r){
174 r->callable->call(r->callable,r,&_pxprpc__stepCall4);
175 struct _pxprpc__ServCo *self=r->server_context_data;
176 _pxprpc__step1(self);
178 static void _pxprpc__stepCall2(struct _pxprpc__ServCo *self){
179 struct pxprpc_request *req=pxprpc__malloc(sizeof(struct pxprpc_request));
180 req->session=self->hdr.session;
181 req->io1=self->io1;
182 req->ref_slots=self->refSlots;
183 req->dest_addr=self->hdr.addr1;
184 req->server_context_data=self;
185 struct pxprpc_callable *func=(struct pxprpc_callable *)((struct pxprpc_object *)self->refSlots[self->hdr.addr2])->object1;
186 func->readParameter(func,req,&_pxprpc__stepCall3);
188 static void _pxprpc__stepCall1(struct _pxprpc__ServCo *self){
189 self->io1->read(self->io1,8,(uint8_t*)&self->hdr.addr1,(void (*)(void *))&_pxprpc__stepCall2,self);
193 //GetFunc handler
194 static void _pxprpc__stepGetFunc2(struct _pxprpc__ServCo *self){
195 struct pxprpc_bytes *bs=self->refSlots[self->hdr.addr2]->object1;
196 //Avoid buffer overflow
197 if(bs->data[bs->length-1]!=0){
198 bs->data[bs->length-1]=0;
200 for(int i=0;i<self->lengthOfNamedFuncs;i++){
201 if(strcmp(self->namedfuncs[i].name,bs->data)){
202 _pxprpc__RefSlotsPut(self,self->hdr.addr1,
203 pxprpc_new_object(self->namedfuncs->callable));
205 break;
207 pthread_mutex_lock(&self->writeMutex);
208 self->io1->write(self->io1,4,(uint8_t *)&self->hdr.session);
209 pthread_mutex_unlock(&self->writeMutex);
211 _pxprpc__step1(self);
213 static void _pxprpc__stepGetFunc1(struct _pxprpc__ServCo *self){
214 self->io1->read(self->io1,8,(uint8_t*)&self->hdr.addr1,(void(*)(void *))&_pxprpc__stepGetFunc2,self);
218 //Close handler
219 static void _pxprpc__stepClose1(struct _pxprpc__ServCo *self){
220 pxprpc_close(self);
225 //GetInfo handler
226 static void _pxprpc__stepGetInfo1(struct _pxprpc__ServCo *self){
227 pthread_mutex_lock(&self->writeMutex);
228 uint32_t length=strlen(ServerInfo);
229 self->io1->write(self->io1,4,(uint8_t *)&length);
230 self->io1->write(self->io1,length,ServerInfo);
231 pthread_mutex_unlock(&self->writeMutex);
236 static void _pxprpc__step1(struct _pxprpc__ServCo *self){
237 if(_pxprpc__ServCoIsClosed(self)){
238 return;
240 int opcode=self->hdrbuf[0];
241 switch(opcode){
242 case 1:
243 _pxprpc__stepPush1(self);
244 break;
245 case 2:
246 _pxprpc__stepPull1(self);
247 break;
248 case 3:
249 _pxprpc__stepAssign1(self);
250 break;
251 case 4:
252 _pxprpc__stepUnlink1(self);
253 break;
254 case 5:
255 _pxprpc__stepCall1(self);
256 break;
257 case 6:
258 _pxprpc__stepGetFunc1(self);
259 break;
260 case 7:
261 pxprpc_close(self);
262 break;
263 case 8:
264 _pxprpc__stepGetInfo1(self);
265 break;
270 extern void pxprpc_close(void *server_context){
271 struct _pxprpc__ServCo *self=server_context;
272 for(int i=0;i<MAX_REFSLOTS_COUNT;i++){
273 if(self->refSlots[i]!=NULL){
274 self->refSlots[i]->release(self->refSlots[i]);
277 self->status|=0x1;
281 extern struct pxprpc_object *pxprpc_new_object(void *obj){
282 struct pxprpc_object *ref=pxprpc__malloc(sizeof(struct pxprpc_object));
283 ref->addRef=&_pxprpc__ref_AddRef;
284 ref->release=&_pxprpc__ref_Release;
285 ref->count=0;
286 ref->object1=obj;
287 ref->size_of_struct=sizeof(struct pxprpc_object);
288 return ref;
291 extern struct pxprpc_object *pxprpc_new_bytes_object(uint32_t size){
292 struct pxprpc_object *ref=pxprpc_new_object(pxprpc__malloc(size+4));
293 *((int *)(ref->object1))=size;
294 ref->release=_pxprpc__ref_bytes_Release;
295 return ref;