[UnigramDev/Unigram/develop](https://github.com/UnigramDev/Unigram/tree/develop) • [c603834](https://github.com/UnigramDev/Unigram/commit/c603834bb22488c1cb9a7a3db38bc8cf0ef0ffb5) • _3 files, +104/-74_
Close the lock leak in the group call participants and chat positions

An app-wide grep for Monitor.Enter after the topic services turned up four more
files with the same unprotected pairs. Two of them are worth fixing now.

TdExtensions.GetPosition and GetOrder are the ones that matter. Each takes an
early Monitor.Exit inside a loop and another after it, and what they lock is the
Chat itself — the same objects ClientService.OnResult locks on the receive
thread. A throw inside AreTheSame on the UI thread would have leaked that chat's
monitor and stopped update delivery for the whole app, which is the same failure
the ClientService pass was closing. return inside lock releases correctly, so
both lose their early exits entirely.

VoipGroupCallParticipants turns out to be a sixth copy of the paging method,
with the same two shapes as the five already converted, so it gets the same
treatment: decide under the lock how many participants are still to load, then
answer from the cache inside it or fall out and await with nothing held. Its
three return paths are unchanged, including the null for a response that is
neither Ok nor Error.

That the count of this method went from three to five to six as the search
widened is a better argument for merging them than the duplicated line count.

DiceView and VideoNoteContent have the same bug and are left for now: both are
in UI code rather than on the receive thread, so they can wedge a control but
not the update pipeline.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

[UnigramDev/Unigram/develop](https://github.com/UnigramDev/Unigram/tree/develop) • [d9a6e67](https://github.com/UnigramDev/Unigram/commit/d9a6e67a5195bcaa1ca92137bc039456191d92aa) • _2 files, +15/-2_
Ignore a second VoipManager::Start

Assigning over m_impl would destroy the running instance without tgcalls' own
teardown. Nothing calls Start twice today, but it was the last hole left in the
Start/Stop lifecycle after the destructors went in.

Keeping the instance in flight is the right way round: it is the one serving the
live call, and a second descriptor would be for that same call.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

[UnigramDev/Unigram/develop](https://github.com/UnigramDev/Unigram/tree/develop) • [3321c86](https://github.com/UnigramDev/Unigram/commit/3321c8692044fae1a0370236f403dc49919b1b88) • _2 files, +46/-6_
Sort the offered call protocols numerically

The versions were compared as strings, so the registered set

  2.7.7 5.0.0 7.0.0 8.0.0 9.0.0 10.0.0 11.0.0

came out as 9 8 7 5 2.7.7 11 10 — the two newest protocols at the end of a list
the server reads newest first. Filed during the review as latent, on the
assumption the majors were single digits. They have not been for a while.

Compared component by component as numbers now, checked against that set and
for the strict weak ordering std::sort requires.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

[#unigram](?q=%23unigram)