unicorn 0.91.0 → 0.92.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (96) hide show
  1. data/{CHANGELOG → .CHANGELOG.old} +0 -0
  2. data/.document +4 -0
  3. data/.gitignore +5 -0
  4. data/.mailmap +26 -0
  5. data/CONTRIBUTORS +1 -1
  6. data/Documentation/.gitignore +5 -0
  7. data/Documentation/GNUmakefile +30 -0
  8. data/Documentation/unicorn.1.txt +158 -0
  9. data/Documentation/unicorn_rails.1.txt +150 -0
  10. data/GIT-VERSION-GEN +40 -0
  11. data/GNUmakefile +102 -14
  12. data/README +3 -2
  13. data/Rakefile +104 -32
  14. data/SIGNALS +2 -4
  15. data/TODO +3 -9
  16. data/bin/unicorn +5 -2
  17. data/bin/unicorn_rails +5 -3
  18. data/ext/unicorn_http/c_util.h +2 -2
  19. data/ext/unicorn_http/common_field_optimization.h +2 -1
  20. data/ext/unicorn_http/ext_help.h +29 -4
  21. data/ext/unicorn_http/extconf.rb +5 -0
  22. data/ext/unicorn_http/unicorn_http.rl +131 -76
  23. data/lib/unicorn.rb +6 -2
  24. data/lib/unicorn/app/exec_cgi.rb +3 -1
  25. data/lib/unicorn/app/inetd.rb +2 -0
  26. data/lib/unicorn/app/old_rails.rb +2 -0
  27. data/lib/unicorn/app/old_rails/static.rb +3 -1
  28. data/lib/unicorn/cgi_wrapper.rb +3 -1
  29. data/lib/unicorn/configurator.rb +2 -0
  30. data/lib/unicorn/const.rb +8 -6
  31. data/lib/unicorn/http_request.rb +6 -5
  32. data/lib/unicorn/http_response.rb +4 -2
  33. data/lib/unicorn/launcher.rb +6 -0
  34. data/lib/unicorn/socket_helper.rb +5 -5
  35. data/lib/unicorn/tee_input.rb +2 -0
  36. data/lib/unicorn/util.rb +2 -0
  37. data/local.mk.sample +4 -2
  38. data/setup.rb +1 -0
  39. data/test/aggregate.rb +2 -0
  40. data/test/exec/test_exec.rb +157 -0
  41. data/test/rails/app-1.2.3/app/controllers/application.rb +2 -0
  42. data/test/rails/app-1.2.3/app/controllers/foo_controller.rb +2 -0
  43. data/test/rails/app-1.2.3/app/helpers/application_helper.rb +2 -0
  44. data/test/rails/app-1.2.3/config/boot.rb +2 -0
  45. data/test/rails/app-1.2.3/config/environment.rb +2 -0
  46. data/test/rails/app-1.2.3/config/environments/development.rb +2 -0
  47. data/test/rails/app-1.2.3/config/environments/production.rb +2 -0
  48. data/test/rails/app-1.2.3/config/routes.rb +2 -0
  49. data/test/rails/app-2.0.2/app/controllers/application.rb +2 -0
  50. data/test/rails/app-2.0.2/app/controllers/foo_controller.rb +2 -0
  51. data/test/rails/app-2.0.2/app/helpers/application_helper.rb +2 -0
  52. data/test/rails/app-2.0.2/config/boot.rb +2 -0
  53. data/test/rails/app-2.0.2/config/environment.rb +2 -0
  54. data/test/rails/app-2.0.2/config/environments/development.rb +2 -0
  55. data/test/rails/app-2.0.2/config/environments/production.rb +2 -0
  56. data/test/rails/app-2.0.2/config/routes.rb +2 -0
  57. data/test/rails/app-2.1.2/app/controllers/application.rb +2 -0
  58. data/test/rails/app-2.1.2/app/controllers/foo_controller.rb +2 -0
  59. data/test/rails/app-2.1.2/app/helpers/application_helper.rb +2 -0
  60. data/test/rails/app-2.1.2/config/boot.rb +2 -0
  61. data/test/rails/app-2.1.2/config/environment.rb +2 -0
  62. data/test/rails/app-2.1.2/config/environments/development.rb +2 -0
  63. data/test/rails/app-2.1.2/config/environments/production.rb +2 -0
  64. data/test/rails/app-2.1.2/config/routes.rb +2 -0
  65. data/test/rails/app-2.2.2/app/controllers/application.rb +2 -0
  66. data/test/rails/app-2.2.2/app/controllers/foo_controller.rb +2 -0
  67. data/test/rails/app-2.2.2/app/helpers/application_helper.rb +2 -0
  68. data/test/rails/app-2.2.2/config/boot.rb +2 -0
  69. data/test/rails/app-2.2.2/config/environment.rb +2 -0
  70. data/test/rails/app-2.2.2/config/environments/development.rb +2 -0
  71. data/test/rails/app-2.2.2/config/environments/production.rb +2 -0
  72. data/test/rails/app-2.2.2/config/routes.rb +2 -0
  73. data/test/rails/app-2.3.3.1/app/controllers/application_controller.rb +2 -0
  74. data/test/rails/app-2.3.3.1/app/controllers/foo_controller.rb +2 -0
  75. data/test/rails/app-2.3.3.1/app/helpers/application_helper.rb +2 -0
  76. data/test/rails/app-2.3.3.1/config/boot.rb +2 -0
  77. data/test/rails/app-2.3.3.1/config/environment.rb +2 -0
  78. data/test/rails/app-2.3.3.1/config/environments/development.rb +2 -0
  79. data/test/rails/app-2.3.3.1/config/environments/production.rb +2 -0
  80. data/test/rails/app-2.3.3.1/config/routes.rb +2 -0
  81. data/test/rails/test_rails.rb +2 -0
  82. data/test/test_helper.rb +8 -0
  83. data/test/unit/test_configurator.rb +2 -0
  84. data/test/unit/test_http_parser.rb +13 -0
  85. data/test/unit/test_http_parser_ng.rb +2 -0
  86. data/test/unit/test_request.rb +2 -0
  87. data/test/unit/test_response.rb +2 -0
  88. data/test/unit/test_server.rb +2 -0
  89. data/test/unit/test_signals.rb +2 -0
  90. data/test/unit/test_socket_helper.rb +2 -0
  91. data/test/unit/test_tee_input.rb +2 -1
  92. data/test/unit/test_upload.rb +2 -0
  93. data/test/unit/test_util.rb +2 -0
  94. data/unicorn.gemspec +38 -28
  95. metadata +38 -42
  96. data/Manifest +0 -137
