2 * Copyright (c) 2005 MontaVista Software, Inc.
6 * Author: Steven Dake (sdake@mvista.com)
8 * This software licensed under BSD license, the text of which follows:
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions are met:
13 * - Redistributions of source code must retain the above copyright notice,
14 * this list of conditions and the following disclaimer.
15 * - Redistributions in binary form must reproduce the above copyright notice,
16 * this list of conditions and the following disclaimer in the documentation
17 * and/or other materials provided with the distribution.
18 * - Neither the name of the MontaVista Software, Inc. nor the names of its
19 * contributors may be used to endorse or promote products derived from this
20 * software without specific prior written permission.
22 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
23 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
26 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
27 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
28 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
29 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
30 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
31 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
32 * THE POSSIBILITY OF SUCH DAMAGE.
42 #include <sys/types.h>
44 #include <sys/socket.h>
45 #include <sys/select.h>
56 struct message_overlay
{
57 mar_res_header_t header
__attribute__((aligned(8)));
62 * Data structure for instance data
67 SaLckCallbacksT callbacks
;
69 SaLckHandleT lckHandle
;
70 struct list_head resource_list
;
71 pthread_mutex_t response_mutex
;
72 pthread_mutex_t dispatch_mutex
;
75 struct lckResourceInstance
{
77 SaLckHandleT lckHandle
;
78 SaLckResourceHandleT lckResourceHandle
;
79 SaLckResourceOpenFlagsT resourceOpenFlags
;
80 SaNameT lockResourceName
;
81 struct list_head list
;
82 mar_message_source_t source
;
83 pthread_mutex_t
*response_mutex
;
86 struct lckLockIdInstance
{
88 SaLckResourceHandleT lckResourceHandle
;
89 struct list_head list
;
91 pthread_mutex_t
*response_mutex
;
94 void lckHandleInstanceDestructor (void *instance
);
95 void lckResourceHandleInstanceDestructor (void *instance
);
96 void lckResourceHandleLockIdInstanceDestructor (void *instance
);
99 * All LCK instances in this database
101 static struct saHandleDatabase lckHandleDatabase
= {
104 .mutex
= PTHREAD_MUTEX_INITIALIZER
,
105 .handleInstanceDestructor
= lckHandleInstanceDestructor
109 * All Resource instances in this database
111 static struct saHandleDatabase lckResourceHandleDatabase
= {
114 .mutex
= PTHREAD_MUTEX_INITIALIZER
,
115 .handleInstanceDestructor
= lckResourceHandleInstanceDestructor
119 * All Resource Lock Identifier instances in this database
121 static struct saHandleDatabase lckLockIdHandleDatabase
= {
124 .mutex
= PTHREAD_MUTEX_INITIALIZER
,
125 .handleInstanceDestructor
= lckResourceHandleLockIdInstanceDestructor
131 static SaVersionT lckVersionsSupported
[] = {
135 static struct saVersionDatabase lckVersionDatabase
= {
136 sizeof (lckVersionsSupported
) / sizeof (SaVersionT
),
144 void lckHandleInstanceDestructor (void *instance
)
146 struct lckInstance
*lckInstance
= instance
;
148 pthread_mutex_destroy (&lckInstance
->response_mutex
);
149 pthread_mutex_destroy (&lckInstance
->dispatch_mutex
);
152 void lckResourceHandleInstanceDestructor (void *instance
)
156 void lckResourceHandleLockIdInstanceDestructor (void *instance
)
161 static void lckSectionIterationInstanceFinalize (struct lckSectionIterationInstance
*lckSectionIterationInstance
)
163 struct iteratorSectionIdListEntry
*iteratorSectionIdListEntry
;
164 struct list_head
*sectionIdIterationList
;
165 struct list_head
*sectionIdIterationListNext
;
167 * iterate list of section ids for this iterator to free the allocated memory
168 * be careful to cache next pointer because free removes memory from use
170 for (sectionIdIterationList
= lckSectionIterationInstance
->sectionIdListHead
.next
,
171 sectionIdIterationListNext
= sectionIdIterationList
->next
;
172 sectionIdIterationList
!= &lckSectionIterationInstance
->sectionIdListHead
;
173 sectionIdIterationList
= sectionIdIterationListNext
,
174 sectionIdIterationListNext
= sectionIdIterationList
->next
) {
176 iteratorSectionIdListEntry
= list_entry (sectionIdIterationList
,
177 struct iteratorSectionIdListEntry
, list
);
179 free (iteratorSectionIdListEntry
);
182 list_del (&lckSectionIterationInstance
->list
);
184 saHandleDestroy (&lckSectionIterationHandleDatabase
,
185 lckSectionIterationInstance
->sectionIterationHandle
);
188 static void lckResourceInstanceFinalize (struct lckResourceInstance
*lckResourceInstance
)
190 struct lckSectionIterationInstance
*sectionIterationInstance
;
191 struct list_head
*sectionIterationList
;
192 struct list_head
*sectionIterationListNext
;
194 for (sectionIterationList
= lckResourceInstance
->section_iteration_list_head
.next
,
195 sectionIterationListNext
= sectionIterationList
->next
;
196 sectionIterationList
!= &lckResourceInstance
->section_iteration_list_head
;
197 sectionIterationList
= sectionIterationListNext
,
198 sectionIterationListNext
= sectionIterationList
->next
) {
200 sectionIterationInstance
= list_entry (sectionIterationList
,
201 struct lckSectionIterationInstance
, list
);
203 lckSectionIterationInstanceFinalize (sectionIterationInstance
);
206 list_del (&lckResourceInstance
->list
);
208 saHandleDestroy (&lckResourceHandleDatabase
, lckResourceInstance
->lckResourceHandle
);
211 static void lckInstanceFinalize (struct lckInstance
*lckInstance
)
213 struct lckResourceInstance
*lckResourceInstance
;
214 struct list_head
*resourceInstanceList
;
215 struct list_head
*resourceInstanceListNext
;
217 for (resourceInstanceList
= lckInstance
->resource_list
.next
,
218 resourceInstanceListNext
= resourceInstanceList
->next
;
219 resourceInstanceList
!= &lckInstance
->resource_list
;
220 resourceInstanceList
= resourceInstanceListNext
,
221 resourceInstanceListNext
= resourceInstanceList
->next
) {
223 lckResourceInstance
= list_entry (resourceInstanceList
,
224 struct lckResourceInstance
, list
);
226 lckResourceInstanceFinalize (lckResourceInstance
);
229 saHandleDestroy (&lckHandleDatabase
, lckInstance
->lckHandle
);
236 SaLckHandleT
*lckHandle
,
237 const SaLckCallbacksT
*callbacks
,
240 struct lckInstance
*lckInstance
;
241 SaAisErrorT error
= SA_AIS_OK
;
243 if (lckHandle
== NULL
) {
244 return (SA_AIS_ERR_INVALID_PARAM
);
247 error
= saVersionVerify (&lckVersionDatabase
, version
);
248 if (error
!= SA_AIS_OK
) {
249 goto error_no_destroy
;
252 error
= saHandleCreate (&lckHandleDatabase
, sizeof (struct lckInstance
),
254 if (error
!= SA_AIS_OK
) {
255 goto error_no_destroy
;
258 error
= saHandleInstanceGet (&lckHandleDatabase
, *lckHandle
,
259 (void *)&lckInstance
);
260 if (error
!= SA_AIS_OK
) {
264 lckInstance
->response_fd
= -1;
266 error
= saServiceConnect (&lckInstance
->response_fd
,
267 &lckInstance
->dispatch_fd
, LCK_SERVICE
);
268 if (error
!= SA_AIS_OK
) {
269 goto error_put_destroy
;
273 memcpy (&lckInstance
->callbacks
, callbacks
, sizeof (SaLckCallbacksT
));
275 memset (&lckInstance
->callbacks
, 0, sizeof (SaLckCallbacksT
));
278 list_init (&lckInstance
->resource_list
);
280 lckInstance
->lckHandle
= *lckHandle
;
282 pthread_mutex_init (&lckInstance
->response_mutex
, NULL
);
285 saHandleInstancePut (&lckHandleDatabase
, *lckHandle
);
290 saHandleInstancePut (&lckHandleDatabase
, *lckHandle
);
292 saHandleDestroy (&lckHandleDatabase
, *lckHandle
);
298 saLckSelectionObjectGet (
299 const SaLckHandleT lckHandle
,
300 SaSelectionObjectT
*selectionObject
)
302 struct lckInstance
*lckInstance
;
305 if (selectionObject
== NULL
) {
306 return (SA_AIS_ERR_INVALID_PARAM
);
308 error
= saHandleInstanceGet (&lckHandleDatabase
, lckHandle
, (void *)&lckInstance
);
309 if (error
!= SA_AIS_OK
) {
313 *selectionObject
= lckInstance
->dispatch_fd
;
315 saHandleInstancePut (&lckHandleDatabase
, lckHandle
);
322 SaLckHandleT lckHandle
,
323 SaLckOptionsT
*lckOptions
)
330 const SaLckHandleT lckHandle
,
331 SaDispatchFlagsT dispatchFlags
)
336 SaLckCallbacksT callbacks
;
339 struct lckInstance
*lckInstance
;
340 struct lckResourceInstance
*lckResourceInstance
;
341 struct lckLockIdInstance
*lckLockIdInstance
;
342 int cont
= 1; /* always continue do loop except when set to 0 */
343 struct message_overlay dispatch_data
;
344 struct res_lib_lck_lockwaitercallback
*res_lib_lck_lockwaitercallback
;
345 struct res_lib_lck_resourceopenasync
*res_lib_lck_resourceopenasync
= NULL
;
346 struct res_lib_lck_resourcelockasync
*res_lib_lck_resourcelockasync
= NULL
;
347 struct res_lib_lck_resourceunlockasync
*res_lib_lck_resourceunlockasync
;
350 if (dispatchFlags
!= SA_DISPATCH_ONE
&&
351 dispatchFlags
!= SA_DISPATCH_ALL
&&
352 dispatchFlags
!= SA_DISPATCH_BLOCKING
) {
354 return (SA_AIS_ERR_INVALID_PARAM
);
357 error
= saHandleInstanceGet (&lckHandleDatabase
, lckHandle
,
358 (void *)&lckInstance
);
359 if (error
!= SA_AIS_OK
) {
364 * Timeout instantly for SA_DISPATCH_ALL
366 if (dispatchFlags
== SA_DISPATCH_ALL
) {
372 * Read data directly from socket
374 poll_fd
= lckInstance
->dispatch_fd
;
376 ufds
.events
= POLLIN
;
379 error
= saPollRetry(&ufds
, 1, timeout
);
380 if (error
!= SA_AIS_OK
) {
383 pthread_mutex_lock(&lckInstance
->dispatch_mutex
);
385 if (lckInstance
->finalize
== 1) {
390 if ((ufds
.revents
& (POLLERR
|POLLHUP
|POLLNVAL
)) != 0) {
391 error
= SA_AIS_ERR_BAD_HANDLE
;
395 dispatch_avail
= (ufds
.revents
& POLLIN
);
397 if (dispatch_avail
== 0 && dispatchFlags
== SA_DISPATCH_ALL
) {
398 pthread_mutex_unlock(&lckInstance
->dispatch_mutex
);
399 break; /* exit do while cont is 1 loop */
401 if (dispatch_avail
== 0) {
402 pthread_mutex_unlock(&lckInstance
->dispatch_mutex
);
406 memset(&dispatch_data
,0, sizeof(struct message_overlay
));
407 error
= saRecvRetry (lckInstance
->dispatch_fd
, &dispatch_data
.header
, sizeof (mar_res_header_t
));
408 if (error
!= SA_AIS_OK
) {
411 if (dispatch_data
.header
.size
> sizeof (mar_res_header_t
)) {
412 error
= saRecvRetry (lckInstance
->dispatch_fd
, &dispatch_data
.data
,
413 dispatch_data
.header
.size
- sizeof (mar_res_header_t
));
414 if (error
!= SA_AIS_OK
) {
420 * Make copy of callbacks, message data, unlock instance,
421 * and call callback. A risk of this dispatch method is that
422 * the callback routines may operate at the same time that
423 * LckFinalize has been called in another thread.
425 memcpy(&callbacks
,&lckInstance
->callbacks
, sizeof(lckInstance
->callbacks
));
426 pthread_mutex_unlock(&lckInstance
->dispatch_mutex
);
428 * Dispatch incoming response
430 switch (dispatch_data
.header
.id
) {
431 case MESSAGE_RES_LCK_LOCKWAITERCALLBACK
:
432 if (callbacks
.saLckResourceOpenCallback
== NULL
) {
435 res_lib_lck_lockwaitercallback
= (struct res_lib_lck_lockwaitercallback
*)&dispatch_data
;
436 callbacks
.saLckLockWaiterCallback (
437 res_lib_lck_lockwaitercallback
->waiter_signal
,
438 res_lib_lck_lockwaitercallback
->lock_id
,
439 res_lib_lck_lockwaitercallback
->mode_held
,
440 res_lib_lck_lockwaitercallback
->mode_requested
);
443 case MESSAGE_RES_LCK_RESOURCEOPENASYNC
:
444 if (callbacks
.saLckLockWaiterCallback
== NULL
) {
447 res_lib_lck_resourceopenasync
= (struct res_lib_lck_resourceopenasync
*)&dispatch_data
;
449 * This instance get/listadd/put required so that close
450 * later has the proper list of resources
452 if (res_lib_lck_resourceopenasync
->header
.error
== SA_AIS_OK
) {
453 error
= saHandleInstanceGet (&lckResourceHandleDatabase
,
454 res_lib_lck_resourceopenasync
->resourceHandle
,
455 (void *)&lckResourceInstance
);
457 assert (error
== SA_AIS_OK
); /* should only be valid handles here */
459 * open succeeded without error
462 callbacks
.saLckResourceOpenCallback(
463 res_lib_lck_resourceopenasync
->invocation
,
464 res_lib_lck_resourceopenasync
->resourceHandle
,
465 res_lib_lck_resourceopenasync
->header
.error
);
466 saHandleInstancePut (&lckResourceHandleDatabase
,
467 res_lib_lck_resourceopenasync
->resourceHandle
);
470 * open failed with error
472 callbacks
.saLckResourceOpenCallback(
473 res_lib_lck_resourceopenasync
->invocation
,
475 res_lib_lck_resourceopenasync
->header
.error
);
478 case MESSAGE_RES_LCK_RESOURCELOCKASYNC
:
479 DPRINT (("grant\n"));
480 if (callbacks
.saLckLockGrantCallback
== NULL
) {
483 res_lib_lck_resourcelockasync
= (struct res_lib_lck_resourcelockasync
*)&dispatch_data
;
485 * This instance get/listadd/put required so that close
486 * later has the proper list of resources
488 if (res_lib_lck_resourcelockasync
->header
.error
== SA_AIS_OK
) {
489 error
= saHandleInstanceGet (&lckLockIdHandleDatabase
,
490 res_lib_lck_resourcelockasync
->lockId
,
491 (void *)&lckLockIdInstance
);
493 assert (error
== SA_AIS_OK
); /* should only be valid handles here */
495 * open succeeded without error
497 lckLockIdInstance
->resource_lock
= res_lib_lck_resourcelockasync
->resource_lock
;
499 callbacks
.saLckLockGrantCallback(
500 res_lib_lck_resourcelockasync
->invocation
,
501 res_lib_lck_resourcelockasync
->lockStatus
,
502 res_lib_lck_resourcelockasync
->header
.error
);
503 saHandleInstancePut (&lckLockIdHandleDatabase
,
504 res_lib_lck_resourcelockasync
->lockId
);
507 * open failed with error
509 callbacks
.saLckLockGrantCallback (
510 res_lib_lck_resourceopenasync
->invocation
,
512 res_lib_lck_resourceopenasync
->header
.error
);
517 case MESSAGE_RES_LCK_RESOURCEUNLOCKASYNC
:
518 if (callbacks
.saLckResourceUnlockCallback
== NULL
) {
521 res_lib_lck_resourceunlockasync
= (struct res_lib_lck_resourceunlockasync
*)&dispatch_data
;
522 callbacks
.saLckResourceUnlockCallback (
523 res_lib_lck_resourceunlockasync
->invocation
,
524 res_lib_lck_resourceunlockasync
->header
.error
);
526 if (res_lib_lck_resourcelockasync
->header
.error
== SA_AIS_OK
) {
527 error
= saHandleInstanceGet (&lckLockIdHandleDatabase
,
528 res_lib_lck_resourceunlockasync
->lockId
,
529 (void *)&lckLockIdInstance
);
530 if (error
== SA_AIS_OK
) {
531 saHandleInstancePut (&lckLockIdHandleDatabase
, res_lib_lck_resourceunlockasync
->lockId
);
533 saHandleDestroy (&lckLockIdHandleDatabase
, res_lib_lck_resourceunlockasync
->lockId
);
539 case MESSAGE_RES_LCK_RESOURCESYNCHRONIZEASYNC
:
540 if (callbacks
.saLckResourceSynchronizeCallback
== NULL
) {
544 res_lib_lck_resourcesynchronizeasync
= (struct res_lib_lck_resourcesynchronizeasync
*) &dispatch_data
;
546 callbacks
.saLckResourceSynchronizeCallback(
547 res_lib_lck_resourcesynchronizeasync
->invocation
,
548 res_lib_lck_resourcesynchronizeasync
->header
.error
);
557 * Determine if more messages should be processed
559 switch (dispatchFlags
) {
560 case SA_DISPATCH_ONE
:
563 case SA_DISPATCH_ALL
:
565 case SA_DISPATCH_BLOCKING
:
570 pthread_mutex_unlock(&lckInstance
->dispatch_mutex
);
572 saHandleInstancePut(&lckHandleDatabase
, lckHandle
);
579 const SaLckHandleT lckHandle
)
581 struct lckInstance
*lckInstance
;
584 error
= saHandleInstanceGet (&lckHandleDatabase
, lckHandle
,
585 (void *)&lckInstance
);
586 if (error
!= SA_AIS_OK
) {
590 pthread_mutex_lock (&lckInstance
->response_mutex
);
593 * Another thread has already started finalizing
595 if (lckInstance
->finalize
) {
596 pthread_mutex_unlock (&lckInstance
->response_mutex
);
597 saHandleInstancePut (&lckHandleDatabase
, lckHandle
);
598 return (SA_AIS_ERR_BAD_HANDLE
);
601 lckInstance
->finalize
= 1;
603 pthread_mutex_unlock (&lckInstance
->response_mutex
);
605 // TODO lckInstanceFinalize (lckInstance);
607 if (lckInstance
->response_fd
!= -1) {
608 shutdown (lckInstance
->response_fd
, 0);
609 close (lckInstance
->response_fd
);
612 if (lckInstance
->dispatch_fd
!= -1) {
613 shutdown (lckInstance
->dispatch_fd
, 0);
614 close (lckInstance
->dispatch_fd
);
617 saHandleInstancePut (&lckHandleDatabase
, lckHandle
);
624 SaLckHandleT lckHandle
,
625 const SaNameT
*lockResourceName
,
626 SaLckResourceOpenFlagsT resourceOpenFlags
,
628 SaLckResourceHandleT
*lckResourceHandle
)
631 struct lckResourceInstance
*lckResourceInstance
;
632 struct lckInstance
*lckInstance
;
633 struct req_lib_lck_resourceopen req_lib_lck_resourceopen
;
634 struct res_lib_lck_resourceopen res_lib_lck_resourceopen
;
636 if (lckResourceHandle
== NULL
) {
637 return (SA_AIS_ERR_INVALID_PARAM
);
640 if (lockResourceName
== NULL
) {
641 return (SA_AIS_ERR_INVALID_PARAM
);
644 error
= saHandleInstanceGet (&lckHandleDatabase
, lckHandle
,
645 (void *)&lckInstance
);
646 if (error
!= SA_AIS_OK
) {
650 error
= saHandleCreate (&lckResourceHandleDatabase
,
651 sizeof (struct lckResourceInstance
), lckResourceHandle
);
652 if (error
!= SA_AIS_OK
) {
656 error
= saHandleInstanceGet (&lckResourceHandleDatabase
,
657 *lckResourceHandle
, (void *)&lckResourceInstance
);
658 if (error
!= SA_AIS_OK
) {
662 lckResourceInstance
->response_fd
= lckInstance
->response_fd
;
664 lckResourceInstance
->lckHandle
= lckHandle
;
665 lckResourceInstance
->lckResourceHandle
= *lckResourceHandle
;
666 lckResourceInstance
->response_mutex
= &lckInstance
->response_mutex
;
668 req_lib_lck_resourceopen
.header
.size
= sizeof (struct req_lib_lck_resourceopen
);
669 req_lib_lck_resourceopen
.header
.id
= MESSAGE_REQ_LCK_RESOURCEOPEN
;
671 marshall_to_mar_name_t (&req_lib_lck_resourceopen
.lockResourceName
, (SaNameT
*)lockResourceName
);
673 memcpy (&lckResourceInstance
->lockResourceName
, lockResourceName
, sizeof(SaNameT
));
674 req_lib_lck_resourceopen
.resourceOpenFlags
= resourceOpenFlags
;
675 req_lib_lck_resourceopen
.resourceHandle
= *lckResourceHandle
;
676 req_lib_lck_resourceopen
.async_call
= 0;
678 pthread_mutex_lock (&lckInstance
->response_mutex
);
680 error
= saSendReceiveReply (lckResourceInstance
->response_fd
,
681 &req_lib_lck_resourceopen
,
682 sizeof (struct req_lib_lck_resourceopen
),
683 &res_lib_lck_resourceopen
,
684 sizeof (struct res_lib_lck_resourceopen
));
686 pthread_mutex_unlock (&lckInstance
->response_mutex
);
688 if (res_lib_lck_resourceopen
.header
.error
!= SA_AIS_OK
) {
689 error
= res_lib_lck_resourceopen
.header
.error
;
690 goto error_put_destroy
;
693 memcpy (&lckResourceInstance
->source
,
694 &res_lib_lck_resourceopen
.source
,
695 sizeof (mar_message_source_t
));
697 saHandleInstancePut (&lckResourceHandleDatabase
, *lckResourceHandle
);
699 saHandleInstancePut (&lckHandleDatabase
, lckHandle
);
701 list_init (&lckResourceInstance
->list
);
703 list_add (&lckResourceInstance
->list
, &lckInstance
->resource_list
);
707 saHandleInstancePut (&lckResourceHandleDatabase
, *lckResourceHandle
);
709 saHandleDestroy (&lckResourceHandleDatabase
, *lckResourceHandle
);
711 saHandleInstancePut (&lckHandleDatabase
, lckHandle
);
717 saLckResourceOpenAsync (
718 SaLckHandleT lckHandle
,
719 SaInvocationT invocation
,
720 const SaNameT
*lockResourceName
,
721 SaLckResourceOpenFlagsT resourceOpenFlags
)
723 struct lckResourceInstance
*lckResourceInstance
;
724 struct lckInstance
*lckInstance
;
725 SaLckResourceHandleT lckResourceHandle
;
727 struct req_lib_lck_resourceopen req_lib_lck_resourceopen
;
728 struct res_lib_lck_resourceopenasync res_lib_lck_resourceopenasync
;
730 error
= saHandleInstanceGet (&lckHandleDatabase
, lckHandle
,
731 (void *)&lckInstance
);
732 if (error
!= SA_AIS_OK
) {
736 if (lckInstance
->callbacks
.saLckResourceOpenCallback
== NULL
) {
737 error
= SA_AIS_ERR_INIT
;
741 error
= saHandleCreate (&lckResourceHandleDatabase
,
742 sizeof (struct lckResourceInstance
), &lckResourceHandle
);
743 if (error
!= SA_AIS_OK
) {
747 error
= saHandleInstanceGet (&lckResourceHandleDatabase
, lckResourceHandle
,
748 (void *)&lckResourceInstance
);
749 if (error
!= SA_AIS_OK
) {
753 lckResourceInstance
->response_fd
= lckInstance
->response_fd
;
754 lckResourceInstance
->response_mutex
= &lckInstance
->response_mutex
;
755 lckResourceInstance
->lckHandle
= lckHandle
;
756 lckResourceInstance
->lckResourceHandle
= lckResourceHandle
;
757 lckResourceInstance
->resourceOpenFlags
= resourceOpenFlags
;
759 memcpy (&lckResourceInstance
->lockResourceName
, lockResourceName
, sizeof (SaNameT
));
760 req_lib_lck_resourceopen
.header
.size
= sizeof (struct req_lib_lck_resourceopen
);
761 req_lib_lck_resourceopen
.header
.id
= MESSAGE_REQ_LCK_RESOURCEOPENASYNC
;
762 req_lib_lck_resourceopen
.invocation
= invocation
;
763 req_lib_lck_resourceopen
.resourceOpenFlags
= resourceOpenFlags
;
764 req_lib_lck_resourceopen
.resourceHandle
= lckResourceHandle
;
765 req_lib_lck_resourceopen
.async_call
= 1;
767 pthread_mutex_lock (&lckInstance
->response_mutex
);
769 error
= saSendReceiveReply (lckResourceInstance
->response_fd
,
770 &req_lib_lck_resourceopen
,
771 sizeof (struct req_lib_lck_resourceopen
),
772 &res_lib_lck_resourceopenasync
,
773 sizeof (struct res_lib_lck_resourceopenasync
));
775 pthread_mutex_unlock (&lckInstance
->response_mutex
);
777 if (error
== SA_AIS_OK
) {
778 saHandleInstancePut (&lckResourceHandleDatabase
,
780 saHandleInstancePut (&lckHandleDatabase
, lckHandle
);
781 return (res_lib_lck_resourceopenasync
.header
.error
);
784 saHandleInstancePut (&lckResourceHandleDatabase
, lckResourceHandle
);
786 saHandleDestroy (&lckResourceHandleDatabase
, lckResourceHandle
);
788 saHandleInstancePut (&lckHandleDatabase
, lckHandle
);
795 SaLckResourceHandleT lckResourceHandle
)
797 struct req_lib_lck_resourceclose req_lib_lck_resourceclose
;
798 struct res_lib_lck_resourceclose res_lib_lck_resourceclose
;
800 struct lckResourceInstance
*lckResourceInstance
;
802 error
= saHandleInstanceGet (&lckResourceHandleDatabase
, lckResourceHandle
,
803 (void *)&lckResourceInstance
);
804 if (error
!= SA_AIS_OK
) {
808 req_lib_lck_resourceclose
.header
.size
= sizeof (struct req_lib_lck_resourceclose
);
809 req_lib_lck_resourceclose
.header
.id
= MESSAGE_REQ_LCK_RESOURCECLOSE
;
810 marshall_to_mar_name_t (&req_lib_lck_resourceclose
.lockResourceName
,
811 &lckResourceInstance
->lockResourceName
);
812 req_lib_lck_resourceclose
.resourceHandle
= lckResourceHandle
;
814 pthread_mutex_lock (lckResourceInstance
->response_mutex
);
816 error
= saSendReceiveReply (lckResourceInstance
->response_fd
,
817 &req_lib_lck_resourceclose
,
818 sizeof (struct req_lib_lck_resourceclose
),
819 &res_lib_lck_resourceclose
,
820 sizeof (struct res_lib_lck_resourceclose
));
822 pthread_mutex_unlock (lckResourceInstance
->response_mutex
);
824 saHandleInstancePut (&lckResourceHandleDatabase
, lckResourceHandle
);
826 saHandleDestroy (&lckResourceHandleDatabase
, lckResourceHandle
);
828 return (error
== SA_AIS_OK
? res_lib_lck_resourceclose
.header
.error
: error
);
833 SaLckResourceHandleT lckResourceHandle
,
834 SaLckLockIdT
*lockId
,
835 SaLckLockModeT lockMode
,
836 SaLckLockFlagsT lockFlags
,
837 SaLckWaiterSignalT waiterSignal
,
839 SaLckLockStatusT
*lockStatus
)
841 struct req_lib_lck_resourcelock req_lib_lck_resourcelock
;
842 struct res_lib_lck_resourcelock res_lib_lck_resourcelock
;
844 struct lckResourceInstance
*lckResourceInstance
;
845 struct lckLockIdInstance
*lckLockIdInstance
;
849 error
= saHandleInstanceGet (&lckResourceHandleDatabase
, lckResourceHandle
,
850 (void *)&lckResourceInstance
);
851 if (error
!= SA_AIS_OK
) {
855 error
= saHandleCreate (&lckLockIdHandleDatabase
,
856 sizeof (struct lckLockIdInstance
), lockId
);
857 if (error
!= SA_AIS_OK
) {
861 error
= saHandleInstanceGet (&lckLockIdHandleDatabase
, *lockId
,
862 (void *)&lckLockIdInstance
);
863 if (error
!= SA_AIS_OK
) {
867 error
= saServiceConnect (&lock_fd
, &dummy_fd
, LCK_SERVICE
);
868 if (error
!= SA_AIS_OK
) { // TODO error handling
872 lckLockIdInstance
->response_mutex
= lckResourceInstance
->response_mutex
;
873 lckLockIdInstance
->response_fd
= lckResourceInstance
->response_fd
;
874 lckLockIdInstance
->lckResourceHandle
= lckResourceHandle
;
876 req_lib_lck_resourcelock
.header
.size
= sizeof (struct req_lib_lck_resourcelock
);
877 req_lib_lck_resourcelock
.header
.id
= MESSAGE_REQ_LCK_RESOURCELOCK
;
878 marshall_to_mar_name_t (&req_lib_lck_resourcelock
.lockResourceName
,
879 &lckResourceInstance
->lockResourceName
);
880 req_lib_lck_resourcelock
.lockMode
= lockMode
;
881 req_lib_lck_resourcelock
.lockFlags
= lockFlags
;
882 req_lib_lck_resourcelock
.waiterSignal
= waiterSignal
;
883 req_lib_lck_resourcelock
.lockId
= *lockId
;
884 req_lib_lck_resourcelock
.async_call
= 0;
885 req_lib_lck_resourcelock
.invocation
= 0;
886 req_lib_lck_resourcelock
.resourceHandle
= lckResourceHandle
;
888 memcpy (&req_lib_lck_resourcelock
.source
,
889 &lckResourceInstance
->source
,
890 sizeof (mar_message_source_t
));
893 * no mutex needed here since its a new connection
895 error
= saSendReceiveReply (lock_fd
,
896 &req_lib_lck_resourcelock
,
897 sizeof (struct req_lib_lck_resourcelock
),
898 &res_lib_lck_resourcelock
,
899 sizeof (struct res_lib_lck_resourcelock
));
904 if (error
== SA_AIS_OK
) {
905 lckLockIdInstance
->resource_lock
= res_lib_lck_resourcelock
.resource_lock
;
906 *lockStatus
= res_lib_lck_resourcelock
.lockStatus
;
908 return (res_lib_lck_resourcelock
.header
.error
);
914 saHandleInstancePut (&lckLockIdHandleDatabase
, *lockId
);
917 saHandleDestroy (&lckLockIdHandleDatabase
, *lockId
);
920 saHandleInstancePut (&lckResourceHandleDatabase
, lckResourceHandle
);
926 saLckResourceLockAsync (
927 SaLckResourceHandleT lckResourceHandle
,
928 SaInvocationT invocation
,
929 SaLckLockIdT
*lockId
,
930 SaLckLockModeT lockMode
,
931 SaLckLockFlagsT lockFlags
,
932 SaLckWaiterSignalT waiterSignal
)
934 struct req_lib_lck_resourcelock req_lib_lck_resourcelock
;
935 struct res_lib_lck_resourcelockasync res_lib_lck_resourcelockasync
;
937 struct lckResourceInstance
*lckResourceInstance
;
938 struct lckLockIdInstance
*lckLockIdInstance
;
942 error
= saHandleInstanceGet (&lckResourceHandleDatabase
, lckResourceHandle
,
943 (void *)&lckResourceInstance
);
944 if (error
!= SA_AIS_OK
) {
948 error
= saHandleCreate (&lckLockIdHandleDatabase
,
949 sizeof (struct lckLockIdInstance
), lockId
);
950 if (error
!= SA_AIS_OK
) {
954 error
= saHandleInstanceGet (&lckLockIdHandleDatabase
, *lockId
,
955 (void *)&lckLockIdInstance
);
956 if (error
!= SA_AIS_OK
) {
960 error
= saServiceConnect (&lock_fd
, &dummy_fd
, LCK_SERVICE
);
961 if (error
!= SA_AIS_OK
) { // TODO error handling
965 lckLockIdInstance
->response_mutex
= lckResourceInstance
->response_mutex
;
966 lckLockIdInstance
->response_fd
= lckResourceInstance
->response_fd
;
967 lckLockIdInstance
->lckResourceHandle
= lckResourceHandle
;
969 req_lib_lck_resourcelock
.header
.size
= sizeof (struct req_lib_lck_resourcelock
);
970 req_lib_lck_resourcelock
.header
.id
= MESSAGE_REQ_LCK_RESOURCELOCKASYNC
;
971 marshall_to_mar_name_t (&req_lib_lck_resourcelock
.lockResourceName
,
972 &lckResourceInstance
->lockResourceName
);
973 req_lib_lck_resourcelock
.lockMode
= lockMode
;
974 req_lib_lck_resourcelock
.lockFlags
= lockFlags
;
975 req_lib_lck_resourcelock
.waiterSignal
= waiterSignal
;
976 req_lib_lck_resourcelock
.lockId
= *lockId
;
977 req_lib_lck_resourcelock
.async_call
= 1;
978 req_lib_lck_resourcelock
.invocation
= invocation
;
979 req_lib_lck_resourcelock
.resourceHandle
= lckResourceHandle
;
981 memcpy (&req_lib_lck_resourcelock
.source
,
982 &lckResourceInstance
->source
,
983 sizeof (mar_message_source_t
));
986 * no mutex needed here since its a new connection
988 error
= saSendReceiveReply (lock_fd
,
989 &req_lib_lck_resourcelock
,
990 sizeof (struct req_lib_lck_resourcelock
),
991 &res_lib_lck_resourcelockasync
,
992 sizeof (struct res_lib_lck_resourcelock
));
997 if (error
== SA_AIS_OK
) {
998 return (res_lib_lck_resourcelockasync
.header
.error
);
1004 saHandleInstancePut (&lckLockIdHandleDatabase
, *lockId
);
1007 saHandleDestroy (&lckLockIdHandleDatabase
, *lockId
);
1010 saHandleInstancePut (&lckResourceHandleDatabase
, lckResourceHandle
);
1015 saLckResourceUnlock (
1016 SaLckLockIdT lockId
,
1019 struct req_lib_lck_resourceunlock req_lib_lck_resourceunlock
;
1020 struct res_lib_lck_resourceunlock res_lib_lck_resourceunlock
;
1022 struct lckLockIdInstance
*lckLockIdInstance
;
1023 struct lckResourceInstance
*lckResourceInstance
;
1025 error
= saHandleInstanceGet (&lckLockIdHandleDatabase
, lockId
,
1026 (void *)&lckLockIdInstance
);
1027 if (error
!= SA_AIS_OK
) {
1032 * Retrieve resource name
1034 error
= saHandleInstanceGet (&lckResourceHandleDatabase
,
1035 lckLockIdInstance
->lckResourceHandle
, (void *)&lckResourceInstance
);
1036 if (error
!= SA_AIS_OK
) {
1037 saHandleInstancePut (&lckLockIdHandleDatabase
, lockId
);
1041 marshall_to_mar_name_t (&req_lib_lck_resourceunlock
.lockResourceName
,
1042 &lckResourceInstance
->lockResourceName
);
1044 saHandleInstancePut (&lckResourceHandleDatabase
,
1045 lckLockIdInstance
->lckResourceHandle
);
1047 req_lib_lck_resourceunlock
.header
.size
= sizeof (struct req_lib_lck_resourceunlock
);
1048 req_lib_lck_resourceunlock
.header
.id
= MESSAGE_REQ_LCK_RESOURCEUNLOCK
;
1049 req_lib_lck_resourceunlock
.lockId
= lockId
;
1050 req_lib_lck_resourceunlock
.timeout
= timeout
;
1051 req_lib_lck_resourceunlock
.invocation
= -1;
1052 req_lib_lck_resourceunlock
.async_call
= 0;
1053 req_lib_lck_resourceunlock
.resource_lock
= lckLockIdInstance
->resource_lock
;
1055 pthread_mutex_lock (lckLockIdInstance
->response_mutex
);
1057 error
= saSendReceiveReply (lckLockIdInstance
->response_fd
,
1058 &req_lib_lck_resourceunlock
,
1059 sizeof (struct req_lib_lck_resourceunlock
),
1060 &res_lib_lck_resourceunlock
,
1061 sizeof (struct res_lib_lck_resourceunlock
));
1063 pthread_mutex_unlock (lckLockIdInstance
->response_mutex
);
1065 saHandleInstancePut (&lckLockIdHandleDatabase
, lockId
);
1067 saHandleDestroy (&lckLockIdHandleDatabase
, lockId
);
1069 return (error
== SA_AIS_OK
? res_lib_lck_resourceunlock
.header
.error
: error
);
1073 saLckResourceUnlockAsync (
1074 SaInvocationT invocation
,
1075 SaLckLockIdT lockId
)
1077 struct req_lib_lck_resourceunlock req_lib_lck_resourceunlock
;
1078 struct res_lib_lck_resourceunlockasync res_lib_lck_resourceunlockasync
;
1080 struct lckLockIdInstance
*lckLockIdInstance
;
1081 struct lckResourceInstance
*lckResourceInstance
;
1083 error
= saHandleInstanceGet (&lckLockIdHandleDatabase
, lockId
,
1084 (void *)&lckLockIdInstance
);
1085 if (error
!= SA_AIS_OK
) {
1090 * Retrieve resource name
1092 error
= saHandleInstanceGet (&lckResourceHandleDatabase
,
1093 lckLockIdInstance
->lckResourceHandle
, (void *)&lckResourceInstance
);
1094 if (error
!= SA_AIS_OK
) {
1095 saHandleInstancePut (&lckLockIdHandleDatabase
, lockId
);
1099 marshall_to_mar_name_t (&req_lib_lck_resourceunlock
.lockResourceName
,
1100 &lckResourceInstance
->lockResourceName
);
1102 saHandleInstancePut (&lckResourceHandleDatabase
,
1103 lckLockIdInstance
->lckResourceHandle
);
1107 * Build and send request
1109 req_lib_lck_resourceunlock
.header
.size
= sizeof (struct req_lib_lck_resourceunlock
);
1110 req_lib_lck_resourceunlock
.header
.id
= MESSAGE_REQ_LCK_RESOURCEUNLOCKASYNC
;
1111 req_lib_lck_resourceunlock
.invocation
= invocation
;
1112 req_lib_lck_resourceunlock
.lockId
= lockId
;
1113 req_lib_lck_resourceunlock
.async_call
= 1;
1115 pthread_mutex_lock (lckLockIdInstance
->response_mutex
);
1117 error
= saSendReceiveReply (lckLockIdInstance
->response_fd
,
1118 &req_lib_lck_resourceunlock
,
1119 sizeof (struct req_lib_lck_resourceunlock
),
1120 &res_lib_lck_resourceunlockasync
,
1121 sizeof (struct res_lib_lck_resourceunlockasync
));
1123 pthread_mutex_unlock (lckLockIdInstance
->response_mutex
);
1125 saHandleInstancePut (&lckLockIdHandleDatabase
, lockId
);
1127 return (error
== SA_AIS_OK
? res_lib_lck_resourceunlockasync
.header
.error
: error
);
1132 SaLckResourceHandleT lckResourceHandle
)
1134 struct req_lib_lck_lockpurge req_lib_lck_lockpurge
;
1135 struct res_lib_lck_lockpurge res_lib_lck_lockpurge
;
1137 struct lckResourceInstance
*lckResourceInstance
;
1139 error
= saHandleInstanceGet (&lckResourceHandleDatabase
, lckResourceHandle
,
1140 (void *)&lckResourceInstance
);
1141 if (error
!= SA_AIS_OK
) {
1145 req_lib_lck_lockpurge
.header
.size
= sizeof (struct req_lib_lck_lockpurge
);
1146 req_lib_lck_lockpurge
.header
.id
= MESSAGE_REQ_LCK_LOCKPURGE
;
1147 marshall_to_mar_name_t (&req_lib_lck_lockpurge
.lockResourceName
,
1148 &lckResourceInstance
->lockResourceName
);
1150 pthread_mutex_lock (lckResourceInstance
->response_mutex
);
1152 error
= saSendReceiveReply (lckResourceInstance
->response_fd
,
1153 &req_lib_lck_lockpurge
,
1154 sizeof (struct req_lib_lck_lockpurge
),
1155 &res_lib_lck_lockpurge
,
1156 sizeof (struct res_lib_lck_lockpurge
));
1158 pthread_mutex_unlock (lckResourceInstance
->response_mutex
);
1160 saHandleInstancePut (&lckResourceHandleDatabase
, lckResourceHandle
);
1162 return (error
== SA_AIS_OK
? res_lib_lck_lockpurge
.header
.error
: error
);