kopia lustrzana https://github.com/Hamlib/Hamlib
Add mutex for rig_send_morse and when locked use cache
for rig_get_freq, rig_get_mode, rig_get_vfo, and rig_get_split_vfo Might need to add more down the road https://github.com/Hamlib/Hamlib/issues/1514pull/1522/head
rodzic
25ee5d65d5
commit
c68ef118e9
92
src/rig.c
92
src/rig.c
|
@ -174,16 +174,33 @@ const char hamlib_copyright[231] = /* hamlib 1.2 ABI specifies 231 bytes */
|
|||
|
||||
#define LOCK(n) if (rig->state.depth == 1) { rig_debug(RIG_DEBUG_CACHE, "%s: %s\n", n?"lock":"unlock", __func__); rig_lock(rig,n); }
|
||||
|
||||
#ifdef PTHREAD
|
||||
#ifdef HAVE_PTHREAD
|
||||
#define MUTEX(var) static pthread_mutex_t var = PTHREAD_MUTEX_INITIALIZER
|
||||
#define MUTEX_LOCK(var) pthread_mutex_lock(var)
|
||||
#define MUTEX_UNLOCK(var) pthread_mutex_unlock(var)
|
||||
#define MUTEX_LOCK(var) pthread_mutex_lock(&var)
|
||||
#define MUTEX_UNLOCK(var) pthread_mutex_unlock(&var)
|
||||
#else
|
||||
#warning NOT PTHREAD
|
||||
#define MUTEX(var)
|
||||
#define MUTEX_LOCK(var)
|
||||
#define MUTEX_UNLOCK(var)
|
||||
#endif
|
||||
|
||||
MUTEX(morse_mutex);
|
||||
|
||||
// returns true if mutex is busy
|
||||
int MUTEX_CHECK(pthread_mutex_t *m)
|
||||
{
|
||||
int trylock = pthread_mutex_trylock(m);
|
||||
|
||||
if (trylock != EBUSY)
|
||||
{
|
||||
pthread_mutex_unlock(m);
|
||||
}
|
||||
|
||||
return trylock == EBUSY;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Data structure to track the opened rig (by rig_open)
|
||||
*/
|
||||
|
@ -358,7 +375,7 @@ char debugmsgsave[DEBUGMSGSAVE_SIZE] = "";
|
|||
char debugmsgsave2[DEBUGMSGSAVE_SIZE] = ""; // deprecated
|
||||
char debugmsgsave3[DEBUGMSGSAVE_SIZE] = ""; // deprecated
|
||||
|
||||
MUTEX(debugmsgsave);
|
||||
MUTEX(mutex_debugmsgsave);
|
||||
|
||||
void add2debugmsgsave(const char *s)
|
||||
{
|
||||
|
@ -366,7 +383,7 @@ void add2debugmsgsave(const char *s)
|
|||
char stmp[DEBUGMSGSAVE_SIZE];
|
||||
int i, nlines;
|
||||
int maxmsg = DEBUGMSGSAVE_SIZE / 2;
|
||||
MUTEX_LOCK(debugmsgsave);
|
||||
MUTEX_LOCK(mutex_debugmsgsave);
|
||||
memset(stmp, 0, sizeof(stmp));
|
||||
|
||||
// we'll keep 20 lines including this one
|
||||
|
@ -409,7 +426,7 @@ void add2debugmsgsave(const char *s)
|
|||
(int)strlen(debugmsgsave), (int)strlen(s));
|
||||
}
|
||||
|
||||
MUTEX_UNLOCK(debugmsgsave);
|
||||
MUTEX_UNLOCK(mutex_debugmsgsave);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -2322,6 +2339,7 @@ int HAMLIB_API rig_get_freq(RIG *rig, vfo_t vfo, freq_t *freq)
|
|||
rmode_t mode;
|
||||
pbwidth_t width;
|
||||
int curr_band;
|
||||
int use_cache = 0;
|
||||
static int last_band = -1;
|
||||
|
||||
if (CHECK_RIG_ARG(rig))
|
||||
|
@ -2360,12 +2378,18 @@ int HAMLIB_API rig_get_freq(RIG *rig, vfo_t vfo, freq_t *freq)
|
|||
rig_debug(RIG_DEBUG_VERBOSE, "%s(%d) vfo=%s, curr_vfo=%s\n", __FILE__, __LINE__,
|
||||
rig_strvfo(vfo), rig_strvfo(curr_vfo));
|
||||
|
||||
if (MUTEX_CHECK(&morse_mutex))
|
||||
{
|
||||
use_cache = 1;
|
||||
}
|
||||
|
||||
if (vfo == RIG_VFO_CURR) { vfo = curr_vfo; }
|
||||
|
||||
// we ignore get_freq for the uplink VFO for gpredict to behave better
|
||||
if ((rig->state.uplink == 1 && vfo == RIG_VFO_SUB)
|
||||
|| (rig->state.uplink == 2 && vfo == RIG_VFO_MAIN)
|
||||
|| (vfo == RIG_VFO_TX && cachep->ptt == 0))
|
||||
|| (vfo == RIG_VFO_TX && cachep->ptt == 0)
|
||||
|| use_cache)
|
||||
{
|
||||
rig_debug(RIG_DEBUG_TRACE, "%s: uplink=%d, ignoring get_freq\n", __func__,
|
||||
rig->state.uplink);
|
||||
|
@ -2717,7 +2741,8 @@ int HAMLIB_API rig_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width)
|
|||
retcode = caps->get_mode(rig, vfo, &mode_curr, &width_curr);
|
||||
|
||||
// For Icom rigs we may need to force the filter so we always set mode
|
||||
if (retcode == RIG_OK && mode == mode_curr && RIG_ICOM != RIG_BACKEND_NUM(rig->caps->rig_model))
|
||||
if (retcode == RIG_OK && mode == mode_curr
|
||||
&& RIG_ICOM != RIG_BACKEND_NUM(rig->caps->rig_model))
|
||||
{
|
||||
rig_debug(RIG_DEBUG_VERBOSE,
|
||||
"%s: mode already %s and bw change not requested\n", __func__,
|
||||
|
@ -2842,6 +2867,7 @@ int HAMLIB_API rig_get_mode(RIG *rig,
|
|||
{
|
||||
const struct rig_caps *caps;
|
||||
int retcode;
|
||||
int use_cache = 0;
|
||||
freq_t freq;
|
||||
vfo_t curr_vfo;
|
||||
struct rig_cache *cachep = CACHE(rig);
|
||||
|
@ -2871,6 +2897,7 @@ int HAMLIB_API rig_get_mode(RIG *rig,
|
|||
|
||||
curr_vfo = rig->state.current_vfo;
|
||||
vfo = vfo_fixup(rig, vfo, cachep->split);
|
||||
|
||||
if (vfo == RIG_VFO_CURR) { vfo = curr_vfo; }
|
||||
|
||||
*mode = RIG_MODE_NONE;
|
||||
|
@ -2883,8 +2910,13 @@ int HAMLIB_API rig_get_mode(RIG *rig,
|
|||
|
||||
rig_cache_show(rig, __func__, __LINE__);
|
||||
|
||||
if (MUTEX_CHECK(&morse_mutex))
|
||||
{
|
||||
use_cache = 1;
|
||||
}
|
||||
|
||||
if (cachep->timeout_ms == HAMLIB_CACHE_ALWAYS
|
||||
|| rig->state.use_cached_mode)
|
||||
|| rig->state.use_cached_mode || use_cache)
|
||||
{
|
||||
rig_debug(RIG_DEBUG_TRACE, "%s: cache hit age mode=%dms, width=%dms\n",
|
||||
__func__, cache_ms_mode, cache_ms_width);
|
||||
|
@ -3305,6 +3337,7 @@ int HAMLIB_API rig_get_vfo(RIG *rig, vfo_t *vfo)
|
|||
struct rig_cache *cachep = CACHE(rig);
|
||||
int retcode = -RIG_EINTERNAL;
|
||||
int cache_ms;
|
||||
int use_cache = 0;
|
||||
|
||||
if (CHECK_RIG_ARG(rig) || !vfo)
|
||||
{
|
||||
|
@ -3328,7 +3361,12 @@ int HAMLIB_API rig_get_vfo(RIG *rig, vfo_t *vfo)
|
|||
cache_ms = elapsed_ms(&cachep->time_vfo, HAMLIB_ELAPSED_GET);
|
||||
//rig_debug(RIG_DEBUG_TRACE, "%s: cache check age=%dms\n", __func__, cache_ms);
|
||||
|
||||
if (cache_ms < cachep->timeout_ms)
|
||||
if (MUTEX_CHECK(&morse_mutex))
|
||||
{
|
||||
use_cache = 1;
|
||||
}
|
||||
|
||||
if (cache_ms < cachep->timeout_ms || use_cache)
|
||||
{
|
||||
*vfo = cachep->vfo;
|
||||
rig_debug(RIG_DEBUG_TRACE, "%s: cache hit age=%dms, vfo=%s\n", __func__,
|
||||
|
@ -4529,7 +4567,8 @@ int HAMLIB_API rig_set_split_freq(RIG *rig, vfo_t vfo, freq_t tx_freq)
|
|||
// Always use the previously selected TX VFO for split. The targeted VFO will have no effect.
|
||||
tx_vfo = rs->tx_vfo;
|
||||
|
||||
if (cachep->split == RIG_SPLIT_OFF || tx_vfo == RIG_VFO_NONE || tx_vfo == RIG_VFO_CURR)
|
||||
if (cachep->split == RIG_SPLIT_OFF || tx_vfo == RIG_VFO_NONE
|
||||
|| tx_vfo == RIG_VFO_CURR)
|
||||
{
|
||||
// Turn split on if not enabled already
|
||||
retcode = rig_set_split_vfo(rig, rs->current_vfo, RIG_SPLIT_ON, vfo_fixup(rig,
|
||||
|
@ -4718,7 +4757,8 @@ int HAMLIB_API rig_get_split_freq(RIG *rig, vfo_t vfo, freq_t *tx_freq)
|
|||
// Always use the previously selected TX VFO for split. The targeted VFO will have no effect.
|
||||
tx_vfo = rs->tx_vfo;
|
||||
|
||||
if (cachep->split == RIG_SPLIT_OFF || tx_vfo == RIG_VFO_NONE || tx_vfo == RIG_VFO_CURR)
|
||||
if (cachep->split == RIG_SPLIT_OFF || tx_vfo == RIG_VFO_NONE
|
||||
|| tx_vfo == RIG_VFO_CURR)
|
||||
{
|
||||
// Split frequency not available if split is off
|
||||
*tx_freq = 0;
|
||||
|
@ -4894,7 +4934,8 @@ int HAMLIB_API rig_set_split_mode(RIG *rig,
|
|||
// Always use the previously selected TX VFO for split. The targeted VFO will have no effect.
|
||||
tx_vfo = rs->tx_vfo;
|
||||
|
||||
if (cachep->split == RIG_SPLIT_OFF || tx_vfo == RIG_VFO_NONE || tx_vfo == RIG_VFO_CURR)
|
||||
if (cachep->split == RIG_SPLIT_OFF || tx_vfo == RIG_VFO_NONE
|
||||
|| tx_vfo == RIG_VFO_CURR)
|
||||
{
|
||||
// Turn split on if not enabled already
|
||||
retcode = rig_set_split_vfo(rig, rs->current_vfo, RIG_SPLIT_ON, vfo_fixup(rig,
|
||||
|
@ -5130,7 +5171,8 @@ int HAMLIB_API rig_get_split_mode(RIG *rig, vfo_t vfo, rmode_t *tx_mode,
|
|||
// Always use the previously selected TX VFO for split. The targeted VFO will have no effect.
|
||||
tx_vfo = rs->tx_vfo;
|
||||
|
||||
if (cachep->split == RIG_SPLIT_OFF || tx_vfo == RIG_VFO_NONE || tx_vfo == RIG_VFO_CURR)
|
||||
if (cachep->split == RIG_SPLIT_OFF || tx_vfo == RIG_VFO_NONE
|
||||
|| tx_vfo == RIG_VFO_CURR)
|
||||
{
|
||||
// Split mode and filter width are not available if split is off
|
||||
*tx_mode = RIG_MODE_NONE;
|
||||
|
@ -5289,7 +5331,8 @@ int HAMLIB_API rig_set_split_freq_mode(RIG *rig,
|
|||
// Always use the previously selected TX VFO for split. The targeted VFO will have no effect.
|
||||
tx_vfo = rs->tx_vfo;
|
||||
|
||||
if (cachep->split == RIG_SPLIT_OFF || tx_vfo == RIG_VFO_NONE || tx_vfo == RIG_VFO_CURR)
|
||||
if (cachep->split == RIG_SPLIT_OFF || tx_vfo == RIG_VFO_NONE
|
||||
|| tx_vfo == RIG_VFO_CURR)
|
||||
{
|
||||
// Turn split on if not enabled already
|
||||
retcode = rig_set_split_vfo(rig, rs->current_vfo, RIG_SPLIT_ON, vfo_fixup(rig,
|
||||
|
@ -5435,7 +5478,8 @@ int HAMLIB_API rig_get_split_freq_mode(RIG *rig,
|
|||
// Always use the previously selected TX VFO for split. The targeted VFO will have no effect.
|
||||
tx_vfo = rs->tx_vfo;
|
||||
|
||||
if (cachep->split == RIG_SPLIT_OFF || tx_vfo == RIG_VFO_NONE || tx_vfo == RIG_VFO_CURR)
|
||||
if (cachep->split == RIG_SPLIT_OFF || tx_vfo == RIG_VFO_NONE
|
||||
|| tx_vfo == RIG_VFO_CURR)
|
||||
{
|
||||
// Split frequency, mode and filter width are not available if split is off
|
||||
*tx_freq = 0;
|
||||
|
@ -5634,6 +5678,7 @@ int HAMLIB_API rig_set_split_vfo(RIG *rig,
|
|||
// Only update cache on success
|
||||
rs->rx_vfo = rs->current_vfo;
|
||||
cachep->split = split;
|
||||
|
||||
if (split == RIG_SPLIT_OFF)
|
||||
{
|
||||
rs->tx_vfo = rs->current_vfo;
|
||||
|
@ -5692,6 +5737,7 @@ int HAMLIB_API rig_set_split_vfo(RIG *rig,
|
|||
{
|
||||
// Only update cache on success
|
||||
cachep->split = split;
|
||||
|
||||
if (split == RIG_SPLIT_OFF)
|
||||
{
|
||||
if (caps->targetable_vfo & RIG_TARGETABLE_FREQ)
|
||||
|
@ -5746,6 +5792,7 @@ int HAMLIB_API rig_get_split_vfo(RIG *rig,
|
|||
struct rig_cache *cachep = CACHE(rig);
|
||||
int retcode;
|
||||
int cache_ms;
|
||||
int use_cache;
|
||||
|
||||
if (CHECK_RIG_ARG(rig))
|
||||
{
|
||||
|
@ -5767,14 +5814,16 @@ int HAMLIB_API rig_get_split_vfo(RIG *rig,
|
|||
caps = rig->caps;
|
||||
rs = &rig->state;
|
||||
|
||||
if (caps->get_split_vfo == NULL)
|
||||
if (MUTEX_CHECK(&morse_mutex))
|
||||
{
|
||||
use_cache = 1;
|
||||
}
|
||||
|
||||
if (caps->get_split_vfo == NULL || use_cache)
|
||||
{
|
||||
// if we can't get the vfo we will return whatever we have cached
|
||||
*split = cachep->split;
|
||||
*tx_vfo = cachep->split_vfo;
|
||||
rig_debug(RIG_DEBUG_VERBOSE,
|
||||
"%s: no get_split_vfo so returning split=%d, tx_vfo=%s\n", __func__, *split,
|
||||
rig_strvfo(*tx_vfo));
|
||||
ELAPSED2;
|
||||
RETURNFUNC(RIG_OK);
|
||||
}
|
||||
|
@ -8560,6 +8609,7 @@ void *morse_data_handler(void *arg)
|
|||
if (strlen(c) > 0)
|
||||
{
|
||||
int nloops = 10;
|
||||
MUTEX_LOCK(morse_mutex);
|
||||
|
||||
do
|
||||
{
|
||||
|
@ -8585,6 +8635,8 @@ void *morse_data_handler(void *arg)
|
|||
}
|
||||
while (result != RIG_OK && rig->state.fifo_morse->flush == 0 && --nloops > 0);
|
||||
|
||||
MUTEX_UNLOCK(morse_mutex);
|
||||
|
||||
if (nloops == 0)
|
||||
{
|
||||
rig_debug(RIG_DEBUG_ERR, "%s: send_morse failed\n", __func__);
|
||||
|
|
Ładowanie…
Reference in New Issue