From 4fa4a524d28a15951fc5a5883d6cf58d991c311f Mon Sep 17 00:00:00 2001 From: leitner Date: Thu, 9 Oct 2014 09:02:28 +0000 Subject: [PATCH] add io_fd_flags so the caller can tell io_fd whether the socket is blocking (saves one fcntl syscall) --- CHANGES | 2 ++ io.h | 10 ++++++++++ io/io_fd.c | 22 +++++++++++++++++----- 3 files changed, 29 insertions(+), 5 deletions(-) diff --git a/CHANGES b/CHANGES index 2ec2154..289ed32 100644 --- a/CHANGES +++ b/CHANGES @@ -21,6 +21,8 @@ on Linux, in iob_send, if MSG_MORE is defined, and the request type lends itself to it, used sendto/sendmsg with MSG_MORE instead of TCP_CORK (saves two syscalls) + add io_fd_flags so the caller can tell io_fd whether the socket is blocking + (saves one fcntl syscall) 0.29: save 8 bytes in taia.h for 64-bit systems diff --git a/io.h b/io.h index 49fb38e..c6547e6 100644 --- a/io.h +++ b/io.h @@ -78,9 +78,19 @@ int64 io_canwrite(); /* return next descriptor with expired timeout */ int64 io_timeouted(); +/* 1 means: have IO_FD_CANWRITE, IO_FD_BLOCK and IO_FD_NONBLOCK, + * will be incremented if API is extended in the future */ +#define HAVE_IO_FD_FLAGS 1 +enum io_fd_flags { + IO_FD_CANWRITE=1, /* new TCP connection, we know it's writable */ + IO_FD_BLOCK=2, /* skip the fcntl, assume fd is set to blocking */ + IO_FD_NONBLOCK=4, /* skip the fcntl, assume fd is set to non-blocking */ +}; + /* put d on internal data structure, return 1 on success, 0 on error */ int io_fd(int64 d); /* use this for sockets before you called connect() or accept() */ int io_fd_canwrite(int64 d); /* use this for connected sockets (assumes socket is writable) */ +int io_fd_flags(int64 d,int flags); /* can be used to tell io_fd to skip one syscall */ void io_setcookie(int64 d,void* cookie); void* io_getcookie(int64 d); diff --git a/io/io_fd.c b/io/io_fd.c index 1b9538f..794a306 100644 --- a/io/io_fd.c +++ b/io/io_fd.c @@ -53,12 +53,18 @@ long alt_firstwrite; #endif /* put d on internal data structure, return 1 on success, 0 on error */ -static io_entry* io_fd_internal(int64 d) { +static io_entry* io_fd_internal(int64 d,int flags) { io_entry* e; #ifndef __MINGW32__ long r; - if ((r=fcntl(d,F_GETFL,0)) == -1) - return 0; /* file descriptor not open */ + if ((flags&(IO_FD_BLOCK|IO_FD_NONBLOCK))==0) { + if ((r=fcntl(d,F_GETFL,0)) == -1) + return 0; /* file descriptor not open */ + } else + if (flags&IO_FD_NONBLOCK) + r=O_NDELAY; + else + r=0; #endif /* Problem: we might be the first to use io_fds. We need to make sure * we are the only ones to initialize it. So set io_fds_inited to 2 @@ -146,12 +152,18 @@ static io_entry* io_fd_internal(int64 d) { } int io_fd(int64 d) { - io_entry* e=io_fd_internal(d); + io_entry* e=io_fd_internal(d,0); return !!e; } int io_fd_canwrite(int64 d) { - io_entry* e=io_fd_internal(d); + io_entry* e=io_fd_internal(d,0); if (e) e->canwrite=1; return !!e; } + +int io_fd_flags(int64 d,int flags) { + io_entry* e=io_fd_internal(d,flags); + if (e && (flags&IO_FD_CANWRITE)) e->canwrite=1; + return !!e; +}