views:

30

answers:

2

I searched google as much as I could but I couldn't find any good answers to this.

localtime_r is supposed to be a thread-safe function for getting the system time. However, when checking my application with Valgrind --tool=drd, it consistantly tells me that there is a data race condition on this function. Are the common search results lying to me, or am I just missing something? It doesn't seem efficient to surround each localtime_r call with a mutex, especially if it is supposed to by thread safe in the first place. here is how i'm using it:

timeval handlerTime;
gettimeofday(&handlerTime,NULL);

tm handlerTm;
localtime_r(&handlerTime.tv_sec,&handlerTm);

Any ideas?

+1  A: 

If the documentation says it is reentrant (and thus thread-safe), then it is.

If ever there was a bug in the code (not your code) and the function wasn't really thread-safe, there is nothing much you can do about it (unless using another function), and it's not up to you to fix this in your code: the function must behave the way it is documented.

However, I would be careful with the results given by valgrind. It is a great tool, and I use it often. But sometimes, it is just wrong. And for something as hard as detecting race conditions, I would be even more careful about what it says. Especially about a standard function that is beeing used for decades.

My advice here would be: just ignore it. If you ever experience issues and believe localtime_r() is responsible for it, write to the appropriate mailing-list to report the issue, and/or use another function.

In the meanwhile, you should be just fine.

ereOn
+1  A: 

From the manpage:

The ctime_r(), localtime_r(), and tzset() functions are MT-Safe in multithread applications, as long as no user-defined function directly modifies one of the following variables: timezone, altzone, daylight, and tzname. These four variables are not MT-Safe to access. They are modified by the tzset() function in an MT-Safe manner. The mktime(), localtime_r(), and ctime_r() functions call tzset().

As long as you aren't accessing any of those variable directly in your code, it seems possible that valgrind is reporting a false positive. Does it give you any further detail about where it thinks the race condition exists within the function?

Unless you have further corroboration with valgrind, I would think it's safe to continue using it without extra locks.

Mark B