@@ -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
+ Tcl_Free (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
+ Tcl_Free (data -> mcLitIdxs );
361
373
data -> mcLitIdxs = NULL ;
362
374
}
363
375
@@ -4638,20 +4650,21 @@ 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
+ long long lastRefresh ; /* Used for latency before next refresh. */
4656
+ size_t epoch ; /* Epoch, signals that TZ changed. */
4657
+ size_t envEpoch ; /* Last env epoch, for faster signaling,
4658
+ * that TZ changed via TCL */
4659
+ } ClockTzStatic ;
4660
+ static ClockTzStatic tz = { /* Global timezone info; protected by
4661
+ * clockMutex.*/
4662
+ TZ_INIT_MARKER , 0 , 0 , 0
4663
+ };
4664
+
4641
4665
static size_t
4642
4666
TzsetIfNecessary (void )
4643
4667
{
4644
- typedef struct ClockTzStatic {
4645
- WCHAR * was ; /* Previous value of TZ. */
4646
- long 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
4668
const WCHAR * tzNow ; /* Current value of TZ. */
4656
4669
Tcl_Time now ; /* Current time. */
4657
4670
size_t epoch ; /* The tz.epoch that the TZ was read at. */
@@ -4700,6 +4713,19 @@ TzsetIfNecessary(void)
4700
4713
return epoch ;
4701
4714
}
4702
4715
4716
+ static void
4717
+ ClockFinalize (
4718
+ TCL_UNUSED (void * ))
4719
+ {
4720
+ ClockFrmScnFinalize ();
4721
+
4722
+ if (tz .was && tz .was != TZ_INIT_MARKER ) {
4723
+ Tcl_Free (tz .was );
4724
+ }
4725
+
4726
+ Tcl_MutexFinalize (& clockMutex );
4727
+ }
4728
+
4703
4729
/*
4704
4730
* Local Variables:
4705
4731
* mode: c
0 commit comments