@@ -1,3 +1,5 @@
1
+ # -*- encoding: binary -*-
2
+
1
3
  require 'unicorn'
2
4
 
3
5
  module Unicorn::App
@@ -24,7 +26,7 @@ module Unicorn::App
24
26
  SERVER_PORT
25
27
  SERVER_PROTOCOL
26
28
  SERVER_SOFTWARE
27
- ).map { |x| x.freeze }.freeze # frozen strings are faster for Hash lookups
29
+ ).map { |x| x.freeze } # frozen strings are faster for Hash assignments
28
30
 
29
31
  # Intializes the app, example of usage in a config.ru
30
32
  # map "/cgit" do
@@ -1,3 +1,5 @@
1
+ # -*- encoding: binary -*-
2
+
1
3
  # Copyright (c) 2009 Eric Wong
2
4
  # You can redistribute it and/or modify it under the same terms as Ruby.
3
5
 
@@ -1,3 +1,5 @@
1
+ # -*- encoding: binary -*-
2
+
1
3
  # This code is based on the original Rails handler in Mongrel
2
4
  # Copyright (c) 2005 Zed A. Shaw
3
5
  # Copyright (c) 2009 Eric Wong
@@ -1,3 +1,5 @@
1
+ # -*- encoding: binary -*-
2
+
1
3
  # This code is based on the original Rails handler in Mongrel
