aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas White <taw@physics.org>2023-12-14 14:35:29 +0100
committerThomas White <taw@physics.org>2024-02-06 16:59:34 +0100
commit1340c96cc8af6df9a5d587649d5e2334fc94497d (patch)
treedd66d6fe5f5f09b858ac1af6041d2cd77379e1e8
parent371d46c0a9bc0ba1a279cfea561e389c755292ef (diff)
Prevent adding a PeakList to two different images
This is kind-of-OK in C, but will break Julia's memory management.
-rw-r--r--julia/CrystFEL/src/image.jl7
-rw-r--r--julia/CrystFEL/src/peaklist.jl13
2 files changed, 17 insertions, 3 deletions
diff --git a/julia/CrystFEL/src/image.jl b/julia/CrystFEL/src/image.jl
index 868afdc4..4f126c28 100644
--- a/julia/CrystFEL/src/image.jl
+++ b/julia/CrystFEL/src/image.jl
@@ -53,7 +53,7 @@ function Base.getproperty(image::Image, name::Symbol)
if pl == C_NULL
throw(ErrorException("Image doesn't have a peak list"))
else
- PeakList(pl)
+ PeakList(pl, true)
end
end
else
@@ -70,7 +70,12 @@ function Base.setproperty!(image::Image, name::Symbol, val)
idata = unsafe_load(image.internalptr)
if name === :peaklist
if val isa PeakList
+ if val.in_image
+ throw(ArgumentError("PeakList is already in an image. "*
+ "Add a copy (use `deepcopy`) instead."))
+ end
setproperty!(idata, name, val.internalptr)
+ val.in_image = true
unsafe_store!(image.internalptr, idata)
else
throw(ArgumentError("Must be a PeakList"))
diff --git a/julia/CrystFEL/src/peaklist.jl b/julia/CrystFEL/src/peaklist.jl
index f8c9b407..1735de5e 100644
--- a/julia/CrystFEL/src/peaklist.jl
+++ b/julia/CrystFEL/src/peaklist.jl
@@ -14,8 +14,9 @@ end
mutable struct InternalPeakList end
-struct PeakList
+mutable struct PeakList
internalptr::Ptr{InternalPeakList}
+ in_image # if true, this PeakList belongs to an Image struct
end
@@ -24,10 +25,18 @@ function PeakList()
if out == C_NULL
throw(ArgumentError("Failed to create peak list"))
end
- PeakList(out)
+ PeakList(out, false)
end
+function Base.deepcopy(peaklist::PeakList)
+ out = @ccall libcrystfel.image_feature_list_copy(peaklist.internalptr::Ptr{InternalPeakList})::Ptr{InternalPeakList}
+ if out == C_NULL
+ throw(ErrorException("Failed to copy peak list"))
+ end
+ PeakList(out, false)
+end
+
function Base.length(peaklist::PeakList)
@ccall libcrystfel.image_feature_count(peaklist.internalptr::Ptr{InternalPeakList})::Cint
end