components/visual-panels/smf/src/cmd/rad/mod/smf/rhandle.c
branchs11-update
changeset 2805 4888f6212f94
parent 2804 7546c836fd87
child 2806 8ac3cbf66125
equal deleted inserted replaced
2804:7546c836fd87 2805:4888f6212f94
     1 /*
       
     2  * CDDL HEADER START
       
     3  *
       
     4  * The contents of this file are subject to the terms of the
       
     5  * Common Development and Distribution License (the "License").
       
     6  * You may not use this file except in compliance with the License.
       
     7  *
       
     8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
       
     9  * or http://www.opensolaris.org/os/licensing.
       
    10  * See the License for the specific language governing permissions
       
    11  * and limitations under the License.
       
    12  *
       
    13  * When distributing Covered Code, include this CDDL HEADER in each
       
    14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
       
    15  * If applicable, add the following below this CDDL HEADER, with the
       
    16  * fields enclosed by brackets "[]" replaced with your own identifying
       
    17  * information: Portions Copyright [yyyy] [name of copyright owner]
       
    18  *
       
    19  * CDDL HEADER END
       
    20  */
       
    21 
       
    22 /*
       
    23  * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
       
    24  */
       
    25 
       
    26 #include <stdlib.h>
       
    27 #include <assert.h>
       
    28 #include <pthread.h>
       
    29 
       
    30 #include <libscf.h>
       
    31 #include <rad/rad_modapi.h>
       
    32 
       
    33 #include "rhandle.h"
       
    34 
       
    35 static pthread_mutex_t handle_lock = PTHREAD_MUTEX_INITIALIZER;
       
    36 static rad_handle_t *rhandle;
       
    37 
       
    38 /*
       
    39  * Rebinding a repository handle after the connection is broken
       
    40  * requires that we correctly drain all its users, which is difficult.
       
    41  * Instead we wrap and reference count the handle, and force callers
       
    42  * to re-fetch the latest handle on connection failures.
       
    43  */
       
    44 
       
    45 static scf_handle_t *
       
    46 handle_create(void)
       
    47 {
       
    48 	scf_handle_t *h = scf_handle_create(SCF_VERSION);
       
    49 	if (h == NULL)
       
    50 		return (NULL);
       
    51 
       
    52 	if (scf_handle_bind(h) == -1) {
       
    53 		scf_handle_destroy(h);
       
    54 		return (NULL);
       
    55 	}
       
    56 	return (h);
       
    57 }
       
    58 
       
    59 rad_handle_t *
       
    60 rh_fetch(void)
       
    61 {
       
    62 	rad_handle_t *rh;
       
    63 
       
    64 	rad_mutex_enter(&handle_lock);
       
    65 	if (rhandle != NULL) {
       
    66 		rh = rhandle;
       
    67 		rh->rh_refs++;
       
    68 	} else {
       
    69 		rh = malloc(sizeof (rad_handle_t));
       
    70 		if (rh == NULL)
       
    71 			goto out;
       
    72 		if ((rh->rh_hdl = handle_create()) == NULL) {
       
    73 			free(rh);
       
    74 			rh = NULL;
       
    75 			goto out;
       
    76 		}
       
    77 		rh->rh_refs = 1;
       
    78 		rhandle = rh;
       
    79 	}
       
    80 out:
       
    81 	rad_mutex_exit(&handle_lock);
       
    82 
       
    83 	return (rh);
       
    84 }
       
    85 
       
    86 void
       
    87 rh_rele(rad_handle_t *rh)
       
    88 {
       
    89 	if (rh == NULL)
       
    90 		return;
       
    91 
       
    92 	rad_mutex_enter(&handle_lock);
       
    93 	if (--rh->rh_refs == 0 && rhandle != rh) {
       
    94 		scf_handle_destroy(rh->rh_hdl);
       
    95 		free(rh);
       
    96 	}
       
    97 	rad_mutex_exit(&handle_lock);
       
    98 }
       
    99 
       
   100 void
       
   101 rh_kill(rad_handle_t *rh)
       
   102 {
       
   103 	if (rh == NULL)
       
   104 		return;
       
   105 
       
   106 	rad_mutex_enter(&handle_lock);
       
   107 	if (rhandle == rh)
       
   108 		rhandle = NULL;
       
   109 	rad_mutex_exit(&handle_lock);
       
   110 }