From c2a2a15c126f4b88f75f6fbd98bc53076c00013b Mon Sep 17 00:00:00 2001 From: leitner Date: Fri, 24 Feb 2012 02:00:52 +0000 Subject: [PATCH] document the return value expected from the callback given to iob_write remove unused #include in iob_reset if iob_addfile_close fails, it now closes the fd if iob_addbuf_munmap fails, it now munmaps the buf if iob_addbuf_free fails, it now frees the buf some win32 cross-compile fixes for iarray --- array/iarray_allocate.c | 12 ++++++++++++ iarray.h | 8 ++++++++ io/iob_addbuf_free.c | 5 ++++- io/iob_addbuf_munmap.c | 4 ++-- io/iob_addfile_close.c | 5 ++++- io/iob_reset.c | 1 - io/iob_write.3 | 7 ++++++- 7 files changed, 36 insertions(+), 6 deletions(-) diff --git a/array/iarray_allocate.c b/array/iarray_allocate.c index 095b5b2..deab547 100644 --- a/array/iarray_allocate.c +++ b/array/iarray_allocate.c @@ -9,7 +9,11 @@ void* iarray_allocate(iarray* ia,size_t pos) { return ia->pages[y]+(pos%ia->elemperpage)*ia->elemsize; /* the case where ia->pages == NULL is implicit */ +#ifdef __MINGW32__ + EnterCriticalSection(&ia->cs); +#else pthread_mutex_lock(&ia->m); +#endif if (__unlikely(y >= ia->pagefence)) { char** np; @@ -37,11 +41,19 @@ void* iarray_allocate(iarray* ia,size_t pos) { * however */ if (__unlikely(ia->pages[y]==0 && (ia->pages[y]=malloc(ia->bytesperpage))==0)) { unlockandfail: +#ifdef __MINGW32__ + LeaveCriticalSection(&ia->cs); +#else pthread_mutex_unlock(&ia->m); +#endif return 0; } +#ifdef __MINGW32__ + LeaveCriticalSection(&ia->cs); +#else pthread_mutex_unlock(&ia->m); +#endif return ia->pages[y] + (pos%ia->elemperpage)*ia->elemsize; } diff --git a/iarray.h b/iarray.h index 2066858..0a76e65 100644 --- a/iarray.h +++ b/iarray.h @@ -6,7 +6,11 @@ #include "uint64.h" #include +#ifdef __MINGW32__ +#include +#else #include +#endif /* this is an indirect array; it only reallocs the indirect index, not * the whole array. The actual data does not move. So there is no need @@ -17,7 +21,11 @@ typedef struct { size_t elemsize,pagefence,elemperpage,bytesperpage; /* pagefence is the number of pages + 1, * i.e. the first out of bounds index in "pages" */ +#ifdef __MINGW32__ + CRITICAL_SECTION cs; +#else pthread_mutex_t m; +#endif } iarray; void iarray_init(iarray* ia,size_t elemsize); diff --git a/io/iob_addbuf_free.c b/io/iob_addbuf_free.c index c9a21d4..4eddff5 100644 --- a/io/iob_addbuf_free.c +++ b/io/iob_addbuf_free.c @@ -6,5 +6,8 @@ static void cleanup(struct iob_entry* x) { } int iob_addbuf_free(io_batch* b,const void* buf,uint64 n) { - return iob_addbuf_internal(b,buf,n,cleanup); + int r=iob_addbuf_internal(b,buf,n,cleanup); + if (r==0) + free((char*)buf); + return r; } diff --git a/io/iob_addbuf_munmap.c b/io/iob_addbuf_munmap.c index 86bd370..52a1acb 100644 --- a/io/iob_addbuf_munmap.c +++ b/io/iob_addbuf_munmap.c @@ -1,9 +1,9 @@ #include -#include +#include "mmap.h" #include "iob_internal.h" static void cleanup(struct iob_entry* x) { - munmap((char*)x->buf,x->offset+x->n); + mmap_unmap((char*)x->buf,x->offset+x->n); } int iob_addbuf_munmap(io_batch* b,const void* buf,uint64 n) { diff --git a/io/iob_addfile_close.c b/io/iob_addfile_close.c index 53541c9..bbce966 100644 --- a/io/iob_addfile_close.c +++ b/io/iob_addfile_close.c @@ -13,7 +13,10 @@ int iob_addfile_close(io_batch* b,int64 fd,uint64 off,uint64 n) { io_fd(fd); e=array_allocate(&b->b,sizeof(iob_entry), array_length(&b->b,sizeof(iob_entry))); - if (!e) return 0; + if (!e) { + io_close(fd); + return 0; + } e->type=FROMFILE; e->fd=fd; e->buf=0; diff --git a/io/iob_reset.c b/io/iob_reset.c index 0ccf241..192e6c3 100644 --- a/io/iob_reset.c +++ b/io/iob_reset.c @@ -1,5 +1,4 @@ #include -#include #include "byte.h" #include "iob_internal.h" diff --git a/io/iob_write.3 b/io/iob_write.3 index 62a3639..8b26727 100644 --- a/io/iob_write.3 +++ b/io/iob_write.3 @@ -23,9 +23,14 @@ error (for example "connection reset by peer"). The normal usage pattern is using io_wait to know when a descriptor is writable, and then calling iob_write until it returns 0, -1 or -3. -If it returns 0, terminate the loop (everything was written OK). If it +If iob_write returns 0, terminate the loop (everything was written OK). If it returns -1, call io_wait again. If it returned -3, signal an error. +The callback is supposed to behave like write(2), i.e. return the number +of bytes written, 0 for EOF, -1 for error (iob_write will return -3 +then). Return -1 with errno==EAGAIN if using non-blocking I/O when we +need to wait for the next write event. iob_write will then return -1. + .SH NOTE iob_write will continue to call your callback until it returns an error. So if you are in a state machine, for example a web server using this