colouringcode-passenger 0.1 → 0.2

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 (170) hide show
  1. data/NEWS +129 -0
  2. data/Rakefile +2 -2
  3. data/bin/passenger-install-apache2-module +1 -0
  4. data/bin/passenger-install-nginx-module +4 -2
  5. data/ext/apache2/Hooks.cpp +4 -2
  6. data/ext/common/ApplicationPoolServer.h +1 -1
  7. data/ext/common/ApplicationPoolServerExecutable.cpp +1 -1
  8. data/ext/common/MessageChannel.h +48 -4
  9. data/ext/common/StandardApplicationPool.h +4 -2
  10. data/ext/common/Version.h +1 -1
  11. data/ext/nginx/Configuration.c +1 -1
  12. data/ext/nginx/HttpStatusExtractor.h +1 -0
  13. data/ext/nginx/ScgiRequestParser.h +1 -0
  14. data/ext/oxt/system_calls.cpp +11 -0
  15. data/ext/oxt/system_calls.hpp +2 -1
  16. data/ext/oxt/thread.hpp +97 -1
  17. data/ext/phusion_passenger/native_support.c +30 -1
  18. data/lib/phusion_passenger/constants.rb +1 -1
  19. data/lib/phusion_passenger/dependencies.rb +32 -0
  20. data/lib/phusion_passenger/message_channel.rb +45 -3
  21. data/lib/phusion_passenger/platform_info.rb +1 -1
  22. data/lib/phusion_passenger/rack/application_spawner.rb +10 -4
  23. data/lib/phusion_passenger/rack/request_handler.rb +2 -5
  24. data/lib/phusion_passenger/railz/application_spawner.rb +59 -7
  25. data/lib/phusion_passenger/utils.rb +70 -16
  26. data/{vendor/rack-1.0.0-git/lib/rack → lib/phusion_passenger/utils}/rewindable_input.rb +34 -9
  27. data/test/ApplicationPoolTest.cpp +1 -1
  28. data/test/MessageChannelTest.cpp +9 -1
  29. data/test/stub/message_channel.rb +1 -1
  30. data/test/stub/message_channel_2.rb +1 -1
  31. data/test/stub/message_channel_3.rb +2 -2
  32. metadata +43 -155
  33. data/doc/Architectural overview.html +0 -1
  34. data/doc/rdoc/classes/ConditionVariable.html +0 -194
  35. data/doc/rdoc/classes/Exception.html +0 -120
  36. data/doc/rdoc/classes/GC.html +0 -113
  37. data/doc/rdoc/classes/IO.html +0 -169
  38. data/doc/rdoc/classes/PhusionPassenger.html +0 -238
  39. data/doc/rdoc/classes/PhusionPassenger/AbstractInstaller.html +0 -153
  40. data/doc/rdoc/classes/PhusionPassenger/AbstractRequestHandler.html +0 -517
  41. data/doc/rdoc/classes/PhusionPassenger/AbstractServer.html +0 -719
  42. data/doc/rdoc/classes/PhusionPassenger/AbstractServer/ServerAlreadyStarted.html +0 -97
  43. data/doc/rdoc/classes/PhusionPassenger/AbstractServer/ServerError.html +0 -96
  44. data/doc/rdoc/classes/PhusionPassenger/AbstractServer/ServerNotStarted.html +0 -97
  45. data/doc/rdoc/classes/PhusionPassenger/AbstractServer/UnknownMessage.html +0 -96
  46. data/doc/rdoc/classes/PhusionPassenger/AbstractServerCollection.html +0 -598
  47. data/doc/rdoc/classes/PhusionPassenger/AdminTools.html +0 -140
  48. data/doc/rdoc/classes/PhusionPassenger/AdminTools/ControlProcess.html +0 -317
  49. data/doc/rdoc/classes/PhusionPassenger/AdminTools/ControlProcess/Instance.html +0 -138
  50. data/doc/rdoc/classes/PhusionPassenger/AppInitError.html +0 -154
  51. data/doc/rdoc/classes/PhusionPassenger/Application.html +0 -283
  52. data/doc/rdoc/classes/PhusionPassenger/ConsoleTextTemplate.html +0 -172
  53. data/doc/rdoc/classes/PhusionPassenger/FrameworkInitError.html +0 -145
  54. data/doc/rdoc/classes/PhusionPassenger/HTMLTemplate.html +0 -181
  55. data/doc/rdoc/classes/PhusionPassenger/InitializationError.html +0 -141
  56. data/doc/rdoc/classes/PhusionPassenger/InvalidPath.html +0 -92
  57. data/doc/rdoc/classes/PhusionPassenger/MessageChannel.html +0 -489
  58. data/doc/rdoc/classes/PhusionPassenger/NativeSupport.html +0 -350
  59. data/doc/rdoc/classes/PhusionPassenger/Rack.html +0 -91
  60. data/doc/rdoc/classes/PhusionPassenger/Rack/ApplicationSpawner.html +0 -188
  61. data/doc/rdoc/classes/PhusionPassenger/Rack/RequestHandler.html +0 -199
  62. data/doc/rdoc/classes/PhusionPassenger/Railz.html +0 -95
  63. data/doc/rdoc/classes/PhusionPassenger/Railz/ApplicationSpawner.html +0 -438
  64. data/doc/rdoc/classes/PhusionPassenger/Railz/ApplicationSpawner/Error.html +0 -98
  65. data/doc/rdoc/classes/PhusionPassenger/Railz/CGIFixed.html +0 -200
  66. data/doc/rdoc/classes/PhusionPassenger/Railz/FrameworkSpawner.html +0 -436
  67. data/doc/rdoc/classes/PhusionPassenger/Railz/FrameworkSpawner/Error.html +0 -98
  68. data/doc/rdoc/classes/PhusionPassenger/Railz/RequestHandler.html +0 -155
  69. data/doc/rdoc/classes/PhusionPassenger/SpawnManager.html +0 -402
  70. data/doc/rdoc/classes/PhusionPassenger/UnknownError.html +0 -125
  71. data/doc/rdoc/classes/PhusionPassenger/Utils.html +0 -803
  72. data/doc/rdoc/classes/PhusionPassenger/Utils/PseudoIO.html +0 -169
  73. data/doc/rdoc/classes/PhusionPassenger/VersionNotFound.html +0 -140
  74. data/doc/rdoc/classes/PhusionPassenger/WSGI.html +0 -89
  75. data/doc/rdoc/classes/PhusionPassenger/WSGI/ApplicationSpawner.html +0 -188
  76. data/doc/rdoc/classes/PlatformInfo.html +0 -866
  77. data/doc/rdoc/classes/RakeExtensions.html +0 -197
  78. data/doc/rdoc/classes/Signal.html +0 -131
  79. data/doc/rdoc/created.rid +0 -1
  80. data/doc/rdoc/files/DEVELOPERS_TXT.html +0 -255
  81. data/doc/rdoc/files/README.html +0 -175
  82. data/doc/rdoc/files/ext/phusion_passenger/native_support_c.html +0 -92
  83. data/doc/rdoc/files/lib/phusion_passenger/abstract_installer_rb.html +0 -129
  84. data/doc/rdoc/files/lib/phusion_passenger/abstract_request_handler_rb.html +0 -129
  85. data/doc/rdoc/files/lib/phusion_passenger/abstract_server_collection_rb.html +0 -126
  86. data/doc/rdoc/files/lib/phusion_passenger/abstract_server_rb.html +0 -128
  87. data/doc/rdoc/files/lib/phusion_passenger/admin_tools/control_process_rb.html +0 -130
  88. data/doc/rdoc/files/lib/phusion_passenger/admin_tools_rb.html +0 -122
  89. data/doc/rdoc/files/lib/phusion_passenger/application_rb.html +0 -127
  90. data/doc/rdoc/files/lib/phusion_passenger/console_text_template_rb.html +0 -126
  91. data/doc/rdoc/files/lib/phusion_passenger/constants_rb.html +0 -122
  92. data/doc/rdoc/files/lib/phusion_passenger/dependencies_rb.html +0 -134
  93. data/doc/rdoc/files/lib/phusion_passenger/events_rb.html +0 -122
  94. data/doc/rdoc/files/lib/phusion_passenger/exceptions_rb.html +0 -122
  95. data/doc/rdoc/files/lib/phusion_passenger/html_template_rb.html +0 -126
  96. data/doc/rdoc/files/lib/phusion_passenger/message_channel_rb.html +0 -120
  97. data/doc/rdoc/files/lib/phusion_passenger/packaging_rb.html +0 -122
  98. data/doc/rdoc/files/lib/phusion_passenger/platform_info_rb.html +0 -127
  99. data/doc/rdoc/files/lib/phusion_passenger/rack/application_spawner_rb.html +0 -133
  100. data/doc/rdoc/files/lib/phusion_passenger/rack/request_handler_rb.html +0 -125
  101. data/doc/rdoc/files/lib/phusion_passenger/railz/application_spawner_rb.html +0 -140
  102. data/doc/rdoc/files/lib/phusion_passenger/railz/cgi_fixed_rb.html +0 -126
  103. data/doc/rdoc/files/lib/phusion_passenger/railz/framework_spawner_rb.html +0 -145
  104. data/doc/rdoc/files/lib/phusion_passenger/railz/request_handler_rb.html +0 -125
  105. data/doc/rdoc/files/lib/phusion_passenger/simple_benchmarking_rb.html +0 -122
  106. data/doc/rdoc/files/lib/phusion_passenger/spawn_manager_rb.html +0 -159
  107. data/doc/rdoc/files/lib/phusion_passenger/utils_rb.html +0 -174
  108. data/doc/rdoc/files/lib/phusion_passenger/wsgi/application_spawner_rb.html +0 -129
  109. data/doc/rdoc/files/misc/rake/extensions_rb.html +0 -130
  110. data/doc/rdoc/fr_class_index.html +0 -91
  111. data/doc/rdoc/fr_file_index.html +0 -76
  112. data/doc/rdoc/fr_method_index.html +0 -205
  113. data/doc/rdoc/index.html +0 -26
  114. data/doc/rdoc/rdoc-style.css +0 -187
  115. data/vendor/README +0 -13
  116. data/vendor/README_FOR_PACKAGERS +0 -1
  117. data/vendor/rack-1.0.0-git/COPYING +0 -18
  118. data/vendor/rack-1.0.0-git/KNOWN-ISSUES +0 -18
  119. data/vendor/rack-1.0.0-git/README +0 -353
  120. data/vendor/rack-1.0.0-git/Rakefile +0 -164
  121. data/vendor/rack-1.0.0-git/lib/rack.rb +0 -90
  122. data/vendor/rack-1.0.0-git/lib/rack/adapter/camping.rb +0 -22
  123. data/vendor/rack-1.0.0-git/lib/rack/auth/abstract/handler.rb +0 -37
  124. data/vendor/rack-1.0.0-git/lib/rack/auth/abstract/request.rb +0 -37
  125. data/vendor/rack-1.0.0-git/lib/rack/auth/basic.rb +0 -58
  126. data/vendor/rack-1.0.0-git/lib/rack/auth/digest/md5.rb +0 -124
  127. data/vendor/rack-1.0.0-git/lib/rack/auth/digest/nonce.rb +0 -51
  128. data/vendor/rack-1.0.0-git/lib/rack/auth/digest/params.rb +0 -55
  129. data/vendor/rack-1.0.0-git/lib/rack/auth/digest/request.rb +0 -40
  130. data/vendor/rack-1.0.0-git/lib/rack/auth/openid.rb +0 -487
  131. data/vendor/rack-1.0.0-git/lib/rack/builder.rb +0 -63
  132. data/vendor/rack-1.0.0-git/lib/rack/cascade.rb +0 -41
  133. data/vendor/rack-1.0.0-git/lib/rack/chunked.rb +0 -49
  134. data/vendor/rack-1.0.0-git/lib/rack/commonlogger.rb +0 -52
  135. data/vendor/rack-1.0.0-git/lib/rack/conditionalget.rb +0 -47
  136. data/vendor/rack-1.0.0-git/lib/rack/content_length.rb +0 -29
  137. data/vendor/rack-1.0.0-git/lib/rack/content_type.rb +0 -23
  138. data/vendor/rack-1.0.0-git/lib/rack/deflater.rb +0 -96
  139. data/vendor/rack-1.0.0-git/lib/rack/directory.rb +0 -153
  140. data/vendor/rack-1.0.0-git/lib/rack/file.rb +0 -88
  141. data/vendor/rack-1.0.0-git/lib/rack/handler.rb +0 -69
  142. data/vendor/rack-1.0.0-git/lib/rack/handler/cgi.rb +0 -61
  143. data/vendor/rack-1.0.0-git/lib/rack/handler/evented_mongrel.rb +0 -8
  144. data/vendor/rack-1.0.0-git/lib/rack/handler/fastcgi.rb +0 -88
  145. data/vendor/rack-1.0.0-git/lib/rack/handler/lsws.rb +0 -55
  146. data/vendor/rack-1.0.0-git/lib/rack/handler/mongrel.rb +0 -84
  147. data/vendor/rack-1.0.0-git/lib/rack/handler/scgi.rb +0 -59
  148. data/vendor/rack-1.0.0-git/lib/rack/handler/swiftiplied_mongrel.rb +0 -8
  149. data/vendor/rack-1.0.0-git/lib/rack/handler/thin.rb +0 -18
  150. data/vendor/rack-1.0.0-git/lib/rack/handler/webrick.rb +0 -67
  151. data/vendor/rack-1.0.0-git/lib/rack/head.rb +0 -19
  152. data/vendor/rack-1.0.0-git/lib/rack/lint.rb +0 -537
  153. data/vendor/rack-1.0.0-git/lib/rack/lobster.rb +0 -65
  154. data/vendor/rack-1.0.0-git/lib/rack/lock.rb +0 -16
  155. data/vendor/rack-1.0.0-git/lib/rack/methodoverride.rb +0 -27
  156. data/vendor/rack-1.0.0-git/lib/rack/mime.rb +0 -204
  157. data/vendor/rack-1.0.0-git/lib/rack/mock.rb +0 -184
  158. data/vendor/rack-1.0.0-git/lib/rack/recursive.rb +0 -57
  159. data/vendor/rack-1.0.0-git/lib/rack/reloader.rb +0 -106
  160. data/vendor/rack-1.0.0-git/lib/rack/request.rb +0 -248
  161. data/vendor/rack-1.0.0-git/lib/rack/response.rb +0 -183
  162. data/vendor/rack-1.0.0-git/lib/rack/session/abstract/id.rb +0 -142
  163. data/vendor/rack-1.0.0-git/lib/rack/session/cookie.rb +0 -91
  164. data/vendor/rack-1.0.0-git/lib/rack/session/memcache.rb +0 -109
  165. data/vendor/rack-1.0.0-git/lib/rack/session/pool.rb +0 -100
  166. data/vendor/rack-1.0.0-git/lib/rack/showexceptions.rb +0 -349
  167. data/vendor/rack-1.0.0-git/lib/rack/showstatus.rb +0 -106
  168. data/vendor/rack-1.0.0-git/lib/rack/static.rb +0 -38
  169. data/vendor/rack-1.0.0-git/lib/rack/urlmap.rb +0 -55
  170. data/vendor/rack-1.0.0-git/lib/rack/utils.rb +0 -522
