diff options
author | nick@chromium.org <nick@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-09-10 06:05:27 +0000 |
---|---|---|
committer | nick@chromium.org <nick@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-09-10 06:05:27 +0000 |
commit | 5852edc1b6eab234b9e048c41dd0d664ae7fc747 (patch) | |
tree | 9e5d8eb4833b76cdb11e66fc3607689e0f5e0122 /chrome/browser/sync/util/pthread_helpers.h | |
parent | f6059e37f8b8ac335ce18a189a13e702974a1c7e (diff) | |
download | chromium_src-5852edc1b6eab234b9e048c41dd0d664ae7fc747.zip chromium_src-5852edc1b6eab234b9e048c41dd0d664ae7fc747.tar.gz chromium_src-5852edc1b6eab234b9e048c41dd0d664ae7fc747.tar.bz2 |
Initial commit of sync engine code to browser/sync.
The code is not built on any platform yet. That will arrive
as a subsequent checkin.
This is an implementation of the interface exposed earlier
through syncapi.h. It is the client side of a sync
protocol that lets users sync their browser data
(currently, just bookmarks) with their Google Account.
Table of contents:
browser/sync/
protocol - The protocol definition, and
other definitions necessary to connect to
the service.
syncable/ - defines a data model for syncable objects,
and provides a sqlite-based backing store
for this model.
engine/ - includes the core sync logic, including commiting
changes to the server, downloading changes from
the server, resolving conflicts, other parts of
the sync algorithm.
engine/net - parts of the sync engine focused on the
business of talking to the server. Some of
this is binds a generic "server connection"
interface to a concrete implementation
provided by Chromium.
notifier - the part of the syncer focused on the business
of sending and receiving xmpp notifications.
Notifications are used instead of polling to
achieve very low latency change propagation.
util - not necessarily sync specific utility code. Much
of this is scaffolding which should either be
replaced by, or merged with, the utility code
in base/.
BUG=none
TEST=this code includes its own suite of unit tests.
Review URL: http://codereview.chromium.org/194065
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@25850 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/sync/util/pthread_helpers.h')
-rw-r--r-- | chrome/browser/sync/util/pthread_helpers.h | 259 |
1 files changed, 259 insertions, 0 deletions
diff --git a/chrome/browser/sync/util/pthread_helpers.h b/chrome/browser/sync/util/pthread_helpers.h new file mode 100644 index 0000000..26defe0 --- /dev/null +++ b/chrome/browser/sync/util/pthread_helpers.h @@ -0,0 +1,259 @@ +// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_SYNC_UTIL_PTHREAD_HELPERS_H_ +#define CHROME_BROWSER_SYNC_UTIL_PTHREAD_HELPERS_H_ + +#include <pthread.h> +#include "base/logging.h" + +#ifdef OS_WINDOWS +typedef void* thread_handle; +#else +typedef pthread_t thread_handle; +#endif + +// Creates a pthread, detaches from it, and returns a Win32 HANDLE for it that +// the caller must CloseHandle(). +thread_handle CreatePThread(void* (*start)(void* payload), void* parameter); + +class PThreadRWLock { + public: + inline PThreadRWLock() { + int result = pthread_rwlock_init(&rwlock_, 0); + DCHECK_EQ(0, result); + } + ~PThreadRWLock() { + int result = pthread_rwlock_destroy(&rwlock_); + DCHECK_EQ(0, result); + } + pthread_rwlock_t rwlock_; + + DISALLOW_COPY_AND_ASSIGN(PThreadRWLock); +}; + +// ScopedReadLock attempts to acquire a write lock in its constructor and then +// releases it in its destructor. +class ScopedWriteLock { + public: + explicit ScopedWriteLock(pthread_rwlock_t* rwlock) : rwlock_(rwlock) { + int result = pthread_rwlock_wrlock(rwlock_); + DCHECK_EQ(0, result); + } + + explicit ScopedWriteLock(PThreadRWLock* rwlock) : rwlock_(&rwlock->rwlock_) { + int result = pthread_rwlock_wrlock(rwlock_); + DCHECK_EQ(0, result); + } + + ~ScopedWriteLock() { + int result = pthread_rwlock_unlock(rwlock_); + DCHECK_EQ(0, result); + } + + protected: + pthread_rwlock_t* rwlock_; + private: + DISALLOW_COPY_AND_ASSIGN(ScopedWriteLock); +}; + +// ScopedReadLock attempts to acquire a read lock in its constructor and then +// releases it in its destructor. +class ScopedReadLock { + public: + explicit ScopedReadLock(pthread_rwlock_t* rwlock) : rwlock_(rwlock) { + int result = pthread_rwlock_rdlock(rwlock_); + DCHECK_EQ(0, result); + } + + explicit ScopedReadLock(PThreadRWLock* rwlock) : rwlock_(&rwlock->rwlock_) { + int result = pthread_rwlock_rdlock(rwlock_); + DCHECK_EQ(0, result); + } + + ~ScopedReadLock() { + int result = pthread_rwlock_unlock(rwlock_); + DCHECK_EQ(0, result); + } + protected: + pthread_rwlock_t* rwlock_; + private: + DISALLOW_COPY_AND_ASSIGN(ScopedReadLock); +}; + +template <typename LockType> +class PThreadScopedLock { + public: + explicit inline PThreadScopedLock(LockType* lock) : lock_(lock) { + if (lock_) + lock->Lock(); + } + inline ~PThreadScopedLock() { + Unlock(); + } + inline void Unlock() { + if (lock_) { + lock_->Unlock(); + lock_ = NULL; + } + } + LockType* lock_; + + private: + DISALLOW_COPY_AND_ASSIGN(PThreadScopedLock); +}; + +class PThreadNoLock { + public: + inline void Lock() { } + inline void Unlock() { } +}; + +// On win32, the pthread mutex implementation is about as efficient a critical +// section. It uses atomic operations and only needs kernel calls on +// contention. +class PThreadMutex { + public: + inline PThreadMutex() { + pthread_mutexattr_t* attributes = NULL; +#ifndef NDEBUG + private_attributes_in_use_ = true; + pthread_mutexattr_init(&mutex_attributes_); + pthread_mutexattr_settype(&mutex_attributes_, PTHREAD_MUTEX_ERRORCHECK); + attributes = &mutex_attributes_; +#endif + int result = pthread_mutex_init(&mutex_, attributes); + DCHECK_EQ(0, result); + } + inline explicit PThreadMutex(const pthread_mutexattr_t* attr) { +#ifndef NDEBUG + private_attributes_in_use_ = false; +#endif + int result = pthread_mutex_init(&mutex_, attr); + DCHECK_EQ(0, result); + } + inline ~PThreadMutex() { + int result = pthread_mutex_destroy(&mutex_); + DCHECK_EQ(0, result); +#ifndef NDEBUG + if (private_attributes_in_use_) { + pthread_mutexattr_destroy(&mutex_attributes_); + } +#endif + } + inline void Lock() { + int result = pthread_mutex_lock(&mutex_); + DCHECK_EQ(0, result); + } + inline void Unlock() { + int result = pthread_mutex_unlock(&mutex_); + DCHECK_EQ(0, result); + } + pthread_mutex_t mutex_; + +#ifndef NDEBUG + pthread_mutexattr_t mutex_attributes_; + bool private_attributes_in_use_; +#endif + + private: + DISALLOW_COPY_AND_ASSIGN(PThreadMutex); +}; + +class PThreadMutexAttr { + public: + pthread_mutexattr_t attr; + inline PThreadMutexAttr(int type) { + pthread_mutexattr_init(&attr); + pthread_mutexattr_settype(&attr, type); + } + inline ~PThreadMutexAttr() { + pthread_mutexattr_destroy(&attr); + } + private: + DISALLOW_COPY_AND_ASSIGN(PThreadMutexAttr); +}; + +class PThreadRecursiveMutex : public PThreadMutex { + public: + inline PThreadRecursiveMutex() : PThreadMutex(recursive_attr()) {} + private: + static inline pthread_mutexattr_t* recursive_attr() { + static PThreadMutexAttr recursive(PTHREAD_MUTEX_RECURSIVE); + return &recursive.attr; + } + DISALLOW_COPY_AND_ASSIGN(PThreadRecursiveMutex); +}; + + +class PThreadScopedDisabledCancellation { + public: + inline PThreadScopedDisabledCancellation() { + pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &old_cancel_state_); + } + inline ~PThreadScopedDisabledCancellation() { + pthread_setcancelstate(old_cancel_state_, NULL); + } + private: + int old_cancel_state_; + + DISALLOW_COPY_AND_ASSIGN(PThreadScopedDisabledCancellation); +}; + +class PThreadCondVar { + public: + inline PThreadCondVar() { + int result = pthread_cond_init(&condvar_, 0); + DCHECK_EQ(0, result); + } + ~PThreadCondVar() { + int result = pthread_cond_destroy(&condvar_); + DCHECK_EQ(0, result); + } + inline void Signal() { + int result = pthread_cond_signal(&condvar_); + DCHECK_EQ(0, result); + } + inline void Broadcast() { + int result = pthread_cond_broadcast(&condvar_); + DCHECK_EQ(0, result); + } + pthread_cond_t condvar_; + + private: + DISALLOW_COPY_AND_ASSIGN(PThreadCondVar); +}; + +template <typename ValueType> +class PThreadThreadVar { + public: + PThreadThreadVar(void (*destructor)(void* payload)) { + int result = pthread_key_create(&thread_key_, destructor); + DCHECK_EQ(0, result); + } + ~PThreadThreadVar() { + int result = pthread_key_delete(thread_key_); + DCHECK_EQ(0, result); + } + void SetValue(ValueType value) { + int result = pthread_setspecific(thread_key_, static_cast<void*>(value)); + DCHECK_EQ(0, result); + } + ValueType GetValue() { + return static_cast<ValueType>(pthread_getspecific(thread_key_)); + } + private: + pthread_key_t thread_key_; + DISALLOW_COPY_AND_ASSIGN(PThreadThreadVar); +}; + +// Returns the absolute time ms milliseconds from now. Useful for passing +// result to pthread_cond_timedwait(). +struct timespec GetPThreadAbsoluteTime(uint32 ms_from_now); + +// Assign a descriptive label to the current thread. This is useful to see +// in a GUI debugger, but may not be implementable on all platforms. +void NameCurrentThreadForDebugging(char* name); + +#endif // CHROME_BROWSER_SYNC_UTIL_PTHREAD_HELPERS_H_ |