xref: /onnv-gate/usr/src/cmd/cmd-inet/usr.lib/dsvclockd/container.h (revision 0:68f95e015346)
1*0Sstevel@tonic-gate /*
2*0Sstevel@tonic-gate  * CDDL HEADER START
3*0Sstevel@tonic-gate  *
4*0Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
5*0Sstevel@tonic-gate  * Common Development and Distribution License, Version 1.0 only
6*0Sstevel@tonic-gate  * (the "License").  You may not use this file except in compliance
7*0Sstevel@tonic-gate  * with the License.
8*0Sstevel@tonic-gate  *
9*0Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10*0Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
11*0Sstevel@tonic-gate  * See the License for the specific language governing permissions
12*0Sstevel@tonic-gate  * and limitations under the License.
13*0Sstevel@tonic-gate  *
14*0Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
15*0Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16*0Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
17*0Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
18*0Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
19*0Sstevel@tonic-gate  *
20*0Sstevel@tonic-gate  * CDDL HEADER END
21*0Sstevel@tonic-gate  */
22*0Sstevel@tonic-gate /*
23*0Sstevel@tonic-gate  * Copyright (c) 2000 by Sun Microsystems, Inc.
24*0Sstevel@tonic-gate  * All rights reserved.
25*0Sstevel@tonic-gate  */
26*0Sstevel@tonic-gate 
27*0Sstevel@tonic-gate #ifndef	DSVCD_CONTAINER_H
28*0Sstevel@tonic-gate #define	DSVCD_CONTAINER_H
29*0Sstevel@tonic-gate 
30*0Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
31*0Sstevel@tonic-gate 
32*0Sstevel@tonic-gate #include <sys/types.h>
33*0Sstevel@tonic-gate #include <synch.h>
34*0Sstevel@tonic-gate 
35*0Sstevel@tonic-gate #include "dsvclockd.h"
36*0Sstevel@tonic-gate 
37*0Sstevel@tonic-gate /*
38*0Sstevel@tonic-gate  * Container-related data structures, functions and constants.  See
39*0Sstevel@tonic-gate  * comments in container.c for a description of how to use the exported
40*0Sstevel@tonic-gate  * functions.
41*0Sstevel@tonic-gate  */
42*0Sstevel@tonic-gate 
43*0Sstevel@tonic-gate #ifdef	__cplusplus
44*0Sstevel@tonic-gate extern "C" {
45*0Sstevel@tonic-gate #endif
46*0Sstevel@tonic-gate 
47*0Sstevel@tonic-gate /*
48*0Sstevel@tonic-gate  * Number of seconds to wait for container lockholders to relinquish all
49*0Sstevel@tonic-gate  * locks on a given container (when it's being destroyed).
50*0Sstevel@tonic-gate  */
51*0Sstevel@tonic-gate #define	CN_DESTROY_WAIT	60
52*0Sstevel@tonic-gate 
53*0Sstevel@tonic-gate /*
54*0Sstevel@tonic-gate  * Describes a thread waiting to access a given container; exactly one per
55*0Sstevel@tonic-gate  * waiting thread.
56*0Sstevel@tonic-gate  */
57*0Sstevel@tonic-gate typedef struct dsvcd_waitlist {
58*0Sstevel@tonic-gate 	struct dsvcd_waitlist	*wl_next;	/* next waiter in list */
59*0Sstevel@tonic-gate 	struct dsvcd_waitlist	*wl_prev;	/* prev waiter in list */
60*0Sstevel@tonic-gate 	cond_t			wl_cv;		/* our condition variable */
61*0Sstevel@tonic-gate 	dsvcd_locktype_t	wl_locktype;	/* type of lock we want */
62*0Sstevel@tonic-gate } dsvcd_waitlist_t;
63*0Sstevel@tonic-gate 
64*0Sstevel@tonic-gate /*
65*0Sstevel@tonic-gate  * States for the host lock state machine.  The state machine is a simple
66*0Sstevel@tonic-gate  * cycle of UNLOCKED->PENDING->{RD,WR}LOCKED->UNLOCKED->...
67*0Sstevel@tonic-gate  */
68*0Sstevel@tonic-gate enum cn_hlockstate { CN_HUNLOCKED, CN_HPENDING, CN_HRDLOCKED, CN_HWRLOCKED };
69*0Sstevel@tonic-gate 
70*0Sstevel@tonic-gate /*
71*0Sstevel@tonic-gate  * Describes a given container within a datastore.  There is at most one of
72*0Sstevel@tonic-gate  * these per datastore container (there may be none if there are no current
73*0Sstevel@tonic-gate  * consumers of a given container within a datastore).  If there is more
74*0Sstevel@tonic-gate  * than one open handle to a given container (through multiple calls to
75*0Sstevel@tonic-gate  * open_d?()) there will still only be one dsvcd_container_t for that
76*0Sstevel@tonic-gate  * container.  This object is used to synchronize access to an underlying
77*0Sstevel@tonic-gate  * container through use of its custom reader/writer lock (it can't use the
78*0Sstevel@tonic-gate  * rwlock_t's built into Solaris because we need locks that do not care if
79*0Sstevel@tonic-gate  * the unlocking thread is the same as the locking thread).  It also
80*0Sstevel@tonic-gate  * contains other per-container information like the container id.
81*0Sstevel@tonic-gate  */
82*0Sstevel@tonic-gate typedef struct dsvcd_container {
83*0Sstevel@tonic-gate 	char			*cn_id;		/* container's id */
84*0Sstevel@tonic-gate 	boolean_t		cn_crosshost;	/* synchronize across hosts */
85*0Sstevel@tonic-gate 	boolean_t		cn_closing;	/* container is going away */
86*0Sstevel@tonic-gate 	mutex_t			cn_lock;	/* protects preceding fields */
87*0Sstevel@tonic-gate 
88*0Sstevel@tonic-gate 	dsvcd_waitlist_t	*cn_whead;	/* head of wait list */
89*0Sstevel@tonic-gate 	dsvcd_waitlist_t	*cn_wtail;	/* tail of wait list */
90*0Sstevel@tonic-gate 	int			cn_nholds;	/* num readers (-1 == writer) */
91*0Sstevel@tonic-gate 	mutex_t			cn_nholds_lock;	/* for nholds and waitlist */
92*0Sstevel@tonic-gate 
93*0Sstevel@tonic-gate 	int			cn_hlockfd;	/* host lock file descriptor */
94*0Sstevel@tonic-gate 	int			cn_hlockcount;	/* current # of host locks */
95*0Sstevel@tonic-gate 	enum cn_hlockstate	cn_hlockstate;	/* host lock state */
96*0Sstevel@tonic-gate 	cond_t			cn_hlockcv;	/* host lock condvar */
97*0Sstevel@tonic-gate 	mutex_t			cn_hlock_lock;	/* mutex for cn_hlock* */
98*0Sstevel@tonic-gate 
99*0Sstevel@tonic-gate 	/*
100*0Sstevel@tonic-gate 	 * These fields are used to keep metadata state regarding the
101*0Sstevel@tonic-gate 	 * container and are actually maintained by the containing
102*0Sstevel@tonic-gate 	 * datastore, not the container.
103*0Sstevel@tonic-gate 	 */
104*0Sstevel@tonic-gate 	uint_t			cn_nout;	/* number checked out */
105*0Sstevel@tonic-gate 	time_t			cn_lastrel;	/* last released */
106*0Sstevel@tonic-gate 	uint32_t		cn_idhash;	/* hash before modulation */
107*0Sstevel@tonic-gate 	struct dsvcd_container	*cn_next;	/* hash chain next */
108*0Sstevel@tonic-gate 	struct dsvcd_container	*cn_prev;	/* hash chain prev */
109*0Sstevel@tonic-gate } dsvcd_container_t;
110*0Sstevel@tonic-gate 
111*0Sstevel@tonic-gate extern dsvcd_container_t	*cn_create(const char *, boolean_t);
112*0Sstevel@tonic-gate extern void			cn_destroy(dsvcd_container_t *);
113*0Sstevel@tonic-gate extern int			cn_rdlock(dsvcd_container_t *, boolean_t);
114*0Sstevel@tonic-gate extern int			cn_wrlock(dsvcd_container_t *, boolean_t);
115*0Sstevel@tonic-gate extern int			cn_unlock(dsvcd_container_t *);
116*0Sstevel@tonic-gate extern dsvcd_locktype_t		cn_locktype(dsvcd_container_t *);
117*0Sstevel@tonic-gate 
118*0Sstevel@tonic-gate #ifdef	__cplusplus
119*0Sstevel@tonic-gate }
120*0Sstevel@tonic-gate #endif
121*0Sstevel@tonic-gate 
122*0Sstevel@tonic-gate #endif	/* DSVCD_CONTAINER_H */
123