data/NEWS CHANGED
@@ -1,3 +1,132 @@
1
+ Release 2.2.12
2
+ --------------
3
+
4
+ * Improved Bundler support.
5
+ Previous versions might not be able to correctly load gems bundled
6
+ by Bundler.
7
+ * Fixed some Ruby 1.9 tempfile.rb compatibility problems.
8
+
9
+
10
+ Release 2.2.11
11
+ --------------
12
+
13
+ * This release fixes a regression that appeared in 2.2.10 which only
14
+ affects Apache. When under high load, Apache might freeze and stop
15
+ responding to requests. It is caused by a race conditions which is
16
+ why it escaped our last release testing.
17
+
18
+ This problem does not affect Nginx; you only have to upgrade if
19
+ you're using Apache.
20
+
21
+ http://groups.google.com/group/phusion-passenger/t/d5bb2f17c8446ea0
22
+
23
+
24
+ Release 2.2.10
25
+ --------------
26
+
27
+ * Fixed some Bundler compatibility problems.
28
+ * Fixed some file descriptor passing problems, which previously
29
+ could lead to mysterious crashes.
30
+ * Fixed some compilation problems on newer GCC versions. Issue #430.
31
+ * Support #size method in rack.input.
32
+
33
+
34
+ Release 2.2.9
35
+ -------------
36
+
37
+ * Fixed compatibility with Rails 3.
38
+ Actually, previous Phusion Passenger releases were already compatible
39
+ with Rails 3, depending on the spawn method that would be invoked. Here's
40
+ the story:
41
+
42
+ Since Phusion Passenger 2.2.8, when the file config.ru exists, Phusion
43
+ Passenger will treat the app as a Rack app, not as a Rails app. This is
44
+ in contrast to earlier versions which gave Rails detection more priority
45
+ than Rack detection. Phusion Passenger loads Rack apps and Rails apps in
46
+ different ways. The Rails loader was not compatible with Rails 3, which
47
+ is what we've fixed in this release.
48
+
49
+ That said, a Rails 3 app would have worked out-of-the-box on Phusion
50
+ Passenger 2.2.8 as well because Rails 3 apps include a config.ru file
51
+ by default, causing Phusion Passenger 2.2.8 to use the Rack loader.
52
+ Earlier versions of Phusion Passenger would just completely bail out
53
+ because they'd use the Rails loader.
54
+
55
+ That said, with 2.2.9 there are still some caveats:
56
+ - Smart spawning (the mechanism with which REE's 33% memory reduction
57
+ is implemented) is *not* supported for Rack apps. This means that if
58
+ you want to utilize smart spawning with Rails 3, then you should
59
+ remove your config.ru file.
60
+ - Rails 3 depends on Rack 1.1.0. You must have Rack 1.1.0 installed as
61
+ a gem, even if you've bundled it with the gem bundler. This is because
62
+ Phusion Passenger itself depends on Rack.
63
+
64
+ Both of these caveats are temporary. We have plans to solve both of these
65
+ properly in the future.
66
+ * What's up with the Gem Bundler?
67
+ There has been some reports that Phusion Passenger is not compatible with
68
+ Yehuda Katz's gem bundler (http://github.com/wycats/bundler). This might
69
+ have been true for an earlier version of the gem bundler, but the latest
70
+ version seems to work fine. Please note that you need to insert the
71
+ following snippet in config/preinitializer.rb, as instructed by the gem
72
+ bundler's README:
73
+
74
+ require "#{RAILS_ROOT}/vendor/gems/environment"
75
+
76
+ The Rails::Boot monkey patching code as posted at
77
+ http://yehudakatz.com/2009/11/03/using-the-new-gem-bundler-today/
78
+ does not seem to be required anymore.
79
+ * Fixed support for ActiveRecord subclasses that connect to another database.
80
+ ActiveRecord subclasses that connect to a database other than the default
81
+ one did not have their connection correctly cleared after forking.
82
+ This can result in weird errors along the lines of "Lost connection to
83
+ MySQL server during query". Issue #429.
84
+ * [Nginx] Fixed PCRE URL.
85
+ passenger-install-nginx-module downloads PCRE 7.8 if PCRE is not already
86
+ installed. However PCRE 7.8 has been removed from their FTP server,
87
+ so we've updated the URL to point to the latest version, 8.0.
88
+
89
+
90
+ Release 2.2.8
91
+ -------------
92
+
93
+ * [Nginx] Fixed some signal handling problems.
94
+ Restarting Nginx on OS X with SIGHUP can sometimes take a long time or
95
+ even fail completely. This is because of some signal handling problems,
96
+ which have now been fixed.
97
+ * [Nginx] Added OpenSSL as dependency.
98
+ OpenSSL is required in order to install Nginx, but this was not checked
99
+ by passenger-install-nginx-module. As a result,
100
+ passenger-install-nginx-module fails on e.g. out-of-the-box Ubuntu
101
+ installations until the user manually installs OpenSSL. Issue #422.
102
+ * [Nginx] Fixed support for internal redirects and subrequests.
103
+ It is now possible to, for example, point X-Accel-Redirects to Phusion
104
+ Passenger-served URLs. Patch contributed by W. Andrew Loe III: issue #433.
105
+ * [Apache] Fixed a GnuTLS compatibility issue.
106
+ mod_gnutls can cause Phusion Passenger to crash because of an unchecked
107
+ NULL pointer. This problem has now been fixed: issue #391.
108
+ * Fixed thread creation issue on Intel Itanium platforms.
109
+ This fixes issue #427.
110
+ * Fixed compilation problems on Linux running on the Renesas SH4 CPU.
111
+ Patch contributed by iwamatsu: issue #428.
112
+ * The Rack library has been unvendored.
113
+ The original reason for vendoring was to work around broken Rails
114
+ applications that explicitly specify Rack as a gem dependency. We've
115
+ found a better workaround that does not require vendoring Rack.
116
+ This also fixes a compatibility problem with Rails 3, because Rails
117
+ 3 depends on a newer Rack version than the one we had vendored.
118
+ Issue #432.
119
+ * Fixed compatibility with Ruby 1.9.1 patchlevel >= 152
120
+ Ruby 1.9.1 patchlevel >= 152 has a bug in its tempfile library. If you've
121
+ seen an error message along the lines of
122
+
123
+ *** Exception IOError in Passenger RequestHandler (closed stream)
124
+
125
+ then this is a Ruby bug at work. This bug has been fixed in Ruby 1.9.2,
126
+ but Ruby 1.9.1 still contains this bug. We've added a workaround so that
127
+ the bug is not triggered with this Ruby version. Issue #432.
128
+
129
+
1
130
  Release 2.2.7
