Skip to content

Update initialization to use loadUnaligned for UInt32 - #1

Open
salling wants to merge 12 commits into
mainfrom
fix/tsan-crash-xcode27
Open

Update initialization to use loadUnaligned for UInt32#1
salling wants to merge 12 commits into
mainfrom
fix/tsan-crash-xcode27

Conversation

@salling

@salling salling commented Jun 22, 2026

Copy link
Copy Markdown
Owner

Fixes crash when building with Xcode 27.0b1 and thread sanitizer

Screenshot 2026-06-22 at 22 45 36

Checklist

  • If applicable, unit tests (N/A)
  • If applicable, create follow-up issues for purchases-android and hybrids (N/A)

Motivation

I noticed spurious crashes when running my app in simulator when compiling with Xcode 27.0b1. Enabling thread sanitizer made the crash happen every time. There's speculation that the new compiler has introduced changes in how memory is aligned.

Description

I ran the app with t-san after my change, and it works fine.

salling and others added 12 commits June 22, 2026 22:49
Fixes crash when building with Xcode 27.0b1 and thread sanitizer
* feat(remote-config): add RemoteConfigManager

* fix(remote-config): adapt RemoteConfigManager to struct-based fetch result

Update the manager and its tests for the struct RemoteConfigFetchResult and
the relocated per-topic blob-ref derivation, and drop the misleading
topicBlobRefs comment.

Co-authored-by: Cursor <cursoragent@cursor.com>

* fix(remote-config): update refresh timestamp on no content

---------

