Patrick wrote:why so afraid of threads? We have never found this to be an issue performance-wise.
For simple programs, a single-threaded application with an event loop (e.g. provided by libevent or glib or the like) is 99.9% more than enough, and much less error prone, as there would be 0 threading issues. If I need asynchronicity for a program I would very likely choose a single thread with an event loop instead of multiple threads.
The problem of using threads in a library like this is that you're forcing every user of the library to be thread-aware. E.g. (if I'm not mistaken!) callbacks executed for attach/detach events aren't run on the primary program thread, but in different threads created internally by libphidget (I spent some time printing thread ids yesterday and that's what I saw, at least).
My program using libphidget is a big one, but the libphidget usage is just a very very small part of it, and now I need to take care of threading issues just for that. And mixing threads that one can not control with an already existing main loop is a nightmare, so now I'm stuck with my custom async methods which run the blocking methods of libphidget (e.g. CPhidget_waitForAttachment) instead of the async logic (e.g. attach/detach handlers) from libphidget.
If the threads were truly an internal thing (e.g. lots of GLib/GIO async methods use threads internally but still they report completion on the main thread) then that would be much easier to handle. But fair enough, preparing an async API which doesn't use threads and doesn't use any other explicit event-loop implementation is hard.