diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2012-09-20 12:56:42 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-09-20 12:56:42 -0700 |
commit | 2f7fa769d4bb3de7c84d621aaab761a4c69394a0 (patch) | |
tree | a3b0d5d0e0eb237af646dc707532eb3775124cbf | |
parent | f4bc0ca37b47fd731bf55bc6c4675a34092771da (diff) | |
download | subsurface-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>
-rw-r--r-- | libdivecomputer.c | 16 |
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) |