shutdown.c revision 266e564d
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 40266e564dSmrgIceProtocolShutdown (iceConn, majorOpcode) 41266e564dSmrg 42266e564dSmrgIceConn iceConn; 43266e564dSmrgint majorOpcode; 44266e564dSmrg 45266e564dSmrg{ 46266e564dSmrg if (iceConn->proto_ref_count == 0 || iceConn->process_msg_info == NULL || 47266e564dSmrg majorOpcode < 1 || majorOpcode > _IceLastMajorOpcode) 48266e564dSmrg { 49266e564dSmrg return (0); 50266e564dSmrg } 51266e564dSmrg else 52266e564dSmrg { 53266e564dSmrg /* 54266e564dSmrg * Make sure this majorOpcode is really being used. 55266e564dSmrg */ 56266e564dSmrg 57266e564dSmrg int i; 58266e564dSmrg 59266e564dSmrg for (i = iceConn->his_min_opcode; i <= iceConn->his_max_opcode; i++) 60266e564dSmrg { 61266e564dSmrg if (iceConn->process_msg_info[ 62266e564dSmrg i - iceConn->his_min_opcode].in_use && 63266e564dSmrg iceConn->process_msg_info[ 64266e564dSmrg i - iceConn->his_min_opcode].my_opcode == majorOpcode) 65266e564dSmrg break; 66266e564dSmrg } 67266e564dSmrg 68266e564dSmrg if (i > iceConn->his_max_opcode) 69266e564dSmrg { 70266e564dSmrg return (0); 71266e564dSmrg } 72266e564dSmrg else 73266e564dSmrg { 74266e564dSmrg /* 75266e564dSmrg * OK, we can shut down the protocol. 76266e564dSmrg */ 77266e564dSmrg 78266e564dSmrg iceConn->process_msg_info[ 79266e564dSmrg i - iceConn->his_min_opcode].in_use = False; 80266e564dSmrg iceConn->proto_ref_count--; 81266e564dSmrg 82266e564dSmrg return (1); 83266e564dSmrg } 84266e564dSmrg } 85266e564dSmrg} 86266e564dSmrg 87266e564dSmrg 88266e564dSmrg 89266e564dSmrgvoid 90266e564dSmrgIceSetShutdownNegotiation (iceConn, negotiate) 91266e564dSmrg 92266e564dSmrgIceConn iceConn; 93266e564dSmrgBool negotiate; 94266e564dSmrg 95266e564dSmrg{ 96266e564dSmrg iceConn->skip_want_to_close = negotiate ? False : True; 97266e564dSmrg} 98266e564dSmrg 99266e564dSmrg 100266e564dSmrg 101266e564dSmrgBool 102266e564dSmrgIceCheckShutdownNegotiation (iceConn) 103266e564dSmrg 104266e564dSmrgIceConn iceConn; 105266e564dSmrg 106266e564dSmrg{ 107266e564dSmrg return (iceConn->skip_want_to_close ? False : True); 108266e564dSmrg} 109266e564dSmrg 110266e564dSmrg 111266e564dSmrg 112266e564dSmrgIceCloseStatus 113266e564dSmrgIceCloseConnection (iceConn) 114266e564dSmrg 115266e564dSmrgIceConn iceConn; 116266e564dSmrg 117266e564dSmrg{ 118266e564dSmrg int refCountReachedZero; 119266e564dSmrg IceCloseStatus status; 120266e564dSmrg 121266e564dSmrg /* 122266e564dSmrg * If this connection object was never valid, we can close 123266e564dSmrg * it right now. This happens if IceAcceptConnection was 124266e564dSmrg * called, but after calling IceProcessMessages several times 125266e564dSmrg * the connection was rejected (because of authentication or 126266e564dSmrg * some other reason). 127266e564dSmrg */ 128266e564dSmrg 129266e564dSmrg if (iceConn->listen_obj && 130266e564dSmrg iceConn->connection_status != IceConnectAccepted) 131266e564dSmrg { 132266e564dSmrg _IceConnectionClosed (iceConn); /* invoke watch procs */ 133266e564dSmrg _IceFreeConnection (iceConn); 134266e564dSmrg return (IceClosedNow); 135266e564dSmrg } 136266e564dSmrg 137266e564dSmrg 138266e564dSmrg /*--------------------------------------------------------------- 139266e564dSmrg 140266e564dSmrg ACTIONS: 141266e564dSmrg 142266e564dSmrg A = Invoke Watch Procedures 143266e564dSmrg B = Set free-asap bit 144266e564dSmrg C = Free connection 145266e564dSmrg D = Initialize shutdown negotiation 146266e564dSmrg N = do nothing 147266e564dSmrg 148266e564dSmrg 149266e564dSmrg ACTION TABLE: 150266e564dSmrg 151266e564dSmrg IO free- dispatch protocol shutdown 152266e564dSmrg error asap bit level refcount negotiation ACTION 153266e564dSmrg occured set reached 0 reached 0 154266e564dSmrg 155266e564dSmrg 0 0 0 0 0 N 156266e564dSmrg 0 0 0 0 1 N 157266e564dSmrg 0 0 0 1 0 AB 158266e564dSmrg 0 0 0 1 1 N 159266e564dSmrg 0 0 1 0 0 N 160266e564dSmrg 0 0 1 0 1 N 161266e564dSmrg 0 0 1 1 0 AC 162266e564dSmrg 0 0 1 1 1 D 163266e564dSmrg 0 1 0 0 0 N 164266e564dSmrg 0 1 0 0 1 N 165266e564dSmrg 0 1 0 1 0 N 166266e564dSmrg 0 1 0 1 1 N 167266e564dSmrg 0 1 1 0 0 C 168266e564dSmrg 0 1 1 0 1 D 169266e564dSmrg 0 1 1 1 0 C 170266e564dSmrg 0 1 1 1 1 D 171266e564dSmrg 1 0 0 0 0 AB 172266e564dSmrg 1 0 0 0 1 AB 173266e564dSmrg 1 0 0 1 0 AB 174266e564dSmrg 1 0 0 1 1 AB 175266e564dSmrg 1 0 1 0 0 AC 176266e564dSmrg 1 0 1 0 1 AC 177266e564dSmrg 1 0 1 1 0 AC 178266e564dSmrg 1 0 1 1 1 AC 179266e564dSmrg 1 1 0 0 0 N 180266e564dSmrg 1 1 0 0 1 N 181266e564dSmrg 1 1 0 1 0 N 182266e564dSmrg 1 1 0 1 1 N 183266e564dSmrg 1 1 1 0 0 C 184266e564dSmrg 1 1 1 0 1 C 185266e564dSmrg 1 1 1 1 0 C 186266e564dSmrg 1 1 1 1 1 C 187266e564dSmrg 188266e564dSmrg ---------------------------------------------------------------*/ 189266e564dSmrg 190266e564dSmrg if (iceConn->open_ref_count > 0) 191266e564dSmrg iceConn->open_ref_count--; 192266e564dSmrg 193266e564dSmrg refCountReachedZero = iceConn->open_ref_count == 0 && 194266e564dSmrg iceConn->proto_ref_count == 0; 195266e564dSmrg 196266e564dSmrg status = IceConnectionInUse; 197266e564dSmrg 198266e564dSmrg if (!iceConn->free_asap && (!iceConn->io_ok || 199266e564dSmrg (iceConn->io_ok && refCountReachedZero && 200266e564dSmrg iceConn->skip_want_to_close))) 201266e564dSmrg { 202266e564dSmrg /* 203266e564dSmrg * Invoke the watch procedures now. 204266e564dSmrg */ 205266e564dSmrg 206266e564dSmrg _IceConnectionClosed (iceConn); 207266e564dSmrg status = IceClosedNow; /* may be overwritten by IceClosedASAP */ 208266e564dSmrg } 209266e564dSmrg 210266e564dSmrg if (!iceConn->free_asap && iceConn->dispatch_level != 0 && 211266e564dSmrg (!iceConn->io_ok || 212266e564dSmrg (iceConn->io_ok && refCountReachedZero && 213266e564dSmrg iceConn->skip_want_to_close))) 214266e564dSmrg { 215266e564dSmrg /* 216266e564dSmrg * Set flag so we free the connection as soon as possible. 217266e564dSmrg */ 218266e564dSmrg 219266e564dSmrg iceConn->free_asap = True; 220266e564dSmrg status = IceClosedASAP; 221266e564dSmrg } 222266e564dSmrg 223266e564dSmrg if (iceConn->io_ok && iceConn->dispatch_level == 0 && 224266e564dSmrg !iceConn->skip_want_to_close && refCountReachedZero) 225266e564dSmrg { 226266e564dSmrg /* 227266e564dSmrg * Initiate shutdown negotiation. 228266e564dSmrg */ 229266e564dSmrg 230266e564dSmrg IceSimpleMessage (iceConn, 0, ICE_WantToClose); 231266e564dSmrg IceFlush (iceConn); 232266e564dSmrg 233266e564dSmrg iceConn->want_to_close = 1; 234266e564dSmrg 235266e564dSmrg status = IceStartedShutdownNegotiation; 236266e564dSmrg } 237266e564dSmrg else if (iceConn->dispatch_level == 0 && 238266e564dSmrg (!iceConn->io_ok || (iceConn->io_ok && iceConn->skip_want_to_close && 239266e564dSmrg (iceConn->free_asap || (!iceConn->free_asap && refCountReachedZero))))) 240266e564dSmrg { 241266e564dSmrg /* 242266e564dSmrg * Free the connection. 243266e564dSmrg */ 244266e564dSmrg 245266e564dSmrg _IceFreeConnection (iceConn); 246266e564dSmrg 247266e564dSmrg status = IceClosedNow; 248266e564dSmrg } 249266e564dSmrg 250266e564dSmrg return (status); 251266e564dSmrg} 252266e564dSmrg 253266e564dSmrg 254266e564dSmrg 255266e564dSmrgvoid 256266e564dSmrg_IceFreeConnection (iceConn) 257266e564dSmrg 258266e564dSmrgIceConn iceConn; 259266e564dSmrg 260266e564dSmrg{ 261266e564dSmrg if (iceConn->listen_obj == NULL) 262266e564dSmrg { 263266e564dSmrg /* 264266e564dSmrg * This iceConn was created with IceOpenConnection. 265266e564dSmrg * We keep track of all open IceConn's, so we need 266266e564dSmrg * to remove it from the list. 267266e564dSmrg */ 268266e564dSmrg 269266e564dSmrg int i; 270266e564dSmrg 271266e564dSmrg for (i = 0; i < _IceConnectionCount; i++) 272266e564dSmrg if (_IceConnectionObjs[i] == iceConn) 273266e564dSmrg break; 274266e564dSmrg 275266e564dSmrg if (i < _IceConnectionCount) 276266e564dSmrg { 277266e564dSmrg if (i < _IceConnectionCount - 1) 278266e564dSmrg { 279266e564dSmrg _IceConnectionObjs[i] = 280266e564dSmrg _IceConnectionObjs[_IceConnectionCount - 1]; 281266e564dSmrg _IceConnectionStrings[i] = 282266e564dSmrg _IceConnectionStrings[_IceConnectionCount - 1]; 283266e564dSmrg } 284266e564dSmrg 285266e564dSmrg _IceConnectionCount--; 286266e564dSmrg } 287266e564dSmrg } 288266e564dSmrg 289266e564dSmrg if (iceConn->trans_conn) 290266e564dSmrg _IceTransClose (iceConn->trans_conn); 291266e564dSmrg 292266e564dSmrg if (iceConn->connection_string) 293266e564dSmrg free (iceConn->connection_string); 294266e564dSmrg 295266e564dSmrg if (iceConn->vendor) 296266e564dSmrg free (iceConn->vendor); 297266e564dSmrg 298266e564dSmrg if (iceConn->release) 299266e564dSmrg free (iceConn->release); 300266e564dSmrg 301266e564dSmrg if (iceConn->inbuf) 302266e564dSmrg free (iceConn->inbuf); 303266e564dSmrg 304266e564dSmrg if (iceConn->outbuf) 305266e564dSmrg free (iceConn->outbuf); 306266e564dSmrg 307266e564dSmrg if (iceConn->scratch) 308266e564dSmrg free (iceConn->scratch); 309266e564dSmrg 310266e564dSmrg if (iceConn->process_msg_info) 311266e564dSmrg free ((char *) iceConn->process_msg_info); 312266e564dSmrg 313266e564dSmrg if (iceConn->connect_to_you) 314266e564dSmrg free ((char *) iceConn->connect_to_you); 315266e564dSmrg 316266e564dSmrg if (iceConn->protosetup_to_you) 317266e564dSmrg free ((char *) iceConn->protosetup_to_you); 318266e564dSmrg 319266e564dSmrg if (iceConn->connect_to_me) 320266e564dSmrg free ((char *) iceConn->connect_to_me); 321266e564dSmrg 322266e564dSmrg if (iceConn->protosetup_to_me) 323266e564dSmrg free ((char *) iceConn->protosetup_to_me); 324266e564dSmrg 325266e564dSmrg free ((char *) iceConn); 326266e564dSmrg} 327266e564dSmrg 328266e564dSmrg 329266e564dSmrg 330266e564dSmrg 331