Browse code

socklib: add per-fd userptr

Dario Rodriguez authored on 12/06/2014 11:21:04
Showing 2 changed files
... ...
@@ -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 *)&ltime,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);