Hi all,
I'm having a really terrible bug that seemed to come from nowhere
and is really hard to narrow down. I have a threaded message
service that works via local TcpSocket. Every time I run it,
either an error saying:
Unable to open 'recv.c': Unable to read file
'/build/glibc-ZN95T4/glibc-2.31/sysdeps/unix/sysv/linux/recv.c'
(Error: Unable to resolve non-existing file
'/build/glibc-ZN95T4/glibc-2.31/sysdeps/unix/sysv/linux/recv.c').
when socket.receive() is called. Sometimes I get the same thing
but for socket.accept() instead (different file). This seems to
generate a core.exception.InvalidMemoryOperationError that I
can't catch.
Yesterday, this came up after a couple of minutes of the program
running, now it happens straight away. I haven't touched this
class in a week or so and can't think of why all of a sudden it
has come up with this issue. Code dump below
---------------------------------------------
module message_service;
import std.stdio;
import std.socket;
import core.thread;
/**
Threaded socket manager to serve inter-service communication
Calls delegates when the appropriate command is received
*/
class MessageService : Thread{
/// The socket over which communication is possible
private Socket server;
/// The connection to the client that sends commands
private Socket client;
/// Associative array of command strings and relative
functions to call
private void delegate()[string] commands;
/// Global buffer. Holds the command being recieved
private char[1024] buffer = 0;
///
this(ushort port, void delegate()[string] _commands){
commands = _commands;
server = new TcpSocket();
server.setOption(SocketOptionLevel.SOCKET,
SocketOption.REUSEADDR, true);
server.bind(new InternetAddress(port));
writefln("Message service started on port %d", port);
super(&mainLoop);
start();
}
/// Loops over polling the client socket for commands
void mainLoop(){
while(true){
pollMessages();
}
}
/**
Polls the client socket for characters to build up the
message buffer
When a string command is found, it calls the appropriate
function
*/
void pollMessages(){
server.listen(1);
if(client is null) client = server.accept();
// Add to the message buffer
auto buffLength = client.receive(buffer);
if(buffLength){
auto message = cast(string) buffer[0 .. buffLength];
foreach(cmd; commands.byKey){
if(cmd == message){
// Reset the message buffer
buffer = 0;
commands[cmd]();
return;
}
}
}
}
}