shutdown.c revision c5629e66
1266e564dSmrg/* $Xorg: shutdown.c,v 1.4 2001/02/09 02:03:26 xorgcvs Exp $ */
2266e564dSmrg/******************************************************************************
3266e564dSmrg
4266e564dSmrg
5266e564dSmrgCopyright 1993, 1998  The Open Group
6266e564dSmrg
7266e564dSmrgPermission to use, copy, modify, distribute, and sell this software and its
8266e564dSmrgdocumentation for any purpose is hereby granted without fee, provided that
9266e564dSmrgthe above copyright notice appear in all copies and that both that
10266e564dSmrgcopyright notice and this permission notice appear in supporting
11266e564dSmrgdocumentation.
12266e564dSmrg
13266e564dSmrgThe above copyright notice and this permission notice shall be included in
14266e564dSmrgall copies or substantial portions of the Software.
15266e564dSmrg
16266e564dSmrgTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17266e564dSmrgIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18266e564dSmrgFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
19266e564dSmrgOPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
20266e564dSmrgAN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
21266e564dSmrgCONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22266e564dSmrg
23266e564dSmrgExcept as contained in this notice, the name of The Open Group shall not be
24266e564dSmrgused in advertising or otherwise to promote the sale, use or other dealings
25266e564dSmrgin this Software without prior written authorization from The Open Group.
26266e564dSmrg
27266e564dSmrgAuthor: Ralph Mor, X Consortium
28266e564dSmrg******************************************************************************/
29266e564dSmrg/* $XFree86: xc/lib/ICE/shutdown.c,v 3.3 2001/08/01 00:44:37 tsi Exp $ */
30266e564dSmrg
31266e564dSmrg#ifdef HAVE_CONFIG_H
32266e564dSmrg#include <config.h>
33266e564dSmrg#endif
34266e564dSmrg#include <X11/ICE/ICElib.h>
35266e564dSmrg#include "ICElibint.h"
36266e564dSmrg#include <X11/Xtrans/Xtrans.h>
37266e564dSmrg
38266e564dSmrg
39266e564dSmrgStatus
40c5629e66SmrgIceProtocolShutdown (
41c5629e66Smrg	IceConn iceConn,
42c5629e66Smrg	int	majorOpcode
43c5629e66Smrg)
44266e564dSmrg{
45266e564dSmrg    if (iceConn->proto_ref_count == 0 || iceConn->process_msg_info == NULL ||
46266e564dSmrg        majorOpcode < 1 || majorOpcode > _IceLastMajorOpcode)
47266e564dSmrg    {
48266e564dSmrg	return (0);
49266e564dSmrg    }
50266e564dSmrg    else
51266e564dSmrg    {
52266e564dSmrg	/*
53266e564dSmrg	 * Make sure this majorOpcode is really being used.
54266e564dSmrg	 */
55266e564dSmrg
56266e564dSmrg	int i;
57266e564dSmrg
58266e564dSmrg	for (i = iceConn->his_min_opcode; i <= iceConn->his_max_opcode; i++)
59266e564dSmrg	{
60266e564dSmrg	    if (iceConn->process_msg_info[
61266e564dSmrg		i - iceConn->his_min_opcode].in_use &&
62266e564dSmrg                iceConn->process_msg_info[
63266e564dSmrg		i - iceConn->his_min_opcode].my_opcode == majorOpcode)
64266e564dSmrg		break;
65266e564dSmrg	}
66266e564dSmrg
67266e564dSmrg	if (i > iceConn->his_max_opcode)
68266e564dSmrg	{
69266e564dSmrg	    return (0);
70266e564dSmrg	}
71266e564dSmrg	else
72266e564dSmrg	{
73266e564dSmrg	    /*
74266e564dSmrg	     * OK, we can shut down the protocol.
75266e564dSmrg	     */
76266e564dSmrg
77266e564dSmrg	    iceConn->process_msg_info[
78266e564dSmrg		i - iceConn->his_min_opcode].in_use = False;
79266e564dSmrg	    iceConn->proto_ref_count--;
80266e564dSmrg
81266e564dSmrg	    return (1);
82266e564dSmrg	}
83266e564dSmrg    }
84266e564dSmrg}
85266e564dSmrg
86266e564dSmrg
87266e564dSmrg
88266e564dSmrgvoid
89c5629e66SmrgIceSetShutdownNegotiation (
90c5629e66Smrg	IceConn     	iceConn,
91c5629e66Smrg	Bool		negotiate
92c5629e66Smrg)
93266e564dSmrg{
94266e564dSmrg    iceConn->skip_want_to_close = negotiate ? False : True;
95266e564dSmrg}
96266e564dSmrg
97266e564dSmrg
98266e564dSmrg
99266e564dSmrgBool
100c5629e66SmrgIceCheckShutdownNegotiation (
101c5629e66Smrg	IceConn     iceConn
102c5629e66Smrg)
103266e564dSmrg{
104266e564dSmrg    return (iceConn->skip_want_to_close ? False : True);
105266e564dSmrg}
106266e564dSmrg
107266e564dSmrg
108266e564dSmrg
109266e564dSmrgIceCloseStatus
110c5629e66SmrgIceCloseConnection (
111c5629e66Smrg	IceConn     iceConn
112c5629e66Smrg)
113266e564dSmrg{
114266e564dSmrg    int refCountReachedZero;
115266e564dSmrg    IceCloseStatus status;
116266e564dSmrg
117266e564dSmrg    /*
118266e564dSmrg     * If this connection object was never valid, we can close
119266e564dSmrg     * it right now.  This happens if IceAcceptConnection was
120266e564dSmrg     * called, but after calling IceProcessMessages several times
121266e564dSmrg     * the connection was rejected (because of authentication or
122266e564dSmrg     * some other reason).
123266e564dSmrg     */
124266e564dSmrg
125266e564dSmrg    if (iceConn->listen_obj &&
126266e564dSmrg	iceConn->connection_status != IceConnectAccepted)
127266e564dSmrg    {
128266e564dSmrg	_IceConnectionClosed (iceConn);		/* invoke watch procs */
129266e564dSmrg	_IceFreeConnection (iceConn);
130266e564dSmrg	return (IceClosedNow);
131266e564dSmrg    }
132266e564dSmrg
133266e564dSmrg
134266e564dSmrg    /*---------------------------------------------------------------
135266e564dSmrg
136266e564dSmrg    ACTIONS:
137266e564dSmrg
138266e564dSmrg    A = Invoke Watch Procedures
139266e564dSmrg    B = Set free-asap bit
140266e564dSmrg    C = Free connection
141266e564dSmrg    D = Initialize shutdown negotiation
142266e564dSmrg    N = do nothing
143266e564dSmrg
144266e564dSmrg
145266e564dSmrg    ACTION TABLE:
146266e564dSmrg
147266e564dSmrg    IO	       free-      dispatch   protocol   shutdown
148266e564dSmrg    error      asap bit   level      refcount   negotiation     ACTION
149266e564dSmrg    occured    set        reached 0  reached 0
150266e564dSmrg
151266e564dSmrg        0          0          0          0          0		N
152266e564dSmrg        0          0          0          0          1		N
153266e564dSmrg        0          0          0          1          0		AB
154266e564dSmrg        0          0          0          1          1		N
155266e564dSmrg        0          0          1          0          0		N
156266e564dSmrg        0          0          1          0          1		N
157266e564dSmrg        0          0          1          1          0		AC
158266e564dSmrg        0          0          1          1          1		D
159266e564dSmrg        0          1          0          0          0		N
160266e564dSmrg        0          1          0          0          1		N
161266e564dSmrg        0          1          0          1          0		N
162266e564dSmrg        0          1          0          1          1		N
163266e564dSmrg        0          1          1          0          0		C
164266e564dSmrg        0          1          1          0          1		D
165266e564dSmrg        0          1          1          1          0		C
166266e564dSmrg        0          1          1          1          1		D
167266e564dSmrg        1          0          0          0          0		AB
168266e564dSmrg        1          0          0          0          1		AB
169266e564dSmrg        1          0          0          1          0		AB
170266e564dSmrg        1          0          0          1          1		AB
171266e564dSmrg        1          0          1          0          0		AC
172266e564dSmrg        1          0          1          0          1		AC
173266e564dSmrg        1          0          1          1          0		AC
174266e564dSmrg        1          0          1          1          1		AC
175266e564dSmrg        1          1          0          0          0		N
176266e564dSmrg        1          1          0          0          1		N
177266e564dSmrg        1          1          0          1          0		N
178266e564dSmrg        1          1          0          1          1		N
179266e564dSmrg        1          1          1          0          0		C
180266e564dSmrg        1          1          1          0          1		C
181266e564dSmrg        1          1          1          1          0		C
182266e564dSmrg        1          1          1          1          1		C
183266e564dSmrg
184266e564dSmrg    ---------------------------------------------------------------*/
185266e564dSmrg
186266e564dSmrg    if (iceConn->open_ref_count > 0)
187266e564dSmrg	iceConn->open_ref_count--;
188266e564dSmrg
189266e564dSmrg    refCountReachedZero = iceConn->open_ref_count == 0 &&
190266e564dSmrg	iceConn->proto_ref_count == 0;
191266e564dSmrg
192266e564dSmrg    status = IceConnectionInUse;
193266e564dSmrg
194266e564dSmrg    if (!iceConn->free_asap && (!iceConn->io_ok ||
195266e564dSmrg	(iceConn->io_ok && refCountReachedZero &&
196266e564dSmrg	iceConn->skip_want_to_close)))
197266e564dSmrg    {
198266e564dSmrg	/*
199266e564dSmrg	 * Invoke the watch procedures now.
200266e564dSmrg	 */
201266e564dSmrg
202266e564dSmrg	_IceConnectionClosed (iceConn);
203266e564dSmrg	status = IceClosedNow;	     /* may be overwritten by IceClosedASAP */
204266e564dSmrg    }
205266e564dSmrg
206266e564dSmrg    if (!iceConn->free_asap && iceConn->dispatch_level != 0 &&
207266e564dSmrg	(!iceConn->io_ok ||
208266e564dSmrg	(iceConn->io_ok && refCountReachedZero &&
209266e564dSmrg	iceConn->skip_want_to_close)))
210266e564dSmrg    {
211266e564dSmrg	/*
212266e564dSmrg	 * Set flag so we free the connection as soon as possible.
213266e564dSmrg	 */
214266e564dSmrg
215266e564dSmrg	iceConn->free_asap = True;
216266e564dSmrg	status = IceClosedASAP;
217266e564dSmrg    }
218266e564dSmrg
219266e564dSmrg    if (iceConn->io_ok && iceConn->dispatch_level == 0 &&
220266e564dSmrg	!iceConn->skip_want_to_close && refCountReachedZero)
221266e564dSmrg    {
222266e564dSmrg	/*
223266e564dSmrg	 * Initiate shutdown negotiation.
224266e564dSmrg	 */
225266e564dSmrg
226266e564dSmrg	IceSimpleMessage (iceConn, 0, ICE_WantToClose);
227266e564dSmrg	IceFlush (iceConn);
228266e564dSmrg
229266e564dSmrg	iceConn->want_to_close = 1;
230266e564dSmrg
231266e564dSmrg	status = IceStartedShutdownNegotiation;
232266e564dSmrg    }
233266e564dSmrg    else if (iceConn->dispatch_level == 0 &&
234266e564dSmrg	(!iceConn->io_ok || (iceConn->io_ok && iceConn->skip_want_to_close &&
235266e564dSmrg	(iceConn->free_asap || (!iceConn->free_asap && refCountReachedZero)))))
236266e564dSmrg    {
237266e564dSmrg	/*
238266e564dSmrg	 * Free the connection.
239266e564dSmrg	 */
240266e564dSmrg
241266e564dSmrg	_IceFreeConnection (iceConn);
242266e564dSmrg
243266e564dSmrg	status = IceClosedNow;
244266e564dSmrg    }
245266e564dSmrg
246266e564dSmrg    return (status);
247266e564dSmrg}
248266e564dSmrg
249266e564dSmrg
250266e564dSmrg
251266e564dSmrgvoid
252c5629e66Smrg_IceFreeConnection (
253c5629e66Smrg	IceConn iceConn
254c5629e66Smrg)
255266e564dSmrg{
256266e564dSmrg    if (iceConn->listen_obj == NULL)
257266e564dSmrg    {
258266e564dSmrg	/*
259266e564dSmrg	 * This iceConn was created with IceOpenConnection.
260266e564dSmrg	 * We keep track of all open IceConn's, so we need
261266e564dSmrg	 * to remove it from the list.
262266e564dSmrg	 */
263266e564dSmrg
264266e564dSmrg	int i;
265266e564dSmrg
266266e564dSmrg	for (i = 0; i < _IceConnectionCount; i++)
267266e564dSmrg	    if (_IceConnectionObjs[i] == iceConn)
268266e564dSmrg		break;
269266e564dSmrg
270266e564dSmrg	if (i < _IceConnectionCount)
271266e564dSmrg	{
272266e564dSmrg	    if (i < _IceConnectionCount - 1)
273266e564dSmrg	    {
274266e564dSmrg		_IceConnectionObjs[i] =
275266e564dSmrg		    _IceConnectionObjs[_IceConnectionCount - 1];
276266e564dSmrg		_IceConnectionStrings[i] =
277266e564dSmrg		    _IceConnectionStrings[_IceConnectionCount - 1];
278266e564dSmrg	    }
279266e564dSmrg
280266e564dSmrg	    _IceConnectionCount--;
281266e564dSmrg	}
282266e564dSmrg    }
283266e564dSmrg
284266e564dSmrg    if (iceConn->trans_conn)
285266e564dSmrg	_IceTransClose (iceConn->trans_conn);
286266e564dSmrg
287266e564dSmrg    if (iceConn->connection_string)
288266e564dSmrg	free (iceConn->connection_string);
289266e564dSmrg
290266e564dSmrg    if (iceConn->vendor)
291266e564dSmrg	free (iceConn->vendor);
292266e564dSmrg
293266e564dSmrg    if (iceConn->release)
294266e564dSmrg	free (iceConn->release);
295266e564dSmrg
296266e564dSmrg    if (iceConn->inbuf)
297266e564dSmrg	free (iceConn->inbuf);
298266e564dSmrg
299266e564dSmrg    if (iceConn->outbuf)
300266e564dSmrg	free (iceConn->outbuf);
301266e564dSmrg
302266e564dSmrg    if (iceConn->scratch)
303266e564dSmrg	free (iceConn->scratch);
304266e564dSmrg
305266e564dSmrg    if (iceConn->process_msg_info)
306266e564dSmrg	free ((char *) iceConn->process_msg_info);
307266e564dSmrg
308266e564dSmrg    if (iceConn->connect_to_you)
309266e564dSmrg	free ((char *) iceConn->connect_to_you);
310266e564dSmrg
311266e564dSmrg    if (iceConn->protosetup_to_you)
312266e564dSmrg	free ((char *) iceConn->protosetup_to_you);
313266e564dSmrg
314266e564dSmrg    if (iceConn->connect_to_me)
315266e564dSmrg	free ((char *) iceConn->connect_to_me);
316266e564dSmrg
317266e564dSmrg    if (iceConn->protosetup_to_me)
318266e564dSmrg	free ((char *) iceConn->protosetup_to_me);
319266e564dSmrg
320266e564dSmrg    free ((char *) iceConn);
321266e564dSmrg}
322266e564dSmrg
323266e564dSmrg
324266e564dSmrg
325266e564dSmrg
326