From d73f703b97ef0672e62854b3a90b9757775cc0d3 Mon Sep 17 00:00:00 2001 From: Julian P Samaroo Date: Mon, 18 May 2026 11:12:27 -0700 Subject: [PATCH 1/2] Vendor ConcurrentStack, remove ConcurrentCollections dep --- Project.toml | 2 -- src/MemPool.jl | 2 +- src/stack.jl | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 51 insertions(+), 3 deletions(-) create mode 100644 src/stack.jl diff --git a/Project.toml b/Project.toml index 8a8583d..890b17c 100644 --- a/Project.toml +++ b/Project.toml @@ -5,7 +5,6 @@ desc = "a simple distributed data store" version = "0.4.14" [deps] -ConcurrentCollections = "5060bff5-0b44-40c5-b522-fcd3ca5cecdd" Distributed = "8ba89e20-285c-5b6f-9357-94700520ee1b" DistributedNext = "fab6aee4-877b-4bac-a744-3eca44acbb6f" Mmap = "a63ad114-7e13-5084-954f-fe012c677804" @@ -16,7 +15,6 @@ Serialization = "9e88b42a-f829-5b0c-bbe9-9e923198166b" Sockets = "6462fe0b-24de-5631-8697-dd941f90decc" [compat] -ConcurrentCollections = "0.1" DistributedNext = "1" Preferences = "1" ScopedValues = "1" diff --git a/src/MemPool.jl b/src/MemPool.jl index 7edd3c8..12dc75b 100644 --- a/src/MemPool.jl +++ b/src/MemPool.jl @@ -6,7 +6,6 @@ import Serialization: serialize, deserialize export DRef, FileRef, poolset, poolget, mmwrite, mmread, cleanup import .Threads: ReentrantLock using ScopedValues -using ConcurrentCollections ## Wrapping-unwrapping of payloads: @@ -70,6 +69,7 @@ end include("io.jl") include("lock.jl") include("read_write_lock.jl") +include("stack.jl") include("clock.jl") include("datastore.jl") diff --git a/src/stack.jl b/src/stack.jl new file mode 100644 index 0000000..b1d5c52 --- /dev/null +++ b/src/stack.jl @@ -0,0 +1,50 @@ +# Adapted from ConcurrentCollections.jl/src/stack.jl + +mutable struct TSNode{T} + value::T + @atomic next::Union{TSNode{T},Nothing} +end + +TSNode{T}(value::T) where {T} = TSNode{T}(value, nothing) + +mutable struct ConcurrentStack{T} + @atomic next::Union{TSNode{T},Nothing} +end + +ConcurrentStack{T}() where {T} = ConcurrentStack{T}(nothing) + +function Base.push!(stack::ConcurrentStack{T}, v) where {T} + v = convert(T, v) + node = TSNode{T}(v) + + next = @atomic stack.next + while true + @atomic node.next = next + next, ok = @atomicreplace(stack.next, next => node) + ok && break + end + + return stack +end + +function maybepop!(stack::ConcurrentStack) + while true + node = @atomic stack.next + node === nothing && return nothing + + next = @atomic node.next + next, ok = @atomicreplace(stack.next, node => next) + if ok + return Some(node.value) + end + end +end + +function Base.pop!(stack::ConcurrentStack) + r = maybepop!(stack) + if r === nothing + error("stack is empty") + else + return something(r) + end +end From eb14220b280faacc3eee93028e2311c81aac44f4 Mon Sep 17 00:00:00 2001 From: Julian P Samaroo Date: Mon, 18 May 2026 11:17:40 -0700 Subject: [PATCH 2/2] CI: Add 1.12 --- .github/workflows/test.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index bde16d7..f866735 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -16,6 +16,7 @@ jobs: - '1.9' - '1.10' - '1.11' + - '1.12' - 'nightly' fail-fast: false name: Test with Julia ${{ matrix.julia-version }}