2
4
  # Copyright (c) 2005 Zed A. Shaw
3
5
  # Copyright (c) 2009 Eric Wong
@@ -18,7 +20,7 @@
18
20
  # with Unicorn and you should see a decent speed boost (but not as
19
21
  # fast as if you use a static server like nginx).
20
22
  class Unicorn::App::OldRails::Static < Struct.new(:app, :root, :file_server)
21
- FILE_METHODS = { 'GET' => true, 'HEAD' => true }.freeze
23
+ FILE_METHODS = { 'GET' => true, 'HEAD' => true }
22
24
  REQUEST_METHOD = 'REQUEST_METHOD'.freeze
23
25
  REQUEST_URI = 'REQUEST_URI'.freeze
24
26
  PATH_INFO = 'PATH_INFO'.freeze
@@ -1,3 +1,5 @@
1
+ # -*- encoding: binary -*-
2
+
1
3
  # This code is based on the original CGIWrapper from Mongrel
2
4
  # Copyright (c) 2005 Zed A. Shaw
3
5
  # Copyright (c) 2009 Eric Wong
@@ -44,7 +46,7 @@ class Unicorn::CGIWrapper < ::CGI
44
46
  'language' => 'Content-Language'.freeze,
45
47
  'expires' => 'Expires'.freeze,
46
48
  'length' => CONTENT_LENGTH,
47
- }.freeze
49
+ }
48
50
 
49
51
  # Takes an a Rackable environment, plus any additional CGI.new
50
52
  # arguments These are used internally to create a wrapper around the
@@ -1,3 +1,5 @@
1
+ # -*- encoding: binary -*-
2
+
1
3
  require 'socket'
2
4
  require 'logger'
3
5
 
@@ -1,3 +1,5 @@
1
+ # -*- encoding: binary -*-
2
+
1
3
  module Unicorn
2
4
 
3
5
  # Frequently used constants when constructing requests or responses. Many times
@@ -5,11 +7,11 @@ module Unicorn
5
7
  # gave about a 3% to 10% performance improvement over using the strings directly.
6
8
  # Symbols did not really improve things much compared to constants.
7
9
  module Const
8
- UNICORN_VERSION="0.91.0".freeze
10
+ UNICORN_VERSION="0.92.0"
9
11
 
10
- DEFAULT_HOST = "0.0.0.0".freeze # default TCP listen host address
11
- DEFAULT_PORT = "8080".freeze # default TCP listen port
12
- DEFAULT_LISTEN = "#{DEFAULT_HOST}:#{DEFAULT_PORT}".freeze
12
+ DEFAULT_HOST = "0.0.0.0" # default TCP listen host address
13
+ DEFAULT_PORT = "8080" # default TCP listen port
14
+ DEFAULT_LISTEN = "#{DEFAULT_HOST}:#{DEFAULT_PORT}"
13
15
 
14
16
  # The basic max request size we'll try to read.
15
17
  CHUNK_SIZE=(16 * 1024)
@@ -22,8 +24,8 @@ module Unicorn
22
24
  MAX_BODY=MAX_HEADER
23
25
 
24
26
  # common errors we'll send back
25
- ERROR_400_RESPONSE = "HTTP/1.1 400 Bad Request\r\n\r\n".freeze
26
- ERROR_500_RESPONSE = "HTTP/1.1 500 Internal Server Error\r\n\r\n".freeze
27
+ ERROR_400_RESPONSE = "HTTP/1.1 400 Bad Request\r\n\r\n"
28
+ ERROR_500_RESPONSE = "HTTP/1.1 500 Internal Server Error\r\n\r\n"
27
29
  EXPECT_100_RESPONSE = "HTTP/1.1 100 Continue\r\n\r\n"
28
30
 
29
31
  # A frozen format for this is about 15% faster
@@ -1,4 +1,5 @@
1
- # coding:binary
1
+ # -*- encoding: binary -*-
2
+
2
3
  require 'stringio'
3
4
  require 'unicorn_http'
