mORMot2 DailyЕжедневный обзор коммитов апстрима

Thread wake-up goes lockless, and two API moves worth grepping for

Today is mostly about the asynchronous server core. The thread-wakeup path used by every async HTTP, WebSocket and TFTP server drops its lock in favour of two atomic counters, which should show up as less contention on busy multi-core boxes. One smaller change is worth a grep through your own code: the mORMot 1 compatibility function Lecuyer moved to another unit. TOrmTable.GetAsVariant and ToDocVariant also swapped an out parameter for var, with no consequence for callers. Everything else is internal cleanup.

Коротко

  • Async server thread wake-up is now lockless: two CAS counters replace the TLightLock that guarded acoThreadSmooting.
  • TOrmTable.GetAsVariant and ToDocVariant went from out to var: no caller-visible change, one compiler finalization less per call.
  • The legacy Lecuyer function moved from mormot.core.base to mormot.crypt.core and now returns the shared ThreadRandom generator.
  • TLoggedThread gained an ExecuteDone property, standing in for the RTL Finished property on older compilers.
  • The TFTP server compiles again on Delphi 7 and 2007 after last week's worker-lifetime fix.

Рекомендации по обновлению

Nothing here forces an emergency upgrade. If you run async servers under load, this batch is worth pulling for the wake-up path alone — check the Lecuyer note first, since a unit move can compile differently in your tree than it does upstream. If you build with PUREMORMOT2, the Lecuyer removal is a no-op for you.

Сборка2.4.16604 → 2.4.16618
Коммиты11
Строки+467 -280
Чтение4 мин

9 из 9 записей · 11 коммитов в апстриме

Сюжеты
# Запись Категория Модули
1 Средний Async server thread wake-up drops its lock for atomic counters mormot.core.base gains LockedGet32(Target: PInteger), an atomic read-and-reset built on LockedExc32. mormot.net.async then replaces the fThreadPollingWakeupSafe TLightLock with two cardinal CAS counters, fWakeupOne and fWakeupEvents, and reads them through LockedGet32 inside ThreadPollingWakeupOne and ThreadPollingWakeupEvents. About 250 lines of the wake-up path were reshuffled around those counters. Производительность mormot.core.base+1 73cb9543+150-116

core: new LockedGet32() wrapper function

Влияние

No API change for application code. On a busy async HTTP or WebSocket server with acoThreadSmooting enabled, threads no longer serialise on a lock to decide who wakes up, so wake-up latency should flatten out under contention. The effect grows with core count and connection churn; a lightly loaded server will not notice.

Публичный API

  • LockedGet32(Target: PInteger): integeradded — Atomic 'read then zero' on a 32-bit value, in mormot.core.base.

Arnaud Bouchez · 12:03 UTC · открыть коммит на GitHub →

2 Средний TFTP server builds again on Delphi 7 and 2007 The TTftpConnectionThread.HasFinished helper introduced by pull request #556 relied on the RTL Finished property, which does not exist on Delphi 7 and 2007. It was removed and replaced by the new TLoggedThread.ExecuteDone property, and the shutdown loop that terminated each worker was simplified at the same time. Компилятор и платформы mormot.net.tftp.server 0acf8522+19-25

net: fixed TFTP server compilation under Delphi 7/2007 - after #556 fix

Влияние

If you build the TFTP server on an old Delphi, it compiles again. Everyone else gets the same behaviour through a different property. This is the compatibility follow-up to the worker-lifetime fix merged earlier today.

Arnaud Bouchez · 07:42 UTC · PR #556 · открыть коммит на GitHub →

3 Средний The legacy Lecuyer function moved out of mormot.core.base The mORMot 1 compatibility function Lecuyer and its _Lecuyer threadvar were removed from mormot.core.base and re-declared in mormot.crypt.core, where the function now simply returns ThreadRandom. As before, the whole thing is compiled out under PUREMORMOT2. This unblocks compilation in PUREMORMOT2 mode, which the previous refactoring had broken. Компилятор и платформы mormot.core.base+1 fdb5f378+14-28

crypt: fixed compilation in PUREMORMOT2 mode - the Lecuyer function should move to mormot.crypt.core and use the better RandomLecuyer() factory

Влияние

Code still calling Lecuyer — typically old mORMot 1 code — now needs mormot.crypt.core in its uses clause instead of relying on mormot.core.base, and shares the ThreadRandom generator rather than its own threadvar. If you already build with PUREMORMOT2 the symbol never existed for you and nothing changes.

Стоит взглянуть

Grep for 'Lecuyer' outside the framework. Where it appears, add mormot.crypt.core to the uses clause, or switch to ThreadRandom / RandomLecuyer directly.

Публичный API

  • Lecuyer: PLecuyerrenamed — Same name, different unit: mormot.core.base -> mormot.crypt.core.

Arnaud Bouchez · 06:28 UTC · открыть коммит на GitHub →

4 Низкий New ShortStringToVariant helper for UTF-8 short strings mormot.core.base adds ShortStringToVariant(const Txt: ShortString; var Value: variant), an inlined wrapper over RawUtf8ToVariant that produces a varString RawUtf8 variant from a UTF-8 encoded ShortString. Новые возможности mormot.core.base a4bad08e+11-2

core: new ShortStringToVariant() function

Влияние

Additive convenience, used internally by today's ORM variant work. Nothing to change in existing code; it saves a manual conversion if you convert ShortStrings to variants yourself.

Публичный API

  • ShortStringToVariant(const Txt: ShortString; var Value: variant)added

Модули

Arnaud Bouchez · 07:41 UTC · открыть коммит на GitHub →

