lgunsch / zmq-vala

ØMQ bindings for the Vala language

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Memory leak

David-L-Gonzalez opened this issue · comments

Hi

I'm doing some tests to use the library bindings for vala, but with a simple server and client I have found a memory issue.
When you launch both, the memory of the server begins to increase.

The source code of the server:
using ZMQ;
using Random;

int numberObjects=200;
DemoServer []myServers;
Socket publisher;

public bool newSignal(string signalName,int id, double value){

    // Get values that will fool the boss
    int temperature, relhumidity;
    temperature = int_range (-80, 135);
    relhumidity = int_range (10, 60);

    // Send message to all subscribers
    string update = @"$(signalName) $(id) $(temperature) $(relhumidity)";
    stdout.printf("Sending: %s.\n", update);
    //size_t size = update.length;
    var reply = Msg.with_data (update.data,null);

    publisher.send (ref reply,0);
    return true;
}

public class DemoServer : Object {
    private int id;
    private int counterA;

    public DemoServer(int id){      
        this.id=id;
    }
    public void sendSignalA(){      
        newSignalA(counterA);
        counterA++;
    }
    public void newSignalA (double value){
        newSignal("newSignalA",id,counterA);
    }
}

public static int main(string [] argv) {
    var context = new Context (1);

    // Socket to talk to server
    stdout.printf ("Connecting to server…\n");
    publisher = Socket.create (context, SocketType.PUB);
    publisher.bind ("ipc:///tmp/feeds/0");

    myServers=new DemoServer[numberObjects];

    for (int i=0;i<numberObjects;i++){
        myServers[i]=new DemoServer (i);
    }       

    Timeout.add (250, () => {
        for (int i=0;i<numberObjects;i++){
            myServers[i].sendSignalA();
        }
        return true;
    });             
    new MainLoop ().run ();
    return 0;
}

The source code of the client:
using ZMQ;
using Random;

namespace ZMQ {
    public string? s_recv(ZMQ.Socket socket) {
        var msg = ZMQ.Msg ();
        if (socket.recv (ref msg) != 0) {
            return null;
        }
        size_t size = msg.size () + 1;
        uint8[] data = new uint8[size];
        Memory.copy(data, msg.data, size - 1);
        data[size - 1] = '\0';
        return (string)data;
    }
}

public static int main(string[] args) {
    var context = new Context (1);

    // Socket to talk to server
    stdout.printf ("Collecting updates from weather server...\n");
    var subscriber = Socket.create (context, SocketType.SUB);
    subscriber.connect ("ipc:///tmp/feeds/0");
    string filter = (args.length > 1)? args[1]: "newSignalA ";
    subscriber.setsockopt (SocketOption.SUBSCRIBE, filter, filter.length);
    stdout.printf ("Starting\n");
    while (true)    {       
        var strReply = s_recv (subscriber);
        stdout.printf ("Receiving: "+strReply + "\n");
    }
}

Kind regards,
David.

Hi,

On the line below (as seen in your test), the null parameter is normally the delegate free function free_fn. ZMQ will try to free the string with the given free function, but will not free it if it is null. I have updated the libzmq bindings to now use GLib.free as the default free function rather than none (see line 77 of libzmq.vapi). I have also updated the examples to reflect this. It should work for you if you just remove the null parameter in your message constructor. Let me know if this works for you, as it worked for me.

var reply = Msg.with_data (update.data, null);

Also, any feedback on these bindings would be appreciated.

Cheers,
~Lewis

Thank you very much for your quick response.

After changing the vapi and the code, the test is working perfectly.

Kind regards,
David.