4
5
 
@@ -11,15 +12,15 @@ module Unicorn
11
12
  "rack.multiprocess" => true,
12
13
  "rack.multithread" => false,
13
14
  "rack.run_once" => false,
14
- "rack.version" => [1, 0].freeze,
15
- "SCRIPT_NAME" => "".freeze,
15
+ "rack.version" => [1, 0],
16
+ "SCRIPT_NAME" => "",
16
17
 
17
18
  # this is not in the Rack spec, but some apps may rely on it
18
- "SERVER_SOFTWARE" => "Unicorn #{Const::UNICORN_VERSION}".freeze
19
+ "SERVER_SOFTWARE" => "Unicorn #{Const::UNICORN_VERSION}"
19
20
  }
20
21
 
21
22
  NULL_IO = StringIO.new(Z)
22
- LOCALHOST = '127.0.0.1'.freeze
23
+ LOCALHOST = '127.0.0.1'
23
24
 
24
25
  # Being explicitly single-threaded, we have certain advantages in
25
26
  # not having to worry about variables being clobbered :)
@@ -1,3 +1,5 @@
1
+ # -*- encoding: binary -*-
2
+
1
3
  require 'time'
2
4
 
3
5
  module Unicorn
@@ -30,7 +32,7 @@ module Unicorn
30
32
  # Rack does not set/require a Date: header. We always override the
31
33
  # Connection: and Date: headers no matter what (if anything) our
32
34
  # Rack application sent us.
33
- SKIP = { 'connection' => true, 'date' => true, 'status' => true }.freeze
35
+ SKIP = { 'connection' => true, 'date' => true, 'status' => true }
34
36
  OUT = [] # :nodoc
35
37
 
36
38
  def self.write_header(socket, status, headers)
@@ -67,7 +69,7 @@ module Unicorn
67
69
  body.each { |chunk| socket.write(chunk) }
68
70
  socket.close # flushes and uncorks the socket immediately
69
71
  ensure
70
- body.respond_to?(:close) and body.close rescue nil
72
+ body.respond_to?(:close) and body.close
71
73
  end
72
74
 
73
75
  end
@@ -1,4 +1,10 @@
1
+ # -*- encoding: binary -*-
2
+
1
3
  $stdin.sync = $stdout.sync = $stderr.sync = true
4
+ $stdin.binmode
5
+ $stdout.binmode
6
+ $stderr.binmode
7
+
2
8
  require 'unicorn'
3
9
 
4
10
  class Unicorn::Launcher
@@ -1,3 +1,5 @@
1
+ # -*- encoding: binary -*-
2
+
1
3
  require 'socket'
2
4
 
3
5
  module Unicorn
@@ -18,10 +20,8 @@ module Unicorn
18
20
  # Use the HTTP accept filter if available.
19
21
  # The struct made by pack() is defined in /usr/include/sys/socket.h
20
22
  # as accept_filter_arg
21
- # We won't be seupportin the "dataready" filter unlike nginx
22
- # since we only support HTTP and no other protocols
23
23
  unless `/sbin/sysctl -nq net.inet.accf.http`.empty?
24
- HTTPREADY = ['httpready', nil].pack('a16a240').freeze
24
+ FILTER_ARG = ['httpready', nil].pack('a16a240')
25
25
  end
26
26
  end
27
27
 
@@ -44,8 +44,8 @@ module Unicorn
44
44
  # No good reason to ever have deferred accepts off
45
45
  if defined?(TCP_DEFER_ACCEPT)
46
46
  sock.setsockopt(SOL_TCP, TCP_DEFER_ACCEPT, 1) rescue nil
47
- elsif defined?(SO_ACCEPTFILTER) && defined?(HTTPREADY)
48
- sock.setsockopt(SOL_SOCKET, SO_ACCEPTFILTER, HTTPREADY) rescue nil
47
+ elsif defined?(SO_ACCEPTFILTER) && defined?(FILTER_ARG)
48
+ sock.setsockopt(SOL_SOCKET, SO_ACCEPTFILTER, FILTER_ARG) rescue nil
49
49
  end