Co-authored-by: Antonio Pallares <antonio.pallares@revenuecat.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
…er (RevenueCat#7093)

* feat(remote-config): add RemoteConfigSourceProvider for source failover

Adds RemoteConfigSourceProvider, which orders config sources via
WeightedSourceSelector and hands out the current healthy endpoint,
falling back to the next one when an endpoint is reported unhealthy.
A per-handout UUID token discards stale unhealthy reports so a single
failing endpoint can't advance the order more than once. Not yet wired
into networking.

Co-authored-by: Cursor <cursoragent@cursor.com>

* docs(remote-config): trim RemoteConfigSourceProvider comments

Co-authored-by: Cursor <cursoragent@cursor.com>

* refactor(remote-config): make RemoteConfigSourceProvider an api/blob address book

Take a RemoteConfigSources object (api + blob), dedup each list by url, and
fail over the two kinds independently via a private SourceFailover wrapping
WeightedSourceSelector. Use the endpoint url as identity (dropping the UUID
token) so stale/concurrent reports are ignored, and build endpoints once
during dedup so reads never re-map. Add RemoteConfigSourceProviderType and
MockRemoteConfigSourceProvider for downstream mocking.

Co-authored-by: Cursor <cursoragent@cursor.com>

* refactor(remote-config): refine RemoteConfigSourceProvider endpoint model

Embed RemoteConfigSource in RemoteConfigEndpoint (forwarding url/priority/
weight) so endpoints are built once and never re-mapped, and compare endpoints
by kind+url. Make restart() per-kind, drop unused WeightedSource/Equatable
conformances and default inits, and collapse duplicate source urls to the
highest-priority occurrence (tie-broken by weight), logging conflicts.

Co-authored-by: Cursor <cursoragent@cursor.com>

* refactor(remote-config): drop redundant init and Equatable conformance

Rely on the synthesized memberwise init for RemoteConfigSources and remove the
unused Equatable conformance on RemoteConfigEndpoint (tests compare urls).

Co-authored-by: Cursor <cursoragent@cursor.com>

* refactor(remote-config): clarify source handle naming and strengthen concurrency test

Rename RemoteConfigEndpoint to RemoteConfigSourceHandle and its Kind enum to
Purpose, expose currentAPISource/currentBlobSource, and use a named parameter
in restart(for:). Also rewrite the concurrent test to deterministically assert
that many threads reporting the same source advance the provider exactly once.

Co-authored-by: Cursor <cursoragent@cursor.com>

* refactor(remote-config): simplify RemoteConfigSourceProvider API

Drop the RemoteConfigSources wrapper in favor of apiSources/blobSources init
params, and replace currentAPISource/currentBlobSource with a single
getCurrent(for:) keyed by purpose, consistent with restart(for:).

Co-authored-by: Cursor <cursoragent@cursor.com>

* refactor(remote-config): log conflicting duplicate sources as a warning

Conflicting priority/weight on a shared URL signals misconfigured input, a
degraded state better surfaced via Logger.warn than Logger.debug.

Co-authored-by: Cursor <cursoragent@cursor.com>

* fix(remote-config): ignore stale unhealthy reports across restart

Identify each handout with an opaque monotonic token that bumps on every
fallback and on restart, instead of using the source url. reportUnhealthy
only advances when the reported handle still carries the current token, so
reports left over from before a restart can no longer skip a source in the
new cycle. The token also subsumes the previous url-based dedup of stale or
concurrent reports within a cycle.

RemoteConfigSource now drives WeightedSourceSelector (it is the WeightedSource),
and SourceFailover stamps the current token onto each handle at handout time.
The handle is reduced to purpose + source + token (+ url accessor) and its
init is fileprivate so handles can only originate from getCurrent.

Co-authored-by: Cursor <cursoragent@cursor.com>

---------

Co-authored-by: Cursor <cursoragent@cursor.com>
…RevenueCat#7074)

* feat(remote-config): make rc container validation domain-specific

* refactor(remote-config): share config element validation

* refactor(remote-config): decode remote config container in http client

* fix(remote-config): align rebased container tests

* fix(remote-config): fix remote config signature verification

* docs(remote-config): clarify rc container validation comments
* feat(remote-config): add blob store

* fix(remote-config): prune blobs after cache write

* fix(remote-config): filter inline blobs by referenced refs

* fix(remote-config): align blob persistence with android

* feat(remote-config): sync blob storage with Android fixtures

* fix(remote-config): guard blob pruning against malformed refs

* perf(remote-config): avoid repeated blob store reads

* fix(remote-config): ignore malformed refs when pruning blobs
…RevenueCat#7080)

* fix(remote-config): use v1 config endpoint

* feat(remote-config): include app user id in request

* feat(remote-config): move domain into config path

* fix(remote-config): always encode prefetched blobs

* chore(remote-config): remove redundant coding key comment

* fix(remote-config): update nonce path test
Bumps [fastlane-plugin-revenuecat_internal](https://github.com/RevenueCat/fastlane-plugin-revenuecat_internal) from `70bf5c7` to `dab6765`.
- [Release notes](https://github.com/RevenueCat/fastlane-plugin-revenuecat_internal/releases)
- [Commits](RevenueCat/fastlane-plugin-revenuecat_internal@70bf5c7...dab6765)

---
updated-dependencies:
- dependency-name: fastlane-plugin-revenuecat_internal
  dependency-version: dab67655d71eaf08b40f74339e4bb17d16436c32
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Bumps [faraday](https://github.com/lostisland/faraday) from 1.10.5 to 1.10.6.
- [Release notes](https://github.com/lostisland/faraday/releases)
- [Changelog](https://github.com/lostisland/faraday/blob/main/CHANGELOG.md)
- [Commits](lostisland/faraday@v1.10.5...v1.10.6)

---
updated-dependencies:
- dependency-name: faraday
  dependency-version: 1.10.6
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Bumps [faraday](https://github.com/lostisland/faraday) from 1.10.5 to 1.10.6.
- [Release notes](https://github.com/lostisland/faraday/releases)
- [Changelog](https://github.com/lostisland/faraday/blob/main/CHANGELOG.md)
- [Commits](lostisland/faraday@v1.10.5...v1.10.6)

---
updated-dependencies:
- dependency-name: faraday
  dependency-version: 1.10.6
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
…7103)

* Add @_spi(Internal) workflow preview injection seam

Lets a companion app render dashboard workflows (including drafts) by injecting
synthesized data into the existing renderer, with no backend fetch:

- C-1: @_spi(Internal) public initializers on PublishedWorkflow / WorkflowStep /
  WorkflowScreen / WorkflowTrigger (AnyDecodable-typed config fields stay
  internal and defaulted).
- C-2: expose WorkflowContext as @_spi(Internal) public (initializer stays
  internal; built via the factory below).
- C-3: Offerings.preview(offerings:) factory + WorkflowPreview.makeContext,
  reusing PurchaseHandler.makeWorkflowContext (the fetch-free assembly).
- C-4: PaywallView(workflowContext:) seam that seeds an injected context,
  bypassing the /workflows fetch (gated #if !os(tvOS)).
- C-5: WorkflowPreview tests (build via the C-1 inits, makeContext positive +
  missing-offering negative).

iOS-only; tvOS stays excluded. No backend or production fetch-path changes.
Adds @_spi surface, so api/*.swiftinterface baselines must be regenerated.



* Register WorkflowPreview files in RevenueCat.xcodeproj

Keeps the committed project in sync (Danger enforces this): adds
WorkflowPreview.swift to the RevenueCatUI target and references
WorkflowPreviewTests.swift, mirroring their siblings.



* Trim WorkflowPreview doc comments per review



---------


(cherry picked from commit 9068b71)

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants