passenger 3.9.2.beta → 4.0.0.rc4

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of passenger might be problematic. Click here for more details.

Files changed (159) hide show
  1. data/.travis.yml +3 -0
  2. data/NEWS +77 -7
  3. data/README.md +3 -11
  4. data/bin/passenger-install-apache2-module +24 -20
  5. data/bin/passenger-install-nginx-module +25 -23
  6. data/build/agents.rb +11 -0
  7. data/build/apache2.rb +9 -5
  8. data/build/basics.rb +37 -30
  9. data/build/common_library.rb +4 -1
  10. data/build/cplusplus_support.rb +5 -5
  11. data/build/cxx_tests.rb +28 -8
  12. data/build/integration_tests.rb +6 -3
  13. data/build/nginx.rb +3 -3
  14. data/build/packaging.rb +95 -57
  15. data/build/ruby_extension.rb +34 -21
  16. data/build/ruby_tests.rb +4 -2
  17. data/build/test_basics.rb +1 -1
  18. data/dev/run_travis.sh +36 -1
  19. data/doc/Users guide Apache.html +425 -308
  20. data/doc/Users guide Apache.idmap.txt +78 -70
  21. data/doc/Users guide Apache.index.sqlite3 +0 -0
  22. data/doc/Users guide Apache.txt +33 -92
  23. data/doc/Users guide Nginx.html +519 -220
  24. data/doc/Users guide Nginx.idmap.txt +78 -60
  25. data/doc/Users guide Nginx.txt +115 -26
  26. data/doc/Users guide Standalone.html +8 -2
  27. data/doc/users_guide_snippets/analysis_and_system_maintenance.txt +1 -7
  28. data/doc/users_guide_snippets/installation.txt +167 -22
  29. data/doc/users_guide_snippets/rackup_specifications.txt +4 -0
  30. data/doc/users_guide_snippets/since_version.txt +1 -0
  31. data/doc/users_guide_snippets/support_information.txt +3 -7
  32. data/doc/users_guide_snippets/tips.txt +0 -24
  33. data/ext/apache2/Configuration.cpp +11 -33
  34. data/ext/apache2/Configuration.hpp +3 -18
  35. data/ext/apache2/DirectoryMapper.h +20 -70
  36. data/ext/apache2/Hooks.cpp +2 -2
  37. data/ext/common/AgentsStarter.cpp +0 -2
  38. data/ext/common/AgentsStarter.h +0 -1
  39. data/ext/common/AgentsStarter.hpp +1 -3
  40. data/ext/common/ApplicationPool2/AppTypes.cpp +74 -0
  41. data/ext/common/ApplicationPool2/AppTypes.h +202 -0
  42. data/ext/common/ApplicationPool2/Common.h +12 -10
  43. data/ext/common/ApplicationPool2/DirectSpawner.h +256 -0
  44. data/ext/common/ApplicationPool2/DummySpawner.h +90 -0
  45. data/ext/common/ApplicationPool2/Group.h +311 -94
  46. data/ext/common/ApplicationPool2/Implementation.cpp +405 -145
  47. data/ext/common/ApplicationPool2/Options.h +24 -26
  48. data/ext/common/ApplicationPool2/PipeWatcher.h +20 -13
  49. data/ext/common/ApplicationPool2/Pool.h +326 -183
  50. data/ext/common/ApplicationPool2/Process.h +205 -55
  51. data/ext/common/ApplicationPool2/README.md +1 -1
  52. data/ext/common/ApplicationPool2/Session.h +21 -10
  53. data/ext/common/ApplicationPool2/SmartSpawner.h +801 -0
  54. data/ext/common/ApplicationPool2/Spawner.h +141 -1149
  55. data/ext/common/ApplicationPool2/SpawnerFactory.h +132 -0
  56. data/ext/common/ApplicationPool2/SuperGroup.h +146 -223
  57. data/ext/common/Constants.h +4 -2
  58. data/ext/common/Exceptions.h +23 -1
  59. data/ext/common/Logging.cpp +17 -6
  60. data/ext/common/Logging.h +37 -7
  61. data/ext/common/ResourceLocator.h +1 -1
  62. data/ext/common/Utils.cpp +49 -1
  63. data/ext/common/Utils.h +13 -4
  64. data/ext/common/{AnsiColorConstants.h → Utils/AnsiColorConstants.h} +0 -0
  65. data/ext/common/{BCrypt.cpp → Utils/BCrypt.cpp} +0 -0
  66. data/ext/common/{BCrypt.h → Utils/BCrypt.h} +0 -0
  67. data/ext/common/{Blowfish.c → Utils/Blowfish.c} +0 -0
  68. data/ext/common/{Blowfish.h → Utils/Blowfish.h} +0 -0
  69. data/ext/common/Utils/CachedFileStat.hpp +27 -25
  70. data/ext/common/Utils/Curl.h +184 -0
  71. data/ext/common/{HttpConstants.h → Utils/HttpConstants.h} +3 -0
  72. data/ext/common/Utils/IOUtils.cpp +6 -2
  73. data/ext/common/{IniFile.h → Utils/IniFile.h} +0 -0
  74. data/ext/common/Utils/LargeFiles.cpp +30 -0
  75. data/ext/common/Utils/LargeFiles.h +40 -0
  76. data/ext/common/Utils/StrIntUtils.cpp +72 -8
  77. data/ext/common/Utils/StrIntUtils.h +24 -2
  78. data/ext/common/Utils/StringMap.h +12 -2
  79. data/ext/common/Utils/VariantMap.h +51 -2
  80. data/ext/common/Utils/jsoncpp.cpp +1 -1
  81. data/ext/common/agents/Base.cpp +147 -11
  82. data/ext/common/agents/HelperAgent/AgentOptions.h +14 -6
  83. data/ext/common/agents/HelperAgent/Main.cpp +79 -19
  84. data/ext/common/agents/HelperAgent/RequestHandler.h +36 -16
  85. data/ext/common/agents/LoggingAgent/LoggingServer.h +3 -5
  86. data/ext/common/agents/LoggingAgent/Main.cpp +2 -4
  87. data/ext/common/agents/LoggingAgent/RemoteSender.h +18 -24
  88. data/ext/common/agents/SpawnPreparer.cpp +7 -0
  89. data/ext/common/agents/Watchdog/Main.cpp +96 -38
  90. data/ext/nginx/Configuration.c +26 -22
  91. data/ext/nginx/Configuration.h +4 -2
  92. data/ext/nginx/ContentHandler.c +23 -52
  93. data/ext/nginx/ContentHandler.h +5 -11
  94. data/ext/nginx/config +10 -3
  95. data/ext/nginx/ngx_http_passenger_module.c +21 -6
  96. data/ext/nginx/ngx_http_passenger_module.h +4 -1
  97. data/ext/oxt/dynamic_thread_group.hpp +9 -1
  98. data/ext/oxt/system_calls.cpp +2 -2
  99. data/ext/ruby/extconf.rb +2 -1
  100. data/helper-scripts/backtrace-sanitizer.rb +2 -0
  101. data/helper-scripts/wsgi-loader.py +54 -21
  102. data/lib/phusion_passenger.rb +5 -3
  103. data/lib/phusion_passenger/abstract_installer.rb +18 -41
  104. data/lib/phusion_passenger/admin_tools/memory_stats.rb +2 -2
  105. data/lib/phusion_passenger/admin_tools/server_instance.rb +2 -2
  106. data/lib/phusion_passenger/common_library.rb +23 -3
  107. data/lib/phusion_passenger/debug_logging.rb +10 -3
  108. data/lib/phusion_passenger/packaging.rb +1 -0
  109. data/lib/phusion_passenger/platform_info.rb +113 -115
  110. data/lib/phusion_passenger/platform_info/compiler.rb +224 -134
  111. data/lib/phusion_passenger/platform_info/cxx_portability.rb +143 -0
  112. data/lib/phusion_passenger/platform_info/depcheck.rb +371 -0
  113. data/lib/phusion_passenger/platform_info/depcheck_specs/apache2.rb +124 -0
  114. data/lib/phusion_passenger/platform_info/depcheck_specs/compiler_toolchain.rb +97 -0
  115. data/lib/phusion_passenger/platform_info/depcheck_specs/gems.rb +39 -0
  116. data/lib/phusion_passenger/platform_info/depcheck_specs/libs.rb +118 -0
  117. data/lib/phusion_passenger/platform_info/depcheck_specs/ruby.rb +137 -0
  118. data/lib/phusion_passenger/platform_info/depcheck_specs/utilities.rb +15 -0
  119. data/lib/phusion_passenger/platform_info/operating_system.rb +6 -5
  120. data/lib/phusion_passenger/platform_info/ruby.rb +45 -34
  121. data/lib/phusion_passenger/request_handler.rb +35 -22
  122. data/lib/phusion_passenger/request_handler/thread_handler.rb +5 -6
  123. data/lib/phusion_passenger/ruby_core_enhancements.rb +7 -1
  124. data/lib/phusion_passenger/standalone/runtime_installer.rb +43 -34
  125. data/lib/phusion_passenger/utils/robust_interruption.rb +34 -18
  126. data/passenger.gemspec +25 -0
  127. data/resources/templates/standalone/config.erb +3 -1
  128. data/test/config.json.travis +2 -2
  129. data/test/cxx/ApplicationPool2/DirectSpawnerTest.cpp +37 -5
  130. data/test/cxx/ApplicationPool2/PoolTest.cpp +143 -50
  131. data/test/cxx/ApplicationPool2/ProcessTest.cpp +8 -0
  132. data/test/cxx/ApplicationPool2/SmartSpawnerTest.cpp +28 -17
  133. data/test/cxx/ApplicationPool2/SpawnerTestCases.cpp +31 -26
  134. data/test/cxx/RequestHandlerTest.cpp +17 -1
  135. data/test/cxx/UtilsTest.cpp +84 -10
  136. data/test/integration_tests/apache2_tests.rb +49 -163
  137. data/test/integration_tests/hello_world_wsgi_spec.rb +2 -2
  138. data/test/integration_tests/mycook_spec.rb +1 -1
  139. data/test/integration_tests/nginx_tests.rb +37 -19
  140. data/test/ruby/request_handler_spec.rb +1 -0
  141. data/test/ruby/spec_helper.rb +52 -1
  142. data/test/stub/nginx/nginx.conf.erb +2 -0
  143. data/test/stub/rack/start.rb +5 -0
  144. data/test/stub/rails3.0/Gemfile.lock +30 -30
  145. data/test/stub/rails3.1/Gemfile +1 -1
  146. data/test/stub/rails3.1/Gemfile.lock +3 -3
  147. data/test/stub/rails3.2/Gemfile +1 -1
  148. data/test/stub/rails3.2/Gemfile.lock +4 -4
  149. data/test/stub/rails_apps/2.3/mycook/app/controllers/welcome_controller.rb +1 -1
  150. data/test/stub/rails_apps/2.3/mycook/app/helpers/recipes_helper.rb +2 -0
  151. data/test/stub/rails_apps/2.3/mycook/app/helpers/test_helper.rb +2 -0
  152. data/test/stub/rails_apps/2.3/mycook/app/helpers/uploads_helper.rb +2 -0
  153. data/test/stub/rails_apps/2.3/mycook/app/helpers/welcome_helper.rb +2 -0
  154. data/test/support/nginx_controller.rb +2 -1
  155. metadata +160 -156
  156. data/build/gempackagetask.rb +0 -99
  157. data/build/packagetask.rb +0 -186
  158. data/ext/common/StringListCreator.h +0 -83
  159. data/lib/phusion_passenger/dependencies.rb +0 -657
