Add yaz_mutex_set_name to debug a MUTEX
[yaz-moved-to-github.git] / src / mutex.c
1 /* This file is part of the YAZ toolkit.
2  * Copyright (C) 1995-2010 Index Data
3  * See the file LICENSE for details.
4  */
5
6 /**
7  * \file mutex.c
8  * \brief Implements MUTEX functions
9  *
10  */
11 #if HAVE_CONFIG_H
12 #include <config.h>
13 #endif
14
15 #include <assert.h>
16 #include <stdlib.h>
17 #include <string.h>
18 #include <errno.h>
19 #include <stddef.h>
20 #include <yaz/xmalloc.h>
21 #include <yaz/nmem.h>
22 #include <yaz/log.h>
23 #include <yaz/mutex.h>
24
25 #ifdef WIN32
26 #include <windows.h>
27 #endif
28
29 #if YAZ_POSIX_THREADS
30 #include <pthread.h>
31 #endif
32
33 struct yaz_mutex {
34 #ifdef WIN32
35     CRITICAL_SECTION handle;
36 #elif YAZ_POSIX_THREADS
37     pthread_mutex_t handle;
38 #endif
39     char *name;
40 };
41
42 void yaz_mutex_create(YAZ_MUTEX *p)
43 {
44     if (!*p)
45     {
46         *p = (YAZ_MUTEX) malloc(sizeof(**p));
47 #ifdef WIN32
48         InitializeCriticalSection(&(*p)->handle);
49 #elif YAZ_POSIX_THREADS
50         pthread_mutex_init(&(*p)->handle, 0);
51 #endif
52         (*p)->name = 0;
53     }
54 }
55
56 void yaz_mutex_set_name(YAZ_MUTEX p, const char *name)
57 {
58     if (p->name)
59         free(p->name);
60     p->name = 0;
61     if (name)
62         p->name = strdup(name);
63 }
64
65 void yaz_mutex_enter(YAZ_MUTEX p)
66 {
67     if (p)
68     {
69 #ifdef WIN32
70         EnterCriticalSection(&p->handle);
71 #elif YAZ_POSIX_THREADS
72         int r = 1;
73         if (p->name)
74         {   /* debugging */
75             r = pthread_mutex_trylock(&p->handle);
76             if (r)
77             {
78                 yaz_log(YLOG_WARN|YLOG_ERRNO,
79                         "yaz_mutex_enter: %p name=%s waiting", p, p->name);
80             }
81         }
82         if (r && pthread_mutex_lock(&p->handle))
83         {
84             yaz_log(YLOG_WARN|YLOG_ERRNO, "yaz_mutex_enter: %p error", p);
85         }
86 #endif
87         if (p->name)
88         {
89             yaz_log(YLOG_LOG, "yaz_mutex_enter: %p name=%s lock", p, p->name);
90         }
91     }
92 }
93
94 void yaz_mutex_leave(YAZ_MUTEX p)
95 {
96     if (p)
97     {
98 #ifdef WIN32
99         LeaveCriticalSection(&p->handle);
100 #elif YAZ_POSIX_THREADS
101         pthread_mutex_unlock(&p->handle);
102 #endif
103         if (p->name)
104         {
105             yaz_log(YLOG_LOG, "yaz_mutex_leave: %p name=%s unlock", p, p->name);
106         }
107     }
108 }
109
110 void yaz_mutex_destroy(YAZ_MUTEX *p)
111 {
112     if (*p)
113     {
114 #ifdef WIN32
115         DeleteCriticalSection(&(*p)->handle);
116 #elif YAZ_POSIX_THREADS
117         pthread_mutex_destroy(&(*p)->handle);
118 #endif
119         if ((*p)->name)
120             free((*p)->name);
121         free(*p);
122         *p = 0;
123     }
124 }
125
126 /*
127  * Local variables:
128  * c-basic-offset: 4
129  * c-file-style: "Stroustrup"
130  * indent-tabs-mode: nil
131  * End:
132  * vim: shiftwidth=4 tabstop=8 expandtab
133  */
134