@@ -115,6 +115,7 @@ static struct tm * ThreadSafeLocalTime(const time_t *);
115
115
static size_t TzsetIfNecessary (void );
116
116
static void ClockDeleteCmdProc (void * );
117
117
static Tcl_ObjCmdProc ClockSafeCatchCmd ;
118
+ static void ClockFinalize (void * );
118
119
/*
119
120
* Structure containing description of "native" clock commands to create.
120
121
*/
@@ -180,6 +181,15 @@ TclClockInit(
180
181
ClockClientData * data ;
181
182
int i ;
182
183
184
+ static int initialized = 0 ; /* global clock engine initialized (in process) */
185
+ /*
186
+ * Register handler to finalize clock on exit.
187
+ */
188
+ if (!initialized ) {
189
+ Tcl_CreateExitHandler (ClockFinalize , NULL );
190
+ initialized = 1 ;
191
+ }
192
+
183
193
/*
184
194
* Safe interps get [::clock] as alias to a parent, so do not need their
185
195
* own copies of the support routines.
@@ -352,12 +362,14 @@ ClockDeleteCmdProc(
352
362
for (i = 0 ; i < MCLIT__END ; ++ i ) {
353
363
Tcl_DecrRefCount (data -> mcLiterals [i ]);
354
364
}
365
+ ckfree (data -> mcLiterals );
355
366
data -> mcLiterals = NULL ;
356
367
}
357
368
if (data -> mcLitIdxs != NULL ) {
358
369
for (i = 0 ; i < MCLIT__END ; ++ i ) {
359
370
Tcl_DecrRefCount (data -> mcLitIdxs [i ]);
360
371
}
372
+ ckfree (data -> mcLitIdxs );
361
373
data -> mcLitIdxs = NULL ;
362
374
}
363
375
@@ -4638,20 +4650,25 @@ ClockSafeCatchCmd(
4638
4650
#endif
4639
4651
#define TZ_INIT_MARKER ((WCHAR *) INT2PTR(-1))
4640
4652
4653
+ typedef struct ClockTzStatic {
4654
+ WCHAR * was ; /* Previous value of TZ. */
4655
+ #if TCL_MAJOR_VERSION > 8
4656
+ long long lastRefresh ; /* Used for latency before next refresh. */
4657
+ #else
4658
+ long lastRefresh ; /* Used for latency before next refresh. */
4659
+ #endif
4660
+ size_t epoch ; /* Epoch, signals that TZ changed. */
4661
+ size_t envEpoch ; /* Last env epoch, for faster signaling,
4662
+ * that TZ changed via TCL */
4663
+ } ClockTzStatic ;
4664
+ static ClockTzStatic tz = { /* Global timezone info; protected by
4665
+ * clockMutex.*/
4666
+ TZ_INIT_MARKER , 0 , 0 , 0
4667
+ };
4668
+
4641
4669
static size_t
4642
4670
TzsetIfNecessary (void )
4643
4671
{
4644
- typedef struct ClockTzStatic {
4645
- WCHAR * was ; /* Previous value of TZ. */
4646
- long lastRefresh ; /* Used for latency before next refresh. */
4647
- size_t epoch ; /* Epoch, signals that TZ changed. */
4648
- size_t envEpoch ; /* Last env epoch, for faster signaling,
4649
- * that TZ changed via TCL */
4650
- } ClockTzStatic ;
4651
- static ClockTzStatic tz = { /* Global timezone info; protected by
4652
- * clockMutex.*/
4653
- TZ_INIT_MARKER , 0 , 0 , 0
4654
- };
4655
4672
const WCHAR * tzNow ; /* Current value of TZ. */
4656
4673
Tcl_Time now ; /* Current time. */
4657
4674
size_t epoch ; /* The tz.epoch that the TZ was read at. */
@@ -4701,6 +4718,19 @@ TzsetIfNecessary(void)
4701
4718
return epoch ;
4702
4719
}
4703
4720
4721
+ static void
4722
+ ClockFinalize (
4723
+ TCL_UNUSED (void * ))
4724
+ {
4725
+ ClockFrmScnFinalize ();
4726
+
4727
+ if (tz .was && tz .was != TZ_INIT_MARKER ) {
4728
+ ckfree (tz .was );
4729
+ }
4730
+
4731
+ Tcl_MutexFinalize (& clockMutex );
4732
+ }
4733
+
4704
4734
/*
4705
4735
* Local Variables:
4706
4736
* mode: c
0 commit comments