summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMatthew Sackman <matthew@lshift.net>2009-11-03 18:23:18 +0000
committerMatthew Sackman <matthew@lshift.net>2009-11-03 18:23:18 +0000
commit50e004b1488080cd9ae8e6c95f69b43bd82fb063 (patch)
tree7d7380f04bc666249b733c5f3fcb43e24866230f /src
parent3d8a846b69581cb4372903b9dd27361077fb8ad5 (diff)
downloadrabbitmq-server-git-50e004b1488080cd9ae8e6c95f69b43bd82fb063.tar.gz
subtle bug in queue_index in that there's a sort of race because scattering the journal out to the segments can cause the publish file handle to be closed, should the segment become full. Fixed.
Diffstat (limited to 'src')
-rw-r--r--src/file_handle_cache.erl2
-rw-r--r--src/rabbit_queue_index.erl12
2 files changed, 10 insertions, 4 deletions
diff --git a/src/file_handle_cache.erl b/src/file_handle_cache.erl
index 38aa482040..ae9133b8da 100644
--- a/src/file_handle_cache.erl
+++ b/src/file_handle_cache.erl
@@ -338,7 +338,7 @@ copy(Src, Dest, Count) ->
get_or_reopen(Ref) ->
case get({Ref, fhc_handle}) of
- undefined -> {error, not_open};
+ undefined -> {error, not_open, Ref};
#handle { hdl = closed, mode = Mode, global_key = GRef,
options = Options } ->
#file { path = Path } = get({GRef, fhc_file}),
diff --git a/src/rabbit_queue_index.erl b/src/rabbit_queue_index.erl
index febf3217bd..f21f9e17ee 100644
--- a/src/rabbit_queue_index.erl
+++ b/src/rabbit_queue_index.erl
@@ -175,7 +175,7 @@ terminate(State = #qistate { seg_num_handles = SegHdls }) ->
true -> State;
false -> State1 = #qistate { dir = Dir } = close_all_handles(State),
store_clean_shutdown(Dir),
- State1
+ State1 #qistate { publish_handle = undefined }
end.
terminate_and_erase(State) ->
@@ -781,9 +781,15 @@ append_acks_to_segment(SegNum, Acks,
append_acks_to_segment(SegNum, AckCount2, Acks,
State #qistate { seg_ack_counts = AckCounts1 }).
-append_acks_to_segment(SegNum, AckCount, _Acks, State = #qistate { dir = Dir })
+append_acks_to_segment(SegNum, AckCount, _Acks,
+ State = #qistate { dir = Dir, publish_handle = PubHdl })
when AckCount == ?SEGMENT_ENTRIES_COUNT ->
- State1 = close_handle(SegNum, State),
+ PubHdl1 = case PubHdl of
+ {SegNum, Hdl, ?SEGMENT_ENTRIES_COUNT} when Hdl /= undefined ->
+ {SegNum + 1, undefined, 0};
+ _ -> PubHdl
+ end,
+ State1 = close_handle(SegNum, State #qistate { publish_handle = PubHdl1 }),
ok = case file:delete(seg_num_to_path(Dir, SegNum)) of
ok -> ok;
{error, enoent} -> ok