2003-07-30 Moritz Schulte <moritz@g10code.com>
[libgcrypt.git] / src / ath-pth.c
1 /* ath-pth.c - Pth module for self-adapting thread-safeness library
2  *      Copyright (C) 2002 g10 Code GmbH
3  *      Copyright (C) 2002 Free Software Foundation, Inc.
4  *
5  * This file is part of Libgcrypt.
6  *
7  * Libgcrypt is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU Lesser General Public License as
9  * published by the Free Software Foundation; either version 2.1 of
10  * the License, or (at your option) any later version.
11  *
12  * Libgcrypt is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with this program; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
20  */
21
22 #include <stdlib.h>
23 #include <errno.h>
24 #include <pth.h>
25
26 #include "ath.h"
27
28 #pragma weak pth_mutex_init
29 #pragma weak pth_mutex_acquire
30 #pragma weak pth_mutex_release
31 #pragma weak pth_read
32 #pragma weak pth_write
33 #pragma weak pth_select
34 #pragma weak pth_waitpid
35
36 /* The lock we take while checking for lazy lock initialization.  */
37 static pth_mutex_t check_init_lock = PTH_MUTEX_INIT;
38
39 /* Initialize the mutex *PRIV.  If JUST_CHECK is true, only do this if
40    it is not already initialized.  */
41 static int
42 mutex_pth_init (void **priv, int just_check)
43 {
44   int err = 0;
45
46   if (just_check)
47     pth_mutex_acquire (&check_init_lock, 0, NULL);
48   if (!*priv || !just_check)
49     {
50       pth_mutex_t *lock = malloc (sizeof (pth_mutex_t));
51       if (!lock)
52         err = ENOMEM;
53       if (!err)
54         {
55           err = pth_mutex_init (lock);
56           if (err == FALSE)
57             err = errno;
58           else
59             err = 0;
60
61           if (err)
62             free (lock);
63           else
64             *priv = lock;
65         }
66     }
67   if (just_check)
68     pth_mutex_release (&check_init_lock);
69   return err;
70 }
71
72
73 static int
74 mutex_pth_destroy (void *priv)
75 {
76   free (priv);
77   return 0;
78 }
79
80
81 static int
82 mutex_pth_lock (void *priv)
83 {
84   int ret = pth_mutex_acquire ((pth_mutex_t *) priv, 0, NULL);
85   return ret == FALSE ? errno : 0;
86 }
87
88
89 static int
90 mutex_pth_unlock (void *priv)
91 {
92   int ret = pth_mutex_release ((pth_mutex_t *) priv);
93   return ret == FALSE ? errno : 0;
94 }
95
96
97 static struct ath_ops ath_pth_ops =
98   {
99     mutex_pth_init,
100     mutex_pth_destroy,
101     mutex_pth_lock,
102     mutex_pth_unlock,
103     pth_read,
104     pth_write,
105     pth_select,
106     pth_waitpid
107   };
108
109
110 struct ath_ops *
111 ath_pth_available (void)
112 {
113   if (pth_mutex_init && pth_mutex_acquire && pth_mutex_release
114       && pth_read && pth_write && pth_select && pth_waitpid)
115     return &ath_pth_ops;
116   else
117     return 0;
118 }
119
120
121
122
123
124