mirror of
https://github.com/lammertb/libhttp.git
synced 2025-08-06 05:02:40 +03:00
httplib_localtime_r thread safe
This commit is contained in:
9
Makefile
9
Makefile
@@ -407,8 +407,7 @@ OBJLIST = \
|
|||||||
${OBJDIR}httplib_pthread_setspecific${OBJEXT} \
|
${OBJDIR}httplib_pthread_setspecific${OBJEXT} \
|
||||||
${OBJDIR}wince_gmtime${OBJEXT} \
|
${OBJDIR}wince_gmtime${OBJEXT} \
|
||||||
${OBJDIR}wince_gmtime_s${OBJEXT} \
|
${OBJDIR}wince_gmtime_s${OBJEXT} \
|
||||||
${OBJDIR}wince_localtime${OBJEXT} \
|
${OBJDIR}httplib_localtime_r${OBJEXT} \
|
||||||
${OBJDIR}wince_localtime_s${OBJEXT} \
|
|
||||||
${OBJDIR}wince_rename${OBJEXT} \
|
${OBJDIR}wince_rename${OBJEXT} \
|
||||||
${OBJDIR}wince_stat${OBJEXT} \
|
${OBJDIR}wince_stat${OBJEXT} \
|
||||||
${OBJDIR}wince_strftime${OBJEXT} \
|
${OBJDIR}wince_strftime${OBJEXT} \
|
||||||
@@ -1447,11 +1446,7 @@ ${OBJDIR}wince_gmtime_s${OBJEXT} : ${SRCDIR}wince_gmtime_s.c \
|
|||||||
${SRCDIR}httplib_utils.h \
|
${SRCDIR}httplib_utils.h \
|
||||||
${INCDIR}libhttp.h
|
${INCDIR}libhttp.h
|
||||||
|
|
||||||
${OBJDIR}wince_localtime${OBJEXT} : ${SRCDIR}wince_localtime.c \
|
${OBJDIR}httplib_localtime_r${OBJEXT} : ${SRCDIR}httplib_localtime_r.c \
|
||||||
${SRCDIR}httplib_main.h \
|
|
||||||
${INCDIR}libhttp.h
|
|
||||||
|
|
||||||
${OBJDIR}wince_localtime_s${OBJEXT} : ${SRCDIR}wince_localtime_s.c \
|
|
||||||
${SRCDIR}httplib_main.h \
|
${SRCDIR}httplib_main.h \
|
||||||
${SRCDIR}httplib_utils.h \
|
${SRCDIR}httplib_utils.h \
|
||||||
${INCDIR}libhttp.h
|
${INCDIR}libhttp.h
|
||||||
|
@@ -922,6 +922,7 @@ LIBHTTP_API const char * httplib_get_option( const struct httplib_context *ctx,
|
|||||||
LIBHTTP_API uint64_t httplib_get_random( void );
|
LIBHTTP_API uint64_t httplib_get_random( void );
|
||||||
LIBHTTP_API void * httplib_get_user_connection_data( const struct httplib_connection *conn );
|
LIBHTTP_API void * httplib_get_user_connection_data( const struct httplib_connection *conn );
|
||||||
LIBHTTP_API int httplib_kill( pid_t pid, int sig_num );
|
LIBHTTP_API int httplib_kill( pid_t pid, int sig_num );
|
||||||
|
LIBHTTP_API struct tm * httplib_localtime_r( const time_t *clock, struct tm *result );
|
||||||
LIBHTTP_API int httplib_mkdir( const char *path, int mode );
|
LIBHTTP_API int httplib_mkdir( const char *path, int mode );
|
||||||
LIBHTTP_API DIR * httplib_opendir( const char *name );
|
LIBHTTP_API DIR * httplib_opendir( const char *name );
|
||||||
LIBHTTP_API int httplib_poll( struct pollfd *pfd, unsigned int nfds, int timeout );
|
LIBHTTP_API int httplib_poll( struct pollfd *pfd, unsigned int nfds, int timeout );
|
||||||
|
@@ -34,15 +34,19 @@
|
|||||||
|
|
||||||
const int XX_httplib_days_per_month[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
|
const int XX_httplib_days_per_month[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
|
||||||
|
|
||||||
|
#endif /* _WIN32_WCE */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* struct tm *localtime_s( const time_t *ptime, struct tm *ptm );
|
* struct tm *httplib_localtime_r( const time_t *clock, struct tm *result );
|
||||||
*
|
*
|
||||||
* The function localtime_s() returns a converted time to tm structure. This
|
* The function localtime_s() returns a converted time to tm structure. This
|
||||||
* function is not available on all operating systems and this version offers
|
* function is not available on all operating systems and this version offers
|
||||||
* a subsitute for use on Windows CE.
|
* a subsitute for use on Windows CE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
struct tm *localtime_s( const time_t *ptime, struct tm *ptm ) {
|
struct tm *httplib_localtime_r( const time_t *clock, struct tm *result ) {
|
||||||
|
|
||||||
|
#if defined(_WIN32_WCE)
|
||||||
|
|
||||||
int a;
|
int a;
|
||||||
int doy;
|
int doy;
|
||||||
@@ -51,30 +55,38 @@ struct tm *localtime_s( const time_t *ptime, struct tm *ptm ) {
|
|||||||
SYSTEMTIME st;
|
SYSTEMTIME st;
|
||||||
TIME_ZONE_INFORMATION tzinfo;
|
TIME_ZONE_INFORMATION tzinfo;
|
||||||
|
|
||||||
if ( ptime == NULL || ptm == NULL ) return NULL;
|
if ( clock == NULL || result == NULL ) return NULL;
|
||||||
|
|
||||||
*(int64_t *)&ft = ((int64_t)*ptime) * RATE_DIFF + EPOCH_DIFF;
|
*(int64_t *)&ft = ((int64_t)*clock) * RATE_DIFF + EPOCH_DIFF;
|
||||||
|
|
||||||
FileTimeToLocalFileTime( & ft, & lft );
|
FileTimeToLocalFileTime( & ft, & lft );
|
||||||
FileTimeToSystemTime( & lft, & st );
|
FileTimeToSystemTime( & lft, & st );
|
||||||
|
|
||||||
ptm->tm_year = st.wYear - 1900;
|
result->tm_year = st.wYear - 1900;
|
||||||
ptm->tm_mon = st.wMonth - 1;
|
result->tm_mon = st.wMonth - 1;
|
||||||
ptm->tm_wday = st.wDayOfWeek;
|
result->tm_wday = st.wDayOfWeek;
|
||||||
ptm->tm_mday = st.wDay;
|
result->tm_mday = st.wDay;
|
||||||
ptm->tm_hour = st.wHour;
|
result->tm_hour = st.wHour;
|
||||||
ptm->tm_min = st.wMinute;
|
result->tm_min = st.wMinute;
|
||||||
ptm->tm_sec = st.wSecond;
|
result->tm_sec = st.wSecond;
|
||||||
ptm->tm_isdst = (GetTimeZoneInformation(&tzinfo) == TIME_ZONE_ID_DAYLIGHT) ? 1 : 0;
|
result->tm_isdst = (GetTimeZoneInformation(&tzinfo) == TIME_ZONE_ID_DAYLIGHT) ? 1 : 0;
|
||||||
|
|
||||||
doy = ptm->tm_mday;
|
doy = result->tm_mday;
|
||||||
for (a=0; a<ptm->tm_mon; a++) doy += days_per_month[a];
|
for (a=0; a<result->tm_mon; a++) doy += days_per_month[a];
|
||||||
if ( ptm->tm_mon >= 2 && LEAP_YEAR( ptm->tm_year+1900 ) ) doy++;
|
if ( result->tm_mon >= 2 && LEAP_YEAR( result->tm_year+1900 ) ) doy++;
|
||||||
|
|
||||||
ptm->tm_yday = doy;
|
result->tm_yday = doy;
|
||||||
|
|
||||||
return ptm;
|
return result;
|
||||||
|
|
||||||
} /* localtime_s */
|
#elif defined(_WIN32)
|
||||||
|
|
||||||
#endif /* defined(_WIN32_WCE) */
|
return localtime_s( clock, result );
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
return localtime_r( clock, result );
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
} /* httplib_localtime_r */
|
@@ -43,7 +43,7 @@ void XX_httplib_log_access( const struct httplib_connection *conn ) {
|
|||||||
struct file fi;
|
struct file fi;
|
||||||
char date[64];
|
char date[64];
|
||||||
char src_addr[IP_ADDR_STR_LEN];
|
char src_addr[IP_ADDR_STR_LEN];
|
||||||
struct tm *tm;
|
struct tm tmm;
|
||||||
const char *referer;
|
const char *referer;
|
||||||
const char *user_agent;
|
const char *user_agent;
|
||||||
char buf[4096];
|
char buf[4096];
|
||||||
@@ -63,9 +63,7 @@ void XX_httplib_log_access( const struct httplib_connection *conn ) {
|
|||||||
|
|
||||||
if ( fi.fp == NULL && conn->ctx->callbacks.log_access == NULL ) return;
|
if ( fi.fp == NULL && conn->ctx->callbacks.log_access == NULL ) return;
|
||||||
|
|
||||||
tm = localtime( & conn->conn_birth_time );
|
if ( httplib_localtime_r( &conn->conn_birth_time, &tmm ) != NULL ) strftime( date, sizeof(date), "%d/%b/%Y:%H:%M:%S %z", &tmm );
|
||||||
|
|
||||||
if ( tm != NULL ) strftime( date, sizeof(date), "%d/%b/%Y:%H:%M:%S %z", tm );
|
|
||||||
else {
|
else {
|
||||||
httplib_strlcpy( date, "01/Jan/1970:00:00:00 +0000", sizeof(date) );
|
httplib_strlcpy( date, "01/Jan/1970:00:00:00 +0000", sizeof(date) );
|
||||||
date[sizeof(date) - 1] = '\0';
|
date[sizeof(date) - 1] = '\0';
|
||||||
|
@@ -33,7 +33,7 @@ void XX_httplib_print_dir_entry( struct de *de ) {
|
|||||||
char size[64];
|
char size[64];
|
||||||
char mod[64];
|
char mod[64];
|
||||||
char href[PATH_MAX * 3 /* worst case */];
|
char href[PATH_MAX * 3 /* worst case */];
|
||||||
struct tm *tm;
|
struct tm tmm;
|
||||||
|
|
||||||
if ( de->file.is_directory ) XX_httplib_snprintf( de->conn, NULL, size, sizeof(size), "%s", "[DIRECTORY]" );
|
if ( de->file.is_directory ) XX_httplib_snprintf( de->conn, NULL, size, sizeof(size), "%s", "[DIRECTORY]" );
|
||||||
else {
|
else {
|
||||||
@@ -53,8 +53,7 @@ void XX_httplib_print_dir_entry( struct de *de ) {
|
|||||||
* So, string truncation checks are not required here.
|
* So, string truncation checks are not required here.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
tm = localtime( &de->file.last_modified );
|
if ( httplib_localtime_r( &de->file.last_modified, &tmm ) != NULL ) strftime( mod, sizeof(mod), "%d-%b-%Y %H:%M", &tmm );
|
||||||
if ( tm != NULL ) strftime( mod, sizeof(mod), "%d-%b-%Y %H:%M", tm );
|
|
||||||
|
|
||||||
else {
|
else {
|
||||||
httplib_strlcpy( mod, "01-Jan-1970 00:00", sizeof(mod) );
|
httplib_strlcpy( mod, "01-Jan-1970 00:00", sizeof(mod) );
|
||||||
|
@@ -1,60 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2016 Lammert Bies
|
|
||||||
* Copyright (c) 2013-2016 the Civetweb developers
|
|
||||||
* Copyright (c) 2004-2013 Sergey Lyubka
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
|
||||||
* in the Software without restriction, including without limitation the rights
|
|
||||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
* copies of the Software, and to permit persons to whom the Software is
|
|
||||||
* furnished to do so, subject to the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice shall be included in
|
|
||||||
* all copies or substantial portions of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
||||||
* THE SOFTWARE.
|
|
||||||
*
|
|
||||||
* ============
|
|
||||||
* Release: 2.0
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "httplib_main.h"
|
|
||||||
|
|
||||||
#if defined(_WIN32_WCE)
|
|
||||||
|
|
||||||
struct tm XX_httplib_tm_array[MAX_WORKER_THREADS];
|
|
||||||
volatile int XX_httplib_tm_index = 0;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* struct tm *localtime( const time_t *ptime );
|
|
||||||
*
|
|
||||||
* The time conversion function localtime() is not available on all platforms.
|
|
||||||
* This implementation provides an equivalent function which can be used on
|
|
||||||
* platforms where the native system libraries have no support for localtime().
|
|
||||||
* The function is thread safe by using an array with multiple entries to
|
|
||||||
* store the outcome of the function. Please note however that the number of
|
|
||||||
* entries in the table is equal to the normal number of threads started by
|
|
||||||
* LibHTTP, but this still may lead to overwriting results in border cases
|
|
||||||
* where the application creates additional threads which also use calls to
|
|
||||||
* this localtime implementation().
|
|
||||||
*
|
|
||||||
* The implementation should therefore use thread local storage in the future.
|
|
||||||
*/
|
|
||||||
|
|
||||||
struct tm *localtime( const time_t *ptime ) {
|
|
||||||
|
|
||||||
int i;
|
|
||||||
|
|
||||||
i = XX_httplib_atomic_inc( & XX_httplib_tm_index ) % MAX_WORKER_THREADS;
|
|
||||||
return localtime_s( ptime, XX_httplib_tm_array + i );
|
|
||||||
|
|
||||||
} /* localtime */
|
|
||||||
|
|
||||||
#endif /* defined(_WIN32_WCE) */
|
|
Reference in New Issue
Block a user