11 #ifdef USE_PTHREAD_HEADER
15 #define MACRO_TO_STR(x) #x
16 #define MACRO_TO_STR2(s) MACRO_TO_STR(s)
19 static const char *ServerInfo
="server name:pxprpc for c\n"
21 "reference slots size:" MACRO_TO_STR2(MAX_REFSLOTS_COUNT
)"\n";
25 static uint32_t _pxprpc__ref_AddRef(struct pxprpc_object
*ref
){
30 static uint32_t _pxprpc__ref_Release(struct pxprpc_object
*ref
){
40 static uint32_t _pxprpc__ref_bytes_Release(struct pxprpc_object
*ref
){
41 void *bytes
=ref
->object1
;
45 return _pxprpc__ref_Release(ref
);
48 static struct pxprpc_object
*pxprpc_new_object(void *obj
){
49 struct pxprpc_object
*ref
=pxprpc__malloc(sizeof(struct pxprpc_object
));
50 ref
->addRef
=&_pxprpc__ref_AddRef
;
51 ref
->release
=&_pxprpc__ref_Release
;
57 static struct pxprpc_object
*pxprpc_new_bytes_object(uint32_t size
){
58 struct pxprpc_object
*ref
=pxprpc_new_object(pxprpc__malloc(size
+4));
60 *((int *)(ref
->object1
))=size
;
61 ref
->release
=_pxprpc__ref_bytes_Release
;
65 static void pxprpc_fill_bytes_object(struct pxprpc_object
*obj
,uint8_t *data
,int size
){
66 struct pxprpc_bytes
* bytes
=(struct pxprpc_bytes
*)obj
->object1
;
67 if(size
>bytes
->length
){
70 memcpy(&bytes
->data
,data
,size
);
73 struct _pxprpc__ServCo
{
87 struct pxprpc_abstract_io
*io1
;
88 struct pxprpc_object
**refSlots
;
89 int slotMaxHashOffset
;
91 struct pxprpc_object
*t1
;
92 pthread_mutex_t writeMutex
;
93 int lengthOfNamedFuncs
;
94 struct pxprpc_namedfunc
*namedfuncs
;
99 #define _pxprpc__ServCoIsClosed(self) self->status&0x1
101 static int pxprpc_closed(void *server_context
){
102 return _pxprpc__ServCoIsClosed(((struct _pxprpc__ServCo
*)server_context
));
105 static int pxprpc_close(pxprpc_server_context server_context
){
106 if(pxprpc_closed(server_context
)){
109 struct _pxprpc__ServCo
*self
=server_context
;
110 for(int i
=0;i
<MAX_REFSLOTS_COUNT
;i
++){
111 if(self
->refSlots
[i
]!=NULL
){
112 self
->refSlots
[i
]->release(self
->refSlots
[i
]);
116 pxprpc__free(self
->refSlots
);
121 static void _pxprpc__step1(struct _pxprpc__ServCo
*self
);
123 static void _pxprpc__ServCoStart(struct _pxprpc__ServCo
*self
){
124 self
->slotsSize
=MAX_REFSLOTS_COUNT
;
125 self
->refSlots
=pxprpc__malloc(sizeof(struct pxprpc_object
)*MAX_REFSLOTS_COUNT
);
126 memset(self
->refSlots
,0,sizeof(struct pxprpc_object
)*MAX_REFSLOTS_COUNT
);
127 pthread_mutex_init(&self
->writeMutex
,NULL
);
129 _pxprpc__step1(self
);
132 static void _pxprpc__RefSlotsPut(struct _pxprpc__ServCo
*self
,uint32_t addr
, struct pxprpc_object
*ref2
){
133 struct pxprpc_object
*ref
=self
->refSlots
[addr
];
140 self
->refSlots
[addr
]=ref2
;
143 static void _pxprpc__nopcallback(void *p
){}
146 static void _pxprpc__stepPush3(struct _pxprpc__ServCo
*self
){
147 if(self
->io1
->get_error(self
->io1
,self
->io1
->read
)!=NULL
)return;
148 _pxprpc__RefSlotsPut(self
,self
->hdr
.addr1
,self
->t1
);
149 pthread_mutex_lock(&self
->writeMutex
);
150 self
->io1
->write(self
->io1
,4,(uint8_t *)&self
->hdr
.session
,(void (*)(void *))_pxprpc__step1
,self
);
151 pthread_mutex_unlock(&self
->writeMutex
);
153 static void _pxprpc__stepPush2(struct _pxprpc__ServCo
*self
){
154 if(self
->io1
->get_error(self
->io1
,self
->io1
->read
)!=NULL
)return;
155 self
->t1
=pxprpc_new_bytes_object(self
->hdr
.length1
);
157 self
->io1
->read(self
->io1
,self
->hdr
.length1
,((struct pxprpc_bytes
*)self
->t1
->object1
)->data
,
158 (void (*)(void *))&_pxprpc__stepPush3
,self
);
160 static void _pxprpc__stepPush1(struct _pxprpc__ServCo
*self
){
161 self
->io1
->read(self
->io1
,8,(uint8_t*)&self
->hdr
.addr1
,(void (*)(void *))&_pxprpc__stepPush2
,self
);
165 static void _pxprpc__stepPull2(struct _pxprpc__ServCo
*self
){
166 if(self
->io1
->get_error(self
->io1
,self
->io1
->read
)!=NULL
)return;
167 int destAddr
=self
->hdr
.addr1
;
169 struct pxprpc_bytes
*bytes
=self
->refSlots
[destAddr
]->object1
;
171 pthread_mutex_lock(&self
->writeMutex
);
172 self
->io1
->write(self
->io1
,4,(uint8_t *)&self
->hdr
.session
,_pxprpc__nopcallback
,NULL
);
174 self
->io1
->write(self
->io1
,4,(uint8_t *)&bytes
->length
,_pxprpc__nopcallback
,NULL
);
175 self
->io1
->write(self
->io1
,bytes
->length
,bytes
->data
,(void (*)(void *))_pxprpc__step1
,self
);
177 *(uint32_t *)(&self
->writeBuf
)=0xffffffff;
178 self
->io1
->write(self
->io1
,4,self
->writeBuf
,(void (*)(void *))_pxprpc__step1
,self
);
180 pthread_mutex_unlock(&self
->writeMutex
);
182 static void _pxprpc__stepPull1(struct _pxprpc__ServCo
*self
){
183 self
->io1
->read(self
->io1
,4,(uint8_t*)&self
->hdr
.addr1
,(void (*)(void *))&_pxprpc__stepPull2
,self
);
187 static void _pxprpc__stepAssign2(struct _pxprpc__ServCo
*self
){
188 if(self
->io1
->get_error(self
->io1
,self
->io1
->read
)!=NULL
)return;
189 _pxprpc__RefSlotsPut(self
,self
->hdr
.addr1
,self
->refSlots
[self
->hdr
.addr2
]);
190 pthread_mutex_lock(&self
->writeMutex
);
191 self
->io1
->write(self
->io1
,4,(uint8_t *)&self
->hdr
.session
,(void (*)(void *))_pxprpc__step1
,self
);
192 pthread_mutex_unlock(&self
->writeMutex
);
194 static void _pxprpc__stepAssign1(struct _pxprpc__ServCo
*self
){
195 self
->io1
->read(self
->io1
,8,(uint8_t*)&self
->hdr
.addr1
,(void (*)(void *))&_pxprpc__stepAssign2
,self
);
200 static void _pxprpc__stepUnlink2(struct _pxprpc__ServCo
*self
){
201 if(self
->io1
->get_error(self
->io1
,self
->io1
->read
)!=NULL
)return;
202 _pxprpc__RefSlotsPut(self
,self
->hdr
.addr1
,NULL
);
203 pthread_mutex_lock(&self
->writeMutex
);
204 self
->io1
->write(self
->io1
,4,(uint8_t *)&self
->hdr
.session
,(void (*)(void *))_pxprpc__step1
,self
);
205 pthread_mutex_unlock(&self
->writeMutex
);
207 static void _pxprpc__stepUnlink1(struct _pxprpc__ServCo
*self
){
208 self
->io1
->read(self
->io1
,4,(uint8_t*)&self
->hdr
.addr1
,(void (*)(void *))&_pxprpc__stepUnlink2
,self
);
212 static void _pxprpc__stepCall4(struct pxprpc_request
*r
, struct pxprpc_object
*result
){
213 struct _pxprpc__ServCo
*self
=r
->server_context
;
214 _pxprpc__RefSlotsPut(r
->server_context
,r
->dest_addr
,result
);
216 pthread_mutex_lock(&self
->writeMutex
);
217 self
->io1
->write(self
->io1
,4,(uint8_t *)&r
->session
,_pxprpc__nopcallback
,NULL
);
218 r
->callable
->writeResult(r
->callable
,r
);
219 pthread_mutex_unlock(&self
->writeMutex
);
223 static void _pxprpc__stepCall3(struct pxprpc_request
*r
){
224 struct _pxprpc__ServCo
*self
=(struct _pxprpc__ServCo
*)r
->server_context
;
225 r
->callable
->call(r
->callable
,r
,&_pxprpc__stepCall4
);
226 _pxprpc__step1(self
);
228 static void _pxprpc__stepCall2(struct _pxprpc__ServCo
*self
){
229 if(self
->io1
->get_error(self
->io1
,self
->io1
->read
)!=NULL
)return;
230 struct pxprpc_request
*req
=(struct pxprpc_request
*)pxprpc__malloc(sizeof(struct pxprpc_request
));
231 req
->session
=self
->hdr
.session
;
233 req
->ref_slots
=self
->refSlots
;
234 req
->dest_addr
=self
->hdr
.addr1
;
235 req
->server_context
=self
;
236 struct pxprpc_callable
*func
=(struct pxprpc_callable
*)((struct pxprpc_object
*)self
->refSlots
[self
->hdr
.addr2
])->object1
;
238 func
->readParameter(func
,req
,&_pxprpc__stepCall3
);
240 static void _pxprpc__stepCall1(struct _pxprpc__ServCo
*self
){
241 self
->io1
->read(self
->io1
,8,(uint8_t*)&self
->hdr
.addr1
,(void (*)(void *))&_pxprpc__stepCall2
,self
);
244 //str1(2)Len = -1 indicate 0-ending string, In this case the real length will be put into *str1(2)Len after function return.
245 //string length is limited to 0x1000
246 static int _pxprpc__strcmp2(const char *str1
,int *str1Len
,const char *str2
,int *str2Len
){
249 for(i
=0;i
<0x1000;i
++){
257 for(i
=0;i
<0x1000;i
++){
264 if(*str1Len
==*str2Len
){
265 for(i
=0,r
=0;i
<*str1Len
;i
++){
266 if(str1
[i
]!=str2
[i
]){
277 static void _pxprpc__stepGetFunc2(struct _pxprpc__ServCo
*self
){
278 if(self
->io1
->get_error(self
->io1
,self
->io1
->read
)!=NULL
)return;
279 struct pxprpc_bytes
*bs
=(struct pxprpc_bytes
*)self
->refSlots
[self
->hdr
.addr2
]->object1
;
282 for(int i
=0;i
<self
->lengthOfNamedFuncs
;i
++){
284 int cmp1
=_pxprpc__strcmp2(self
->namedfuncs
[i
].name
,&lenOut
,(const char *)bs
->data
,&bs
->length
);
286 _pxprpc__RefSlotsPut(self
,self
->hdr
.addr1
,pxprpc_new_object(self
->namedfuncs
[i
].callable
));
287 returnAddr
=self
->hdr
.addr1
;
291 pthread_mutex_lock(&self
->writeMutex
);
292 *(uint32_t *)(&self
->writeBuf
)=returnAddr
;
293 self
->io1
->write(self
->io1
,4,(uint8_t *)&self
->hdr
.session
,_pxprpc__nopcallback
,NULL
);
294 self
->io1
->write(self
->io1
,4,self
->writeBuf
,(void (*)(void *))_pxprpc__step1
,self
);
295 pthread_mutex_unlock(&self
->writeMutex
);
297 static void _pxprpc__stepGetFunc1(struct _pxprpc__ServCo
*self
){
298 self
->io1
->read(self
->io1
,8,(uint8_t*)&self
->hdr
.addr1
,(void(*)(void *))&_pxprpc__stepGetFunc2
,self
);
303 static int _pxprpc__stepClose1(struct _pxprpc__ServCo
*self
){
310 static void _pxprpc__stepGetInfo1(struct _pxprpc__ServCo
*self
){
311 pthread_mutex_lock(&self
->writeMutex
);
312 uint32_t length
=strlen(ServerInfo
);
313 self
->io1
->write(self
->io1
,4,(uint8_t *)&self
->hdr
.session
,_pxprpc__nopcallback
,NULL
);
314 *(uint32_t *)(&self
->writeBuf
)=length
;
315 self
->io1
->write(self
->io1
,4,(uint8_t *)&length
,_pxprpc__nopcallback
,NULL
);
316 self
->io1
->write(self
->io1
,length
,ServerInfo
,(void (*)(void *))_pxprpc__step1
,self
);
317 pthread_mutex_unlock(&self
->writeMutex
);
321 static void _pxprpc__step2(struct _pxprpc__ServCo
*self
){
322 if(self
->io1
->get_error(self
->io1
,self
->io1
->read
)!=NULL
)return;
323 int opcode
=self
->hdrbuf
[0];
326 _pxprpc__stepPush1(self
);
329 _pxprpc__stepPull1(self
);
332 _pxprpc__stepAssign1(self
);
335 _pxprpc__stepUnlink1(self
);
338 _pxprpc__stepCall1(self
);
341 _pxprpc__stepGetFunc1(self
);
347 _pxprpc__stepGetInfo1(self
);
352 static void _pxprpc__step1(struct _pxprpc__ServCo
*self
){
353 if(_pxprpc__ServCoIsClosed(self
)){
356 self
->io1
->read(self
->io1
,4,self
->hdrbuf
,(void(*)(void *))_pxprpc__step2
,self
);
361 static int pxprpc_new_server_context(pxprpc_server_context
*server_context
,struct pxprpc_abstract_io
*io1
,struct pxprpc_namedfunc
*namedfuncs
,int len_namedfuncs
){
362 struct _pxprpc__ServCo
*ctx
=(struct _pxprpc__ServCo
*)pxprpc__malloc(sizeof(struct _pxprpc__ServCo
));
363 memset(ctx
,0,sizeof(struct _pxprpc__ServCo
));
365 ctx
->namedfuncs
=namedfuncs
;
366 ctx
->lengthOfNamedFuncs
=len_namedfuncs
;
371 static int pxprpc_start_serve(pxprpc_server_context server_context
){
372 struct _pxprpc__ServCo
*ctx
=(struct _pxprpc__ServCo
*)server_context
;
373 _pxprpc__ServCoStart(ctx
);
377 static int pxprpc_free_context(pxprpc_server_context
*server_context
){
378 struct _pxprpc__ServCo
*ctx
=(struct _pxprpc__ServCo
*)*server_context
;
380 pxprpc__free(*server_context
);
385 static pxprpc_server_api exports
={
386 &pxprpc_new_server_context
,&pxprpc_start_serve
,&pxprpc_closed
,&pxprpc_close
,&pxprpc_free_context
,
387 &pxprpc_new_object
,&pxprpc_new_bytes_object
,&pxprpc_fill_bytes_object
390 extern int pxprpc_server_query_interface(pxprpc_server_api
**outapi
){