50
50
  end
51
51
 
@@ -1,3 +1,5 @@
1
+ # -*- encoding: binary -*-
2
+
1
3
  module Unicorn
2
4
 
3
5
  # acts like tee(1) on an input input to provide a input-like stream
@@ -1,3 +1,5 @@
1
+ # -*- encoding: binary -*-
2
+
1
3
  require 'fcntl'
2
4
  require 'tmpdir'
3
5
 
@@ -31,6 +31,7 @@ test-19:
31
31
  publish_doc:
32
32
  -git set-file-times
33
33
  $(MAKE) doc
34
+ awk 'BEGIN{RS="=== ";ORS=""}NR==2{ print RS""$$0 }' NEWS > doc/LATEST
34
35
  $(MAKE) doc_gz
35
36
  rsync -av --delete doc/ dcvr:/srv/unicorn/
36
37
  git ls-files | xargs touch
@@ -38,7 +39,8 @@ publish_doc:
38
39
  # Create gzip variants of the same timestamp as the original so nginx
39
40
  # "gzip_static on" can serve the gzipped versions directly.
40
41
  doc_gz: suf := html js css
41
- doc_gz: docs = $(shell find doc/ -regex '^.*\.\(html\|js\|css\)$$') doc/COPYING
42
+ doc_gz: docs = $(shell find doc -type f ! -regex '^.*\.\(gif\|jpg\|png\|gz\)$$')
42
43
  doc_gz:
44
+ touch doc/NEWS.atom.xml -d "$$(awk 'NR==1{print $$4,$$5,$$6}' NEWS)"
43
45
  for i in $(docs); do \
44
- gzip --rsyncable < $$i > $$i.gz; touch -r $$i $$i.gz; done
46
+ gzip --rsyncable -9 < $$i > $$i.gz; touch -r $$i $$i.gz; done
data/setup.rb CHANGED
@@ -1,3 +1,4 @@
1
+ # -*- encoding: binary -*-
1
2
  #
2
3
  # setup.rb
3
4
  #
@@ -1,4 +1,6 @@
1
1
  #!/usr/bin/ruby -n
2
+ # -*- encoding: binary -*-
3
+
2
4
  BEGIN { $tests = $assertions = $failures = $errors = 0 }
3
5
 
4
6
  $_ =~ /(\d+) tests, (\d+) assertions, (\d+) failures, (\d+) errors/ or next
@@ -1,4 +1,7 @@
1
+ # -*- encoding: binary -*-
2
+
1
3
  # Copyright (c) 2009 Eric Wong
4
+ FLOCK_PATH = File.expand_path(__FILE__)
2
5
  require 'test/test_helper'
3
6
 
4
7
  do_test = true
@@ -695,4 +698,158 @@ end
695
698
  wait_for_death(pid)
696
699
  end
697
700
 
