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:
Jeff Kaufman
2013-01-29 18:12:07 -05:00
parent d0464e8982
commit be9a78b18a
7 changed files with 63 additions and 194 deletions
+3 -23
View File
@@ -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
+1
View File
@@ -50,6 +50,7 @@ class NgxCache {
void RootInit();
void ChildInit();
void GlobalCleanup(MessageHandler* handler); // only called in root process
private:
void FallBackToFileBasedLocking();
+29 -44
View File
@@ -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,
+17 -73
View File
@@ -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
+7 -35
View File
@@ -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);
};
+5 -15
View File
@@ -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
+1 -4
View File
@@ -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);
};