X-Git-Url: http://www.git.stargrave.org/?a=blobdiff_plain;f=lib%2FPublicInbox%2FSpawn.pm;h=e0a51c2167e829549d20683470aa55b02c3556b5;hb=74f027ca317067f7ae7289b15465d6a49078f65c;hp=e940d3c9d7f44710e86b8b1118f921cf8cea562e;hpb=dacde5e35071579fb25c3f5276355ec76c840151;p=public-inbox.git diff --git a/lib/PublicInbox/Spawn.pm b/lib/PublicInbox/Spawn.pm index e940d3c9..e0a51c21 100644 --- a/lib/PublicInbox/Spawn.pm +++ b/lib/PublicInbox/Spawn.pm @@ -34,6 +34,9 @@ BEGIN { #include #include #include +#include +#include +#include /* some platforms need alloca.h, but some don't */ #if defined(__GNUC__) && !defined(alloca) @@ -162,6 +165,22 @@ int pi_fork_exec(SV *redirref, SV *file, SV *cmdref, SV *envref, SV *rlimref, return (int)pid; } +static int sleep_wait(unsigned *tries, int err) +{ + const struct timespec req = { 0, 100000000 }; /* 100ms */ + switch (err) { + case ENOBUFS: case ENOMEM: case ETOOMANYREFS: + if (++*tries < 50) { + fprintf(stderr, "sleeping on sendmsg: %s (#%u)\n", + strerror(err), *tries); + nanosleep(&req, NULL); + return 1; + } + default: + return 0; + } +} + #if defined(CMSG_SPACE) && defined(CMSG_LEN) #define SEND_FD_CAPA 10 #define SEND_FD_SPACE (SEND_FD_CAPA * sizeof(int)) @@ -180,6 +199,7 @@ SV *send_cmd4(PerlIO *s, SV *svfds, SV *data, int flags) AV *fds = (AV *)SvRV(svfds); I32 i, nfds = av_len(fds) + 1; int *fdp; + unsigned tries = 0; if (SvOK(data)) { iov.iov_base = SvPV(data, dlen); @@ -207,7 +227,9 @@ SV *send_cmd4(PerlIO *s, SV *svfds, SV *data, int flags) *fdp++ = SvIV(*fd); } } - sent = sendmsg(PerlIO_fileno(s), &msg, flags); + do { + sent = sendmsg(PerlIO_fileno(s), &msg, flags); + } while (sent < 0 && sleep_wait(&tries, errno)); return sent >= 0 ? newSViv(sent) : &PL_sv_undef; } @@ -258,9 +280,6 @@ ALL_LIBC #include #include #include -#include -#include -#include void nodatacow_fd(int fd) {