From 6ca781b8a38474ab428d5fcb3b489dfe3e974334 Mon Sep 17 00:00:00 2001 From: bustico Date: Fri, 21 Mar 2008 09:03:34 +0000 Subject: - numerous fixes - socket in non blocking mode (resolve some deadlock, and agent are immune to another agent beeing blocked) --- src/ivyfifo.c | 279 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 279 insertions(+) create mode 100644 src/ivyfifo.c (limited to 'src/ivyfifo.c') diff --git a/src/ivyfifo.c b/src/ivyfifo.c new file mode 100644 index 0000000..9bee644 --- /dev/null +++ b/src/ivyfifo.c @@ -0,0 +1,279 @@ +#include +#include +#include +#include +#include // DEBUG, pour printf +#include "ivyfifo.h" +#include "param.h" + + + +#define MIN(a, b) ((a) > (b) ? (b) : (a)) + + +static void IvyFifoRealloc(IvyFifoBuffer *f, unsigned int neededSize); + +static unsigned int IvyFifoGenericRead(IvyFifoBuffer *f, const int buf_size, + void (*func)(void*, void*, int), void* dest); + +static void IvyFifoDrain(IvyFifoBuffer *f, int size); + +/* static unsigned char IvyFifoPeek(IvyFifoBuffer *f, int offs); */ + + + +int IvyFifoInit(IvyFifoBuffer *f) +{ + f->wptr = f->rptr = + f->buffer = malloc(IVY_FIFO_ALLOC_SIZE); + f->end = f->buffer + IVY_FIFO_ALLOC_SIZE; + f->full = 0; + + if (!f->buffer) + return -1; + return 0; +} + +void IvyFifoFree (IvyFifoBuffer *f) +{ + free(f->buffer); + f->wptr = f->rptr = f->buffer = NULL; +} + + +IvyFifoBuffer* IvyFifoNew (void) +{ + IvyFifoBuffer* ifb = malloc (sizeof (IvyFifoBuffer)); + IvyFifoInit (ifb); + return (ifb); +} + +void IvyFifoDelete (IvyFifoBuffer *f) +{ + IvyFifoFree (f); + free (f); +} + + +unsigned int IvyFifoSize (const IvyFifoBuffer *f) +{ + return (f->end - f->buffer); +} + +unsigned int IvyFifoLength (const IvyFifoBuffer *f) +{ + long size = f->wptr - f->rptr; + if (size < 0) + size += f->end - f->buffer; + return size; +} + +unsigned int IvyFifoAvail(const IvyFifoBuffer *f) +{ + return (IvyFifoSize (f)- IvyFifoLength (f)); +} + +unsigned int IvyFifoRead (IvyFifoBuffer *f, char *buf, int buf_size) +{ + return IvyFifoGenericRead(f, buf_size, NULL, buf); +} + +void IvyFifoRealloc (IvyFifoBuffer *f, unsigned int new_size) +{ + unsigned int old_size= IvyFifoSize (f); + unsigned int alignedNewSize = ((new_size/IVY_FIFO_ALLOC_SIZE) +1) * IVY_FIFO_ALLOC_SIZE; + if (alignedNewSize > IVY_FIFO_MAX_ALLOC_SIZE) { + f->full = 1; + } else if (old_size < alignedNewSize) { + int len= IvyFifoLength(f); + IvyFifoBuffer f2; + + f2.wptr = f2.rptr = + f2.buffer = malloc(alignedNewSize); + f2.end = f2.buffer + alignedNewSize; + f2.full = 0; + + IvyFifoRead(f, f2.buffer, len); + f2.wptr += len; + free(f->buffer); + *f= f2; + } +} + +void IvyFifoWrite (IvyFifoBuffer *f, const char *buf, int size) +{ + if (size >= IvyFifoAvail (f)) { + IvyFifoRealloc(f, size + IvyFifoLength (f)); + } + if (f->full) { + return ; + } + do { + int len = MIN(f->end - f->wptr, size); + memcpy(f->wptr, buf, len); + f->wptr += len; + if (f->wptr >= f->end) + f->wptr = f->buffer; + buf += len; + size -= len; + } while (size > 0); +} + + +unsigned int IvyFifoGenericRead (IvyFifoBuffer *f, const int buf_size, void (*func)(void*, void*, int), void* dest) +{ + unsigned int bytesToRead, retV; + retV = bytesToRead = MIN(buf_size, IvyFifoLength(f)); + + do { + int len = MIN(f->end - f->rptr, bytesToRead); + if (func) { + func (dest, f->rptr, len); + } else { + memcpy(dest, f->rptr, len); + dest = (unsigned char*)dest + len; + } + IvyFifoDrain(f, len); + bytesToRead -= len; + } while (bytesToRead > 0); + return (retV); +} + + +unsigned int IvyFifoSendSocket (IvyFifoBuffer *f, const int fd) +{ + unsigned int maxLen, realLen; + + do { + maxLen = MIN ((f->end - f->rptr), IvyFifoLength(f)); + realLen = send (fd, f->rptr, maxLen, MSG_DONTWAIT); + IvyFifoDrain(f, realLen); + // printf ("DBG> maxLen=%d realLen=%d IvyFifoLength=%d\n", + // maxLen, realLen, IvyFifoLength(f)); + } while (IvyFifoLength(f) && (maxLen == realLen)); + + return (IvyFifoLength(f)); +} + + + +void IvyFifoDrain (IvyFifoBuffer *f, int size) +{ + f->rptr += size; + if (f->rptr >= f->end) + f->rptr -= f->end - f->buffer; + if (size > 0) { + f->full = 0; + } +} + +int IvyFifoIsFull (const IvyFifoBuffer *f) +{ + return (f->full); +} + +/* unsigned char IvyFifoPeek(IvyFifoBuffer *f, int offs) */ +/* { */ +/* unsigned char *ptr = f->rptr + offs; */ +/* if (ptr >= f->end) */ +/* ptr -= f->end - f->buffer; */ +/* return *ptr; */ +/* } */ + + +//#define TEST_UNITAIRE 1 +#ifdef TEST_UNITAIRE +int main (int argc, char**argv) +{ + if (1 == 2) { + IvyFifoBuffer ifb; + unsigned char toRead [4096]; + unsigned char toWrite [8192]; + int (i); + + for (i=0; i< sizeof (toRead); i++) { + toRead[i] = (char) (i%10)+48; + } + + + IvyFifoInit (&ifb); + IvyFifoWrite(&ifb, toRead, 4096); + printf ("DBG> fifo size=%u, length=%u\n", IvyFifoSize(&ifb), IvyFifoLength(&ifb)); + IvyFifoWrite(&ifb, toRead, 1024); + printf ("DBG> fifo size=%u, length=%u\n", IvyFifoSize(&ifb), IvyFifoLength(&ifb)); + unsigned int nbRead=IvyFifoRead(&ifb, toWrite, sizeof (toWrite)); + // int nbRead=IvyFifoRead(&ifb, toWrite, 1024); + printf ("DBG> ndRead=%u, fifo size=%u, length=%u\n", nbRead, IvyFifoSize(&ifb), IvyFifoLength(&ifb)); + } + + + { + IvyFifoBuffer ifb; + unsigned char toRead [8]; + unsigned char toWrite [16]; + unsigned int nbRead; + int (i); + + for (i=0; i< sizeof (toRead); i++) { + toRead[i] = (char) (i%10)+48; + } + + + IvyFifoInit (&ifb); + + + IvyFifoWrite(&ifb, toRead, 8); + printf ("DBG> fifo size=%u, length=%u\n", IvyFifoSize(&ifb), IvyFifoLength(&ifb)); + + nbRead=IvyFifoRead(&ifb, toWrite, 4); + toWrite[nbRead] = 0; + printf ("DBG> ndRead=%u, fifo size=%u, length=%u, buffer=%s\n", nbRead, IvyFifoSize(&ifb), + IvyFifoLength(&ifb), toWrite); + + IvyFifoWrite(&ifb, toRead, 8); + printf ("DBG> fifo size=%u, length=%u\n", IvyFifoSize(&ifb), IvyFifoLength(&ifb)); + + nbRead=IvyFifoRead(&ifb, toWrite, 8); + toWrite[nbRead] = 0; + printf ("DBG> ndRead=%u, fifo size=%u, length=%u, buffer=%s\n", nbRead, IvyFifoSize(&ifb), + IvyFifoLength(&ifb), toWrite); + + nbRead=IvyFifoRead(&ifb, toWrite, 8); + toWrite[nbRead] = 0; + printf ("DBG> ndRead=%u, fifo size=%u, length=%u, buffer=%s\n", nbRead, IvyFifoSize(&ifb), + IvyFifoLength(&ifb), toWrite); + + nbRead=IvyFifoRead(&ifb, toWrite, 8); + toWrite[nbRead] = 0; + printf ("DBG> ndRead=%u, fifo size=%u, length=%u, buffer=%s\n", nbRead, IvyFifoSize(&ifb), + IvyFifoLength(&ifb), toWrite); + + nbRead=IvyFifoRead(&ifb, toWrite, 4); + toWrite[nbRead] = 0; + printf ("DBG> ndRead=%u, fifo size=%u, length=%u, buffer=%s\n", nbRead, IvyFifoSize(&ifb), + IvyFifoLength(&ifb), toWrite); + + IvyFifoWrite(&ifb, toRead, 8); + printf ("DBG> fifo size=%u, length=%u\n", IvyFifoSize(&ifb), IvyFifoLength(&ifb)); + + nbRead=IvyFifoRead(&ifb, toWrite, 8); + toWrite[nbRead] = 0; + printf ("DBG> ndRead=%u, fifo size=%u, length=%u, buffer=%s\n", nbRead, IvyFifoSize(&ifb), + IvyFifoLength(&ifb), toWrite); + + nbRead=IvyFifoRead(&ifb, toWrite, 8); + toWrite[nbRead] = 0; + printf ("DBG> ndRead=%u, fifo size=%u, length=%u, buffer=%s\n", nbRead, IvyFifoSize(&ifb), + IvyFifoLength(&ifb), toWrite); + + nbRead=IvyFifoRead(&ifb, toWrite, 8); + toWrite[nbRead] = 0; + printf ("DBG> ndRead=%u, fifo size=%u, length=%u, buffer=%s\n", nbRead, IvyFifoSize(&ifb), + IvyFifoLength(&ifb), toWrite); + + } + + + return (0); +} +#endif // TEST_UNITAIRE -- cgit v1.1