xref: /freebsd/crypto/krb5/src/ccapi/server/ccs_lock.c (revision b670c9bafc0e31c7609969bf374b2e80bdc00211)
1 /* ccapi/server/ccs_lock.c */
2 /*
3  * Copyright 2006 Massachusetts Institute of Technology.
4  * All Rights Reserved.
5  *
6  * Export of this software from the United States of America may
7  * require a specific license from the United States Government.
8  * It is the responsibility of any person or organization contemplating
9  * export to obtain such a license before exporting.
10  *
11  * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
12  * distribute this software and its documentation for any purpose and
13  * without fee is hereby granted, provided that the above copyright
14  * notice appear in all copies and that both that copyright notice and
15  * this permission notice appear in supporting documentation, and that
16  * the name of M.I.T. not be used in advertising or publicity pertaining
17  * to distribution of the software without specific, written prior
18  * permission.  Furthermore if you modify this software you must label
19  * your software as modified software and not distribute it in such a
20  * fashion that it might be confused with the original M.I.T. software.
21  * M.I.T. makes no representations about the suitability of
22  * this software for any purpose.  It is provided "as is" without express
23  * or implied warranty.
24  */
25 
26 #include "ccs_common.h"
27 
28 struct ccs_lock_d {
29     cc_uint32 type;
30     ccs_lock_state_t lock_state_owner;
31     ccs_callback_t callback;
32 };
33 
34 struct ccs_lock_d ccs_lock_initializer = { 0, NULL, NULL };
35 
36 static cc_int32 ccs_lock_invalidate_callback (ccs_callback_owner_t io_lock,
37 					      ccs_callback_t       in_callback);
38 
39 /* ------------------------------------------------------------------------ */
40 
41 cc_int32 ccs_lock_new (ccs_lock_t       *out_lock,
42                        cc_uint32         in_type,
43                        cc_int32          in_invalid_object_err,
44                        ccs_pipe_t        in_client_pipe,
45                        ccs_pipe_t        in_reply_pipe,
46                        ccs_lock_state_t  in_lock_state_owner)
47 {
48     cc_int32 err = ccNoError;
49     ccs_lock_t lock = NULL;
50 
51     if (!out_lock                       ) { err = cci_check_error (ccErrBadParam); }
52     if (!ccs_pipe_valid (in_client_pipe)) { err = cci_check_error (ccErrBadParam); }
53     if (!ccs_pipe_valid (in_reply_pipe) ) { err = cci_check_error (ccErrBadParam); }
54     if (!in_lock_state_owner            ) { err = cci_check_error (ccErrBadParam); }
55 
56     if (in_type != cc_lock_read &&
57         in_type != cc_lock_write &&
58         in_type != cc_lock_upgrade &&
59         in_type != cc_lock_downgrade) {
60         err = cci_check_error (ccErrBadLockType);
61     }
62 
63     if (!err) {
64         lock = malloc (sizeof (*lock));
65         if (lock) {
66             *lock = ccs_lock_initializer;
67         } else {
68             err = cci_check_error (ccErrNoMem);
69         }
70     }
71 
72     if (!err) {
73         lock->type = in_type;
74         lock->lock_state_owner = in_lock_state_owner;
75 
76         err = ccs_callback_new (&lock->callback,
77 				in_invalid_object_err,
78 				in_client_pipe,
79 				in_reply_pipe,
80 				(ccs_callback_owner_t) lock,
81 				ccs_lock_invalidate_callback);
82     }
83 
84     if (!err) {
85         *out_lock = lock;
86         lock = NULL;
87     }
88 
89     ccs_lock_release (lock);
90 
91     return cci_check_error (err);
92 }
93 
94 /* ------------------------------------------------------------------------ */
95 
96 cc_int32 ccs_lock_release (ccs_lock_t io_lock)
97 {
98     cc_int32 err = ccNoError;
99 
100     if (!err && io_lock) {
101 	ccs_callback_release (io_lock->callback);
102         free (io_lock);
103     }
104 
105     return cci_check_error (err);
106 }
107 
108 /* ------------------------------------------------------------------------ */
109 
110 static cc_int32 ccs_lock_invalidate_callback (ccs_callback_owner_t io_lock,
111 					      ccs_callback_t       in_callback)
112 {
113     cc_int32 err = ccNoError;
114 
115     if (!io_lock    ) { err = cci_check_error (ccErrBadParam); }
116     if (!in_callback) { err = cci_check_error (ccErrBadParam); }
117 
118     if (!err) {
119 	ccs_lock_t lock = (ccs_lock_t) io_lock;
120 
121 	err = ccs_lock_state_invalidate_lock (lock->lock_state_owner, lock);
122     }
123 
124     return cci_check_error (err);
125 }
126 
127 /* ------------------------------------------------------------------------ */
128 
129 cc_int32 ccs_lock_grant_lock (ccs_lock_t io_lock)
130 {
131     cc_int32 err = ccNoError;
132 
133     if (!io_lock) { err = cci_check_error (ccErrBadParam); }
134 
135     if (!err) {
136 	err = ccs_callback_reply_to_client (io_lock->callback, NULL);
137     }
138 
139     return cci_check_error (err);
140 }
141 
142 /* ------------------------------------------------------------------------ */
143 
144 cc_uint32 ccs_lock_is_pending (ccs_lock_t  in_lock,
145                                cc_uint32  *out_pending)
146 {
147     cc_int32 err = ccNoError;
148 
149     if (!in_lock    ) { err = cci_check_error (ccErrBadParam); }
150     if (!out_pending) { err = cci_check_error (ccErrBadParam); }
151 
152     if (!err) {
153 	err = ccs_callback_is_pending (in_lock->callback, out_pending);
154     }
155 
156     return cci_check_error (err);
157 }
158 
159 /* ------------------------------------------------------------------------ */
160 
161 cc_int32 ccs_lock_type (ccs_lock_t  in_lock,
162                         cc_uint32  *out_lock_type)
163 {
164     cc_int32 err = ccNoError;
165 
166     if (!in_lock      ) { err = cci_check_error (ccErrBadParam); }
167     if (!out_lock_type) { err = cci_check_error (ccErrBadParam); }
168 
169     if (!err) {
170         *out_lock_type = in_lock->type;
171     }
172 
173     return cci_check_error (err);
174 }
175 
176 /* ------------------------------------------------------------------------ */
177 
178 cc_int32 ccs_lock_is_read_lock (ccs_lock_t  in_lock,
179                                 cc_uint32  *out_is_read_lock)
180 {
181     cc_int32 err = ccNoError;
182 
183     if (!in_lock         ) { err = cci_check_error (ccErrBadParam); }
184     if (!out_is_read_lock) { err = cci_check_error (ccErrBadParam); }
185 
186     if (!err) {
187         *out_is_read_lock = (in_lock->type == cc_lock_read ||
188                              in_lock->type == cc_lock_downgrade);
189     }
190 
191     return cci_check_error (err);
192 }
193 
194 /* ------------------------------------------------------------------------ */
195 
196 cc_int32 ccs_lock_is_write_lock (ccs_lock_t  in_lock,
197                                  cc_uint32  *out_is_write_lock)
198 {
199     cc_int32 err = ccNoError;
200 
201     if (!in_lock          ) { err = cci_check_error (ccErrBadParam); }
202     if (!out_is_write_lock) { err = cci_check_error (ccErrBadParam); }
203 
204     if (!err) {
205         *out_is_write_lock = (in_lock->type == cc_lock_write ||
206                               in_lock->type == cc_lock_upgrade);
207     }
208 
209     return cci_check_error (err);
210 }
211 
212 /* ------------------------------------------------------------------------ */
213 
214 cc_int32 ccs_lock_is_for_client_pipe (ccs_lock_t     in_lock,
215                                       ccs_pipe_t     in_client_pipe,
216                                       cc_uint32     *out_is_for_client_pipe)
217 {
218     cc_int32 err = ccNoError;
219 
220     if (!in_lock                        ) { err = cci_check_error (ccErrBadParam); }
221     if (!ccs_pipe_valid (in_client_pipe)) { err = cci_check_error (ccErrBadParam); }
222     if (!out_is_for_client_pipe         ) { err = cci_check_error (ccErrBadParam); }
223 
224     if (!err) {
225 	err = ccs_callback_is_for_client_pipe (in_lock->callback, in_client_pipe,
226 					       out_is_for_client_pipe);
227     }
228 
229     return cci_check_error (err);
230 }
231 
232 
233 /* ------------------------------------------------------------------------ */
234 
235 cc_int32 ccs_lock_client_pipe (ccs_lock_t  in_lock,
236                                ccs_pipe_t *out_client_pipe)
237 {
238     cc_int32 err = ccNoError;
239 
240     if (!in_lock        ) { err = cci_check_error (ccErrBadParam); }
241     if (!out_client_pipe) { err = cci_check_error (ccErrBadParam); }
242 
243     if (!err) {
244 	err = ccs_callback_client_pipe (in_lock->callback, out_client_pipe);
245     }
246 
247     return cci_check_error (err);
248 }
249