@@ -1,6 +1,6 @@
1
1
  /*
2
2
  * Phusion Passenger - https://www.phusionpassenger.com/
3
- * Copyright (c) 2010, 2011, 2012 Phusion
3
+ * Copyright (c) 2010-2013 Phusion
4
4
  *
5
5
  * "Phusion Passenger" is a trademark of Hongli Lai & Ninh Bui.
6
6
  *
@@ -26,11 +26,13 @@
26
26
  #define _PASSENGER_CONSTANTS_H_
27
27
 
28
28
  /* Don't forget to update lib/phusion_passenger.rb too. */
29
- #define PASSENGER_VERSION "3.9.2.beta"
29
+ #define PASSENGER_VERSION "4.0.0.rc4"
30
30
 
31
31
  #define FEEDBACK_FD 3
32
32
 
33
33
  #define DEFAULT_LOG_LEVEL 0
34
+ #define DEFAULT_RUBY "ruby"
35
+ #define DEFAULT_PYTHON "python"
34
36
  #define DEFAULT_MAX_POOL_SIZE 6
35
37
  #define DEFAULT_POOL_IDLE_TIME 300
36
38
  #define DEFAULT_MAX_INSTANCES_PER_APP 0
@@ -1,6 +1,6 @@
1
1
  /*
2
2
  * Phusion Passenger - https://www.phusionpassenger.com/
3
- * Copyright (c) 2010 Phusion
3
+ * Copyright (c) 2010-2013 Phusion
4
4
  *
5
5
  * "Phusion Passenger" is a trademark of Hongli Lai & Ninh Bui.
6
6
  *
@@ -301,6 +301,28 @@ public:
301
301
  }
302
302
  };
303
303
 
304
+ /**
305
+ * Indicates that a Pool::get() or Pool::asyncGet() request was denied.
306
+ * The request never reached a process. This could be because, before the
307
+ * request could reach a process, the administrator detached the containing
308
+ * SuperGroup. Or maybe the request sat in the queue for too long.
309
+ */
310
+ class GetAbortedException: public oxt::tracable_exception {
311
+ private:
312
+ string msg;
313
+
314
+ public:
315
+ GetAbortedException(const string &message)
316
+ : msg(message)
317
+ { }
318
+
319
+ virtual ~GetAbortedException() throw() {}
320
+
321
+ virtual const char *what() const throw() {
322
+ return msg.c_str();
323
+ }
324
+ };
325
+
304
326
  /**
305
327
  * Indicates that a specified argument is incorrect or violates a requirement.
306
328
  *
@@ -1,6 +1,6 @@
1
1
  /*
2
2
  * Phusion Passenger - https://www.phusionpassenger.com/
3
- * Copyright (c) 2010 Phusion
3
+ * Copyright (c) 2010-2013 Phusion
4
4
  *
5
5
  * "Phusion Passenger" is a trademark of Hongli Lai & Ninh Bui.
6
6
  *
@@ -27,6 +27,7 @@
27
27
  #include <fcntl.h>
28
28
  #include <unistd.h>
29
29
  #include <Logging.h>
30
+ #include <Utils/StrIntUtils.h>
30
31
 
31
32
  namespace Passenger {
32
33
 
@@ -55,22 +56,32 @@ setDebugFile(const char *logFile) {
55
56
  }
56
57
 
57
58
  void
58
- _prepareLogEntry(std::stringstream &sstream) {
59
+ _prepareLogEntry(std::stringstream &sstream, const char *file, unsigned int line) {
59
60
  time_t the_time;
60
61
  struct tm the_tm;
61
62
  char datetime_buf[60];
62
63
  struct timeval tv;
64
+
65
+ if (startsWith(file, "ext/")) {
66
+ file += sizeof("ext/") - 1;
67
+ if (startsWith(file, "common/")) {
68
+ file += sizeof("common/") - 1;
69
+ if (startsWith(file, "ApplicationPool2/")) {
70
+ file += sizeof("Application") - 1;
71
+ }
72
+ }
73
+ }
63
74
 
64
75
  the_time = time(NULL);
65
76
  localtime_r(&the_time, &the_tm);
66
77
  strftime(datetime_buf, sizeof(datetime_buf) - 1, "%F %H:%M:%S", &the_tm);
67
78
  gettimeofday(&tv, NULL);
68
79
  sstream <<
69
- "[ pid=" << std::dec << getpid() <<
70
- " thr=" << std::hex << pthread_self() << std::dec <<
71
- " time=" << datetime_buf << "." << std::setfill('0') << std::setw(4) <<
80
+ "[ " << datetime_buf << "." << std::setfill('0') << std::setw(4) <<
72
81
  (unsigned long) (tv.tv_usec / 100) <<
73
- " file=" << __FILE__ << ":" << (unsigned long) __LINE__ <<
82
+ " " << std::dec << getpid() << "/" <<
83
+ std::hex << pthread_self() << std::dec <<
84
+ " " << file << ":" << line <<
74
85
  " ]: ";
75
86
  }
76
87
 
@@ -62,18 +62,27 @@ extern int _logOutput;
62
62
  int getLogLevel();
63
63
  void setLogLevel(int value);
64
64
  bool setDebugFile(const char *logFile = NULL);
65
- void _prepareLogEntry(std::stringstream &sstream);
65
+ void _prepareLogEntry(std::stringstream &sstream, const char *file, unsigned int line);
66
66
  void _writeLogEntry(const std::string &str);
67
67
 
68
68
 
69
+ enum PassengerLogLevel {
70
+ LVL_CRIT = -2,
71
+ LVL_ERROR = -1,
72
+ LVL_INFO = 0,
73
+ LVL_WARN = 0,
74
+ LVL_DEBUG = 1,
75
+ LVL_DEBUG2 = 2
76
+ };
77
+
69
78
  /**
70
79
  * Write the given expression to the log stream.
71
80
  */