701
+ def hup_test_common(preload)
702
+ File.open("config.ru", "wb") { |fp| fp.syswrite(HI.gsub("HI", '#$$')) }
703
+ pid_file = Tempfile.new('pid')
704
+ ucfg = Tempfile.new('unicorn_test_config')
705
+ ucfg.syswrite("listen '#@addr:#@port'\n")
706
+ ucfg.syswrite("pid '#{pid_file.path}'\n")
707
+ ucfg.syswrite("preload_app true\n") if preload
708
+ ucfg.syswrite("stderr_path 'test_stderr.#$$.log'\n")
709
+ ucfg.syswrite("stdout_path 'test_stdout.#$$.log'\n")
710
+ pid = xfork {
711
+ redirect_test_io { exec($unicorn_bin, "-D", "-c", ucfg.path) }
712
+ }
713
+ _, status = Process.waitpid2(pid)
714
+ assert status.success?
715
+ wait_master_ready("test_stderr.#$$.log")
716
+ wait_workers_ready("test_stderr.#$$.log", 1)
717
+ uri = URI.parse("http://#@addr:#@port/")
718
+ pids = Tempfile.new('worker_pids')
719
+ hitter = fork {
720
+ bodies = Hash.new(0)
721
+ at_exit { pids.syswrite(bodies.inspect) }
722
+ trap(:TERM) { exit(0) }
723
+ loop {
724
+ rv = Net::HTTP.get(uri)
725
+ pid = rv.to_i
726
+ exit!(1) if pid <= 0
727
+ bodies[pid] += 1
728
+ }
729
+ }
730
+ sleep 1 # racy
731
+ daemon_pid = pid_file.read.to_i
732
+ assert daemon_pid > 0
733
+ Process.kill(:HUP, daemon_pid)
734
+ sleep 1 # racy
735
+ assert_nothing_raised { Process.kill(:TERM, hitter) }
736
+ _, hitter_status = Process.waitpid2(hitter)
737
+ assert hitter_status.success?
738
+ pids.sysseek(0)
739
+ pids = eval(pids.read)
740
+ assert_kind_of(Hash, pids)
741
+ assert_equal 2, pids.size
742
+ pids.keys.each { |x|
743
+ assert_kind_of(Integer, x)
744
+ assert x > 0
745
+ assert pids[x] > 0
746
+ }
747
+ assert_nothing_raised { Process.kill(:QUIT, daemon_pid) }
748
+ wait_for_death(daemon_pid)
749
+ end
750
+
751
+ def test_preload_app_hup
752
+ hup_test_common(true)
753
+ end
754
+
755
+ def test_hup
756
+ hup_test_common(false)
757
+ end
758
+
759
+ def test_default_listen_hup_holds_listener
760
+ default_listen_lock do
761
+ res, pid_path = default_listen_setup
762
+ daemon_pid = File.read(pid_path).to_i
763
+ assert_nothing_raised { Process.kill(:HUP, daemon_pid) }
764
+ wait_workers_ready("test_stderr.#$$.log", 1)
765
+ res2 = hit(["http://#{Unicorn::Const::DEFAULT_LISTEN}/"])
766
+ assert_match %r{\d+}, res2.first
767
+ assert res2.first != res.first
768
+ assert_nothing_raised { Process.kill(:QUIT, daemon_pid) }
769
+ wait_for_death(daemon_pid)
770
+ end
771
+ end
772
+
773
+ def test_default_listen_upgrade_holds_listener
774
+ default_listen_lock do
775
+ res, pid_path = default_listen_setup
776
+ daemon_pid = File.read(pid_path).to_i
777
+ assert_nothing_raised {
778
+ Process.kill(:USR2, daemon_pid)
779
+ wait_for_file("#{pid_path}.oldbin")
780
+ wait_for_file(pid_path)
781
+ Process.kill(:QUIT, daemon_pid)
782
+ wait_for_death(daemon_pid)
783
+ }
784
+ daemon_pid = File.read(pid_path).to_i
785
+ wait_workers_ready("test_stderr.#$$.log", 1)
786
+ File.truncate("test_stderr.#$$.log", 0)
787
+
788
+ res2 = hit(["http://#{Unicorn::Const::DEFAULT_LISTEN}/"])
789
+ assert_match %r{\d+}, res2.first
790
+ assert res2.first != res.first
791
+
792
+ assert_nothing_raised { Process.kill(:HUP, daemon_pid) }
793
+ wait_workers_ready("test_stderr.#$$.log", 1)
794
+ File.truncate("test_stderr.#$$.log", 0)
795
+ res3 = hit(["http://#{Unicorn::Const::DEFAULT_LISTEN}/"])
796
+ assert res2.first != res3.first
797
+
798
+ assert_nothing_raised { Process.kill(:QUIT, daemon_pid) }
799
+ wait_for_death(daemon_pid)
800
+ end
801
+ end
802
+
803
+ def default_listen_setup
804
+ File.open("config.ru", "wb") { |fp| fp.syswrite(HI.gsub("HI", '#$$')) }
805
+ pid_path = (tmp = Tempfile.new('pid')).path
806
+ tmp.close!
807
+ ucfg = Tempfile.new('unicorn_test_config')
808
+ ucfg.syswrite("pid '#{pid_path}'\n")
809
+ ucfg.syswrite("stderr_path 'test_stderr.#$$.log'\n")
810
+ ucfg.syswrite("stdout_path 'test_stdout.#$$.log'\n")
811
+ pid = xfork {
812
+ redirect_test_io { exec($unicorn_bin, "-D", "-c", ucfg.path) }
813
+ }
814
+ _, status = Process.waitpid2(pid)
815
+ assert status.success?
816
+ wait_master_ready("test_stderr.#$$.log")
817
+ wait_workers_ready("test_stderr.#$$.log", 1)
818
+ File.truncate("test_stderr.#$$.log", 0)
819
+ res = hit(["http://#{Unicorn::Const::DEFAULT_LISTEN}/"])
820
+ assert_match %r{\d+}, res.first
821
+ [ res, pid_path ]
822
+ end
823
+
824
+ # we need to flock() something to prevent these tests from running
825
+ def default_listen_lock(&block)
826
+ fp = File.open(FLOCK_PATH, "rb")
827
+ begin
828
+ fp.flock(File::LOCK_EX)
829
+ begin
830
+ TCPServer.new(Unicorn::Const::DEFAULT_HOST,
831
+ Unicorn::Const::DEFAULT_PORT).close
832
+ rescue Errno::EADDRINUSE, Errno::EACCES
833
+ warn "can't bind to #{Unicorn::Const::DEFAULT_LISTEN}"
834
+ return false
835
+ end
836
+
837
+ # unused_port should never take this, but we may run an environment
838
+ # where tests are being run against older unicorns...
839
+ lock_path = "#{Dir::tmpdir}/unicorn_test." \
840
+ "#{Unicorn::Const::DEFAULT_LISTEN}.lock"
841
+ begin
842
+ lock = File.open(lock_path, File::WRONLY|File::CREAT|File::EXCL, 0600)
843
+ yield
844
+ rescue Errno::EEXIST
845
+ lock_path = nil
846
+ return false
847
+ ensure
848
+ File.unlink(lock_path) if lock_path
849
+ end
850
+ ensure
851
+ fp.flock(File::LOCK_UN)
852
+ end
853
+ end
854
+
698
855
  end if do_test
