You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nuttx.apache.org by xi...@apache.org on 2021/03/22 08:31:21 UTC
[incubator-nuttx] branch master updated: libs/libc/time/localtime:
fix race condition
This is an automated email from the ASF dual-hosted git repository.
xiaoxiang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-nuttx.git
The following commit(s) were added to refs/heads/master by this push:
new 6a6ad96 libs/libc/time/localtime: fix race condition
6a6ad96 is described below
commit 6a6ad96066fd1cad48af41316ea00de466060804
Author: chao.an <an...@xiaomi.com>
AuthorDate: Tue Feb 2 17:26:41 2021 +0800
libs/libc/time/localtime: fix race condition
fix race condition on create the instance of lcl/gmt
Signed-off-by: chao.an <an...@xiaomi.com>
---
libs/libc/time/lib_localtime.c | 48 +++++++++++++++++++++++++++++++++---------
1 file changed, 38 insertions(+), 10 deletions(-)
diff --git a/libs/libc/time/lib_localtime.c b/libs/libc/time/lib_localtime.c
index 4e48e44..c782321 100644
--- a/libs/libc/time/lib_localtime.c
+++ b/libs/libc/time/lib_localtime.c
@@ -321,6 +321,8 @@ static const char g_wildabbr[] = WILDABBR;
static char g_lcl_tzname[MY_TZNAME_MAX + 1];
static int g_lcl_isset;
static int g_gmt_isset;
+static sem_t g_lcl_sem = SEM_INITIALIZER(1);
+static sem_t g_gmt_sem = SEM_INITIALIZER(1);
/* Section 4.12.3 of X3.159-1989 requires that
* Except for the strftime function, these functions [asctime,
@@ -414,6 +416,28 @@ static FAR struct state_s *gmtptr;
* Private Functions
****************************************************************************/
+static void tz_semtake(FAR sem_t *sem)
+{
+ int errcode = 0;
+ int ret;
+
+ do
+ {
+ ret = _SEM_WAIT(sem);
+ if (ret < 0)
+ {
+ errcode = _SEM_ERRNO(ret);
+ DEBUGASSERT(errcode == EINTR || errcode == ECANCELED);
+ }
+ }
+ while (ret < 0 && errcode == EINTR);
+}
+
+static void tz_semgive(FAR sem_t *sem)
+{
+ DEBUGVERIFY(_SEM_POST(sem));
+}
+
static int_fast32_t detzcode(FAR const char *const codep)
{
int_fast32_t result;
@@ -1639,29 +1663,29 @@ static void gmtload(FAR struct state_s *const sp)
static void tzsetwall(void)
{
+ tz_semtake(&g_lcl_sem);
+
if (g_lcl_isset < 0)
{
+ tz_semgive(&g_lcl_sem);
return;
}
- g_lcl_isset = -1;
-
if (lclptr == NULL)
{
lclptr = lib_malloc(sizeof *lclptr);
- if (lclptr == NULL)
- {
- settzname(); /* all we can do */
- return;
- }
}
- if (tzload(NULL, lclptr, TRUE) != 0)
+ if (lclptr != NULL && tzload(NULL, lclptr, TRUE) != 0)
{
gmtload(lclptr);
}
settzname();
+
+ g_lcl_isset = -1;
+
+ tz_semgive(&g_lcl_sem);
}
/* The easy way to behave "as if no library function calls" localtime
@@ -1791,16 +1815,20 @@ static struct tm *localsub(FAR const time_t * const timep,
static struct tm *gmtsub(FAR const time_t * const timep,
const int_fast32_t offset, struct tm *const tmp)
{
+ tz_semtake(&g_gmt_sem);
+
if (!g_gmt_isset)
{
gmtptr = lib_malloc(sizeof *gmtptr);
- g_gmt_isset = gmtptr != NULL;
- if (g_gmt_isset)
+ if (gmtptr != NULL)
{
gmtload(gmtptr);
+ g_gmt_isset = 1;
}
}
+ tz_semgive(&g_gmt_sem);
+
return timesub(timep, offset, gmtptr, tmp);
}