72
81
  #define P_LOG(level, expr) \
73
82
  do { \
74
- if (Passenger::_logLevel >= level) { \
83
+ if (Passenger::_logLevel >= (level)) { \
75
84
  std::stringstream sstream; \
76
- Passenger::_prepareLogEntry(sstream); \
85
+ Passenger::_prepareLogEntry(sstream, __FILE__, __LINE__); \
77
86
  sstream << expr << "\n"; \
78
87
  Passenger::_writeLogEntry(sstream.str()); \
79
88
  } \
@@ -83,25 +92,31 @@ void _writeLogEntry(const std::string &str);
83
92
  * Write the given expression, which represents a warning,
84
93
  * to the log stream.
85
94
  */
86
- #define P_WARN(expr) P_LOG(0, expr)
95
+ #define P_WARN(expr) P_LOG(LVL_WARN, expr)
87
96
 
88
97
  /**
89
98
  * Write the given expression, which represents a warning,
90
99
  * to the log stream.
91
100
  */
92
- #define P_INFO(expr) P_LOG(0, expr)
101
+ #define P_INFO(expr) P_LOG(LVL_INFO, expr)
93
102
 
94
103
  /**
95
104
  * Write the given expression, which represents an error,
96
105
  * to the log stream.
97
106
  */
98
- #define P_ERROR(expr) P_LOG(-1, expr)
107
+ #define P_ERROR(expr) P_LOG(LVL_ERROR, expr)
108
+
109
+ /**
110
+ * Write the given expression, which represents a critical non-recoverable error,
111
+ * to the log stream.
112
+ */
113
+ #define P_CRITICAL(expr) P_LOG(LVL_CRIT, expr)
99
114
 
100
115
  /**
101
116
  * Write the given expression, which represents a debugging message,
102
117
  * to the log stream.
103
118
  */
104
- #define P_DEBUG(expr) P_TRACE(1, expr)
119
+ #define P_DEBUG(expr) P_TRACE(LVL_DEBUG, expr)
105
120
 
106
121
  #ifdef PASSENGER_DEBUG
107
122
  #define P_TRACE(level, expr) P_LOG(level, expr)
@@ -110,6 +125,21 @@ void _writeLogEntry(const std::string &str);
110
125
  #endif
111
126
 
112
127
 
128
+ #define P_BUG(expr) \
129
+ do { \
130
+ TRACE_POINT(); \
131
+ P_CRITICAL("[BUG] " << expr); \
132
+ abort(); \
133
+ } while (false)
134
+
135
+ #define P_BUG_UTP(expr) \
136
+ do { \
137
+ UPDATE_TRACE_POINT(); \
138
+ P_CRITICAL("[BUG] " << expr); \
139
+ abort(); \
140
+ } while (false)
141
+
142
+
113
143
  class NotExpectingExceptions {
114
144
  private:
115
145
  this_thread::disable_interruption di;
@@ -26,9 +26,9 @@
26
26
  #define _PASSENGER_RESOURCE_LOCATOR_H_
27
27
 
28
28
  #include <string>
29
- #include <IniFile.h>
30
29
  #include <Exceptions.h>
31
30
  #include <Utils.h>
31
+ #include <Utils/IniFile.h>
32
32
 
33
33
  namespace Passenger {
34
34
 
@@ -113,7 +113,7 @@ getFileType(const StaticString &filename, CachedFileStat *cstat, unsigned int th
113
113
  int ret;
114
114
 
115
115
  if (cstat != NULL) {
116
- ret = cstat->stat(filename.toString(), &buf, throttleRate);
116
+ ret = cstat->stat(filename, &buf, throttleRate);
117
117
  } else {
118
118
  ret = stat(filename.c_str(), &buf);
119
119
  }
@@ -277,6 +277,54 @@ extractDirName(const StaticString &path) {
277
277
  return result_string;
278
278
  }
279
279
 
280
+ StaticString
281
+ extractDirNameStatic(const StaticString &path) {
282
+ breakpoint();
283
+ if (path.empty()) {
284
+ return StaticString(".", 1);
285
+ }
286
+
287
+ const char *data = path.data();
288
+ const char *end = path.data() + path.size();
289
+
290
+ // Ignore trailing '/' characters.
291
+ while (end > data && end[-1] == '/') {
292
+ end--;
293
+ }
294
+ if (end == data) {
295
+ // Apparently the entire path consists of slashes.
296
+ return StaticString("/", 1);
297
+ }
298
+
299
+ // Find last '/'.
300
+ end--;
301
+ while (end > data && *end != '/') {
302
+ end--;
303
+ }
304
+ if (end == data) {
305
+ if (*data == '/') {
306
+ // '/' found, but it's the first character in the path.
307
+ return StaticString("/", 1);
308
+ } else {
309
+ // No '/' found in path.
310
+ return StaticString(".", 1);
311
+ }
312
+ } else {
313
+ // '/' found and it's not the first character in path.
314
+ // 'end' points to that '/' character.
315
+ // Skip to first non-'/' character.
316
+ while (end >= data && *end == '/') {
317
+ end--;
318
+ }
319
+ if (end < data) {
320
+ // The entire path consists of '/' characters.
321
+ return StaticString("/", 1);
322
+ } else {
323
+ return StaticString(data, end - data + 1);
324
+ }
325
+ }
326
+ }
327
+
280
328
  string
281
329
  extractBaseName(const StaticString &path) {
282
330
  char *path_copy = strdup(path.c_str());
@@ -1,6 +1,6 @@
1
1
  /*
2
2
  * Phusion Passenger - https://www.phusionpassenger.com/
3
- * Copyright (c) 2010, 2011, 2012 Phusion
3
+ * Copyright (c) 2010-2013 Phusion
4
4
  *
5
5
  * "Phusion Passenger" is a trademark of Hongli Lai & Ninh Bui.
6
6
  *
@@ -39,8 +39,9 @@
39
39
  #include <cstring>
40
40
  #include <errno.h>
41
41
  #include <unistd.h>
42
- #include "StaticString.h"
43
- #include "Exceptions.h"
42
+ #include <StaticString.h>
43
+ #include <Exceptions.h>
44
+ #include <Utils/LargeFiles.h>
44
45
 
45
46
  namespace Passenger {
46
47
 
@@ -178,6 +179,14 @@ string resolveSymlink(const StaticString &path);
178
179
  */
179
180
  string extractDirName(const StaticString &path);
180
181
 
182
+ /**
183
+ * Given a path, extracts its directory name. This version does not use
184
+ * any dynamically allocated storage and does not require `path` to be
185
+ * NULL-terminated. It returns a StaticString that points either to static
186
+ * storage, or to a substring of `path`.
187
+ */
188
+ StaticString extractDirNameStatic(const StaticString &path);
189
+
181
190
  /**
182
191
  * Given a path, extracts its base name.
183
192
  * <em>path</em> MUST be null-terminated!
@@ -435,7 +444,7 @@ public:
435
444
 
436
445
  snprintf(templ, sizeof(templ), "%s/%s.XXXXXX", dir.c_str(), identifier);
437
446
  templ[sizeof(templ) - 1] = '\0';
438
- fd = mkstemp(templ);
447
+ fd = lfs_mkstemp(templ);
439
448
  if (fd == -1) {
440
449
  char message[1024];
441
450
  int e = errno;
File without changes
@@ -1,6 +1,6 @@
1
1
  /*
2
2
  * Phusion Passenger - https://www.phusionpassenger.com/
3
- * Copyright (c) 2010 Phusion
3
+ * Copyright (c) 2010-2013 Phusion
4
4
  *
5
5
  * "Phusion Passenger" is a trademark of Hongli Lai & Ninh Bui.
6
6
  *
@@ -34,11 +34,12 @@
34
34
  #include <cassert>
35
35
  #include <string>
36
36
  #include <boost/shared_ptr.hpp>
37
+ #include <boost/make_shared.hpp>
37
38
  #include <oxt/system_calls.hpp>
38
39
 
39
- #include "SystemTime.h"
40
- #include "StaticString.h"
41
- #include "Utils/HashMap.h"
40
+ #include <StaticString.h>
41
+ #include <Utils/SystemTime.h>
42
+ #include <Utils/StringMap.h>
42
43
 
43
44
  namespace Passenger {
44
45
 
@@ -72,13 +73,13 @@ public:
72
73
  time_t last_time;
73
74
 
74
75
  /**
75
- * Checks whether <em>interval</em> seconds have elapsed since <em>begin</em>
76
- * The current time is returned via the <tt>currentTime</tt> argument,
76
+ * Checks whether `interval` seconds have elapsed since `begin`.
77
+ * The current time is returned via the `currentTime` argument,
77
78
  * so that the caller doesn't have to call time() again if it needs the current
78
79
  * time.
79
80
  *
80
81
  * @pre begin <= time(NULL)
81
- * @return Whether <tt>interval</tt> seconds have elapsed since <tt>begin</tt>.
82
+ * @return Whether `interval` seconds have elapsed since `begin`.
82
83
  * @throws TimeRetrievalException Something went wrong while retrieving the time.
83
84
  * @throws boost::thread_interrupted
84
85
  */
@@ -100,9 +101,10 @@ public:
100
101
  *
101
102
  * @param filename The file to stat.
102
103
  */
103
- Entry(const string &filename) {
104
+ Entry(const string &_filename)
105
+ : filename(_filename)
106
+ {
104
107
  memset(&info, 0, sizeof(struct stat));
105
- this->filename = filename;
106
108
  last_result = -1;
107
109
  last_errno = 0;
108
110
  last_time = 0;
@@ -141,7 +143,7 @@ public:
141
143
 
142
144
  typedef shared_ptr<Entry> EntryPtr;
143
145
  typedef list<EntryPtr> EntryList;
144
- typedef HashMap<string, EntryList::iterator, StaticString::Hash> EntryMap;
146
+ typedef StringMap<EntryList::iterator> EntryMap;
145
147
 
146
148
  unsigned int maxSize;
147
149
  EntryList entries;
@@ -158,7 +160,7 @@ public:
158
160
  }
159
161
 
160
162
  /**
161
- * Stats the given file. If <tt>throttleRate</tt> seconds have passed since
163
+ * Stats the given file. If `throttleRate` seconds have passed since
162
164
  * the last time stat() was called on this file, then the file will be
163
165
  * re-stat()ted, otherwise the cached stat information will be returned.
164
166
  *
@@ -175,35 +177,35 @@ public:
175
177
  * SystemException being thrown.
176
178
  * @throws boost::thread_interrupted
177
179
  */
178
- int stat(const string &filename, struct stat *buf, unsigned int throttleRate = 0) {
180
+ int stat(const StaticString &filename, struct stat *buf, unsigned int throttleRate = 0) {
179
181
  boost::unique_lock<boost::mutex> l(lock);
180
- EntryMap::iterator it(cache.find(filename));
182
+ EntryList::iterator it(cache.get(filename, entries.end()));
181
183
  EntryPtr entry;
182
184
  int ret;
183
185
 
184
- if (it == cache.end()) {
186
+ if (it == entries.end()) {
185
187
  // Filename not in cache.
186
188
  // If cache is full, remove the least recently used
187
189
  // cache entry.
188
190
  if (maxSize != 0 && cache.size() == maxSize) {
189
191
  EntryList::iterator listEnd(entries.end());
190
192
  listEnd--;
191
- string filename((*listEnd)->filename);
193
+ string filename2((*listEnd)->filename);
192
194
  entries.pop_back();
193
- cache.erase(filename);
195
+ cache.remove(filename2);
194
196
  }
195
197
 
196
198
  // Add to cache as most recently used.
197
- entry = EntryPtr(new Entry(filename));
199
+ entry = make_shared<Entry>(filename);
198
200
  entries.push_front(entry);
199
- cache[filename] = entries.begin();
201
+ cache.set(filename, entries.begin());
200
202
  } else {
201
203
  // Cache hit.
202
- entry = *it->second;
204
+ entry = *it;
203
205
 
204
206
  // Mark this cache item as most recently used.
205
- entries.splice(entries.begin(), entries, it->second);
206
- cache[filename] = entries.begin();
207
+ entries.splice(entries.begin(), entries, it);
208
+ cache.set(filename, entries.begin());
207
209
  }
208
210
  ret = entry->refresh(throttleRate);
209
211
  *buf = entry->info;
@@ -224,18 +226,18 @@ public:
224
226
  for (int i = 0; i < toRemove; i++) {
225
227
  string filename(entries.back()->filename);
226
228
  entries.pop_back();
227
- cache.erase(filename);
229
+ cache.remove(filename);
228
230
  }
229
231
  }
230
232
  this->maxSize = maxSize;
231
233
  }
232
234
 
233
235
  /**
234
- * Returns whether <tt>filename</tt> is in the cache.
236
+ * Returns whether `filename` is in the cache.
235
237
  */
236
- bool knows(const string &filename) const {
238
+ bool knows(const StaticString &filename) const {
237
239
  boost::unique_lock<boost::mutex> l(lock);
238
- return cache.find(filename) != cache.end();
240
+ return cache.get(filename) != EntryList::iterator();
239
241
  }
240
242
  };
241
243