From 40caf0ad9bef07bdfb568a88192c157dd1840100 Mon Sep 17 00:00:00 2001 From: "David M. Lee" <dlee@respoke.io> Date: Fri, 24 Jul 2015 17:04:35 -0500 Subject: [PATCH] Replaces clock_gettime() with ast_tsnow() clock_gettime() is, unfortunately, not portable. But I did like that over our usual `ts.tv_nsec = tv.tv_usec * 1000` copy/paste code we usually do when we want a timespec and all we have is ast_tvnow(). This patch adds ast_tsnow(), which mimics ast_tvnow(), but returns a timespec. If clock_gettime() is available, it will use that. Otherwise ast_tsnow() falls back to using ast_tvnow(). Change-Id: Ibb1ee67ccf4826b9b76d5a5eb62e90b29b6c456e --- configure | 132 +++++++++++++++++++++++++++++-- configure.ac | 4 + include/asterisk/autoconfig.h.in | 3 + include/asterisk/time.h | 34 ++++++++ main/Makefile | 1 + makeopts.in | 2 + tests/test_dns.c | 6 +- tests/test_dns_query_set.c | 2 +- tests/test_dns_recurring.c | 8 +- 9 files changed, 179 insertions(+), 13 deletions(-) diff --git a/configure b/configure index 731b2f7a99..a64e0102d2 100755 --- a/configure +++ b/configure @@ -756,6 +756,10 @@ PBX_SUPPSERV SUPPSERV_DIR SUPPSERV_INCLUDE SUPPSERV_LIB +PBX_RT +RT_DIR +RT_INCLUDE +RT_LIB PBX_OPENSSL OPENSSL_DIR OPENSSL_INCLUDE @@ -11270,6 +11274,18 @@ fi +RT_DESCRIP="Realtime functions" + +RT_DIR=${rt_DIR} + +PBX_RT=0 + + + + + + + SUPPSERV_DESCRIP="mISDN Supplemental Services" SUPPSERV_OPTION="suppserv" PBX_SUPPSERV=0 @@ -12962,6 +12978,112 @@ if test "x$JANSSON_LIB" == "x"; then as_fn_error $? "*** JSON support not found (this typically means the libjansson development package is missing)" "$LINENO" 5 fi +# See if clock_gettime is in librt + +if test "x${PBX_RT}" != "x1" -a "${USE_RT}" != "no"; then + pbxlibdir="" + # if --with-RT=DIR has been specified, use it. + if test "x${RT_DIR}" != "x"; then + if test -d ${RT_DIR}/lib; then + pbxlibdir="-L${RT_DIR}/lib" + else + pbxlibdir="-L${RT_DIR}" + fi + fi + pbxfuncname="clock_gettime" + if test "x${pbxfuncname}" = "x" ; then # empty lib, assume only headers + AST_RT_FOUND=yes + else + ast_ext_lib_check_save_CFLAGS="${CFLAGS}" + CFLAGS="${CFLAGS} " + as_ac_Lib=`$as_echo "ac_cv_lib_rt_${pbxfuncname}" | $as_tr_sh` +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ${pbxfuncname} in -lrt" >&5 +$as_echo_n "checking for ${pbxfuncname} in -lrt... " >&6; } +if eval \${$as_ac_Lib+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lrt ${pbxlibdir} $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char ${pbxfuncname} (); +int +main () +{ +return ${pbxfuncname} (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + eval "$as_ac_Lib=yes" +else + eval "$as_ac_Lib=no" +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +eval ac_res=\$$as_ac_Lib + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } +if eval test \"x\$"$as_ac_Lib"\" = x"yes"; then : + AST_RT_FOUND=yes +else + AST_RT_FOUND=no +fi + + CFLAGS="${ast_ext_lib_check_save_CFLAGS}" + fi + + # now check for the header. + if test "${AST_RT_FOUND}" = "yes"; then + RT_LIB="${pbxlibdir} -lrt " + # if --with-RT=DIR has been specified, use it. + if test "x${RT_DIR}" != "x"; then + RT_INCLUDE="-I${RT_DIR}/include" + fi + RT_INCLUDE="${RT_INCLUDE} " + if test "x" = "x" ; then # no header, assume found + RT_HEADER_FOUND="1" + else # check for the header + ast_ext_lib_check_saved_CPPFLAGS="${CPPFLAGS}" + CPPFLAGS="${CPPFLAGS} ${RT_INCLUDE}" + ac_fn_c_check_header_mongrel "$LINENO" "" "ac_cv_header_" "$ac_includes_default" +if test "x$ac_cv_header_" = xyes; then : + RT_HEADER_FOUND=1 +else + RT_HEADER_FOUND=0 +fi + + + CPPFLAGS="${ast_ext_lib_check_saved_CPPFLAGS}" + fi + if test "x${RT_HEADER_FOUND}" = "x0" ; then + RT_LIB="" + RT_INCLUDE="" + else + if test "x${pbxfuncname}" = "x" ; then # only checking headers -> no library + RT_LIB="" + fi + PBX_RT=1 + cat >>confdefs.h <<_ACEOF +#define HAVE_RT 1 +_ACEOF + + fi + fi +fi + + + if test "x${PBX_LIBXML2}" != "x1" -a "${USE_LIBXML2}" != "no"; then PBX_LIBXML2=0 @@ -13515,7 +13637,7 @@ else We can't simply define LARGE_OFF_T to be 9223372036854775807, since some C++ compilers masquerading as C compilers incorrectly reject 9223372036854775807. */ -#define LARGE_OFF_T ((((off_t) 1 << 31) << 31) - 1 + (((off_t) 1 << 31) << 31)) +#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62)) int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 && LARGE_OFF_T % 2147483647 == 1) ? 1 : -1]; @@ -13561,7 +13683,7 @@ else We can't simply define LARGE_OFF_T to be 9223372036854775807, since some C++ compilers masquerading as C compilers incorrectly reject 9223372036854775807. */ -#define LARGE_OFF_T ((((off_t) 1 << 31) << 31) - 1 + (((off_t) 1 << 31) << 31)) +#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62)) int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 && LARGE_OFF_T % 2147483647 == 1) ? 1 : -1]; @@ -13585,7 +13707,7 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext We can't simply define LARGE_OFF_T to be 9223372036854775807, since some C++ compilers masquerading as C compilers incorrectly reject 9223372036854775807. */ -#define LARGE_OFF_T ((((off_t) 1 << 31) << 31) - 1 + (((off_t) 1 << 31) << 31)) +#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62)) int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 && LARGE_OFF_T % 2147483647 == 1) ? 1 : -1]; @@ -13630,7 +13752,7 @@ else We can't simply define LARGE_OFF_T to be 9223372036854775807, since some C++ compilers masquerading as C compilers incorrectly reject 9223372036854775807. */ -#define LARGE_OFF_T ((((off_t) 1 << 31) << 31) - 1 + (((off_t) 1 << 31) << 31)) +#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62)) int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 && LARGE_OFF_T % 2147483647 == 1) ? 1 : -1]; @@ -13654,7 +13776,7 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext We can't simply define LARGE_OFF_T to be 9223372036854775807, since some C++ compilers masquerading as C compilers incorrectly reject 9223372036854775807. */ -#define LARGE_OFF_T ((((off_t) 1 << 31) << 31) - 1 + (((off_t) 1 << 31) << 31)) +#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62)) int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 && LARGE_OFF_T % 2147483647 == 1) ? 1 : -1]; diff --git a/configure.ac b/configure.ac index c09d30a7f8..178fea9a64 100644 --- a/configure.ac +++ b/configure.ac @@ -505,6 +505,7 @@ AST_EXT_LIB_SETUP([SQLITE3], [SQLite], [sqlite3]) AST_EXT_LIB_SETUP([SRTP], [Secure RTP], [srtp]) AST_EXT_LIB_SETUP_OPTIONAL([SRTP_SHUTDOWN], [SRTP Library Shutdown Function], [SRTP], [srtp]) AST_EXT_LIB_SETUP([OPENSSL], [OpenSSL Secure Sockets Layer], [ssl]) +AST_EXT_LIB_SETUP_OPTIONAL([RT], [Realtime functions], [rt]) AST_EXT_LIB_SETUP([SUPPSERV], [mISDN Supplemental Services], [suppserv]) AST_EXT_LIB_SETUP([FREETDS], [FreeTDS], [tds]) AST_EXT_LIB_SETUP([TERMCAP], [Termcap], [termcap]) @@ -577,6 +578,9 @@ if test "x$JANSSON_LIB" == "x"; then AC_MSG_ERROR([*** JSON support not found (this typically means the libjansson development package is missing)]) fi +# See if clock_gettime is in librt +AST_EXT_LIB_CHECK([RT], [rt], [clock_gettime]) + AST_EXT_TOOL_CHECK([LIBXML2], [xml2-config], , , [#include <libxml/tree.h> #include <libxml/parser.h>], diff --git a/include/asterisk/autoconfig.h.in b/include/asterisk/autoconfig.h.in index 6b41a8c9a7..c0c34736b6 100644 --- a/include/asterisk/autoconfig.h.in +++ b/include/asterisk/autoconfig.h.in @@ -764,6 +764,9 @@ /* Define to 1 if you have the `roundl' function. */ #undef HAVE_ROUNDL +/* Define to 1 if rt has the Realtime functions feature. */ +#undef HAVE_RT + /* Define if your system has the RTLD_NOLOAD headers. */ #undef HAVE_RTLD_NOLOAD diff --git a/include/asterisk/time.h b/include/asterisk/time.h index f2382df338..529490630c 100644 --- a/include/asterisk/time.h +++ b/include/asterisk/time.h @@ -23,10 +23,16 @@ #ifndef _ASTERISK_TIME_H #define _ASTERISK_TIME_H +#include "asterisk/autoconfig.h" + #ifdef HAVE_SYS_TIME_H #include <sys/time.h> #endif +#ifdef HAVE_UNISTD_H +#include <unistd.h> +#endif + #include "asterisk/inline_api.h" /* We have to let the compiler learn what types to use for the elements of a @@ -141,6 +147,34 @@ struct timeval ast_tvnow(void), } ) +/*! + * \brief Returns current timespec. Meant to avoid calling ast_tvnow() just to + * create a timespec from the timeval it returns. + */ +#if defined _POSIX_TIMERS && _POSIX_TIMERS > 0 +AST_INLINE_API( +struct timespec ast_tsnow(void), +{ + struct timespec ts; + clock_gettime(CLOCK_REALTIME, &ts); + return ts; +} +) +#else +AST_INLINE_API( +struct timespec ast_tsnow(void), +{ + struct timeval tv = ast_tvnow(); + struct timespec ts; + /* Can't use designated initializer, because it does odd things with + * the AST_INLINE_API macro. Go figure. */ + ts.tv_sec = tv.tv_sec; + ts.tv_nsec = tv.tv_usec * 1000; + return ts; +} +) +#endif + /*! * \brief Returns the sum of two timevals a + b */ diff --git a/main/Makefile b/main/Makefile index bfdfb463de..b25fb450ac 100644 --- a/main/Makefile +++ b/main/Makefile @@ -41,6 +41,7 @@ AST_LIBS+=$(URIPARSER_LIB) AST_LIBS+=$(UUID_LIB) AST_LIBS+=$(CRYPT_LIB) AST_LIBS+=$(AST_CLANG_BLOCKS_LIBS) +AST_LIBS+=$(RT_LIB) ifneq ($(findstring $(OSARCH), linux-gnu uclinux linux-uclibc kfreebsd-gnu),) ifneq ($(findstring LOADABLE_MODULES,$(MENUSELECT_CFLAGS)),) diff --git a/makeopts.in b/makeopts.in index 69636f18e7..d91dc9ba4a 100644 --- a/makeopts.in +++ b/makeopts.in @@ -243,6 +243,8 @@ PRI_LIB=@PRI_LIB@ RESAMPLE_INCLUDE=@RESAMPLE_INCLUDE@ RESAMPLE_LIB=@RESAMPLE_LIB@ +RT_LIB=@RT_LIB@ + SS7_INCLUDE=@SS7_INCLUDE@ SS7_LIB=@SS7_LIB@ diff --git a/tests/test_dns.c b/tests/test_dns.c index 4e2c4a4649..718cffc507 100644 --- a/tests/test_dns.c +++ b/tests/test_dns.c @@ -694,7 +694,7 @@ static void *resolution_thread(void *dns_query) static const size_t V4_BUFSIZE = sizeof(struct in_addr); char v4_buf[V4_BUFSIZE]; - clock_gettime(CLOCK_REALTIME, &timeout); + timeout = ast_tsnow(); timeout.tv_sec += 5; ast_mutex_lock(&test_resolver_data.lock); @@ -1089,7 +1089,7 @@ AST_TEST_DEFINE(resolver_resolve_async) goto cleanup; } - clock_gettime(CLOCK_REALTIME, &timeout); + timeout = ast_tsnow(); timeout.tv_sec += 10; ast_mutex_lock(&async_data->lock); while (!async_data->complete) { @@ -1279,7 +1279,7 @@ AST_TEST_DEFINE(resolver_resolve_async_cancel) goto cleanup; } - clock_gettime(CLOCK_REALTIME, &timeout); + timeout = ast_tsnow(); timeout.tv_sec += 10; ast_mutex_lock(&async_data->lock); while (!async_data->complete) { diff --git a/tests/test_dns_query_set.c b/tests/test_dns_query_set.c index 98a6051db5..aeb61c7675 100644 --- a/tests/test_dns_query_set.c +++ b/tests/test_dns_query_set.c @@ -245,7 +245,7 @@ static enum ast_test_result_state query_set_test(struct ast_test *test, int reso } } - clock_gettime(CLOCK_REALTIME, &timeout); + timeout = ast_tsnow(); timeout.tv_sec += 10; ast_mutex_lock(&qsdata->lock); diff --git a/tests/test_dns_recurring.c b/tests/test_dns_recurring.c index b5736c22cd..d1add6ee1f 100644 --- a/tests/test_dns_recurring.c +++ b/tests/test_dns_recurring.c @@ -210,7 +210,7 @@ static int wait_for_resolution(struct ast_test *test, struct recurring_data *rda struct timespec timeout; int secdiff; - clock_gettime(CLOCK_REALTIME, &begin); + begin = ast_tsnow(); timeout.tv_sec = begin.tv_sec + 20; timeout.tv_nsec = begin.tv_nsec; @@ -229,7 +229,7 @@ static int wait_for_resolution(struct ast_test *test, struct recurring_data *rda } rdata->query_complete = 0; - clock_gettime(CLOCK_REALTIME, &end); + end = ast_tsnow(); secdiff = end.tv_sec - begin.tv_sec; @@ -504,7 +504,7 @@ AST_TEST_DEFINE(recurring_query_cancel_between) /* Query has been canceled, so let's wait to make sure that we don't get * told another query has occurred. */ - clock_gettime(CLOCK_REALTIME, &timeout); + timeout = ast_tsnow(); timeout.tv_sec += 10; ast_mutex_lock(&rdata->lock); @@ -602,7 +602,7 @@ AST_TEST_DEFINE(recurring_query_cancel_during) } /* Now ensure that no more queries get completed after cancellation. */ - clock_gettime(CLOCK_REALTIME, &timeout); + timeout = ast_tsnow(); timeout.tv_sec += 10; ast_mutex_lock(&rdata->lock); -- GitLab