static gboolean net_io_do(GtkWidget *parent, net_io_request_t *request) { /* the request structure is shared between master and worker thread. */ /* typically the master thread will do some waiting until the worker */ /* thread returns. But the master may very well stop waiting since e.g. */ /* the user activated some cancel button. The client will learn this */ /* from the fact that it's holding the only reference to the request */ GtkWidget *pbar = NULL; GtkWidget *dialog = busy_dialog(parent, &pbar, &request->cancel); /* create worker thread */ request->refcount = 2; // master and worker hold a reference if(!g_thread_create(&worker_thread, request, FALSE, NULL) != 0) { g_warning("failed to create the worker thread"); /* free request and return error */ request->refcount--; /* decrease by one for dead worker thread */ gtk_widget_destroy(dialog); return FALSE; } /* wait for worker thread */ float progress = 0; while(request->refcount > 1 && !request->cancel) { while(gtk_events_pending()) gtk_main_iteration(); /* worker has made progress changed the progress value */ if(request->progress != progress) { gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(pbar), request->progress); progress = request->progress; } else if(!progress) gtk_progress_bar_pulse(GTK_PROGRESS_BAR(pbar)); usleep(100000); } gtk_widget_destroy(dialog); /* user pressed cancel */ if(request->refcount > 1) { printf("operation cancelled, leave worker alone\n"); return FALSE; } printf("worker thread has ended\n"); /* --------- evaluate result --------- */ /* the http connection itself may have failed */ if(request->res != 0) { errorf(parent, _("Download failed with message:\n\n%s"), request->buffer); return FALSE; } /* a valid http connection may have returned an error */ if(request->response != 200) { errorf(parent, _("Download failed with code %ld:\n\n%s\n"), request->response, http_message(request->response)); return FALSE; } return TRUE; }
static gboolean net_io_do(GtkWidget *parent, net_io_request_t *request, const char *title) { /* the request structure is shared between master and worker thread. */ /* typically the master thread will do some waiting until the worker */ /* thread returns. But the master may very well stop waiting since e.g. */ /* the user activated some cancel button. The client will learn this */ /* from the fact that it's holding the only reference to the request */ GtkProgressBar *pbar = NULL; GtkWidget *dialog = busy_dialog(parent, &pbar, &request->cancel, title); /* create worker thread */ request->refcount = 2; // master and worker hold a reference GThread *worker; #if GLIB_CHECK_VERSION(2,32,0) worker = g_thread_try_new("download", &worker_thread, request, NULL); #else worker = g_thread_create(&worker_thread, request, FALSE, NULL); #endif if(worker == NULL) { g_warning("failed to create the worker thread"); /* free request and return error */ request->refcount--; /* decrease by one for dead worker thread */ gtk_widget_destroy(dialog); return FALSE; } /* wait for worker thread */ curl_off_t last = 0; while(request->refcount > 1 && !request->cancel) { while(gtk_events_pending()) gtk_main_iteration(); /* worker has made progress changed the progress value */ if(request->download_cur != last) { if(request->download_end != 0) { gdouble progress = (gdouble)request->download_cur / (gdouble)request->download_end; gtk_progress_bar_set_fraction(pbar, progress); } else { gtk_progress_bar_pulse(pbar); } gchar buf[G_ASCII_DTOSTR_BUF_SIZE]; g_snprintf(buf, sizeof(buf), "%llu", (unsigned long long)request->download_cur); gtk_progress_bar_set_text(pbar, buf); } usleep(100000); } #if GLIB_CHECK_VERSION(2,32,0) g_thread_unref(worker); #endif gtk_widget_destroy(dialog); /* user pressed cancel */ if(request->refcount > 1) { printf("operation cancelled, leave worker alone\n"); return FALSE; } printf("worker thread has ended\n"); /* --------- evaluate result --------- */ /* the http connection itself may have failed */ if(request->res != 0) { errorf(parent, _("Download failed with message:\n\n%s"), request->buffer); return FALSE; } /* a valid http connection may have returned an error */ if(request->response != 200) { errorf(parent, _("Download failed with code %ld:\n\n%s\n"), request->response, http_message(request->response)); return FALSE; } return TRUE; }