Waterfall race condition

* Some methods in waterfall are being called
    before a modem has been instantiated.  Possibly
    due to threads being assigned to separate cpu
    processors.  This cannot happen on h/w with a
    single cpu thread implementation.
pull/1/head
David Freese 2013-10-29 04:46:53 -05:00
rodzic 35a6486a2b
commit f7ea783c0f
1 zmienionych plików z 63 dodań i 86 usunięć

Wyświetl plik

@ -204,6 +204,7 @@ void WFdisp::initMarkers() {
// draw a marker of specified width and colour centred at freq and clrM
inline void WFdisp::makeMarker_(int width, const RGB* color, int freq, const RGB* clrMin, RGB* clrM, const RGB* clrMax)
{
if (!active_modem) return;
trx_mode marker_mode = active_modem->get_mode();
if (marker_mode == MODE_RTTY) {
// rtty has two bandwidth indicators on the waterfall
@ -340,7 +341,6 @@ void WFdisp::makeMarker()
}
}
void WFdisp::makeScale() {
uchar *gmap = scaleimage;
int hwidth = step / 2;
@ -629,7 +629,7 @@ void WFdisp::sig_data( double *sig, int len, int sr )
update_freq:
static char szFrequency[14];
if (rfc != 0) { // use a boolean for the waterfall
if (active_modem && rfc != 0) { // use a boolean for the waterfall
int cwoffset = 0;
int rttyoffset = 0;
trx_mode mode = active_modem->get_mode();
@ -857,7 +857,7 @@ case Step: for (int row = 0; row < image_height; row++) { \
}
#undef UPD_LOOP
if (progdefaults.UseBWTracks) {
if (active_modem && progdefaults.UseBWTracks) {
int bw_lo = bandwidth / 2;
int bw_hi = bandwidth / 2;
trx_mode mode = active_modem->get_mode();
@ -922,7 +922,8 @@ void WFdisp::drawcolorWF() {
update_waterfall();
if (wantcursor && (progdefaults.UseCursorLines || progdefaults.UseCursorCenterLine) ) {
if (active_modem && wantcursor &&
(progdefaults.UseCursorLines || progdefaults.UseCursorCenterLine) ) {
trx_mode mode = active_modem->get_mode();
int bw_lo = bandwidth / 2;
int bw_hi = bandwidth / 2;
@ -960,45 +961,6 @@ void WFdisp::drawcolorWF() {
drawScale();
}
/*
// following method is not used in versions > 3.12
void WFdisp::drawgrayWF() {
uchar *pixmap = (uchar*)fft_img;
update_waterfall();
if (wantcursor && (progdefaults.UseCursorLines || progdefaults.UseCursorCenterLine) ) {
trx_mode mode = active_modem->get_mode();
int bw_lo = bandwidth / 2;
int bw_hi = bandwidth / 2;
if (mode >= MODE_MT63_500S && mode <= MODE_MT63_2000L)
bw_hi = bw_hi * 31 / 32;
RGBI *pos0 = (fft_img + cursorpos);
RGBI *pos1 = (fft_img + cursorpos - bw_lo/step);
RGBI *pos2 = (fft_img + cursorpos + bw_hi/step);
if (pos1 >= fft_img && pos2 < fft_img + disp_width)
for (int y = 0; y < image_height; y ++) {
if (progdefaults.UseCursorLines)
*pos1 = *pos2 = progdefaults.cursorLineRGBI;
if (progdefaults.UseCursorCenterLine)
*pos0 = progdefaults.cursorCenterRGBI;
pos0 += disp_width;
pos1 += disp_width;
pos2 += disp_width;
}
}
fl_color(FL_BLACK);
fl_rectf(x(), y(), w(), WFSCALE + WFMARKER + WFTEXT + image_height);
fl_draw_image_mono(
pixmap + 3,
x(), y() + WFSCALE + WFMARKER + WFTEXT,
disp_width, image_height,
sizeof(RGBI), disp_width * sizeof(RGBI));
drawScale();
}
*/
void WFdisp::drawspectrum() {
int sig;
int ynext,
@ -1040,7 +1002,8 @@ void WFdisp::drawspectrum() {
pos2 += IMAGE_WIDTH/step;
}
}
if (wantcursor && (progdefaults.UseCursorLines || progdefaults.UseCursorCenterLine)) {
if (active_modem && wantcursor &&
(progdefaults.UseCursorLines || progdefaults.UseCursorCenterLine)) {
trx_mode mode = active_modem->get_mode();
int bw_lo = bandwidth / 2;
int bw_hi = bandwidth / 2;
@ -1153,13 +1116,14 @@ void carrier_cb(Fl_Widget *w, void *v) {
int selfreq = (int) cntr->value();
if (selfreq > progdefaults.HighFreqCutoff) selfreq = progdefaults.HighFreqCutoff - wf->wfdisp->Bandwidth() / 2;
stopMacroTimer();
active_modem->set_freq(selfreq);
if (active_modem) active_modem->set_freq(selfreq);
wf->wfdisp->carrier(selfreq);
restoreFocus();
}
void do_qsy(bool dir)
{
if (!active_modem) return;
static vector<qrg_mode_t> qsy_stack;
qrg_mode_t m;
@ -1234,6 +1198,7 @@ void rate_cb(Fl_Widget *w, void *v) {
void xmtrcv_cb(Fl_Widget *w, void *vi)
{
if (!active_modem) return;
FL_LOCK_D();
Fl_Light_Button *b = (Fl_Light_Button *)w;
int v = b->value();
@ -1267,6 +1232,7 @@ void xmtrcv_cb(Fl_Widget *w, void *vi)
void xmtlock_cb(Fl_Widget *w, void *vi)
{
if (!active_modem) return;
FL_LOCK_D();
Fl_Light_Button *b = (Fl_Light_Button *)w;
int v = b->value();
@ -1325,7 +1291,9 @@ void ampspan_cb(Fl_Widget *w, void *v) {
restoreFocus();
}
void btnRev_cb(Fl_Widget *w, void *v) {
void btnRev_cb(Fl_Widget *w, void *v)
{
if (!active_modem) return;
FL_LOCK_D();
waterfall *wf = (waterfall *)w->parent();
Fl_Light_Button *b = (Fl_Light_Button *)w;
@ -1339,6 +1307,7 @@ void btnRev_cb(Fl_Widget *w, void *v) {
void btnMem_cb(Fl_Widget *, void *menu_event)
{
if (!active_modem) return;
static std::vector<qrg_mode_t> qrg_list;
enum { SELECT, APPEND, REPLACE, REMOVE, CLEAR };
int op = SELECT, elem = 0;
@ -1432,6 +1401,7 @@ void btnMem_cb(Fl_Widget *, void *menu_event)
}
void waterfall::opmode() {
if (!active_modem) return;
int val = (int)active_modem->get_bandwidth();
wfdisp->carrier((int)CLAMP(
@ -1513,7 +1483,7 @@ int waterfall::Carrier()
void waterfall::Carrier(int f)
{
active_modem->set_freq(f);
if (active_modem) active_modem->set_freq(f);
}
void waterfall::rfcarrier(long long cf) {
@ -1542,7 +1512,7 @@ void waterfall::USB(bool b) {
if (wfdisp->USB() == b)
return;
wfdisp->USB(b);
active_modem->set_reverse(reverse);
if (active_modem) active_modem->set_reverse(reverse);
REQ(&viewer_redraw);
}
@ -1769,7 +1739,7 @@ int waterfall::handle(int event)
// this does not belong here, but we don't have access to this widget's
// handle method (or its parent's)
if (Fl::event_inside(MODEstatus)) {
if (active_modem && Fl::event_inside(MODEstatus)) {
trx_mode mode = active_modem->get_mode();
for (;;) {
mode = WCLAMP(mode + d, 0, NUM_MODES - 1);
@ -1809,7 +1779,7 @@ static void hide_cursor(void *w)
void waterfall::insert_text(bool check)
{
if (check) {
if (active_modem && check) {
qrg_mode_t m;
m.rfcarrier = wf->rfcarrier();
m.carrier = active_modem->get_freq();
@ -1836,6 +1806,7 @@ void waterfall::insert_text(bool check)
static void find_signal_text(void)
{
if (!active_modem) return;
int freq = active_modem->get_freq();
trx_mode mode = active_modem->get_mode();
@ -1924,7 +1895,7 @@ int WFdisp::handle(int event)
if (!USB())
newrfc = -newrfc;
newrfc += rfcarrier();
qsy(newrfc, active_modem->get_freq());
qsy(newrfc, active_modem ? active_modem->get_freq() : 1500);
pxpos = xpos;
return 1;
}
@ -1942,14 +1913,16 @@ int WFdisp::handle(int event)
if (progdefaults.WaterfallHistoryDefault)
bHistory = true;
newcarrier = cursorFreq(xpos);
newcarrier = (int)CLAMP(
newcarrier,
progdefaults.LowFreqCutoff + active_modem->get_bandwidth() / 2,
progdefaults.HighFreqCutoff - active_modem->get_bandwidth() / 2);
active_modem->set_freq(newcarrier);
viewer_paste_freq(newcarrier);
if (!(Fl::event_state() & FL_SHIFT))
active_modem->set_sigsearch(SIGSEARCH);
if (active_modem) {
newcarrier = (int)CLAMP(
newcarrier,
progdefaults.LowFreqCutoff + active_modem->get_bandwidth() / 2,
progdefaults.HighFreqCutoff - active_modem->get_bandwidth() / 2);
active_modem->set_freq(newcarrier);
viewer_paste_freq(newcarrier);
if (!(Fl::event_state() & FL_SHIFT))
active_modem->set_sigsearch(SIGSEARCH);
}
redrawCursor();
restoreFocus();
break;
@ -1968,7 +1941,7 @@ int WFdisp::handle(int event)
switch (eb = Fl::event_button()) {
case FL_RIGHT_MOUSE:
tmp_carrier = false;
active_modem->set_freq(oldcarrier);
if (active_modem) active_modem->set_freq(oldcarrier);
redrawCursor();
restoreFocus();
// fall through
@ -2026,11 +1999,13 @@ int WFdisp::handle(int event)
case FL_Left: case FL_Right:
if (k == FL_Left)
d = -d;
oldcarrier = newcarrier = (int)CLAMP(
carrier() + d,
progdefaults.LowFreqCutoff + active_modem->get_bandwidth() / 2,
progdefaults.HighFreqCutoff - active_modem->get_bandwidth() / 2);
active_modem->set_freq(newcarrier);
if (active_modem) {
oldcarrier = newcarrier = (int)CLAMP(
carrier() + d,
progdefaults.LowFreqCutoff + active_modem->get_bandwidth() / 2,
progdefaults.HighFreqCutoff - active_modem->get_bandwidth() / 2);
active_modem->set_freq(newcarrier);
}
redrawCursor();
break;
case FL_Tab:
@ -2081,30 +2056,32 @@ void waterfall::handle_mouse_wheel(int what, int d)
return;
case WF_AFC_BW:
{
trx_mode m = active_modem->get_mode();
if (m >= MODE_PSK_FIRST && m <= MODE_PSK_LAST)
val = mailserver ? cntServerOffset : cntSearchRange;
else if (m >= MODE_HELL_FIRST && m <= MODE_HELL_LAST)
val = sldrHellBW;
else if (m >= MODE_HELL_FIRST && m <= MODE_HELL_LAST) {
val = sldrHellBW;
msg_label = "BW";
if (active_modem) {
trx_mode m = active_modem->get_mode();
if (m >= MODE_PSK_FIRST && m <= MODE_PSK_LAST) {
val = mailserver ? cntServerOffset : cntSearchRange;
msg_label = "Srch Rng";
}
else if (m >= MODE_HELL_FIRST && m <= MODE_HELL_LAST) {
val = sldrHellBW;
msg_label = "BW";
}
else if (m == MODE_CW) {
val = sldrCWbandwidth;
msg_label = "BW";
}
else
return;
msg_fmt = "%s: %2.0f Hz";
}
else if (m == MODE_CW) {
val = sldrCWbandwidth;
msg_label = "BW";
}
else
return;
msg_fmt = "%s = %2.0f Hz";
msg_label = val->label();
break;
}
case WF_SIGNAL_SEARCH:
if (d > 0)
active_modem->searchDown();
else
active_modem->searchUp();
if (d > 0) {
if (active_modem) active_modem->searchDown();
} else {
if (active_modem) active_modem->searchUp();
}
return;
case WF_SQUELCH:
val = sldrSquelch;
@ -2128,7 +2105,7 @@ void waterfall::handle_mouse_wheel(int what, int d)
val->do_callback();
progdefaults.changed = changed_save;
if (val == cntServerOffset || val == cntSearchRange)
active_modem->set_sigsearch(SIGSEARCH);
if (active_modem) active_modem->set_sigsearch(SIGSEARCH);
else if (val == sldrSquelch) // sldrSquelch gives focus to TransmitText
take_focus();