... | ... |
@@ -32,6 +32,8 @@ typedef struct _sselect { |
32 | 32 |
int sizeresult; |
33 | 33 |
int readresultreturned; |
34 | 34 |
int writeresultreturned; |
35 |
+ int sizeuserptr; |
|
36 |
+ void **userptr; |
|
35 | 37 |
} _sselect; |
36 | 38 |
|
37 | 39 |
|
... | ... |
@@ -47,6 +49,11 @@ typedef struct _sselect { |
47 | 49 |
s.sin_port=htons(port) |
48 | 50 |
#endif |
49 | 51 |
|
52 |
+#define USERPTRBLOCKSIZE 1024 |
|
53 |
+ |
|
54 |
+static int sselect_adduserptr(_sselect *ssel, int fd, void *userptr); |
|
55 |
+static int sselect_clearuserptr(_sselect *ssel, int fd); |
|
56 |
+ |
|
50 | 57 |
char * |
51 | 58 |
ipv4_genip(char *hostname, long *resulthostsize) |
52 | 59 |
{ |
... | ... |
@@ -231,6 +238,20 @@ sselect_init(void) |
231 | 238 |
return((sselect *)ssel); |
232 | 239 |
} |
233 | 240 |
|
241 |
+void |
|
242 |
+sselect_free(sselect *paramssel) |
|
243 |
+{ |
|
244 |
+ _sselect *ssel=(_sselect *)paramssel; |
|
245 |
+ if(ssel==NULL) |
|
246 |
+ return; |
|
247 |
+ if(ssel->userptr!=NULL) { |
|
248 |
+ ssel->sizeuserptr=0; |
|
249 |
+ free(ssel->userptr),ssel->userptr=NULL; |
|
250 |
+ } |
|
251 |
+ free(ssel),ssel=NULL; |
|
252 |
+} |
|
253 |
+ |
|
254 |
+ |
|
234 | 255 |
int |
235 | 256 |
sselect_reset(sselect *paramssel) |
236 | 257 |
{ |
... | ... |
@@ -243,15 +264,21 @@ sselect_reset(sselect *paramssel) |
243 | 264 |
ssel->numfd=0; |
244 | 265 |
FD_ZERO(&(ssel->readresult)); |
245 | 266 |
FD_ZERO(&(ssel->writeresult)); |
267 |
+ memset(ssel->userptr,0,sizeof(void *)*ssel->sizeuserptr); |
|
246 | 268 |
return(0); |
247 | 269 |
} |
248 | 270 |
|
249 | 271 |
int |
250 |
-sselect_addread(sselect *paramssel, int fd) |
|
272 |
+sselect_addread(sselect *paramssel, int fd, void *userptr) |
|
251 | 273 |
{ |
252 | 274 |
_sselect *ssel=(_sselect *)paramssel; |
253 | 275 |
if(ssel==NULL || fd<0 || FD_ISSET(fd,&(ssel->readset))) |
254 | 276 |
return(-1); |
277 |
+ if(userptr!=NULL) { |
|
278 |
+ if(sselect_adduserptr(ssel, fd, userptr)!=0) |
|
279 |
+ return(-1); |
|
280 |
+ } else |
|
281 |
+ sselect_clearuserptr(ssel,fd); |
|
255 | 282 |
FD_SET(fd,&(ssel->readset)); |
256 | 283 |
if(fd>ssel->maxfd) |
257 | 284 |
ssel->maxfd=fd; |
... | ... |
@@ -261,11 +288,16 @@ sselect_addread(sselect *paramssel, int fd) |
261 | 288 |
|
262 | 289 |
|
263 | 290 |
int |
264 |
-sselect_addwrite(sselect *paramssel, int fd) |
|
291 |
+sselect_addwrite(sselect *paramssel, int fd, void *userptr) |
|
265 | 292 |
{ |
266 | 293 |
_sselect *ssel=(_sselect *)paramssel; |
267 | 294 |
if(ssel==NULL || fd<0 || FD_ISSET(fd,&(ssel->writeset))) |
268 | 295 |
return(-1); |
296 |
+ if(userptr!=NULL) { |
|
297 |
+ if(sselect_adduserptr(ssel, fd, userptr)!=0) |
|
298 |
+ return(-1); |
|
299 |
+ } else |
|
300 |
+ sselect_clearuserptr(ssel,fd); |
|
269 | 301 |
FD_SET(fd,&(ssel->writeset)); |
270 | 302 |
if(fd>ssel->maxfd) |
271 | 303 |
ssel->maxfd=fd; |
... | ... |
@@ -386,6 +418,15 @@ sselect_getwritefiltered(sselect *paramssel, fd_set *filter, int *fds, int sizef |
386 | 418 |
return(n); |
387 | 419 |
} |
388 | 420 |
|
421 |
+void * |
|
422 |
+sselect_getuserptr(sselect *paramssel, int fd) |
|
423 |
+{ |
|
424 |
+ _sselect *ssel=(_sselect *)paramssel; |
|
425 |
+ if(ssel==NULL || fd<0 || fd>=ssel->sizeuserptr) |
|
426 |
+ return(NULL); |
|
427 |
+ return(ssel->userptr[fd]); |
|
428 |
+} |
|
429 |
+ |
|
389 | 430 |
|
390 | 431 |
/* aux functions */ |
391 | 432 |
void |
... | ... |
@@ -408,3 +449,34 @@ sock_setunsafe(int fd) |
408 | 449 |
setsockopt(fd,SOL_SOCKET,SO_LINGER,(void *)<ime,sizeof(ltime)); |
409 | 450 |
} |
410 | 451 |
|
452 |
+/* local functions */ |
|
453 |
+static int |
|
454 |
+sselect_adduserptr(_sselect *ssel, int fd, void *userptr) |
|
455 |
+{ |
|
456 |
+ if(ssel==NULL || fd<0) |
|
457 |
+ return(-1); |
|
458 |
+ if(ssel->sizeuserptr<(fd+1)) { |
|
459 |
+ void **newptr; |
|
460 |
+ int newsize; |
|
461 |
+ newsize=(fd+USERPTRBLOCKSIZE)/USERPTRBLOCKSIZE; |
|
462 |
+ newsize*=USERPTRBLOCKSIZE; |
|
463 |
+ if((newptr=realloc(ssel->userptr,sizeof(void *)*newsize))==NULL) |
|
464 |
+ return(-1); |
|
465 |
+ ssel->userptr=newptr; |
|
466 |
+ memset(ssel->userptr+ssel->sizeuserptr,sizeof(void *)*(newsize-ssel->sizeuserptr),0); |
|
467 |
+ } |
|
468 |
+ ssel->userptr[fd]=userptr; |
|
469 |
+ return(0); |
|
470 |
+} |
|
471 |
+ |
|
472 |
+static int |
|
473 |
+sselect_clearuserptr(_sselect *ssel, int fd) |
|
474 |
+{ |
|
475 |
+ if(ssel==NULL || fd<0) |
|
476 |
+ return(-1); |
|
477 |
+ if(ssel->sizeuserptr<(fd+1)) |
|
478 |
+ return(0); |
|
479 |
+ ssel->userptr[fd]=NULL; |
|
480 |
+ return(0); |
|
481 |
+} |
|
482 |
+ |
... | ... |
@@ -33,14 +33,16 @@ int sock_queued(int fd); |
33 | 33 |
int sock_setblocking(int fd, int block); |
34 | 34 |
|
35 | 35 |
sselect *sselect_init(void); |
36 |
+void sselect_free(sselect *ssel); |
|
36 | 37 |
int sselect_reset(sselect *ssel); |
37 |
-int sselect_addread(sselect *ssel, int fd); |
|
38 |
-int sselect_addwrite(sselect *ssel, int fd); |
|
38 |
+int sselect_addread(sselect *ssel, int fd, void *userptr); |
|
39 |
+int sselect_addwrite(sselect *ssel, int fd, void *userptr); |
|
39 | 40 |
int sselect_delread(sselect *ssel, int fd); |
40 | 41 |
int sselect_delwrite(sselect *ssel, int fd); |
41 | 42 |
int sselect_wait(sselect *ssel, int ms); |
42 | 43 |
int sselect_getread(sselect *ssel, int *fds, int sizefds); |
43 | 44 |
int sselect_getwrite(sselect *ssel, int *fds, int sizefds); |
45 |
+void *sselect_getuserptr(sselect *ssel, int fd); |
|
44 | 46 |
|
45 | 47 |
/* advanced sselect functions */ |
46 | 48 |
int sselect_getreadfiltered(sselect *ssel, fd_set *filter, int *fds, int sizefds); |