Browse code

webkernel: sbuf acquire/release

Dario Rodriguez authored on 15/06/2014 14:41:12
Showing 4 changed files
1 1
deleted file mode 100644
... ...
@@ -1,71 +0,0 @@
1
-/*
2
- * iobuf.c
3
- *
4
- * An I/O buffer library based on sbuf.
5
- *
6
- * History:
7
- *      12/03/2014 Creation.
8
- *      14/03/2014 Compilation fixes.
9
- *
10
- * Author: Dario Rodriguez dario@softhome.net
11
- * This library is licensed on the terms of the GNU LGPL v2+
12
- */
13
-
14
-#include <stdlib.h>
15
-#include <string.h>
16
-#include "iobuf.h"
17
-
18
-/* exported funcions */
19
-siobuf *
20
-iobuf_init(int insize,int outsize)
21
-{
22
-        siobuf *iobuf;
23
-        if((iobuf=malloc(sizeof(siobuf)))==NULL)
24
-                return(NULL);
25
-        memset(iobuf,0,sizeof(siobuf));
26
-        if((iobuf->in=sbuf_init(insize))==NULL) {
27
-                free(iobuf),iobuf=NULL;
28
-                return(NULL);
29
-        }
30
-        if((iobuf->out=sbuf_init(outsize))==NULL) {
31
-                sbuf_free(iobuf->in),iobuf->in=NULL;
32
-                free(iobuf),iobuf=NULL;
33
-                return(NULL);
34
-        }
35
-        return(iobuf);
36
-}
37
-
38
-siobuf *
39
-iobuf_staticinit(siobuf *uninitiobuf, sbuf *uninitinbuf, sbuf *uninitoutbuf,int insize, int outsize, char *inbuf, char *outbuf)
40
-{
41
-        memset(uninitiobuf,0,sizeof(siobuf));
42
-        if((uninitiobuf->in=sbuf_staticinit(uninitinbuf,insize,inbuf))==NULL)
43
-                return(NULL);
44
-        if((uninitiobuf->out=sbuf_staticinit(uninitoutbuf,outsize,outbuf))==NULL)
45
-                return(NULL);
46
-        return(uninitiobuf);
47
-}
48
-
49
-void
50
-iobuf_free(siobuf *iobuf)
51
-{
52
-        if(iobuf==NULL)
53
-                return;
54
-        if(iobuf->in!=NULL)
55
-                sbuf_free(iobuf->in),iobuf->in=NULL;
56
-        if(iobuf->out!=NULL)
57
-                sbuf_free(iobuf->out),iobuf->out=NULL;
58
-        free(iobuf);
59
-}
60
-
61
-void
62
-iobuf_staticfree(siobuf *iobuf)
63
-{
64
-        if(iobuf==NULL)
65
-                return;
66
-        sbuf_staticfree(iobuf->in),iobuf->in=NULL;
67
-        sbuf_staticfree(iobuf->out),iobuf->out=NULL;
68
-        return;
69
-}
70
-
71
-
72 0
deleted file mode 100644
... ...
@@ -1,35 +0,0 @@
1
-/*
2
- * iobuf.h
3
- *
4
- * An I/O buffer library based on sbuf.
5
- *
6
- * Header file.
7
- *
8
- * History:
9
- *      21/01/2014 Creation.
10
- *      12/03/2014 Fix _staticinit() and  _*free() prototypes.
11
- *
12
- * Author: Dario Rodriguez dario@softhome.net
13
- * This library is licensed on the terms of the GNU LGPL v2+
14
- */
15
-
16
-#ifndef IOBUF_H
17
-#define IOBUF_H
18
-
19
-#include "sbuf.h"
20
-
21
-typedef struct {
22
-        int iobufnum;
23
-        sbuf *in;
24
-        sbuf *out;
25
-} siobuf;
26
-
27
-/* iobuf */
28
-siobuf *iobuf_init(int insize,int outsize);
29
-siobuf *iobuf_staticinit(siobuf *uninitiobuf, sbuf *uninitinbuf, sbuf *uninitoutbuf,int insize, int outsize, char *inbuf, char *outbuf);
30
-
31
-void iobuf_free(siobuf *iobuf);
32
-void iobuf_staticfree(siobuf *iobuf);
33
-
34
-#endif
35
-
... ...
@@ -12,18 +12,27 @@
12 12
 #include <stdlib.h>
13 13
 #include <unistd.h>
14 14
 #include <string.h>
15
+#include "sbuf.h"
15 16
 #include "socklib.h"
16 17
 #include "webkernel.h"
17 18
 
18 19
 #define FDBLOCK 256
19 20
 #define CLIENTBLOCK 1024
20 21
 #define CLIENTBLOCKBLOCK 256
