Invocation: apply a consistent ordering on the chained hash calculation
...this seems to be a tricky aspect; we use hash-chaining to create derived entries, which may cause the identity of an entry to depend on the order of specialisation. Looked through the possible code paths, but these seem to be quite complicated; I see the lurking danger of creating a second entry (with a different hash), and then in worst case even locking/unlocking a given buffer twice....
This commit is contained in:
parent
6d7a814495
commit
72c7386435
2 changed files with 70 additions and 69 deletions
|
|
@ -217,17 +217,20 @@ namespace engine {
|
|||
forEntry (Key const& parent, const void* bufferAddr, LocalTag const& localTag =LocalTag::UNKNOWN)
|
||||
{
|
||||
Key newKey{parent}; // copy of parent as baseline
|
||||
if (nontrivial(localTag))
|
||||
{
|
||||
if (nontrivial(parent.specifics_))
|
||||
throw error::Logic{"Implementation defined local key should not be overridden. "
|
||||
"Underlying buffer type already defines a nontrivial LocalTag"};
|
||||
newKey.parent_ = HashVal(parent);
|
||||
newKey.hashID_ = chainedHash(newKey.hashID_, localTag);
|
||||
newKey.specifics_ = localTag;
|
||||
}
|
||||
if (bufferAddr)
|
||||
{
|
||||
newKey.parent_ = HashVal(parent);
|
||||
newKey.hashID_ = chainedHash(parent, bufferAddr);
|
||||
if (nontrivial(localTag))
|
||||
{
|
||||
if (nontrivial(parent.specifics_))
|
||||
throw error::Logic{"Implementation defined local key should not be overridden. "
|
||||
"Underlying buffer type already defines a nontrivial LocalTag"};
|
||||
newKey.specifics_ = localTag;
|
||||
} }
|
||||
newKey.hashID_ = chainedHash(newKey.hashID_, bufferAddr);
|
||||
}
|
||||
return newKey;
|
||||
}
|
||||
|
||||
|
|
@ -482,9 +485,8 @@ namespace engine {
|
|||
Entry&
|
||||
store (Entry const& newEntry)
|
||||
{
|
||||
using std::make_pair;
|
||||
REQUIRE (!fetch (newEntry), "duplicate buffer metadata entry");
|
||||
MetadataStore::iterator pos = entries_.insert (make_pair (HashVal(newEntry), newEntry))
|
||||
MetadataStore::iterator pos = entries_.emplace (HashVal(newEntry), newEntry)
|
||||
.first;
|
||||
|
||||
ENSURE (pos != entries_.end());
|
||||
|
|
@ -610,7 +612,7 @@ namespace engine {
|
|||
Key const&
|
||||
key (Key const& parentKey, void* concreteBuffer, LocalTag const& specifics =LocalTag::UNKNOWN)
|
||||
{
|
||||
Key derivedKey = Key::forEntry (parentKey, concreteBuffer);
|
||||
Key derivedKey = Key::forEntry (parentKey, concreteBuffer, specifics);
|
||||
Entry* existing = table_.fetch (derivedKey);
|
||||
|
||||
return existing? *existing
|
||||
|
|
@ -619,16 +621,18 @@ namespace engine {
|
|||
|
||||
/** core operation to access or create a concrete buffer metadata entry.
|
||||
* The hashID of the entry in question is built, based on the parentKey,
|
||||
* which denotes a buffer type, and the concrete buffer address. If yet
|
||||
* unknown, a new concrete buffer metadata Entry is created and initialised
|
||||
* to LOCKED state. Otherwise just the existing Entry is fetched.
|
||||
* which denotes a buffer type, optionally a implementation defined LocalTag,
|
||||
* and the concrete buffer address. If yet unknown, a new concrete buffer
|
||||
* metadata Entry is created and initialised to LOCKED state. Otherwise
|
||||
* just the existing Entry is fetched and locked.
|
||||
* @note this function really \em activates the buffer.
|
||||
* In case the type (Key) involves a TypeHandler (functor),
|
||||
* its constructor function will be invoked, if actually a new
|
||||
* entry gets created. Typically this mechanism will be used
|
||||
* to placement-create an object into the buffer.
|
||||
* @param parentKey a key describing the \em type of the buffer
|
||||
* @param parentKey a key describing the _type_ of the buffer
|
||||
* @param concreteBuffer storage pointer, must not be NULL
|
||||
* @param specifics an implementation defined tag
|
||||
* @param onlyNew disallow fetching an existing entry
|
||||
* @throw error::Logic when #onlyNew is set, but an equivalent entry
|
||||
* was registered previously. This indicates a serious error
|
||||
|
|
@ -660,8 +664,8 @@ namespace engine {
|
|||
throw error::Logic{"Attempt to re-lock a buffer still in use"
|
||||
, LERR_(LIFECYCLE)};
|
||||
|
||||
if (!existing)
|
||||
return store_and_lock (newEntry); // actual creation
|
||||
if (not existing)
|
||||
return store_as_locked (newEntry); // actual creation
|
||||
else
|
||||
return existing->lock (concreteBuffer);
|
||||
}
|
||||
|
|
@ -753,7 +757,7 @@ namespace engine {
|
|||
Key
|
||||
trackKey (PAR parent, DEF specialisation)
|
||||
{
|
||||
Key newKey (parent,specialisation);
|
||||
Key newKey{parent, specialisation};
|
||||
maybeStore (newKey);
|
||||
return newKey;
|
||||
}
|
||||
|
|
@ -762,12 +766,20 @@ namespace engine {
|
|||
maybeStore (Key const& key)
|
||||
{
|
||||
if (isKnown (key)) return;
|
||||
table_.store (Entry (key, NULL));
|
||||
table_.store (Entry{key, nullptr});
|
||||
}
|
||||
|
||||
/** store a fully populated entry immediately starting with locked state
|
||||
* @remark the (optional) constructor function for a type embedded into the
|
||||
* buffer is invoked when a _persistent_ entry transitions to _locked_ state;
|
||||
* since a new buffer created with storage location is already marked as _locked,_
|
||||
* for sake of consistency the embedded constructor must now be invoked; if this
|
||||
* fails, the state has to be transitioned back to FREE before re-throwing.
|
||||
*/
|
||||
Entry&
|
||||
store_and_lock (Entry const& metadata)
|
||||
store_as_locked (Entry const& metadata)
|
||||
{
|
||||
REQUIRE (metadata.isLocked());
|
||||
Entry& newEntry = table_.store (metadata);
|
||||
try
|
||||
{
|
||||
|
|
|
|||
|
|
@ -4686,9 +4686,7 @@
|
|||
</node>
|
||||
<node CREATED="1483909984005" ID="ID_590392737" MODIFIED="1518487921058">
|
||||
<richcontent TYPE="NODE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
<i>aber</i> ist nicht auf dem Visitor-Interface darstellbar
|
||||
|
|
@ -4702,9 +4700,7 @@
|
|||
<node CREATED="1483910056243" ID="ID_967619584" MODIFIED="1518487921058" TEXT="da Record eine Payload ist"/>
|
||||
<node CREATED="1483910117819" ID="ID_117939525" MODIFIED="1576282358145" TEXT="man könnte....">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
....über einen GenNode-Visitor nachdenken
|
||||
|
|
@ -4785,9 +4781,7 @@
|
|||
<node CREATED="1483921149368" ID="ID_1028150245" MODIFIED="1518487921058" TEXT="im GUI nur noch Command-IDs"/>
|
||||
<node CREATED="1483924872930" ID="ID_242219866" MODIFIED="1582487507380">
|
||||
<richcontent TYPE="NODE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
...das wäre eine <b>Protokoll-Erweiterung</b>
|
||||
|
|
@ -4803,9 +4797,7 @@
|
|||
</node>
|
||||
<node CREATED="1483927472385" HGAP="30" ID="ID_774425061" MODIFIED="1582487441000" VSHIFT="13">
|
||||
<richcontent TYPE="NODE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
letztlich verworfen; siehe Ticket <font color="#c52a05">#1058</font>
|
||||
|
|
@ -4838,9 +4830,7 @@
|
|||
</node>
|
||||
<node CREATED="1483924903190" ID="ID_1436586014" MODIFIED="1576282358144" TEXT="wenn man das Design akzeptiert">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
...das heißt,
|
||||
|
|
@ -5118,9 +5108,7 @@
|
|||
</node>
|
||||
<node CREATED="1553902425206" ID="ID_908225698" MODIFIED="1576282358142" TEXT="verwendet im Hintergrund noch den alten PanelManager">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
...der aber irgendwann (demnächst in diesem Theater) umgebaut/zurückgebaut werden soll
|
||||
|
|
@ -5909,9 +5897,7 @@
|
|||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1678573145778" ID="ID_529832770" MODIFIED="1678576114059">
|
||||
<richcontent TYPE="NODE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
<font size="5">Style-Scheme</font> for Lumiera
|
||||
|
|
@ -7746,9 +7732,7 @@
|
|||
</node>
|
||||
<node CREATED="1506723746120" ID="ID_154958112" MODIFIED="1506723790105" TEXT="unit-test dazu">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
VariadicArgumentPicker_test
|
||||
|
|
@ -10012,9 +9996,7 @@
|
|||
<icon BUILTIN="yes"/>
|
||||
<node CREATED="1513396293343" ID="ID_861758487" MODIFIED="1513396293343">
|
||||
<richcontent TYPE="NODE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
...das ist nämlich der triviale Workaround
|
||||
|
|
@ -13607,9 +13589,7 @@
|
|||
<icon BUILTIN="hourglass"/>
|
||||
<node CREATED="1518745809189" ID="ID_334346990" MODIFIED="1518746202442" TEXT="hier geht es um einen subtilen Punkt im Gebrauch des UI-Raumes">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
Man möchte, daß für spezielle Sub-Elemente,
|
||||
|
|
@ -52562,9 +52542,7 @@
|
|||
</node>
|
||||
<node CREATED="1492167970338" FOLDED="true" ID="ID_1983035921" MODIFIED="1613945160418" TEXT="InteractionState ⟺ Invocation-Instance">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
...ist jetzt geklärt.
|
||||
|
|
@ -52657,9 +52635,7 @@
|
|||
</node>
|
||||
<node CREATED="1492173887792" ID="ID_552249287" MODIFIED="1576282357981" TEXT="wozu Auslösung über BusTerm eines Widgets">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
...wenn es doch offenbar für den "fire-and-forget"-Fall
|
||||
|
|
@ -88649,8 +88625,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200<br/>
|
|||
heißt: wir vergeben diese nulläre Optimierung und legen fest, daß das Ergebnis einfach in einem Buffer im Arbeitsspeicher liegt. Jeder Render-Job bekommt dann einen explizit gecodeten Kopier-Schritt
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</html></richcontent>
|
||||
</node>
|
||||
<node CREATED="1721866917499" ID="ID_1329080039" MODIFIED="1722005129923" TEXT="ein spezielles Tag im Buffer-Descriptor ablegen">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
|
|
@ -88660,8 +88635,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200<br/>
|
|||
das müßte eine Marke sein, die die spezielle BufferProvider-Implementierung — also der OutputBufferProvider — erkennt und daraufhin den konkreten extrnen Output-Buffer herausgibt
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</html></richcontent>
|
||||
<linktarget COLOR="#4395d3" DESTINATION="ID_1329080039" ENDARROW="Default" ENDINCLINATION="-105;0;" ID="Arrow_ID_1999279188" SOURCE="ID_1451110951" STARTARROW="None" STARTINCLINATION="6;-21;"/>
|
||||
</node>
|
||||
<node CREATED="1721867643305" ID="ID_327945127" MODIFIED="1721947494363" TEXT="aus dem Schema ausbrechen und diesen Buffer dirrekt durchgeben">
|
||||
|
|
@ -88682,8 +88656,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200<br/>
|
|||
Diese Annahme kann man ziemlich sicher machen; eine Abweichung davon wäre nur möglich bei einem ziemlich speziellen Setup, bei dem dann setets mehrere Ergebnise auf verschiedenen Ebenen aber im gleichen Rechenprozeß anfallen
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</html></richcontent>
|
||||
</node>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1721956892200" ID="ID_1451110951" MODIFIED="1721956974355" TEXT="strukturell wäre das Spezial-Tag die beste Lösung">
|
||||
|
|
@ -88727,8 +88700,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200<br/>
|
|||
...dieser eigentliche Buffer kann auch nochmal per TypeHandler einen »Inlay-Type« bekommen; aber hier beim TrackingHeapBlockProvider ist ja der entscheidenden Punkt, jede Allokation nochmal sekundär zu verzeichnen und nachzuverfolgen, um entsprechende Verifikationen in den Tests zu ermöglichen
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</html></richcontent>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1721962165891" ID="ID_1229002680" MODIFIED="1722091876751" TEXT="das LocalTag darf in jeder Hierarchie genau einmal gesetzt werden">
|
||||
|
|
@ -88759,8 +88731,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200<br/>
|
|||
deshalb habe ich <b>genau für diesen Zweck</b> bereits einen Mechanismus geschaffen
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</html></richcontent>
|
||||
</node>
|
||||
<node CREATED="1721962371425" ID="ID_1532700922" MODIFIED="1722091708754">
|
||||
<richcontent TYPE="NODE"><html>
|
||||
|
|
@ -88770,8 +88741,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200<br/>
|
|||
dieses <font color="#1b40b4" face="Monospaced">LocalTag</font> ist aber nicht überall auf das Buffer-Provider-API herausgeführt
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</html></richcontent>
|
||||
<icon BUILTIN="messagebox_warning"/>
|
||||
</node>
|
||||
</node>
|
||||
|
|
@ -88801,9 +88771,28 @@ Date:   Thu Apr 20 18:53:17 2023 +0200<br/>
|
|||
im Besonderen an die Reihenfolge denken ... mir fällt auf, daß ich <i>chainedHash</i>  verwende; damit wäre der Hash-Key <i>pfadabhängig</i>
|
||||
</p>
|
||||
</body>
|
||||
</html></richcontent>
|
||||
<icon BUILTIN="messagebox_warning"/>
|
||||
<node BACKGROUND_COLOR="#f0d5c5" COLOR="#990033" CREATED="1722129822146" ID="ID_768909598" MODIFIED="1722129849880" TEXT="hilft eine feste Reihenfolge?">
|
||||
<icon BUILTIN="help"/>
|
||||
<node CREATED="1722129884245" ID="ID_732292850" MODIFIED="1722129899976" TEXT="Ausgangspunkt: gegebener (parent)Type-hash"/>
|
||||
<node CREATED="1722129857702" ID="ID_114268361" MODIFIED="1722129879231" TEXT="sinnvollerweise: LocalKey stets zuerst, dann die Adresse"/>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#e0ceaa" COLOR="#980e5e" CREATED="1722129450311" ID="ID_584023703" MODIFIED="1722129479340" TEXT="hab ein ganz ungutes Gefühl hier">
|
||||
<icon BUILTIN="smily_bad"/>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#fafe99" COLOR="#fa002a" CREATED="1722129503142" ID="ID_791304404" MODIFIED="1722129798643" TEXT="Gefahr, einen bereits bestehenden Eintrag nicht mehr zu finden">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
...und zwar je nachdem, in welcher Reihenfolge das LocalTag und die Buffer-Adresse gegeben waren: war das LocalTag zuerst da, dann würde das bereits Teil des Hash; wenn dann später jemand mit der gleichen Buffer-Adresse ankommt, aber ohne das LocalTag, dann wird der bestehende (schlimmstenfalls bereits gelockte) Eintrag nicht gefunden ⟹ es wird ein neuer Eintrag erzeugt und somit <b>zweimal gelockt.</b>
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
<icon BUILTIN="messagebox_warning"/>
|
||||
<icon BUILTIN="broken-line"/>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node COLOR="#338800" CREATED="1722006993331" ID="ID_1387727951" MODIFIED="1722091917790" TEXT="muß mehrfach-Spezialisierung unterbinden">
|
||||
|
|
|
|||
Loading…
Reference in a new issue