@@ -1,3 +1,5 @@
1
+ # -*- encoding: binary -*-
2
+
1
3
  class ApplicationController < ActionController::Base
2
4
  # Pick a unique cookie name to distinguish our session data from others'
3
5
  session :session_key => "_unicorn_rails_test.#{rand}"
@@ -1,3 +1,5 @@
1
+ # -*- encoding: binary -*-
2
+
1
3
  require 'digest/sha1'
2
4
  class FooController < ApplicationController
3
5
  def index
@@ -1,2 +1,4 @@
1
+ # -*- encoding: binary -*-
2
+
1
3
  module ApplicationHelper
2
4
  end
@@ -1,3 +1,5 @@
1
+ # -*- encoding: binary -*-
2
+
1
3
  unless defined?(RAILS_ROOT)
2
4
  root_path = File.join(File.dirname(__FILE__), '..')
3
5
  RAILS_ROOT = root_path
@@ -1,3 +1,5 @@
1
+ # -*- encoding: binary -*-
2
+
1
3
  unless defined? RAILS_GEM_VERSION
2
4
  RAILS_GEM_VERSION = ENV['UNICORN_RAILS_VERSION'] # || '1.2.3'
3
5
  end
@@ -1,3 +1,5 @@
1
+ # -*- encoding: binary -*-
2
+
1
3
  config.cache_classes = false
2
4
  config.whiny_nils = true
3
5
  config.breakpoint_server = true
@@ -1,3 +1,5 @@
1
+ # -*- encoding: binary -*-
2
+
1
3
  config.cache_classes = true
2
4
  config.action_controller.consider_all_requests_local = false
3
5
  config.action_controller.perform_caching = true