dumping ground for random patches and texts
 help / color / mirror / Atom feed
* [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:04 [PATCH] socket: cache common socket families in fptr->mode Eric Wong
  -- strict thread matches above, loose matches on Subject: below --
2015-06-23  2:11 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).