#include <errno.h>
#include <unistd.h>
-#define WRITEV_IOV 32 /* FIXME future configured value */
+#include "ebuf.h"
+#define WRITEV_IOV 32 /* FIXME future configured value */
#define DEBUG
-
#define MAX_FDS 1024 /* maximum supported file descriptors */
-
#define BUFSIZE 8192
/* typedefs make life easier */
ipvx addr; /* address of the client */
unsigned int bufsize; /* current size of the buffer */
char buffer[BUFSIZE]; /* the buffer! */
+ eBuf recvQ; /* inbound queue */
+ eBuf sendQ; /* outbound queue */
int sockerr; /* any socket error is cached here */
unsigned short port; /* the remote port */
int type; /* the type of this connection (tcp/udp/raw) */
if(pack_off) {
/* will enter into the parse queue later */
c->parser(c, pack_off);
+ } else {
+ /* no contained message, queue and check against older stuff */
+ if(ebuf_put(&c->recvQ, &readbuf, len))
+ return;
+ if(eBufLength(&c->recvQ) > len) {
+ len = ebuf_get(&c->recvQ, &readbuf, BUFSIZE);
+ pack_off = c->packeter(c, &readbuf, len);
+ if(pack_off)
+ c->parser(c, pack_off);
+ }
}
}
if(rw) {
*/
#include "sockeng.h"
+#include "ebuf.h"
/* Maximum message length */
#define MAX_MSGLEN 512
#define EBUF_LARGE_BUFFER MAX_MSGLEN
#define EBUF_SMALL_BUFFER (MAX_MSGLEN / 2)
-/* Macros */
-#define eBufLength(s) ((s)->length)
-#define eBufClear(s) ebuf_delete((s), (s)->length)
-
-/* forward declaration */
-typedef struct _eBuffer eBuffer;
-typedef struct _eBufUser eBufUser;
-typedef struct _eBuf eBuf;
-typedef struct _eBufBlock eBufBlock;
-typedef struct _eBufUserBlock eBufUserBlock;
-
-struct _eBuf
-{
- int length;
- eBufUser *head, *tail;
-};
-
-struct _eBuffer
-{
- eBuffer *next;
- int shared;
- int bufsize;
- int refcount;
- char *end;
-};
-
-struct _eBufBlock
-{
- int num;
- eBuffer *bufs;
- eBufBlock *next;
-};
-
-struct _eBufUser
-{
- char *start;
- eBuffer *buf;
- eBufUser *next;
-};
-
-struct _eBufUserBlock
-{
- int num;
- eBufUser *users;
- eBufUserBlock *next;
-};
-
-
typedef struct _eBufConfig {
eBuffer *largeebuf_pool, *smallebuf_pool;
eBufUser *user_pool;
* we allocate an ebuffer with the data, and return it to the calling
* function via ptr
*/
-int ebuf_begin_share(const char *buffer, int len, void **ptr)
+eBuffer *ebuf_begin_share(const char *buffer, int len)
{
eBuffer *s;
len = MAX_MSGLEN;
s = ebuf_alloc(len);
- if(!s || len > s->bufsize)
- return ebuf_alloc_error();
+ if(!s || len > s->bufsize) {
+ ebuf_alloc_error();
+ return NULL;
+ }
memcpy(s->end, buffer, len);
s->end += len;
s->refcount = 0;
s->shared = 1;
- *ptr = (void *) s;
- return 0;
+ return s;
}
/* identify that this buffer has been associated to all references now */
-int ebuf_end_share(void *ptr)
+int ebuf_end_share(eBuffer *s)
{
- eBuffer *s = ptr;
-
s->shared = 0;
if(s->refcount == 0)
ebuf_free(s);
}
/* associate a given shared buffer with a queue */
-int ebuf_put_share(eBuf *sb, void *ptr)
+int ebuf_put_share(eBuf *sb, eBuffer *s)
{
eBufUser *user;
- eBuffer *s = ptr;
if(!s)
return -1;
}
/* create and place a buffer in the correct user location */
-int ebuf_put(eBuf *sb, const char *buffer, int len)
+int ebuf_put(eBuf *sb, char *buffer, int len)
{
eBufUser **user, *u;
int chunk;
return 0;
}
+/*
int ebuf_putiov(eBuf *sb, struct iovec *v, int count)
{
int i = 0, ret;
}
return 0;
}
+*/
int ebuf_delete(eBuf *sb, int len)
{
}
*/
+/* get an arbitrary length from the queue and put it in buffer */
int ebuf_get(eBuf *sb, char *buffer, int len)
{
eBufUser *user;
- int copied;
+ int copied = 0;
char *ptr, *max;
- if(ebuf_flush(sb) == 0)
- return 0;
-
- copied = 0;
for(user = sb->head; user && len; user = user->next) {
max = user->start + len;
if(max > user->buf->end)
max = user->buf->end;
- for(ptr = user->start; ptr < max && !IsEol(*ptr); )
+ ptr = user->start;
+ while(ptr < max)
*buffer++ = *ptr++;
copied += ptr - user->start;
len -= ptr - user->start;
- if(ptr < max) {
- *buffer = 0;
+ if(!len) {
+ *buffer = 0; /* null terminate.. */
+ /*
ebuf_delete(sb, copied);
ebuf_flush(sb);
+ */
return copied;
}
}