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