Re #1945 (misc): Use localtime_r() instead of localtime() (if available) since localtime() is not thread safe.

This fixes a data race in pj_time_decode() which is called from multiple threads.
Thanks to Kal (b17 c0de) for the patch.


git-svn-id: https://svn.pjsip.org/repos/pjproject/trunk@5458 74dad513-b988-da41-8d7b-12977e46ad98
This commit is contained in:
Riza Sulistyo 2016-10-13 04:32:29 +00:00
parent 0db777a6cc
commit a9bd0fd451
6 changed files with 30 additions and 9 deletions

View File

@ -5414,6 +5414,12 @@ if test "x$ac_cv_header_net_if_h" = xyes; then :
fi
ac_fn_c_check_func "$LINENO" "localtime_r" "ac_cv_func_localtime_r"
if test "x$ac_cv_func_localtime_r" = xyes; then :
$as_echo "#define PJ_HAS_LOCALTIME_R 1" >>confdefs.h
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: Setting PJ_OS_NAME to $target" >&5
$as_echo "Setting PJ_OS_NAME to $target" >&6; }
cat >>confdefs.h <<_ACEOF

View File

@ -265,6 +265,9 @@ AC_CHECK_HEADER(net/if.h,[AC_DEFINE(PJ_HAS_NET_IF_H,1)],[],
# include <sys/socket.h>
#endif
])
AC_CHECK_FUNC(localtime_r,[AC_DEFINE(PJ_HAS_LOCALTIME_R,1)])
AC_MSG_RESULT([Setting PJ_OS_NAME to $target])
AC_DEFINE_UNQUOTED(PJ_OS_NAME,["$target"])

View File

@ -166,6 +166,9 @@
# define PJ_OS_HAS_CHECK_STACK 0
#endif
/* Is localtime_r() available? */
#undef PJ_HAS_LOCALTIME_R
/* Unicode? */
#undef PJ_NATIVE_STRING_IS_UNICODE

View File

@ -55,6 +55,8 @@
#define PJ_HAS_WINSOCK_H 0
#define PJ_HAS_WINSOCK2_H 0
#define PJ_HAS_LOCALTIME_R 1
/* Is errno a good way to retrieve OS errors?
*/
#define PJ_HAS_ERRNO_VAR 1

View File

@ -55,6 +55,8 @@
#define PJ_HAS_WINSOCK_H 0
#define PJ_HAS_WINSOCK2_H 0
#define PJ_HAS_LOCALTIME_R 1
#define PJ_SOCK_HAS_INET_ATON 1
/* Set 1 if native sockaddr_in has sin_len member.

View File

@ -28,19 +28,24 @@
PJ_DEF(pj_status_t) pj_time_decode(const pj_time_val *tv, pj_parsed_time *pt)
{
struct tm *local_time;
struct tm local_time;
PJ_CHECK_STACK();
local_time = localtime((time_t*)&tv->sec);
#if defined(PJ_HAS_LOCALTIME_R) && PJ_HAS_LOCALTIME_R != 0
localtime_r((time_t*)&tv->sec, &local_time);
#else
/* localtime() is NOT thread-safe. */
local_time = *localtime((time_t*)&tv->sec);
#endif
pt->year = local_time->tm_year+1900;
pt->mon = local_time->tm_mon;
pt->day = local_time->tm_mday;
pt->hour = local_time->tm_hour;
pt->min = local_time->tm_min;
pt->sec = local_time->tm_sec;
pt->wday = local_time->tm_wday;
pt->year = local_time.tm_year+1900;
pt->mon = local_time.tm_mon;
pt->day = local_time.tm_mday;
pt->hour = local_time.tm_hour;
pt->min = local_time.tm_min;
pt->sec = local_time.tm_sec;
pt->wday = local_time.tm_wday;
pt->msec = tv->msec;
return PJ_SUCCESS;