Use std::bind if available

pull/2/head
Stelios Bounanos 2008-01-02 20:42:16 +00:00
rodzic d3849ae877
commit 0dc1e2357e
7 zmienionych plików z 90 dodań i 117 usunięć

Wyświetl plik

@ -1,6 +1,8 @@
Change Log: Change Log:
2.08 1) Use PortAudio's C API; the C++ bindings are no longer required 2.08 1) Use PortAudio's C API; the C++ bindings are no longer required
2) Boost is no longer required when std::(tr1::)bind is available, as is
the case with g++ >= 4.0
2.07 1) bug fix for mode changes via SysV interface (pskmail / flarq) 2.07 1) bug fix for mode changes via SysV interface (pskmail / flarq)
2) bug fix for modem configuration post quick change from status 2) bug fix for modem configuration post quick change from status

Wyświetl plik

@ -3,10 +3,12 @@ Installation Instructions for fldigi
To compile fldigi you will need: To compile fldigi you will need:
* version 1.1.x of the Fast Light Tool Kit (FLTK), with its * A recent C++ compiler. The GNU C++ compilers in the 4.x series are
development libraries and headers, and known to work. Building with g++ 3.x requires the development files
for the Boost C++ library.
* the development files for the Boost C++ library. * Version 1.1.x of the Fast Light Tool Kit (FLTK), with its
development libraries and headers.
You should also install the libraries and headers for PortAudio, the You should also install the libraries and headers for PortAudio, the
Portable audio I/O library. It is possible, but not recommended, to Portable audio I/O library. It is possible, but not recommended, to

Wyświetl plik

