further Windoze support (test/io5.c works, gatling still doesn't)
This is just to get gatling to work, I may remove it again after that.
This commit is contained in:
parent
f65398ff2e
commit
c1c50c7dbd
3
CHANGES
3
CHANGES
@ -4,6 +4,9 @@
|
|||||||
allocates space, it also needs to be in the initialized space.
|
allocates space, it also needs to be in the initialized space.
|
||||||
add -D_REENTRANT to CFLAGS so libowfat can be used in multi-threaded
|
add -D_REENTRANT to CFLAGS so libowfat can be used in multi-threaded
|
||||||
programs
|
programs
|
||||||
|
further Windoze support (test/io5.c works, gatling still doesn't)
|
||||||
|
This is just to get gatling to work, I may remove it again after
|
||||||
|
that.
|
||||||
|
|
||||||
0.24:
|
0.24:
|
||||||
fix scan_to_sa (Tim Lorenz)
|
fix scan_to_sa (Tim Lorenz)
|
||||||
|
10
GNUmakefile
10
GNUmakefile
@ -14,7 +14,9 @@ buffer.a mmap.a taia.a tai.a dns.a case.a mult.a array.a io.a textcode.a
|
|||||||
|
|
||||||
all: t $(LIBS) libowfat.a libsocket
|
all: t $(LIBS) libowfat.a libsocket
|
||||||
|
|
||||||
CC=gcc
|
CROSS=
|
||||||
|
#CROSS=i686-mingw-
|
||||||
|
CC=$(CROSS)gcc
|
||||||
CFLAGS=-pipe -W -Wall -O2 -fomit-frame-pointer
|
CFLAGS=-pipe -W -Wall -O2 -fomit-frame-pointer
|
||||||
#CFLAGS=-pipe -Os -march=pentiumpro -mcpu=pentiumpro -fomit-frame-pointer -fschedule-insns2 -Wall
|
#CFLAGS=-pipe -Os -march=pentiumpro -mcpu=pentiumpro -fomit-frame-pointer -fschedule-insns2 -Wall
|
||||||
|
|
||||||
@ -126,8 +128,8 @@ $(TAIA_OBJS) $(TAI_OBJS) $(CASE_OBJS) $(ARRAY_OBJS) $(MULT_OBJS) \
|
|||||||
$(IO_OBJS)
|
$(IO_OBJS)
|
||||||
|
|
||||||
libowfat.a: $(ALL_OBJS)
|
libowfat.a: $(ALL_OBJS)
|
||||||
ar cr $@ $(ALL_OBJS)
|
$(CROSS)ar cr $@ $(ALL_OBJS)
|
||||||
-ranlib $@
|
-$(CROSS)ranlib $@
|
||||||
|
|
||||||
CFLAGS+=-I.
|
CFLAGS+=-I.
|
||||||
|
|
||||||
@ -290,3 +292,5 @@ Makefile: GNUmakefile dep libdep
|
|||||||
-e 's/^CURNAME=.*/'CURNAME=$(CURNAME)/ \
|
-e 's/^CURNAME=.*/'CURNAME=$(CURNAME)/ \
|
||||||
-e 's/ Makefile//' < GNUmakefile >> $@
|
-e 's/ Makefile//' < GNUmakefile >> $@
|
||||||
|
|
||||||
|
windoze:
|
||||||
|
$(MAKE) DIET= CROSS=i686-mingw32-
|
||||||
|
@ -3,6 +3,10 @@
|
|||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include "io_internal.h"
|
#include "io_internal.h"
|
||||||
|
|
||||||
|
#ifdef __MINGW32__
|
||||||
|
#include <stdio.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
int64 io_canread() {
|
int64 io_canread() {
|
||||||
io_entry* e;
|
io_entry* e;
|
||||||
if (first_readable==-1)
|
if (first_readable==-1)
|
||||||
@ -26,7 +30,18 @@ int64 io_canread() {
|
|||||||
first_readable=e->next_read;
|
first_readable=e->next_read;
|
||||||
e->next_read=-1;
|
e->next_read=-1;
|
||||||
debug_printf(("io_canread: dequeue %lld from normal read queue (next is %ld)\n",r,first_readable));
|
debug_printf(("io_canread: dequeue %lld from normal read queue (next is %ld)\n",r,first_readable));
|
||||||
if (e->wantread && e->canread) {
|
|
||||||
|
#ifdef __MINGW32__
|
||||||
|
// printf("event on %d: wr %d rq %d aq %d\n",(int)r,e->wantread,e->readqueued,e->acceptqueued);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (e->wantread &&
|
||||||
|
#ifdef __MINGW32__
|
||||||
|
(e->canread || e->acceptqueued==1 || e->readqueued==1)
|
||||||
|
#else
|
||||||
|
e->canread
|
||||||
|
#endif
|
||||||
|
) {
|
||||||
#ifdef HAVE_SIGIO
|
#ifdef HAVE_SIGIO
|
||||||
e->next_read=alt_firstread;
|
e->next_read=alt_firstread;
|
||||||
alt_firstread=r;
|
alt_firstread=r;
|
||||||
|
@ -26,7 +26,13 @@ int64 io_canwrite() {
|
|||||||
first_writeable=e->next_write;
|
first_writeable=e->next_write;
|
||||||
e->next_write=-1;
|
e->next_write=-1;
|
||||||
debug_printf(("io_canwrite: dequeue %lld from normal write queue (next is %ld)\n",r,first_writeable));
|
debug_printf(("io_canwrite: dequeue %lld from normal write queue (next is %ld)\n",r,first_writeable));
|
||||||
if (e->wantwrite && e->canwrite) {
|
if (e->wantwrite &&
|
||||||
|
#ifdef __MINGW32__
|
||||||
|
(e->canwrite || e->sendfilequeued==1)
|
||||||
|
#else
|
||||||
|
e->canwrite
|
||||||
|
#endif
|
||||||
|
) {
|
||||||
#ifdef HAVE_SIGIO
|
#ifdef HAVE_SIGIO
|
||||||
e->next_write=alt_firstwrite;
|
e->next_write=alt_firstwrite;
|
||||||
alt_firstwrite=r;
|
alt_firstwrite=r;
|
||||||
|
19
io/io_fd.c
19
io/io_fd.c
@ -50,8 +50,10 @@ int io_fd(int64 d) {
|
|||||||
long r;
|
long r;
|
||||||
if ((r=fcntl(d,F_GETFL,0)) == -1)
|
if ((r=fcntl(d,F_GETFL,0)) == -1)
|
||||||
return 0; /* file descriptor not open */
|
return 0; /* file descriptor not open */
|
||||||
|
printf("io_fd(%d)\n",(int)d);
|
||||||
#endif
|
#endif
|
||||||
if (!(e=array_allocate(&io_fds,sizeof(io_entry),d))) return 0;
|
if (!(e=array_allocate(&io_fds,sizeof(io_entry),d))) return 0;
|
||||||
|
if (e->inuse) return 1;
|
||||||
byte_zero(e,sizeof(io_entry));
|
byte_zero(e,sizeof(io_entry));
|
||||||
e->inuse=1;
|
e->inuse=1;
|
||||||
#ifdef __MINGW32__
|
#ifdef __MINGW32__
|
||||||
@ -90,8 +92,13 @@ int io_fd(int64 d) {
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#ifdef __MINGW32__
|
#ifdef __MINGW32__
|
||||||
io_comport=CreateIoCompletionPort(INVALID_HANDLE_VALUE,NULL,0,1);
|
io_comport=CreateIoCompletionPort(INVALID_HANDLE_VALUE,NULL,0,0);
|
||||||
if (io_comport) io_waitmode=COMPLETIONPORT;
|
if (io_comport) {
|
||||||
|
io_waitmode=COMPLETIONPORT;
|
||||||
|
} else {
|
||||||
|
errno=EINVAL;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
#if defined(HAVE_SIGIO)
|
#if defined(HAVE_SIGIO)
|
||||||
@ -103,6 +110,14 @@ int io_fd(int64 d) {
|
|||||||
#endif
|
#endif
|
||||||
fcntl(d,F_SETFL,fcntl(d,F_GETFL)|O_NONBLOCK|O_ASYNC);
|
fcntl(d,F_SETFL,fcntl(d,F_GETFL)|O_NONBLOCK|O_ASYNC);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
#ifdef __MINGW32__
|
||||||
|
if (io_comport) {
|
||||||
|
if (CreateIoCompletionPort((HANDLE)d,io_comport,(ULONG_PTR)d,0)==0) {
|
||||||
|
errno=EBADF;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -6,8 +6,8 @@
|
|||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#else
|
#else
|
||||||
#include <sys/mman.h>
|
#include <sys/mman.h>
|
||||||
#include <errno.h>
|
|
||||||
#endif
|
#endif
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
#define BUFSIZE 16384
|
#define BUFSIZE 16384
|
||||||
|
|
||||||
|
@ -112,6 +112,38 @@ int64 io_sendfile(int64 s,int64 fd,uint64 off,uint64 n) {
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#elif defined(__MINGW32__)
|
||||||
|
|
||||||
|
#include <windows.h>
|
||||||
|
#include <mswsock.h>
|
||||||
|
|
||||||
|
int64 io_sendfile(int64 out,int64 in,uint64 off,uint64 bytes) {
|
||||||
|
io_entry* e=array_get(&io_fds,sizeof(io_entry),out);
|
||||||
|
if (!e) { errno=EBADF; return -3; }
|
||||||
|
if (e->sendfilequeued==1) {
|
||||||
|
/* we called TransmitFile, and it returned. */
|
||||||
|
e->sendfilequeued=2;
|
||||||
|
errno=e->errorcode;
|
||||||
|
if (e->bytes_written==-1) return -1;
|
||||||
|
if (e->bytes_written!=bytes) { /* we wrote less than caller wanted to write */
|
||||||
|
e->sendfilequeued=1; /* so queue next request */
|
||||||
|
off+=e->bytes_written;
|
||||||
|
bytes-=e->bytes_written;
|
||||||
|
e->os.Offset=off;
|
||||||
|
e->os.OffsetHigh=(off>>32);
|
||||||
|
TransmitFile(out,(HANDLE)in,bytes>0xffff?0xffff:bytes,0,&e->os,0,TF_USE_KERNEL_APC);
|
||||||
|
}
|
||||||
|
return e->bytes_written;
|
||||||
|
} else {
|
||||||
|
e->sendfilequeued=1;
|
||||||
|
e->os.Offset=off;
|
||||||
|
e->os.OffsetHigh=(off>>32);
|
||||||
|
/* we always write at most 64k, so timeout handling is possible */
|
||||||
|
if (!TransmitFile(out,(HANDLE)in,bytes>0xffff?0xffff:bytes,0,&e->os,0,TF_USE_KERNEL_APC))
|
||||||
|
return -3;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
#include <iob.h>
|
#include <iob.h>
|
||||||
|
@ -1,8 +1,74 @@
|
|||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
|
#ifdef __MINGW32__
|
||||||
|
#include <windows.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#else
|
||||||
#include <poll.h>
|
#include <poll.h>
|
||||||
|
#endif
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include "io_internal.h"
|
#include "io_internal.h"
|
||||||
|
#include "byte.h"
|
||||||
|
|
||||||
|
#ifdef __MINGW32__
|
||||||
|
/* In Windows, I/O works differently. */
|
||||||
|
/* Instead of calling read until it says EAGAIN, you call read in
|
||||||
|
* overlapping mode, and then wait for it to finish.
|
||||||
|
* We map this to our API by having the first call to io_tryread always
|
||||||
|
* return EAGAIN, wait for the I/O completion port to tell us the read
|
||||||
|
* is finished, and then return the data we actually read the next time
|
||||||
|
* we are called. */
|
||||||
|
|
||||||
|
int64 io_tryread(int64 d,char* buf,int64 len) {
|
||||||
|
io_entry* e=array_get(&io_fds,sizeof(io_entry),d);
|
||||||
|
if (!e) { errno=EBADF; return -3; }
|
||||||
|
if (len<0) { errno=EINVAL; return -3; }
|
||||||
|
if (e->readqueued==2) {
|
||||||
|
int x=e->bytes_read;
|
||||||
|
if (e->errorcode) {
|
||||||
|
errno=e->errorcode;
|
||||||
|
e->canread=0;
|
||||||
|
return -3;
|
||||||
|
}
|
||||||
|
if (x>len) x=len;
|
||||||
|
if (x) {
|
||||||
|
byte_copy(buf,x,e->inbuf);
|
||||||
|
byte_copy(e->inbuf,e->bytes_read-x,e->inbuf+x);
|
||||||
|
e->bytes_read-=x;
|
||||||
|
}
|
||||||
|
if (!e->bytes_read) {
|
||||||
|
e->canread=0;
|
||||||
|
if (len>x) {
|
||||||
|
/* queue next read */
|
||||||
|
if (len>sizeof(e->inbuf)) len=sizeof(e->inbuf);
|
||||||
|
if (ReadFile((HANDLE)d,e->inbuf,len,0,&e->or)) {
|
||||||
|
e->canread=1;
|
||||||
|
e->readqueued=2;
|
||||||
|
e->next_write=first_writeable;
|
||||||
|
first_writeable=d;
|
||||||
|
} else if ((e->errorcode=GetLastError())==ERROR_IO_PENDING) {
|
||||||
|
e->readqueued=1;
|
||||||
|
e->errorcode=0;
|
||||||
|
} else {
|
||||||
|
e->canread=1;
|
||||||
|
e->readqueued=2;
|
||||||
|
e->next_write=first_writeable;
|
||||||
|
first_writeable=d;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
if (!e->readqueued) {
|
||||||
|
if (len>sizeof(e->inbuf)) len=sizeof(e->inbuf);
|
||||||
|
if (ReadFile((HANDLE)d,e->inbuf,len,0,&e->or))
|
||||||
|
e->readqueued=1;
|
||||||
|
}
|
||||||
|
errno=EAGAIN;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
int64 io_tryread(int64 d,char* buf,int64 len) {
|
int64 io_tryread(int64 d,char* buf,int64 len) {
|
||||||
long r;
|
long r;
|
||||||
@ -48,3 +114,5 @@ int64 io_tryread(int64 d,char* buf,int64 len) {
|
|||||||
}
|
}
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
@ -1,9 +1,63 @@
|
|||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
|
#ifdef __MINGW32__
|
||||||
|
#include <windows.h>
|
||||||
|
#else
|
||||||
#include <poll.h>
|
#include <poll.h>
|
||||||
|
#endif
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include "io_internal.h"
|
#include "io_internal.h"
|
||||||
|
|
||||||
|
#ifdef __MINGW32__
|
||||||
|
/* All the Unix trickery is unsupported on Windows. Instead, one is
|
||||||
|
* supposed to do the whole write in overlapping mode and then get
|
||||||
|
* notified via an I/O completion port when it's done. */
|
||||||
|
|
||||||
|
/* So we assume io_trywrite is not used so much and do the overlapping
|
||||||
|
* stuff on I/O batches. */
|
||||||
|
|
||||||
|
int64 io_trywrite(int64 d,const char* buf,int64 len) {
|
||||||
|
io_entry* e=array_get(&io_fds,sizeof(io_entry),d);
|
||||||
|
int r;
|
||||||
|
if (!e) { errno=EBADF; return -3; }
|
||||||
|
if (!e->nonblock) {
|
||||||
|
DWORD written;
|
||||||
|
if (WriteFile((HANDLE)d,buf,len,&written,0))
|
||||||
|
return written;
|
||||||
|
else
|
||||||
|
return winsock2errno(-3);
|
||||||
|
} else {
|
||||||
|
if (e->writequeued) {
|
||||||
|
errno=EAGAIN;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (e->canwrite) {
|
||||||
|
e->canwrite=0;
|
||||||
|
e->next_write=-1;
|
||||||
|
if (e->errorcode) {
|
||||||
|
errno=winsock2errno(e->errorcode);
|
||||||
|
return -3;
|
||||||
|
}
|
||||||
|
return e->bytes_written;
|
||||||
|
} else {
|
||||||
|
if (WriteFile((HANDLE)d,buf,len,&e->errorcode,&e->ow))
|
||||||
|
return e->errorcode; /* should not happen */
|
||||||
|
else if (GetLastError()==ERROR_IO_PENDING) {
|
||||||
|
e->writequeued=1;
|
||||||
|
errno=EAGAIN;
|
||||||
|
e->errorcode=0;
|
||||||
|
return -1;
|
||||||
|
} else {
|
||||||
|
winsock2errno(-1);
|
||||||
|
e->errorcode=errno;
|
||||||
|
return -3;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
int64 io_trywrite(int64 d,const char* buf,int64 len) {
|
int64 io_trywrite(int64 d,const char* buf,int64 len) {
|
||||||
long r;
|
long r;
|
||||||
struct itimerval old,new;
|
struct itimerval old,new;
|
||||||
@ -49,3 +103,5 @@ int64 io_trywrite(int64 d,const char* buf,int64 len) {
|
|||||||
}
|
}
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
@ -1,8 +1,34 @@
|
|||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
#ifdef __MINGW32__
|
||||||
|
#include <windows.h>
|
||||||
|
#else
|
||||||
#include <poll.h>
|
#include <poll.h>
|
||||||
|
#endif
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include "io_internal.h"
|
#include "io_internal.h"
|
||||||
|
|
||||||
|
#ifdef __MINGW32__
|
||||||
|
|
||||||
|
int64 io_waitread(int64 d,char* buf,int64 len) {
|
||||||
|
long r;
|
||||||
|
io_entry* e=array_get(&io_fds,sizeof(io_entry),d);
|
||||||
|
if (!e) { errno=EBADF; return -3; }
|
||||||
|
if (e->nonblock) {
|
||||||
|
unsigned long i=0;
|
||||||
|
ioctlsocket(d, FIONBIO, &i);
|
||||||
|
}
|
||||||
|
r=read(d,buf,len);
|
||||||
|
if (e->nonblock) {
|
||||||
|
unsigned long i=1;
|
||||||
|
ioctlsocket(d, FIONBIO, &i);
|
||||||
|
}
|
||||||
|
if (r==-1)
|
||||||
|
r=-3;
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
int64 io_waitread(int64 d,char* buf,int64 len) {
|
int64 io_waitread(int64 d,char* buf,int64 len) {
|
||||||
long r;
|
long r;
|
||||||
struct pollfd p;
|
struct pollfd p;
|
||||||
@ -25,3 +51,5 @@ again:
|
|||||||
}
|
}
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
@ -8,7 +8,11 @@
|
|||||||
#endif
|
#endif
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
|
#ifdef __MINGW32__
|
||||||
|
#include <windows.h>
|
||||||
|
#else
|
||||||
#include <poll.h>
|
#include <poll.h>
|
||||||
|
#endif
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#ifdef HAVE_KQUEUE
|
#ifdef HAVE_KQUEUE
|
||||||
#include <sys/event.h>
|
#include <sys/event.h>
|
||||||
@ -28,7 +32,9 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
int64 io_waituntil2(int64 milliseconds) {
|
int64 io_waituntil2(int64 milliseconds) {
|
||||||
|
#ifndef __MINGW32__
|
||||||
struct pollfd* p;
|
struct pollfd* p;
|
||||||
|
#endif
|
||||||
long i,j,r;
|
long i,j,r;
|
||||||
if (!io_wanted_fds) return 0;
|
if (!io_wanted_fds) return 0;
|
||||||
#ifdef HAVE_EPOLL
|
#ifdef HAVE_EPOLL
|
||||||
@ -195,6 +201,78 @@ int64 io_waituntil2(int64 milliseconds) {
|
|||||||
}
|
}
|
||||||
dopoll:
|
dopoll:
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef __MINGW32__
|
||||||
|
DWORD numberofbytes;
|
||||||
|
ULONG_PTR x;
|
||||||
|
LPOVERLAPPED o;
|
||||||
|
if (first_readable!=-1 || first_writeable!=-1) return;
|
||||||
|
if (GetQueuedCompletionStatus(io_comport,&numberofbytes,&x,&o,milliseconds==-1?milliseconds:INFINITE)) {
|
||||||
|
io_entry* e=array_get(&io_fds,sizeof(io_entry),x);
|
||||||
|
if (!e) return 0;
|
||||||
|
e->errorcode=0;
|
||||||
|
if (o==&e->or && e->readqueued==1) {
|
||||||
|
e->readqueued=2;
|
||||||
|
e->canread=1;
|
||||||
|
e->bytes_read=numberofbytes;
|
||||||
|
e->next_read=first_readable;
|
||||||
|
first_readable=x;
|
||||||
|
// printf("read %lu bytes on fd %lu: %p\n",numberofbytes,x,e);
|
||||||
|
} else if (o==&e->ow && e->writequeued==1) {
|
||||||
|
e->writequeued=2;
|
||||||
|
e->canwrite=1;
|
||||||
|
e->bytes_written=numberofbytes;
|
||||||
|
e->next_write=first_writeable;
|
||||||
|
first_writeable=x;
|
||||||
|
} else if (o==&e->or && e->acceptqueued==1) {
|
||||||
|
e->acceptqueued=2;
|
||||||
|
e->canread=1;
|
||||||
|
e->next_read=first_readable;
|
||||||
|
first_readable=x;
|
||||||
|
} else if (o==&e->ow && e->connectqueued==1) {
|
||||||
|
e->connectqueued=2;
|
||||||
|
e->canwrite=1;
|
||||||
|
e->next_write=first_writeable;
|
||||||
|
first_writeable=x;
|
||||||
|
} else if (o==&e->os && e->sendfilequeued==1) {
|
||||||
|
e->sendfilequeued=2;
|
||||||
|
e->canwrite=1;
|
||||||
|
e->bytes_written=numberofbytes;
|
||||||
|
e->next_write=first_writeable;
|
||||||
|
first_writeable=x;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
} else {
|
||||||
|
/* either the overlapped I/O request failed or we timed out */
|
||||||
|
DWORD err;
|
||||||
|
io_entry* e;
|
||||||
|
if (!o) return 0; /* timeout */
|
||||||
|
/* we got a completion packet for a failed I/O operation */
|
||||||
|
err=GetLastError();
|
||||||
|
if (err==WAIT_TIMEOUT) return 0; /* or maybe not */
|
||||||
|
e=array_get(&io_fds,sizeof(io_entry),x);
|
||||||
|
if (!e) return 0; /* WTF?! */
|
||||||
|
e->errorcode=err;
|
||||||
|
if (o==&e->or && (e->readqueued || e->acceptqueued)) {
|
||||||
|
if (e->readqueued) e->readqueued=2; else
|
||||||
|
if (e->acceptqueued) e->acceptqueued=2;
|
||||||
|
e->canread=1;
|
||||||
|
e->bytes_read=-1;
|
||||||
|
e->next_read=first_readable;
|
||||||
|
first_readable=x;
|
||||||
|
} else if ((o==&e->ow || o==&e->os) &&
|
||||||
|
(e->writequeued || e->connectqueued || e->sendfilequeued)) {
|
||||||
|
if (o==&e->ow) {
|
||||||
|
if (e->writequeued) e->writequeued=2; else
|
||||||
|
if (e->connectqueued) e->connectqueued=2;
|
||||||
|
} else if (o==&e->os) e->sendfilequeued=2;
|
||||||
|
e->canwrite=1;
|
||||||
|
e->bytes_written=-1;
|
||||||
|
e->next_write=first_writeable;
|
||||||
|
first_writeable=x;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
#else
|
||||||
for (i=r=0; i<array_length(&io_fds,sizeof(io_entry)); ++i) {
|
for (i=r=0; i<array_length(&io_fds,sizeof(io_entry)); ++i) {
|
||||||
io_entry* e=array_get(&io_fds,sizeof(io_entry),i);
|
io_entry* e=array_get(&io_fds,sizeof(io_entry),i);
|
||||||
if (!e) return -1;
|
if (!e) return -1;
|
||||||
@ -231,4 +309,5 @@ dopoll:
|
|||||||
p++;
|
p++;
|
||||||
}
|
}
|
||||||
return i;
|
return i;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
@ -1,8 +1,34 @@
|
|||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
#ifdef __MINGW32__
|
||||||
|
#include <windows.h>
|
||||||
|
#else
|
||||||
#include <poll.h>
|
#include <poll.h>
|
||||||
|
#endif
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include "io_internal.h"
|
#include "io_internal.h"
|
||||||
|
|
||||||
|
#ifdef __MINGW32__
|
||||||
|
|
||||||
|
int64 io_waitwrite(int64 d,const char* buf,int64 len) {
|
||||||
|
long r;
|
||||||
|
io_entry* e=array_get(&io_fds,sizeof(io_entry),d);
|
||||||
|
if (!e) { errno=EBADF; return -3; }
|
||||||
|
if (e->nonblock) {
|
||||||
|
unsigned long i=0;
|
||||||
|
ioctlsocket(d, FIONBIO, &i);
|
||||||
|
}
|
||||||
|
r=write(d,buf,len);
|
||||||
|
if (e->nonblock) {
|
||||||
|
unsigned long i=1;
|
||||||
|
ioctlsocket(d, FIONBIO, &i);
|
||||||
|
}
|
||||||
|
if (r==-1)
|
||||||
|
r=-3;
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
int64 io_waitwrite(int64 d,const char* buf,int64 len) {
|
int64 io_waitwrite(int64 d,const char* buf,int64 len) {
|
||||||
long r;
|
long r;
|
||||||
struct pollfd p;
|
struct pollfd p;
|
||||||
@ -26,3 +52,5 @@ again:
|
|||||||
}
|
}
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
@ -19,6 +19,9 @@
|
|||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
#include <sys/devpoll.h>
|
#include <sys/devpoll.h>
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef __MINGW32__
|
||||||
|
#include <mswsock.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
void io_wantread(int64 d) {
|
void io_wantread(int64 d) {
|
||||||
int newfd;
|
int newfd;
|
||||||
@ -69,6 +72,34 @@ void io_wantread(int64 d) {
|
|||||||
first_readable=d;
|
first_readable=d;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
#ifdef __MINGW32__
|
||||||
|
if (e->listened) {
|
||||||
|
if (e->next_accept==0) e->next_accept=socket(AF_INET,SOCK_STREAM,0);
|
||||||
|
if (e->next_accept!=-1) {
|
||||||
|
AcceptEx(d,e->next_accept,e->inbuf,0,200,200,&e->errorcode,&e->or);
|
||||||
|
e->acceptqueued=1;
|
||||||
|
}
|
||||||
|
} else if (!e->wantread) {
|
||||||
|
if (ReadFile((HANDLE)d,e->inbuf,sizeof(e->inbuf),&e->errorcode,&e->or)) {
|
||||||
|
queueread:
|
||||||
|
/* had something to read immediately. Damn! */
|
||||||
|
e->readqueued=0;
|
||||||
|
e->canread=1;
|
||||||
|
e->bytes_read=e->errorcode;
|
||||||
|
e->errorcode=0;
|
||||||
|
e->next_read=first_readable;
|
||||||
|
first_readable=d;
|
||||||
|
return;
|
||||||
|
} else if (GetLastError()==ERROR_IO_PENDING)
|
||||||
|
e->readqueued=1;
|
||||||
|
else
|
||||||
|
goto queueread;
|
||||||
|
#if 0
|
||||||
|
e->next_read=first_readable;
|
||||||
|
first_readable=d;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
e->wantread=1;
|
e->wantread=1;
|
||||||
}
|
}
|
||||||
|
@ -69,6 +69,12 @@ void io_wantwrite(int64 d) {
|
|||||||
first_writeable=d;
|
first_writeable=d;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
#ifdef __MINGW32__
|
||||||
|
if (!e->wantwrite) {
|
||||||
|
e->next_write=first_writeable;
|
||||||
|
first_writeable=d;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
e->wantwrite=1;
|
e->wantwrite=1;
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,15 @@
|
|||||||
#include "iob_internal.h"
|
#include "iob_internal.h"
|
||||||
|
|
||||||
|
#ifdef __MINGW32__
|
||||||
|
|
||||||
|
/* not supported */
|
||||||
|
void iob_internal(io_batch* b,uint64 bytes) {
|
||||||
|
(void)b;
|
||||||
|
(void)bytes;
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/mman.h>
|
#include <sys/mman.h>
|
||||||
@ -40,3 +51,5 @@ void iob_prefetch(io_batch* b,uint64 bytes) {
|
|||||||
}
|
}
|
||||||
(void)x;
|
(void)x;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
@ -1,3 +1,82 @@
|
|||||||
|
#ifdef __MINGW32__
|
||||||
|
|
||||||
|
#include <windows.h>
|
||||||
|
#include <mswsock.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include "io_internal.h"
|
||||||
|
#include "iob_internal.h"
|
||||||
|
|
||||||
|
int64 iob_send(int64 s,io_batch* b) {
|
||||||
|
/* Windows has a sendfile called TransmitFile, which can send one
|
||||||
|
* header and one trailer buffer. */
|
||||||
|
iob_entry* x,* last;
|
||||||
|
io_entry* e;
|
||||||
|
int64 sent;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (b->bytesleft==0) return 0;
|
||||||
|
sent=-1;
|
||||||
|
e=array_get(&io_fds,sizeof(io_entry),s);
|
||||||
|
if (!e) { errno=EBADF; return -3; }
|
||||||
|
if (!(x=array_get(&b->b,sizeof(iob_entry),b->next)))
|
||||||
|
return -3; /* can't happen error */
|
||||||
|
last=(iob_entry*)(((char*)array_start(&b->b))+array_bytes(&b->b));
|
||||||
|
|
||||||
|
if (e->canwrite || e->sendfilequeued==1) {
|
||||||
|
/* An overlapping write finished. Reap the result. */
|
||||||
|
if (e->bytes_written==-1) return -3;
|
||||||
|
if (e->bytes_written<x->n) {
|
||||||
|
sent=e->bytes_written;
|
||||||
|
if (x->n < e->bytes_written) {
|
||||||
|
e->bytes_written-=x->n;
|
||||||
|
x->n=0;
|
||||||
|
++x;
|
||||||
|
}
|
||||||
|
x->n -= e->bytes_written;
|
||||||
|
x->offset += e->bytes_written;
|
||||||
|
b->bytesleft -= e->bytes_written;
|
||||||
|
}
|
||||||
|
e->canwrite=0; e->sendfilequeued=0;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i=0; x+i<last; ++i)
|
||||||
|
if (x[i].n) break;
|
||||||
|
|
||||||
|
if (x[i].type==FROMBUF || x[i].type==FROMBUF_FREE) {
|
||||||
|
if (x+i+1 < last &&
|
||||||
|
(x[i+1].type==FROMFILE || x[i+1].type==FROMFILE_CLOSE)) {
|
||||||
|
TRANSMIT_FILE_BUFFERS tfb;
|
||||||
|
e->sendfilequeued=1;
|
||||||
|
memset(&tfb,0,sizeof(tfb));
|
||||||
|
memset(&e[i].os,0,sizeof(e[i].os));
|
||||||
|
e[i].os.Offset=x[i].offset;
|
||||||
|
e[i].os.OffsetHigh=(x[i].offset>>32);
|
||||||
|
if (!TransmitFile(s,(HANDLE)x[i].fd,
|
||||||
|
x[i].n+tfb.HeadLength>0xffff?0xffff:x[i].n,
|
||||||
|
0,&e[i].os,&tfb,TF_USE_KERNEL_APC))
|
||||||
|
return -3;
|
||||||
|
return sent;
|
||||||
|
} else {
|
||||||
|
e->writequeued=1;
|
||||||
|
if (!WriteFile(s,x[i].buf+x[i].offset,x[i].n,0,&e->ow))
|
||||||
|
return -3;
|
||||||
|
return sent;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
e->sendfilequeued=1;
|
||||||
|
memset(&e[i].os,0,sizeof(e[i].os));
|
||||||
|
e[i].os.Offset=x[i].offset;
|
||||||
|
e[i].os.OffsetHigh=(x[i].offset>>32);
|
||||||
|
if (!TransmitFile(s,(HANDLE)x[i].fd,
|
||||||
|
x[i].n>0xffff?0xffff:x[i].n,
|
||||||
|
0,&e[i].os,0,TF_USE_KERNEL_APC))
|
||||||
|
return -3;
|
||||||
|
return sent;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
#include "havebsdsf.h"
|
#include "havebsdsf.h"
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
@ -132,3 +211,5 @@ eagain:
|
|||||||
abort:
|
abort:
|
||||||
return total;
|
return total;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
@ -1,5 +1,9 @@
|
|||||||
#include "io.h"
|
#include "io.h"
|
||||||
#include "array.h"
|
#include "array.h"
|
||||||
|
#ifdef __MINGW32__
|
||||||
|
#include "socket.h"
|
||||||
|
extern HANDLE io_comport;
|
||||||
|
#else
|
||||||
#include "haveepoll.h"
|
#include "haveepoll.h"
|
||||||
#include "havekqueue.h"
|
#include "havekqueue.h"
|
||||||
#include "havedevpoll.h"
|
#include "havedevpoll.h"
|
||||||
@ -8,10 +12,6 @@
|
|||||||
#define _GNU_SOURCE
|
#define _GNU_SOURCE
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef __MINGW32__
|
|
||||||
#include "socket.h"
|
|
||||||
extern HANDLE io_comport;
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
@ -22,6 +22,14 @@ typedef struct {
|
|||||||
unsigned int canwrite:1;
|
unsigned int canwrite:1;
|
||||||
unsigned int nonblock:1;
|
unsigned int nonblock:1;
|
||||||
unsigned int inuse:1;
|
unsigned int inuse:1;
|
||||||
|
#ifdef __MINGW32__
|
||||||
|
unsigned int readqueued:2;
|
||||||
|
unsigned int writequeued:2;
|
||||||
|
unsigned int acceptqueued:2;
|
||||||
|
unsigned int connectqueued:2;
|
||||||
|
unsigned int sendfilequeued:2;
|
||||||
|
unsigned int listened:1;
|
||||||
|
#endif
|
||||||
long next_read;
|
long next_read;
|
||||||
long next_write;
|
long next_write;
|
||||||
void* cookie;
|
void* cookie;
|
||||||
@ -29,8 +37,12 @@ typedef struct {
|
|||||||
long maplen;
|
long maplen;
|
||||||
uint64 mapofs;
|
uint64 mapofs;
|
||||||
#ifdef __MINGW32__
|
#ifdef __MINGW32__
|
||||||
OVERLAPPED o;
|
OVERLAPPED or,ow,os; /* overlapped for read+accept, write+connect, sendfile */
|
||||||
HANDLE /* fd, */ mh;
|
HANDLE /* fd, */ mh;
|
||||||
|
char inbuf[8192];
|
||||||
|
int bytes_read,bytes_written;
|
||||||
|
DWORD errorcode;
|
||||||
|
SOCKET next_accept;
|
||||||
#endif
|
#endif
|
||||||
} io_entry;
|
} io_entry;
|
||||||
|
|
||||||
|
@ -7,12 +7,75 @@
|
|||||||
#include "socket.h"
|
#include "socket.h"
|
||||||
#include "havesl.h"
|
#include "havesl.h"
|
||||||
|
|
||||||
|
#ifdef __MINGW32__
|
||||||
|
#include <windows.h>
|
||||||
|
#include <mswsock.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include "io_internal.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
int socket_accept4(int s,char *ip,uint16 *port) {
|
int socket_accept4(int s,char *ip,uint16 *port) {
|
||||||
struct sockaddr_in si;
|
struct sockaddr_in si;
|
||||||
socklen_t len = sizeof si;
|
socklen_t len = sizeof si;
|
||||||
int fd;
|
int fd;
|
||||||
if ((fd=accept(s,(void*) &si,&len))==-1)
|
|
||||||
return winsock2errno(-1);
|
#ifdef __MINGW32__
|
||||||
|
io_entry* e=array_get(&io_fds,sizeof(io_entry),s);
|
||||||
|
if (e && e->inuse) {
|
||||||
|
int sa2len;
|
||||||
|
fd=-1;
|
||||||
|
if (e->acceptqueued==1) {
|
||||||
|
errno=EAGAIN;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (e->acceptqueued==2) {
|
||||||
|
incoming:
|
||||||
|
/* incoming! */
|
||||||
|
{
|
||||||
|
struct sockaddr* x,* y;
|
||||||
|
GetAcceptExSockaddrs(e->inbuf,0,200,200,&x,&sa2len,&y,&len);
|
||||||
|
if (len>sizeof(si)) len=sizeof(si);
|
||||||
|
memcpy(&si,y,len);
|
||||||
|
}
|
||||||
|
fd=e->next_accept;
|
||||||
|
e->next_accept=0;
|
||||||
|
if (e->nonblock) {
|
||||||
|
if (io_fd(fd)) {
|
||||||
|
io_entry* f=array_get(&io_fds,sizeof(io_entry),fd);
|
||||||
|
if (f) {
|
||||||
|
f->nonblock=1;
|
||||||
|
// printf("setting fd %lu to non-blocking\n",(int)fd);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* no accept queued, queue one now. */
|
||||||
|
if (e->next_accept==0) {
|
||||||
|
e->next_accept=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
|
||||||
|
if (e==-1)
|
||||||
|
return winsock2errno(-1);
|
||||||
|
}
|
||||||
|
if (AcceptEx(s,e->next_accept,e->inbuf,0,200,200,&e->errorcode,&e->or))
|
||||||
|
goto incoming;
|
||||||
|
if (WSAGetLastError() != ERROR_IO_PENDING)
|
||||||
|
return winsock2errno(-1);
|
||||||
|
e->acceptqueued=1;
|
||||||
|
if (fd==-1) {
|
||||||
|
errno=EAGAIN;
|
||||||
|
return fd;
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if ((fd=accept(s,(void*) &si,&len))==-1)
|
||||||
|
return winsock2errno(-1);
|
||||||
|
|
||||||
|
#ifdef __MINGW32__
|
||||||
|
}
|
||||||
|
#endif
|
||||||
if (ip) *(uint32*)ip = *(uint32*)&si.sin_addr;
|
if (ip) *(uint32*)ip = *(uint32*)&si.sin_addr;
|
||||||
if (port) uint16_unpack_big((char *) &si.sin_port,port);
|
if (port) uint16_unpack_big((char *) &si.sin_port,port);
|
||||||
return fd;
|
return fd;
|
||||||
|
@ -12,6 +12,14 @@
|
|||||||
#include "havesl.h"
|
#include "havesl.h"
|
||||||
#include "havescope.h"
|
#include "havescope.h"
|
||||||
|
|
||||||
|
#ifdef __MINGW32__
|
||||||
|
#include <windows.h>
|
||||||
|
#include <mswsock.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include "io_internal.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
int socket_accept6(int s,char* ip,uint16* port,uint32* scope_id)
|
int socket_accept6(int s,char* ip,uint16* port,uint32* scope_id)
|
||||||
{
|
{
|
||||||
#ifdef LIBC_HAS_IP6
|
#ifdef LIBC_HAS_IP6
|
||||||
@ -22,9 +30,61 @@ int socket_accept6(int s,char* ip,uint16* port,uint32* scope_id)
|
|||||||
socklen_t dummy = sizeof sa;
|
socklen_t dummy = sizeof sa;
|
||||||
int fd;
|
int fd;
|
||||||
|
|
||||||
fd = accept(s,(struct sockaddr *) &sa,&dummy);
|
#ifdef __MINGW32__
|
||||||
if (fd == -1)
|
io_entry* e=array_get(&io_fds,sizeof(io_entry),s);
|
||||||
return winsock2errno(-1);
|
if (e && e->inuse) {
|
||||||
|
int sa2len;
|
||||||
|
fd=-1;
|
||||||
|
if (e->acceptqueued==1) {
|
||||||
|
errno=EAGAIN;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (e->acceptqueued==2) {
|
||||||
|
incoming:
|
||||||
|
/* incoming! */
|
||||||
|
{
|
||||||
|
struct sockaddr* x,* y;
|
||||||
|
GetAcceptExSockaddrs(e->inbuf,0,200,200,&x,&sa2len,&y,&dummy);
|
||||||
|
if (dummy>sizeof(sa)) dummy=sizeof(sa);
|
||||||
|
memcpy(&sa,y,dummy);
|
||||||
|
}
|
||||||
|
fd=e->next_accept;
|
||||||
|
e->next_accept=0;
|
||||||
|
if (e->nonblock) {
|
||||||
|
if (io_fd(fd)) {
|
||||||
|
io_entry* f=array_get(&io_fds,sizeof(io_entry),fd);
|
||||||
|
if (f) {
|
||||||
|
f->nonblock=1;
|
||||||
|
// printf("setting fd %lu to non-blocking\n",(int)fd);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* no accept queued, queue one now. */
|
||||||
|
if (e->next_accept==0) {
|
||||||
|
e->next_accept=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
|
||||||
|
if (e==-1)
|
||||||
|
return winsock2errno(-1);
|
||||||
|
}
|
||||||
|
if (AcceptEx(s,e->next_accept,e->inbuf,0,200,200,&e->errorcode,&e->or))
|
||||||
|
goto incoming;
|
||||||
|
if (WSAGetLastError() != ERROR_IO_PENDING)
|
||||||
|
return winsock2errno(-1);
|
||||||
|
e->acceptqueued=1;
|
||||||
|
if (fd==-1) {
|
||||||
|
errno=EAGAIN;
|
||||||
|
return fd;
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
#endif
|
||||||
|
fd = accept(s,(struct sockaddr *) &sa,&dummy);
|
||||||
|
if (fd == -1)
|
||||||
|
return winsock2errno(-1);
|
||||||
|
#ifdef __MINGW32__
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef LIBC_HAS_IP6
|
#ifdef LIBC_HAS_IP6
|
||||||
if (sa.sin6_family==AF_INET) {
|
if (sa.sin6_family==AF_INET) {
|
||||||
|
@ -1,10 +1,33 @@
|
|||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#ifndef __MINGW32__
|
#ifdef __MINGW32__
|
||||||
|
#include "io_internal.h"
|
||||||
|
#include <mswsock.h>
|
||||||
|
#else
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
#endif
|
#endif
|
||||||
#include "socket.h"
|
#include "socket.h"
|
||||||
#include "windoze.h"
|
#include "windoze.h"
|
||||||
|
|
||||||
int socket_listen(int s,unsigned int backlog) {
|
int socket_listen(int s,unsigned int backlog) {
|
||||||
return winsock2errno(listen(s, backlog));
|
#ifdef __MINGW32__
|
||||||
|
io_entry* e;
|
||||||
|
int r = listen(s, backlog);
|
||||||
|
if (r==-1) return winsock2errno(-1);
|
||||||
|
e=array_get(&io_fds,sizeof(io_entry),s);
|
||||||
|
if (e && e->inuse) {
|
||||||
|
e->listened=1;
|
||||||
|
if (e->wantread) {
|
||||||
|
/* queue a non-blocking accept */
|
||||||
|
DWORD received;
|
||||||
|
e->next_accept=socket(AF_INET,SOCK_STREAM,0);
|
||||||
|
if (e->next_accept!=-1) {
|
||||||
|
AcceptEx(s,e->next_accept,e->inbuf,0,200,200,&received,&e->or);
|
||||||
|
e->acceptqueued=1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return r;
|
||||||
|
#else
|
||||||
|
return listen(s, backlog);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
14
test/io5.c
14
test/io5.c
@ -15,6 +15,12 @@ int main() {
|
|||||||
buffer_putnlflush(buffer_2);
|
buffer_putnlflush(buffer_2);
|
||||||
return 111;
|
return 111;
|
||||||
}
|
}
|
||||||
|
if (!io_fd(s)) {
|
||||||
|
buffer_puts(buffer_2,"io_fd: ");
|
||||||
|
buffer_puterror(buffer_2);
|
||||||
|
buffer_putnlflush(buffer_2);
|
||||||
|
return 111;
|
||||||
|
}
|
||||||
if (socket_listen(s,16)==-1) {
|
if (socket_listen(s,16)==-1) {
|
||||||
buffer_puts(buffer_2,"socket_listen: ");
|
buffer_puts(buffer_2,"socket_listen: ");
|
||||||
buffer_puterror(buffer_2);
|
buffer_puterror(buffer_2);
|
||||||
@ -22,12 +28,6 @@ int main() {
|
|||||||
return 111;
|
return 111;
|
||||||
}
|
}
|
||||||
io_nonblock(s);
|
io_nonblock(s);
|
||||||
if (!io_fd(s)) {
|
|
||||||
buffer_puts(buffer_2,"io_fd: ");
|
|
||||||
buffer_puterror(buffer_2);
|
|
||||||
buffer_putnlflush(buffer_2);
|
|
||||||
return 111;
|
|
||||||
}
|
|
||||||
io_wantread(s);
|
io_wantread(s);
|
||||||
buffer_puts(buffer_2,"listening on port 1234 (fd #");
|
buffer_puts(buffer_2,"listening on port 1234 (fd #");
|
||||||
buffer_putulong(buffer_2,s);
|
buffer_putulong(buffer_2,s);
|
||||||
@ -35,7 +35,6 @@ int main() {
|
|||||||
for (;;) {
|
for (;;) {
|
||||||
int64 i;
|
int64 i;
|
||||||
io_wait();
|
io_wait();
|
||||||
buffer_putsflush(buffer_2,"io_wait() returned!\n");
|
|
||||||
while ((i=io_canread())!=-1) {
|
while ((i=io_canread())!=-1) {
|
||||||
if (i==s) {
|
if (i==s) {
|
||||||
int n;
|
int n;
|
||||||
@ -64,6 +63,7 @@ int main() {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
char buf[1024];
|
char buf[1024];
|
||||||
|
|
||||||
int l=io_tryread(i,buf,sizeof buf);
|
int l=io_tryread(i,buf,sizeof buf);
|
||||||
if (l==-1) {
|
if (l==-1) {
|
||||||
buffer_puts(buffer_2,"io_tryread(");
|
buffer_puts(buffer_2,"io_tryread(");
|
||||||
|
Loading…
x
Reference in New Issue
Block a user