You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@httpd.apache.org by ji...@apache.org on 2014/05/01 13:43:45 UTC
svn commit: r1591622 [23/33] - in /httpd/mod_spdy/trunk: ./ base/
base/base.xcodeproj/ base/metrics/ build/ build/all.xcodeproj/
build/build_util.xcodeproj/ build/install.xcodeproj/ build/internal/
build/linux/ build/mac/ build/util/ build/win/ install...
Added: httpd/mod_spdy/trunk/net/instaweb/util/public/pthread_shared_mem.h
URL: http://svn.apache.org/viewvc/httpd/mod_spdy/trunk/net/instaweb/util/public/pthread_shared_mem.h?rev=1591622&view=auto
==============================================================================
--- httpd/mod_spdy/trunk/net/instaweb/util/public/pthread_shared_mem.h (added)
+++ httpd/mod_spdy/trunk/net/instaweb/util/public/pthread_shared_mem.h Thu May 1 11:43:36 2014
@@ -0,0 +1,71 @@
+// Copyright 2011 Google Inc.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+// Author: morlovich@google.com (Maksim Orlovich)
+
+#ifndef NET_INSTAWEB_UTIL_PUBLIC_PTHREAD_SHARED_MEM_H_
+#define NET_INSTAWEB_UTIL_PUBLIC_PTHREAD_SHARED_MEM_H_
+
+#include <cstddef>
+#include <map>
+
+#include "net/instaweb/util/public/abstract_shared_mem.h"
+#include "net/instaweb/util/public/basictypes.h"
+#include "net/instaweb/util/public/string.h"
+
+namespace net_instaweb {
+class MessageHandler;
+
+// POSIX shared memory support, using mmap/pthread_mutexattr_setpshared
+// Supports both processes and threads, but processes that want to access it
+// must be results of just fork (without exec), and all the CreateSegment
+// calls must occur before the fork.
+//
+// This implementation is also not capable of deallocating segments except
+// at exit, so it should not be used when the set of segments may be dynamic.
+class PthreadSharedMem : public AbstractSharedMem {
+ public:
+ PthreadSharedMem();
+ virtual ~PthreadSharedMem();
+
+ virtual size_t SharedMutexSize() const;
+
+ virtual AbstractSharedMemSegment* CreateSegment(
+ const GoogleString& name, size_t size, MessageHandler* handler);
+
+ virtual AbstractSharedMemSegment* AttachToSegment(
+ const GoogleString& name, size_t size, MessageHandler* handler);
+
+ virtual void DestroySegment(const GoogleString& name,
+ MessageHandler* handler);
+
+ private:
+ typedef std::map<GoogleString, char*> SegmentBaseMap;
+
+ // Accessor for below. Note that the segment_bases_lock will be held at exit.
+ static SegmentBaseMap* AcquireSegmentBases();
+
+ static void UnlockSegmentBases();
+
+ // The root process stores segment locations here. Child processes will
+ // inherit a readonly copy of this map after the fork. Note that this is
+ // initialized in a thread-unsafe manner, given the above assumptions.
+ static SegmentBaseMap* segment_bases_;
+
+ DISALLOW_COPY_AND_ASSIGN(PthreadSharedMem);
+};
+
+} // namespace net_instaweb
+
+#endif // NET_INSTAWEB_UTIL_PUBLIC_PTHREAD_SHARED_MEM_H_
Propchange: httpd/mod_spdy/trunk/net/instaweb/util/public/pthread_shared_mem.h
------------------------------------------------------------------------------
svn:eol-style = native
Added: httpd/mod_spdy/trunk/net/instaweb/util/public/pthread_thread_system.h
URL: http://svn.apache.org/viewvc/httpd/mod_spdy/trunk/net/instaweb/util/public/pthread_thread_system.h?rev=1591622&view=auto
==============================================================================
--- httpd/mod_spdy/trunk/net/instaweb/util/public/pthread_thread_system.h (added)
+++ httpd/mod_spdy/trunk/net/instaweb/util/public/pthread_thread_system.h Thu May 1 11:43:36 2014
@@ -0,0 +1,53 @@
+/*
+ * Copyright 2011 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// Author: morlovich@google.com (Maksim Orlovich)
+//
+// Implementation of thread-creation for pthreads
+
+#ifndef NET_INSTAWEB_UTIL_PUBLIC_PTHREAD_THREAD_SYSTEM_H_
+#define NET_INSTAWEB_UTIL_PUBLIC_PTHREAD_THREAD_SYSTEM_H_
+
+#include "net/instaweb/util/public/basictypes.h"
+#include "net/instaweb/util/public/thread_system.h"
+
+namespace net_instaweb {
+
+class PthreadThreadSystem : public ThreadSystem {
+ public:
+ PthreadThreadSystem();
+ virtual ~PthreadThreadSystem();
+
+ virtual CondvarCapableMutex* NewMutex();
+
+ virtual RWLock* NewRWLock();
+
+ protected:
+ // This hook will get invoked by the implementation in the context of a
+ // thread before invoking its Run() method.
+ virtual void BeforeThreadRunHook();
+
+ private:
+ friend class PthreadThreadImpl;
+
+ virtual ThreadImpl* NewThreadImpl(Thread* wrapper, ThreadFlags flags);
+
+ DISALLOW_COPY_AND_ASSIGN(PthreadThreadSystem);
+};
+
+} // namespace net_instaweb
+
+#endif // NET_INSTAWEB_UTIL_PUBLIC_PTHREAD_THREAD_SYSTEM_H_
Propchange: httpd/mod_spdy/trunk/net/instaweb/util/public/pthread_thread_system.h
------------------------------------------------------------------------------
svn:eol-style = native
Added: httpd/mod_spdy/trunk/net/instaweb/util/public/query_params.h
URL: http://svn.apache.org/viewvc/httpd/mod_spdy/trunk/net/instaweb/util/public/query_params.h?rev=1591622&view=auto
==============================================================================
--- httpd/mod_spdy/trunk/net/instaweb/util/public/query_params.h (added)
+++ httpd/mod_spdy/trunk/net/instaweb/util/public/query_params.h Thu May 1 11:43:36 2014
@@ -0,0 +1,51 @@
+// Copyright 2010-2011 Google Inc.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+// Author: jmarantz@google.com (Joshua Marantz)
+
+#ifndef NET_INSTAWEB_UTIL_PUBLIC_QUERY_PARAMS_H_
+#define NET_INSTAWEB_UTIL_PUBLIC_QUERY_PARAMS_H_
+
+#include "net/instaweb/util/public/string_multi_map.h"
+
+#include "net/instaweb/util/public/basictypes.h"
+#include "net/instaweb/util/public/string.h"
+#include "net/instaweb/util/public/string_util.h"
+
+namespace net_instaweb {
+
+// Parses and rewrites URL query parameters.
+class QueryParams : public StringMultiMapSensitive {
+ public:
+ QueryParams() { }
+
+ // Parse a query param string, e.g. x=0&y=1&z=2. We expect the "?"
+ // to be extracted (e.g. this string is the output of GURL::query().
+ //
+ // Note that the value can be NULL, indicating that the variables
+ // was not followed by a '='. So given "a=0&b&c=", the values will
+ // be {"0", NULL, ""}.
+ void Parse(const StringPiece& query_string);
+
+ GoogleString ToString() const;
+
+ int size() const { return num_values(); }
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(QueryParams);
+};
+
+} // namespace net_instaweb
+
+#endif // NET_INSTAWEB_UTIL_PUBLIC_QUERY_PARAMS_H_
Propchange: httpd/mod_spdy/trunk/net/instaweb/util/public/query_params.h
------------------------------------------------------------------------------
svn:eol-style = native
Added: httpd/mod_spdy/trunk/net/instaweb/util/public/queued_alarm.h
URL: http://svn.apache.org/viewvc/httpd/mod_spdy/trunk/net/instaweb/util/public/queued_alarm.h?rev=1591622&view=auto
==============================================================================
--- httpd/mod_spdy/trunk/net/instaweb/util/public/queued_alarm.h (added)
+++ httpd/mod_spdy/trunk/net/instaweb/util/public/queued_alarm.h Thu May 1 11:43:36 2014
@@ -0,0 +1,86 @@
+// Copyright 2011 Google Inc.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+// Author: morlovich@google.com (Maksim Orlovich)
+
+#ifndef NET_INSTAWEB_UTIL_PUBLIC_QUEUED_ALARM_H_
+#define NET_INSTAWEB_UTIL_PUBLIC_QUEUED_ALARM_H_
+
+#include "base/scoped_ptr.h"
+#include "net/instaweb/util/public/basictypes.h"
+#include "net/instaweb/util/public/function.h"
+#include "net/instaweb/util/public/queued_worker_pool.h"
+#include "net/instaweb/util/public/scheduler.h"
+
+namespace net_instaweb {
+
+class AbstractMutex;
+
+// A helper for managing alarms that need to both run in a sequence and be
+// cancellable (in the CancelAlarm sense) safely; note that
+// QueuedWorkerPool::Sequence::AddFunction does not provide alarm awareness.
+class QueuedAlarm : public Function {
+ public:
+ // Schedules a function to run at a given time in a given sequence.
+ // (Note that the function's invocation may be delayed by other work
+ // present in the sequence at time of alarm going off).
+ //
+ // This constructor must be invoked from that sequence as well.
+ //
+ // The object will be destroyed automatically when either the callback
+ // is invoked or the cancellation is complete. You should not free the
+ // sequence until one of these points is reached.
+ QueuedAlarm(Scheduler* scheduler,
+ QueuedWorkerPool::Sequence* sequence,
+ int64 wakeup_time_us,
+ Function* callback);
+
+ // Cancels the alarm. This method must be run from the sequence given to the
+ // constructor; and should not be called when the callback has already been
+ // invoked. It is suggested that as both invocations of CancelAlarm and
+ // the callback are deallocation points that you defensively clear any
+ // pointers to the QueuedAlarm object when they occur.
+ //
+ // The function's Cancel method will be invoked; but no guarantee is made
+ // as to when or in what thread context. The class does guarantee, however,
+ // that it will not access the sequence_ once CancelAlarm() completes.
+ void CancelAlarm();
+
+ private:
+ virtual ~QueuedAlarm();
+
+ // Runs in an arbitrary thread.
+ virtual void Run();
+
+ // Runs in the sequence case.
+ void SequencePortionOfRun();
+
+ // This can get invoked if our client freed the sequence upon calling
+ // CancelAlarm, in the case where what normally would be SequencePortionOfRun
+ // is already on the queue.
+ void SequencePortionOfRunCancelled();
+
+ scoped_ptr<AbstractMutex> mutex_;
+ Scheduler* scheduler_;
+ QueuedWorkerPool::Sequence* sequence_;
+ Function* callback_;
+ Scheduler::Alarm* alarm_;
+
+ bool canceled_;
+ bool queued_sequence_portion_;
+};
+
+} // namespace net_instaweb
+
+#endif // NET_INSTAWEB_UTIL_PUBLIC_QUEUED_ALARM_H_
Propchange: httpd/mod_spdy/trunk/net/instaweb/util/public/queued_alarm.h
------------------------------------------------------------------------------
svn:eol-style = native
Added: httpd/mod_spdy/trunk/net/instaweb/util/public/queued_worker.h
URL: http://svn.apache.org/viewvc/httpd/mod_spdy/trunk/net/instaweb/util/public/queued_worker.h?rev=1591622&view=auto
==============================================================================
--- httpd/mod_spdy/trunk/net/instaweb/util/public/queued_worker.h (added)
+++ httpd/mod_spdy/trunk/net/instaweb/util/public/queued_worker.h Thu May 1 11:43:36 2014
@@ -0,0 +1,63 @@
+/*
+ * Copyright 2011 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// Author: morlovich@google.com (Maksim Orlovich)
+//
+// This contains QueuedWorker, which runs tasks in a background thread
+// in FIFO order.
+
+#ifndef NET_INSTAWEB_UTIL_PUBLIC_QUEUED_WORKER_H_
+#define NET_INSTAWEB_UTIL_PUBLIC_QUEUED_WORKER_H_
+
+#include "net/instaweb/util/public/basictypes.h"
+#include "net/instaweb/util/public/thread_system.h"
+#include "net/instaweb/util/public/worker.h"
+
+namespace net_instaweb {
+
+class Function;
+
+// See file comment.
+class QueuedWorker : public Worker {
+ public:
+ // Initializes the worker. You still need to call ->Start to actually
+ // start the thread, however. (Note: start can return false on failure).
+ explicit QueuedWorker(ThreadSystem* runtime);
+
+ // This waits for the running task to terminate.
+ virtual ~QueuedWorker();
+
+ // Runs the given closure in the work thread. Not that it's possible for the
+ // closure to be deleted without running in case where the system is shutting
+ // down.
+ //
+ // Takes ownership of the closure.
+ void RunInWorkThread(Function* closure);
+
+ // Issue a TimedWait on the specified condition variable. In a mock-time
+ // world, this queues a time-advancement closure on the worker, and then
+ // blocks waiting for the work-queue to be drained.
+ void TimedWait(ThreadSystem::Condvar* condvar, int64 timeout_ms);
+
+ private:
+ virtual bool IsPermitted(Function* closure);
+
+ DISALLOW_COPY_AND_ASSIGN(QueuedWorker);
+};
+
+} // namespace net_instaweb
+
+#endif // NET_INSTAWEB_UTIL_PUBLIC_QUEUED_WORKER_H_
Propchange: httpd/mod_spdy/trunk/net/instaweb/util/public/queued_worker.h
------------------------------------------------------------------------------
svn:eol-style = native
Added: httpd/mod_spdy/trunk/net/instaweb/util/public/queued_worker_pool.h
URL: http://svn.apache.org/viewvc/httpd/mod_spdy/trunk/net/instaweb/util/public/queued_worker_pool.h?rev=1591622&view=auto
==============================================================================
--- httpd/mod_spdy/trunk/net/instaweb/util/public/queued_worker_pool.h (added)
+++ httpd/mod_spdy/trunk/net/instaweb/util/public/queued_worker_pool.h Thu May 1 11:43:36 2014
@@ -0,0 +1,206 @@
+/*
+ * Copyright 2011 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// Author: jmarantz@google.com (Joshua Marantz)
+//
+// implements a simple worker pool, allowing arbitrary functions to run
+// using a pool of threads of predefined maximum size.
+//
+// This differs from QueuedWorker, which always uses exactly one thread.
+// In this interface, any task can be assigned to any thread.
+
+#ifndef NET_INSTAWEB_UTIL_PUBLIC_QUEUED_WORKER_POOL_H_
+#define NET_INSTAWEB_UTIL_PUBLIC_QUEUED_WORKER_POOL_H_
+
+#include <cstddef> // for size_t
+#include <deque>
+#include <set>
+#include <vector>
+
+#include "base/scoped_ptr.h"
+#include "net/instaweb/util/public/basictypes.h"
+#include "net/instaweb/util/public/function.h"
+#include "net/instaweb/util/public/thread_system.h"
+
+namespace net_instaweb {
+
+class AbstractMutex;
+class QueuedWorker;
+class Waveform;
+
+// Maintains a predefined number of worker threads, and dispatches any
+// number of groups of sequential tasks to those threads.
+class QueuedWorkerPool {
+ public:
+ QueuedWorkerPool(int max_workers, ThreadSystem* thread_system);
+ ~QueuedWorkerPool();
+
+ // Functions added to a Sequence will be run sequentially, though not
+ // necessarily always from the same worker thread. The scheduler will
+ // continue to schedule new work added to the sequence until
+ // FreeSequence is called.
+ class Sequence {
+ public:
+ // AddFunction is a callback that when invoked queues another callback on
+ // the given sequence, and when canceled queues a cancel call to the
+ // sequence instead. The cancellation behavior is what makes this different
+ // from a simple call to MakeFunction(sequence, &Sequence::Add, callback).
+ class AddFunction : public Function {
+ public:
+ AddFunction(Sequence* sequence, Function* callback)
+ : sequence_(sequence), callback_(callback) { }
+ virtual ~AddFunction();
+
+ protected:
+ virtual void Run() {
+ sequence_->Add(callback_);
+ }
+ virtual void Cancel() {
+ sequence_->Add(MakeFunction(callback_, &Function::CallCancel));
+ }
+
+ private:
+ Sequence* sequence_;
+ Function* callback_;
+ DISALLOW_COPY_AND_ASSIGN(AddFunction);
+ };
+
+ // Adds 'function' to a sequence. Note that this can occur at any time
+ // the sequence is live -- you can add functions to a sequence that has
+ // already started processing.
+ //
+ // 'function' can be called any time after Add(), and may in fact be
+ // called before Add() returns.
+ //
+ // Ownership of 'function' is transferred to the Sequence, which deletes
+ // it after execution or upon cancellation due to shutdown.
+ void Add(Function* function);
+
+ void set_queue_size_stat(Waveform* x) { queue_size_ = x; }
+
+ private:
+ // Construct using QueuedWorkerPool::NewSequence().
+ Sequence(ThreadSystem* thread_system, QueuedWorkerPool* pool);
+
+ // Free by calling QueuedWorkerPool::FreeSequence().
+ ~Sequence();
+
+ // Resets a new or recycled Sequence to its original state.
+ void Reset();
+
+ // Waits for any currently active function to complete, deletes
+ // any other outstanding functions. During the shutdown process,
+ // the Sequence will simply delete, without running, any function
+ // added to it from another thread.
+ //
+ // This function blocks until shutdown is complete.
+ void WaitForShutDown();
+
+ // Puts the Sequence in shutdown mode, but does not block until shutdown
+ // is complete. Return 'true' if the sequence is inactive and thus can
+ // be immediately recycled.
+ bool InitiateShutDown();
+
+ // Gets the next function in the sequence, and transfers ownership
+ // the the caller.
+ Function* NextFunction();
+
+ // Assumes sequence_mutex_ held
+ bool IsBusy();
+
+ // Assumes sequence_mutex_ held. Returns number of tasks that were canceled.
+ int CancelTasksOnWorkQueue();
+
+ friend class QueuedWorkerPool;
+ std::deque<Function*> work_queue_;
+ scoped_ptr<ThreadSystem::CondvarCapableMutex> sequence_mutex_;
+ QueuedWorkerPool* pool_;
+ bool shutdown_;
+ bool active_;
+ scoped_ptr<ThreadSystem::Condvar> termination_condvar_;
+ Waveform* queue_size_;
+
+ DISALLOW_COPY_AND_ASSIGN(Sequence);
+ };
+
+ typedef std::set<Sequence*> SequenceSet;
+
+ // Sequence is owned by the pool, and will be automatically freed when
+ // the pool is finally freed (e.g. on server shutdown). But the sequence
+ // does *not* auto-destruct when complete; it must be explicitly freed
+ // using FreeSequence().
+ Sequence* NewSequence(); // Returns NULL if shutting down.
+
+ // Shuts down a sequence and frees it. This does *not* block waiting
+ // for the Sequence to finish.
+ void FreeSequence(Sequence* sequence);
+
+ // Shuts down all Sequences and Worker threads, but does not delete the
+ // sequences. The sequences will be deleted when the pool is destructed.
+ void ShutDown();
+
+ // Returns true if any of the given sequences is busy. Note that multiple
+ // sequences are checked atomically; otherwise we could end up missing
+ // work. For example, consider if we had a sequence for main rewrite work,
+ // and an another one for expensive work.
+ // In this case, if we tried to check their busyness independently, the
+ // following could happen:
+ // 1) First portion of inexpensive work is done, so we queue up
+ // some on expensive work thread.
+ // 2) We check whether inexpensive work sequence is busy. It's not.
+ // 3) The expensive work runs, finishes, and queues up more inexpensive
+ // work.
+ // 4) We check whether expensive sequence is busy. It's not, so we would
+ // conclude we quiesced --- while there was still work in the inexpensive
+ // queue.
+ static bool AreBusy(const SequenceSet& sequences);
+
+ // Sets up a timed-variable statistic indicating the current queue depth.
+ //
+ // This must be called prior to creating sequences.
+ void set_queue_size_stat(Waveform* x) { queue_size_ = x; }
+
+ private:
+ friend class Sequence;
+ void Run(Sequence* sequence, QueuedWorker* worker);
+ void QueueSequence(Sequence* sequence);
+ Sequence* AssignWorkerToNextSequence(QueuedWorker* worker);
+ void SequenceNoLongerActive(Sequence* sequence);
+
+ ThreadSystem* thread_system_;
+ scoped_ptr<AbstractMutex> mutex_;
+
+ // active_workers_ and available_workers_ are mutually exclusive.
+ std::set<QueuedWorker*> active_workers_;
+ std::vector<QueuedWorker*> available_workers_;
+
+ // queued_sequences_ and free_sequences_ are mutually exclusive, but
+ // all_sequences contains all of them.
+ std::vector<Sequence*> all_sequences_;
+ std::deque<Sequence*> queued_sequences_;
+ std::vector<Sequence*> free_sequences_;
+
+ size_t max_workers_;
+ bool shutdown_;
+
+ Waveform* queue_size_;
+
+ DISALLOW_COPY_AND_ASSIGN(QueuedWorkerPool);
+};
+
+} // namespace net_instaweb
+
+#endif // NET_INSTAWEB_UTIL_PUBLIC_QUEUED_WORKER_POOL_H_
Propchange: httpd/mod_spdy/trunk/net/instaweb/util/public/queued_worker_pool.h
------------------------------------------------------------------------------
svn:eol-style = native
Added: httpd/mod_spdy/trunk/net/instaweb/util/public/ref_counted_owner.h
URL: http://svn.apache.org/viewvc/httpd/mod_spdy/trunk/net/instaweb/util/public/ref_counted_owner.h?rev=1591622&view=auto
==============================================================================
--- httpd/mod_spdy/trunk/net/instaweb/util/public/ref_counted_owner.h (added)
+++ httpd/mod_spdy/trunk/net/instaweb/util/public/ref_counted_owner.h Thu May 1 11:43:36 2014
@@ -0,0 +1,131 @@
+/*
+ * Copyright 2011 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// Author: morlovich@google.com (Maksim Orlovich)
+//
+// A RefCountedOwner<T> helps a family of objects manage lifetime of a single
+// shared T, initializing it with the first owner, and getting rid of it
+// when all the owners are gone. This is different from a singleton in that
+// there is no limit to having only a single instance of T, but rather
+// a single T instance per a single RefCountedOwner<T>::Family instance.
+//
+// Warning: this class doesn't provide for full thread safety; as it assumes
+// that all the owners will be created and destroyed in a single thread.
+// The accessors, however, are readonly, so can be used from multiple threads
+// if their use follows the sequential initialization and precedes object
+// destruction.
+//
+// Typical usage:
+// class OwnerClass {
+// static RefCountedOwner<SharedClass>::Family shared_family_;
+// RefCountedOwner<SharedClass> shared_;
+// };
+//
+// OwnerClass::OwnerClass() : shared_(&shared_family_) {
+// if (shared_.ShouldInitialize()) {
+// shared_->Initialize(new SharedClass(...));
+// }
+// }
+//
+
+
+#ifndef NET_INSTAWEB_UTIL_PUBLIC_REF_COUNTED_OWNER_H_
+#define NET_INSTAWEB_UTIL_PUBLIC_REF_COUNTED_OWNER_H_
+
+#include "base/logging.h"
+#include "net/instaweb/util/public/basictypes.h"
+
+// See file comment.
+template<typename T>
+class RefCountedOwner {
+ public:
+ class Family {
+ public:
+ Family() : ptr_(NULL), ref_count_(0) {}
+
+ private:
+ friend class RefCountedOwner<T>;
+ T* ptr_;
+ int ref_count_;
+ DISALLOW_COPY_AND_ASSIGN(Family);
+ };
+
+ // Instances of RefCountedOwner that share the same 'family' object will
+ // share an instance of T.
+ explicit RefCountedOwner(Family* family)
+ : family_(family),
+ attached_(false) {}
+
+ ~RefCountedOwner() {
+ if (attached_) {
+ --family_->ref_count_;
+ if (family_->ref_count_ == 0) {
+ delete family_->ptr_;
+ family_->ptr_ = NULL;
+ }
+ }
+ }
+
+ // If an another member of the family has already created the managed
+ // object, Attach() will return true and attach 'this' to it, making the
+ // object accessible via get() and pointer operations.
+ //
+ // Otherwise, it returns false, and you should call Initialize() to
+ // set the object.
+ bool Attach() {
+ if (attached_) {
+ return true; // we are already attached, no need to initialize.
+ } else if (family_->ref_count_ != 0) {
+ // Someone already made an instance
+ attached_ = true;
+ ++family_->ref_count_;
+ return true;
+ } else {
+ // If need to create it.
+ return false;
+ }
+ }
+
+ // Sets the value of the object our family will share. Pre-condition:
+ // one must not have been set already (in other words, this must only be
+ // called if Attach() returned false).
+ void Initialize(T* value) {
+ CHECK(!attached_ && family_->ref_count_ == 0);
+ attached_ = true;
+ family_->ref_count_ = 1;
+ family_->ptr_ = value;
+ }
+
+ // Note that you must call Attach() (and Initialize() if it
+ // returned false) before using these.
+ T* Get() {
+ DCHECK(attached_);
+ return family_->ptr_;
+ }
+
+ const T* Get() const {
+ DCHECK(attached_);
+ return family_->ptr_;
+ }
+
+ private:
+ friend class Family;
+ Family* family_;
+ bool attached_; // whether we've grabbed a reference to the data.
+ DISALLOW_COPY_AND_ASSIGN(RefCountedOwner);
+};
+
+#endif // NET_INSTAWEB_UTIL_PUBLIC_REF_COUNTED_OWNER_H_
Propchange: httpd/mod_spdy/trunk/net/instaweb/util/public/ref_counted_owner.h
------------------------------------------------------------------------------
svn:eol-style = native
Added: httpd/mod_spdy/trunk/net/instaweb/util/public/ref_counted_ptr.h
URL: http://svn.apache.org/viewvc/httpd/mod_spdy/trunk/net/instaweb/util/public/ref_counted_ptr.h?rev=1591622&view=auto
==============================================================================
--- httpd/mod_spdy/trunk/net/instaweb/util/public/ref_counted_ptr.h (added)
+++ httpd/mod_spdy/trunk/net/instaweb/util/public/ref_counted_ptr.h Thu May 1 11:43:36 2014
@@ -0,0 +1,142 @@
+/*
+ * Copyright 2010 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// Author: jmarantz@google.com (Joshua Marantz)
+//
+// Implements a generic ref-counted class, with full sharing. This
+// class does *not* implement copy-on-write semantics, but it provides
+// 'unique()', which helps implement COW at a higher level.
+//
+// There are two pointer templates here:
+// - RefCountedPtr<T> --- requires T to inherit off RefCounted<T>,
+// stores it by pointer to supports full polymorphism.
+// - RefCountedObj<T> --- no requirements on T besides default and copy
+// construction, but stores T by value so it must always store exactly T.
+//
+// TODO(jmaessen): explore adding C++x0 shared_ptr support
+
+#ifndef NET_INSTAWEB_UTIL_PUBLIC_REF_COUNTED_PTR_H_
+#define NET_INSTAWEB_UTIL_PUBLIC_REF_COUNTED_PTR_H_
+
+#include "net/instaweb/util/public/basictypes.h"
+
+#include "base/memory/ref_counted.h"
+
+namespace net_instaweb {
+
+
+template<class T>
+class RefCounted : public base::RefCountedThreadSafe<T> {
+};
+
+// Template class to help make reference-counted pointers. You can use
+// a typedef or subclass RefCountedPtr<YourClass>. YourClass has to inherit
+// off RefCounted<T>.
+template<class T>
+class RefCountedPtr : public scoped_refptr<T> {
+ public:
+ RefCountedPtr() : scoped_refptr<T>(NULL) {}
+ explicit RefCountedPtr(T* t) : scoped_refptr<T>(t) {}
+
+ template<class U>
+ explicit RefCountedPtr(const RefCountedPtr<U>& src)
+ : scoped_refptr<T>(src) {
+ }
+
+ // Determines whether any other RefCountedPtr objects share the same
+ // storage. This can be used to create copy-on-write semantics if
+ // desired.
+ bool unique() const { return !this->ptr_ || this->ptr_->HasOneRef(); }
+
+ void clear() {
+ *this = RefCountedPtr();
+ }
+ void reset(T* ptr) {
+ *this = RefCountedPtr(ptr);
+ }
+ void reset(const RefCountedPtr& src) {
+ *this = src;
+ }
+
+ private:
+ operator void*() const; // don't compare directly to NULL; use get()
+ operator T*() const; // don't assign directly to pointer; use get()
+
+ // Note that copy and assign of RefCountedPtr is allowed -- that
+ // is how the reference counts are updated.
+};
+
+// If you can't inherit off RefCounted due to using a pre-existing
+// class, you can use RefCountedObj instead. This however is limited to
+// having a single type (so no polymorphism). It also has slightly
+// different semantics in that it initializes to a default-constructed object
+// and not NULL.
+template<class T>
+class RefCountedObj {
+ public:
+ RefCountedObj() : data_ptr_(new Data()) {}
+ explicit RefCountedObj(const T& val) : data_ptr_(new Data(val)) {}
+
+ // Determines whether any other RefCountedObj objects share the same
+ // storage. This can be used to create copy-on-write semantics if
+ // desired.
+ bool unique() const { return data_ptr_.unique(); }
+
+ T* get() { return &data_ptr_->value; }
+ const T* get() const { return &data_ptr_->value; }
+ T* operator->() { return &data_ptr_->value; }
+ const T* operator->() const { return &data_ptr_->value; }
+ T& operator*() { return data_ptr_->value; }
+ const T& operator*() const { return data_ptr_->value; }
+
+ protected:
+ struct Data : public RefCounted<Data> {
+ Data() {}
+ explicit Data(const T& val) : value(val) {}
+ T value;
+ };
+
+ RefCountedPtr<Data> data_ptr_;
+
+ private:
+ operator void*() const; // don't compare directly to NULL; use get()
+ operator T*() const; // don't assign directly to pointer; use get()
+
+ // Copying, etc., are OK thanks to data_ptr_.
+};
+
+// Helper macro to allow declaration of user-visible macro
+// REFCOUNT_DISALLOW_EXPLICIT_DESTROY which is used to generate
+// compile-time errors for code that deletes ref-counted objects
+// explicitly.
+#define REFCOUNT_SHARED_MEM_IMPL_CLASS base::RefCountedThreadSafe
+
+
+// Macro for users implementing C++ ref-counted classes to prevent
+// explicit destruction. Once a class is reference counted, it
+// should never be stack-allocated or explicitly deleted. It should
+// only be deleted by the reference count object. Put this declaration
+// in the 'protected:' or 'private:' section, and group it with
+// a destructor declaration.
+//
+// This is only required for RefCountedPtr<T>, not RefCountedObj<T>.
+//
+#define REFCOUNT_FRIEND_DECLARATION(class_name) \
+ friend class REFCOUNT_SHARED_MEM_IMPL_CLASS<class_name>
+
+} // namespace net_instaweb
+
+#endif // NET_INSTAWEB_UTIL_PUBLIC_REF_COUNTED_PTR_H_
Propchange: httpd/mod_spdy/trunk/net/instaweb/util/public/ref_counted_ptr.h
------------------------------------------------------------------------------
svn:eol-style = native
Added: httpd/mod_spdy/trunk/net/instaweb/util/public/rolling_hash.h
URL: http://svn.apache.org/viewvc/httpd/mod_spdy/trunk/net/instaweb/util/public/rolling_hash.h?rev=1591622&view=auto
==============================================================================
--- httpd/mod_spdy/trunk/net/instaweb/util/public/rolling_hash.h (added)
+++ httpd/mod_spdy/trunk/net/instaweb/util/public/rolling_hash.h Thu May 1 11:43:36 2014
@@ -0,0 +1,70 @@
+/*
+ * Copyright 2010 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+// Author: jmaessen@google.com (Jan Maessen)
+
+#ifndef NET_INSTAWEB_UTIL_PUBLIC_ROLLING_HASH_H_
+#define NET_INSTAWEB_UTIL_PUBLIC_ROLLING_HASH_H_
+
+#include <cstddef>
+#include "base/logging.h"
+#include "net/instaweb/util/public/basictypes.h"
+
+namespace net_instaweb {
+
+// Rolling hash for char buffers based on a polynomial lookup table.
+// See http://en.wikipedia.org/wiki/Rolling_hash
+
+// Per character hash values. Exported for use in NextRollingHash.
+extern const uint64 kRollingHashCharTable[256];
+
+// Compute the rolling hash of buf[start : start + n - 1]
+uint64 RollingHash(const char* buf, size_t start, size_t n);
+
+// Given the rolling hash prev of buf[start - 1 : start + n - 2], efficiently
+// compute the hash of buf[start : start + n - 1]. Note that this indexes
+// buf[start - 1], so we can't just use a StringPiece here. We eschew
+// StringPiece in any case, because of efficiency.
+//
+// Note that to get efficient operation here for fixed n (eg when we're doing
+// something like Rabin-Karp string matching), we must inline the computation of
+// shift amounts and then hoist them as loop invariants. That is why this
+// function (intended for use in an inner loop) is inlined.
+inline uint64 NextRollingHash(
+ const char* buf, size_t start, size_t n, uint64 prev) {
+ // In a reasonable loop, the following two tests should be eliminated based on
+ // contextual information, if our compiler is optimizing enough.
+ CHECK_LT(static_cast<size_t>(0), start);
+ uint64 start_hash =
+ kRollingHashCharTable[static_cast<uint8>(buf[start - 1])];
+ uint64 end_hash =
+ kRollingHashCharTable[static_cast<uint8>(buf[start - 1 + n])];
+ uint64 prev_rot1 = (prev << 1) | (prev >> 63); // rotate left 1
+ uint64 start_hash_rotn;
+ // Corner case: shift by >= 64 bits is not defined in C. gcc had better
+ // constant-fold this to a rotate! (It appears to.) We inline in large part
+ // to ensure the truthiness of this fact.
+ size_t shift = n % 64;
+ if (shift == 0) {
+ start_hash_rotn = start_hash;
+ } else {
+ // rotate left by shift (equiv to rotating left n times).
+ start_hash_rotn = (start_hash << shift) | (start_hash >> (64 - shift));
+ }
+ return (start_hash_rotn ^ prev_rot1 ^ end_hash);
+}
+} // net_instaweb
+
+#endif // NET_INSTAWEB_UTIL_PUBLIC_ROLLING_HASH_H_
Propchange: httpd/mod_spdy/trunk/net/instaweb/util/public/rolling_hash.h
------------------------------------------------------------------------------
svn:eol-style = native
Added: httpd/mod_spdy/trunk/net/instaweb/util/public/scheduler.h
URL: http://svn.apache.org/viewvc/httpd/mod_spdy/trunk/net/instaweb/util/public/scheduler.h?rev=1591622&view=auto
==============================================================================
--- httpd/mod_spdy/trunk/net/instaweb/util/public/scheduler.h (added)
+++ httpd/mod_spdy/trunk/net/instaweb/util/public/scheduler.h Thu May 1 11:43:36 2014
@@ -0,0 +1,193 @@
+// Copyright 2011 Google Inc.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+// Author: jmarantz@google.com (Joshua Marantz)
+
+#ifndef NET_INSTAWEB_UTIL_PUBLIC_SCHEDULER_H_
+#define NET_INSTAWEB_UTIL_PUBLIC_SCHEDULER_H_
+
+#include <set>
+
+#include "base/scoped_ptr.h"
+#include "net/instaweb/util/public/atomic_bool.h"
+#include "net/instaweb/util/public/basictypes.h"
+#include "net/instaweb/util/public/function.h"
+#include "net/instaweb/util/public/queued_worker_pool.h"
+#include "net/instaweb/util/public/thread_system.h"
+
+namespace net_instaweb {
+
+class Timer;
+
+// Implements a simple scheduler that allows a thread to block until either time
+// expires, or a condition variable is signaled. Also permits various alarms to
+// be scheduled; these are lightweight short-lived callbacks that must be safely
+// runnable from any thread in any lock state in which scheduler invocations
+// occur. Finally, implements a hybrid between these: a callback that can be
+// run when the condition variable is signaled.
+//
+// This class is designed to be overridden, but only to re-implement its
+// internal notion of blocking to permit time to be mocked by MockScheduler.
+class Scheduler {
+ public:
+ // A callback for a scheduler alarm, with an associated wakeup time (absolute
+ // time after which the callback will be invoked with Run() by the scheduler).
+ // Alarm should be treated as an opaque type.
+ class Alarm;
+
+ // Sorting comparator for Alarms, so that they can be retrieved in time
+ // order. For use by std::set, thus public.
+ struct CompareAlarms {
+ bool operator()(const Alarm* a, const Alarm* b) const;
+ };
+
+ Scheduler(ThreadSystem* thread_system, Timer* timer);
+ virtual ~Scheduler();
+
+ ThreadSystem::CondvarCapableMutex* mutex();
+
+ // Optionally check that mutex is locked for debugging purposes.
+ void DCheckLocked();
+
+ // Condition-style methods: The following three methods provide a simple
+ // condition-variable-style interface that can be used to coordinate the
+ // threads sharing the scheduler.
+
+ // Wait at most timeout_us, or until Signal() is called. mutex() must be held
+ // when calling BlockingTimedWait.
+ void BlockingTimedWait(int64 timeout_ms);
+
+ // Non-blocking invocation of callback either when Signal() is called, or
+ // after timeout_us have passed. Ownership of callback passes to the
+ // scheduler, which deallocates it after invocation. mutex() must be held on
+ // the initial call, and is locked for the duration of callback. Note that
+ // callback may be invoked in a different thread from the calling thread.
+ void TimedWait(int64 timeout_ms, Function* callback);
+
+ // Signal threads in BlockingTimedWait and invoke TimedWait callbacks.
+ // mutex() must be held when calling Signal. Performs outstanding work,
+ // including any triggered by the signal, before returning; note that this
+ // means it may drop the scheduler lock internally while doing callback
+ // invocation, which is different from the usual condition variable signal
+ // semantics.
+ void Signal();
+
+ // Alarms. The following two methods provide a mechanism for scheduling
+ // alarm tasks, each run at a particular time.
+
+ // Schedules an alarm for absolute time wakeup_time_us, using the passed-in
+ // Function* as the alarm callback. Returns the created Alarm. Performs
+ // outstanding work. The returned alarm will own the callback and will clean
+ // itself and the callback when it is run or cancelled. NOTE in particular
+ // that calls to CancelAlarm must ensure the callback has not been invoked
+ // yet. This is why the scheduler mutex must be held for CancelAlarm.
+ Alarm* AddAlarm(int64 wakeup_time_us, Function* callback);
+
+ // Cancels an alarm, calling the Cancel() method and deleting the alarm
+ // object. Scheduler mutex must be held before call to ensure that alarm is
+ // not called back before cancellation occurs. Doesn't perform outstanding
+ // work. Returns true if the cancellation occurred. If false is returned,
+ // the alarm is already being run / has been run in another thread; if the
+ // alarm deletes itself on Cancel(), it may no longer safely be used.
+ bool CancelAlarm(Alarm* alarm);
+
+ // Finally, ProcessAlarms provides a mechanism to ensure that pending alarms
+ // are executed in the absence of other scheduler activity. ProcessAlarms:
+ // handle outstanding alarms, or if there are none wait until the next wakeup
+ // and handle alarms then before relinquishing control. Idle no longer than
+ // timeout_us. Passing in timeout_us=0 will run without blocking.
+ // mutex() must be held.
+ void ProcessAlarms(int64 timeout_us);
+
+ // Obtain the timer that the scheduler is using internally. Important if you
+ // and the scheduler want to agree on the passage of time.
+ Timer* timer() { return timer_; }
+
+ // Obtain the thread system used by the scheduler.
+ ThreadSystem* thread_system() { return thread_system_; }
+
+ // Internal method to kick the system because something of interest to the
+ // overridden AwaitWakeup method has happened. Exported here because C++
+ // naming hates you.
+ void Wakeup();
+
+ // These methods notify the scheduler of work sequences that may run work
+ // on it. They are only used for time simulations in MockScheduler and
+ // are no-ops during normal usage.
+ virtual void RegisterWorker(QueuedWorkerPool::Sequence* w);
+ virtual void UnregisterWorker(QueuedWorkerPool::Sequence* w);
+
+ protected:
+ // Internal method to await a wakeup event. Block until wakeup_time_us (an
+ // absolute time since the epoch), or until something interesting (such as a
+ // call to Signal) occurs. This is virtual to permit us to mock it out (the
+ // mock simply advances time). This maybe called with 0 in case where there
+ // are no timers currently active.
+ virtual void AwaitWakeupUntilUs(int64 wakeup_time_us);
+
+ bool running_waiting_alarms() const { return running_waiting_alarms_; }
+
+ private:
+ class CondVarTimeout;
+ class CondVarCallbackTimeout;
+ friend class SchedulerTest;
+
+ typedef std::set<Alarm*, CompareAlarms> AlarmSet;
+
+ int64 RunAlarms(bool* ran_alarms);
+ void AddAlarmMutexHeld(int64 wakeup_time_us, Alarm* alarm);
+ void CancelWaiting(Alarm* alarm);
+ bool NoPendingAlarms();
+
+ ThreadSystem* thread_system_;
+ Timer* timer_;
+ scoped_ptr<ThreadSystem::CondvarCapableMutex> mutex_;
+ // condvar_ tracks whether interesting (next-wakeup decreasing or
+ // signal_count_ increasing) events occur.
+ scoped_ptr<ThreadSystem::Condvar> condvar_;
+ uint32 index_; // Used to disambiguate alarms with equal deadlines
+ AlarmSet outstanding_alarms_; // Priority queue of future alarms
+ // An alarm may be deleted iff it is successfully removed from
+ // outstanding_alarms_.
+ int64 signal_count_; // Number of times Signal has been called
+ AlarmSet waiting_alarms_; // Alarms waiting for signal_count to change
+ bool running_waiting_alarms_; // True if we're in process of invoking
+ // user callbacks...
+ DISALLOW_COPY_AND_ASSIGN(Scheduler);
+};
+
+// A simple adapter class that permits blocking until an alarm has been run or
+// cancelled. Designed for stack allocation.
+//
+// Note that success_ is guarded by the acquire/release semantics of
+// atomic_bool and by monotonicity of done_. Field order (==initialization
+// order) is important here.
+class SchedulerBlockingFunction : public Function {
+ public:
+ explicit SchedulerBlockingFunction(Scheduler* scheduler);
+ virtual ~SchedulerBlockingFunction();
+ virtual void Run();
+ virtual void Cancel();
+ // Block until called back, returning true for Run and false for Cancel.
+ bool Block();
+ private:
+ Scheduler* scheduler_;
+ bool success_;
+ AtomicBool done_;
+ DISALLOW_COPY_AND_ASSIGN(SchedulerBlockingFunction);
+};
+
+} // namespace net_instaweb
+
+#endif // NET_INSTAWEB_UTIL_PUBLIC_SCHEDULER_H_
Propchange: httpd/mod_spdy/trunk/net/instaweb/util/public/scheduler.h
------------------------------------------------------------------------------
svn:eol-style = native
Added: httpd/mod_spdy/trunk/net/instaweb/util/public/scheduler_based_abstract_lock.h
URL: http://svn.apache.org/viewvc/httpd/mod_spdy/trunk/net/instaweb/util/public/scheduler_based_abstract_lock.h?rev=1591622&view=auto
==============================================================================
--- httpd/mod_spdy/trunk/net/instaweb/util/public/scheduler_based_abstract_lock.h (added)
+++ httpd/mod_spdy/trunk/net/instaweb/util/public/scheduler_based_abstract_lock.h Thu May 1 11:43:36 2014
@@ -0,0 +1,59 @@
+/*
+ * Copyright 2011 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// Author: jmaessen@google.com (Jan Maessen)
+
+#ifndef NET_INSTAWEB_UTIL_PUBLIC_SCHEDULER_BASED_ABSTRACT_LOCK_H_
+#define NET_INSTAWEB_UTIL_PUBLIC_SCHEDULER_BASED_ABSTRACT_LOCK_H_
+
+#include "net/instaweb/util/public/basictypes.h"
+#include "net/instaweb/util/public/named_lock_manager.h"
+
+namespace net_instaweb {
+
+class Function;
+class Scheduler;
+
+// A SchedulerBasedAbstractLock implements a Lock by blocking using the
+// scheduler, using exponential sleep time backoff and polling the lock on
+// wakeup. The total time blocked on a long-held lock will be about 1.5 times
+// the time between the initial call to the lock routine attempt and the time
+// the lock is unlocked (ie we might wait for an extra amount of time equal to
+// half the time we were forced to wait).
+class SchedulerBasedAbstractLock : public NamedLock {
+ public:
+ virtual ~SchedulerBasedAbstractLock();
+ virtual bool LockTimedWait(int64 wait_ms);
+ virtual void LockTimedWait(int64 wait_ms, Function* callback);
+
+ virtual bool LockTimedWaitStealOld(int64 wait_ms, int64 steal_ms);
+ virtual void LockTimedWaitStealOld(
+ int64 wait_ms, int64 steal_ms, Function* callback);
+
+ protected:
+ virtual Scheduler* scheduler() const = 0;
+
+ private:
+ typedef bool (SchedulerBasedAbstractLock::*TryLockMethod)(int64 steal_ms);
+ bool TryLockIgnoreSteal(int64 steal_ignored);
+ bool BusySpin(TryLockMethod try_lock, int64 steal_ms);
+ void PollAndCallback(TryLockMethod try_lock, int64 steal_ms,
+ int64 wait_ms, Function* callback);
+};
+
+} // namespace net_instaweb
+
+#endif // NET_INSTAWEB_UTIL_PUBLIC_SCHEDULER_BASED_ABSTRACT_LOCK_H_
Propchange: httpd/mod_spdy/trunk/net/instaweb/util/public/scheduler_based_abstract_lock.h
------------------------------------------------------------------------------
svn:eol-style = native
Added: httpd/mod_spdy/trunk/net/instaweb/util/public/scheduler_thread.h
URL: http://svn.apache.org/viewvc/httpd/mod_spdy/trunk/net/instaweb/util/public/scheduler_thread.h?rev=1591622&view=auto
==============================================================================
--- httpd/mod_spdy/trunk/net/instaweb/util/public/scheduler_thread.h (added)
+++ httpd/mod_spdy/trunk/net/instaweb/util/public/scheduler_thread.h Thu May 1 11:43:36 2014
@@ -0,0 +1,63 @@
+// Copyright 2011 Google Inc.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+// Author: morlovich@google.com (Maksim Orlovich)
+//
+// Contains SchedulerThread, used to run the Scheduler dispatch loop for
+// non-blocking servers.
+
+#ifndef NET_INSTAWEB_UTIL_PUBLIC_SCHEDULER_THREAD_H_
+#define NET_INSTAWEB_UTIL_PUBLIC_SCHEDULER_THREAD_H_
+
+#include "net/instaweb/util/public/basictypes.h"
+#include "net/instaweb/util/public/thread.h"
+#include "net/instaweb/util/public/thread_system.h"
+
+namespace net_instaweb {
+
+class Function;
+class Scheduler;
+
+// This class is a helper used to dispatch events on a scheduler in a thread
+// in case where the server infrastructure is non-blocking and therefore does
+// not provide a natural way to do it.
+class SchedulerThread : public ThreadSystem::Thread {
+ public:
+ // Creates the thread. The user still needs to call Start() manually.
+ SchedulerThread(ThreadSystem* thread_system, Scheduler* scheduler);
+
+ // Returns a function that, when run, will properly synchronize with this
+ // thread and shut it down cleanly, deleting the object as well.
+ // It is suggested for use with RewriteDriverFactory::defer_delete(); as it
+ // needs to be run after it's OK if scheduler timeouts no longer work.
+ Function* MakeDeleter();
+
+ protected:
+ virtual void Run();
+
+ private:
+ class CleanupFunction;
+ friend class CleanupFunction;
+
+ virtual ~SchedulerThread();
+
+ bool quit_;
+ Scheduler* scheduler_;
+
+ DISALLOW_COPY_AND_ASSIGN(SchedulerThread);
+};
+
+} // namespace net_instaweb
+
+#endif // NET_INSTAWEB_UTIL_PUBLIC_SCHEDULER_THREAD_H_
Propchange: httpd/mod_spdy/trunk/net/instaweb/util/public/scheduler_thread.h
------------------------------------------------------------------------------
svn:eol-style = native
Added: httpd/mod_spdy/trunk/net/instaweb/util/public/shared_circular_buffer.h
URL: http://svn.apache.org/viewvc/httpd/mod_spdy/trunk/net/instaweb/util/public/shared_circular_buffer.h?rev=1591622&view=auto
==============================================================================
--- httpd/mod_spdy/trunk/net/instaweb/util/public/shared_circular_buffer.h (added)
+++ httpd/mod_spdy/trunk/net/instaweb/util/public/shared_circular_buffer.h Thu May 1 11:43:36 2014
@@ -0,0 +1,94 @@
+/*
+ * Copyright 2011 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// Author: fangfei@google.com (Fangfei Zhou)
+
+#ifndef NET_INSTAWEB_UTIL_PUBLIC_SHARED_CIRCULAR_BUFFER_H_
+#define NET_INSTAWEB_UTIL_PUBLIC_SHARED_CIRCULAR_BUFFER_H_
+
+#include "base/scoped_ptr.h"
+#include "net/instaweb/util/public/basictypes.h"
+#include "net/instaweb/util/public/string.h"
+#include "net/instaweb/util/public/string_util.h"
+
+namespace net_instaweb {
+
+class AbstractSharedMem;
+class AbstractSharedMemSegment;
+class AbstractMutex;
+class CircularBuffer;
+class MessageHandler;
+class Writer;
+
+// Shared memory circular buffer, the content of its shared memory segment is a
+// Mutex and a CircularBuffer.
+// In parent process, we initialize a shared memory segment. Then we create a
+// SharedCircularBuffer object in each process and attach it to the segment by
+// calling InitSegment(true, handler) once in the parent process and calling
+// InitSegment(false, handler) in each child.
+
+class SharedCircularBuffer {
+ public:
+ // Construct with shared memory, data buffer capacity, filename_prefix and
+ // filename_suffix. filename_prefix and filename_suffix are used to name
+ // segment for the shared circular buffer.
+ SharedCircularBuffer(AbstractSharedMem* shm_runtime,
+ const int buffer_capacity,
+ const GoogleString& filename_prefix,
+ const GoogleString& filename_suffix);
+ virtual ~SharedCircularBuffer();
+ // Initialize the shared memory segment.
+ // parent = true if this is invoked in root process -- initialize the shared
+ // memory; parent = false if this is invoked in child process -- attach to
+ // existing segment.
+ bool InitSegment(bool parent, MessageHandler* handler);
+ // Reset circular buffer.
+ void Clear();
+ // Write content to circular buffer.
+ bool Write(const StringPiece& message);
+ // Write content of data in buffer to writer, without clearing the buffer.
+ bool Dump(Writer* writer, MessageHandler* handler);
+ // Return data content as string. This is for test purposes.
+ GoogleString ToString(MessageHandler* handler);
+ // This should be called from the root process as it is about to exit, when no
+ // future children are expected to start.
+ void GlobalCleanup(MessageHandler* handler);
+
+ private:
+ bool InitMutex(MessageHandler* handler);
+ GoogleString SegmentName() const;
+
+ // SegmentName looks like:
+ // filename_prefix/SharedCircularBuffer.filename_suffix.
+ AbstractSharedMem* shm_runtime_;
+ // Capacity of circular buffer.
+ const int buffer_capacity_;
+ // Circular buffer.
+ CircularBuffer* buffer_;
+ const GoogleString filename_prefix_;
+ // filename_suffix_ is used to distinguish SharedCircularBuffer.
+ const GoogleString filename_suffix_;
+ // Mutex for segment.
+ scoped_ptr<AbstractMutex> mutex_;
+ // Shared memory segment.
+ scoped_ptr<AbstractSharedMemSegment> segment_;
+
+ DISALLOW_COPY_AND_ASSIGN(SharedCircularBuffer);
+};
+
+} // namespace net_instaweb
+
+#endif // NET_INSTAWEB_UTIL_PUBLIC_SHARED_CIRCULAR_BUFFER_H_
Propchange: httpd/mod_spdy/trunk/net/instaweb/util/public/shared_circular_buffer.h
------------------------------------------------------------------------------
svn:eol-style = native
Added: httpd/mod_spdy/trunk/net/instaweb/util/public/shared_circular_buffer_test_base.h
URL: http://svn.apache.org/viewvc/httpd/mod_spdy/trunk/net/instaweb/util/public/shared_circular_buffer_test_base.h?rev=1591622&view=auto
==============================================================================
--- httpd/mod_spdy/trunk/net/instaweb/util/public/shared_circular_buffer_test_base.h (added)
+++ httpd/mod_spdy/trunk/net/instaweb/util/public/shared_circular_buffer_test_base.h Thu May 1 11:43:36 2014
@@ -0,0 +1,108 @@
+// Copyright 2011 Google Inc.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+// Author: fangfei@google.com (Fangfei Zhou)
+
+#ifndef NET_INSTAWEB_UTIL_PUBLIC_SHARED_CIRCULAR_BUFFER_TEST_BASE_H_
+#define NET_INSTAWEB_UTIL_PUBLIC_SHARED_CIRCULAR_BUFFER_TEST_BASE_H_
+
+#include "base/scoped_ptr.h"
+#include "net/instaweb/util/public/abstract_shared_mem.h"
+#include "net/instaweb/util/public/basictypes.h"
+#include "net/instaweb/util/public/gtest.h"
+#include "net/instaweb/util/public/mock_message_handler.h"
+#include "net/instaweb/util/public/shared_mem_test_base.h"
+#include "net/instaweb/util/public/string_util.h"
+
+namespace net_instaweb {
+class SharedCircularBuffer;
+
+// This TestBase is added to pthread_shared_mem_test
+class SharedCircularBufferTestBase : public testing::Test {
+ protected:
+ typedef void (SharedCircularBufferTestBase::*TestMethod)();
+
+ explicit SharedCircularBufferTestBase(SharedMemTestEnv* test_env);
+
+ bool CreateChild(TestMethod method);
+
+ // Test basic initialization/writing/cleanup.
+ void TestCreate();
+ // Test writing from child process.
+ void TestAdd();
+ // Test cleanup from child process.
+ void TestClear();
+ // Test the shared memory circular buffer.
+ void TestCircular();
+
+ private:
+ // Helper functions.
+ void TestCreateChild();
+ void TestAddChild();
+ void TestClearChild();
+ // Write to SharedCircularBuffer in a child process.
+ void TestChildWrite();
+ // Check content of SharedCircularBuffer in a child process.
+ void TestChildBuff();
+
+ // Initialize SharedMemoryCircularBuffer from child process.
+ SharedCircularBuffer* ChildInit();
+ // Initialize SharedMemoryCircularBuffer from root process.
+ SharedCircularBuffer* ParentInit();
+
+ scoped_ptr<SharedMemTestEnv> test_env_;
+ scoped_ptr<AbstractSharedMem> shmem_runtime_;
+ MockMessageHandler handler_;
+ // Message to write in Child process.
+ // We can't pass in argument in callback functions in this TestBase,
+ // stick value to member variable instead.
+ StringPiece message_;
+ // Expected content of SharedCircularBuffer.
+ // Used to check buffer content in a child process.
+ StringPiece expected_result_;
+
+ DISALLOW_COPY_AND_ASSIGN(SharedCircularBufferTestBase);
+};
+
+template<typename ConcreteTestEnv>
+class SharedCircularBufferTestTemplate : public SharedCircularBufferTestBase {
+ public:
+ SharedCircularBufferTestTemplate()
+ : SharedCircularBufferTestBase(new ConcreteTestEnv) {
+ }
+};
+
+TYPED_TEST_CASE_P(SharedCircularBufferTestTemplate);
+
+TYPED_TEST_P(SharedCircularBufferTestTemplate, TestCreate) {
+ SharedCircularBufferTestBase::TestCreate();
+}
+
+TYPED_TEST_P(SharedCircularBufferTestTemplate, TestAdd) {
+ SharedCircularBufferTestBase::TestAdd();
+}
+
+TYPED_TEST_P(SharedCircularBufferTestTemplate, TestClear) {
+ SharedCircularBufferTestBase::TestClear();
+}
+
+TYPED_TEST_P(SharedCircularBufferTestTemplate, TestCircular) {
+ SharedCircularBufferTestBase::TestCircular();
+}
+
+REGISTER_TYPED_TEST_CASE_P(SharedCircularBufferTestTemplate, TestCreate,
+ TestAdd, TestClear, TestCircular);
+
+} // namespace net_instaweb
+#endif // NET_INSTAWEB_UTIL_PUBLIC_SHARED_CIRCULAR_BUFFER_TEST_BASE_H_
Propchange: httpd/mod_spdy/trunk/net/instaweb/util/public/shared_circular_buffer_test_base.h
------------------------------------------------------------------------------
svn:eol-style = native
Added: httpd/mod_spdy/trunk/net/instaweb/util/public/shared_dynamic_string_map.h
URL: http://svn.apache.org/viewvc/httpd/mod_spdy/trunk/net/instaweb/util/public/shared_dynamic_string_map.h?rev=1591622&view=auto
==============================================================================
--- httpd/mod_spdy/trunk/net/instaweb/util/public/shared_dynamic_string_map.h (added)
+++ httpd/mod_spdy/trunk/net/instaweb/util/public/shared_dynamic_string_map.h Thu May 1 11:43:36 2014
@@ -0,0 +1,238 @@
+/*
+ * Copyright 2011 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// Author: jhoch@google.com (Jason Hoch)
+
+#ifndef NET_INSTAWEB_UTIL_PUBLIC_SHARED_DYNAMIC_STRING_MAP_H_
+#define NET_INSTAWEB_UTIL_PUBLIC_SHARED_DYNAMIC_STRING_MAP_H_
+
+#include <cstddef>
+#include "base/scoped_ptr.h"
+#include "net/instaweb/util/public/abstract_mutex.h"
+#include "net/instaweb/util/public/abstract_shared_mem.h"
+#include "net/instaweb/util/public/basictypes.h"
+#include "net/instaweb/util/public/string.h"
+#include "net/instaweb/util/public/string_util.h"
+
+namespace net_instaweb {
+
+class MessageHandler;
+class Writer;
+
+struct Entry {
+ int value;
+ size_t string_offset;
+};
+
+// A shared memory string to int dictionary/map, no deletion.
+// Currently the map is designed to fill with number_of_strings strings of
+// average length average_string_length. Once the map is full it ignores
+// attempts to add additional information.
+// TODO(jhoch): make map dynamically sized
+class SharedDynamicStringMap {
+ public:
+ // Number of strings will be rounded up to a power of 2.
+ // Average string length should include terminating null character.
+ // Map will be able to hold exactly number_of_strings * average_string_length
+ // chars worth of string data.
+ SharedDynamicStringMap(size_t number_of_strings,
+ size_t average_string_length,
+ AbstractSharedMem* shm_runtime,
+ const GoogleString& filename_prefix,
+ const GoogleString& filename_suffix);
+
+ // Initialize the shared memory segment. This method should complete before
+ // any other methods are executed.
+ // parent = true means invoked in root process, initialize the shared memory
+ // = false means invoked in child process -- attach to existing segment
+ bool InitSegment(bool parent, MessageHandler* message_handler);
+
+ // Increments value corresponding to given string by 1.
+ // Adds the string to the map with initial value 1 if the string is not
+ // present.
+ // Returns the new value corresponding to the element.
+ // If the map is full it does nothing and returns 0.
+ int IncrementElement(const StringPiece& string);
+
+ // Retrieve the value corresponding to the string (returns 0 if the string is
+ // not in the map)
+ int LookupElement(const StringPiece& string) const;
+
+ // Dumps table's strings into StringSet
+ void GetKeys(StringSet* strings);
+
+ // Retrieve the number of strings inserted into the table.
+ int GetNumberInserted() const;
+
+ // Destroy shared memory segment and other relevant clean-up
+ void GlobalCleanup(MessageHandler* message_handler);
+
+ // Iterates through the string data that is present at the time of calling
+ // and dumps out each string with its associated value. The value produced
+ // for a given string is going to be the value present whenever that string
+ // is dumped.
+ void Dump(Writer* writer, MessageHandler* message_handler);
+
+ private:
+ void ClearSegment(MessageHandler* message_handler);
+
+ // ***If lock = true, locks the mutex associated with the returned entry***
+ // (to be unlocked by caller)
+ // Finds the index of the entry with the given string, or the first empty
+ // entry encountered, which can either be used for insertion purposes or
+ // to know that the string is not present, since the table does not support
+ // deletion.
+ // -1 is returned if the entire table is traversed without finding the
+ // string or an empty spot (this should not happen if the table never exceeds
+ // 50% capacity).
+ // entry_pointer is an output parameter.
+ // Note that lock must always be set to true for any writing operation, and
+ // setting write to false for a read operation can result in a false read,
+ // albeit in very rare circumstances. The circumstance is that an entry "AB"
+ // is being added to the table, where A and B are arbitrary strings, and a
+ // read of "A" is occurring, and the read of "A" catches the write of "AB"
+ // mid-write at exactly the moment where it can only see "A."
+ // The fact that looking up without locking is possible relies on the
+ // assumption that entries are not deleted and that null characters fill up
+ // the char space upon initialization.
+ // If 100% accurate lookup is needed then a new LookupElement method could
+ // be added that calls FindEntry(lock = true).
+ int FindEntry(const StringPiece& string,
+ bool lock,
+ Entry** entry_pointer) const;
+ Entry* GetEntry(size_t n) const;
+ Entry* GetFirstEntry() const;
+
+ // Gets the mutex for the nth table entry.
+ AbstractMutex* GetMutex(size_t n) const;
+ // Inserts the given string into the table (if there is room), by adding it
+ // to char storage and setting the entry_pointer's char offset and value (the
+ // former to string_offset and the latter to 1), and returns the resulting
+ // value of the entry (1 if it was successfully inserted, 0 otherwise)
+ // The entry should be locked when this method is called.
+ int InsertString(const StringPiece& string, Entry* entry_pointer);
+ char* GetStringAtOffset(size_t offset) const;
+
+ // Math utility function, returns the smallest power of two greater than or
+ // equal to the input.
+ static size_t NextPowerOfTwo(size_t n);
+
+ // |
+ // Structure content | Offset
+ // |
+ // ___________________________ | mutex_offset_ = 0
+ // | Mutex0 | | - memory location = segment_->Base()
+ // | | |
+ // | Mutex1 | | mutex_offset_ + mutex_size
+ // | | |
+ // | Mutex2 | | mutex_offset_ + mutex_size_ * 2
+ // | . | |
+ // | . | | - each mutex has size mutex_size
+ // | . | |
+ // | | |
+ // | MutexN | | mutex_offset_ + mutex_size_ * N
+ // | . | |
+ // | . | | - there are table_size_ + 1 mutexes
+ // | . | | (last mutex is for string_offset
+ // | . | | and number_inserted)
+ // | . | |
+ // |___________________________| | strings_offset_ = mutex_offset_ +
+ // | String0======= | | kTableSize * mutex_size_
+ // | | | = String offset0
+ // | | |
+ // | String1======= | | String offset1
+ // | _____| |
+ // | | |
+ // | String2= | | String offset2
+ // | |________________ |
+ // | | |
+ // | String3================== | | etc.
+ // | _________| |
+ // | | |
+ // | String4======== | | - strings are variable length, null
+ // | |_ | terminated
+ // | | |
+ // | String5========== | | - total allocated space is
+ // | _| | number_of_strings times average
+ // | | | string length
+ // | String6======== | |
+ // | |_ | - there are as many strings as have been
+ // | . | | added
+ // | . | |
+ // | . | | - location at which to add next string is
+ // |___________________| | stored at string_offset_offset_
+ // | | | (see below)
+ // | | |
+ // | String offset | | string_offset_offset_ = strings_offset_ +
+ // |_________________| | number_of_strings_ *
+ // | | | average_string_length_
+ // | Number | |
+ // | Inse- | | number_inserted_offset_ =
+ // | rted | | string_offset_offset_ + kOffsetSize
+ // | | |
+ // |________|________________ | table_offset_ = number_inserted_offset_ +
+ // | Value0 | String offset0 | | kIntSize
+ // | (int) | (size_t) | |
+ // | | | |
+ // | Value1 | String offset1 | | table_offset_ + kEntrySize
+ // | | | |
+ // | Value2 | String offset2 | | table_offset_ + kEntrySize* 2
+ // | . | . | |
+ // | . | . | | - each value and string offset makes an
+ // | . | . | | Entry struct
+ // | | | |
+ // | ValueN | String offsetN | | table_offset_ + kEntrySize * N
+ // | . | . | |
+ // | . | . | | - there are table_size entries
+ // | . | . | |
+ // |________|________________| |
+
+ size_t number_of_strings_;
+ size_t average_string_length_;
+ // Sizes of various portions of the memory
+ size_t mutex_size_;
+ size_t table_size_;
+ // Offset from segment_->Base() at which various portions of the structure
+ // begin (see above depiction).
+ // mutex_offset_ is the beginning of the (table_size_ + 1) mutexes
+ // strings_offset_ is the beginning of the strings
+ // string_offset_offset_ is where the offset of the next string to be
+ // inserted is located
+ // number_inserted_offset_ is where the number of inserted strings is
+ // located
+ // table_offset_ is the beginning of the table_size_ entries
+ size_t mutex_offset_;
+ size_t strings_offset_;
+ size_t string_offset_offset_;
+ size_t number_inserted_offset_;
+ size_t table_offset_;
+ // Total size of shared memory segment
+ size_t total_size_;
+
+ // The mutex for inserting strings, i.e. the one shared by the
+ // string_offset_ and number_inserted_ values.
+ scoped_ptr<AbstractMutex> insert_string_mutex_;
+
+ const GoogleString segment_name_;
+ AbstractSharedMem* shm_runtime_;
+ scoped_ptr<AbstractSharedMemSegment> segment_;
+
+ DISALLOW_COPY_AND_ASSIGN(SharedDynamicStringMap);
+};
+
+} // namespace net_instaweb
+
+#endif // NET_INSTAWEB_UTIL_PUBLIC_SHARED_DYNAMIC_STRING_MAP_H_
Propchange: httpd/mod_spdy/trunk/net/instaweb/util/public/shared_dynamic_string_map.h
------------------------------------------------------------------------------
svn:eol-style = native
Added: httpd/mod_spdy/trunk/net/instaweb/util/public/shared_dynamic_string_map_test_base.h
URL: http://svn.apache.org/viewvc/httpd/mod_spdy/trunk/net/instaweb/util/public/shared_dynamic_string_map_test_base.h?rev=1591622&view=auto
==============================================================================
--- httpd/mod_spdy/trunk/net/instaweb/util/public/shared_dynamic_string_map_test_base.h (added)
+++ httpd/mod_spdy/trunk/net/instaweb/util/public/shared_dynamic_string_map_test_base.h Thu May 1 11:43:36 2014
@@ -0,0 +1,131 @@
+// Copyright 2011 Google Inc.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+// Author: jhoch@google.com (Jason Hoch)
+
+#ifndef NET_INSTAWEB_UTIL_PUBLIC_SHARED_DYNAMIC_STRING_MAP_TEST_BASE_H_
+#define NET_INSTAWEB_UTIL_PUBLIC_SHARED_DYNAMIC_STRING_MAP_TEST_BASE_H_
+
+#include <vector>
+#include "base/scoped_ptr.h"
+#include "net/instaweb/util/public/abstract_shared_mem.h"
+#include "net/instaweb/util/public/basictypes.h"
+#include "net/instaweb/util/public/gtest.h"
+#include "net/instaweb/util/public/mock_message_handler.h"
+#include "net/instaweb/util/public/shared_mem_test_base.h"
+#include "net/instaweb/util/public/string.h"
+
+namespace net_instaweb {
+class SharedDynamicStringMap;
+
+class SharedDynamicStringMapTestBase : public testing::Test {
+ protected:
+ typedef void (SharedDynamicStringMapTestBase::*TestMethod0)();
+ typedef void (SharedDynamicStringMapTestBase::*TestMethod2)(int, int);
+
+ explicit SharedDynamicStringMapTestBase(SharedMemTestEnv* test_env);
+
+ // Create child process for given method - the latter is used for TestFill
+ // methods, which require arguments
+ bool CreateChild(TestMethod0 method);
+ bool CreateFillChild(TestMethod2 method, int start, int number_of_strings);
+
+ // Test simple functionality using Dump(Writer*)
+ void TestSimple();
+ // Test the creation and use of a child process.
+ void TestCreate();
+ // Test the creation and use of two child processes.
+ void TestAdd();
+ // Test that no unwanted insertions are performed when filling the map 1/4 of
+ // the way by checking length of Dump result.
+ void TestQuarterFull();
+ // Test the filling of the string map.
+ void TestFillSingleThread();
+ // Test the filling of the string map by more than one thread;
+ // no two threads access the same string.
+ void TestFillMultipleNonOverlappingThreads();
+ // Test the filling of the string map by more than one thread;
+ // no two child threads access the same string, but parent process
+ // hits strings at the same time as the child threads.
+ void TestFillMultipleOverlappingThreads();
+
+ private:
+ void AddChild();
+ void AddFillChild(int start, int number_of_strings);
+ void AddToFullTable();
+
+ // Initialize child process object
+ SharedDynamicStringMap* ChildInit();
+ // Initialize parent process object
+ SharedDynamicStringMap* ParentInit();
+
+ std::vector<GoogleString> strings_;
+
+ scoped_ptr<SharedMemTestEnv> test_env_;
+ scoped_ptr<AbstractSharedMem> shmem_runtime_;
+ MockMessageHandler handler_;
+
+ DISALLOW_COPY_AND_ASSIGN(SharedDynamicStringMapTestBase);
+};
+
+template<typename ConcreteTestEnv>
+class SharedDynamicStringMapTestTemplate
+ : public SharedDynamicStringMapTestBase {
+ public:
+ SharedDynamicStringMapTestTemplate()
+ : SharedDynamicStringMapTestBase(new ConcreteTestEnv) {
+ }
+};
+
+TYPED_TEST_CASE_P(SharedDynamicStringMapTestTemplate);
+
+TYPED_TEST_P(SharedDynamicStringMapTestTemplate, TestSimple) {
+ SharedDynamicStringMapTestBase::TestSimple();
+}
+
+TYPED_TEST_P(SharedDynamicStringMapTestTemplate, TestCreate) {
+ SharedDynamicStringMapTestBase::TestCreate();
+}
+
+TYPED_TEST_P(SharedDynamicStringMapTestTemplate, TestAdd) {
+ SharedDynamicStringMapTestBase::TestAdd();
+}
+
+TYPED_TEST_P(SharedDynamicStringMapTestTemplate, TestQuarterFull) {
+ SharedDynamicStringMapTestBase::TestQuarterFull();
+}
+
+TYPED_TEST_P(SharedDynamicStringMapTestTemplate, TestFillSingleThread) {
+ SharedDynamicStringMapTestBase::TestFillSingleThread();
+}
+
+TYPED_TEST_P(SharedDynamicStringMapTestTemplate,
+ TestFillMultipleNonOverlappingThreads) {
+ SharedDynamicStringMapTestBase::TestFillMultipleNonOverlappingThreads();
+}
+
+TYPED_TEST_P(SharedDynamicStringMapTestTemplate,
+ TestFillMultipleOverlappingThreads) {
+ SharedDynamicStringMapTestBase::TestFillMultipleOverlappingThreads();
+}
+
+REGISTER_TYPED_TEST_CASE_P(SharedDynamicStringMapTestTemplate, TestSimple,
+ TestCreate, TestAdd, TestQuarterFull,
+ TestFillSingleThread,
+ TestFillMultipleNonOverlappingThreads,
+ TestFillMultipleOverlappingThreads);
+
+} // namespace net_instaweb
+
+#endif // NET_INSTAWEB_UTIL_PUBLIC_SHARED_DYNAMIC_STRING_MAP_TEST_BASE_H_
Propchange: httpd/mod_spdy/trunk/net/instaweb/util/public/shared_dynamic_string_map_test_base.h
------------------------------------------------------------------------------
svn:eol-style = native
Added: httpd/mod_spdy/trunk/net/instaweb/util/public/shared_mem_lock_manager.h
URL: http://svn.apache.org/viewvc/httpd/mod_spdy/trunk/net/instaweb/util/public/shared_mem_lock_manager.h?rev=1591622&view=auto
==============================================================================
--- httpd/mod_spdy/trunk/net/instaweb/util/public/shared_mem_lock_manager.h (added)
+++ httpd/mod_spdy/trunk/net/instaweb/util/public/shared_mem_lock_manager.h Thu May 1 11:43:36 2014
@@ -0,0 +1,98 @@
+/*
+ * Copyright 2011 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// Author: morlovich@google.com (Maksim Orlovich)
+
+#ifndef NET_INSTAWEB_UTIL_PUBLIC_SHARED_MEM_LOCK_MANAGER_H_
+#define NET_INSTAWEB_UTIL_PUBLIC_SHARED_MEM_LOCK_MANAGER_H_
+
+#include <cstddef>
+#include "base/scoped_ptr.h"
+#include "net/instaweb/util/public/basictypes.h"
+#include "net/instaweb/util/public/named_lock_manager.h"
+#include "net/instaweb/util/public/string.h"
+#include "net/instaweb/util/public/string_util.h"
+
+namespace net_instaweb {
+
+class AbstractSharedMem;
+class AbstractSharedMemSegment;
+class Hasher;
+class MessageHandler;
+class Scheduler;
+
+namespace SharedMemLockData {
+
+struct Bucket;
+
+} // namespace SharedMemLockData
+
+// A simple shared memory named locking manager, which uses scheduler alarms
+// (via SchedulerBasedAbstractLock) when it needs to block.
+//
+// TODO(morlovich): Implement condvars?
+class SharedMemLockManager : public NamedLockManager {
+ public:
+ // Note that you must call Initialize() in the root process, and Attach in
+ // child processes to finish the initialization.
+ //
+ // Locks created by this object must not live after it dies.
+ SharedMemLockManager(
+ AbstractSharedMem* shm, const GoogleString& path, Scheduler* scheduler,
+ Hasher* hasher, MessageHandler* handler);
+ virtual ~SharedMemLockManager();
+
+ // Sets up our shared state for use of all child processes. Returns
+ // whether successful.
+ bool Initialize();
+
+ // Connects to already initialized state from a child process.
+ // Returns whether successful.
+ bool Attach();
+
+ // This should be called from the root process as it is about to exit,
+ // with the same value as were passed to the constructor of any
+ // instance on which Initialize() was called, except the message_handler
+ // may be different (if for example the original one is no longer available
+ // due to the cleanup sequence).
+ static void GlobalCleanup(AbstractSharedMem* shm, const GoogleString& path,
+ MessageHandler* message_handler);
+
+ virtual NamedLock* CreateNamedLock(const StringPiece& name);
+
+ private:
+ friend class SharedMemLock;
+
+ SharedMemLockData::Bucket* Bucket(size_t bucket);
+
+ // Offset of mutex wrt to segment base.
+ size_t MutexOffset(SharedMemLockData::Bucket*);
+
+ AbstractSharedMem* shm_runtime_;
+ GoogleString path_;
+
+ scoped_ptr<AbstractSharedMemSegment> seg_;
+ Scheduler* scheduler_;
+ Hasher* hasher_;
+ MessageHandler* handler_;
+ size_t lock_size_;
+
+ DISALLOW_COPY_AND_ASSIGN(SharedMemLockManager);
+};
+
+} // namespace net_instaweb
+
+#endif // NET_INSTAWEB_UTIL_PUBLIC_SHARED_MEM_LOCK_MANAGER_H_
Propchange: httpd/mod_spdy/trunk/net/instaweb/util/public/shared_mem_lock_manager.h
------------------------------------------------------------------------------
svn:eol-style = native
Added: httpd/mod_spdy/trunk/net/instaweb/util/public/shared_mem_lock_manager_test_base.h
URL: http://svn.apache.org/viewvc/httpd/mod_spdy/trunk/net/instaweb/util/public/shared_mem_lock_manager_test_base.h?rev=1591622&view=auto
==============================================================================
--- httpd/mod_spdy/trunk/net/instaweb/util/public/shared_mem_lock_manager_test_base.h (added)
+++ httpd/mod_spdy/trunk/net/instaweb/util/public/shared_mem_lock_manager_test_base.h Thu May 1 11:43:36 2014
@@ -0,0 +1,97 @@
+// Copyright 2011 Google Inc.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+// Author: morlovich@google.com (Maksim Orlovich)
+
+#ifndef NET_INSTAWEB_UTIL_PUBLIC_SHARED_MEM_LOCK_MANAGER_TEST_BASE_H_
+#define NET_INSTAWEB_UTIL_PUBLIC_SHARED_MEM_LOCK_MANAGER_TEST_BASE_H_
+
+#include "base/scoped_ptr.h"
+#include "net/instaweb/util/public/abstract_shared_mem.h"
+#include "net/instaweb/util/public/basictypes.h"
+#include "net/instaweb/util/public/gtest.h"
+#include "net/instaweb/util/public/md5_hasher.h"
+#include "net/instaweb/util/public/mock_message_handler.h"
+#include "net/instaweb/util/public/mock_scheduler.h"
+#include "net/instaweb/util/public/mock_timer.h"
+#include "net/instaweb/util/public/shared_mem_lock_manager.h"
+#include "net/instaweb/util/public/shared_mem_test_base.h"
+#include "net/instaweb/util/public/thread_system.h"
+
+namespace net_instaweb {
+
+class SharedMemLockManagerTestBase : public testing::Test {
+ protected:
+ typedef void (SharedMemLockManagerTestBase::*TestMethod)();
+
+ explicit SharedMemLockManagerTestBase(SharedMemTestEnv* test_env);
+ virtual void SetUp();
+ virtual void TearDown();
+
+ void TestBasic();
+ void TestDestructorUnlock();
+ void TestSteal();
+
+ private:
+ bool CreateChild(TestMethod method);
+
+ SharedMemLockManager* CreateLockManager();
+ SharedMemLockManager* AttachDefault();
+
+ void TestBasicChild();
+ void TestStealChild();
+
+ scoped_ptr<SharedMemTestEnv> test_env_;
+ scoped_ptr<AbstractSharedMem> shmem_runtime_;
+ MockMessageHandler handler_;
+ MockTimer timer_; // note: this is thread-unsafe, and if we are running in
+ // a process-based environment it's not shared at all.
+ // Therefore, all advancement must be done in either
+ // parent or kid but not both.
+ scoped_ptr<ThreadSystem> thread_system_;
+ MockScheduler scheduler_;
+ MD5Hasher hasher_;
+ scoped_ptr<SharedMemLockManager> root_lock_manager_; // used for init only.
+
+ DISALLOW_COPY_AND_ASSIGN(SharedMemLockManagerTestBase);
+};
+
+template<typename ConcreteTestEnv>
+class SharedMemLockManagerTestTemplate : public SharedMemLockManagerTestBase {
+ public:
+ SharedMemLockManagerTestTemplate()
+ : SharedMemLockManagerTestBase(new ConcreteTestEnv) {
+ }
+};
+
+TYPED_TEST_CASE_P(SharedMemLockManagerTestTemplate);
+
+TYPED_TEST_P(SharedMemLockManagerTestTemplate, TestBasic) {
+ SharedMemLockManagerTestBase::TestBasic();
+}
+
+TYPED_TEST_P(SharedMemLockManagerTestTemplate, TestDestructorUnlock) {
+ SharedMemLockManagerTestBase::TestDestructorUnlock();
+}
+
+TYPED_TEST_P(SharedMemLockManagerTestTemplate, TestSteal) {
+ SharedMemLockManagerTestBase::TestSteal();
+}
+
+REGISTER_TYPED_TEST_CASE_P(SharedMemLockManagerTestTemplate, TestBasic,
+ TestDestructorUnlock, TestSteal);
+
+} // namespace net_instaweb
+
+#endif // NET_INSTAWEB_UTIL_PUBLIC_SHARED_MEM_LOCK_MANAGER_TEST_BASE_H_
Propchange: httpd/mod_spdy/trunk/net/instaweb/util/public/shared_mem_lock_manager_test_base.h
------------------------------------------------------------------------------
svn:eol-style = native