2
131
  -------------
3
132
 
data/Rakefile CHANGED
@@ -648,7 +648,7 @@ spec = Gem::Specification.new do |s|
648
648
  s.homepage = "http://www.colouringcode.com/"
649
649
  s.summary = "Apache module for Ruby on Rails support, custom template support"
650
650
  s.name = "colouringcode-passenger"
651
- s.version = "0.1"
651
+ s.version = "0.2"
652
652
  s.rubyforge_project = "colouringcode-passenger"
653
653
  s.author = "Colouring Code - http://www.colouringcode.com/"
654
654
  s.email = "techystuff@colouringcode.com"
@@ -656,6 +656,7 @@ spec = Gem::Specification.new do |s|
656
656
  s.require_paths = ["lib", "ext"]
657
657
  s.add_dependency 'rake', '>= 0.8.1'
658
658
  s.add_dependency 'fastthread', '>= 1.0.1'
659
+ s.add_dependency 'rack'
659
660
  s.extensions << 'ext/phusion_passenger/extconf.rb'
660
661
  s.files = FileList[
661
662
  'Rakefile',
@@ -702,7 +703,6 @@ spec = Gem::Specification.new do |s|
702
703
  'benchmark/*.{cpp,rb}',
703
704
  'misc/*',
704
705
  'misc/*/*',
705
- 'vendor/**/*',
706
706
  'test/*.{rb,cpp,example}',
707
707
  'test/support/*.{cpp,h,rb}',
708
708
  'test/oxt/*.cpp',
@@ -48,6 +48,7 @@ class Installer < PhusionPassenger::AbstractInstaller
48
48
  Dependencies::Ruby_OpenSSL,
49
49
  Dependencies::RubyGems,
50
50
  Dependencies::Rake,
51
+ Dependencies::Rack,
51
52
  Dependencies::Apache2,
52
53
  Dependencies::Apache2_DevHeaders
53
54
  ]
