Browse Source
another try with a shared memory based ringbuffer...this performs well for keep-alive sessions but is much slower without. actually i am not sure why but most likely the shared memory setup is quite expensive. @TODO: make a profiling.
master
another try with a shared memory based ringbuffer...this performs well for keep-alive sessions but is much slower without. actually i am not sure why but most likely the shared memory setup is quite expensive. @TODO: make a profiling.
master
35 changed files with 557 additions and 223 deletions
-
6ChangeLog
-
1include/http/message.h
-
8include/http/request/parser.h
-
15include/http/response/writer.h
-
3include/http/worker.h
-
3include/server.h
-
2include/socket.h
-
7src/Makefile.am
-
113src/cbuf.c
-
11src/cbuf/addr_index.c
-
19src/cbuf/get_data.c
-
11src/cbuf/get_free.c
-
26src/cbuf/get_line.c
-
9src/cbuf/get_read.c
-
9src/cbuf/get_write.c
-
14src/cbuf/inc_read.c
-
14src/cbuf/inc_write.c
-
9src/cbuf/is_empty.c
-
11src/cbuf/memchr.c
-
37src/cbuf/read.c
-
23src/cbuf/set_data.c
-
12src/cbuf/skip_non_alpha.c
-
29src/cbuf/write.c
-
16src/http/request/parser.c
-
55src/http/request/parser/get_body.c
-
94src/http/request/parser/parse.c
-
63src/http/request/parser/read.c
-
7src/http/response/writer.c
-
90src/http/response/writer/write.c
-
14src/http/worker.c
-
2src/server/close_conn.c
-
10src/server/handle_accept.c
-
26src/server/run.c
-
5src/socket/accept.c
-
6src/testserver.c
@ -0,0 +1,113 @@ |
|||
#define _POSIX_SOURCE |
|||
#define _POSIX_C_SOURCE 200112L |
|||
|
|||
#include <sys/types.h> |
|||
#include <sys/stat.h> |
|||
#include <sys/mman.h> |
|||
#include <stdarg.h> |
|||
#include <stdlib.h> |
|||
#include <stdio.h> |
|||
#include <unistd.h> |
|||
#include <fcntl.h> |
|||
|
|||
#include "class.h" |
|||
#include "interface/class.h" |
|||
|
|||
#include "cbuf.h" |
|||
|
|||
|
|||
static void dtor(void*); |
|||
|
|||
static |
|||
void |
|||
ctor(void * _this, va_list * params) |
|||
{ |
|||
Cbuf this = _this; |
|||
char state = 0; |
|||
char * shm_name = va_arg(*params, char*); |
|||
long psize = sysconf(_SC_PAGESIZE); |
|||
size_t size; |
|||
int shm; |
|||
|
|||
this->shm_name = malloc(strlen(shm_name) + 7 + 2); |
|||
sprintf(this->shm_name, "/%06d_%s", getpid(), shm_name); |
|||
|
|||
/** |
|||
* align size at page boundary. |
|||
* increase as neccessary |
|||
*/ |
|||
size = va_arg(*params, size_t); |
|||
size = (0 >= size)? 1 : (0 != size%psize)? (size/psize)+1 : size/psize; |
|||
this->bsize = psize * size; |
|||
|
|||
while (0 == state) { |
|||
shm = shm_open(this->shm_name, O_RDWR|O_CREAT|O_EXCL, S_IRWXU); |
|||
if (-1 == shm) { |
|||
break; |
|||
} |
|||
|
|||
if (-1 == ftruncate(shm, this->bsize)) { |
|||
break; |
|||
} |
|||
|
|||
this->data = mmap (0, this->bsize << 1, |
|||
PROT_READ|PROT_WRITE, MAP_SHARED, shm, 0); |
|||
if (this->data == MAP_FAILED) { |
|||
this->data = NULL; |
|||
break; |
|||
} |
|||
|
|||
munmap(this->data + this->bsize, this->bsize); |
|||
|
|||
this->mirror = mmap (this->data + this->bsize, this->bsize, |
|||
PROT_READ|PROT_WRITE, MAP_SHARED, shm, 0); |
|||
if (this->mirror != this->data + this->bsize) { |
|||
if (this->mirror == this->data - this->bsize) { |
|||
this->data = this->mirror; |
|||
this->mirror += this->bsize; |
|||
} |
|||
else { |
|||
this->mirror = NULL; |
|||
break; |
|||
} |
|||
} |
|||
|
|||
state = 1; |
|||
} |
|||
|
|||
if (-1 != shm) { |
|||
shm_unlink(this->shm_name); |
|||
close(shm); |
|||
} |
|||
|
|||
if (1 != state) { |
|||
dtor(this); |
|||
} |
|||
} |
|||
|
|||
static |
|||
void |
|||
dtor(void * _this) |
|||
{ |
|||
Cbuf this = _this; |
|||
|
|||
if (NULL != this->shm_name) { |
|||
free(this->shm_name); |
|||
this->shm_name = NULL; |
|||
} |
|||
|
|||
if (NULL != this->data) { |
|||
munmap(this->data, this->bsize); |
|||
this->data = NULL; |
|||
} |
|||
|
|||
if (NULL != this->mirror) { |
|||
munmap(this->mirror, this->bsize); |
|||
this->mirror = NULL; |
|||
} |
|||
} |
|||
|
|||
INIT_IFACE(Class, ctor, dtor, NULL); |
|||
CREATE_CLASS(Cbuf, NULL, IFACE(Class)); |
|||
|
|||
// vim: set ts=4 sw=4: |
|||
@ -0,0 +1,11 @@ |
|||
#include <sys/types.h> |
|||
|
|||
#include "cbuf.h" |
|||
|
|||
size_t |
|||
cbufAddrIndex(Cbuf this, const void * c) |
|||
{ |
|||
return c - (const void *)cbufGetRead(this); |
|||
} |
|||
|
|||
// vim: set ts=4 sw=4: |
|||
@ -0,0 +1,19 @@ |
|||
#include <sys/types.h> |
|||
#include <string.h> |
|||
|
|||
#include "cbuf.h" |
|||
|
|||
char * |
|||
cbufGetData(Cbuf this, size_t n) |
|||
{ |
|||
char * ret = cbufGetRead(this); |
|||
|
|||
if (n > this->bused) { |
|||
return -1; |
|||
} |
|||
|
|||
cbufIncRead(this, n); |
|||
return ret; |
|||
} |
|||
|
|||
// vim: set ts=4 sw=4: |
|||
@ -0,0 +1,11 @@ |
|||
#include <sys/types.h> |
|||
|
|||
#include "cbuf.h" |
|||
|
|||
size_t |
|||
cbufGetFree(Cbuf this) |
|||
{ |
|||
return this->bsize - this->bused; |
|||
} |
|||
|
|||
// vim: set ts=4 sw=4: |
|||
@ -0,0 +1,26 @@ |
|||
#include <sys/types.h> |
|||
|
|||
#include <string.h> |
|||
|
|||
#include "cbuf.h" |
|||
|
|||
char * |
|||
cbufGetLine(Cbuf this) |
|||
{ |
|||
char * nl = cbufMemchr(this, '\n'); |
|||
char * ret = NULL; |
|||
|
|||
if (NULL != nl) { |
|||
size_t len = cbufAddrIndex(this, nl) + 1; |
|||
|
|||
*nl = 0; |
|||
*(nl-1) = ('\r' == *(nl-1))? 0 : *(nl-1); |
|||
|
|||
ret = cbufGetRead(this); |
|||
cbufIncRead(this, len); |
|||
} |
|||
|
|||
return ret; |
|||
} |
|||
|
|||
// vim: set ts=4 sw=4: |
|||
@ -0,0 +1,9 @@ |
|||
#include "cbuf.h" |
|||
|
|||
char * |
|||
cbufGetRead(Cbuf this) |
|||
{ |
|||
return this->data + this->read; |
|||
} |
|||
|
|||
// vim: set ts=4 sw=4: |
|||
@ -0,0 +1,9 @@ |
|||
#include "cbuf.h" |
|||
|
|||
char * |
|||
cbufGetWrite(Cbuf this) |
|||
{ |
|||
return this->data + this->write; |
|||
} |
|||
|
|||
// vim: set ts=4 sw=4: |
|||
@ -0,0 +1,14 @@ |
|||
#include <sys/types.h> |
|||
|
|||
#include "cbuf.h" |
|||
|
|||
void |
|||
cbufIncRead(Cbuf this, size_t n) |
|||
{ |
|||
this->read += n; |
|||
this->read = (this->read >= this->bsize)? |
|||
this->read - this->bsize : this->read; |
|||
this->bused -= n; |
|||
} |
|||
|
|||
// vim: set ts=4 sw=4: |
|||
@ -0,0 +1,14 @@ |
|||
#include <sys/types.h> |
|||
|
|||
#include "cbuf.h" |
|||
|
|||
void |
|||
cbufIncWrite(Cbuf this, size_t n) |
|||
{ |
|||
this->write += n; |
|||
this->write = (this->write >= this->bsize)? |
|||
this->write - this->bsize : this->write; |
|||
this->bused += n; |
|||
} |
|||
|
|||
// vim: set ts=4 sw=4: |
|||
@ -0,0 +1,9 @@ |
|||
#include "cbuf.h" |
|||
|
|||
char |
|||
cbufIsEmpty(Cbuf this) |
|||
{ |
|||
return (0 == this->bused); |
|||
} |
|||
|
|||
// vim: set ts=4 sw=4: |
|||
@ -0,0 +1,11 @@ |
|||
#include <string.h> |
|||
|
|||
#include "cbuf.h" |
|||
|
|||
char * |
|||
cbufMemchr(Cbuf this, int c) |
|||
{ |
|||
return memchr(cbufGetRead(this), c, this->bused); |
|||
} |
|||
|
|||
// vim: set ts=4 sw=4: |
|||
@ -0,0 +1,37 @@ |
|||
#include <sys/types.h> |
|||
#include <unistd.h> |
|||
#include <errno.h> |
|||
|
|||
#include "cbuf.h" |
|||
|
|||
|
|||
ssize_t |
|||
cbufRead(Cbuf this, int fd) |
|||
{ |
|||
ssize_t rrsize = 0; |
|||
size_t rsize = cbufGetFree(this); |
|||
|
|||
if (0 == rsize) { |
|||
errno = ECBUFOVFL; |
|||
return -1; |
|||
} |
|||
|
|||
rrsize = read(fd, cbufGetWrite(this), rsize); |
|||
|
|||
switch (rrsize) { |
|||
case 0: |
|||
rrsize = -2; |
|||
// DROP THROUGH |
|||
|
|||
case -1: |
|||
break; |
|||
|
|||
default: |
|||
cbufIncWrite(this, rrsize); |
|||
break; |
|||
} |
|||
|
|||
return rrsize; |
|||
} |
|||
|
|||
// vim: set ts=4 sw=4: |
|||
@ -0,0 +1,23 @@ |
|||
#include <sys/types.h> |
|||
#include <string.h> |
|||
#include <errno.h> |
|||
|
|||
#include "cbuf.h" |
|||
|
|||
char * |
|||
cbufSetData(Cbuf this, const void * src, size_t n) |
|||
{ |
|||
char * addr; |
|||
|
|||
if (n > cbufGetFree(this)) { |
|||
errno = ECBUFOVFL; |
|||
return -1; |
|||
} |
|||
|
|||
addr = memcpy(cbufGetWrite(this), src, n); |
|||
cbufIncWrite(this, n); |
|||
|
|||
return addr; |
|||
} |
|||
|
|||
// vim: set ts=4 sw=4: |
|||
@ -0,0 +1,12 @@ |
|||
#include <ctype.h> |
|||
|
|||
#include "cbuf.h" |
|||
|
|||
void |
|||
cbufSkipNonAlpha(Cbuf this) |
|||
{ |
|||
while(0 > this->bused && isalpha(*cbufGetRead(this))) |
|||
cbufIncRead(this, 1); |
|||
} |
|||
|
|||
// vim: set ts=4 sw=4: |
|||
@ -0,0 +1,29 @@ |
|||
#include <sys/types.h> |
|||
#include <unistd.h> |
|||
|
|||
#include "cbuf.h" |
|||
|
|||
|
|||
ssize_t |
|||
cbufWrite(Cbuf this, int fd) |
|||
{ |
|||
ssize_t wwsize = 0; |
|||
size_t wsize = this->bused; |
|||
|
|||
if (0 == wsize) return 0; |
|||
|
|||
wwsize = write(fd, cbufGetRead(this), wsize); |
|||
|
|||
switch (wwsize) { |
|||
case -1: |
|||
break; |
|||
|
|||
default: |
|||
cbufIncRead(this, wwsize); |
|||
break; |
|||
} |
|||
|
|||
return wwsize; |
|||
} |
|||
|
|||
// vim: set ts=4 sw=4: |
|||
Write
Preview
Loading…
Cancel
Save
Reference in new issue