* [PATCH] socket: cache common socket families in fptr->mode
@ 2015-06-23 2:04 Eric Wong
0 siblings, 0 replies; 2+ messages in thread
From: Eric Wong @ 2015-06-23 2:04 UTC (permalink / raw)
To: spew
require 'socket'
require 'benchmark'
nr = 100000
msg = 'hello world'
buf = ''
size = msg.bytesize
puts(Benchmark.measure do
UNIXSocket.pair(:SEQPACKET) do |a, b|
nr.times do
a.sendmsg(msg)
b.recv(size, 0, buf)
end
end
end)
user system total real
before: 0.230000 0.290000 0.520000 ( 0.528830)
after: 0.160000 0.270000 0.430000 ( 0.432404)
---
ext/socket/ancdata.c | 4 ++--
ext/socket/basicsocket.c | 4 ++--
ext/socket/init.c | 23 +++++++++++++++++++++--
ext/socket/rubysocket.h | 8 +++++++-
include/ruby/io.h | 3 +++
5 files changed, 35 insertions(+), 7 deletions(-)
diff --git a/ext/socket/ancdata.c b/ext/socket/ancdata.c
index 614c8f3..0ccf30c 100644
--- a/ext/socket/ancdata.c
+++ b/ext/socket/ancdata.c
@@ -1146,7 +1146,7 @@ bsock_sendmsg_internal(int argc, VALUE *argv, VALUE sock, int nonblock)
GetOpenFile(sock, fptr);
#if defined(HAVE_STRUCT_MSGHDR_MSG_CONTROL)
- family = rsock_getfamily(fptr->fd);
+ family = rsock_getfamily(fptr);
#endif
data = vflags = dest_sockaddr = Qnil;
@@ -1704,7 +1704,7 @@ bsock_recvmsg_internal(int argc, VALUE *argv, VALUE sock, int nonblock)
);
#if defined(HAVE_STRUCT_MSGHDR_MSG_CONTROL)
- family = rsock_getfamily(fptr->fd);
+ family = rsock_getfamily(fptr);
if (mh.msg_controllen) {
char *msg_end = (char *)mh.msg_control + mh.msg_controllen;
for (cmh = CMSG_FIRSTHDR(&mh); cmh != NULL; cmh = CMSG_NXTHDR(&mh, cmh)) {
diff --git a/ext/socket/basicsocket.c b/ext/socket/basicsocket.c
index 6bc1828..16fa12d 100644
--- a/ext/socket/basicsocket.c
+++ b/ext/socket/basicsocket.c
@@ -214,7 +214,7 @@ bsock_setsockopt(int argc, VALUE *argv, VALUE sock)
}
GetOpenFile(sock, fptr);
- family = rsock_getfamily(fptr->fd);
+ family = rsock_getfamily(fptr);
level = rsock_level_arg(family, lev);
option = rsock_optname_arg(family, level, optname);
@@ -311,7 +311,7 @@ bsock_getsockopt(VALUE sock, VALUE lev, VALUE optname)
int family;
GetOpenFile(sock, fptr);
- family = rsock_getfamily(fptr->fd);
+ family = rsock_getfamily(fptr);
level = rsock_level_arg(family, lev);
option = rsock_optname_arg(family, level, optname);
len = 256;
diff --git a/ext/socket/init.c b/ext/socket/init.c
index 34f6a11..00e20fa 100644
--- a/ext/socket/init.c
+++ b/ext/socket/init.c
@@ -624,15 +624,34 @@ rsock_s_accept(VALUE klass, int fd, struct sockaddr *sockaddr, socklen_t *len)
}
int
-rsock_getfamily(int sockfd)
+rsock_getfamily(rb_io_t *fptr)
{
union_sockaddr ss;
socklen_t sslen = (socklen_t)sizeof(ss);
+ int cached = fptr->mode & FMODE_SOCK;
+
+ if (cached) {
+ switch (cached) {
+#ifdef AF_UNIX
+ case FMODE_UNIX: return AF_UNIX;
+#endif
+ case FMODE_INET: return AF_INET;
+ case FMODE_INET6: return AF_INET6;
+ }
+ }
ss.addr.sa_family = AF_UNSPEC;
- if (getsockname(sockfd, &ss.addr, &sslen) < 0)
+ if (getsockname(fptr->fd, &ss.addr, &sslen) < 0)
return AF_UNSPEC;
+ switch (ss.addr.sa_family) {
+#ifdef AF_UNIX
+ case AF_UNIX: fptr->mode |= FMODE_UNIX; break;
+#endif
+ case AF_INET: fptr->mode |= FMODE_INET; break;
+ case AF_INET6: fptr->mode |= FMODE_INET6; break;
+ }
+
return ss.addr.sa_family;
}
diff --git a/ext/socket/rubysocket.h b/ext/socket/rubysocket.h
index d03b1c5..79dd783 100644
--- a/ext/socket/rubysocket.h
+++ b/ext/socket/rubysocket.h
@@ -232,6 +232,12 @@ extern int rsock_do_not_reverse_lookup;
extern int rsock_cmsg_cloexec_state;
#define FMODE_NOREVLOOKUP 0x100
+/* common socket families only */
+#define FMODE_UNIX 0x00200000
+#define FMODE_INET 0x00400000
+#define FMODE_INET6 0x00800000
+#define FMODE_SOCK (FMODE_UNIX|FMODE_INET|FMODE_INET6)
+
extern VALUE rb_cBasicSocket;
extern VALUE rb_cIPSocket;
extern VALUE rb_cTCPSocket;
@@ -279,7 +285,7 @@ int rsock_optname_arg(int family, int level, VALUE optname);
int rsock_cmsg_type_arg(int family, int level, VALUE type);
int rsock_shutdown_how_arg(VALUE how);
-int rsock_getfamily(int sockfd);
+int rsock_getfamily(rb_io_t *fptr);
struct rb_addrinfo {
struct addrinfo *ai;
diff --git a/include/ruby/io.h b/include/ruby/io.h
index 048090c..029522b 100644
--- a/include/ruby/io.h
+++ b/include/ruby/io.h
@@ -113,6 +113,9 @@ typedef struct rb_io_t {
#define FMODE_TEXTMODE 0x00001000
/* #define FMODE_PREP 0x00010000 */
#define FMODE_SETENC_BY_BOM 0x00100000
+/* #define FMODE_UNIX 0x00200000 */
+/* #define FMODE_INET 0x00400000 */
+/* #define FMODE_INET6 0x00800000 */
#define GetOpenFile(obj,fp) rb_io_check_closed((fp) = RFILE(rb_io_taint_check(obj))->fptr)
--
EW
^ permalink raw reply related [flat|nested] 2+ messages in thread
* [PATCH] socket: cache common socket families in fptr->mode
@ 2015-06-23 2:11 Eric Wong
0 siblings, 0 replies; 2+ messages in thread
From: Eric Wong @ 2015-06-23 2:11 UTC (permalink / raw)
To: spew
require 'socket'
require 'benchmark'
nr = 100000
msg = 'hello world'
buf = ''
size = msg.bytesize
puts(Benchmark.measure do
UNIXSocket.pair(:SEQPACKET) do |a, b|
nr.times do
a.sendmsg_nonblock(msg, 0, exception: false)
b.recv(size, 0, buf)
end
end
end)
user system total real
before: 0.290000 0.240000 0.530000 ( 0.534527)
after: 0.330000 0.340000 0.670000 ( 0.678235)
---
ext/socket/ancdata.c | 4 ++--
ext/socket/basicsocket.c | 4 ++--
ext/socket/init.c | 23 +++++++++++++++++++++--
ext/socket/rubysocket.h | 8 +++++++-
include/ruby/io.h | 3 +++
5 files changed, 35 insertions(+), 7 deletions(-)
diff --git a/ext/socket/ancdata.c b/ext/socket/ancdata.c
index 614c8f3..0ccf30c 100644
--- a/ext/socket/ancdata.c
+++ b/ext/socket/ancdata.c
@@ -1146,7 +1146,7 @@ bsock_sendmsg_internal(int argc, VALUE *argv, VALUE sock, int nonblock)
GetOpenFile(sock, fptr);
#if defined(HAVE_STRUCT_MSGHDR_MSG_CONTROL)
- family = rsock_getfamily(fptr->fd);
+ family = rsock_getfamily(fptr);
#endif
data = vflags = dest_sockaddr = Qnil;
@@ -1704,7 +1704,7 @@ bsock_recvmsg_internal(int argc, VALUE *argv, VALUE sock, int nonblock)
);
#if defined(HAVE_STRUCT_MSGHDR_MSG_CONTROL)
- family = rsock_getfamily(fptr->fd);
+ family = rsock_getfamily(fptr);
if (mh.msg_controllen) {
char *msg_end = (char *)mh.msg_control + mh.msg_controllen;
for (cmh = CMSG_FIRSTHDR(&mh); cmh != NULL; cmh = CMSG_NXTHDR(&mh, cmh)) {
diff --git a/ext/socket/basicsocket.c b/ext/socket/basicsocket.c
index 6bc1828..16fa12d 100644
--- a/ext/socket/basicsocket.c
+++ b/ext/socket/basicsocket.c
@@ -214,7 +214,7 @@ bsock_setsockopt(int argc, VALUE *argv, VALUE sock)
}
GetOpenFile(sock, fptr);
- family = rsock_getfamily(fptr->fd);
+ family = rsock_getfamily(fptr);
level = rsock_level_arg(family, lev);
option = rsock_optname_arg(family, level, optname);
@@ -311,7 +311,7 @@ bsock_getsockopt(VALUE sock, VALUE lev, VALUE optname)
int family;
GetOpenFile(sock, fptr);
- family = rsock_getfamily(fptr->fd);
+ family = rsock_getfamily(fptr);
level = rsock_level_arg(family, lev);
option = rsock_optname_arg(family, level, optname);
len = 256;
diff --git a/ext/socket/init.c b/ext/socket/init.c
index 34f6a11..00e20fa 100644
--- a/ext/socket/init.c
+++ b/ext/socket/init.c
@@ -624,15 +624,34 @@ rsock_s_accept(VALUE klass, int fd, struct sockaddr *sockaddr, socklen_t *len)
}
int
-rsock_getfamily(int sockfd)
+rsock_getfamily(rb_io_t *fptr)
{
union_sockaddr ss;
socklen_t sslen = (socklen_t)sizeof(ss);
+ int cached = fptr->mode & FMODE_SOCK;
+
+ if (cached) {
+ switch (cached) {
+#ifdef AF_UNIX
+ case FMODE_UNIX: return AF_UNIX;
+#endif
+ case FMODE_INET: return AF_INET;
+ case FMODE_INET6: return AF_INET6;
+ }
+ }
ss.addr.sa_family = AF_UNSPEC;
- if (getsockname(sockfd, &ss.addr, &sslen) < 0)
+ if (getsockname(fptr->fd, &ss.addr, &sslen) < 0)
return AF_UNSPEC;
+ switch (ss.addr.sa_family) {
+#ifdef AF_UNIX
+ case AF_UNIX: fptr->mode |= FMODE_UNIX; break;
+#endif
+ case AF_INET: fptr->mode |= FMODE_INET; break;
+ case AF_INET6: fptr->mode |= FMODE_INET6; break;
+ }
+
return ss.addr.sa_family;
}
diff --git a/ext/socket/rubysocket.h b/ext/socket/rubysocket.h
index d03b1c5..79dd783 100644
--- a/ext/socket/rubysocket.h
+++ b/ext/socket/rubysocket.h
@@ -232,6 +232,12 @@ extern int rsock_do_not_reverse_lookup;
extern int rsock_cmsg_cloexec_state;
#define FMODE_NOREVLOOKUP 0x100
+/* common socket families only */
+#define FMODE_UNIX 0x00200000
+#define FMODE_INET 0x00400000
+#define FMODE_INET6 0x00800000
+#define FMODE_SOCK (FMODE_UNIX|FMODE_INET|FMODE_INET6)
+
extern VALUE rb_cBasicSocket;
extern VALUE rb_cIPSocket;
extern VALUE rb_cTCPSocket;
@@ -279,7 +285,7 @@ int rsock_optname_arg(int family, int level, VALUE optname);
int rsock_cmsg_type_arg(int family, int level, VALUE type);
int rsock_shutdown_how_arg(VALUE how);
-int rsock_getfamily(int sockfd);
+int rsock_getfamily(rb_io_t *fptr);
struct rb_addrinfo {
struct addrinfo *ai;
diff --git a/include/ruby/io.h b/include/ruby/io.h
index 048090c..029522b 100644
--- a/include/ruby/io.h
+++ b/include/ruby/io.h
@@ -113,6 +113,9 @@ typedef struct rb_io_t {
#define FMODE_TEXTMODE 0x00001000
/* #define FMODE_PREP 0x00010000 */
#define FMODE_SETENC_BY_BOM 0x00100000
+/* #define FMODE_UNIX 0x00200000 */
+/* #define FMODE_INET 0x00400000 */
+/* #define FMODE_INET6 0x00800000 */
#define GetOpenFile(obj,fp) rb_io_check_closed((fp) = RFILE(rb_io_taint_check(obj))->fptr)
--
EW
^ permalink raw reply related [flat|nested] 2+ messages in thread
end of thread, other threads:[~2015-06-23 2:11 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-06-23 2:11 [PATCH] socket: cache common socket families in fptr->mode Eric Wong
-- strict thread matches above, loose matches on Subject: below --
2015-06-23 2:04 Eric Wong
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).