Problems with Threading

Hi together!

I am working on Bluetooth component for the vvvv-platform. I have already successfully implemented a BT scanner for detecting available BT nodes.

Now, the next step is the implementation of a OBEX (ObjectExchange protocol) receiver. Thus, the component is implemented as a listener which I want to run in an own thread…

There is the problem: I use the following (pseudo)-code:

{CODE(ln=>1)}Thread thread = new Thread(new ThreadStart(runThread));
thread.Start();^

and the runThread-method is implemented like the following:

{CODE(ln=>1)}private void runThread() {
try {
while (listener.IsListening) {
ObexListenerContext olc = listener.GetContext();
ObexListenerRequest olr = olc.Request;
string filename = olr.RawUrl.Replace("/","").Replace("%EF%BF%BD","");
olr.WriteFile(“c:\”+filename);
}
}
catch (Exception e){}
}^

This works fine for a singular object exchange. The file is properly stored on the given location in the filesystem. But at the same moment vvvv aborts with an “unknown” exception.

Does anybody made experiences with threaded plugin development?

Thanks & regards,
salocinx.

-and is there a way to print debug messages out to the tty renderer or to the logfile node? this would help us to find out where vvvv is crashing…?

-what about the hoster? we havnt really found out what the idea of it is? is it a a standalone .exe where you can test plugs? how to compile it? hhen we compile the hoster project we got a running timeliner SA ?

the particles plugin from tonfilm made use of threading. maybe that helps.

as for logging:
the host has a method called Log for interfacing with the tty-renderer. be sure to use the latest dlls though.

yeah we allready use tonfilms threading sample but we got a crash with it as soon we display something on the outlet in vvvv.
saloncinx will post the project later on the svn, maybe some can have a look on it.

and… probably were stupid, but how to use the hoster?
when we compile th project file all we get is the timeliner standalone…???

you can use the hoster by adding references to your plugin within the hoster project.
now you can select your plugin and after checking the debug checkbox of the hoster you can adjust input values by right drag.

basically the obex receiver plugin works now. but there is still some strange behavior. the following list outlines the problem domain:

– as soon as i attach an output pin and try to switch off the obex listener (e.g. setting “Do Listen” input node to 0.0), vvvv immediately crashes when moving the mouse pointer over the output pin.

– if i leave the output pin out (e.g. only two input pins), the Evaluate() method seems not to be called back by the underlying plugin-interface.

– thus, the code within the Evaluate() method shows no impact at all… but in return, the obex-listener correctly works.

i have attached the project to this thread in the hope that somebody takes a peek at those few lines of codes (i.e. only about 15 lines ;-))

okay - that’s it - many thanks in advance!

cheers,
salocinx.

BTReceiverPlugin.zip (214.7 kB)

helos,

have you got your plugin to run with the hoster? the hosters exact purpose is to allow you debugging of your code and see what happens stepbystep, to discover problems. so make sure you get the hoster to run as greg mentioned and it also says here in a little more detail: The Hoster.

then you can set breakpoints and step through your troubles…

  • as soon as i attach an output pin and try to switch off the obex listener (e.g. setting “Do Listen” input node to 0.0), vvvv immediately crashes when moving the mouse pointer over the output pin.
    you are calling
    listener.Start()
    twice. once in the constructor, the next time in the evaluate method, when the pin has changed and is == 1. the first time the Evaluate is called (when you hover the output with the mouse) the input pin is changed and
    listener.Start()
    will be called again, before having been stopped before. maybe that is a problem?

  • if i leave the output pin out (e.g. only two input pins), the Evaluate() method seems not to be called back by the underlying plugin-interface.
    true. that is a feature. evaluate is only called if really someone is interested in its output. if you have no output set IPugin.AutoEvaluate to true.

hope that helps.

Hello,

had a debug on your code, when your plugin has IsListening to 1, the code is blocked at the following line (I suppose it’s waiting for an object to be transferred).
As you run in a thread, the plugin still continues.

  • ObexListenerContext olc = listener.GetContext();

Whe you set the “IsListening” to 0, you release the listener, so the method above send a null value in the olc variable, so when it goes to this line there is an exception:
ObexListenerRequest olr = olc.Request;

To correct it, the best way is either to stop the thread, using thread.Abort();
(Note: for this one make sure to put it in a try-catch statement, as calling thread.Abort() will throw an exception.

Otherwise you can change the listen method by the following:

private void listen()
{
while(listener.IsListening)
{
ObexListenerContext olc = listener.GetContext();
if (olc != null)
{
ObexListenerRequest olr = olc.Request;
string filename = olr.RawUrl.Replace("/", “”).Replace("%EF%BF%BD", “”);
olr.WriteFile(path + filename);
}
}
}

On a last note, I saw you were calling those in the plugin destructor:

listener.Close();
thread.Abort();

it would be better if you put it in the dispose method, so it will be called when you delete the plugin.

MANY THANKS for your vital hints. The plugin works now!

i didn’t had the time to take a closer look at the Hoster debugging variant. but i will examine it asap.

i finally used IPlugin.AutoEvaluate to continuously catch changes made at the input pins.

another thing i didn’t know was the fact that pins only should be set within the Evaluate() method (otherwise unstable behaviour may emerge, thanks to vux). Thus, using flags for triggering/propagating events inside the Evaluate mainlop is a simple and robust method to get rid of system crashes.

finally, i decided to completely shutdown the listening thread when the user sets the input switch to “off”. simply instantiating a new thread when the listener is turned “on” again. this solution seemed better to me, since interrupting/resuming threads would require additional sync-maintenance and maybe would be even more error-prone.

i attached a copy of the working project for interested readers.

many thanks to joreg and vux for your helpful support!

BTReceiverPlugin.zip (216.6 kB)