5 Низкий TLoggedThread can now tell you its Execute has finished mormot.core.threads adds a private fExecuteDone flag, set once the thread body returns, exposed as the read-only ExecuteDone property on TLoggedThread. The comment says it mimics the Finished property of newer Delphi and FPC runtimes. Новые возможности mormot.core.threads e42d4a3c+7-3

core: new TLoggedThread.ExecuteDone property

Влияние

Useful when you shut a pool of worker threads down and need to know which ones are really out of Execute, on compilers whose RTL has no Finished property. Purely additive: existing code is unaffected.

Публичный API

  • TLoggedThread.ExecuteDone: booleanadded — Read-only, set when Execute returns.

Arnaud Bouchez · 07:42 UTC · открыть коммит на GitHub →

6 Низкий TOrmTable variant getters shed a redundant clear at the call site TOrmTableAbstract.GetAsVariant and TOrmTableAbstract.ToDocVariant changed their destination parameter from 'out value: variant' to 'var value: variant', and the time-field conversion moved into a new ValueVarTimeAsText helper that fills the variant in place. The body still clears the destination itself — VarClearAndSetType(value, varNull) is the first statement of GetAsVariant — so all the change removes is the finalization the compiler inserted at every call site. Производительность mormot.orm.base 5530a593+69-59

orm: optimize TOrmTable variant generation

Влияние

No change for callers. Because the function clears the destination on entry, a variant you pass in cannot carry stale content and nothing leaks. What disappears is one compiler-inserted finalization per call, which is where the speed-up comes from when walking a large result set row by row. Recompiling is enough.

Публичный API

  • TOrmTableAbstract.GetAsVariant(row, field: PtrInt; var value: variant; ...)signature-changed — out -> var; the function clears the destination itself, so callers are unaffected.
  • TOrmTableAbstract.ToDocVariant(Row: PtrInt; var doc: variant; ...)signature-changed — out -> var; the function clears the destination itself, so callers are unaffected.

Модули

Arnaud Bouchez · 06:52 UTC · открыть коммит на GitHub →

7 Низкий Wake-up rewrite finished, with inlining made conditional again The finishing commit of the lockless wake-up work. ThreadPollingWakeupOne keeps its inline directive but behind {$ifdef HASINLINE}, ThreadPollingWakeupEvents loses inlining altogether, and the comment describing when a thread is woken was rewritten to mention slow REST processing next to accept() on an idle server. Производительность mormot.net.async 4c702f55+5-5

net: new lockless acoThreadSmooting implementation - use two CAS counters to avoid spinning on contention during thread wakeup

Влияние

No behaviour change for application code. The conditional inline matters only if you build with a compiler that has no inlining support, where the previous commit would not have compiled.

Модули

Arnaud Bouchez · 12:08 UTC · открыть коммит на GitHub →

8 Низкий ORM temp variants switch to TSynVarData and standard VarClear Several ORM helpers that used a raw TVarData scratch value now use TSynVarData, set VType directly instead of poking through PCardinal, and release it with VarClear(variant(value)) rather than calling VarClearProc. Same code paths, clearer and less pointer-cast-heavy. Внутреннее устройство mormot.orm.base 7813f048+14-14

orm: some refactoring about variant values

Влияние

No impact on application code: these are local temporaries inside the ORM. Worth knowing only if you maintain a patch against these units, where it will conflict.

Модули

Arnaud Bouchez · 07:14 UTC · открыть коммит на GitHub →

9 Низкий TFTP server test coverage extended around the #556 fix test.net.proto exercises the TFTP server more thoroughly after the worker-lifetime pull request, checking connection shutdown rather than only the happy path. Тесты ca302d17+14-8

tests: better TFTP server coverage - refactored #556 pull request

Влияние

No impact on application code. It makes the regression suite more likely to catch a future break in TFTP worker shutdown.

Arnaud Bouchez · 07:43 UTC · PR #556 · открыть коммит на GitHub →

Активность апстрима коммитов в день · последние 60 дней
Коммиты977
Активных дней44/60
Пик активности2026-09-30
Максимум60
2026-08-15: 0 commits2026-08-16: 0 commits2026-08-17: 0 commits2026-08-18: 0 commits2026-08-19: 0 commits2026-08-20: 0 commits2026-08-21: 0 commits2026-08-22: 0 commits2026-08-23: 0 commits2026-08-24: 0 commits2026-08-25: 0 commits2026-08-26: 0 commits2026-08-27: 26 commits2026-08-28: 11 commits2026-08-29: 10 commits2026-08-30: 1 commit2026-08-31: 23 commits2026-09-01: 0 commits2026-09-02: 20 commits2026-09-03: 29 commits2026-09-04: 35 commits2026-09-05: 13 commits2026-09-06: 0 commits2026-09-07: 0 commits2026-09-08: 23 commits2026-09-09: 10 commits2026-09-10: 17 commits2026-09-11: 23 commits2026-09-12: 14 commits2026-09-13: 9 commits2026-09-14: 7 commits2026-09-15: 4 commits2026-09-16: 24 commits2026-09-17: 26 commits2026-09-18: 21 commits2026-09-19: 59 commits2026-09-20: 13 commits2026-09-21: 5 commits2026-09-22: 34 commits2026-09-23: 17 commits2026-09-24: 57 commits2026-09-25: 22 commits2026-09-26: 26 commits2026-09-27: 0 commits2026-09-28: 2 commits2026-09-29: 19 commits2026-09-30: 60 commits2026-10-01: 26 commits2026-10-02: 30 commits2026-10-03: 32 commits2026-10-04: 15 commits2026-10-05: 1 commit2026-10-06: 26 commits2026-10-07: 37 commits2026-10-08: 27 commits2026-10-09: 35 commits2026-10-10: 33 commits2026-10-11: 9 commits2026-10-12: 11 commits2026-10-13: 35 commits
2026-08-152026-10-13