@@ -45,6 +45,8 @@ class Installer < PhusionPassenger::AbstractInstaller
45
45
  Dependencies::Ruby_OpenSSL,
46
46
  Dependencies::RubyGems,
47
47
  Dependencies::Rake,
48
+ Dependencies::Rack,
49
+ Dependencies::OpenSSL_Dev,
48
50
  Dependencies::Zlib_Dev
49
51
  ]
50
52
  if Dependencies.fastthread_required?
@@ -147,8 +149,8 @@ private
147
149
  new_screen
148
150
  color_puts "<banner>PCRE (required by Nginx) not installed, downloading it...</banner>"
149
151
 
150
- basename = "pcre-7.8.tar.gz"
151
- dirname = "pcre-7.8"
152
+ basename = "pcre-8.00.tar.gz"
153
+ dirname = "pcre-8.00"
152
154
  url = "ftp://ftp.csx.cam.ac.uk/pub/software/programming/pcre/#{basename}"
153
155
  File.unlink("/tmp/#{basename}") rescue nil
154
156
  FileUtils.rm_rf("/tmp/#{dirname}")
@@ -175,8 +175,10 @@ private:
175
175
  env_arr = apr_table_elts(r->subprocess_env);
176
176
  env_entries = (apr_table_entry_t *) env_arr->elts;
