6360e30e42bf88dcc8a04937184bf289702b0877
[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     int log_level;
41 };
42
43 void yaz_mutex_create(YAZ_MUTEX *p)
44 {
45     if (!*p)
46     {
47         *p = (YAZ_MUTEX) malloc(sizeof(**p));
48 #ifdef WIN32
49         InitializeCriticalSection(&(*p)->handle);
50 #elif YAZ_POSIX_THREADS
51         pthread_mutex_init(&(*p)->handle, 0);
52 #endif
53         (*p)->name = 0;
54         (*p)->log_level = 0;
55     }
56 }
57
58 void yaz_mutex_set_name(YAZ_MUTEX p, int log_level, const char *name)
59 {
60     if (p->name)
61         free(p->name);
62     p->name = 0;
63     p->log_level = 0;
64     if (name)
65     {
66         p->name = strdup(name);
67         p->log_level = log_level;
68     }
69 }
70
71 void yaz_mutex_enter(YAZ_MUTEX p)
72 {
73     if (p)
74     {
75 #ifdef WIN32
76         EnterCriticalSection(&p->handle);
77 #elif YAZ_POSIX_THREADS
78         int r = 1;
79         if (p->log_level)
80         {   /* debugging */
81             r = pthread_mutex_trylock(&p->handle);
82             if (r)
83             {
84                 yaz_log(p->log_level,
85                         "yaz_mutex_enter: %p name=%s waiting", p, p->name);
86             }
87         }
88         /* r == 0 if already locked */
89         if (r && pthread_mutex_lock(&p->handle))
90         {
91             yaz_log(p->log_level ? p->log_level : YLOG_WARN,
92                     "yaz_mutex_enter: %p error", p);
93         }
94 #endif
95         if (p->log_level)
96         {
97             yaz_log(p->log_level, "yaz_mutex_enter: %p name=%s lock", p,
98                     p->name);
99         }
100     }
101 }
102
103 void yaz_mutex_leave(YAZ_MUTEX p)
104 {
105     if (p)
106     {
107 #ifdef WIN32
108         LeaveCriticalSection(&p->handle);
109 #elif YAZ_POSIX_THREADS
110         pthread_mutex_unlock(&p->handle);
111 #endif
112         if (p->log_level)
113         {
114             yaz_log(p->log_level, "yaz_mutex_leave: %p name=%s unlock", p,
115                     p->name);
116         }
117     }
118 }
119
120 void yaz_mutex_destroy(YAZ_MUTEX *p)
121 {
122     if (*p)
123     {
124 #ifdef WIN32
125         DeleteCriticalSection(&(*p)->handle);
126 #elif YAZ_POSIX_THREADS
127         pthread_mutex_destroy(&(*p)->handle);
128 #endif
129         if ((*p)->name)
130             free((*p)->name);
131         free(*p);
132         *p = 0;
133     }
134 }
135
136 /*
137  * Local variables:
138  * c-basic-offset: 4
139  * c-file-style: "Stroustrup"
140  * indent-tabs-mode: nil
141  * End:
142  * vim: shiftwidth=4 tabstop=8 expandtab
143  */
144