Is thread safety expected in Gadgeteer module drivers?

Dec 20, 2014 at 2:39 PM
Edited Dec 20, 2014 at 2:39 PM
Is there a general expectation of thread safety in Gadgeteer module drivers?

For example, a module driver internally sends serial commands to the module as a result of an application calling various driver methods, and the device would get into an unknown state if multiple application threads made conflicting calls before previous commands had completed. To avoid this, the internal commands sent to the device should be serialized, so that no more than one command is ever outstanding, no matter how many application threads simultaneously call driver methods that send commands to the module.

This is easy enough to implement, but I was wondering if the tradeoff in size and performance would outweigh the benefit in the Gadgeteer environment. Is it acceptable to document that a module driver is not thread-safe, requiring the application to use it from a single thread or be responsible for synchronization? Alternatively, is it acceptable to provide two distinct drivers for the module - one that's thread-safe and one that isn't?

Dec 21, 2014 at 7:12 PM
Edited Dec 21, 2014 at 7:13 PM
There is a general expectation that drivers will invoke event handlers on the Dispatcher's thread by default, see module builder's guide, page 13.

However, it should be caller's responsibility to synchronize access from multiple threads to your driver (unless you have components specifically intended for multithreaded access). That is a general .NET Framework guideline - static members thread safe, instance members not.

If one was concerned about performance, I would recommend bypassing the .NET Gadgeteer layer (preferably create a plain .NET Micro Framework driver and make the .NET Gadgeteer one call that one). It is definitely acceptable to provide two distinct drivers for a module, but depending on your target audience, users might not be aware of the concept of thread safety and might get confused by two drivers in the toolbox.
Marked as answer by kengr on 12/21/2014 at 12:50 PM
Dec 21, 2014 at 7:50 PM
Thanks for your insights.

Yes, I always invoke event handlers on the Dispatcher thread.

In this case, all members are instance members, and everything will work as long as the caller doesn't hit the driver from multiple threads simultaneously. In the multiple thread scenario, interleaved serial commands sent to the device can put it into an unusable state (requiring a reset). I would like to avoid that situation, but if the expectation is that instance members are not necessarily thread-safe, then it sounds like I could just document it and provide some sample code for doing the appropriate locking in application code.

I agree that providing multiple drivers can be confusing, reminiscent of the choice between thread-safe and thread-not-so-safe libraries in C. My target audience runs the gamut, so I know that a significant percentage would not yet have the thread safety concept down.

Again, thanks.