diff options
| author | sebres <sebres@users.sourceforge.net> | 2024-04-14 14:41:35 (GMT) |
|---|---|---|
| committer | sebres <sebres@users.sourceforge.net> | 2024-04-14 14:41:35 (GMT) |
| commit | c4829502e7b25f121f85f3caaaea837c820ef6d8 (patch) | |
| tree | 78c0a6ea343ce15989ca5a52d8e91d015255353e | |
| parent | e77504c051229173cdff610a10f409df2ed6c721 (diff) | |
| download | tcl-c4829502e7b25f121f85f3caaaea837c820ef6d8.zip tcl-c4829502e7b25f121f85f3caaaea837c820ef6d8.tar.gz tcl-c4829502e7b25f121f85f3caaaea837c820ef6d8.tar.bz2 | |
free tz.was (in exit handler)
| -rw-r--r-- | generic/tclClock.c | 44 | ||||
| -rw-r--r-- | generic/tclClockFmt.c | 10 | ||||
| -rw-r--r-- | generic/tclDate.h | 1 |
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 */ |
