12 #ifdef USE_PTHREAD_HEADER
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"
22 "reference slots size:" MACRO_TO_STR2(MAX_REFSLOTS_COUNT
)"\n";
26 static uint32_t _pxprpc__ref_AddRef(struct pxprpc_object
*ref
){
31 static uint32_t _pxprpc__ref_Release(struct pxprpc_object
*ref
){
41 static uint32_t _pxprpc__ref_bytes_Release(struct pxprpc_object
*ref
){
42 void *bytes
=ref
->object1
;
46 return _pxprpc__ref_Release(ref
);
49 static struct pxprpc_object
*pxprpc_new_object(void *obj
){
50 struct pxprpc_object
*ref
=pxprpc__malloc(sizeof(struct pxprpc_object
));
51 ref
->addRef
=&_pxprpc__ref_AddRef
;
52 ref
->release
=&_pxprpc__ref_Release
;
58 static struct pxprpc_object
*pxprpc_new_bytes_object(uint32_t size
){
59 struct pxprpc_object
*ref
=pxprpc_new_object(pxprpc__malloc(size
+4));
61 *((int *)(ref
->object1
))=size
;
62 ref
->release
=_pxprpc__ref_bytes_Release
;
66 static void pxprpc_fill_bytes_object(struct pxprpc_object
*obj
,uint8_t *data
,int size
){
67 struct pxprpc_bytes
* bytes
=(struct pxprpc_bytes
*)obj
->object1
;
68 if(size
>bytes
->length
){
71 memcpy(&bytes
->data
,data
,size
);
74 struct _pxprpc__ServCo
{
88 struct pxprpc_abstract_io
*io1
;
89 struct pxprpc_object
**refSlots
;
90 int slotMaxHashOffset
;
92 struct pxprpc_object
*t1
;
93 pthread_mutex_t writeMutex
;
94 int lengthOfNamedFuncs
;
95 struct pxprpc_namedfunc
*namedfuncs
;
100 #define _pxprpc__ServCoIsClosed(self) self->status&0x1
102 static int pxprpc_closed(void *server_context
){
103 return _pxprpc__ServCoIsClosed(((struct _pxprpc__ServCo
*)server_context
));
106 static int pxprpc_close(pxprpc_server_context server_context
){
107 if(pxprpc_closed(server_context
)){
110 struct _pxprpc__ServCo
*self
=server_context
;
111 for(int i
=0;i
<MAX_REFSLOTS_COUNT
;i
++){
112 if(self
->refSlots
[i
]!=NULL
){
113 self
->refSlots
[i
]->release(self
->refSlots
[i
]);
117 pxprpc__free(self
->refSlots
);
122 static void _pxprpc__step1(struct _pxprpc__ServCo
*self
);
124 static void _pxprpc__ServCoStart(struct _pxprpc__ServCo
*self
){
125 self
->slotsSize
=MAX_REFSLOTS_COUNT
;
126 self
->refSlots
=pxprpc__malloc(sizeof(struct pxprpc_object
)*MAX_REFSLOTS_COUNT
);
127 memset(self
->refSlots
,0,sizeof(struct pxprpc_object
)*MAX_REFSLOTS_COUNT
);
128 pthread_mutex_init(&self
->writeMutex
,NULL
);
130 _pxprpc__step1(self
);
133 static void _pxprpc__RefSlotsPut(struct _pxprpc__ServCo
*self
,uint32_t addr
, struct pxprpc_object
*ref2
){
134 struct pxprpc_object
*ref
=self
->refSlots
[addr
];
141 self
->refSlots
[addr
]=ref2
;
144 static void _pxprpc__nopcallback(void *p
){}
147 static void _pxprpc__stepPush3(struct _pxprpc__ServCo
*self
){
148 if(self
->io1
->get_error(self
->io1
,self
->io1
->read
)!=NULL
)return;
149 _pxprpc__RefSlotsPut(self
,self
->hdr
.addr1
,self
->t1
);
150 pthread_mutex_lock(&self
->writeMutex
);
151 self
->io1
->write(self
->io1
,4,(uint8_t *)&self
->hdr
.session
,(void (*)(void *))_pxprpc__step1
,self
);
152 pthread_mutex_unlock(&self
->writeMutex
);
154 static void _pxprpc__stepPush2(struct _pxprpc__ServCo
*self
){
155 if(self
->io1
->get_error(self
->io1
,self
->io1
->read
)!=NULL
)return;
156 self
->t1
=pxprpc_new_bytes_object(self
->hdr
.length1
);
158 self
->io1
->read(self
->io1
,self
->hdr
.length1
,((struct pxprpc_bytes
*)self
->t1
->object1
)->data
,
159 (void (*)(void *))&_pxprpc__stepPush3
,self
);
161 static void _pxprpc__stepPush1(struct _pxprpc__ServCo
*self
){
162 self
->io1
->read(self
->io1
,8,(uint8_t*)&self
->hdr
.addr1
,(void (*)(void *))&_pxprpc__stepPush2
,self
);
166 static void _pxprpc__stepPull2(struct _pxprpc__ServCo
*self
){
167 if(self
->io1
->get_error(self
->io1
,self
->io1
->read
)!=NULL
)return;
168 int destAddr
=self
->hdr
.addr1
;
170 struct pxprpc_bytes
*bytes
=self
->refSlots
[destAddr
]->object1
;
172 pthread_mutex_lock(&self
->writeMutex
);
173 self
->io1
->write(self
->io1
,4,(uint8_t *)&self
->hdr
.session
,_pxprpc__nopcallback
,NULL
);
175 self
->io1
->write(self
->io1
,4,(uint8_t *)&bytes
->length
,_pxprpc__nopcallback
,NULL
);
176 self
->io1
->write(self
->io1
,bytes
->length
,bytes
->data
,(void (*)(void *))_pxprpc__step1
,self
);
178 *(uint32_t *)(&self
->writeBuf
)=0xffffffff;
179 self
->io1
->write(self
->io1
,4,self
->writeBuf
,(void (*)(void *))_pxprpc__step1
,self
);
181 pthread_mutex_unlock(&self
->writeMutex
);
183 static void _pxprpc__stepPull1(struct _pxprpc__ServCo
*self
){
184 self
->io1
->read(self
->io1
,4,(uint8_t*)&self
->hdr
.addr1
,(void (*)(void *))&_pxprpc__stepPull2
,self
);
188 static void _pxprpc__stepAssign2(struct _pxprpc__ServCo
*self
){
189 if(self
->io1
->get_error(self
->io1
,self
->io1
->read
)!=NULL
)return;
190 _pxprpc__RefSlotsPut(self
,self
->hdr
.addr1
,self
->refSlots
[self
->hdr
.addr2
]);
191 pthread_mutex_lock(&self
->writeMutex
);
192 self
->io1
->write(self
->io1
,4,(uint8_t *)&self
->hdr
.session
,(void (*)(void *))_pxprpc__step1
,self
);
193 pthread_mutex_unlock(&self
->writeMutex
);
195 static void _pxprpc__stepAssign1(struct _pxprpc__ServCo
*self
){
196 self
->io1
->read(self
->io1
,8,(uint8_t*)&self
->hdr
.addr1
,(void (*)(void *))&_pxprpc__stepAssign2
,self
);
201 static void _pxprpc__stepUnlink2(struct _pxprpc__ServCo
*self
){
202 if(self
->io1
->get_error(self
->io1
,self
->io1
->read
)!=NULL
)return;
203 _pxprpc__RefSlotsPut(self
,self
->hdr
.addr1
,NULL
);
204 pthread_mutex_lock(&self
->writeMutex
);
205 self
->io1
->write(self
->io1
,4,(uint8_t *)&self
->hdr
.session
,(void (*)(void *))_pxprpc__step1
,self
);
206 pthread_mutex_unlock(&self
->writeMutex
);
208 static void _pxprpc__stepUnlink1(struct _pxprpc__ServCo
*self
){
209 self
->io1
->read(self
->io1
,4,(uint8_t*)&self
->hdr
.addr1
,(void (*)(void *))&_pxprpc__stepUnlink2
,self
);
213 static void _pxprpc__stepCall4(struct pxprpc_request
*r
, struct pxprpc_object
*result
){
214 struct _pxprpc__ServCo
*self
=r
->server_context
;
215 _pxprpc__RefSlotsPut(r
->server_context
,r
->dest_addr
,result
);
217 pthread_mutex_lock(&self
->writeMutex
);
218 self
->io1
->write(self
->io1
,4,(uint8_t *)&r
->session
,_pxprpc__nopcallback
,NULL
);
219 r
->callable
->writeResult(r
->callable
,r
);
220 pthread_mutex_unlock(&self
->writeMutex
);
224 static void _pxprpc__stepCall3(struct pxprpc_request
*r
){
225 struct _pxprpc__ServCo
*self
=(struct _pxprpc__ServCo
*)r
->server_context
;
226 r
->callable
->call(r
->callable
,r
,&_pxprpc__stepCall4
);
227 _pxprpc__step1(self
);
229 static void _pxprpc__stepCall2(struct _pxprpc__ServCo
*self
){
230 if(self
->io1
->get_error(self
->io1
,self
->io1
->read
)!=NULL
)return;
231 struct pxprpc_request
*req
=(struct pxprpc_request
*)pxprpc__malloc(sizeof(struct pxprpc_request
));
232 req
->session
=self
->hdr
.session
;
234 req
->ref_slots
=self
->refSlots
;
235 req
->dest_addr
=self
->hdr
.addr1
;
236 req
->server_context
=self
;
237 struct pxprpc_callable
*func
=(struct pxprpc_callable
*)((struct pxprpc_object
*)self
->refSlots
[self
->hdr
.addr2
])->object1
;
239 func
->readParameter(func
,req
,&_pxprpc__stepCall3
);
241 static void _pxprpc__stepCall1(struct _pxprpc__ServCo
*self
){
242 self
->io1
->read(self
->io1
,8,(uint8_t*)&self
->hdr
.addr1
,(void (*)(void *))&_pxprpc__stepCall2
,self
);
245 //str1(2)Len = -1 indicate 0-ending string, In this case the real length will be put into *str1(2)Len after function return.
246 //string length is limited to 0x1000
247 static int _pxprpc__strcmp2(const char *str1
,int *str1Len
,const char *str2
,int *str2Len
){
250 for(i
=0;i
<0x1000;i
++){
258 for(i
=0;i
<0x1000;i
++){
265 if(*str1Len
==*str2Len
){
266 for(i
=0,r
=0;i
<*str1Len
;i
++){
267 if(str1
[i
]!=str2
[i
]){
278 static void _pxprpc__stepGetFunc2(struct _pxprpc__ServCo
*self
){
279 if(self
->io1
->get_error(self
->io1
,self
->io1
->read
)!=NULL
)return;
280 struct pxprpc_bytes
*bs
=(struct pxprpc_bytes
*)self
->refSlots
[self
->hdr
.addr2
]->object1
;
283 for(int i
=0;i
<self
->lengthOfNamedFuncs
;i
++){
285 int cmp1
=_pxprpc__strcmp2(self
->namedfuncs
[i
].name
,&lenOut
,(const char *)bs
->data
,&bs
->length
);
287 _pxprpc__RefSlotsPut(self
,self
->hdr
.addr1
,pxprpc_new_object(self
->namedfuncs
[i
].callable
));
288 returnAddr
=self
->hdr
.addr1
;
292 pthread_mutex_lock(&self
->writeMutex
);
293 *(uint32_t *)(&self
->writeBuf
)=returnAddr
;
294 self
->io1
->write(self
->io1
,4,(uint8_t *)&self
->hdr
.session
,_pxprpc__nopcallback
,NULL
);
295 self
->io1
->write(self
->io1
,4,self
->writeBuf
,(void (*)(void *))_pxprpc__step1
,self
);
296 pthread_mutex_unlock(&self
->writeMutex
);
298 static void _pxprpc__stepGetFunc1(struct _pxprpc__ServCo
*self
){
299 self
->io1
->read(self
->io1
,8,(uint8_t*)&self
->hdr
.addr1
,(void(*)(void *))&_pxprpc__stepGetFunc2
,self
);
304 static int _pxprpc__stepClose1(struct _pxprpc__ServCo
*self
){
311 static void _pxprpc__stepGetInfo1(struct _pxprpc__ServCo
*self
){
312 pthread_mutex_lock(&self
->writeMutex
);
313 uint32_t length
=strlen(ServerInfo
);
314 self
->io1
->write(self
->io1
,4,(uint8_t *)&self
->hdr
.session
,_pxprpc__nopcallback
,NULL
);
315 *(uint32_t *)(&self
->writeBuf
)=length
;
316 self
->io1
->write(self
->io1
,4,(uint8_t *)&length
,_pxprpc__nopcallback
,NULL
);
317 self
->io1
->write(self
->io1
,length
,ServerInfo
,(void (*)(void *))_pxprpc__step1
,self
);
318 pthread_mutex_unlock(&self
->writeMutex
);
322 static void _pxprpc__step2(struct _pxprpc__ServCo
*self
){
323 if(self
->io1
->get_error(self
->io1
,self
->io1
->read
)!=NULL
)return;
324 int opcode
=self
->hdrbuf
[0];
327 _pxprpc__stepPush1(self
);
330 _pxprpc__stepPull1(self
);
333 _pxprpc__stepAssign1(self
);
336 _pxprpc__stepUnlink1(self
);
339 _pxprpc__stepCall1(self
);
342 _pxprpc__stepGetFunc1(self
);
348 _pxprpc__stepGetInfo1(self
);
353 static void _pxprpc__step1(struct _pxprpc__ServCo
*self
){
354 if(_pxprpc__ServCoIsClosed(self
)){
357 self
->io1
->read(self
->io1
,4,self
->hdrbuf
,(void(*)(void *))_pxprpc__step2
,self
);
362 static int pxprpc_new_server_context(pxprpc_server_context
*server_context
,struct pxprpc_abstract_io
*io1
,struct pxprpc_namedfunc
*namedfuncs
,int len_namedfuncs
){
363 struct _pxprpc__ServCo
*ctx
=(struct _pxprpc__ServCo
*)pxprpc__malloc(sizeof(struct _pxprpc__ServCo
));
364 memset(ctx
,0,sizeof(struct _pxprpc__ServCo
));
366 ctx
->namedfuncs
=namedfuncs
;
367 ctx
->lengthOfNamedFuncs
=len_namedfuncs
;
372 static int pxprpc_start_serve(pxprpc_server_context server_context
){
373 struct _pxprpc__ServCo
*ctx
=(struct _pxprpc__ServCo
*)server_context
;
374 _pxprpc__ServCoStart(ctx
);
378 static int pxprpc_free_context(pxprpc_server_context
*server_context
){
379 struct _pxprpc__ServCo
*ctx
=(struct _pxprpc__ServCo
*)*server_context
;
381 pxprpc__free(*server_context
);
386 static pxprpc_server_api exports
={
387 &pxprpc_new_server_context
,&pxprpc_start_serve
,&pxprpc_closed
,&pxprpc_close
,&pxprpc_free_context
,
388 &pxprpc_new_object
,&pxprpc_new_bytes_object
,&pxprpc_fill_bytes_object
391 extern int pxprpc_server_query_interface(pxprpc_server_api
**outapi
){