summaryrefslogtreecommitdiffstats
path: root/libdivecomputer.c
diff options
context:
space:
mode:
authorGravatar Linus Torvalds <torvalds@linux-foundation.org>2012-09-20 12:56:42 -0700
committerGravatar Linus Torvalds <torvalds@linux-foundation.org>2012-09-20 12:56:42 -0700
commit2f7fa769d4bb3de7c84d621aaab761a4c69394a0 (patch)
treea3b0d5d0e0eb237af646dc707532eb3775124cbf /libdivecomputer.c
parentf4bc0ca37b47fd731bf55bc6c4675a34092771da (diff)
downloadsubsurface-2f7fa769d4bb3de7c84d621aaab761a4c69394a0.tar.gz
Don't update the progress bar from the dive computer import thread
There's no guarantee that gtk is thread-safe (apparently it can be broken at least on Windows, even though it should be fine on top of X). So don't update the progress bar directly from the dive computer import code, instead just update the progress information in static variables, and let the GUI thread update it while it does the idle loop polling anyway. Reported-by: Jef Driesen <jefdriesen@telenet.be> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'libdivecomputer.c')
-rw-r--r--libdivecomputer.c16
1 files changed, 12 insertions, 4 deletions
diff --git a/libdivecomputer.c b/libdivecomputer.c
index d96d2769f..c9683fbb9 100644
--- a/libdivecomputer.c
+++ b/libdivecomputer.c
@@ -18,6 +18,9 @@
#define NOT_FROG
#endif
+static const char *progress_bar_text = "";
+static double progress_bar_fraction = 0.0;
+
static GError *error(const char *fmt, ...)
{
va_list args;
@@ -159,13 +162,13 @@ sample_cb(dc_sample_type_t type, dc_sample_value_t value, void *userdata)
static void dev_info(device_data_t *devdata, const char *fmt, ...)
{
- char buffer[32];
+ static char buffer[32];
va_list ap;
va_start(ap, fmt);
vsnprintf(buffer, sizeof(buffer), fmt, ap);
va_end(ap);
- update_progressbar_text(&devdata->progress, buffer);
+ progress_bar_text = buffer;
}
static int import_dive_number = 0;
@@ -318,8 +321,9 @@ static void event_cb(dc_device_t *device, dc_event_type_t event, const void *dat
dev_info(devdata, "Event: waiting for user action");
break;
case DC_EVENT_PROGRESS:
- update_progressbar(&devdata->progress,
- (double) progress->current / (double) progress->maximum);
+ if (!progress->maximum)
+ break;
+ progress_bar_fraction = (double) progress->current / (double) progress->maximum;
break;
case DC_EVENT_DEVINFO:
dev_info(devdata, "model=%u (0x%08x), firmware=%u (0x%08x), serial=%u (0x%08x)",
@@ -406,9 +410,13 @@ GError *do_import(device_data_t *data)
/* I'm sure there is some better interface for waiting on a thread in a UI main loop */
import_thread_done = 0;
+ progress_bar_text = "";
+ progress_bar_fraction = 0.0;
pthread_create(&pthread, NULL, pthread_wrapper, data);
while (!import_thread_done) {
import_thread_cancelled = process_ui_events();
+ update_progressbar(&data->progress, progress_bar_fraction);
+ update_progressbar_text(&data->progress, progress_bar_text);
usleep(100000);
}
if (pthread_join(pthread, &retval) < 0)