1 /*
2  * pthread_rwlock_init.c
3  *
4  * Description:
5  * This translation unit implements read/write lock primitives.
6  *
7  * --------------------------------------------------------------------------
8  *
9  *      Pthreads4w - POSIX Threads for Windows
10  *      Copyright 1998 John E. Bossom
11  *      Copyright 1999-2018, Pthreads4w contributors
12  *
13  *      Homepage: https://sourceforge.net/projects/pthreads4w/
14  *
15  *      The current list of contributors is contained
16  *      in the file CONTRIBUTORS included with the source
17  *      code distribution. The list can also be seen at the
18  *      following World Wide Web location:
19  *
20  *      https://sourceforge.net/p/pthreads4w/wiki/Contributors/
21  *
22  * Licensed under the Apache License, Version 2.0 (the "License");
23  * you may not use this file except in compliance with the License.
24  * You may obtain a copy of the License at
25  *
26  *     http://www.apache.org/licenses/LICENSE-2.0
27  *
28  * Unless required by applicable law or agreed to in writing, software
29  * distributed under the License is distributed on an "AS IS" BASIS,
30  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
31  * See the License for the specific language governing permissions and
32  * limitations under the License.
33  */
34 
35 #ifdef HAVE_CONFIG_H
36 # include <config.h>
37 #endif
38 
39 #include <limits.h>
40 
41 #include "pthread.h"
42 #include "implement.h"
43 
44 int
pthread_rwlock_init(pthread_rwlock_t * rwlock,const pthread_rwlockattr_t * attr)45 pthread_rwlock_init (pthread_rwlock_t * rwlock,
46 		     const pthread_rwlockattr_t * attr)
47 {
48   int result;
49   pthread_rwlock_t rwl = 0;
50 
51   if (rwlock == NULL)
52     {
53       return EINVAL;
54     }
55 
56   if (attr != NULL && *attr != NULL)
57     {
58       result = EINVAL;		/* Not supported */
59       goto DONE;
60     }
61 
62   rwl = (pthread_rwlock_t) calloc (1, sizeof (*rwl));
63 
64   if (rwl == NULL)
65     {
66       result = ENOMEM;
67       goto DONE;
68     }
69 
70   rwl->nSharedAccessCount = 0;
71   rwl->nExclusiveAccessCount = 0;
72   rwl->nCompletedSharedAccessCount = 0;
73 
74   result = pthread_mutex_init (&rwl->mtxExclusiveAccess, NULL);
75   if (result != 0)
76     {
77       goto FAIL0;
78     }
79 
80   result = pthread_mutex_init (&rwl->mtxSharedAccessCompleted, NULL);
81   if (result != 0)
82     {
83       goto FAIL1;
84     }
85 
86   result = pthread_cond_init (&rwl->cndSharedAccessCompleted, NULL);
87   if (result != 0)
88     {
89       goto FAIL2;
90     }
91 
92   rwl->nMagic =  __PTW32_RWLOCK_MAGIC;
93 
94   result = 0;
95   goto DONE;
96 
97 FAIL2:
98   (void) pthread_mutex_destroy (&(rwl->mtxSharedAccessCompleted));
99 
100 FAIL1:
101   (void) pthread_mutex_destroy (&(rwl->mtxExclusiveAccess));
102 
103 FAIL0:
104   (void) free (rwl);
105   rwl = NULL;
106 
107 DONE:
108   *rwlock = rwl;
109 
110   return result;
111 }
112