I'm currently working on a project that requires me to queue network packets to be processed. I have a ThreadPool with a maximum of 25 threads that processes these packets when they are available. However, when passing the packet data (encapsulated in a class) to the thread_proc method associated with the ThreadPool, the data is being corrupted. I declare my ThreadPool variable like so:
pool = new ThreadPool<Packet>((Func<Packet>)thread_proc, 25, false);
This is the thread method that checks the available packets:
void* run()
{
while (true)
{
var packet = packets.poll();
try
{
pool.push(packet);
}
catch (ThreadError e)
{
error(e.message);
}
}
return null;
}
"packets" is a BlockingQueue (custom blocking queue using a mutex) of the following class:
class Packet : Object
{
public unowned ClientHandler client;
public uint8[] data;
public int index;
public int size;
public Packet(ClientHandler client, uint8[] data, int index, int size)
{
this.client = client;
this.data = data;
this.index = index;
this.size = size;
}
}
The above class is what contains the actual packet data (the "data" var). By the time the Packet instance gets around to thread_proc, the variable values are all wrong...
Any help as to why this is happening and a possible solution would be much appreciated. Thank you in advance.
~ Michael K.
I just pushed a commit to valac git which will let Vala automatically manage the data. It would have broken backwards compatibility, so you'll have to use the new constructor (ThreadPool.with_owned_data) and method (add instead of push).
If you want to avoid a dependency on valac git, you can just do a packet.ref ()
before pushing it, then packet.unref ()
at the end of your callback (thread_proc
). There is an example at https://bugzilla.gnome.org/attachment.cgi?id=214884.
Note that casting thread_proc in the ThreadPool constructor could break the new memory management stuff. Frankly, you should really just avoid casting delegates... it's a great way to get in trouble. It's much better to just fix your function (thread_proc
in this case) to have the correct signature.