2009-11-04 Marcus Brinkmann <marcus@g10code.de>
[gpgme.git] / src / ath-pthread.c
1 /* ath-pthread.c - pthread module for self-adapting thread-safeness library
2    Copyright (C) 2002, 2003, 2004 g10 Code GmbH
3
4    This file is part of GPGME.
5  
6    GPGME is free software; you can redistribute it and/or modify it
7    under the terms of the GNU Lesser General Public License as
8    published by the Free Software Foundation; either version 2.1 of
9    the License, or (at your option) any later version.
10    
11    GPGME is distributed in the hope that it will be useful, but
12    WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14    Lesser General Public License for more details.
15    
16    You should have received a copy of the GNU Lesser General Public
17    License along with this program; if not, write to the Free Software
18    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
19    02111-1307, USA.  */
20
21 #ifdef HAVE_CONFIG_H
22 #include <config.h>
23 #endif
24
25 #include <stdlib.h>
26 #include <errno.h>
27 #include <unistd.h>
28 #ifdef HAVE_SYS_SELECT_H
29 # include <sys/select.h>
30 #else
31 # include <sys/time.h>
32 #endif
33 #include <sys/types.h>
34 #include <sys/wait.h>
35
36 #include <pthread.h>
37
38 #include "ath.h"
39
40
41 /* The lock we take while checking for lazy lock initialization.  */
42 static pthread_mutex_t check_init_lock = PTHREAD_MUTEX_INITIALIZER;
43
44 /* Initialize the mutex *PRIV.  If JUST_CHECK is true, only do this if
45    it is not already initialized.  */
46 static int
47 mutex_pthread_init (ath_mutex_t *priv, int just_check)
48 {
49   int err = 0;
50
51   if (just_check)
52     pthread_mutex_lock (&check_init_lock);
53   if (!*priv || !just_check)
54     {
55       pthread_mutex_t *lock = malloc (sizeof (pthread_mutex_t));
56       if (!lock)
57         err = ENOMEM;
58       if (!err)
59         {
60           err = pthread_mutex_init (lock, NULL);
61           if (err)
62             free (lock);
63           else
64             *priv = (ath_mutex_t) lock;
65         }
66     }
67   if (just_check)
68     pthread_mutex_unlock (&check_init_lock);
69   return err;
70 }
71
72
73 void
74 ath_init (void)
75 {
76   /* Nothing to do.  */
77 }
78
79
80 uintptr_t
81 ath_self (void)
82 {
83   return (uintptr_t) pthread_self ();
84 }
85
86
87 int
88 ath_mutex_init (ath_mutex_t *lock)
89 {
90   return mutex_pthread_init (lock, 0);
91 }
92
93
94 int
95 ath_mutex_destroy (ath_mutex_t *lock)
96 {
97   int err = mutex_pthread_init (lock, 1);
98   if (!err)
99     {
100       err = pthread_mutex_destroy ((pthread_mutex_t *) *lock);
101       free (*lock);
102     }
103   return err;
104 }
105
106
107 int
108 ath_mutex_lock (ath_mutex_t *lock)
109 {
110   int ret = mutex_pthread_init (lock, 1);
111   if (ret)
112     return ret;
113
114   return pthread_mutex_lock ((pthread_mutex_t *) *lock);
115 }
116
117
118 int
119 ath_mutex_unlock (ath_mutex_t *lock)
120 {
121   int ret = mutex_pthread_init (lock, 1);
122   if (ret)
123     return ret;
124
125   return pthread_mutex_unlock ((pthread_mutex_t *) *lock);
126 }
127
128
129 ssize_t
130 ath_read (int fd, void *buf, size_t nbytes)
131 {
132   return read (fd, buf, nbytes);
133 }
134
135
136 ssize_t
137 ath_write (int fd, const void *buf, size_t nbytes)
138 {
139   return write (fd, buf, nbytes);
140 }
141
142
143 ssize_t
144 ath_select (int nfd, fd_set *rset, fd_set *wset, fd_set *eset,
145             struct timeval *timeout)
146 {
147   return select (nfd, rset, wset, eset, timeout);
148 }
149
150  
151 ssize_t
152 ath_waitpid (pid_t pid, int *status, int options)
153 {
154   return waitpid (pid, status, options);
155 }
156
157
158 int
159 ath_accept (int s, struct sockaddr *addr, socklen_t *length_ptr)
160 {
161   return accept (s, addr, length_ptr);
162 }
163
164
165 int
166 ath_connect (int s, const struct sockaddr *addr, socklen_t length)
167 {
168   return connect (s, addr, length);
169 }
170
171 int
172 ath_sendmsg (int s, const struct msghdr *msg, int flags)
173 {
174   return sendmsg (s, msg, flags);
175 }
176
177
178 int
179 ath_recvmsg (int s, struct msghdr *msg, int flags)
180 {
181   return recvmsg (s, msg, flags);
182 }