22
+#define MAXOUTBUF 128
23
+#define BUFSIZE 8192
24
+#define BUFBLOCK 128
25
+#define BUFBLOCKBLOCK 256
21 26
 
22 27
 
23 28
 typedef struct wk_client {
24 29
         wk *web;
25
-        int connid; /* it is numblock*CLIENTBLOCK+offset_in_block */
30
+        int connid; /* this is numblock*CLIENTBLOCK+offset_in_block */
26 31
         int fd;
32
+        int inbufid;
33
+        int sizeoutbufids;
34
+        int usedoutbufids;
35
+        int outbufids[MAXOUTBUF];
27 36
 } wk_client;
28 37
 
29 38
 typedef struct wk_clientblock {
... ...
@@ -33,6 +42,18 @@ typedef struct wk_clientblock {
33 42
         wk_client *clients;
34 43
 } wk_clientblock;
35 44
 
45
+typedef struct wk_buf {
46
+        sbuf buf;
47
+        char bufdata[BUFSIZE];
48
+} wk_buf;
49
+
50
+typedef struct wk_bufblock {
51
+        int sizebufs;
52
+        int usedbufs;
53
+        unsigned char acquired[BUFBLOCK/8];
54
+        wk_buf *bufs;
55
+} wk_bufblock;
56
+
36 57
 typedef struct _wk {
37 58
         int serverfd;
38 59
         fd_set fdset;
... ...
@@ -40,6 +61,9 @@ typedef struct _wk {
40 61
         int sizeclientblocks;
41 62
         int usedclientblocks;
42 63
         wk_clientblock *clientblocks;
64
+        int sizebufblocks;
65
+        int usedbufblocks;
66
+        wk_bufblock *bufblocks;
43 67
 } _wk;
44 68
 
45 69
 static int wk_accept(_wk *web);
... ...
@@ -63,6 +87,7 @@ wk_init(int port, sselect *ssel, void (*callback_event)(/*wk *paramweb,int conni
63 87
                 wk_free((wk *)web),web=NULL;
64 88
                 return(NULL);
65 89
         }
90
+        sock_setunsafe(web->serverfd);
66 91
         FD_SET(web->serverfd,&(web->fdset));
67 92
         sselect_addread(ssel,web->serverfd,NULL);
68 93
         return((wk *)web);
... ...
@@ -129,6 +154,7 @@ wk_service(wk *paramweb)
129 154
         int n;
130 155
         int i;
131 156
         _wk *web=(_wk *)paramweb;
157
+        wk_client *client;
132 158
         if(web==NULL)
133 159
                 return(-1);
134 160
         while((n=sselect_getreadfiltered(web,&(web->fdset),fds,sizeof(fds)/sizeof(fds[0])))>0) {
... ...
@@ -139,6 +165,9 @@ wk_service(wk *paramweb)
139 165
                                 wk_accept(web);
140 166
                                 continue;
141 167
                         }
168
+                        if((client=(wk_client *)sselect_getuserptr(web->ssel,fd))==NULL || client->web!=(wk *)web)
169
+                                continue; /* internal error */
170
+
142 171
                 }
143 172
         }
144 173
 }
... ...
@@ -245,18 +274,101 @@ mime_getdefault(const char *filename, const char *defaultmime)
245 274
         return(defaultmime);
246 275
 }
247 276
 
248
-siobuf *
249
-wk_iobufget(wk *paramweb)
277
+int
278
+wk_sbufacquire(wk *paramweb)
250 279
 {
251
-
280
+        int i,j,k;
281
+        wk_bufblock *bb;
282
+        sbuf *buf;
283
+        _wk *web=(_wk *)paramweb;
284
+        if(web==NULL)
285
+                return(-1);
286
+        /* make sure there are free bufblocks */
287
+        if(web->usedbufblocks==web->sizebufblocks) {
288
+                wk_bufblock *newbb;
289
+                if((newbb=(wk_bufblock *)realloc(web->bufblocks,web->sizebufblocks+BUFBLOCKBLOCK))==NULL)
290
+                        return(-1); /* insufficient memory */
291
+                web->bufblocks=newbb;
292
+                memset(web->bufblocks+web->sizebufblocks,0,BUFBLOCKBLOCK*sizeof(wk_bufblock));
293
+                web->sizebufblocks+=BUFBLOCKBLOCK;
294
+        }
295
+        /* search for a block with unused sbufs (or the first unalloc'd block) */
296
+        for(i=0;i<web->sizebufblocks;i++) {
297
+                bb=web->bufblocks+i;
298
+                if(bb->bufs==NULL || bb->usedbufs<bb->sizebufs)
299
+                        break;
300
+        }
301
+        if(i>=web->sizebufblocks)
302
+                return(-1); /* internal error */
303
+        /* alloc block if not alloc'd */
304
+        if(bb->bufs==NULL) {
305
+                if((bb->bufs=malloc(sizeof(wk_buf)*BUFBLOCK))==NULL)
306
+                        return(-1); /* insufficient memory */
307
+                memset(bb->bufs,0,sizeof(wk_buf)*BUFBLOCK);
308
+                bb->sizebufs=BUFBLOCK;
309
+                bb->usedbufs=0;
310
+        }
311
+        /* get first unused sbuf */
312
+        for(j=0;j<bb->sizebufs;j+=8) {
313
+                if(bb->acquired[j>>3]!=0xff)
314
+                        break;
315
+        }
316
+        if(j>=bb->sizebufs)
317
+                return(-1); /* internal error */
318
+        for(k=0x01;k<0x100;k<<=1,j++) {
319
+                if((bb->acquired[j>>3]&k)==0)
320
+                        break;
321
+        }
322
+        if(k>=0x100)
323
+                return(-1); /* internal error */
324
+        bb->acquired[j>>3]|=k;
325
+        bb->usedbufs++;
326
+        /* initialize sbuf and return it */
327
+        buf=&(bb->bufs[j].buf);
328
+        sbuf_staticinit(buf,BUFSIZE,bb->bufs[j].bufdata);
329
+        return(i*BUFBLOCK+j);
252 330
 }
