From 6107ae8b94b6f3b101d2880835f4715a8e43fad2 Mon Sep 17 00:00:00 2001 From: meh Date: Tue, 8 May 2012 21:26:50 +0200 Subject: [PATCH] Implement proper locking and fix headers --- bin/mbox-daemon | 25 ++++++++++++------------- lib/mbox/mail/headers.rb | 2 ++ lib/mbox/mbox.rb | 8 ++++++++ 3 files changed, 22 insertions(+), 13 deletions(-) diff --git a/bin/mbox-daemon b/bin/mbox-daemon index a1cc312..bcd0a8a 100755 --- a/bin/mbox-daemon +++ b/bin/mbox-daemon @@ -42,32 +42,33 @@ end.parse! end } -class Connection < EventMachine::Protocols::LineAndTextProtocol - @@unread = {} - @@unread_checking = false +$unread = {} +class Connection < EventMachine::Protocols::LineAndTextProtocol attr_accessor :boxes def receive_line (line) whole, target, command, rest = line.match(/^(.*?)\s+(.*?)(?:\s+(.+))?$/).to_a - boxes = target == '*' ? @boxes : @boxes.select { |box| target.include? box.name } + boxes = target == '*' ? $boxes : $boxes.select { |box| target.include? box.name } if command == 'list' command = rest if command == 'unread' send_response boxes.select {|box| - if !@@unread[box] || @@unread[box].last_check < [File.ctime(box.path), File.mtime(box.path)].max - unless @@unread_checking + if !$unread[box] || $unread[box].last_check < [File.ctime(box.path), File.mtime(box.path)].max + unless $unread[:checking] + $unread[:checking] = true + EM.defer { - @@unread[box] = Struct.new(:status, :last_check).new(box.has_unread?, Time.new) - @@unread_checking = false + $unread[box] = Struct.new(:status, :last_check).new(box.has_unread?, Time.new) + $unread[:checking] = false } end end - @@unread[box].status rescue false + $unread[box].status rescue false }.map(&:name) end end @@ -81,13 +82,11 @@ class Connection < EventMachine::Protocols::LineAndTextProtocol end EM.run { - boxes = options[:mail][:boxes].map {|name| + $boxes = options[:mail][:boxes].map {|name| Mbox.open("#{options[:mail][:directory]}/#{name}") } - EM.start_server options[:host], options[:port], Connection do |c| - c.boxes = boxes - end + EM.start_server options[:host], options[:port], Connection EM.add_periodic_timer options[:every] do EM.system 'fetchmail' diff --git a/lib/mbox/mail/headers.rb b/lib/mbox/mail/headers.rb index 1cc5afd..ccfc4b2 100644 --- a/lib/mbox/mail/headers.rb +++ b/lib/mbox/mail/headers.rb @@ -47,6 +47,8 @@ def == (other) to_sym == Name.parse(other).to_sym end + alias eql? == + def hash to_sym.hash end diff --git a/lib/mbox/mbox.rb b/lib/mbox/mbox.rb index 3eb79ed..8d24968 100644 --- a/lib/mbox/mbox.rb +++ b/lib/mbox/mbox.rb @@ -67,9 +67,17 @@ def close def each (opts = {}) @input.seek 0 + if @input.respond_to? :flock + @input.flock File::LOCK_SH + end + while mail = Mail.parse(@input, options.merge(opts)) yield mail end + + if @input.respond_to? :flock + @input.flock File::LOCK_UN + end end def [] (index, opts = {})