1 /*
2  * Copyright (C) 2000-2020 the xine project
3  *
4  * This file is part of xine, a free video player.
5  *
6  * xine is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * xine is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
19  */
20 
21 #ifdef HAVE_CONFIG_H
22 #include "config.h"
23 #endif
24 
25 #include <pthread.h>
26 
27 #define LOG_MODULE "refcounter"
28 #define LOG_VERBOSE
29 /*
30 #define LOG
31 */
32 
33 #include <xine/xine_internal.h>
34 #include <xine/refcounter.h>
35 
_x_new_refcounter(void * object,void (* destructor)(void *))36 refcounter_t* _x_new_refcounter(void *object, void (*destructor)(void *))
37 {
38   refcounter_t *new_refcounter;
39 
40   new_refcounter = (refcounter_t *) calloc(1, sizeof(refcounter_t));
41   if (!new_refcounter)
42     return NULL;
43   new_refcounter->count      = 1;
44   new_refcounter->object     = object;
45   new_refcounter->destructor = destructor;
46   pthread_mutex_init (&new_refcounter->lock, NULL);
47   lprintf("new referenced object %p\n", object);
48   return new_refcounter;
49 }
50 
_x_refcounter_inc(refcounter_t * refcounter)51 int _x_refcounter_inc(refcounter_t *refcounter)
52 {
53   int res;
54 
55   pthread_mutex_lock(&refcounter->lock);
56   _x_assert(refcounter->count > 0);
57   res = ++refcounter->count;
58   pthread_mutex_unlock(&refcounter->lock);
59 
60   return res;
61 }
62 
_x_refcounter_dec(refcounter_t * refcounter)63 int _x_refcounter_dec(refcounter_t *refcounter)
64 {
65   int res;
66 
67   pthread_mutex_lock(&refcounter->lock);
68   res = --refcounter->count;
69   pthread_mutex_unlock(&refcounter->lock);
70   if (!res) {
71     lprintf("calling destructor of object %p\n", refcounter->object);
72     refcounter->destructor(refcounter->object);
73   }
74 
75   return res;
76 }
77 
_x_refcounter_dispose(refcounter_t * refcounter)78 void _x_refcounter_dispose(refcounter_t *refcounter)
79 {
80   pthread_mutex_destroy (&refcounter->lock);
81   free(refcounter);
82 }
83