SIGUSR2 from GC interrupts application system calls on Linux

ikod via Digitalmars-d digitalmars-d at puremagic.com
Thu May 26 11:44:22 PDT 2016


Hello,

On linux, in the code below, receive() returns -1 with 
errno=EINTR if syscall is interrupted by GC (so you can see 
several "insterrupted") when GC enabled, and prints nothing (this 
is desired and expected behavior) when GC disabled.

Looks like the reason of the problem is call sigaction(2) without 
SA_RESTART for SIGUSR2 (used by GC to restart suspended thread) 
in core.thread.

Is there any recommended workaround for this problem? Is this a 
bug?

Thanks for your help with this problem

import std.stdio;
import std.format;
import std.socket;
import std.conv: to;
import core.stdc.errno;
import core.memory;
import std.datetime;

auto myRequest(string x)
{
     auto data = new byte[100240];
     ubyte[16*1024] buffer;
     auto timeout = 5.seconds;
     uint delay = to!uint(x) % 5;
     auto addresses = getAddress("httpbin.org", 80);
     auto s = new Socket(AddressFamily.INET, SocketType.STREAM, 
ProtocolType.TCP);
     scope(exit) {
         s.close();
     }
     s.setOption(SocketOptionLevel.SOCKET, SocketOption.SNDTIMEO, 
timeout);
     s.connect(addresses[0]);
     s.send("GET /delay/%d HTTP/1.1\r\nHost: 
httpbin.org\r\n\r\n".format(delay));
     s.setOption(SocketOptionLevel.SOCKET, SocketOption.RCVTIMEO, 
timeout);
     auto r = s.receive(buffer);
     if ( r <= 0 ) {
         if ( errno == EINTR ) {
             writeln("interrupted");
             return "fail";
         }
     }
     return "ok";
};

void main() {
     import std.parallelism;
     import std.range: iota;
     import std.algorithm: map;
     //GC.disable();
     defaultPoolThreads(8);
     auto r = iota(0, 100).map!(to!string);
     auto p = taskPool.map!myRequest(r); // fails
}



More information about the Digitalmars-d mailing list