summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorsebres <sebres@users.sourceforge.net>2024-04-17 15:03:46 (GMT)
committersebres <sebres@users.sourceforge.net>2024-04-17 15:03:46 (GMT)
commit5bc0c6386aafc9f4bb188e7870574d048fd72613 (patch)
tree96499455beb8a1dd3887bf51cdd3ae9a8c0121d2
parent551d70451a01ed8cf74c263b336775c5954c3132 (diff)
parenta44403b68eafae765d1ae5f6d54091cfbfc84f47 (diff)
downloadtcl-5bc0c6386aafc9f4bb188e7870574d048fd72613.zip
tcl-5bc0c6386aafc9f4bb188e7870574d048fd72613.tar.gz
tcl-5bc0c6386aafc9f4bb188e7870574d048fd72613.tar.bz2
closes [167e0635db]: solves leaks, valgrind test, etc
-rw-r--r--generic/tclClock.c48
-rw-r--r--generic/tclClockFmt.c14
-rw-r--r--generic/tclDate.h1
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 */