1/*
2 * Copyright (c) 2010 Apple Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 *
10 * 1.  Redistributions of source code must retain the above copyright
11 *     notice, this list of conditions and the following disclaimer.
12 * 2.  Redistributions in binary form must reproduce the above copyright
13 *     notice, this list of conditions and the following disclaimer in the
14 *     documentation and/or other materials provided with the distribution.
15 * 3.  Neither the name of Apple Inc. ("Apple") nor the names of its
16 *     contributors may be used to endorse or promote products derived from
17 *     this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
20 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
21 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
23 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
24 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
26 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
28 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 *
30 * Portions of this software have been released under the following terms:
31 *
32 * (c) Copyright 1989-1993 OPEN SOFTWARE FOUNDATION, INC.
33 * (c) Copyright 1989-1993 HEWLETT-PACKARD COMPANY
34 * (c) Copyright 1989-1993 DIGITAL EQUIPMENT CORPORATION
35 *
36 * To anyone who acknowledges that this file is provided "AS IS"
37 * without any express or implied warranty:
38 * permission to use, copy, modify, and distribute this file for any
39 * purpose is hereby granted without fee, provided that the above
40 * copyright notices and this notice appears in all source code copies,
41 * and that none of the names of Open Software Foundation, Inc., Hewlett-
42 * Packard Company or Digital Equipment Corporation be used
43 * in advertising or publicity pertaining to distribution of the software
44 * without specific, written prior permission.  Neither Open Software
45 * Foundation, Inc., Hewlett-Packard Company nor Digital
46 * Equipment Corporation makes any representations about the suitability
47 * of this software for any purpose.
48 *
49 * Copyright (c) 2007, Novell, Inc. All rights reserved.
50 * Redistribution and use in source and binary forms, with or without
51 * modification, are permitted provided that the following conditions
52 * are met:
53 *
54 * 1.  Redistributions of source code must retain the above copyright
55 *     notice, this list of conditions and the following disclaimer.
56 * 2.  Redistributions in binary form must reproduce the above copyright
57 *     notice, this list of conditions and the following disclaimer in the
58 *     documentation and/or other materials provided with the distribution.
59 * 3.  Neither the name of Novell Inc. nor the names of its contributors
60 *     may be used to endorse or promote products derived from this
61 *     this software without specific prior written permission.
62 *
63 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
64 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
65 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
66 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY
67 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
68 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
69 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
70 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
71 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
72 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
73 *
74 * @APPLE_LICENSE_HEADER_END@
75 */
76
77/*
78**
79**  NAME:
80**
81**      dgcall.h
82**
83**  FACILITY:
84**
85**      Remote Procedure Call (RPC)
86**
87**  ABSTRACT:
88**
89**  DG protocol service routines.
90**
91**
92*/
93
94#ifndef _DGCALL_H
95#define _DGCALL_H
96
97/* ======================================================================= */
98
99/*
100 * Call wait flags.
101 *
102 * This enumeration defines the types of events that calls need to wait
103 * for when calling the call_wait routine.  These values indicate whether
104 * the caller is waiting for 1) a network event, such as the arrival
105 * of data, facks, etc., or 2) an internal event, such as
106 * packets/reservations to become available.
107 *
108 * Note that this distinction is only meaningful for users of private sockets.
109 * Call threads using private sockets wait for network events by sleeping in
110 * recvfrom, and wait for internal events by sleeping on a condition variable.
111 * Call threads that use shared sockets always wait on the call handle's
112 * condition variable (i.e., always specify rpc_e_dg_wait_on_internal_event).
113 */
114typedef enum {
115    rpc_e_dg_wait_on_internal_event,
116    rpc_e_dg_wait_on_network_event
117} rpc_dg_wait_event_t;
118
119/* ======================================================================= */
120
121/*
122 * R P C _ D G _ C A L L _ R E F E R E N C E
123 *
124 * Increment the reference count for the CALL.  Note that there's no
125 * RPC_DG_CALL_RELEASE; you must use one of RPC_DG_CCALL_RELEASE or
126 * RPC_DG_SCALL_RELEASE depending on whether you have a client or server
127 * call handle.  (The release function has to call the server/client
128 * specific "free" function.)
129 */
130
131#define RPC_DG_CALL_REFERENCE(call) { \
132    RPC_DG_CALL_LOCK_ASSERT(call); \
133    assert((call)->refcnt < 255); \
134    (call)->refcnt++; \
135}
136
137/*
138 * R P C _ D G _ C A L L _ R E I N I T
139 *
140 * Reinitialize the common part of a call handle.
141 * If we are not going to use MBF, turn off the first fack waiting.
142 */
143
144#define RPC_DG_CALL_REINIT(call) { \
145    (call)->last_rcv_timestamp = 0; \
146    (call)->start_time = rpc__clock_stamp(); \
147    (call)->status = rpc_s_ok; \
148    (call)->blocked_in_receive = false; \
149    (call)->priv_cond_signal = false; \
150    RPC_DG_XMITQ_REINIT(&(call)->xq, (call)); \
151    RPC_DG_RECVQ_REINIT(&(call)->rq); \
152    if ((call)->xq.max_frag_size <= RPC_C_DG_MUST_RECV_FRAG_SIZE) \
153        (call)->xq.first_fack_seen = true; \
154}
155
156/*
157 * R P C _ D G _ C A L L _ S E T _ T I M E R
158 *
159 * Set up a timer for a call handle.  Bump the reference count of the call
160 * handle since the reference from the timer queue counts as a reference.
161 */
162
163#define RPC_DG_CALL_SET_TIMER(call, proc, freq) { \
164    rpc__timer_set(&(call)->timer, (proc), (dce_pointer_t) (call), (freq)); \
165    RPC_DG_CALL_REFERENCE(call); \
166}
167
168/*
169 * R P C _ D G _ C A L L _ S T O P _ T I M E R
170 *
171 * "Request" that a call's timer be stopped.  This amounts to setting
172 * a bit in the call handle.  We use this macro instead of calling
173 * "rpc__timer_clear" directly since we really want the timer to stop
174 * itself so it can eliminate its reference to the call handle in a
175 * race-free fashion.
176 */
177
178#define RPC_DG_CALL_STOP_TIMER(call) \
179    (call)->stop_timer = true
180
181#ifdef __cplusplus
182extern "C" {
183#endif
184
185/*
186 * R P C _ D G _ C A L L _ S E T _ M A X _ F R A G _ S I Z E
187 *
188 * Set the max_frag_size and max_resvs in a call handle.
189 * Also, if we are not going to use MBF, turn off the first fack
190 * waiting.
191 */
192
193#define RPC_DG_CALL_SET_MAX_FRAG_SIZE(call, st) \
194{ \
195    rpc__naf_inq_max_frag_size((call)->addr, \
196                               &((call)->xq.max_frag_size), (st)); \
197    if (*st != rpc_s_ok) \
198        (call)->xq.max_frag_size = RPC_C_DG_MUST_RECV_FRAG_SIZE; \
199    else if ((call)->xq.max_frag_size > RPC_C_DG_MAX_FRAG_SIZE) \
200        (call)->xq.max_frag_size = RPC_C_DG_MAX_FRAG_SIZE; \
201    if ((call)->xq.max_frag_size <= RPC_C_DG_MUST_RECV_FRAG_SIZE) \
202        (call)->xq.first_fack_seen = true; \
203    RPC_DG_FRAG_SIZE_TO_NUM_PKTS((call)->xq.max_frag_size, \
204                                 (call)->max_resvs); \
205}
206
207#ifdef DEBUG
208
209PRIVATE const char *rpc__dg_call_state_name (
210        rpc_dg_call_state_t state
211    );
212
213#else
214
215#define rpc__dg_call_state_name(junk) ""
216
217#endif
218
219PRIVATE void rpc__dg_call_xmit_fack (
220        rpc_dg_call_p_t  /*call*/,
221        rpc_dg_recvq_elt_p_t  /*rqe*/,
222        boolean32 /*is_nocall*/
223    );
224
225PRIVATE void rpc__dg_call_xmit (
226        rpc_dg_call_p_t  /*call*/,
227        boolean32 /*block*/
228    );
229
230PRIVATE void rpc__dg_call_xmitq_timer (
231        rpc_dg_call_p_t /*call*/
232    );
233
234PRIVATE void rpc__dg_call_init (
235        rpc_dg_call_p_t /*call*/
236    );
237
238PRIVATE void rpc__dg_call_free (
239        rpc_dg_call_p_t /*call*/
240    );
241
242PRIVATE void rpc__dg_call_wait (
243        rpc_dg_call_p_t /*call*/,
244        rpc_dg_wait_event_t /*event*/,
245        unsigned32 * /*st*/
246    );
247
248PRIVATE void rpc__dg_call_signal (
249        rpc_dg_call_p_t /*call*/
250    );
251
252PRIVATE void rpc__dg_call_xmitq_push (
253        rpc_dg_call_p_t /*call*/,
254        unsigned32 * /*st*/
255    );
256
257PRIVATE boolean rpc__dg_call_recvq_insert (
258        rpc_dg_call_p_t /*call*/,
259        rpc_dg_recvq_elt_p_t  /*rqe*/,
260        boolean * /*rqe_is_head_inorder*/
261    );
262
263PRIVATE void rpc__dg_call_signal_failure (
264        rpc_dg_call_p_t /*call*/,
265        unsigned32 /*stcode*/
266    );
267
268PRIVATE void rpc__dg_call_local_cancel (
269        rpc_dg_call_p_t /*call*/
270    );
271
272#ifdef __cplusplus
273}
274#endif
275
276#endif
277