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