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