Daniel Nilsson wrote:
I'm not certain I understand all the details of how your application has to work; but i'm willing to take a shot atHi,
I'm working on a program in GTK+ that has a need to communicate with a
slow device (a power supply connected to a serial port). While this
might not be so difficult to achieve what complicates matters is that
the main program consists of two state machines that each needs to be
able to read and write over the serial port. These state machines are
kicked once every 500mS in the gtk_main loop by using
g_timeout_add, as far as I can tell that means that the two
statemachines will never be executed at the same time. Seems like
gtk_main runs all functions added by g_timeout_add sequentially.
Controls on the UI are also require action in the statemachines to happen so I can't block inside the statemachine code waiting for input from the serial port (this would make the UI non-responsive for up to 2 seconds or so which is the time it takes to get an answer over the serial port). Hence I need to have the serial communication happen in the background (separate thread). The serial communication basically consists of; send a command, wait in a select for a response if the command suceeded or not and any data associated. Since there are no IDs with these commands I can't just have each statemachine send the commands directly, because then I don't know what responce goes with which command when I go the read off the serial port.
I've been trying to come up with what the best solution is here, and it seems like the best I have come up with is still a complicated solution. What I thought of was to have a third function that would execute using timeout_add, this function would maintain a FIFO queue of commands from the two statemachines to be sent to the serial port. The function would then decide what command to send, prepare a memory location for the response and then hand this over to actually complete in a separate thread. The complicated portion of this is to get the results (the data payload) back to the statemachine that sent a measurement command to the power supply (for example, a voltage measurement request). Since I can't block in the stateamachine code I then somehow need to first send the command and then come back later and check for a response. In addition, each measurement done over the serial port also needs a timestamp which should be correct down to +/- 1s or so. Error handling also becomes interesting...
Any thoughts of a easier way to do this ? Could I use the glib GIOChannel somehow or coud the glib Asynchronous Queues help in any way ?
how I might approach a similar problem. Basically, you have a task that needs to be accomplished and you want
to display in a graphical window the progress of that task. You may also, want to send commands to the task triggered
by a user. I would break this up into two seperate threads one for the GUI and one for the task. In the GUI thread I
would have a function that is called every 100 ms or so and check if there is any payload in an async queue. This function might
look something like:
g_timeout_add( 100, (GSourceFunc)process_command, queue );
struct Payload{ int msg_id; /// .. other important parts of the message. }; gboolean process_command( GAsyncQueue *queue ) { Payload*msg = (GMsg*)g_async_queue_try_pop( queue ); if( msg ){ switch( msg->msg_id ){ // process each message } } return TRUE; // keep the timeout going }
So, I can use a similar loop in both the GUI thread and the Task thread if I need two way communication.
Hope this helps, todd
_______________________________________________ gtk-list@xxxxxxxxx http://mail.gnome.org/mailman/listinfo/gtk-list