177
177
  for (int i = 0; i < env_arr->nelts; ++i) {
178
- result->push_back(env_entries[i].key);
179
- result->push_back(env_entries[i].val);
178
+ if (env_entries[i].key != NULL && env_entries[i].val != NULL) {
179
+ result->push_back(env_entries[i].key);
180
+ result->push_back(env_entries[i].val);
181
+ }
180
182
  }
181
183
  return result;
182
184
  }
@@ -752,7 +752,7 @@ public:
752
752
  // Write some random data to wake up the server.
753
753
  channel.writeRaw("x", 1);
754
754
 
755
- clientConnection = channel.readFileDescriptor();
755
+ clientConnection = channel.readFileDescriptor(false);
756
756
  return ptr(new Client(clientConnection));
757
757
  } catch (const SystemException &e) {
758
758
  throw SystemException("Could not connect to the ApplicationPool server", e.code());
@@ -701,7 +701,7 @@ Server::start() {
701
701
  }
702
702
 
703
703
  UPDATE_TRACE_POINT();
704
- MessageChannel(serverSocket).writeFileDescriptor(fds[1]);
704
+ MessageChannel(serverSocket).writeFileDescriptor(fds[1], false);
705
705
  syscalls::close(fds[1]);
706
706
 
707
707
  UPDATE_TRACE_POINT();
@@ -319,12 +319,24 @@ public:
319
319
  * descriptor is a Unix socket.
320
320
  *
321
321
  * @param fileDescriptor The file descriptor to pass.
322
+ * @param negotiate See Ruby's MessageChannel#send_io method's comments.
322
323
  * @throws SystemException Something went wrong during file descriptor passing.
323
324
  * @throws boost::thread_interrupted
324
325
  * @pre <tt>fileDescriptor >= 0</tt>
325
326
  * @see readFileDescriptor()
326
327
  */
327
- void writeFileDescriptor(int fileDescriptor) {
328
+ void writeFileDescriptor(int fileDescriptor, bool negotiate = true) {
329
+ // See message_channel.rb for more info about negotiation.
330
+ if (negotiate) {
331
+ vector<string> args;
332
+
333
+ if (!read(args)) {
334
+ throw IOException("Unexpected end of stream encountered while pre-negotiating a file descriptor");
335
+ } else if (args.size() != 1 || args[0] != "pass IO") {
336
+ throw IOException("FD passing pre-negotiation message expected.");
337
+ }
338
+ }
339
+
328
340
  struct msghdr msg;
329
341
  struct iovec vec;
330
342
  char dummy[1];
@@ -368,6 +380,16 @@ public:
368
380
  if (ret == -1) {
369
381
  throw SystemException("Cannot send file descriptor with sendmsg()", errno);
370
382
  }
383
+
384
+ if (negotiate) {
385
+ vector<string> args;
386
+
387
+ if (!read(args)) {
388
+ throw IOException("Unexpected end of stream encountered while post-negotiating a file descriptor");
389
+ } else if (args.size() != 1 || args[0] != "got IO") {
390
+ throw IOException("FD passing post-negotiation message expected.");
391
+ }
392
+ }
371
393
  }
372
394
 
373
395
  /**
@@ -492,6 +514,7 @@ public:
492
514
  * Receive a file descriptor, which had been passed over the underlying
493
515
  * file descriptor.
494
516
  *
517
+ * @param negotiate See Ruby's MessageChannel#send_io method's comments.
495
518
  * @return The passed file descriptor.
496
519
  * @throws SystemException If something went wrong during the
497
520
  * receiving of a file descriptor. Perhaps the underlying
@@ -500,7 +523,12 @@ public:
500
523
  * file descriptor.
501
524
  * @throws boost::thread_interrupted
502
525
  */
503
- int readFileDescriptor() {
526
+ int readFileDescriptor(bool negotiate = true) {
527
+ // See message_channel.rb for more info about negotiation.
528
+ if (negotiate) {
529
+ write("pass IO", NULL);
530
+ }
531
+
504
532
  struct msghdr msg;
505
533
  struct iovec vec;
506
534
  char dummy[1];
@@ -538,16 +566,32 @@ public:
538
566
  }
539
567
 
540
568
  control_header = CMSG_FIRSTHDR(&msg);
569
+ if (control_header == NULL) {
570
+ throw IOException("No valid file descriptor received.");
571
+ }
541
572
  if (control_header->cmsg_len != EXPECTED_CMSG_LEN
542
573
  || control_header->cmsg_level != SOL_SOCKET
543
574
  || control_header->cmsg_type != SCM_RIGHTS) {
544
575
  throw IOException("No valid file descriptor received.");
545
576
  }
577
+
546
578
  #if defined(__APPLE__) || defined(__SOLARIS__) || defined(__arm__)
547
- return control_data.fd;
579
+ int fd = control_data.fd;
548
580
  #else
549
- return *((int *) CMSG_DATA(control_header));
581
+ int fd = *((int *) CMSG_DATA(control_header));
550
582
  #endif
583
+
584
+ if (negotiate) {
585
+ try {
586
+ write("got IO", NULL);
587
+ } catch (...) {
588
+ this_thread::disable_syscall_interruption dsi;
589
+ syscalls::close(fd);
590
+ throw;
591
+ }
592
+ }
593
+
594
+ return fd;
551
595
  }
552
596
 
553
597
  /**
@@ -34,6 +34,7 @@
34
34
 
35
35
  #include <oxt/system_calls.hpp>
36
36
  #include <oxt/backtrace.hpp>
37
+ #include <oxt/thread.hpp>
37
38
 
38
39
  #include <string>
39
40
  #include <sstream>
@@ -242,7 +243,7 @@ private:
242
243
  SpawnManager spawnManager;
243
244
  #endif
244
245
  SharedDataPtr data;
245
- boost::thread *cleanerThread;
246
+ oxt::thread *cleanerThread;
246
247
  bool detached;
247
248
  bool done;
248
249
  unsigned int maxIdleTime;
@@ -632,8 +633,9 @@ public:
632
633
  waitingOnGlobalQueue = 0;
633
634
  maxPerApp = DEFAULT_MAX_INSTANCES_PER_APP;
634
635
  maxIdleTime = DEFAULT_MAX_IDLE_TIME;
635
- cleanerThread = new boost::thread(
636
+ cleanerThread = new oxt::thread(
636
637
  bind(&StandardApplicationPool::cleanerThreadMainLoop, this),
638
+ "ApplicationPool cleaner",
637
639
  CLEANER_THREAD_STACK_SIZE
638
640
  );
639
641
  }
@@ -26,6 +26,6 @@
26
26
  #define _PASSENGER_VERSION_H_
27
27
 
28
28
  /* Don't forget to update lib/phusion_passenger/constants.rb too. */
29
- #define PASSENGER_VERSION "2.2.7"
29
+ #define PASSENGER_VERSION "2.2.12"
30
30
 
31
31
  #endif /* _PASSENGER_VERSION_H */
@@ -194,7 +194,7 @@ passenger_create_loc_conf(ngx_conf_t *cf)
194
194
  DEFINE_VAR_TO_PASS("SCGI", "1");
195
195
  DEFINE_VAR_TO_PASS("QUERY_STRING", "$query_string");
196
196
  DEFINE_VAR_TO_PASS("REQUEST_METHOD", "$request_method");
197
- DEFINE_VAR_TO_PASS("REQUEST_URI", "$request_uri");
197
+ DEFINE_VAR_TO_PASS("REQUEST_URI", "$uri$is_args$args");
198
198
  DEFINE_VAR_TO_PASS("SERVER_PROTOCOL", "$server_protocol");
199
199
  DEFINE_VAR_TO_PASS("SERVER_SOFTWARE", "nginx/$nginx_version");
200
200
  DEFINE_VAR_TO_PASS("REMOTE_ADDR", "$remote_addr");
@@ -26,6 +26,7 @@
26
26
  #include <string>
27
27
  #include <cstdio>
28
28
  #include <cstdlib>
29
+ #include <cstring>
29
30
 
30
31
  namespace Passenger {
31
32
 
@@ -25,6 +25,7 @@
25
25
 
26
26
  #include <string>
27
27
  #include <map>
28
+ #include <cstdlib>
28
29
 
29
30
  #include "StaticString.h"
30
31
 
@@ -42,8 +42,19 @@ interruption_signal_handler(int sig) {
42
42
  void
43
43
  oxt::setup_syscall_interruption_support() {
44
44
  struct sigaction action;
45
+ sigset_t signal_set;
45
46
  int ret;
46
47
 
48
+ /* Very important! The signal mask is inherited across fork()
49
+ * and exec() and we don't know what the parent process did to
50
+ * us. At least on OS X, having a signal mask blocking important
51
+ * signals can lead to stuff like waitpid() malfunction.
52
+ */
53
+ sigemptyset(&signal_set);
54
+ do {
55
+ ret = sigprocmask(SIG_SETMASK, &signal_set, NULL);
56
+ } while (ret == -1 && errno == EINTR);
57
+
47
58
  action.sa_handler = interruption_signal_handler;
48
59
  action.sa_flags = 0;
49
60
  sigemptyset(&action.sa_mask);
@@ -102,7 +102,8 @@ namespace oxt {
102
102
  * Setup system call interruption support.
103
103
  * This function may only be called once. It installs a signal handler
104
104
  * for INTERRUPTION_SIGNAL, so one should not install a different signal
105
- * handler for that signal after calling this function.
105
+ * handler for that signal after calling this function. It also resets
106
+ * the process signal mask.
106
107
  *
107
108
  * @warning
108
109
  * After oxt::setup_syscall_interruption_support() is called, sending a signal
@@ -34,6 +34,9 @@
34
34
  #ifdef OXT_BACKTRACE_IS_ENABLED
35
35
  #include <sstream>
36
36
  #endif
37
+ #include <string>
38
+ #include <list>
39
+ #include <unistd.h>
37
40
  #include <limits.h> // for PTHREAD_STACK_MIN
38
41
 
39
42
  namespace oxt {
@@ -132,17 +135,45 @@ public:
132
135
  set_thread_main_function(boost::bind(thread_main, func, data));
133
136
 
134
137
  unsigned long min_stack_size;
138
+ bool stack_min_size_defined;
139
+ bool round_stack_size;
140
+
135
141
  #ifdef PTHREAD_STACK_MIN
136
142
  // PTHREAD_STACK_MIN may not be a constant macro so we need
137
143
  // to evaluate it dynamically.
138
144
  min_stack_size = PTHREAD_STACK_MIN;
145
+ stack_min_size_defined = true;
139
146
  #else
140
147
  // Assume minimum stack size is 128 KB.
141
148
  min_stack_size = 128 * 1024;
149
+ stack_min_size_defined = false;
142
150
  #endif
143
- if (stack_size < min_stack_size) {
151
+ if (stack_size != 0 && stack_size < min_stack_size) {
144
152
  stack_size = min_stack_size;
153
+ round_stack_size = !stack_min_size_defined;
154
+ } else {
155
+ round_stack_size = true;
156
+ }
157
+
158
+ if (round_stack_size) {
159
+ // Round stack size up to page boundary.
160
+ long page_size;
161
+ #if defined(_SC_PAGESIZE)
162
+ page_size = sysconf(_SC_PAGESIZE);
163
+ #elif defined(_SC_PAGE_SIZE)
164
+ page_size = sysconf(_SC_PAGE_SIZE);
165
+ #elif defined(PAGESIZE)
166
+ page_size = sysconf(PAGESIZE);
167
+ #elif defined(PAGE_SIZE)
168
+ page_size = sysconf(PAGE_SIZE);
169
+ #else
170
+ page_size = getpagesize();
171
+ #endif
172
+ if (stack_size % page_size != 0) {
173
+ stack_size = stack_size - (stack_size % page_size) + page_size;
174
+ }
145
175
  }
176
+
146
177
  start_thread(stack_size);
147
178
  }
148
179
 
@@ -231,6 +262,71 @@ public:
231
262
  done = timed_join(boost::posix_time::millisec(10));
232
263
  }
233
264
  }
265
+
266
+ /**
267
+ * Keep interrupting the thread until it's done, then join it.
268
+ * This method will keep trying for at most <em>timeout</em> milliseconds.
269
+ *
270
+ * @param timeout The maximum number of milliseconds that this method
271
+ * should keep trying.
272
+ * @return True if the thread was successfully joined, false if the
273
+ * timeout has been reached.
274
+ * @throws boost::thread_interrupted The calling thread has been
275
+ * interrupted before we could join this thread.
276
+ */
277
+ bool interrupt_and_join(unsigned int timeout) {
278
+ bool joined = false, timed_out = false;
279
+ boost::posix_time::ptime deadline =
280
+ boost::posix_time::microsec_clock::local_time() +
281
+ boost::posix_time::millisec(timeout);
282
+ while (!joined && !timed_out) {
283
+ interrupt();
284
+ joined = timed_join(boost::posix_time::millisec(10));
285
+ timed_out = !joined && boost::posix_time::microsec_clock::local_time() > deadline;
286
+ }
287
+ return joined;
288
+ }
289
+
290
+ /**
291
+ * Interrupt and join multiple threads in a way that's more efficient than calling
292
+ * interrupt_and_join() on each thread individually. It iterates over all threads,
293
+ * interrupts each one without joining it, then waits until at least one thread
294
+ * is joinable. This is repeated until all threads are joined.
295
+ *
296
+ * @param threads An array of threads to join.
297
+ * @param size The number of elements in <em>threads</em>.
298
+ * @throws boost::thread_interrupted The calling thread has been
299
+ * interrupted before all threads have been joined. Some threads
300
+ * may have been successfully joined while others haven't.
301
+ */
302
+ static void interrupt_and_join_multiple(oxt::thread **threads, unsigned int size) {
303
+ std::list<oxt::thread *> remaining_threads;
304
+ std::list<oxt::thread *>::iterator it, current;
305
+ oxt::thread *thread;
306
+ unsigned int i;
307
+
308
+ for (i = 0; i < size; i++) {
309
+ remaining_threads.push_back(threads[i]);
310
+ }
311
+
312
+ while (!remaining_threads.empty()) {
313
+ for (it = remaining_threads.begin(); it != remaining_threads.end(); it++) {
314
+ thread = *it;
315
+ thread->interrupt();
316
+ }
317
+ for (it = remaining_threads.begin(); it != remaining_threads.end(); it++) {
318
+ thread = *it;
319
+ if (thread->timed_join(boost::posix_time::millisec(0))) {
320
+ current = it;
321
+ it--;
322
+ remaining_threads.erase(current);
323
+ }
324
+ }
325
+ if (!remaining_threads.empty()) {
326
+ syscalls::usleep(10000);
327
+ }
328
+ }
329
+ }
234
330
  };
235
331
 
236
332
  } // namespace oxt