summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorsebres <sebres@users.sourceforge.net>2024-04-14 14:41:35 (GMT)
committersebres <sebres@users.sourceforge.net>2024-04-14 14:41:35 (GMT)
commitc4829502e7b25f121f85f3caaaea837c820ef6d8 (patch)
tree78c0a6ea343ce15989ca5a52d8e91d015255353e
parente77504c051229173cdff610a10f409df2ed6c721 (diff)
downloadtcl-c4829502e7b25f121f85f3caaaea837c820ef6d8.zip
tcl-c4829502e7b25f121f85f3caaaea837c820ef6d8.tar.gz
tcl-c4829502e7b25f121f85f3caaaea837c820ef6d8.tar.bz2
free tz.was (in exit handler)
-rw-r--r--generic/tclClock.c44
-rw-r--r--generic/tclClockFmt.c10
-rw-r--r--generic/tclDate.h1
3 files changed, 39 insertions, 16 deletions
diff --git a/generic/tclClock.c b/generic/tclClock.c
index 7fc18a6..14565ea 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.
@@ -4640,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. */
@@ -4702,6 +4713,17 @@ TzsetIfNecessary(void)
return epoch;
}
+static void
+ClockFinalize(
+ TCL_UNUSED(void *))
+{
+ ClockFrmScnFinalize();
+
+ if (tz.was && tz.was != TZ_INIT_MARKER) {
+ Tcl_Free(tz.was);
+ }
+}
+
/*
* Local Variables:
* mode: c
diff --git a/generic/tclClockFmt.c b/generic/tclClockFmt.c
index 156e4d2..cd4d39c 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 *);
/*
* Derivation of tclStringHashKeyType with another allocEntryProc
@@ -832,7 +831,6 @@ FindOrCreateFmtScnStorage(
&ClockFmtScnStorageHashKeyType);
initialized = 1;
- Tcl_CreateExitHandler(ClockFrmScnFinalize, NULL);
}
/* get or create entry (and alocate storage) */
@@ -3541,10 +3539,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 */
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 */