The last commit to the repository added an extra socket connection. The second socket is used for asynchronous events that are generated by the server. It was very difficult for me to figure out how to share the other socket and not clobber response messages with event messages from the server. In some respects the message queue would have been much simpler in this regard. I still think that sockets are the better way to go, however.
I don't want to add any threads to the module to handle the event loop, so that complexity will have to reside in the module code to some extent. I see three basic ways for the module to deal with the events. The first is with a select() type function, that will wait for an event to come in on the socket and handle it appropriately. This function would block, but will have a timeout.
This method would be used for modules that were purely event driven, like alarming or historical trending modules. It could also be used for modules that only needed to execute the module code occasionally. For instance, a module might only need to run some code once per second so it'd call the blockling function with a 1000 mSec timeout. When the timeout occurred the module could do its thing and then call the function again.
A similar way would be to add a poll() type function that would check the socket for an event and if one was there it would handle it, otherwise it would return. I guess this is really the same as the above function with a zero timeout. The module would have to be responsible for calling the function occasionally to make sure that the events didn't pile up.
The last way would be the most complex. The module would be responsible for the file descriptor of the socket. There would be a function for retrieving the file descriptor from the library that is associated with the asynchronous socket. The module would then have to check whether there was data on that file descriptor and then call a handler function when there was. This would allow modules to have their own event loop. I suspect that Human Interface modules will have to be built this way since the graphic toolkits are usually event driven. I was told that X Windows has a similar mechanism for dealing with events so perhaps I am in good company.
Each event will trigger a callback to the module that would have been set up during the event creation. These callbacks would be generated by the library during any of the above methods.
I also added remote module capability. It was quite easy to do this. (A benefit of using sockets for the IPC.) The server still doesn't deal with the configuration very well. I want to make it so that it can listen on more than one interface or port. I couldn't decide how to handle the configuration in this regard so I decided to wait until I figure that out to proceed.