Skip to content

Allow building on Linux#38

Open
lhoward wants to merge 25 commits into
sideeffect-io:mainfrom
lhoward:linux
Open

Allow building on Linux#38
lhoward wants to merge 25 commits into
sideeffect-io:mainfrom
lhoward:linux

Conversation

@lhoward

@lhoward lhoward commented Jul 18, 2023

Copy link
Copy Markdown

Linux build fixes, pending whilst resolving test failures.

@lhoward

lhoward commented Jul 18, 2023

Copy link
Copy Markdown
Author

Swift version:

lukeh@liebling:~/CVSRoot/padl/AsyncExtensions-1$ swift --version
Swift version 5.9-dev (LLVM edfa23b742ff932, Swift 18d8d9b752723b6)
Target: aarch64-unknown-linux-gnu

Test failures:

Test Case 'AsyncCurrentValueSubjectTests.test_subject_handles_concurrency' started at 2023-07-19 05:19:15.360
Process 90935 stopped
* thread #2, name = 'AsyncExtensions', stop reason = signal SIGTRAP
    frame #0: 0x0000fffff6dfa0f0 libXCTest.so`XCTest.XCTestCase.waitForExpectations(timeout: Swift.Double, file: Swift.StaticString, line: Swift.Int, handler: Swift.Optional<(Swift.Optional<Swift.Error>) -> ()>) -> () + 820
