diff options
author | sebres <sebres@users.sourceforge.net> | 2024-04-17 15:03:46 (GMT) |
---|---|---|
committer | sebres <sebres@users.sourceforge.net> | 2024-04-17 15:03:46 (GMT) |
commit | 5bc0c6386aafc9f4bb188e7870574d048fd72613 (patch) | |
tree | 96499455beb8a1dd3887bf51cdd3ae9a8c0121d2 | |
parent | 551d70451a01ed8cf74c263b336775c5954c3132 (diff) | |
parent | a44403b68eafae765d1ae5f6d54091cfbfc84f47 (diff) | |
download | tcl-5bc0c6386aafc9f4bb188e7870574d048fd72613.zip tcl-5bc0c6386aafc9f4bb188e7870574d048fd72613.tar.gz tcl-5bc0c6386aafc9f4bb188e7870574d048fd72613.tar.bz2 |
closes [167e0635db]: solves leaks, valgrind test, etc
-rw-r--r-- | generic/tclClock.c | 48 | ||||
-rw-r--r-- | generic/tclClockFmt.c | 14 | ||||
-rw-r--r-- | generic/tclDate.h | 1 |
3 files changed, 45 insertions, 18 deletions
diff --git a/generic/tclClock.c b/generic/tclClock.c index 47beb15..fae2089 100644 --- a/generic/tclClock.c +++ b/generic/tclClock.c @@ -115,6 +115,7 @@ static struct tm * ThreadSafeLocalTime(const time_t *); static size_t TzsetIfNecessary(void); static void ClockDeleteCmdProc(void *); static Tcl_ObjCmdProc ClockSafeCatchCmd; +static void ClockFinalize(void *); /* * Structure containing description of "native" clock commands to create. */ @@ -180,6 +181,15 @@ TclClockInit( ClockClientData *data; int i; + static int initialized = 0; /* global clock engine initialized (in process) */ + /* + * Register handler to finalize clock on exit. + */ + if (!initialized) { + Tcl_CreateExitHandler(ClockFinalize, NULL); + initialized = 1; + } + /* * Safe interps get [::clock] as alias to a parent, so do not need their * own copies of the support routines. @@ -352,12 +362,14 @@ ClockDeleteCmdProc( for (i = 0; i < MCLIT__END; ++i) { Tcl_DecrRefCount(data->mcLiterals[i]); } + Tcl_Free(data->mcLiterals); data->mcLiterals = NULL; } if (data->mcLitIdxs != NULL) { for (i = 0; i < MCLIT__END; ++i) { Tcl_DecrRefCount(data->mcLitIdxs[i]); } + Tcl_Free(data->mcLitIdxs); data->mcLitIdxs = NULL; } @@ -4638,20 +4650,21 @@ ClockSafeCatchCmd( #endif #define TZ_INIT_MARKER ((WCHAR *) INT2PTR(-1)) +typedef struct ClockTzStatic { + WCHAR *was; /* Previous value of TZ. */ + long long lastRefresh; /* Used for latency before next refresh. */ + size_t epoch; /* Epoch, signals that TZ changed. */ + size_t envEpoch; /* Last env epoch, for faster signaling, + * that TZ changed via TCL */ +} ClockTzStatic; +static ClockTzStatic tz = { /* Global timezone info; protected by + * clockMutex.*/ + TZ_INIT_MARKER, 0, 0, 0 +}; + static size_t TzsetIfNecessary(void) { - typedef struct ClockTzStatic { - WCHAR *was; /* Previous value of TZ. */ - long long lastRefresh; /* Used for latency before next refresh. */ - size_t epoch; /* Epoch, signals that TZ changed. */ - size_t envEpoch; /* Last env epoch, for faster signaling, - * that TZ changed via TCL */ - } ClockTzStatic; - static ClockTzStatic tz = { /* Global timezone info; protected by - * clockMutex.*/ - TZ_INIT_MARKER, 0, 0, 0 - }; const WCHAR *tzNow; /* Current value of TZ. */ Tcl_Time now; /* Current time. */ size_t epoch; /* The tz.epoch that the TZ was read at. */ @@ -4700,6 +4713,19 @@ TzsetIfNecessary(void) return epoch; } +static void +ClockFinalize( + TCL_UNUSED(void *)) +{ + ClockFrmScnFinalize(); + + if (tz.was && tz.was != TZ_INIT_MARKER) { + Tcl_Free(tz.was); + } + + Tcl_MutexFinalize(&clockMutex); +} + /* * Local Variables: * mode: c diff --git a/generic/tclClockFmt.c b/generic/tclClockFmt.c index 4ab2423..140ecdd 100644 --- a/generic/tclClockFmt.c +++ b/generic/tclClockFmt.c @@ -26,7 +26,6 @@ static void ClockFmtObj_UpdateString(Tcl_Obj *objPtr); TCL_DECLARE_MUTEX(ClockFmtMutex); /* Serializes access to common format list. */ static void ClockFmtScnStorageDelete(ClockFmtScnStorage *fss); -static void ClockFrmScnFinalize(void *); #ifndef TCL_CLOCK_FULL_COMPAT #define TCL_CLOCK_FULL_COMPAT 1 @@ -682,7 +681,7 @@ ClockFmtObj_FreeInternalRep( Tcl_Obj *objPtr) { ClockFmtScnStorage *fss = ObjClockFmtScn(objPtr); - if (fss != NULL) { + if (fss != NULL && initialized) { Tcl_MutexLock(&ClockFmtMutex); /* decrement object reference count of format/scan storage */ if (--fss->objRefCount <= 0) { @@ -836,7 +835,6 @@ FindOrCreateFmtScnStorage( &ClockFmtScnStorageHashKeyType); initialized = 1; - Tcl_CreateExitHandler(ClockFrmScnFinalize, NULL); } /* get or create entry (and alocate storage) */ @@ -3561,10 +3559,12 @@ ClockFrmScnClearCaches(void) Tcl_MutexUnlock(&ClockFmtMutex); } -static void -ClockFrmScnFinalize( - TCL_UNUSED(void *)) +void +ClockFrmScnFinalize() { + if (!initialized) { + return; + } Tcl_MutexLock(&ClockFmtMutex); #if CLOCK_FMT_SCN_STORAGE_GC_SIZE > 0 /* clear GC */ @@ -3573,8 +3573,8 @@ ClockFrmScnFinalize( ClockFmtScnStorage_GC.count = 0; #endif if (initialized) { - Tcl_DeleteHashTable(&FmtScnHashTable); initialized = 0; + Tcl_DeleteHashTable(&FmtScnHashTable); } Tcl_MutexUnlock(&ClockFmtMutex); Tcl_MutexFinalize(&ClockFmtMutex); diff --git a/generic/tclDate.h b/generic/tclDate.h index 1657528..fea7cbd 100644 --- a/generic/tclDate.h +++ b/generic/tclDate.h @@ -560,5 +560,6 @@ MODULE_SCOPE int ClockScan(DateInfo *info, Tcl_Obj *strObj, MODULE_SCOPE int ClockFormat(DateFormat *dateFmt, ClockFmtScnCmdArgs *opts); MODULE_SCOPE void ClockFrmScnClearCaches(void); +MODULE_SCOPE void ClockFrmScnFinalize(); #endif /* _TCLCLOCK_H */ |