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";
24 static uint32_t _pxprpc__ref_AddRef(struct pxprpc_object
*ref
){
29 static uint32_t _pxprpc__ref_Release(struct pxprpc_object
*ref
){
39 static uint32_t _pxprpc__ref_bytes_Release(struct pxprpc_object
*ref
){
40 void *bytes
=ref
->object1
;
41 if(_pxprpc__ref_Release(ref
)==0){
48 struct _pxprpc__ServCo
{
49 void (*next
)(struct _pxprpc__ServCo
*self
);
61 struct pxprpc_abstract_io
*io1
;
62 struct pxprpc_object
**refSlots
;
63 int slotMaxHashOffset
;
65 struct pxprpc_object
*t1
;
66 pthread_mutex_t writeMutex
;
67 int lengthOfNamedFuncs
;
68 struct pxprpc_namedfunc
*namedfuncs
;
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
);
84 static void _pxprpc__RefSlotsPut(struct _pxprpc__ServCo
*self
,uint32_t addr
, struct pxprpc_object
*ref2
){
85 struct pxprpc_object
*ref
=self
->refSlots
[addr
];
92 self
->refSlots
[addr
]=ref2
;
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
);
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
);
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
);
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
);
162 static void _pxprpc__stepCall4(struct pxprpc_request
*r
, struct pxprpc_object
*result
){
163 _pxprpc__RefSlotsPut(r
->server_context_data
,r
->dest_addr
,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
);
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
;
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
);
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
));
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
);
219 static void _pxprpc__stepClose1(struct _pxprpc__ServCo
*self
){
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
)){
240 int opcode
=self
->hdrbuf
[0];
243 _pxprpc__stepPush1(self
);
246 _pxprpc__stepPull1(self
);
249 _pxprpc__stepAssign1(self
);
252 _pxprpc__stepUnlink1(self
);
255 _pxprpc__stepCall1(self
);
258 _pxprpc__stepGetFunc1(self
);
264 _pxprpc__stepGetInfo1(self
);
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
]);
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
;
287 ref
->size_of_struct
=sizeof(struct pxprpc_object
);
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
;