Re: fork() and progress bar...



} wrong. you can start up a thread do the SQL stuff. this is much more
} convenient, since the threads are in the same address space.
}
} but before you do, read the FAQ. the other thread can access GTK+, but
} only if it uses locks. otherwise, you need to use some kind of IPC to
} notify the main GUI thread that an update of the progress bar is
} required. i prefer this latter approach, and i use a pipe to do so.

Ok, I've set up an extra thread with the progressbar updating
in the main thread and the mysql query happening in the
other thread. It works great and mysql loads and there's no
crashes. However, when the 'Fetching...' part happens, it says
'Fetching...', but the progressbar just flickers very fast,
like it's updating too quickly. I tried upping the usleep()'s,
but that never worked. Under the fork() mechanism, the for
loops I have there did the updating at the perfect rate. If
someone could help me out with figuring out those speed issues,
I'd really appreciate it. I've attached a recent copy of my
code below.

Jeff Shipman           E-Mail: jeff nmt edu
Systems Programmer     Phone: (505) 835-5748
NMIMT Computer Center  http://www.nmt.edu/~jeff


int *running;

void *mysql_thread(void *arg)
{
   char *qBuffer = (char *)arg;

   if (mysql_query(&mysql, qBuffer )) {
      fprintf(stderr,  "query failed: Error %s\n", mysql_error(&mysql));
      mysql_close(&mysql);
      exit(0);
   }
   *running = 0;
   pthread_exit(0);
}

void set_progressbar_value(gfloat val)
{
   gtk_progress_bar_update(GTK_PROGRESS_BAR(appProgressBar), val);
   while(gtk_events_pending()) gtk_main_iteration();
}

void set_progressbar_text(gchar *text)
{
   gtk_progress_set_format_string(GTK_PROGRESS(appProgressBar), text);
   while(gtk_events_pending()) gtk_main_iteration();
}

