Home | History | Annotate | Line # | Download | only in src
      1 /******************************************************************************
      2 
      3 
      4 Copyright 1993, 1998  The Open Group
      5 
      6 Permission to use, copy, modify, distribute, and sell this software and its
      7 documentation for any purpose is hereby granted without fee, provided that
      8 the above copyright notice appear in all copies and that both that
      9 copyright notice and this permission notice appear in supporting
     10 documentation.
     11 
     12 The above copyright notice and this permission notice shall be included in
     13 all copies or substantial portions of the Software.
     14 
     15 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     16 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     17 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
     18 OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
     19 AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
     20 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
     21 
     22 Except as contained in this notice, the name of The Open Group shall not be
     23 used in advertising or otherwise to promote the sale, use or other dealings
     24 in this Software without prior written authorization from The Open Group.
     25 
     26 Author: Ralph Mor, X Consortium
     27 ******************************************************************************/
     28 
     29 #ifdef HAVE_CONFIG_H
     30 #include <config.h>
     31 #endif
     32 #include <X11/ICE/ICElib.h>
     33 #include "ICElibint.h"
     34 #include <X11/Xtrans/Xtrans.h>
     35 
     36 
     37 Status
     38 IceProtocolShutdown (
     39 	IceConn iceConn,
     40 	int	majorOpcode
     41 )
     42 {
     43     int i;
     44 
     45     if (iceConn->proto_ref_count == 0 || iceConn->process_msg_info == NULL ||
     46         majorOpcode < 1 || majorOpcode > _IceLastMajorOpcode)
     47     {
     48 	return (0);
     49     }
     50 
     51 
     52     /*
     53      * Make sure this majorOpcode is really being used.
     54      */
     55 
     56     for (i = iceConn->his_min_opcode; i <= iceConn->his_max_opcode; i++)
     57     {
     58 	int n = i - iceConn->his_min_opcode;
     59 	if (iceConn->process_msg_info[n].in_use &&
     60 	    iceConn->process_msg_info[n].my_opcode == majorOpcode)
     61 	{
     62 
     63 	    /*
     64 	     * OK, we can shut down the protocol.
     65 	     */
     66 
     67 	    iceConn->process_msg_info[n].in_use = False;
     68 	    iceConn->proto_ref_count--;
     69 	    return (1);
     70 	}
     71     }
     72 
     73     return (0);
     74 }
     75 
     76 
     77 
     78 void
     79 IceSetShutdownNegotiation (
     80 	IceConn     	iceConn,
     81 	Bool		negotiate
     82 )
     83 {
     84     iceConn->skip_want_to_close = negotiate ? False : True;
     85 }
     86 
     87 
     88 
     89 Bool
     90 IceCheckShutdownNegotiation (
     91 	IceConn     iceConn
     92 )
     93 {
     94     return (iceConn->skip_want_to_close ? False : True);
     95 }
     96 
     97 
     98 
     99 IceCloseStatus
    100 IceCloseConnection (
    101 	IceConn     iceConn
    102 )
    103 {
    104     int refCountReachedZero;
    105     IceCloseStatus status;
    106 
    107     /*
    108      * If this connection object was never valid, we can close
    109      * it right now.  This happens if IceAcceptConnection was
    110      * called, but after calling IceProcessMessages several times
    111      * the connection was rejected (because of authentication or
    112      * some other reason).
    113      */
    114 
    115     if (iceConn->listen_obj &&
    116 	iceConn->connection_status != IceConnectAccepted)
    117     {
    118 	_IceConnectionClosed (iceConn);		/* invoke watch procs */
    119 	_IceFreeConnection (iceConn);
    120 	return (IceClosedNow);
    121     }
    122 
    123 
    124     /*---------------------------------------------------------------
    125 
    126     ACTIONS:
    127 
    128     A = Invoke Watch Procedures
    129     B = Set free-asap bit
    130     C = Free connection
    131     D = Initialize shutdown negotiation
    132     N = do nothing
    133 
    134 
    135     ACTION TABLE:
    136 
    137     IO	       free-      dispatch   protocol   shutdown
    138     error      asap bit   level      refcount   negotiation     ACTION
    139     occurred   set        reached 0  reached 0
    140 
    141         0          0          0          0          0		N
    142         0          0          0          0          1		N
    143         0          0          0          1          0		AB
    144         0          0          0          1          1		N
    145         0          0          1          0          0		N
    146         0          0          1          0          1		N
    147         0          0          1          1          0		AC
    148         0          0          1          1          1		D
    149         0          1          0          0          0		N
    150         0          1          0          0          1		N
    151         0          1          0          1          0		N
    152         0          1          0          1          1		N
    153         0          1          1          0          0		C
    154         0          1          1          0          1		D
    155         0          1          1          1          0		C
    156         0          1          1          1          1		D
    157         1          0          0          0          0		AB
    158         1          0          0          0          1		AB
    159         1          0          0          1          0		AB
    160         1          0          0          1          1		AB
    161         1          0          1          0          0		AC
    162         1          0          1          0          1		AC
    163         1          0          1          1          0		AC
    164         1          0          1          1          1		AC
    165         1          1          0          0          0		N
    166         1          1          0          0          1		N
    167         1          1          0          1          0		N
    168         1          1          0          1          1		N
    169         1          1          1          0          0		C
    170         1          1          1          0          1		C
    171         1          1          1          1          0		C
    172         1          1          1          1          1		C
    173 
    174     ---------------------------------------------------------------*/
    175 
    176     if (iceConn->open_ref_count > 0)
    177 	iceConn->open_ref_count--;
    178 
    179     refCountReachedZero = iceConn->open_ref_count == 0 &&
    180 	iceConn->proto_ref_count == 0;
    181 
    182     status = IceConnectionInUse;
    183 
    184     if (!iceConn->free_asap && (!iceConn->io_ok ||
    185 	(iceConn->io_ok && refCountReachedZero &&
    186 	iceConn->skip_want_to_close)))
    187     {
    188 	/*
    189 	 * Invoke the watch procedures now.
    190 	 */
    191 
    192 	_IceConnectionClosed (iceConn);
    193 	status = IceClosedNow;	     /* may be overwritten by IceClosedASAP */
    194     }
    195 
    196     if (!iceConn->free_asap && iceConn->dispatch_level != 0 &&
    197 	(!iceConn->io_ok ||
    198 	(iceConn->io_ok && refCountReachedZero &&
    199 	iceConn->skip_want_to_close)))
    200     {
    201 	/*
    202 	 * Set flag so we free the connection as soon as possible.
    203 	 */
    204 
    205 	iceConn->free_asap = True;
    206 	status = IceClosedASAP;
    207     }
    208 
    209     if (iceConn->io_ok && iceConn->dispatch_level == 0 &&
    210 	!iceConn->skip_want_to_close && refCountReachedZero)
    211     {
    212 	/*
    213 	 * Initiate shutdown negotiation.
    214 	 */
    215 
    216 	IceSimpleMessage (iceConn, 0, ICE_WantToClose);
    217 	IceFlush (iceConn);
    218 
    219 	iceConn->want_to_close = 1;
    220 
    221 	status = IceStartedShutdownNegotiation;
    222     }
    223     else if (iceConn->dispatch_level == 0 &&
    224 	(!iceConn->io_ok || (iceConn->io_ok && iceConn->skip_want_to_close &&
    225 	(iceConn->free_asap || (!iceConn->free_asap && refCountReachedZero)))))
    226     {
    227 	/*
    228 	 * Free the connection.
    229 	 */
    230 
    231 	_IceFreeConnection (iceConn);
    232 
    233 	status = IceClosedNow;
    234     }
    235 
    236     return (status);
    237 }
    238 
    239 
    240 
    241 void
    242 _IceFreeConnection (
    243 	IceConn iceConn
    244 )
    245 {
    246     if (iceConn->listen_obj == NULL)
    247     {
    248 	/*
    249 	 * This iceConn was created with IceOpenConnection.
    250 	 * We keep track of all open IceConn's, so we need
    251 	 * to remove it from the list.
    252 	 */
    253 
    254 	int i;
    255 
    256 	for (i = 0; i < _IceConnectionCount; i++)
    257 	    if (_IceConnectionObjs[i] == iceConn)
    258 		break;
    259 
    260 	if (i < _IceConnectionCount)
    261 	{
    262 	    if (i < _IceConnectionCount - 1)
    263 	    {
    264 		_IceConnectionObjs[i] =
    265 		    _IceConnectionObjs[_IceConnectionCount - 1];
    266 		_IceConnectionStrings[i] =
    267 		    _IceConnectionStrings[_IceConnectionCount - 1];
    268 	    }
    269 
    270 	    _IceConnectionCount--;
    271 	}
    272     }
    273 
    274     if (iceConn->trans_conn)
    275 	_IceTransClose (iceConn->trans_conn);
    276 
    277     free (iceConn->connection_string);
    278     free (iceConn->vendor);
    279     free (iceConn->release);
    280     free (iceConn->inbuf);
    281     free (iceConn->outbuf);
    282     free (iceConn->scratch);
    283     free (iceConn->process_msg_info);
    284     free (iceConn->connect_to_you);
    285     free (iceConn->protosetup_to_you);
    286     free (iceConn->connect_to_me);
    287     free (iceConn->protosetup_to_me);
    288     free (iceConn);
    289 }
    290 
    291 
    292 
    293 
    294