Revert "locking: support shared memory locking"
I just enabled this on jefftk.com and it locked the server up.
This reverts commit d0464e8982.
This commit is contained in:
+3
-23
@@ -61,7 +61,7 @@ NgxCache::NgxCache(const StringPiece& path,
|
||||
config.file_cache_clean_size_kb() * 1024,
|
||||
config.file_cache_clean_inode_limit());
|
||||
file_cache_ = new FileCache(
|
||||
config.file_cache_path(), factory->file_system(), NULL,
|
||||
config.file_cache_path(), factory->file_system(), factory->slow_worker(),
|
||||
factory->filename_encoder(), policy, factory->message_handler());
|
||||
l2_cache_.reset(new CacheStats(kFileCache, file_cache_, factory->timer(),
|
||||
factory->statistics()));
|
||||
@@ -89,6 +89,8 @@ NgxCache::NgxCache(const StringPiece& path,
|
||||
NgxCache::~NgxCache() {
|
||||
}
|
||||
|
||||
// TODO(oschaaf): see rootinit/childinit from ApacheCache.cc
|
||||
|
||||
void NgxCache::FallBackToFileBasedLocking() {
|
||||
if ((shared_mem_lock_manager_.get() != NULL) || (lock_manager_ == NULL)) {
|
||||
shared_mem_lock_manager_.reset(NULL);
|
||||
@@ -99,26 +101,4 @@ void NgxCache::FallBackToFileBasedLocking() {
|
||||
}
|
||||
}
|
||||
|
||||
void NgxCache::RootInit() {
|
||||
factory_->message_handler()->Message(
|
||||
kInfo, "Initializing shared memory for path: %s.", path_.c_str());
|
||||
if ((shared_mem_lock_manager_.get() != NULL) &&
|
||||
!shared_mem_lock_manager_->Initialize()) {
|
||||
FallBackToFileBasedLocking();
|
||||
}
|
||||
}
|
||||
|
||||
void NgxCache::ChildInit() {
|
||||
factory_->message_handler()->Message(
|
||||
kInfo, "Reusing shared memory for path: %s.", path_.c_str());
|
||||
if ((shared_mem_lock_manager_.get() != NULL) &&
|
||||
!shared_mem_lock_manager_->Attach()) {
|
||||
FallBackToFileBasedLocking();
|
||||
}
|
||||
|
||||
if (file_cache_ != NULL) {
|
||||
file_cache_->set_worker(factory_->slow_worker());
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace net_instaweb
|
||||
|
||||
@@ -50,6 +50,7 @@ class NgxCache {
|
||||
|
||||
void RootInit();
|
||||
void ChildInit();
|
||||
void GlobalCleanup(MessageHandler* handler); // only called in root process
|
||||
|
||||
private:
|
||||
void FallBackToFileBasedLocking();
|
||||
|
||||
+29
-44
@@ -50,6 +50,7 @@ extern "C" {
|
||||
#include "net/instaweb/rewriter/public/static_javascript_manager.h"
|
||||
#include "net/instaweb/public/global_constants.h"
|
||||
#include "net/instaweb/public/version.h"
|
||||
#include "net/instaweb/util/public/file_system_lock_manager.h"
|
||||
#include "net/instaweb/util/public/google_message_handler.h"
|
||||
#include "net/instaweb/util/public/google_url.h"
|
||||
#include "net/instaweb/util/public/string.h"
|
||||
@@ -462,8 +463,6 @@ void ps_cleanup_main_conf(void* data) {
|
||||
cfg_m->handler = NULL;
|
||||
net_instaweb::NgxRewriteDriverFactory::Terminate();
|
||||
net_instaweb::NgxRewriteOptions::Terminate();
|
||||
// TODO(oschaaf): terminate shared mem runtime when we update
|
||||
// psol to a later revision that has it.
|
||||
}
|
||||
|
||||
template <typename ConfT> ConfT* ps_create_conf(ngx_conf_t* cf) {
|
||||
@@ -572,19 +571,38 @@ char* ps_merge_srv_conf(ngx_conf_t* cf, void* parent, void* child) {
|
||||
// with other modules that actually are interested in these signals
|
||||
ps_ignore_sigpipe();
|
||||
net_instaweb::NgxRewriteDriverFactory::Initialize();
|
||||
// TODO(jefftk): We should call NgxRewriteDriverFactory::Terminate() when
|
||||
// we're done with it. That never happens, though, because this is the
|
||||
// top-level config and so sticks around as long as we're running.
|
||||
|
||||
cfg_m->driver_factory = new net_instaweb::NgxRewriteDriverFactory(
|
||||
parent_cfg_s->options);
|
||||
}
|
||||
|
||||
cfg_s->server_context = cfg_m->driver_factory->MakeNgxServerContext();
|
||||
// The server context sets some options when we call global_options(). So
|
||||
// let it do that, then merge in options we got from the config file.
|
||||
cfg_s->server_context = new net_instaweb::NgxServerContext(
|
||||
cfg_m->driver_factory);
|
||||
|
||||
// The server context sets some options when we call global_options(). So let
|
||||
// it do that, then merge in options we got from parsing the config file.
|
||||
// Once we do that we're done with cfg_s->options.
|
||||
cfg_s->server_context->global_options()->Merge(*cfg_s->options);
|
||||
delete cfg_s->options;
|
||||
cfg_s->options = NULL;
|
||||
|
||||
StringPiece filename_prefix =
|
||||
cfg_s->server_context->config()->file_cache_path();
|
||||
cfg_s->server_context->set_lock_manager(
|
||||
new net_instaweb::FileSystemLockManager(
|
||||
cfg_m->driver_factory->file_system(),
|
||||
filename_prefix.as_string(),
|
||||
cfg_m->driver_factory->scheduler(),
|
||||
cfg_m->driver_factory->message_handler()));
|
||||
|
||||
cfg_m->driver_factory->InitServerContext(cfg_s->server_context);
|
||||
|
||||
cfg_s->proxy_fetch_factory =
|
||||
new net_instaweb::ProxyFetchFactory(cfg_s->server_context);
|
||||
|
||||
return NGX_CONF_OK;
|
||||
}
|
||||
|
||||
@@ -1611,50 +1629,17 @@ ngx_http_module_t ps_module = {
|
||||
ps_merge_loc_conf
|
||||
};
|
||||
|
||||
// called after configuration is complete, but before nginx starts forking
|
||||
ngx_int_t ps_init_module(ngx_cycle_t* cycle) {
|
||||
// Called when nginx forks worker processes. No threads should be started
|
||||
// before this.
|
||||
ngx_int_t ps_init_process(ngx_cycle_t* cycle) {
|
||||
ps_main_conf_t* cfg_m = static_cast<ps_main_conf_t*>(
|
||||
ngx_http_cycle_get_module_main_conf(cycle, ngx_pagespeed));
|
||||
if (cfg_m->driver_factory != NULL) {
|
||||
cfg_m->driver_factory->RootInit();
|
||||
cfg_m->driver_factory->StartThreads();
|
||||
}
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
// Called when nginx forks worker processes. No threads should be started
|
||||
// before this.
|
||||
ngx_int_t ps_init_child_process(ngx_cycle_t* cycle) {
|
||||
ps_main_conf_t* cfg_m = static_cast<ps_main_conf_t*>(
|
||||
ngx_http_cycle_get_module_main_conf(cycle, ngx_pagespeed));
|
||||
|
||||
if (cfg_m->driver_factory == NULL) {
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
// ChildInit() will initialise all ServerContexts, which we need to
|
||||
// create ProxyFetchFactories below
|
||||
cfg_m->driver_factory->ChildInit();
|
||||
|
||||
ngx_http_core_main_conf_t* cmcf = static_cast<ngx_http_core_main_conf_t*>(
|
||||
ngx_http_cycle_get_module_main_conf(cycle, ngx_http_core_module));
|
||||
ngx_http_core_srv_conf_t** cscfp = static_cast<ngx_http_core_srv_conf_t**>(
|
||||
cmcf->servers.elts);
|
||||
ngx_uint_t s;
|
||||
|
||||
// Iterate over all configured server{} blocks, and find our context in it,
|
||||
// so we can create and set a ProxyFetchFactory for it.
|
||||
for (s = 0; s < cmcf->servers.nelts; s++) {
|
||||
ps_srv_conf_t* cfg_s = static_cast<ps_srv_conf_t*>(
|
||||
cscfp[s]->ctx->srv_conf[ngx_pagespeed.ctx_index]);
|
||||
cfg_s->proxy_fetch_factory =
|
||||
new net_instaweb::ProxyFetchFactory(cfg_s->server_context);
|
||||
}
|
||||
|
||||
cfg_m->driver_factory->StartThreads();
|
||||
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
} // namespace ngx_psol
|
||||
@@ -1665,8 +1650,8 @@ ngx_module_t ngx_pagespeed = {
|
||||
ngx_psol::ps_commands,
|
||||
NGX_HTTP_MODULE,
|
||||
NULL,
|
||||
ngx_psol::ps_init_module,
|
||||
ngx_psol::ps_init_child_process,
|
||||
NULL,
|
||||
ngx_psol::ps_init_process,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
|
||||
@@ -23,7 +23,6 @@
|
||||
#include "ngx_cache.h"
|
||||
#include "ngx_rewrite_options.h"
|
||||
#include "ngx_thread_system.h"
|
||||
#include "ngx_server_context.h"
|
||||
|
||||
#include "net/instaweb/apache/apr_mem_cache.h"
|
||||
#include "net/instaweb/apache/apr_thread_compatible_pool.h"
|
||||
@@ -48,7 +47,6 @@
|
||||
#include "net/instaweb/util/public/lru_cache.h"
|
||||
#include "net/instaweb/util/public/md5_hasher.h"
|
||||
#include "net/instaweb/util/public/null_shared_mem.h"
|
||||
#include "net/instaweb/util/public/pthread_shared_mem.h"
|
||||
#include "net/instaweb/util/public/scheduler_thread.h"
|
||||
#include "net/instaweb/util/public/simple_stats.h"
|
||||
#include "net/instaweb/util/public/slow_worker.h"
|
||||
@@ -73,14 +71,12 @@ class Writer;
|
||||
|
||||
const char NgxRewriteDriverFactory::kMemcached[] = "memcached";
|
||||
|
||||
NgxRewriteDriverFactory::NgxRewriteDriverFactory(NgxRewriteOptions* main_conf)
|
||||
: RewriteDriverFactory(new NgxThreadSystem()),
|
||||
// TODO(oschaaf): mod_pagespeed ifdefs this:
|
||||
shared_mem_runtime_(new PthreadSharedMem()),
|
||||
cache_hasher_(20),
|
||||
main_conf_(main_conf),
|
||||
threads_started_(false),
|
||||
is_root_process_(true) {
|
||||
NgxRewriteDriverFactory::NgxRewriteDriverFactory(NgxRewriteOptions* main_conf) :
|
||||
RewriteDriverFactory(new NgxThreadSystem()),
|
||||
shared_mem_runtime_(new NullSharedMem()),
|
||||
cache_hasher_(20),
|
||||
main_conf_(main_conf),
|
||||
threads_started_(false) {
|
||||
RewriteDriverFactory::InitStats(&simple_stats_);
|
||||
SerfUrlAsyncFetcher::InitStats(&simple_stats_);
|
||||
AprMemCache::InitStats(&simple_stats_);
|
||||
@@ -96,15 +92,11 @@ NgxRewriteDriverFactory::NgxRewriteDriverFactory(NgxRewriteOptions* main_conf)
|
||||
NgxRewriteDriverFactory::~NgxRewriteDriverFactory() {
|
||||
delete timer_;
|
||||
timer_ = NULL;
|
||||
if (!is_root_process_ && slow_worker_ != NULL) {
|
||||
if (slow_worker_ != NULL) {
|
||||
slow_worker_->ShutDown();
|
||||
}
|
||||
|
||||
ShutDown();
|
||||
|
||||
CHECK(uninitialized_server_contexts_.empty() || is_root_process_);
|
||||
STLDeleteElements(&uninitialized_server_contexts_);
|
||||
|
||||
for (PathCacheMap::iterator p = path_cache_map_.begin(),
|
||||
e = path_cache_map_.end(); p != e; ++p) {
|
||||
NgxCache* cache = p->second;
|
||||
@@ -169,6 +161,10 @@ NamedLockManager* NgxRewriteDriverFactory::DefaultLockManager() {
|
||||
}
|
||||
|
||||
void NgxRewriteDriverFactory::SetupCaches(ServerContext* server_context) {
|
||||
if (slow_worker_ == NULL) {
|
||||
slow_worker_.reset(new SlowWorker(thread_system()));
|
||||
}
|
||||
|
||||
// TODO(jefftk): see the ngx_rewrite_options.h note on OriginRewriteOptions;
|
||||
// this would move to OriginRewriteOptions.
|
||||
|
||||
@@ -291,6 +287,12 @@ CacheInterface* NgxRewriteDriverFactory::GetMemcached(
|
||||
}
|
||||
memcached = batcher;
|
||||
result.first->second = memcached;
|
||||
|
||||
bool connected = mem_cache->Connect();
|
||||
if (!connected) {
|
||||
message_handler()->Message(kError, "Failed to attach memcached, abort");
|
||||
abort();
|
||||
}
|
||||
} else {
|
||||
memcached = result.first->second;
|
||||
}
|
||||
@@ -342,12 +344,6 @@ void NgxRewriteDriverFactory::StopCacheActivity() {
|
||||
}
|
||||
}
|
||||
|
||||
NgxServerContext* NgxRewriteDriverFactory::MakeNgxServerContext() {
|
||||
NgxServerContext* server_context = new NgxServerContext(this);
|
||||
uninitialized_server_contexts_.insert(server_context);
|
||||
return server_context;
|
||||
}
|
||||
|
||||
void NgxRewriteDriverFactory::ShutDown() {
|
||||
RewriteDriverFactory::ShutDown();
|
||||
|
||||
@@ -370,56 +366,4 @@ void NgxRewriteDriverFactory::StartThreads() {
|
||||
threads_started_ = true;
|
||||
}
|
||||
|
||||
void NgxRewriteDriverFactory::ParentOrChildInit() {
|
||||
// left in as a stub, we will need it later on
|
||||
}
|
||||
|
||||
void NgxRewriteDriverFactory::RootInit() {
|
||||
ParentOrChildInit();
|
||||
for (NgxServerContextSet::iterator p = uninitialized_server_contexts_.begin(),
|
||||
e = uninitialized_server_contexts_.end(); p != e; ++p) {
|
||||
NgxServerContext* server_context = *p;
|
||||
|
||||
// Determine the set of caches needed based on the unique
|
||||
// file_cache_path()s in the manager configurations. We ignore
|
||||
// the GetCache return value because our goal is just to populate
|
||||
// the map which we'll iterate on below.
|
||||
GetCache(server_context->config());
|
||||
}
|
||||
|
||||
for (PathCacheMap::iterator p = path_cache_map_.begin(),
|
||||
e = path_cache_map_.end(); p != e; ++p) {
|
||||
NgxCache* cache = p->second;
|
||||
cache->RootInit();
|
||||
}
|
||||
}
|
||||
|
||||
void NgxRewriteDriverFactory::ChildInit() {
|
||||
is_root_process_ = false;
|
||||
ParentOrChildInit();
|
||||
slow_worker_.reset(new SlowWorker(thread_system()));
|
||||
|
||||
for (PathCacheMap::iterator p = path_cache_map_.begin(),
|
||||
e = path_cache_map_.end(); p != e; ++p) {
|
||||
NgxCache* cache = p->second;
|
||||
cache->ChildInit();
|
||||
}
|
||||
for (NgxServerContextSet::iterator p = uninitialized_server_contexts_.begin(),
|
||||
e = uninitialized_server_contexts_.end(); p != e; ++p) {
|
||||
NgxServerContext* server_context = *p;
|
||||
server_context->ChildInit();
|
||||
}
|
||||
|
||||
uninitialized_server_contexts_.clear();
|
||||
|
||||
for (int i = 0, n = memcache_servers_.size(); i < n; ++i) {
|
||||
AprMemCache* mem_cache = memcache_servers_[i];
|
||||
bool connected = mem_cache->Connect();
|
||||
if (!connected) {
|
||||
message_handler()->Message(kError, "Failed to attach memcached, abort");
|
||||
abort();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace net_instaweb
|
||||
|
||||
@@ -19,8 +19,6 @@
|
||||
#ifndef NGX_REWRITE_DRIVER_FACTORY_H_
|
||||
#define NGX_REWRITE_DRIVER_FACTORY_H_
|
||||
|
||||
#include <set>
|
||||
|
||||
#include "apr_pools.h"
|
||||
#include "base/scoped_ptr.h"
|
||||
#include "net/instaweb/rewriter/public/rewrite_driver_factory.h"
|
||||
@@ -60,7 +58,7 @@ class NgxRewriteDriverFactory : public RewriteDriverFactory {
|
||||
virtual FileSystem* DefaultFileSystem();
|
||||
virtual Timer* DefaultTimer();
|
||||
virtual NamedLockManager* DefaultLockManager();
|
||||
virtual void SetupCaches(ServerContext* server_context);
|
||||
virtual void SetupCaches(ServerContext* resource_manager);
|
||||
virtual Statistics* statistics();
|
||||
// Create a new RewriteOptions. In this implementation it will be an
|
||||
// NgxRewriteOptions.
|
||||
@@ -72,12 +70,6 @@ class NgxRewriteDriverFactory : public RewriteDriverFactory {
|
||||
// release the base class resources.
|
||||
virtual void ShutDown();
|
||||
virtual void StopCacheActivity();
|
||||
NgxServerContext* MakeNgxServerContext();
|
||||
// Finds a Cache for the file_cache_path in the config. If none exists,
|
||||
// creates one, using all the other parameters in the NgxRewriteOptions.
|
||||
// Currently, no checking is done that the other parameters (e.g. cache
|
||||
// size, cleanup interval, etc.) are consistent.
|
||||
NgxCache* GetCache(NgxRewriteOptions* rewrite_options);
|
||||
|
||||
AbstractSharedMem* shared_mem_runtime() const {
|
||||
return shared_mem_runtime_.get();
|
||||
@@ -85,6 +77,12 @@ class NgxRewriteDriverFactory : public RewriteDriverFactory {
|
||||
|
||||
SlowWorker* slow_worker() { return slow_worker_.get(); }
|
||||
|
||||
// Finds a Cache for the file_cache_path in the config. If none exists,
|
||||
// creates one, using all the other parameters in the ApacheConfig.
|
||||
// Currently, no checking is done that the other parameters (e.g. cache
|
||||
// size, cleanup interval, etc.) are consistent.
|
||||
NgxCache* GetCache(NgxRewriteOptions* config);
|
||||
|
||||
// Create a new AprMemCache from the given hostname[:port] specification.
|
||||
AprMemCache* NewAprMemCache(const GoogleString& spec);
|
||||
|
||||
@@ -105,29 +103,6 @@ class NgxRewriteDriverFactory : public RewriteDriverFactory {
|
||||
// Starts pagespeed threads if they've not been started already. Must be
|
||||
// called after the caller has finished any forking it intends to do.
|
||||
void StartThreads();
|
||||
// This helper method contains init procedures invoked by both RootInit()
|
||||
// and ChildInit()
|
||||
void ParentOrChildInit();
|
||||
// For shared memory resources the general setup we follow is to have the
|
||||
// first running process (aka the root) create the necessary segments and
|
||||
// fill in their shared data structures, while processes created to actually
|
||||
// handle requests attach to already existing shared data structures.
|
||||
//
|
||||
// During normal server startup[1], RootInit() is called from the nginx hooks
|
||||
// in the root process for the first task, and then ChildInit() is called in
|
||||
// any child process.
|
||||
//
|
||||
// Keep in mind, however, that when fork() is involved a process may
|
||||
// effectively see both calls, in which case the 'ChildInit' call would
|
||||
// come second and override the previous root status. Both calls are also
|
||||
// invoked in the debug single-process mode.
|
||||
//
|
||||
// [1] Besides normal startup, nginx also uses a temporary process to
|
||||
// syntax check the config file. That basically looks like a complete
|
||||
// normal startup and shutdown to the code.
|
||||
bool is_root_process() const { return is_root_process_; }
|
||||
void RootInit();
|
||||
void ChildInit();
|
||||
|
||||
private:
|
||||
SimpleStats simple_stats_;
|
||||
@@ -138,8 +113,6 @@ class NgxRewriteDriverFactory : public RewriteDriverFactory {
|
||||
PathCacheMap path_cache_map_;
|
||||
MD5Hasher cache_hasher_;
|
||||
NgxRewriteOptions* main_conf_;
|
||||
typedef std::set<NgxServerContext*> NgxServerContextSet;
|
||||
NgxServerContextSet uninitialized_server_contexts_;
|
||||
|
||||
// memcache connections are expensive. Just allocate one per
|
||||
// distinct server-list. At the moment there is no consistency
|
||||
@@ -162,7 +135,6 @@ class NgxRewriteDriverFactory : public RewriteDriverFactory {
|
||||
std::vector<AprMemCache*> memcache_servers_;
|
||||
std::vector<AsyncCache*> async_caches_;
|
||||
bool threads_started_;
|
||||
bool is_root_process_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(NgxRewriteDriverFactory);
|
||||
};
|
||||
|
||||
@@ -18,33 +18,23 @@
|
||||
|
||||
#include "ngx_server_context.h"
|
||||
|
||||
#include "ngx_cache.h"
|
||||
#include "ngx_rewrite_options.h"
|
||||
#include "ngx_rewrite_driver_factory.h"
|
||||
#include "net/instaweb/util/public/file_system_lock_manager.h"
|
||||
|
||||
namespace net_instaweb {
|
||||
|
||||
NgxServerContext::NgxServerContext(NgxRewriteDriverFactory* factory)
|
||||
: ServerContext(factory),
|
||||
ngx_factory_(factory),
|
||||
initialized_(false) {
|
||||
NgxServerContext::NgxServerContext(NgxRewriteDriverFactory* factory) :
|
||||
ServerContext(factory),
|
||||
ngx_factory_(factory) {
|
||||
}
|
||||
|
||||
NgxServerContext::~NgxServerContext() {
|
||||
delete lock_manager();
|
||||
}
|
||||
|
||||
NgxRewriteOptions* NgxServerContext::config() {
|
||||
return NgxRewriteOptions::DynamicCast(global_options());
|
||||
}
|
||||
|
||||
void NgxServerContext::ChildInit() {
|
||||
DCHECK(!initialized_);
|
||||
if (!initialized_) {
|
||||
initialized_ = true;
|
||||
NgxCache* cache = ngx_factory_->GetCache(config());
|
||||
set_lock_manager(cache->lock_manager());
|
||||
ngx_factory_->InitServerContext(this);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace net_instaweb
|
||||
|
||||
@@ -37,12 +37,9 @@ class NgxServerContext : public ServerContext {
|
||||
// nginx-specific behavior, call global_options() instead which doesn't
|
||||
// downcast.
|
||||
NgxRewriteOptions* config();
|
||||
// Should be called after the child process is forked.
|
||||
void ChildInit();
|
||||
bool initialized() const { return initialized_; }
|
||||
|
||||
private:
|
||||
NgxRewriteDriverFactory* ngx_factory_;
|
||||
bool initialized_;
|
||||
DISALLOW_COPY_AND_ASSIGN(NgxServerContext);
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user