int sql_load(char *newest, char *oldest, char *status, char *searchString, char *timeStamp) {
  int testval;
  int numloaded;
  pthread_t thread_id;
  void *res;
  int i;
  gfloat newval;
  MYSQL_RES *pMysql_res;
  MYSQL_ROW pMysql_row;
	char *escapedSearchString;
  char qBuffer[1024 + strlen(query_exclude_string())];
  char base_query[] =
    "SELECT DISTINCT status,description,time_spent,est_ttc,priority,"
    "scope,owner,filer,reporter,repname,repphone,category,"
    "subcategory,tickets.ctime,close_time,mtime,est_doc,"
		"UNIX_TIMESTAMP(tickets.ctime),mailto,csa FROM tickets,notes "
		"WHERE tickets.ctime=notes.ctime ";
  char status_condition[] =
    " AND status='%s' ";
  char sooner_than_condition[] =
    " AND tickets.ctime < %s ";
  char later_than_condition[] =
    " AND tickets.ctime > %s ";
  char nsearch_condition[] =
		" AND notes.notes LIKE '%%%s%%' ";
  char tsearch_condition[] =
      " AND tickets.ctime LIKE '%%%s%%' ";
  char user_condition[] =
      " AND scope='external'";
  my_ulonglong numRows;
  dataCoreNode node;

  server_check();
  /* form base of query */
  strcpy(qBuffer, base_query);

  if (status != NULL)
    sprintf(qBuffer + strlen(qBuffer), status_condition, status);

  if (newest != NULL)
    sprintf(qBuffer + strlen(qBuffer), sooner_than_condition, newest);

  if (oldest != NULL)
    sprintf(qBuffer + strlen(qBuffer), later_than_condition, oldest);

	if (searchString != NULL) {
		escapedSearchString = malloc( (strlen(searchString) * 2) +1);
		assert(escapedSearchString != NULL);
		mysql_escape_string(escapedSearchString, searchString,strlen(searchString));
		assert( (strlen(qBuffer) + strlen(escapedSearchString)) < 950);
		sprintf(qBuffer + strlen(qBuffer), nsearch_condition, escapedSearchString);
		free (escapedSearchString);
	}
  if (timeStamp != NULL) {
     escapedSearchString = malloc( (strlen(timeStamp) * 2) +1);
     assert(escapedSearchString != NULL);
     mysql_escape_string(escapedSearchString, timeStamp,strlen(timeStamp));
     assert( (strlen(qBuffer) + strlen(escapedSearchString)) < 950);
     sprintf(qBuffer + strlen(qBuffer), tsearch_condition, escapedSearchString);
     free(escapedSearchString);
  }
  if(!permissions_is_worker())
  {
     sprintf(qBuffer + strlen(qBuffer), user_condition);
  }

  if(strlen(query_exclude_string()))
  {
     sprintf(qBuffer + strlen(qBuffer), query_exclude_string());
  }

  DPRINT2("query string is %s\n\n", qBuffer);

   running = malloc(sizeof(int));
   *running = 1;

   /* Now to load the results and do the spiffy progress bar thing. */
   if((i = pthread_create(&thread_id, NULL, mysql_thread, qBuffer)) != 0)
   {
      fprintf(stderr, "Error: could not create thread.\n"
              "Reason: %s\n", strerror(errno));
      mysql_close(&mysql);
      exit(0);
   }
   while(*running)
   {
      printf("hi\n");
      set_progressbar_text("Fetching...");
      for(i=0.0;i<=100.0;i+=5)
      {
         set_progressbar_value(i/100);
         usleep(5);
      }
      gtk_progress_bar_set_orientation(GTK_PROGRESS_BAR(query_progressbar()),
                                       GTK_PROGRESS_RIGHT_TO_LEFT);
      for(i=100.0;i>=0.0;i-=5)
      {
         set_progressbar_value(i/100);
         usleep(5);
      }
      for(i=0.0;i<=100.0;i+=5)
      {
         set_progressbar_value(i/100);
         usleep(5);
      }
      gtk_progress_bar_set_orientation(GTK_PROGRESS_BAR(query_progressbar()),
                                       GTK_PROGRESS_LEFT_TO_RIGHT);
      for(i=100.0;i>=0.0;i-=5)
      {
         set_progressbar_value(i/100);
         usleep(5);
      }
      printf("bye\n");
   }

   free(running);
   i = pthread_join(thread_id, &res);

   pMysql_res = mysql_store_result(&mysql);
   if (pMysql_res == NULL) {
      fprintf(stderr,  "store result failed: Error %s\n", mysql_error(&mysql));
      mysql_close(&mysql);
      exit(0);
   }
   numRows = mysql_num_rows(pMysql_res);
   DPRINT2("data load got %lu rows\n", (unsigned long) numRows);

   /* don't flame out if no tickets are found */
   if (! numRows) {
      datacore_init(1);
      memset( (void *)&node, 0, sizeof(dataCoreNode));
      strncpy(node.description, "no tickets within range/type", MAX_DESC);
      datacore_insert(&node);
      mysql_free_result(pMysql_res);
      pMysql_res = NULL;
      return 1;
   }

   numloaded = 0;
   set_progressbar_text("Processing... %p%%");
   set_progressbar_value(0.0);

   datacore_init(numRows);
   pMysql_row = mysql_fetch_row(pMysql_res);
   while (pMysql_row != NULL) {
      if(pMysql_row[0])
         strncpy(node.status, pMysql_row[0], MAX_STATUS);
      else
         strcpy(node.status, "active");
      if(pMysql_row[1])
         strncpy(node.description, pMysql_row[1], MAX_DESC);
      else
         strcpy(node.description, "No description available.");
      if(pMysql_row[2])
         node.timeSpent = (float) atof(pMysql_row[2]);
      else
         node.timeSpent=0.0;
      if(pMysql_row[3])
         node.estTTC = (float) atof(pMysql_row[3]);
      else
         node.estTTC = 1.5;

      if(pMysql_row[4])
         node.priority = (unsigned char) atoi(pMysql_row[4]);
      else
         node.priority = 3;

      if(pMysql_row[5])
         node.is_internal = (strcmp(pMysql_row[5], "internal") == 0) ? 1 : 0;
      else
         node.is_internal = 0;

      if(pMysql_row[6])
         strncpy(node.owner, pMysql_row[6], MAX_USERNAME);
      else
         strcpy(node.owner, "unassigned");
      if(pMysql_row[7])
         strncpy(node.filer, pMysql_row[7], MAX_FILERNAME);
      else
         strcpy(node.filer, "N/A");
      if(pMysql_row[8])
         strncpy(node.reporter, pMysql_row[8], MAX_REPORTERNAME);
      else
         strcpy(node.reporter, "N/A");
      if(pMysql_row[9])
         strncpy(node.repname, pMysql_row[9], MAX_REPORTERNAME);
      else
         strcpy(node.repname, "N/A");
      if(pMysql_row[10])
         strncpy(node.repphone, pMysql_row[10], MAX_PHONE);
      else
         strcpy(node.repphone, "N/A");
      if(pMysql_row[11])
         strncpy(node.category, pMysql_row[11], MAX_CATEGORY);
      else
         strcpy(node.category, "other");
      if(pMysql_row[12])
         strncpy(node.subcategory, pMysql_row[12], MAX_CATEGORY);
      else
         strcpy(node.subcategory, "other");
      if(pMysql_row[13])
         strncpy(node.createStamp, pMysql_row[13], STAMP_LENGTH);
      else
         strcpy(node.createStamp, "00000000000000");
      if(pMysql_row[14])
         strncpy(node.closeStamp, pMysql_row[14], STAMP_LENGTH);
      else
         strcpy(node.closeStamp, "00000000000000");
      if(pMysql_row[15])
         strncpy(node.modStamp, pMysql_row[15], STAMP_LENGTH);
      else
         strcpy(node.modStamp, "00000000000000");
      if(pMysql_row[16])
         strncpy(node.estDOC, pMysql_row[16], STAMP_LENGTH);
      else
         strcpy(node.estDOC, "00000000000000");
      if(pMysql_row[17])
         node.unixStamp = atoi(pMysql_row[17]);
      else
         node.unixStamp = 0;

      if(pMysql_row[18])
         strncpy(node.emailto, pMysql_row[18], MAX_EMAIL_LIST);
      else
         node.emailto[0]='\0';
      if(pMysql_row[19])
         strncpy(node.csa, pMysql_row[19], MAX_CSA);
      else
         strncpy(node.csa, "100", MAX_CSA);
      node.flagged = 0;
      /* Set unread stuffs */
      testval = trt_check(node.createStamp, node.modStamp);
      switch (testval) {
         case TRT_READ:
            node.unread = 0;
            break;
         case TRT_NEW:
            node.unread = 2;
            break;
         case TRT_UPDATED:
            node.unread = 1;
            break;
         default:
            DPRINT3("Unhandled switch in %s, line %d",__FILE__, __LINE__);
      }
      datacore_insert(&node);
      pMysql_row = mysql_fetch_row(pMysql_res);
      newval = (gfloat)(++numloaded)/(gfloat)numRows;
      set_progressbar_value(newval);
   }

   set_progressbar_value(0.0);
   set_progressbar_text("Waiting");

   mysql_free_result(pMysql_res);
   pMysql_res = NULL;
   return (int) numRows;
}





[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]