diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/ChangeLog | 5 | ||||
| -rw-r--r-- | src/gpgme.c | 26 | 
2 files changed, 25 insertions, 6 deletions
| diff --git a/src/ChangeLog b/src/ChangeLog index dc1e1164..68619136 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,8 @@ +2009-06-16  Marcus Brinkmann  <[email protected]> + +	* gpgme.c (result_ref_lock): New global variable. +	(gpgme_result_ref, gpgme_result_unref): use it. +  2009-06-16  Werner Koch  <[email protected]>  	* gpgme.h.in (gpgme_op_export_keys_start, gpgme_op_export_keys): New. diff --git a/src/gpgme.c b/src/gpgme.c index 2372a06a..73788e7e 100644 --- a/src/gpgme.c +++ b/src/gpgme.c @@ -45,6 +45,10 @@ static char *def_lc_messages;  gpgme_error_t _gpgme_selftest = GPG_ERR_NOT_OPERATIONAL; +/* Protects all reference counters in result structures.  All other +   accesses to a key are read only.  */ +DEFINE_STATIC_LOCK (result_ref_lock); +  /* Create a new context as an environment for GPGME crypto     operations.  */ @@ -178,29 +182,39 @@ gpgme_release (gpgme_ctx_t ctx)  void  gpgme_result_ref (void *result)  { -  struct ctx_op_data *data = result - sizeof (struct ctx_op_data); +  struct ctx_op_data *data;    if (! result)      return; +  data = result - sizeof (struct ctx_op_data); + +  LOCK (result_ref_lock);    data->references++; +  UNLOCK (result_ref_lock);  }  void  gpgme_result_unref (void *result)  { -  struct ctx_op_data *data = result - sizeof (struct ctx_op_data); +  struct ctx_op_data *data;    if (! result)      return; -  if (--data->references == 0) +  data = result - sizeof (struct ctx_op_data); + +  LOCK (result_ref_lock); +  if (--data->references)      { -      if (data->cleanup) -	(*data->cleanup) (data->hook); -      free (data); +      UNLOCK (result_ref_lock); +      return;      } + +  if (data->cleanup) +    (*data->cleanup) (data->hook); +  free (data);  } | 
