MozRepl command delays

41 views
Skip to first unread message

Dave Hansen

unread,
May 11, 2011, 8:08:21 PM5/11/11
to moz...@googlegroups.com
I'm using WWW::Mechanize::FireFox to examine some web pages and dump out
their forms. However, it can be pretty slow to do this at times if
there are a lot of forms on the page. That's understandable, but what
confounds me is that the CPU is almost completely idle during these
delays.

After some extensive debugging, I eventually tracked the source of the
latency down to TCP_NODELAY/Nagle. Adding this little LD_PRELOAD trick
to Firefox speeds up my WWW::Mechanize::FireFox by about 20x! It also
ends up peaking my CPU, which feels a lot nicer than having tons of idle
time.

The problem is that it can take ~30ms once the "repl>" prompt is written
to the socket for the data to get to the other socket. When you do 50
of these a second, you end up spending all of your time waiting for the
data to move around.

I've done some digging in MozRepl and Firefox themselves, but I don't
see a good way to get these socket options set. It would be _great_ if
we could somehow set these options directly without resorting to
LD_PRELOAD.

/* gcc -fPIC -Wall -W -o nodelay.so --shared -ldl nodelay.c */
// LD_PRELOAD=/tmp/nodelay.so firefox
#define _GNU_SOURCE
#include <stdio.h>
#include <dlfcn.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/tcp.h>

int accept(int sock, struct sockaddr *addr, socklen_t *addrlen)
{
int (*next_accept)(int, struct sockaddr *, socklen_t *) = dlsym(RTLD_NEXT, "accept");
int res = next_accept(sock, addr, addrlen);
//printf(stderr, "in accept hook fd: %d\n", sock);
if (addr->sa_family == AF_INET) {
int opt = 1;
setsockopt(res, IPPROTO_TCP, TCP_NODELAY, &opt, sizeof(opt));
}
return res;
}


-- Dave


Reply all
Reply to author
Forward
0 new messages