socket: memoize common socket families in fptr->mode

This provides a minor speedup by avoiding an extra syscall

	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.330000   0.340000   0.670000 (  0.678235)
 after:  0.290000   0.240000   0.530000 (  0.534527)

* ext/socket/rubysocket.h: flags for common socket families
  (rsock_getfamily): update signature
* include/ruby/io.h: comment socket FMODE flags
* ext/socket/init.c (rsock_getfamily): memoize family
* ext/socket/basicsocket.c: adjust rsock_getfamily calls
* ext/socket/ancdata.c: ditto
  [ruby-core:69713] [Feature #11298]

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@51097 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
normal 2015-07-02 01:58:14 +00:00
Родитель ccd85f7b17
Коммит 6dda4f17a9
6 изменённых файлов: 45 добавлений и 7 удалений

Просмотреть файл

@ -1,3 +1,13 @@
Thu Jul 2 10:43:36 2015 Eric Wong <e@80x24.org>
* ext/socket/rubysocket.h: flags for common socket families
(rsock_getfamily): update signature
* include/ruby/io.h: comment socket FMODE flags
* ext/socket/init.c (rsock_getfamily): memoize family
* ext/socket/basicsocket.c: adjust rsock_getfamily calls
* ext/socket/ancdata.c: ditto
[ruby-core:69713] [Feature #11298]
Thu Jul 2 10:30:01 2015 SHIBATA Hiroshi <hsbt@ruby-lang.org>
* lib/rubygems/resolver.rb: fixed NameError of Gem::Util::NULL_DEVICE.

Просмотреть файл

@ -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;
@ -1692,7 +1692,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)) {

Просмотреть файл

@ -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;

Просмотреть файл

@ -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;
}

Просмотреть файл

@ -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;

Просмотреть файл

@ -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)