c - GTK non blocking pause -


i have gtk+-3.0 application written in c, (gcc) compiled , run under windows 7 / msys64, communicates bespoke device via serial interface.

it needs pause briefly (fraction of second) between writing device , reading reply device, allow time device return data, otherwise there's no data available in serial input buffer.

the application works in fashion if use sleep(1), unresponsive user events due repeated sleeps.

using g_timeout_add or g_timeout_add_seconds doesn't appear help, because first call function occurs @ end of first interval, time serial read attempt has executed, finding no data.

thanks in anticipation of suggestions.

//   p o l l   c o n t r o l l e r   f o r   t s   s e t t n g s     network->poll_event_source_id = gdk_threads_add_timeout(poll_interval, zf_controller_poll, network);  // use g_priority_default  ...  gint zf_controller_poll(gpointer data)  // thread obtain controller settings @ regular intervals {     gboolean res = false;     t_network *network;      network = data;      poll_iteration = (poll_iteration + 1);      printf("zf_controller_poll iteration %d\n", poll_iteration);      if (connection_running == false)     {         printf("not connected controller\n");         error_popup(network->main_window, "not connected controller!");         return(0);     }      if (poll_running)  // poll again after previous poll ended     {       printf("poll still running\n");       return(1);     }      busy_state = true;  // prepare activate "busy..." timeout     g_timeout_add_seconds(2, zf_progress_update, network);  // activate "busy..." timeout      res = timer_read(network);  // ***     if (res)     {       printf("obtained controller settings\n");     }     else     {       printf("failed obtain controller settings\n");     }      busy_state = false;  // terminate "busy..." timeout      return(1);  // if thread returns false (zero), timeout automatically destroyed , function won't called again }  ...  gboolean timer_read (gpointer data) {     t_network *network;     gint i, val, err;     gdouble val_double;     gchar text[10];      network = data;     i=0; val = 0; val_double = 0; err = 0;      poll_running = true;  // poll again after previous poll ended,       (i = 0; i<max_channels; i++)     {          if (gtk_switch_get_active(gtk_switch(network->entry_toggle_mode[i])) == true)         {             err = controller_send(get_channels[i], &val, network);  // ***              if ((err == no_connection) || (err == reconnection_fail))             {                 send_fail_action(network);                 network->tag_timer_read = 0; /*set tag 0 because time out destroyed here*/                 poll_running = false;  // allow poll again after previous poll ended                 return(false);             }             sprintf(text, "%d", val);             gtk_entry_set_text (gtk_entry(network->output_channel_array[i]), text);             val = 0; err = 0;         }else             gtk_entry_set_text (gtk_entry(network->output_channel_array[i]), "0");     }      poll_running = false;  // poll again after previous poll ended,      return(true); }  ...  gint controller_send (const gchar *message, gint *valptr, gpointer main_data) {     gchar reply[2000] = {'\0'};     unsigned char reply_s[4096];     gint err = 0;     gint val = 0;     file *fileptr;     t_network *network = main_data;     int i, j;     const char *message_s;     char controller_cmd[25];        j = strlen(message);       if (j > 25)         j = 25;       for(i = 0; < j; i++)       {         controller_cmd[i] = message[i];  // copy contents of wifi ip gchar buffer intermediate buffer       }     message_s = controller_cmd;  // copy contents of intermediate buffer serial char buffer      time_t t = time (null);     struct tm tm = *localtime(&t);      if (connection_running == false)     {         printf("not connected controller\n");         fileptr = fopen("logfile.txt", "a");         fprintf(fileptr, "%d.%d.%d %d:%d:%d\t not connected controller\n", tm.tm_mday, tm.tm_mon+1, tm.tm_year+1900, tm.tm_hour, tm.tm_min, tm.tm_sec);         fclose(fileptr);         return(no_connection);     }      /*send message controller*/     if(network->comm_serial)  //  send via serial port if connected     {       err = zf_serial_send(network->comport_num, message_s);  // ***     }     else                      //  send via wifi ip     {       err = func_socket_send(network->s, message);     }     printf("error value: %d\n", err);      /*if message send fails then: */     if(err != 0)     {       if(network->comm_ip)  //  try re-establish tcp/ip session       {         network->connect_thread = g_thread_new("id_reconnect", func_reconnect_after_failptr, network);  /*call connect function in separate thread keep gui responsive*/         g_thread_unref (network->connect_thread);       }         connection_running = false;         fileptr = fopen("logfile.txt", "a");         fprintf(fileptr, "%d.%d.%d %d:%d:%d\t error occurred on send, socket closed, trying reconnect \n", tm.tm_mday, tm.tm_mon+1, tm.tm_year+1900, tm.tm_hour, tm.tm_min, tm.tm_sec);         fclose(fileptr);         /*print error value*/         printf("error value %d\n", err);         return (no_connection);     }      err = 0;      if(network->comm_serial)  //  receive via serial port if connected     {       err = zf_serial_recv(network->comport_num, reply_s);  // ***       j = strlen(reply_s);       if (j > 2000)         j = 2000;  // don't write beyond length of destination buffer       for(i = 0; < j; i++)       {         reply[i] = reply_s[i];  // copy contents of serial char buffer wifi ip gchar buffer       }     }     else                      // receive via wifi ip     {       err = func_socket_receive(network->s, reply);     }      if (err != 0)     {         fileptr = fopen("logfile.txt", "a");         fprintf(fileptr, "%d.%d.%d %d:%d:%d\t error occurred on receive, socket closed, trying reconnect \n", tm.tm_mday, tm.tm_mon+1, tm.tm_year+1900, tm.tm_hour, tm.tm_min, tm.tm_sec);         fclose(fileptr);         connection_running = false;       if(network->comm_ip)  //  try re-establish tcp/ip session       {         network->connect_thread = g_thread_new("id_reconnect", func_reconnect_after_failptr, network);  /*call re connect function in separate thread keep gui responsive*/         g_thread_unref(network->connect_thread);       }         /*print error value*/         printf("error value %d\n", err);         return (no_connection);      }else     {         val = get_extract_value(reply);         *valptr = val;     }      return(0); }  ...  gint zf_serial_recv(int comport_num, unsigned char *reply) {     int recv_size = 0;      recv_size = serial_pollcomport(comport_num, reply, 4095);      reply[recv_size] = 0;  // terminate string null      if (recv_size <= 0)     {         printf("serial reception failed: %d\n", recv_size);         serial_closecomport(comport_num);         return(1);     }      printf("\nreceived serial %dbytes\n", recv_size);     printf("serial reply: %s\n", reply);      return (0); }  ...  gint zf_serial_send(int comport_num, const char *message) {     gint bytes_send;     gboolean res;      bytes_send = serial_sendbuf(comport_num, message, strlen(message));  // ***      if( bytes_send < 0)     {         printf("serial send failed: %d\n", bytes_send);         serial_closecomport(comport_num);         return (1);     }      printf("serial send string: %s\n", message);  //  g_timeout_add_seconds(serial_wr_pause, zf_serial_wr_pause, (gpointer) bytes_send); // next line not delay - (first) execution in (approx) 1 second //  res = g_timeout_add_seconds(1, zf_serial_wr_pause, (gpointer) bytes_send);      sleep(1);  // allow time controller response arrive in serial read buffer      return(0); }  ...  int serial_pollcomport(int comport_number, unsigned char *buf, int size) {   int n;    readfile(cport[comport_number], buf, size, (lpdword)((void *)&n), null);    return(n); }  ...  int serial_sendbuf(int comport_number, unsigned char *buf, int size) {   int n;    if(writefile(cport[comport_number], buf, size, (lpdword)((void *)&n), null))   {     return(n);   }    return(-1); } //... // snippet of serial port initialisation: //...   commtimeouts cptimeouts;  /* value of maxdword, combined 0 values both readtotaltimeoutconstant , readtotaltimeoutmultiplier members, specifies read operation return bytes have been received, if no bytes have been received. */   cptimeouts.readintervaltimeout         = maxdword;   cptimeouts.readtotaltimeoutmultiplier  = 0;   cptimeouts.readtotaltimeoutconstant    = 0;   cptimeouts.writetotaltimeoutmultiplier = 0;   cptimeouts.writetotaltimeoutconstant   = 0;    if(!setcommtimeouts(cport[comport_number], &cptimeouts))   {     printf("unable set comport time-out settings\n");     closehandle(cport[comport_number]);     return(1);   } 


Comments

Popular posts from this blog

html - Styling progress bar with inline style -

java - Oracle Sql developer error: could not install some modules -

How to use autoclose brackets in Jupyter notebook? -