www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Interrupted System Call

reply Peter Neubauer <peterneubauer2 gmail.com> writes:
Hello everyone,

I've been getting the error message "Interrupted System Call" a lot 
lately, ever since I started using threads in D. It appears whenever one 
of the threads in my application creates and uses an associative array 
while another thread executes a blocking system call such as readln or 
receive on sockets. Here is an example:

=====================

import std.stdio;
import std.thread;

int readlnfunc (void* arg)
{
	readln();
	return 0;
}

void main ()
{
	(new Thread (&readlnfunc, null)).start();

	while (true) {
		int[int] aa;
		aa[0] = 0;
	}
}

=====================

I'm using dmd 1.033 on Ubuntu 8.04.

This looks like a bug to me; I don't know how to fix it or work around 
it either. Sometimes the error doesn't throw up an exception, but it 
still prevents me from using some other functions:

=====================

import std.socket;
import std.stdio;
import std.thread;

int serverfunc (void* arg)
{
	Socket listener = new TcpSocket ();
	listener.bind (new InternetAddress(1234));
	listener.listen(10);
	Socket socket = listener.accept ();
	assert (socket.isAlive);

	ubyte[512] buf;
	int bytes = socket.receive(buf);
	writefln ("Server: Received %d bytes.", bytes);

	socket.shutdown (SocketShutdown.BOTH);
	socket.close;
	listener.close;
	return 0;
}

int clientfunc (void* arg)
{
	Socket socket = new TcpSocket(new InternetAddress("127.0.0.1", 1234));
	assert (socket.isAlive);

	ubyte[512] buf;
	int bytes = socket.receive(buf);
	writefln ("Client: Received %d bytes.", bytes);

	socket.shutdown (SocketShutdown.BOTH);
	socket.close();
	return 0;
}

void main ()
{
	(new Thread (&serverfunc, null)).start();
	(new Thread (&clientfunc, null)).start();

	for (int i = 0; i < 100000; ++i) {
		int[int] aa;
		aa[0] = 0;
		Thread.yield();
	}
}

=====================

A simple server-client connection and both call receive(). Both these 
calls return Socket.ERROR, and the error disappears when I take out the 
aa in main. Optionally, if I put the aa in another extra thread and let 
the loop run before the client connects, accept() from the server will 
spit out an "Interrupted System Call".

Does anyone have any suggestions on how to fix or work around this 
problem? I couldn't find anyone else who had it.

-Peter
Jul 23 2008
next sibling parent "Jarrett Billingsley" <kb3ctd2 yahoo.com> writes:
"Peter Neubauer" <peterneubauer2 gmail.com> wrote in message 
news:g66s1f$120h$1 digitalmars.com...
 Hello everyone,

 I've been getting the error message "Interrupted System Call" a lot 
 lately, ever since I started using threads in D. It appears whenever one 
 of the threads in my application creates and uses an associative array 
 while another thread executes a blocking system call such as readln or 
 receive on sockets. Here is an example:

 =====================

 import std.stdio;
 import std.thread;

 int readlnfunc (void* arg)
 {
 readln();
 return 0;
 }

 void main ()
 {
 (new Thread (&readlnfunc, null)).start();

 while (true) {
 int[int] aa;
 aa[0] = 0;
 }
 }

 =====================

 I'm using dmd 1.033 on Ubuntu 8.04.

 This looks like a bug to me; I don't know how to fix it or work around it 
 either. Sometimes the error doesn't throw up an exception, but it still 
 prevents me from using some other functions:

 =====================

 import std.socket;
 import std.stdio;
 import std.thread;

 int serverfunc (void* arg)
 {
 Socket listener = new TcpSocket ();
 listener.bind (new InternetAddress(1234));
 listener.listen(10);
 Socket socket = listener.accept ();
 assert (socket.isAlive);

 ubyte[512] buf;
 int bytes = socket.receive(buf);
 writefln ("Server: Received %d bytes.", bytes);

 socket.shutdown (SocketShutdown.BOTH);
 socket.close;
 listener.close;
 return 0;
 }

 int clientfunc (void* arg)
 {
 Socket socket = new TcpSocket(new InternetAddress("127.0.0.1", 1234));
 assert (socket.isAlive);

 ubyte[512] buf;
 int bytes = socket.receive(buf);
 writefln ("Client: Received %d bytes.", bytes);

 socket.shutdown (SocketShutdown.BOTH);
 socket.close();
 return 0;
 }

 void main ()
 {
 (new Thread (&serverfunc, null)).start();
 (new Thread (&clientfunc, null)).start();

 for (int i = 0; i < 100000; ++i) {
 int[int] aa;
 aa[0] = 0;
 Thread.yield();
 }
 }

 =====================

 A simple server-client connection and both call receive(). Both these 
 calls return Socket.ERROR, and the error disappears when I take out the aa 
 in main. Optionally, if I put the aa in another extra thread and let the 
 loop run before the client connects, accept() from the server will spit 
 out an "Interrupted System Call".

 Does anyone have any suggestions on how to fix or work around this 
 problem? I couldn't find anyone else who had it.

 -Peter

See the "linux system calls are canceled by D GC" thread on digitalmars.D.bugs. I think this is what you're experiencing.
Jul 23 2008
prev sibling parent reply Sean Kelly <sean invisibleduck.org> writes:
Peter Neubauer wrote:
 Hello everyone,
 
 I've been getting the error message "Interrupted System Call" a lot 
 lately, ever since I started using threads in D. It appears whenever one 
 of the threads in my application creates and uses an associative array 
 while another thread executes a blocking system call such as readln or 
 receive on sockets.

I imagine you're using Phobos? Phobos omits some signal flags to tell the OS to try and resume system calls if they are interrupted by a garbage collection cycle. Tango sets them properly. Sean
Jul 23 2008
parent Peter Neubauer <peterneubauer2 gmail.com> writes:
Sean Kelly wrote:
 Peter Neubauer wrote:
 Hello everyone,

 I've been getting the error message "Interrupted System Call" a lot 
 lately, ever since I started using threads in D. It appears whenever 
 one of the threads in my application creates and uses an associative 
 array while another thread executes a blocking system call such as 
 readln or receive on sockets.

I imagine you're using Phobos? Phobos omits some signal flags to tell the OS to try and resume system calls if they are interrupted by a garbage collection cycle. Tango sets them properly. Sean

Thanks for your answers, switching to Tango has solved my problem. -Peter
Jul 26 2008