@ -110,11 +110,43 @@ fi
########################### ###########################
# Boost # bind
########################### ###########################
AX_BOOST_BASE(1.32.0) # Look for a working std::bind or std::tr1::bind. If neither is present
if test "x$want_boost" = "xno"; then # we will need Boost >= 1.32.0, which provides boost::bind.
AC_MSG_ERROR([Boost is required]) AC_LANG_PUSH(C++)
AC_MSG_CHECKING([for std::bind in <functional>])
AC_COMPILE_IFELSE( [AC_LANG_PROGRAM([[#include <functional>
void f(void) { }]],
[[std::bind(f)();]])],
[ac_cv_std_bind=yes], [ac_cv_std_bind=no] )
AC_MSG_RESULT([$ac_cv_std_bind])
if test "x$ac_cv_std_bind" = "xyes"; then
AC_DEFINE(HAVE_STD_BIND, 1, [Define to 1 if we have std::bind in <functional>])
else
AC_DEFINE(HAVE_STD_BIND, 0, [Define to 1 if we have std::bind in <functional>])
fi
if test "x$ac_cv_std_bind" = "xno"; then
AC_MSG_CHECKING([for std::tr1::bind in <tr1/functional>])
AC_COMPILE_IFELSE( [AC_LANG_PROGRAM([[#include <tr1/functional>
void f(void) { }]],
[[std::tr1::bind(f)();]])],
[ac_cv_std_tr1_bind=yes], [ac_cv_std_tr1_bind=no] )
AC_MSG_RESULT([$ac_cv_std_tr1_bind])
if test "x$ac_cv_std_tr1_bind" = "xyes"; then
AC_DEFINE(HAVE_STD_TR1_BIND, 1, [Define to 1 if we have std::tr1::bind in <tr1/functional>])
else
AC_DEFINE(HAVE_STD_TR1_BIND, 0, [Define to 1 if we have std::tr1::bind in <tr1/functional>])
fi
fi
AC_LANG_POP(C++)
if test "x$ac_cv_std_bind" = "xno" && test "x$ac_cv_std_tr1_bind" = "xno"; then
AX_BOOST_BASE(1.32.0)
if test "x$want_boost" = "xno"; then
AC_MSG_ERROR([Boost is required])
fi
fi fi
########################### ###########################
@ -178,22 +210,22 @@ AC_ARG_WITH([sndfile],
esac], esac],
[ac_cv_want_sndfile=check]) [ac_cv_want_sndfile=check])
if test "x$ac_cv_want_sndfile" = "xno"; then if test "x$ac_cv_want_sndfile" = "xno"; then
AC_DEFINE(USE_SNDFILE, 0, [Set to 1 if we are using sndfile, 0 otherwise]) AC_DEFINE(USE_SNDFILE, 0, [Define to 1 if we are using sndfile])
ac_cv_sndfile=no ac_cv_sndfile=no
else else
PKG_CHECK_EXISTS(sndfile >= 1.0.10, ac_cv_sndfile=yes, ac_cv_sndfile=no) PKG_CHECK_EXISTS(sndfile >= 1.0.10, ac_cv_sndfile=yes, ac_cv_sndfile=no)
if test "x$ac_cv_want_sndfile" = "xcheck"; then if test "x$ac_cv_want_sndfile" = "xcheck"; then
PKG_CHECK_MODULES(SNDFILE, sndfile >= 1.0.10, [:], [:]) PKG_CHECK_MODULES(SNDFILE, sndfile >= 1.0.10, [:], [:])
if test "x$ac_cv_sndfile" = "xyes"; then if test "x$ac_cv_sndfile" = "xyes"; then
AC_DEFINE(USE_SNDFILE, 1, [Set to 1 if we are using sndfile, 0 otherwise]) AC_DEFINE(USE_SNDFILE, 1, [Define to 1 if we are using sndfile])
else else
AC_DEFINE(USE_SNDFILE, 0, [Set to 1 if we are using sndfile, 0 otherwise]) AC_DEFINE(USE_SNDFILE, 0, [Define to 1 if we are using sndfile])
fi fi
else # $ac_cv_want_sndfile is yes else # $ac_cv_want_sndfile is yes
if test "x$ac_cv_sndfile" = "xno"; then if test "x$ac_cv_sndfile" = "xno"; then
AC_MSG_NOTICE([--with-sndfile was given, but test for sndfile failed]) AC_MSG_NOTICE([--with-sndfile was given, but test for sndfile failed])
else else
AC_DEFINE(USE_SNDFILE, 1, [Set to 1 if we are using sndfile, 0 otherwise]) AC_DEFINE(USE_SNDFILE, 1, [Define to 1 if we are using sndfile])
fi fi
PKG_CHECK_MODULES(SNDFILE, sndfile >= 1.0.10) # for the error message PKG_CHECK_MODULES(SNDFILE, sndfile >= 1.0.10) # for the error message
fi fi
@ -216,13 +248,13 @@ AC_ARG_WITH([portaudio],
if test "x$ac_cv_want_portaudio" = "xyes"; then if test "x$ac_cv_want_portaudio" = "xyes"; then
PKG_CHECK_EXISTS(portaudio-2.0 >= 19, ac_cv_portaudio=yes, ac_cv_portaudio=no) PKG_CHECK_EXISTS(portaudio-2.0 >= 19, ac_cv_portaudio=yes, ac_cv_portaudio=no)
if test "x$ac_cv_portaudio" = "xyes"; then if test "x$ac_cv_portaudio" = "xyes"; then
AC_DEFINE(USE_PORTAUDIO, 1, [Set to 1 if we are using PortAudio, 0 otherwise]) AC_DEFINE(USE_PORTAUDIO, 1, [Define to 1 if we are using PortAudio])
else else
AC_MSG_NOTICE([portaudio test failed (use --without-portaudio to disable)]) AC_MSG_NOTICE([portaudio test failed (use --without-portaudio to disable)])
fi fi
PKG_CHECK_MODULES(PORTAUDIO, portaudio-2.0 >= 19) PKG_CHECK_MODULES(PORTAUDIO, portaudio-2.0 >= 19)
else else
AC_DEFINE(USE_PORTAUDIO, 0, [Set to 1 if we are using PortAudio, 0 otherwise]) AC_DEFINE(USE_PORTAUDIO, 0, [Define to 1 if we are using PortAudio])
ac_cv_portaudio=no ac_cv_portaudio=no
fi fi
AC_SUBST([PORTAUDIO_CFLAGS]) AC_SUBST([PORTAUDIO_CFLAGS])
@ -248,15 +280,15 @@ else
if test "x$ac_cv_want_hamlib" = "xcheck"; then if test "x$ac_cv_want_hamlib" = "xcheck"; then
PKG_CHECK_MODULES(HAMLIB, hamlib >= 1.2.0, [:], [:]) PKG_CHECK_MODULES(HAMLIB, hamlib >= 1.2.0, [:], [:])
if test "x$ac_cv_hamlib" = "xyes"; then if test "x$ac_cv_hamlib" = "xyes"; then
AC_DEFINE(USE_HAMLIB, 1, [Set to 1 if we are using hamlib, 0 otherwise]) AC_DEFINE(USE_HAMLIB, 1, [Define to 1 if we are using hamlib])
else else
AC_DEFINE(USE_HAMLIB, 0, [Set to 1 if we are using hamlib, 0 otherwise]) AC_DEFINE(USE_HAMLIB, 0, [Define to 1 if we are using hamlib])
fi fi
else # $ac_cv_want_hamlib is yes else # $ac_cv_want_hamlib is yes
if test "x$ac_cv_hamlib" = "xno"; then if test "x$ac_cv_hamlib" = "xno"; then
AC_MSG_NOTICE([--with-hamlib was given, but test for hamlib failed]) AC_MSG_NOTICE([--with-hamlib was given, but test for hamlib failed])
else else
AC_DEFINE(USE_HAMLIB, 1, [Set to 1 if we are using hamlib, 0 otherwise]) AC_DEFINE(USE_HAMLIB, 1, [Define to 1 if we are using hamlib])
fi fi
PKG_CHECK_MODULES(HAMLIB, hamlib >= 1.2.0) # for the error message PKG_CHECK_MODULES(HAMLIB, hamlib >= 1.2.0) # for the error message
fi fi

Wyświetl plik

@ -36,7 +36,7 @@
AC_DEFUN([AX_BOOST_BASE], AC_DEFUN([AX_BOOST_BASE],
[ [
AC_ARG_WITH([boost], AC_ARG_WITH([boost],
AS_HELP_STRING([--with-boost=DIR], [specify the root directory for boost]), AS_HELP_STRING([--with-boost=DIR], [specify the root directory for boost @<:@autodetect@:>@]),
[ [
if test "$withval" = "no"; then if test "$withval" = "no"; then
want_boost="no" want_boost="no"

Wyświetl plik

@ -7,7 +7,7 @@ AM_CPPFLAGS = -I$(srcdir) -I$(srcdir)/include -I$(srcdir)/irrxml @BOOST_CPPFLAGS
AM_CXXFLAGS = @FLTK_CFLAGS@ @PORTAUDIO_CFLAGS@ @SNDFILE_CFLAGS@ \ AM_CXXFLAGS = @FLTK_CFLAGS@ @PORTAUDIO_CFLAGS@ @SNDFILE_CFLAGS@ \
@SAMPLERATE_CFLAGS@ @HAMLIB_CFLAGS@ \ @SAMPLERATE_CFLAGS@ @HAMLIB_CFLAGS@ \
-pipe -Wall -O2 -ffast-math -fno-rtti -fexceptions -finline-functions -pipe -Wall -O2 -ffast-math -fexceptions -finline-functions
AM_CFLAGS = $(AM_CXXFLAGS) AM_CFLAGS = $(AM_CXXFLAGS)
LDADD = @BOOST_LDFLAGS@ @FLTK_LIBS@ @PORTAUDIO_LIBS@ @SNDFILE_LIBS@ \ LDADD = @BOOST_LDFLAGS@ @FLTK_LIBS@ @PORTAUDIO_LIBS@ @SNDFILE_LIBS@ \

Wyświetl plik

@ -1202,7 +1202,7 @@ void put_Bandwidth(int bandwidth)
void display_metric(double metric) void display_metric(double metric)
{ {
FL_LOCK_D(); FL_LOCK_D();
QUEUE(CMP_CB(&Fl_Progress::value, pgrsSquelch, metric)); //pgrsSquelch->value(metric); QUEUE(CMP_CB(static_cast<void (Fl_Progress::*)(float)>(&Fl_Progress::value), pgrsSquelch, metric)); //pgrsSquelch->value(metric);
FL_UNLOCK_D(); FL_UNLOCK_D();
FL_AWAKE_D(); FL_AWAKE_D();
} }
@ -1213,8 +1213,8 @@ void put_cwRcvWPM(double wpm)
int L = progdefaults.CWlowerlimit; int L = progdefaults.CWlowerlimit;
double dWPM = 100.0*(wpm - L)/(U - L); double dWPM = 100.0*(wpm - L)/(U - L);
FL_LOCK_D(); FL_LOCK_D();
QUEUE(CMP_CB(&Fl_Progress::value, prgsCWrcvWPM, dWPM)); //prgsCWrcvWPM->value(dWPM); QUEUE(CMP_CB(static_cast<void (Fl_Progress::*)(float)>(&Fl_Progress::value), prgsCWrcvWPM, dWPM)); //prgsCWrcvWPM->value(dWPM);
QUEUE(CMP_CB(&Fl_Value_Output::value, valCWrcvWPM, (int)wpm)); //valCWrcvWPM->value((int)wpm); QUEUE(CMP_CB(static_cast<int (Fl_Value_Output::*)(double)>(&Fl_Value_Output::value), valCWrcvWPM, (int)wpm)); //valCWrcvWPM->value((int)wpm);
FL_UNLOCK_D(); FL_UNLOCK_D();
FL_AWAKE_D(); FL_AWAKE_D();
} }
@ -1295,7 +1295,7 @@ void put_sec_char( char chr )
if (strSecText.length() > 60) if (strSecText.length() > 60)
strSecText.erase(0,1); strSecText.erase(0,1);
FL_LOCK_D(); FL_LOCK_D();
QUEUE(CMP_CB(&Fl_Box::label, StatusBar, strSecText.c_str())); //StatusBar->label(strSecText.c_str()); QUEUE(CMP_CB(static_cast<void (Fl_Box::*)(const char *)>(&Fl_Box::label), StatusBar, strSecText.c_str())); //StatusBar->label(strSecText.c_str());
FL_UNLOCK_D(); FL_UNLOCK_D();
FL_AWAKE_D(); FL_AWAKE_D();
} }
@ -1313,7 +1313,7 @@ void put_status(const char *msg, double timeout)
m[sizeof(m) - 1] = '\0'; m[sizeof(m) - 1] = '\0';
FL_LOCK_D(); FL_LOCK_D();
QUEUE(CMP_CB(&Fl_Box::label, StatusBar, m)); // StatusBar->label(m); QUEUE(CMP_CB(static_cast<void (Fl_Box::*)(const char *)>(&Fl_Box::label), StatusBar, m)); // StatusBar->label(m);
// While it is safe to call to use Fl::add_timeout without qrunner // While it is safe to call to use Fl::add_timeout without qrunner
// regardless of our caller's context, queuing ensures that clear_status_cb // regardless of our caller's context, queuing ensures that clear_status_cb
// really gets called at least ``timeout'' seconds after the label is set. // really gets called at least ``timeout'' seconds after the label is set.
@ -1332,7 +1332,7 @@ void put_Status2(const char *msg)
m[sizeof(m) - 1] = '\0'; m[sizeof(m) - 1] = '\0';
FL_LOCK_D(); FL_LOCK_D();
QUEUE(CMP_CB(&Fl_Box::label, Status2, m)); //Status2->label(m); QUEUE(CMP_CB(static_cast<void (Fl_Box::*)(const char *)>(&Fl_Box::label), Status2, m)); //Status2->label(m);
FL_UNLOCK_D(); FL_UNLOCK_D();
FL_AWAKE_D(); FL_AWAKE_D();
} }
@ -1344,7 +1344,7 @@ void put_Status1(const char *msg)
m[sizeof(m) - 1] = '\0'; m[sizeof(m) - 1] = '\0';
FL_LOCK_D(); FL_LOCK_D();
QUEUE(CMP_CB(&Fl_Box::label, Status1, m)); //Status1->label(m); QUEUE(CMP_CB(static_cast<void (Fl_Box::*)(const char *)>(&Fl_Box::label), Status1, m)); //Status1->label(m);
FL_UNLOCK_D(); FL_UNLOCK_D();
FL_AWAKE_D(); FL_AWAKE_D();
} }
@ -1387,7 +1387,7 @@ void clear_StatusMessages()
void put_MODEstatus(trx_mode mode) void put_MODEstatus(trx_mode mode)
{ {
FL_LOCK_D(); FL_LOCK_D();
QUEUE(CMP_CB(&Fl_Button::label, MODEstatus, mode_info[mode].sname)); //MODEstatus->label(mode_names[mode]); QUEUE(CMP_CB(static_cast<void (Fl_Button::*)(const char *)>(&Fl_Button::label), MODEstatus, mode_info[mode].sname)); //MODEstatus->label(mode_names[mode]);
FL_UNLOCK_D(); FL_UNLOCK_D();
FL_AWAKE_D(); FL_AWAKE_D();
} }

Wyświetl plik

@ -24,14 +24,23 @@
#define QRUNNER_H_ #define QRUNNER_H_
#ifndef NDEBUG #ifndef NDEBUG
# include <iostream> # include <iostream>
#endif #endif
#include <errno.h> #include <errno.h>
#include <stdexcept> #include <stdexcept>
#include <cstring> #include <cstring>
#include <boost/bind.hpp>
#include <boost/bind/protect.hpp> #if HAVE_STD_BIND
# include <functional>
using std::bind;
#elif HAVE_STD_TR1_BIND
# include <tr1/functional>
using std::tr1::bind;
#else
# include <boost/bind.hpp>
using boost::bind;
#endif
#include "threads.h" #include "threads.h"
#include "qrunner/fqueue.h" #include "qrunner/fqueue.h"
@ -48,66 +57,24 @@ private:
std::string msg; std::string msg;
}; };
struct signal_after struct fsignal
{ {
typedef void result_type;
Fl_Mutex *m; Fl_Mutex *m;
Fl_Cond *c; Fl_Cond *c;
signal_after(Fl_Mutex *m_, Fl_Cond *c_) : m(m_), c(c_) { } fsignal(Fl_Mutex *m_, Fl_Cond *c_) : m(m_), c(c_) { }
template <typename F> void operator()(void) const
void operator()(const F& f) const
{ {
f();
fl_lock(m); fl_lock(m);
fl_cond_signal(c); fl_cond_signal(c);
fl_unlock(m); fl_unlock(m);
} }
}; };
struct deadline
{
struct timespec dl;
deadline(const struct timespec &dl_) : dl(dl_) { }
template <typename F>
void operator()(const F& f) const
{
struct timespec now;
if (clock_gettime(CLOCK_REALTIME, &now) == -1)
throw qexception(errno);
if (dl > now)
f();
#ifndef NDEBUG
else
std::cerr << "too late for event\n";
#endif
}
};
#ifndef NDEBUG
struct timer
{
struct timespec t;
timer(const struct timespec &t_) : t(t_) { }
template <typename F>
void operator()(const F& f) const
{
struct timespec now;
if (clock_gettime(CLOCK_REALTIME, &now) == -1)
throw qexception(errno);
struct timespec diff = now - t;
std::cout << "t: " << (double)diff.tv_sec + diff.tv_nsec/1e9 << '\n';
f();
}
};
#endif
struct nop struct nop
{ {
typedef void result_type;
void operator()(void) const { } void operator()(void) const { }
}; };
@ -146,13 +113,17 @@ public:
if (!attached) if (!attached)
return request(f, pri); return request(f, pri);
for (;;) {
if (request(f, pri))
break;
sched_yield();
}
Fl_Mutex m = PTHREAD_MUTEX_INITIALIZER; Fl_Mutex m = PTHREAD_MUTEX_INITIALIZER;
Fl_Cond c = PTHREAD_COND_INITIALIZER; Fl_Cond c = PTHREAD_COND_INITIALIZER;
fsignal s(&m, &c);
fl_lock(&m); fl_lock(&m);
signal_after sa(&m, &c);
for (;;) { for (;;) {
if (request(boost::bind<void>(sa, f), pri)) if (request(s, pri))
break; break;
sched_yield(); sched_yield();
} }
@ -162,30 +133,6 @@ public:
return true; return true;
} }
template <typename F>
bool request_dl(const F &f, double dtime, size_t pri = 0)
{
struct timespec now, dl;
if (clock_gettime(CLOCK_REALTIME, &now) == -1)
throw qexception(errno);
dl = now + dtime;
deadline d(dl);
return request(boost::bind<void>(d, f), pri);
}
#ifndef NDEBUG
template <typename F>
bool request_time(const F &f, size_t pri = 0)
{
struct timespec now;
if (clock_gettime(CLOCK_REALTIME, &now) == -1)
throw qexception(errno);
timer t(now);
return request(boost::bind<void>(t, f), pri);
}
#endif
static void execute(int fd, void *arg); static void execute(int fd, void *arg);
void flush(void); void flush(void);
@ -211,29 +158,19 @@ extern qrunner *cbq[NUM_QRUNNER_THREADS];
#define QUEUE_ASYNC(...) \ #define QUEUE_ASYNC(...) \
do { \ do { \
if (GET_THREAD_ID() != FLMAIN_TID) \ if (GET_THREAD_ID() != FLMAIN_TID) \
cbq[GET_THREAD_ID()]->request(boost::bind(__VA_ARGS__)); \ cbq[GET_THREAD_ID()]->request(bind(__VA_ARGS__)); \
else \ else \
boost::bind(__VA_ARGS__)(); \ bind(__VA_ARGS__)(); \
} while (0) } while (0)
#define QUEUE_SYNC(...) \ #define QUEUE_SYNC(...) \
do { \ do { \
if (GET_THREAD_ID() != FLMAIN_TID) \ if (GET_THREAD_ID() != FLMAIN_TID) \
cbq[GET_THREAD_ID()]->request_sync(boost::protect(boost::bind(__VA_ARGS__))); \ cbq[GET_THREAD_ID()]->request_sync(bind(__VA_ARGS__)); \
else \ else \
boost::bind(__VA_ARGS__)(); \ bind(__VA_ARGS__)(); \
} while (0) } while (0)
#define QUEUE_DL(d_, ...) \
do { \
if (GET_THREAD_ID() != FLMAIN_TID) \
cbq[GET_THREAD_ID()]->request_dl(boost::protect(boost::bind(__VA_ARGS__)), d_); \
else \
boost::bind(__VA_ARGS__)(); \
} while (0)
#define QUEUE_FLUSH() \ #define QUEUE_FLUSH() \
do { \ do { \
if (GET_THREAD_ID() != FLMAIN_TID) \ if (GET_THREAD_ID() != FLMAIN_TID) \