Re: [PATCH V3 1/4] cairo_rwlock: introduce rwlock.
Zhigang Gong <[email protected]>
| Newsgroups | gmane.comp.lib.cairo |
|---|---|
| Message-ID | <[email protected]> |
v3. Fix the broken macros for non-pthread rwlock. From d9cec85705de85b9b5d5cee425ee8d110c332b6e Mon Sep 17 00:00:00 2001 From: Zhigang Gong <[email protected]> Date: Thu, 24 May 2012 15:30:48 +0800 Subject: [PATCH V3 1/4] cairo_rwlock: introduce rwlock. Here is a scenario which make us to introduce rwlock. 1. One thread(A) is rendering to a surface which has a snapshot attached. 2. Some other threads(B...) are replaying recording surfaces which has the snapshot of the surface which is being rendered in thread 1. If thread B already started the replaying, and already get the source by using _cairo_surface_snapshot_source, then before the thread B finish its accessing to the source surface, the thread A start to rendering to the source surface. Although thread A will trigger a COW, but it's too late, as thread B already got the original surface pointer, thus the race ocurrs here, both B is reading and A is writing to the same area concurrently. To fix this issue, we need to use write lock at thread B, and use read lock at thread B to avoid the possible race condtion. Currently, we only implement pthread_rw_lock if the system supports pthread. Otherwise, we degrade the rw_lock to mutex lock. Please be noted, use mutex as rwlock may cause deadlock when replaying recording surface. Signed-off-by: Zhigang Gong <[email protected]> --- build/configure.ac.pthread | 13 ++++++ src/Makefile.sources | 3 + src/cairo-rwlock-impl-private.h | 90 +++++++++++++++++++++++++++++++++++++++ src/cairo-rwlock-private.h | 44 +++++++++++++++++++ src/cairo-rwlock-type-private.h | 82 +++++++++++++++++++++++++++++++++++ 5 files changed, 232 insertions(+), 0 deletions(-) create mode 100644 src/cairo-rwlock-impl-private.h create mode 100644 src/cairo-rwlock-private.h create mode 100644 src/cairo-rwlock-type-private.h diff --git a/build/configure.ac.pthread b/build/configure.ac.pthread index 29c930d..72ed03a 100644 --- a/build/configure.ac.pthread +++ b/build/configure.ac.pthread @@ -76,6 +76,19 @@ int test_mutex_attr (void) x |= pthread_mutex_destroy (&mutex); x |= pthread_mutexattr_destroy (&attr); return x; +} + +pthread_rwlock_t test_rwlock_initializer = PTHREAD_RWLOCK_INITIALIZER; +int test_rwlock (void) +{ + int x = 0; + pthread_rwlock_t rwlock; + x |= pthread_rwlock_init(&rwlock, NULL); + x |= pthread_rwlock_wrlock(&rwlock); + x |= pthread_rwlock_unlock(&rwlock); + x |= pthread_rwlock_rdlock(&rwlock); + x |= pthread_rwlock_unlock(&rwlock); + x |= pthread_rwlock_destroy(&rwlock); }]) dnl ----------------------------------------------------------------------- diff --git a/src/Makefile.sources b/src/Makefile.sources index f487fc1..b989e38 100644 --- a/src/Makefile.sources +++ b/src/Makefile.sources @@ -91,6 +91,9 @@ cairo_private = \ cairo-mutex-list-private.h \ cairo-mutex-private.h \ cairo-mutex-type-private.h \ + cairo-rwlock-private.h \ + cairo-rwlock-impl-private.h \ + cairo-rwlock-type-private.h \ cairo-output-stream-private.h \ cairo-paginated-private.h \ cairo-paginated-surface-private.h \ diff --git a/src/cairo-rwlock-impl-private.h b/src/cairo-rwlock-impl-private.h new file mode 100644 index 0000000..53aa6c5 --- /dev/null +++ b/src/cairo-rwlock-impl-private.h @@ -0,0 +1,90 @@ +/* cairo - a vector graphics library with display and print output + * + * Copyright © 2002 University of Southern California + * Copyright © 2005,2007 Red Hat, Inc. + * Copyright © 2007 Mathias Hasselmann + * + * This library is free software; you can redistribute it and/or + * modify it either under the terms of the GNU Lesser General Public + * License version 2.1 as published by the Free Software Foundation + * (the "LGPL") or, at your option, under the terms of the Mozilla + * Public License Version 1.1 (the "MPL"). If you do not alter this + * notice, a recipient may use your version of this file under either + * the MPL or the LGPL. + * + * You should have received a copy of the LGPL along with this library + * in the file COPYING-LGPL-2.1; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA + * You should have received a copy of the MPL along with this library + * in the file COPYING-MPL-1.1 + * + * The contents of this file are subject to the Mozilla Public License + * Version 1.1 (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.mozilla.org/MPL/ + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY + * OF ANY KIND, either express or implied. See the LGPL or the MPL for + * the specific language governing rights and limitations. + * + * The Original Code is the cairo graphics library. + * + * The Initial Developer of the Original Code is University of Southern + * California. + * + * Contributor(s): + * Zhigang Gong <[email protected]> + */ + +#ifndef CAIRO_RWLOCK_IMPL_PRIVATE_H +#define CAIRO_RWLOCK_IMPL_PRIVATE_H +#include "cairo.h" + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +/* And one that evaluates its argument once */ +#define CAIRO_RWLOCK_IMPL_NOOP1(expr) do { (void)(expr); } while (0) +/* Note: 'if (expr) {}' is an alternative to '(void)(expr);' that will 'use' the + * result of __attribute__((warn_used_result)) functions. */ + +#if CAIRO_NO_RWLOCK + +/* No rwlocks */ + + typedef int cairo_rwlock_impl_t; + +# define CAIRO_RWLOCK_IMPL_NO 1 +# define CAIRO_RWLOCK_IMPL_LOCK(rwlock) CAIRO_RWLOCK_IMPL_NOOP1(rwlock) +# define CAIRO_RWLOCK_IMPL_UNLOCK(rwlock) CAIRO_RWLOCK_IMPL_NOOP1(rwlock) +# define CAIRO_RWLOCK_IMPL_NIL_INITIALIZER 0 + +#elif !CAIRO_HAS_PTHREAD /* use mutex as rwlock ********/ +#include "cairo-mutex-private.h" + typedef cairo_mutex_t cairo_rwlock_impl_t; + +# define CAIRO_RWLOCK_IMPL_MUTEX 1 +# define CAIRO_RWLOCK_IMPL_INIT(rwlock) CAIRO_MUTEX_INIT ((rwlock)) +# define CAIRO_RWLOCK_IMPL_RDLOCK(rwlock) CAIRO_MUTEX_LOCK ((rwlock)) +# define CAIRO_RWLOCK_IMPL_WRLOCK(rwlock) CAIRO_MUTEX_LOCK ((rwlock)) +# define CAIRO_RWLOCK_IMPL_UNLOCK(rwlock) CAIRO_MUTEX_UNLOCK ((rwlock)) +# define CAIRO_RWLOCK_IMPL_FINI(rwlock) CAIRO_MUTEX_FINI ((rwlock)) +# define CAIRO_RWLOCK_IMPL_NIL_INITIALIZER CAIRO_MUTEX_NIL_INITIALIZER + +#elif CAIRO_HAS_PTHREAD /* and finally if there are no native rwlocks ********/ + +# include <pthread.h> + typedef pthread_rwlock_t cairo_rwlock_impl_t; + +# define CAIRO_RWLOCK_IMPL_PTHREAD 1 +# define CAIRO_RWLOCK_IMPL_INIT(rwlock) pthread_rwlock_init (&(rwlock), NULL) +# define CAIRO_RWLOCK_IMPL_RDLOCK(rwlock) pthread_rwlock_rdlock (&(rwlock)) +# define CAIRO_RWLOCK_IMPL_WRLOCK(rwlock) pthread_rwlock_wrlock (&(rwlock)) +# define CAIRO_RWLOCK_IMPL_UNLOCK(rwlock) pthread_rwlock_unlock (&(rwlock)) +# define CAIRO_RWLOCK_IMPL_FINI(rwlock) pthread_rwlock_destroy (&(rwlock)) +# define CAIRO_RWLOCK_IMPL_NIL_INITIALIZER PTHREAD_RWLOCK_INITIALIZER + +#endif + +#endif diff --git a/src/cairo-rwlock-private.h b/src/cairo-rwlock-private.h new file mode 100644 index 0000000..fde3ce8 --- /dev/null +++ b/src/cairo-rwlock-private.h @@ -0,0 +1,44 @@ +/* cairo - a vector graphics library with display and print output + * + * Copyright © 2002 University of Southern California + * Copyright © 2005,2007 Red Hat, Inc. + * Copyright © 2007 Mathias Hasselmann + * + * This library is free software; you can redistribute it and/or + * modify it either under the terms of the GNU Lesser General Public + * License version 2.1 as published by the Free Software Foundation + * (the "LGPL") or, at your option, under the terms of the Mozilla + * Public License Version 1.1 (the "MPL"). If you do not alter this + * notice, a recipient may use your version of this file under either + * the MPL or the LGPL. + * + * You should have received a copy of the LGPL along with this library + * in the file COPYING-LGPL-2.1; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA + * You should have received a copy of the MPL along with this library + * in the file COPYING-MPL-1.1 + * + * The contents of this file are subject to the Mozilla Public License + * Version 1.1 (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.mozilla.org/MPL/ + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY + * OF ANY KIND, either express or implied. See the LGPL or the MPL for + * the specific language governing rights and limitations. + * + * The Original Code is the cairo graphics library. + * + * The Initial Developer of the Original Code is University of Southern + * California. + * + * Contributor(s): + * Zhigang Gong <[email protected]> + */ + +#ifndef CAIRO_RWLOCK_PRIVATE_H +#define CAIRO_RWLOCK_PRIVATE_H + +#include "cairo-rwlock-type-private.h" + +#endif diff --git a/src/cairo-rwlock-type-private.h b/src/cairo-rwlock-type-private.h new file mode 100644 index 0000000..afeac9c --- /dev/null +++ b/src/cairo-rwlock-type-private.h @@ -0,0 +1,82 @@ +/* cairo - a vector graphics library with display and print output + * + * Copyright © 2002 University of Southern California + * Copyright © 2005,2007 Red Hat, Inc. + * Copyright © 2007 Mathias Hasselmann + * + * This library is free software; you can redistribute it and/or + * modify it either under the terms of the GNU Lesser General Public + * License version 2.1 as published by the Free Software Foundation + * (the "LGPL") or, at your option, under the terms of the Mozilla + * Public License Version 1.1 (the "MPL"). If you do not alter this + * notice, a recipient may use your version of this file under either + * the MPL or the LGPL. + * + * You should have received a copy of the LGPL along with this library + * in the file COPYING-LGPL-2.1; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA + * You should have received a copy of the MPL along with this library + * in the file COPYING-MPL-1.1 + * + * The contents of this file are subject to the Mozilla Public License + * Version 1.1 (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.mozilla.org/MPL/ + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY + * OF ANY KIND, either express or implied. See the LGPL or the MPL for + * the specific language governing rights and limitations. + * + * The Original Code is the cairo graphics library. + * + * The Initial Developer of the Original Code is University of Southern + * California. + * + * Contributor(s): + * Zhigang Gong <[email protected]> + */ + +#ifndef CAIRO_RWLOCK_TYPE_PRIVATE_H +#define CAIRO_RWLOCK_TYPE_PRIVATE_H + +#include "cairo-compiler-private.h" +#include "cairo-rwlock-impl-private.h" + +/* Only the following four are mandatory at this point */ +#ifndef CAIRO_RWLOCK_IMPL_RDLOCK +# error "CAIRO_RWLOCK_IMPL_RDLOCK not defined. Check cairo-rwlock-impl-private.h." +#endif +#ifndef CAIRO_RWLOCK_IMPL_WRLOCK +# error "CAIRO_RWLOCK_IMPL_WRLOCK not defined. Check cairo-rwlock-impl-private.h." +#endif +#ifndef CAIRO_RWLOCK_IMPL_UNLOCK +# error "CAIRO_RWLOCK_IMPL_UNLOCK not defined. Check cairo-rwlock-impl-private.h." +#endif +#ifndef CAIRO_RWLOCK_IMPL_NIL_INITIALIZER +# error "CAIRO_RWLOCK_IMPL_NIL_INITIALIZER not defined. Check cairo-rwlock-impl-private.h." +#endif + + +/* Make sure everything we want is defined */ +#ifndef CAIRO_RWLOCK_IMPL_INIT +# error "CAIRO_RWLOCK_IMPL_INIT not defined" +#endif +#ifndef CAIRO_RWLOCK_IMPL_FINI +# error "CAIRO_RWLOCK_IMPL_FINI not defined" +#endif +#ifndef CAIRO_RWLOCK_IMPL_NIL_INITIALIZER +# error "CAIRO_RWLOCK_IMPL_NIL_INITIALIZER not defined" +#endif + +/* Public interface. */ + +# define cairo_rwlock_t cairo_rwlock_impl_t + +#define CAIRO_RWLOCK_RDLOCK CAIRO_RWLOCK_IMPL_RDLOCK +#define CAIRO_RWLOCK_WRLOCK CAIRO_RWLOCK_IMPL_WRLOCK +#define CAIRO_RWLOCK_UNLOCK CAIRO_RWLOCK_IMPL_UNLOCK +#define CAIRO_RWLOCK_INIT CAIRO_RWLOCK_IMPL_INIT +#define CAIRO_RWLOCK_FINI CAIRO_RWLOCK_IMPL_FINI +#define CAIRO_RWLOCK_NIL_INITIALIZER CAIRO_RWLOCK_IMPL_NIL_INITIALIZER + +#endif -- 1.7.4.4 -- cairo mailing list [email protected] http://lists.cairographics.org/mailman/listinfo/cairo