Reduce use of AutoLock where possible. Avoid deadlocks when threads die during shutdown.

pull/2/head
Daniel Richman 2012-11-02 21:56:57 +00:00
rodzic cb04328b0b
commit 4f3b65a9ac
4 zmienionych plików z 50 dodań i 22 usunięć

Wyświetl plik

@ -41,7 +41,8 @@ static void periodically(void *);
/*
* Functions init, ready and cleanup should only be called from main().
* thread_death and periodically are called by FLTK, which will have the lock.
* thread_death and periodically are called by FLTK, which will have the Fl
* lock.
*/
void init()
{

Wyświetl plik

@ -102,7 +102,7 @@ static void mode_choice_callback(Fl_Widget *w, void *a);
void init()
{
/* called with lock acquired */
/* called with Fl lock acquired */
flight_cache_file = HomeDir + "flight_docs.json";
payload_cache_file = HomeDir + "payload_configuration_docs.json";
@ -110,7 +110,7 @@ void init()
void cleanup()
{
/* called with lock acquired */
/* called with Fl lock acquired */
flight_docs.clear();
payload_docs.clear();
@ -127,7 +127,7 @@ void load_cache()
/* resets everything */
select_flight(-1);
/* called with lock acquired */
/* called with Fl lock acquired */
load_cache_file(flight_cache_file, flight_docs);
load_cache_file(payload_cache_file, payload_docs);

Wyświetl plik

@ -36,6 +36,7 @@ DExtractorManager *extrmgr;
DUploaderThread *uthr;
static habitat::UKHASExtractor *ukhas;
static EZ::Mutex rig_mutex;
static time_t rig_freq_updated, rig_mode_updated;
static long long rig_freq;
static string rig_mode;
@ -64,6 +65,9 @@ void cleanup()
extrmgr = 0;
ukhas = 0;
/* This prevents deadlocks with our use of Fl::lock in the uploader
* thread (which is a necessary evil since we're accessing loads of
* global fldigi stuff) */
if (uthr)
uthr->shutdown();
@ -76,14 +80,14 @@ void cleanup()
void rig_set_freq(long long freq)
{
Fl_AutoLock lock;
EZ::MutexLock lock(rig_mutex);
rig_freq_updated = time(NULL);
rig_freq = freq;
}
void rig_set_mode(const string &mode)
{
Fl_AutoLock lock;
EZ::MutexLock lock(rig_mutex);
rig_mode_updated = time(NULL);
rig_mode = mode;
}

Wyświetl plik

@ -30,11 +30,14 @@ namespace dl_fldigi {
namespace update {
static UpdateThread *thr;
static bool update_new;
static string update_text, update_url;
static void got_update(void *);
static void update_check();
static void update_thread_done(void *what);
static void show_update();
/* check, cleanup are called by main thread only, while holding lock */
/* check, cleanup are called by main thread only, while holding Fl lock */
void check()
{
if (thr)
@ -48,12 +51,36 @@ void check()
void cleanup()
{
if (!thr)
return;
while (thr)
Fl::wait();
}
void *UpdateThread::run()
{
update_check();
Fl::awake(update_thread_done, this);
return NULL;
}
/* invoked via Fl::awake; so we have the main Fl lock */
static void update_thread_done(void *what)
{
if (what != thr)
{
LOG_ERROR("unknown thread");
return;
}
if (update_new)
{
show_update();
update_new = false;
}
LOG_INFO("cleaning up");
thr->join();
delete thr;
thr = NULL;
thr = 0;
}
#ifdef __MINGW32__
@ -72,7 +99,7 @@ void cleanup()
#error "Couldn't work out what the platform should be for update checking :-("
#endif
void *UpdateThread::run()
static void update_check()
{
map<string,string> args;
args["platform"] = PLATFORM;
@ -92,7 +119,7 @@ void *UpdateThread::run()
{
Fl_AutoLock lock;
LOG_WARN("Error in update check: %s", e.what());
return NULL;
return;
}
/* blocking download done, now get the lock: */
@ -101,7 +128,7 @@ void *UpdateThread::run()
if (response == "")
{
LOG_INFO("dl-fldigi is up to date");
return NULL;
return;
}
Json::Reader reader;
@ -112,20 +139,18 @@ void *UpdateThread::run()
!val["text"].isString() || !val["url"].isString())
{
LOG_WARN("Error in update check: Bad JSON");
return NULL;
return;
}
update_text = val["text"].asString();
update_url = val["url"].asString();
// Strange bug causing empty dialog boxes and unresponse process
// requires running got_update in the main thread, but whatever:
Fl::awake(got_update, NULL);
return NULL;
// requires running got_update in the main thread, but whatever.
update_new = true;
}
/* Called by main thread only, while holding lock */
static void got_update(void *)
static void show_update()
{
int c = fl_choice2("%s", "Close", "Open in browser", NULL,
update_text.c_str());
@ -135,8 +160,6 @@ static void got_update(void *)
// from fl_digi.h
cb_mnuVisitURL(0, (void *) update_url.c_str());
}
cleanup();
}
} /* namespace update */