[cairo] Locking policy (and new cairo_hash_table interface)

Carl Worth cworth at cworth.org
Wed Jun 29 07:21:17 PDT 2005


On Sun, 26 Jun 2005 21:29:41 -0700, Keith Packard wrote:
> First off, we need to list all of the mutexes and either assert that
> there are no simultaneous locks or define a locking order when there
> are.
> 
> Second, we need to mark areas of code which must be protected by each
> lock, and track down the call graph to the bottom ensuring that both the
> above ordering rules are followed as well as avoiding any recursive
> locks.

I started trying to look at this, but found that the cairo-cache.c
code was making the review process hard. The derived-object interface
and the burying of object creation under _cairo_cache_lookup make
every usage of the cache code very hard to follow.

As a first step in cleaning this up, I've now committed a new file
cairo-hash.c which uses the same basic algorithm to implement a hash
table with a much kinder interface (see below).

From here, I'll add an easy way to get a "cache" from the hash table,
(ie. some easy way of removing entries to maintain a memory quota),
and then I'll start porting usage over to the new code. While I do
that, I'll ensure that the locking behavior is sound.

Any review or help will be appreciated of course.

-Carl

PS. Here's the new interface from cairo-hash-table-private.h. After
I'd finished designing this, I checked glib and found I'd reinvented
an interface almost identical to that of GHashTable. For the sake of
those who are used to using that code, I've now renamed a couple of
operations to reinforce that similarity (store->insert,
iterate->foreach).

typedef struct _cairo_hash_table cairo_hash_table_t;

typedef unsigned long
(*cairo_compute_hash_func_t) (void *key);

typedef cairo_bool_t
(*cairo_keys_equal_func_t) (void *key_a, void *key_b);

typedef void
(*cairo_hash_callback_func_t) (void *key,
			       void *value,
			       void *closure);

cairo_private cairo_hash_table_t *
_cairo_hash_table_create (cairo_compute_hash_func_t compute_hash,
			  cairo_keys_equal_func_t   keys_equal,
			  cairo_destroy_func_t	    key_destroy,
			  cairo_destroy_func_t	    value_destroy);

cairo_private void
_cairo_hash_table_destroy (cairo_hash_table_t *hash_table);

cairo_private cairo_bool_t
_cairo_hash_table_lookup (cairo_hash_table_t *hash_table,
			  void		     *key,
			  void		    **value_return);

cairo_private cairo_status_t
_cairo_hash_table_insert (cairo_hash_table_t *hash_table,
			  void		     *key,
			  void		     *value);

cairo_private void
_cairo_hash_table_remove (cairo_hash_table_t *hash_table,
			  void		     *key);

cairo_private void
_cairo_hash_table_foreach (cairo_hash_table_t 	      *hash_table,
			   cairo_hash_callback_func_t  hash_callback,
			   void			      *closure);
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 189 bytes
Desc: not available
Url : http://lists.freedesktop.org/archives/cairo/attachments/20050629/56ab510d/attachment.pgp


More information about the cairo mailing list