Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | closes [167e0635db]: solves leaks, valgrind test, etc |
---|---|
Downloads: | Tarball | ZIP archive | SQL archive |
Timelines: | family | ancestors | descendants | both | trunk | main |
Files: | files | file ages | folders |
SHA3-256: |
b73516f7cfccbc9ff8478edd1bf1bbac |
User & Date: | sebres 2024-04-17 15:03:46 |
References
2024-04-17
| ||
15:13 | cherrypick [b73516f7cfccbc9f] to 8.7 - closes [167e0635db]: solves leaks, valgrind test, etc check-in: 62f9f8b56b user: sebres tags: core-8-branch | |
Context
2024-04-17
| ||
15:17 | merge point (with small amend, same type as in 9.0 header declared for Tcl_Time::sec) check-in: fdb8258252 user: sebres tags: trunk, main | |
15:13 | cherrypick [b73516f7cfccbc9f] to 8.7 - closes [167e0635db]: solves leaks, valgrind test, etc check-in: 62f9f8b56b user: sebres tags: core-8-branch | |
15:03 | closes [167e0635db]: solves leaks, valgrind test, etc check-in: b73516f7cf user: sebres tags: trunk, main | |
14:58 | merge 8.7 (clock compat repair) check-in: 3dbfd59478 user: sebres tags: trunk, main | |
2024-04-15
| ||
13:21 | clean clock mutex Closed-Leaf check-in: 2484b0ade8 user: sebres tags: dgp-bug-167e0635db | |
Changes
Changes to generic/tclClock.c.
︙ | ︙ | |||
111 112 113 114 115 116 117 118 119 120 121 122 123 124 | static Tcl_ObjCmdProc ClockAddObjCmd; static int ClockValidDate(DateInfo *, ClockFmtScnCmdArgs *, int stage); static struct tm * ThreadSafeLocalTime(const time_t *); static size_t TzsetIfNecessary(void); static void ClockDeleteCmdProc(void *); static Tcl_ObjCmdProc ClockSafeCatchCmd; /* * Structure containing description of "native" clock commands to create. */ struct ClockCommand { const char *name; /* The tail of the command name. The full name * is "::tcl::clock::<name>". When NULL marks | > | 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 | static Tcl_ObjCmdProc ClockAddObjCmd; static int ClockValidDate(DateInfo *, ClockFmtScnCmdArgs *, int stage); 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. */ struct ClockCommand { const char *name; /* The tail of the command name. The full name * is "::tcl::clock::<name>". When NULL marks |
︙ | ︙ | |||
175 176 177 178 179 180 181 182 183 184 185 186 187 188 | const struct ClockCommand *clockCmdPtr; char cmdName[50]; /* Buffer large enough to hold the string *::tcl::clock::GetJulianDayFromEraYearMonthDay * plus a terminating NUL. */ Command *cmdPtr; ClockClientData *data; int i; /* * Safe interps get [::clock] as alias to a parent, so do not need their * own copies of the support routines. */ if (Tcl_IsSafe(interp)) { | > > > > > > > > > | 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 | const struct ClockCommand *clockCmdPtr; char cmdName[50]; /* Buffer large enough to hold the string *::tcl::clock::GetJulianDayFromEraYearMonthDay * plus a terminating NUL. */ Command *cmdPtr; 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. */ if (Tcl_IsSafe(interp)) { |
︙ | ︙ | |||
348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 | for (i = 0; i < LIT__END; ++i) { Tcl_DecrRefCount(data->literals[i]); } if (data->mcLiterals != NULL) { for (i = 0; i < MCLIT__END; ++i) { Tcl_DecrRefCount(data->mcLiterals[i]); } data->mcLiterals = NULL; } if (data->mcLitIdxs != NULL) { for (i = 0; i < MCLIT__END; ++i) { Tcl_DecrRefCount(data->mcLitIdxs[i]); } data->mcLitIdxs = NULL; } ClockConfigureClear(data); Tcl_Free(data->literals); Tcl_Free(data); | > > | 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 | for (i = 0; i < LIT__END; ++i) { Tcl_DecrRefCount(data->literals[i]); } if (data->mcLiterals != NULL) { 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; } ClockConfigureClear(data); Tcl_Free(data->literals); Tcl_Free(data); |
︙ | ︙ | |||
4633 4634 4635 4636 4637 4638 4639 4640 4641 4642 4643 | #else #define WCHAR char #define wcslen strlen #define wcscmp strcmp #define wcscpy strcpy #endif #define TZ_INIT_MARKER ((WCHAR *) INT2PTR(-1)) static size_t TzsetIfNecessary(void) { | > > > > > > > > > > > > < < < < < < < < < < < | 4645 4646 4647 4648 4649 4650 4651 4652 4653 4654 4655 4656 4657 4658 4659 4660 4661 4662 4663 4664 4665 4666 4667 4668 4669 4670 4671 4672 4673 4674 | #else #define WCHAR char #define wcslen strlen #define wcscmp strcmp #define wcscpy strcpy #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) { const WCHAR *tzNow; /* Current value of TZ. */ Tcl_Time now; /* Current time. */ size_t epoch; /* The tz.epoch that the TZ was read at. */ /* * Prevent performance regression on some platforms by resolving of system time zone: * small latency for check whether environment was changed (once per second) |
︙ | ︙ | |||
4695 4696 4697 4698 4699 4700 4701 4702 4703 4704 4705 4706 4707 4708 4709 | } else { epoch = tz.epoch; } Tcl_MutexUnlock(&clockMutex); return epoch; } /* * Local Variables: * mode: c * c-basic-offset: 4 * fill-column: 78 * End: */ | > > > > > > > > > > > > > | 4708 4709 4710 4711 4712 4713 4714 4715 4716 4717 4718 4719 4720 4721 4722 4723 4724 4725 4726 4727 4728 4729 4730 4731 4732 4733 4734 4735 | } else { epoch = tz.epoch; } Tcl_MutexUnlock(&clockMutex); 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 * c-basic-offset: 4 * fill-column: 78 * End: */ |
Changes to generic/tclClockFmt.c.
︙ | ︙ | |||
22 23 24 25 26 27 28 | static void ClockFmtObj_FreeInternalRep(Tcl_Obj *objPtr); static int ClockFmtObj_SetFromAny(Tcl_Interp *, Tcl_Obj *objPtr); static void ClockFmtObj_UpdateString(Tcl_Obj *objPtr); TCL_DECLARE_MUTEX(ClockFmtMutex); /* Serializes access to common format list. */ static void ClockFmtScnStorageDelete(ClockFmtScnStorage *fss); | < | 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | static void ClockFmtObj_FreeInternalRep(Tcl_Obj *objPtr); static int ClockFmtObj_SetFromAny(Tcl_Interp *, Tcl_Obj *objPtr); static void ClockFmtObj_UpdateString(Tcl_Obj *objPtr); TCL_DECLARE_MUTEX(ClockFmtMutex); /* Serializes access to common format list. */ static void ClockFmtScnStorageDelete(ClockFmtScnStorage *fss); #ifndef TCL_CLOCK_FULL_COMPAT #define TCL_CLOCK_FULL_COMPAT 1 #endif /* * Derivation of tclStringHashKeyType with another allocEntryProc |
︙ | ︙ | |||
678 679 680 681 682 683 684 | } static void ClockFmtObj_FreeInternalRep( Tcl_Obj *objPtr) { ClockFmtScnStorage *fss = ObjClockFmtScn(objPtr); | | | 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 | } static void ClockFmtObj_FreeInternalRep( Tcl_Obj *objPtr) { ClockFmtScnStorage *fss = ObjClockFmtScn(objPtr); if (fss != NULL && initialized) { Tcl_MutexLock(&ClockFmtMutex); /* decrement object reference count of format/scan storage */ if (--fss->objRefCount <= 0) { #if CLOCK_FMT_SCN_STORAGE_GC_SIZE > 0 /* don't remove it right now (may be reusable), just add to GC */ ClockFmtScnStorageGC_In(fss); #else |
︙ | ︙ | |||
832 833 834 835 836 837 838 | ClockFmtScnStorageHashKeyType.freeEntryProc = ClockFmtScnStorageFreeProc; /* initialize hash table */ Tcl_InitCustomHashTable(&FmtScnHashTable, TCL_CUSTOM_TYPE_KEYS, &ClockFmtScnStorageHashKeyType); initialized = 1; | < | 831 832 833 834 835 836 837 838 839 840 841 842 843 844 | ClockFmtScnStorageHashKeyType.freeEntryProc = ClockFmtScnStorageFreeProc; /* initialize hash table */ Tcl_InitCustomHashTable(&FmtScnHashTable, TCL_CUSTOM_TYPE_KEYS, &ClockFmtScnStorageHashKeyType); initialized = 1; } /* get or create entry (and alocate storage) */ hPtr = Tcl_CreateHashEntry(&FmtScnHashTable, strFmt, &isNew); if (hPtr != NULL) { fss = FmtScn4HashEntry(hPtr); |
︙ | ︙ | |||
3557 3558 3559 3560 3561 3562 3563 | ClockFrmScnClearCaches(void) { Tcl_MutexLock(&ClockFmtMutex); /* clear caches ... */ Tcl_MutexUnlock(&ClockFmtMutex); } | | | < > > > < > | 3555 3556 3557 3558 3559 3560 3561 3562 3563 3564 3565 3566 3567 3568 3569 3570 3571 3572 3573 3574 3575 3576 3577 3578 3579 3580 3581 3582 3583 3584 3585 3586 3587 3588 | ClockFrmScnClearCaches(void) { Tcl_MutexLock(&ClockFmtMutex); /* clear caches ... */ Tcl_MutexUnlock(&ClockFmtMutex); } void ClockFrmScnFinalize() { if (!initialized) { return; } Tcl_MutexLock(&ClockFmtMutex); #if CLOCK_FMT_SCN_STORAGE_GC_SIZE > 0 /* clear GC */ ClockFmtScnStorage_GC.stackPtr = NULL; ClockFmtScnStorage_GC.stackBound = NULL; ClockFmtScnStorage_GC.count = 0; #endif if (initialized) { initialized = 0; Tcl_DeleteHashTable(&FmtScnHashTable); } Tcl_MutexUnlock(&ClockFmtMutex); Tcl_MutexFinalize(&ClockFmtMutex); } /* * Local Variables: * mode: c * c-basic-offset: 4 * fill-column: 78 * End: */ |
Changes to generic/tclDate.h.
︙ | ︙ | |||
556 557 558 559 560 561 562 563 564 | Tcl_Obj *objPtr); MODULE_SCOPE Tcl_Obj * ClockLocalizeFormat(ClockFmtScnCmdArgs *opts); MODULE_SCOPE int ClockScan(DateInfo *info, Tcl_Obj *strObj, ClockFmtScnCmdArgs *opts); MODULE_SCOPE int ClockFormat(DateFormat *dateFmt, ClockFmtScnCmdArgs *opts); MODULE_SCOPE void ClockFrmScnClearCaches(void); #endif /* _TCLCLOCK_H */ | > | 556 557 558 559 560 561 562 563 564 565 | Tcl_Obj *objPtr); MODULE_SCOPE Tcl_Obj * ClockLocalizeFormat(ClockFmtScnCmdArgs *opts); MODULE_SCOPE int ClockScan(DateInfo *info, Tcl_Obj *strObj, ClockFmtScnCmdArgs *opts); MODULE_SCOPE int ClockFormat(DateFormat *dateFmt, ClockFmtScnCmdArgs *opts); MODULE_SCOPE void ClockFrmScnClearCaches(void); MODULE_SCOPE void ClockFrmScnFinalize(); #endif /* _TCLCLOCK_H */ |