253 331
 
254
-void
255
-wk_iobuffree(wk *paramweb, int iobufnum)
332
+int
333
+wk_bufrelease(wk *paramweb, int sbufid)
256 334
 {
335
+        sbuf *buf;
336
+        int numblock,j,bit;
337
+        _wk *web=(_wk *)paramweb;
338
+        if(web==NULL)
339
+                return(-1);
340
+        numblock=sbufid/BUFBLOCK;
341
+        j=sbufid%BUFBLOCK;
342
+        bit=0x1<<(j&3);
343
+        if((buf=wk_sbufget(web,sbufid))==NULL)
344
+                return(-1);
345
+        web->bufblocks[numblock].usedbufs--;
346
+        web->bufblocks[numblock].acquired[j>>3]&=(~bit);
347
+        sbuf_staticfree(buf);
348
+        memset(web->bufblocks[numblock].bufs[j].bufdata,0,sizeof(BUFSIZE));
349
+        return(0);
350
+}
257 351
 
352
+sbuf *
353
+wk_bufget(wk *paramweb, int sbufid)
354
+{
355
+        int numblock,j,bit;
356
+        _wk *web=(_wk *)paramweb;
357
+        if(web==NULL)
358
+                return(NULL);
359
+        numblock=sbufid/BUFBLOCK;
360
+        j=sbufid%BUFBLOCK;
361
+        bit=0x1<<(j&3);
362
+        if(web==NULL ||
363
+          web->bufblocks==NULL ||
364
+          web->sizebufblocks<=numblock ||
365
+          web->bufblocks[numblock].bufs==NULL ||
366
+          (web->bufblocks[numblock].acquired[j>>3]&bit)!=bit)
367
+                return(NULL);
368
+        return(&(web->bufblocks[numblock].bufs[j].buf));
258 369
 }
259 370
 
371
+
260 372
 /* local functions */
261 373
 static int
262 374
 wk_accept(_wk *web)
... ...
@@ -304,6 +416,7 @@ wk_clientacquire(_wk *web)
304 416
                         return(NULL); /* insufficient memory */
305 417
                 memset(cb->clients,0,sizeof(wk_client)*CLIENTBLOCK);
306 418
                 cb->sizeclients=CLIENTBLOCK;
419
+                cb->usedclients=0;
307 420
         }
308 421
         /* get first unused client */
309 422
         for(j=0;j<cb->sizeclients;j+=8) {
... ...
@@ -361,3 +474,4 @@ wk_clientget(_wk *web, int connid)
361 474
         return(web->clientblocks[numblock].clients+j);
362 475
 }
363 476
 
477
+
... ...
@@ -12,7 +12,7 @@
12 12
 #ifndef WEBKERNEL_H
13 13
 #define WEBKERNEL_H
14 14
 #include <sys/select.h>
15
-#include "iobuf.h"
15
+#include "sbuf.h"
16 16
 #include "socklib.h"
17 17
 
18 18
 typedef void wk;
... ...
@@ -57,7 +57,9 @@ char *wk_uri_getheaderbynum(wk_uri *wkuri, int num);
57 57
 
58 58
 const char *mime_getdefault(const char *filename, const char *defaultmime);
59 59
 
60
-siobuf *wk_iobufget(wk *web);
61
-void wk_iobuffree(wk *web, int iobufnum);
60
+
61
+int wk_sbufacquire(wk *web);
62
+sbuf *wk_sbufget(wk *web, int sbufid);
63
+void wk_sbufrelease(wk *web, int sbufid);
62 64
 
63 65
 #endif