added gentoo ebuilds
[libmixp.git] / libmixp / thread_pthread.c
blob8b2465a71789f7890be6da19fca78013cc673e2f
1 #include <errno.h>
2 #include <pthread.h>
3 #include <stdlib.h>
4 #include <unistd.h>
5 #include <9p-mixp/err.h>
6 #include "mixp_local.h"
7 #include "mixp_pthread.h"
9 static MIXP_THREAD ixp_pthread;
10 static pthread_key_t errstr_k;
12 int
13 ixp_pthread_init() {
14 int ret;
16 ret = pthread_key_create(&errstr_k, free);
17 if(ret) {
18 mixp_werrstr("can't create TLS value: %s", mixp_errbuf());
19 return 1;
22 mixp_thread = &ixp_pthread;
23 return 0;
26 static char*
27 errbuf(void) {
28 char *ret;
30 ret = pthread_getspecific(errstr_k);
31 if(ret == NULL) {
32 ret = calloc(1,IXP_ERRMAX);
33 pthread_setspecific(errstr_k, (void*)ret);
35 return ret;
38 static void
39 mlock(MIXP_MUTEX *m) {
40 pthread_mutex_lock(m->aux);
43 static int
44 mcanlock(MIXP_MUTEX *m) {
45 return !pthread_mutex_trylock(m->aux);
48 static void
49 munlock(MIXP_MUTEX *m) {
50 pthread_mutex_unlock(m->aux);
53 static void
54 mdestroy(MIXP_MUTEX *m) {
55 pthread_mutex_destroy(m->aux);
56 free(m->aux);
59 static int
60 initmutex(MIXP_MUTEX *m) {
61 pthread_mutex_t *mutex;
63 mutex = calloc(1,sizeof *mutex);
64 if(pthread_mutex_init(mutex, NULL)) {
65 free(mutex);
66 return 1;
69 m->aux = mutex;
70 return 0;
73 static void
74 rlock(MIXP_RWLOCK *rw) {
75 pthread_rwlock_rdlock(rw->aux);
78 static int
79 canrlock(MIXP_RWLOCK *rw) {
80 return !pthread_rwlock_tryrdlock(rw->aux);
83 static void
84 wlock(MIXP_RWLOCK *rw) {
85 pthread_rwlock_rdlock(rw->aux);
88 static int
89 canwlock(MIXP_RWLOCK *rw) {
90 return !pthread_rwlock_tryrdlock(rw->aux);
93 static void
94 rwunlock(MIXP_RWLOCK *rw) {
95 pthread_rwlock_unlock(rw->aux);
98 static void
99 rwdestroy(MIXP_RWLOCK *rw) {
100 pthread_rwlock_destroy(rw->aux);
101 free(rw->aux);
104 static int
105 initrwlock(MIXP_RWLOCK *rw) {
106 pthread_rwlock_t *rwlock;
108 rwlock = calloc(1,sizeof *rwlock);
109 if(pthread_rwlock_init(rwlock, NULL)) {
110 free(rwlock);
111 return 1;
114 rw->aux = rwlock;
115 return 0;
118 static void
119 rsleep(MIXP_RENDEZ *r) {
120 pthread_cond_wait(r->aux, r->mutex->aux);
123 static int
124 rwake(MIXP_RENDEZ *r) {
125 pthread_cond_signal(r->aux);
126 return 0;
129 static int
130 rwakeall(MIXP_RENDEZ *r) {
131 pthread_cond_broadcast(r->aux);
132 return 0;
135 static void
136 rdestroy(MIXP_RENDEZ *r) {
137 pthread_cond_destroy(r->aux);
138 free(r->aux);
141 static int
142 initrendez(MIXP_RENDEZ *r) {
143 pthread_cond_t *cond;
145 cond = calloc(1,sizeof *cond);
146 if(pthread_cond_init(cond, NULL)) {
147 free(cond);
148 return 1;
151 r->aux = cond;
152 return 0;
155 static MIXP_THREAD ixp_pthread = {
156 /* Mutex */
157 .initmutex = initmutex,
158 .lock = mlock,
159 .canlock = mcanlock,
160 .unlock = munlock,
161 .mdestroy = mdestroy,
162 /* RWLock */
163 .initrwlock = initrwlock,
164 .rlock = rlock,
165 .canrlock = canrlock,
166 .wlock = wlock,
167 .canwlock = canwlock,
168 .runlock = rwunlock,
169 .wunlock = rwunlock,
170 .rwdestroy = rwdestroy,
171 /* Rendez */
172 .initrendez = initrendez,
173 .sleep = rsleep,
174 .wake = rwake,
175 .wakeall = rwakeall,
176 .rdestroy = rdestroy,
177 /* Other */
178 .errbuf = errbuf,
179 .read = read,
180 .write = write,