about summary refs log tree commit homepage
path: root/lib/unicorn/worker.rb
diff options
context:
space:
mode:
authorEric Wong <normalperson@yhbt.net>2011-06-16 22:54:40 +0000
committerEric Wong <normalperson@yhbt.net>2011-06-16 23:14:14 +0000
commita0c59adf71506b8808de276b1288a319424ee71a (patch)
treee627c424701799b82a5bfea06cb45cf1c2d99efd /lib/unicorn/worker.rb
parent95f543a9583e58c56b1c480df84b4b88e6669403 (diff)
downloadunicorn-a0c59adf71506b8808de276b1288a319424ee71a.tar.gz
This means we no longer waste an extra file descriptor per
worker process in the master.  Now there's no need to set a
higher file descriptor limit for systems running >= 1024
workers.
Diffstat (limited to 'lib/unicorn/worker.rb')
-rw-r--r--lib/unicorn/worker.rb49
1 files changed, 45 insertions, 4 deletions
diff --git a/lib/unicorn/worker.rb b/lib/unicorn/worker.rb
index 39e9e32..cd41e22 100644
--- a/lib/unicorn/worker.rb
+++ b/lib/unicorn/worker.rb
@@ -1,4 +1,5 @@
 # -*- encoding: binary -*-
+require "raindrops"
 
 # This class and its members can be considered a stable interface
 # and will not change in a backwards-incompatible fashion between
@@ -7,13 +8,53 @@
 #
 # Some users may want to access it in the before_fork/after_fork hooks.
 # See the Unicorn::Configurator RDoc for examples.
-class Unicorn::Worker < Struct.new(:nr, :tmp, :switched)
+class Unicorn::Worker
+  # :stopdoc:
+  attr_accessor :nr, :switched
+  attr_writer :tmp
+
+  PER_DROP = Raindrops::PAGE_SIZE / Raindrops::SIZE
+  DROPS = []
+
+  def initialize(nr)
+    drop_index = nr / PER_DROP
+    @raindrop = DROPS[drop_index] ||= Raindrops.new(PER_DROP)
+    @offset = nr % PER_DROP
+    @raindrop[@offset] = 0
+    @nr = nr
+    @tmp = @switched = false
+  end
 
   # worker objects may be compared to just plain Integers
   def ==(other_nr) # :nodoc:
-    nr == other_nr
+    @nr == other_nr
+  end
+
+  # called in the worker process
+  def tick=(value) # :nodoc:
+    @raindrop[@offset] = value
+  end
+
+  # called in the master process
+  def tick # :nodoc:
+    @raindrop[@offset]
   end
 
+  # only exists for compatibility
+  def tmp # :nodoc:
+    @tmp ||= begin
+      tmp = Unicorn::TmpIO.new
+      tmp.fcntl(Fcntl::F_SETFD, Fcntl::FD_CLOEXEC)
+      tmp
+    end
+  end
+
+  def close # :nodoc:
+    @tmp.close if @tmp
+  end
+
+  # :startdoc:
+
   # In most cases, you should be using the Unicorn::Configurator#user
   # directive instead.  This method should only be used if you need
   # fine-grained control of exactly when you want to change permissions
@@ -36,12 +77,12 @@ class Unicorn::Worker < Struct.new(:nr, :tmp, :switched)
     uid = Etc.getpwnam(user).uid
     gid = Etc.getgrnam(group).gid if group
     Unicorn::Util.chown_logs(uid, gid)
-    tmp.chown(uid, gid)
+    @tmp.chown(uid, gid) if @tmp
     if gid && Process.egid != gid
       Process.initgroups(user, gid)
       Process::GID.change_privilege(gid)
     end
     Process.euid != uid and Process::UID.change_privilege(uid)
-    self.switched = true
+    @switched = true
   end
 end