Skip to content

Commit

Permalink
XXX cpan PR Time-Piece: Add locks
Browse files Browse the repository at this point in the history
This add mutex locking around some unsafe thread operations to make this
module thread-safe.
  • Loading branch information
khwilliamson committed Apr 6, 2021
1 parent 8c03923 commit 237175b
Show file tree
Hide file tree
Showing 2 changed files with 74 additions and 8 deletions.
2 changes: 1 addition & 1 deletion cpan/Time-Piece/Piece.pm
Expand Up @@ -19,7 +19,7 @@ our %EXPORT_TAGS = (
':override' => 'internal',
);

our $VERSION = '1.3401';
our $VERSION = '1.3402';

XSLoader::load( 'Time::Piece', $VERSION );

Expand Down
80 changes: 73 additions & 7 deletions cpan/Time-Piece/Piece.xs
Expand Up @@ -26,6 +26,27 @@ extern "C" {
#define WEEKDAY_BIAS 6 /* (1+6)%7 makes Sunday 0 again */
#define TP_BUF_SIZE 160

#ifndef ENV_LOCK
# define ENV_LOCK
# define ENV_UNLOCK
#endif
#ifndef GMTIME_LOCK
# define GMTIME_LOCK ENV_LOCK
# define GMTIME_UNLOCK ENV_UNLOCK
#endif
#ifndef LOCALTIME_LOCK
# define LOCALTIME_LOCK ENV_LOCK
# define LOCALTIME_UNLOCK ENV_UNLOCK
#endif
#ifndef STRFTIME_LOCK
# define STRFTIME_LOCK ENV_LOCK
# define STRFTIME_UNLOCK ENV_UNLOCK
#endif
#ifndef TZSET_LOCK
# define TZSET_LOCK ENV_LOCK
# define TZSET_UNLOCK ENV_UNLOCK
#endif

#ifdef WIN32

/*
Expand Down Expand Up @@ -151,7 +172,9 @@ my_tzset(pTHX)
#endif
fix_win32_tzenv();
#endif
TZSET_LOCK;
tzset();
TZSET_UNLOCK;
}

/*
Expand Down Expand Up @@ -758,10 +781,14 @@ label:
buf = cp;
memset(&mytm, 0, sizeof(mytm));

if(*got_GMT == 1)
if(*got_GMT == 1) {
LOCALTIME_LOCK;
mytm = *localtime(&t);
else
}
else {
GMTIME_LOCK;
mytm = *gmtime(&t);
}

tm->tm_sec = mytm.tm_sec;
tm->tm_min = mytm.tm_min;
Expand All @@ -772,6 +799,13 @@ label:
tm->tm_wday = mytm.tm_wday;
tm->tm_yday = mytm.tm_yday;
tm->tm_isdst = mytm.tm_isdst;

if(*got_GMT == 1) {
LOCALTIME_UNLOCK;
}
else {
GMTIME_UNLOCK;
}
}
break;

Expand Down Expand Up @@ -963,12 +997,17 @@ _strftime(fmt, epoch, islocal = 1)
struct tm mytm;
size_t len;

if(islocal == 1)
/* This should achieve locking localtime and gmtime as well */
STRFTIME_LOCK;
if(islocal == 1) {
mytm = *localtime(&epoch);
else
}
else {
mytm = *gmtime(&epoch);
}

len = strftime(tmpbuf, TP_BUF_SIZE, fmt, &mytm);
STRFTIME_UNLOCK;
/*
** The following is needed to handle to the situation where
** tmpbuf overflows. Basically we want to allocate a buffer
Expand All @@ -994,7 +1033,9 @@ _strftime(fmt, epoch, islocal = 1)

New(0, buf, bufsize, char);
while (buf) {
STRFTIME_LOCK;
buflen = strftime(buf, bufsize, fmt, &mytm);
STRFTIME_UNLOCK;
if (buflen > 0 && buflen < bufsize)
break;
/* heuristic to prevent out-of-memory errors */
Expand Down Expand Up @@ -1069,7 +1110,9 @@ _mini_mktime(int sec, int min, int hour, int mday, int mon, int year)
time_t t;
PPCODE:
t = 0;
GMTIME_LOCK;
mytm = *gmtime(&t);
GMTIME_UNLOCK;

mytm.tm_sec = sec;
mytm.tm_min = min;
Expand All @@ -1088,8 +1131,16 @@ _crt_localtime(time_t sec)
PREINIT:
struct tm mytm;
PPCODE:
if(ix) mytm = *gmtime(&sec);
else mytm = *localtime(&sec);
if(ix) {
GMTIME_LOCK;
mytm = *gmtime(&sec);
GMTIME_UNLOCK;
}
else {
LOCALTIME_LOCK;
mytm = *localtime(&sec);
LOCALTIME_UNLOCK;
}
/* Need to get: $s,$n,$h,$d,$m,$y */

EXTEND(SP, 10);
Expand Down Expand Up @@ -1120,26 +1171,37 @@ _get_localization()
char buf[TP_BUF_SIZE];
size_t i;
time_t t = 1325386800; /*1325386800 = Sun, 01 Jan 2012 03:00:00 GMT*/
struct tm mytm = *gmtime(&t);
struct tm mytm;
CODE:
GMTIME_LOCK;
mytm = *gmtime(&t);
GMTIME_UNLOCK;

for(i = 0; i < 7; ++i){

STRFTIME_LOCK;
len = strftime(buf, TP_BUF_SIZE, "%a", &mytm);
STRFTIME_UNLOCK;
av_push(wdays, (SV *) newSVpvn(buf, len));

STRFTIME_LOCK;
len = strftime(buf, TP_BUF_SIZE, "%A", &mytm);
STRFTIME_UNLOCK;
av_push(weekdays, (SV *) newSVpvn(buf, len));

++mytm.tm_wday;
}

for(i = 0; i < 12; ++i){

STRFTIME_LOCK;
len = strftime(buf, TP_BUF_SIZE, "%b", &mytm);
STRFTIME_UNLOCK;
av_push(mons, (SV *) newSVpvn(buf, len));

STRFTIME_LOCK;
len = strftime(buf, TP_BUF_SIZE, "%B", &mytm);
STRFTIME_UNLOCK;
av_push(months, (SV *) newSVpvn(buf, len));

++mytm.tm_mon;
Expand All @@ -1151,10 +1213,14 @@ _get_localization()
tmp = hv_store(locales, "month", 5, newRV_noinc((SV *) months), 0);
tmp = hv_store(locales, "alt_month", 9, newRV((SV *) months), 0);

STRFTIME_LOCK;
len = strftime(buf, TP_BUF_SIZE, "%p", &mytm);
STRFTIME_UNLOCK;
tmp = hv_store(locales, "AM", 2, newSVpvn(buf,len), 0);
mytm.tm_hour = 18;
STRFTIME_LOCK;
len = strftime(buf, TP_BUF_SIZE, "%p", &mytm);
STRFTIME_UNLOCK;
tmp = hv_store(locales, "PM", 2, newSVpvn(buf,len), 0);

if(tmp == NULL || !SvOK( (SV *) *tmp)){
Expand Down

0 comments on commit 237175b

Please sign in to comment.