libXCTest.so`XCTest.XCTestCase.waitForExpectations(timeout: Swift.Double, file: Swift.StaticString, line: Swift.Int, handler: Swift.Optional<(Swift.Optional<Swift.Error>) -> ()>) -> ():
->  0xfffff6dfa0f0 <+820>: brk    #0x1

libXCTest.so`lazy protocol witness table accessor for type XCTest.XCTWaiter.Result and conformance XCTest.XCTWaiter.Result : Swift.RawRepresentable in XCTest:
    0xfffff6dfa0f4 <+0>:   stp    x29, x30, [sp, #-0x10]!
    0xfffff6dfa0f8 <+4>:   adrp   x8, 45
    0xfffff6dfa0fc <+8>:   mov    x29, sp
Target 0: (AsyncExtensionsPackageTests.xctest) stopped.
(lldb) bt
* thread #2, name = 'AsyncExtensions', stop reason = signal SIGTRAP
  * frame #0: 0x0000fffff6dfa0f0 libXCTest.so`XCTest.XCTestCase.waitForExpectations(timeout: Swift.Double, file: Swift.StaticString, line: Swift.Int, handler: Swift.Optional<(Swift.Optional<Swift.Error>) -> ()>) -> () + 820
    frame #1: 0x0000aaaaaac005d8 AsyncExtensionsPackageTests.xctest`AsyncCurrentValueSubjectTests.test_subject_handles_concurrency(self=0x0000aaaaab2b7820) at AsyncCurrentValueSubjectTests.swift:178:11
    frame #2: 0x0000fffff78f5578 libswift_Concurrency.so`swift::runJobInEstablishedExecutorContext(swift::Job*) + 408
    frame #3: 0x0000fffff78f5e98 libswift_Concurrency.so`swift_job_run + 96
    frame #4: 0x0000fffff772a818 libdispatch.so`_dispatch_continuation_pop + 236
    frame #5: 0x0000fffff772a614 libdispatch.so`_dispatch_async_redirect_invoke + 216
    frame #6: 0x0000fffff7735948 libdispatch.so`_dispatch_worker_thread + 440
    frame #7: 0x0000fffff696d5c8 libc.so.6`start_thread(arg=0x0000000000000000) at pthread_create.c:442:8
    frame #8: 0x0000fffff69d5d1c libc.so.6`thread_start at clone.S:79
(lldb) up

@lhoward lhoward changed the title Linux Allow building on Linux Jul 18, 2023
@lhoward lhoward marked this pull request as ready for review July 22, 2023 08:20

@0xfeedface1993 0xfeedface1993 left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good job! Thanks!

Build success, but test failed.

swift version

Swift version 5.8.1 (swift-5.8.1-RELEASE)
Target: x86_64-unknown-linux-gnu

Test failures:

Test Suite 'AsyncCurrentValueSubjectTests' started at 2023-07-29 03:55:45.682
Test Case 'AsyncCurrentValueSubjectTests.test_init_stores_element' started at 2023-07-29 03:55:45.682
Test Case 'AsyncCurrentValueSubjectTests.test_init_stores_element' passed (0.0 seconds)
Test Case 'AsyncCurrentValueSubjectTests.test_sendFinished_ends_the_subject_and_immediately_resumes_futur_consumer' started at 2023-07-29 03:55:45.682
Test Case 'AsyncCurrentValueSubjectTests.test_sendFinished_ends_the_subject_and_immediately_resumes_futur_consumer' passed (0.0 seconds)
Test Case 'AsyncCurrentValueSubjectTests.test_send_pushes_values_in_the_subject' started at 2023-07-29 03:55:45.682
Test Case 'AsyncCurrentValueSubjectTests.test_send_pushes_values_in_the_subject' passed (0.0 seconds)
Test Case 'AsyncCurrentValueSubjectTests.test_subject_finishes_when_task_is_cancelled' started at 2023-07-29 03:55:45.682
Test Case 'AsyncCurrentValueSubjectTests.test_subject_finishes_when_task_is_cancelled' passed (0.0 seconds)
Test Case 'AsyncCurrentValueSubjectTests.test_subject_handles_concurrency' started at 2023-07-29 03:55:45.683
error: Exited with signal code 4

@lhoward

lhoward commented Jul 29, 2023

Copy link
Copy Markdown
Author

On my list to fix!

@lhoward

lhoward commented Jul 30, 2023

Copy link
Copy Markdown
Author

I get a bit further:

However now it fails here:

Test Suite 'AsyncWithLatestFrom2SequenceTests' started at 2023-07-31 02:19:32.686
Test Case 'AsyncWithLatestFrom2SequenceTests.test_withLatestFrom_finishes_loop_when_task_is_cancelled' started at 2023-07-31 02:19:32.686
/home/lukeh/CVSRoot/padl/AsyncExtensions-1/Tests/Combiners/WithLatestFrom/AsyncWithLatestFrom2SequenceTests.swift:212: error: AsyncWithLatestFrom2SequenceTests.test_withLatestFrom_finishes_loop_when_task_is_cancelled : Asynchronous wait failed - Exceeded timeout of 5.0 seconds, with unfulfilled expectations: The iteration has produced 1 element

If I don't apply the patches, then it fails unwrapping firstElement in AsyncWithLatestFrom2SequenceTests.swift:

    let task = Task(priority: .high) {
      var iterator = sequence.makeAsyncIterator()

      var firstIteration = false
      var firstElement: (Int, String, String)?
      while let element = await iterator.next() {
        if !firstIteration {
          firstElement = element
          firstIteration = true
          iterated.fulfill()
        }
      }
      XCTAssertEqual(Tuple3(firstElement!), Tuple3((1, "a", "x")))

      finished.fulfill()
    }

@woko666

woko666 commented Jul 4, 2024

Copy link
Copy Markdown

@lhoward Great work on linux support, I've tried your latest commits and it's working quite well for me. Are there still any issues you know of? If so, would you appreciate some assistance?

@lhoward

lhoward commented Jul 4, 2024

Copy link
Copy Markdown
Author

I’m still using the branch, haven’t made any progress with test that fails unfortunately but it’s working fine in my application.

@0xfeedface1993

Copy link
Copy Markdown

During my latest tests, I discovered that the closures inside Task and TaskGroup were not executed when created, which resulted in downstream operations like zip not receiving any events from upstream. This issue only occurs on Linux. I suspect there might be a bug in Swift's Concurrency framework, and I am still looking for a workaround.

lhoward and others added 6 commits February 11, 2026 14:43
…heck

The comma-separated 'if case' acted as logical AND, making it impossible
for regulatedElement to match both .termination and .element(.failure)
simultaneously. Use a switch with OR logic instead so the task is
properly cancelled on either termination or failure.

Amp-Thread-ID: https://ampcode.com/threads/T-019d1415-dee4-710f-8b2b-1f45fa5c9e69
Co-authored-by: Amp <amp@ampcode.com>
Unify into a single critical region so that checking terminalState and
registering the channel happen atomically. Previously a send(.finished)
between the two separate lock acquisitions could cause the new channel
to miss termination and hang forever.

Amp-Thread-ID: https://ampcode.com/threads/T-019d1415-dee4-710f-8b2b-1f45fa5c9e69
Co-authored-by: Amp <amp@ampcode.com>
Unify into a single critical region so that checking terminalState and
registering the channel happen atomically, matching the pattern used in
AsyncCurrentValueSubject.

Amp-Thread-ID: https://ampcode.com/threads/T-019d1415-dee4-710f-8b2b-1f45fa5c9e69
Co-authored-by: Amp <amp@ampcode.com>
Unify into a single critical region so that checking terminalState and
registering the channel happen atomically, matching the pattern used in
AsyncCurrentValueSubject.

Amp-Thread-ID: https://ampcode.com/threads/T-019d1415-dee4-710f-8b2b-1f45fa5c9e69
Co-authored-by: Amp <amp@ampcode.com>
Adds a parallel CMake build alongside Package.swift that produces
libAsyncExtensions.so + an installable swiftmodule, plus a find_package
config (AsyncExtensionsConfig.cmake) so downstream Swift-on-Linux
projects can consume AsyncExtensions as a shared library and avoid
duplicate-module / type-identity issues that arise when multiple
consumers in the same process pull in independent static copies.

Ships FindSwiftCollections.cmake and FindSwiftAtomics.cmake shims
because the upstream packages install built artifacts but no
install-tree-usable Config.cmake.

Note: swift-atomics' upstream CMake doesn't install the _AtomicsShims
headers/module.modulemap; the prefix must have those staged manually
(or upstream fixed) for the FindSwiftAtomics shim to resolve.

Co-Authored-By: Claude Opus 4.7 (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