* acinclude.m4 (AC_CHECK_PTH): Added.
[libgcrypt.git] / src / ath-pth-compat.c
1 /* ath-pth-compat.c - Pth module for self-adapting thread-safeness library
2    Copyright (C) 2002 g10 Code GmbH
3
4    This file is part of Libgcrypt.
5  
6    Libgcrypt is free software; you can redistribute it and/or modify
7    it 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    Libgcrypt 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    General Public License for more details.
15  
16    You should have received a copy of the GNU Lesser General Public
17    License along with Libgcrypt; if not, write to the Free Software
18    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
19    02111-1307, USA.  */
20
21 #include <stdlib.h>
22 #include <errno.h>
23 #include <pth.h>
24
25 #include "ath.h"
26
27 #pragma weak pth_mutex_init
28 #pragma weak pth_mutex_acquire
29 #pragma weak pth_mutex_release
30 #pragma weak pth_read
31 #pragma weak pth_write
32 #pragma weak pth_select
33 #pragma weak pth_waitpid
34 #pragma weak pth_accept
35 #pragma weak pth_connect
36
37 /* The lock we take while checking for lazy lock initialization.  */
38 static pth_mutex_t check_init_lock = PTH_MUTEX_INIT;
39
40 /* Initialize the mutex *PRIV.  If JUST_CHECK is true, only do this if
41    it is not already initialized.  */
42 static int
43 mutex_pth_init (void **priv, int just_check)
44 {
45   int err = 0;
46
47   if (just_check)
48     pth_mutex_acquire (&check_init_lock, 0, NULL);
49   if (!*priv || !just_check)
50     {
51       pth_mutex_t *lock = malloc (sizeof (pth_mutex_t));
52       if (!lock)
53         err = ENOMEM;
54       if (!err)
55         {
56           err = pth_mutex_init (lock);
57           if (err == FALSE)
58             err = errno;
59           else
60             err = 0;
61
62           if (err)
63             free (lock);
64           else
65             *priv = lock;
66         }
67     }
68   if (just_check)
69     pth_mutex_release (&check_init_lock);
70   return err;
71 }
72
73
74 static int
75 mutex_pth_destroy (void *priv)
76 {
77   free (priv);
78   return 0;
79 }
80
81
82 static int
83 mutex_pth_lock (void *priv)
84 {
85   int ret = pth_mutex_acquire ((pth_mutex_t *) priv, 0, NULL);
86   return ret == FALSE ? errno : 0;
87 }
88
89
90 static int
91 mutex_pth_unlock (void *priv)
92 {
93   int ret = pth_mutex_release ((pth_mutex_t *) priv);
94   return ret == FALSE ? errno : 0;
95 }
96
97
98 static struct ath_ops ath_pth_ops =
99   {
100     mutex_pth_init,
101     mutex_pth_destroy,
102     mutex_pth_lock,
103     mutex_pth_unlock,
104     pth_read,
105     pth_write,
106     pth_select,
107     pth_waitpid,
108     pth_accept,
109     /* Pth uses const struct sockaddr, so we cast it for now. */
110     (int (*)(int s, struct sockaddr *addr, socklen_t length))pth_connect,
111     NULL,       /* FIXME: When GNU PTh has sendmsg.  */
112     NULL        /* FIXME: When GNU PTh has recvmsg.  */
113   };
114
115
116 struct ath_ops *
117 ath_pth_available (void)
118 {
119   if (pth_mutex_init && pth_mutex_acquire && pth_mutex_release
120       && pth_read && pth_write && pth_select && pth_waitpid)
121     return &ath_pth_ops;
122   else
123     return 0;
124 }