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:
parent
0db777a6cc
commit
a9bd0fd451
|
@ -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
|
||||
|
|
|
@ -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"])
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue