4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License, Version 1.0 only
6 * (the "License"). You may not use this file except in compliance
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
23 * Copyright (c) 1999 by Sun Microsystems, Inc.
24 * All rights reserved.
27 #pragma ident "%Z%%M% %I% %E% SMI"
34 #include <arpa/inet.h>
35 #include <slp-internal.h>
36 #include <slp_net_utils.h>
38 SLPError
SLPOpen(const char *pcLang
, SLPBoolean isAsync
, SLPHandle
*phSLP
) {
39 slp_handle_impl_t
*hp
;
41 if (!pcLang
|| !phSLP
) {
42 return (SLP_PARAMETER_BAD
);
45 /* allocate the handle */
46 if (!(hp
= malloc(sizeof (*hp
)))) {
47 slp_err(LOG_CRIT
, 0, "SLPOpen", "out of memory");
48 return (SLP_MEMORY_ALLOC_FAILED
);
51 /* initialize outcall synchronization */
52 hp
->pending_outcall
= SLP_FALSE
;
53 (void) mutex_init(&(hp
->outcall_lock
), NULL
, NULL
);
54 (void) cond_init(&(hp
->outcall_cv
), NULL
, NULL
);
55 hp
->close_on_end
= SLP_FALSE
;
58 /* locale property overrides argument */
59 if (!(hp
->locale
= SLPGetProperty(SLP_CONFIG_LOCALE
))) {
62 /* Make sure the language string is under our ownership */
63 if (!(hp
->locale
= strdup(hp
->locale
))) {
65 slp_err(LOG_CRIT
, 0, "SLPOpen", "out of memory");
66 return (SLP_MEMORY_ALLOC_FAILED
);
71 /* Asynchronous operation? */
75 hp
->async
= SLP_FALSE
;
77 /* TCP vars -- these are NULL until actually needed */
82 /* Consumer / Producer pipe */
85 /* Interface info, loaded on demand */
88 /* force multicast, false by default */
89 hp
->force_multicast
= SLP_FALSE
;
91 /* internal call, false by default */
92 hp
->internal_call
= SLP_FALSE
;
98 void slp_cleanup_handle(slp_handle_impl_t
*hp
) {
100 if (hp
->tcp_lock
) free(hp
->tcp_lock
);
101 if (hp
->tcp_wait
) free(hp
->tcp_wait
);
103 slp_free_ifinfo(hp
->ifinfo
);
106 free((void *) hp
->locale
);
110 void SLPClose(SLPHandle hSLP
) {
111 slp_handle_impl_t
*hp
= (slp_handle_impl_t
*)hSLP
;
118 * If an outcall is pending on this handle:
119 * If we are being called from a callback resulting
120 * from the outcall associated with this handle or
121 * if close_on_end has already been set:
122 * just set close on end and return -- the cleanup
123 * will be done when the outcall is finished.
125 * wait on the outcall cv for the outcall to complete
126 * Proceed with cleanup
128 (void) mutex_lock(&(hp
->outcall_lock
));
129 if (hp
->pending_outcall
) {
130 /* end the consumer thread */
131 /* this will also kill the producer thread and close net */
134 if (slp_enqueue_at_head(hp
->q
, NULL
) != SLP_OK
) {
139 if (thr_self() == hp
->consumer_tid
|| hp
->close_on_end
) {
140 /* SLPClose called from callback */
141 hp
->close_on_end
= SLP_TRUE
;
142 (void) mutex_unlock(&(hp
->outcall_lock
));
145 /* else not called from callback; wait for outcall to end */
146 while (hp
->pending_outcall
) {
147 (void) cond_wait(&(hp
->outcall_cv
), &(hp
->outcall_lock
));
150 (void) mutex_unlock(&(hp
->outcall_lock
));
153 slp_cleanup_handle(hp
);