2011-02-02 Marcus Brinkmann <mb@g10code.com>
[gpgme.git] / src / ath-pth.c
1 /* ath-pth.c - Pth 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
22 #ifdef HAVE_CONFIG_H
23 #include <config.h>
24 #endif
25
26 #include <stdlib.h>
27 #include <errno.h>
28
29 #include <pth.h>
30
31 #include "ath.h"
32
33
34 /* The lock we take while checking for lazy lock initialization.  */
35 static pth_mutex_t check_init_lock = PTH_MUTEX_INIT;
36
37
38 uintptr_t
39 ath_self (void)
40 {
41   return (uintptr_t) pth_self ();
42 }
43
44
45 /* Initialize the mutex *PRIV.  If JUST_CHECK is true, only do this if
46    it is not already initialized.  */
47 static int
48 mutex_pth_init (ath_mutex_t *priv, int just_check)
49 {
50   int err = 0;
51
52   if (just_check)
53     pth_mutex_acquire (&check_init_lock, 0, NULL);
54   if (!*priv || !just_check)
55     {
56       pth_mutex_t *lock = malloc (sizeof (pth_mutex_t));
57       if (!lock)
58         err = ENOMEM;
59       if (!err)
60         {
61           err = pth_mutex_init (lock);
62           if (err == FALSE)
63             err = errno;
64           else
65             err = 0;
66
67           if (err)
68             free (lock);
69           else
70             *priv = (ath_mutex_t) lock;
71         }
72     }
73   if (just_check)
74     pth_mutex_release (&check_init_lock);
75   return err;
76 }
77
78
79 void
80 ath_init (void)
81 {
82   /* Nothing to do.  */
83 }
84
85
86 int
87 ath_mutex_init (ath_mutex_t *lock)
88 {
89   return mutex_pth_init (lock, 0);
90 }
91
92
93 int
94 ath_mutex_destroy (ath_mutex_t *lock)
95 {
96   int err = mutex_pth_init (lock, 1);
97   if (!err)
98     {
99       /* GNU Pth has no destructor function.  */
100       free (*lock);
101     }
102   return err;
103 }
104
105
106 int
107 ath_mutex_lock (ath_mutex_t *lock)
108 {
109   int ret = mutex_pth_init (lock, 1);
110   if (ret)
111     return ret;
112
113   ret = pth_mutex_acquire ((pth_mutex_t *) *lock, 0, NULL);
114   return ret == FALSE ? errno : 0;
115 }
116
117
118 int
119 ath_mutex_unlock (ath_mutex_t *lock)
120 {
121   int ret = mutex_pth_init (lock, 1);
122   if (ret)
123     return ret;
124
125   ret = pth_mutex_release ((pth_mutex_t *) *lock);
126   return ret == FALSE ? errno : 0;
127 }
128
129
130 ssize_t
131 ath_read (int fd, void *buf, size_t nbytes)
132 {
133   return pth_read (fd, buf, nbytes);
134 }
135
136
137 ssize_t
138 ath_write (int fd, const void *buf, size_t nbytes)
139 {
140   return pth_write (fd, buf, nbytes);
141 }
142
143
144 ssize_t
145 ath_select (int nfd, fd_set *rset, fd_set *wset, fd_set *eset,
146             struct timeval *timeout)
147 {
148   return pth_select (nfd, rset, wset, eset, timeout);
149 }
150
151  
152 ssize_t
153 ath_waitpid (pid_t pid, int *status, int options)
154 {
155   return pth_waitpid (pid, status, options);
156 }
157
158
159 int
160 ath_accept (int s, struct sockaddr *addr, socklen_t *length_ptr)
161 {
162   return pth_accept (s, addr, length_ptr);
163 }
164
165
166 int
167 ath_connect (int s, const struct sockaddr *addr, socklen_t length)
168 {
169   return pth_connect (s, addr, length);
170 }
171
172 int
173 ath_sendmsg (int s, const struct msghdr *msg, int flags)
174 {
175   /* FIXME: GNU Pth is missing pth_sendmsg.  */
176   return sendmsg (s, msg, flags);
177 }
178
179
180 int
181 ath_recvmsg (int s, struct msghdr *msg, int flags)
182 {
183   /* FIXME: GNU Pth is missing pth_recvmsg.  */
184   return recvmsg (s, msg, flags);
185 }
186