shutdown.c revision a3129944
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{ 43a3129944Smrg int i; 44a3129944Smrg 45266e564dSmrg if (iceConn->proto_ref_count == 0 || iceConn->process_msg_info == NULL || 46266e564dSmrg majorOpcode < 1 || majorOpcode > _IceLastMajorOpcode) 47266e564dSmrg { 48266e564dSmrg return (0); 49266e564dSmrg } 50266e564dSmrg 51266e564dSmrg 52a3129944Smrg /* 53a3129944Smrg * Make sure this majorOpcode is really being used. 54a3129944Smrg */ 55266e564dSmrg 56a3129944Smrg for (i = iceConn->his_min_opcode; i <= iceConn->his_max_opcode; i++) 57a3129944Smrg { 58a3129944Smrg int n = i - iceConn->his_min_opcode; 59a3129944Smrg if (iceConn->process_msg_info[n].in_use && 60a3129944Smrg iceConn->process_msg_info[n].my_opcode == majorOpcode) 61266e564dSmrg { 62a3129944Smrg 63266e564dSmrg /* 64266e564dSmrg * OK, we can shut down the protocol. 65266e564dSmrg */ 66266e564dSmrg 67a3129944Smrg iceConn->process_msg_info[n].in_use = False; 68266e564dSmrg iceConn->proto_ref_count--; 69266e564dSmrg return (1); 70266e564dSmrg } 71266e564dSmrg } 72a3129944Smrg 73a3129944Smrg return (0); 74266e564dSmrg} 75266e564dSmrg 76266e564dSmrg 77a3129944Smrg 78266e564dSmrgvoid 79c5629e66SmrgIceSetShutdownNegotiation ( 80c5629e66Smrg IceConn iceConn, 81c5629e66Smrg Bool negotiate 82c5629e66Smrg) 83266e564dSmrg{ 84266e564dSmrg iceConn->skip_want_to_close = negotiate ? False : True; 85266e564dSmrg} 86266e564dSmrg 87266e564dSmrg 88a3129944Smrg 89266e564dSmrgBool 90c5629e66SmrgIceCheckShutdownNegotiation ( 91c5629e66Smrg IceConn iceConn 92c5629e66Smrg) 93266e564dSmrg{ 94266e564dSmrg return (iceConn->skip_want_to_close ? False : True); 95266e564dSmrg} 96266e564dSmrg 97266e564dSmrg 98a3129944Smrg 99266e564dSmrgIceCloseStatus 100c5629e66SmrgIceCloseConnection ( 101c5629e66Smrg IceConn iceConn 102c5629e66Smrg) 103266e564dSmrg{ 104266e564dSmrg int refCountReachedZero; 105266e564dSmrg IceCloseStatus status; 106266e564dSmrg 107266e564dSmrg /* 108266e564dSmrg * If this connection object was never valid, we can close 109266e564dSmrg * it right now. This happens if IceAcceptConnection was 110266e564dSmrg * called, but after calling IceProcessMessages several times 111266e564dSmrg * the connection was rejected (because of authentication or 112266e564dSmrg * some other reason). 113266e564dSmrg */ 114266e564dSmrg 115266e564dSmrg if (iceConn->listen_obj && 116266e564dSmrg iceConn->connection_status != IceConnectAccepted) 117266e564dSmrg { 118266e564dSmrg _IceConnectionClosed (iceConn); /* invoke watch procs */ 119266e564dSmrg _IceFreeConnection (iceConn); 120266e564dSmrg return (IceClosedNow); 121266e564dSmrg } 122266e564dSmrg 123266e564dSmrg 124266e564dSmrg /*--------------------------------------------------------------- 125266e564dSmrg 126266e564dSmrg ACTIONS: 127266e564dSmrg 128266e564dSmrg A = Invoke Watch Procedures 129266e564dSmrg B = Set free-asap bit 130266e564dSmrg C = Free connection 131266e564dSmrg D = Initialize shutdown negotiation 132266e564dSmrg N = do nothing 133266e564dSmrg 134266e564dSmrg 135266e564dSmrg ACTION TABLE: 136266e564dSmrg 137266e564dSmrg IO free- dispatch protocol shutdown 138266e564dSmrg error asap bit level refcount negotiation ACTION 139266e564dSmrg occured set reached 0 reached 0 1409ef0b394Smrg 141266e564dSmrg 0 0 0 0 0 N 142266e564dSmrg 0 0 0 0 1 N 143266e564dSmrg 0 0 0 1 0 AB 144266e564dSmrg 0 0 0 1 1 N 145266e564dSmrg 0 0 1 0 0 N 146266e564dSmrg 0 0 1 0 1 N 147266e564dSmrg 0 0 1 1 0 AC 148266e564dSmrg 0 0 1 1 1 D 149266e564dSmrg 0 1 0 0 0 N 150266e564dSmrg 0 1 0 0 1 N 151266e564dSmrg 0 1 0 1 0 N 152266e564dSmrg 0 1 0 1 1 N 153266e564dSmrg 0 1 1 0 0 C 154266e564dSmrg 0 1 1 0 1 D 155266e564dSmrg 0 1 1 1 0 C 156266e564dSmrg 0 1 1 1 1 D 157266e564dSmrg 1 0 0 0 0 AB 158266e564dSmrg 1 0 0 0 1 AB 159266e564dSmrg 1 0 0 1 0 AB 160266e564dSmrg 1 0 0 1 1 AB 161266e564dSmrg 1 0 1 0 0 AC 162266e564dSmrg 1 0 1 0 1 AC 163266e564dSmrg 1 0 1 1 0 AC 164266e564dSmrg 1 0 1 1 1 AC 165266e564dSmrg 1 1 0 0 0 N 166266e564dSmrg 1 1 0 0 1 N 167266e564dSmrg 1 1 0 1 0 N 168266e564dSmrg 1 1 0 1 1 N 169266e564dSmrg 1 1 1 0 0 C 170266e564dSmrg 1 1 1 0 1 C 171266e564dSmrg 1 1 1 1 0 C 172266e564dSmrg 1 1 1 1 1 C 173266e564dSmrg 174266e564dSmrg ---------------------------------------------------------------*/ 175266e564dSmrg 176266e564dSmrg if (iceConn->open_ref_count > 0) 177266e564dSmrg iceConn->open_ref_count--; 178266e564dSmrg 179266e564dSmrg refCountReachedZero = iceConn->open_ref_count == 0 && 180266e564dSmrg iceConn->proto_ref_count == 0; 181266e564dSmrg 182266e564dSmrg status = IceConnectionInUse; 183266e564dSmrg 184266e564dSmrg if (!iceConn->free_asap && (!iceConn->io_ok || 185266e564dSmrg (iceConn->io_ok && refCountReachedZero && 186266e564dSmrg iceConn->skip_want_to_close))) 187266e564dSmrg { 188266e564dSmrg /* 189266e564dSmrg * Invoke the watch procedures now. 190266e564dSmrg */ 191266e564dSmrg 192266e564dSmrg _IceConnectionClosed (iceConn); 193266e564dSmrg status = IceClosedNow; /* may be overwritten by IceClosedASAP */ 194266e564dSmrg } 195266e564dSmrg 196266e564dSmrg if (!iceConn->free_asap && iceConn->dispatch_level != 0 && 197266e564dSmrg (!iceConn->io_ok || 198266e564dSmrg (iceConn->io_ok && refCountReachedZero && 199266e564dSmrg iceConn->skip_want_to_close))) 200266e564dSmrg { 201266e564dSmrg /* 202266e564dSmrg * Set flag so we free the connection as soon as possible. 203266e564dSmrg */ 204266e564dSmrg 205266e564dSmrg iceConn->free_asap = True; 206266e564dSmrg status = IceClosedASAP; 207266e564dSmrg } 208266e564dSmrg 209266e564dSmrg if (iceConn->io_ok && iceConn->dispatch_level == 0 && 210266e564dSmrg !iceConn->skip_want_to_close && refCountReachedZero) 211266e564dSmrg { 212266e564dSmrg /* 213266e564dSmrg * Initiate shutdown negotiation. 214266e564dSmrg */ 215266e564dSmrg 216266e564dSmrg IceSimpleMessage (iceConn, 0, ICE_WantToClose); 217266e564dSmrg IceFlush (iceConn); 218266e564dSmrg 219266e564dSmrg iceConn->want_to_close = 1; 220266e564dSmrg 221266e564dSmrg status = IceStartedShutdownNegotiation; 222266e564dSmrg } 223266e564dSmrg else if (iceConn->dispatch_level == 0 && 224266e564dSmrg (!iceConn->io_ok || (iceConn->io_ok && iceConn->skip_want_to_close && 225266e564dSmrg (iceConn->free_asap || (!iceConn->free_asap && refCountReachedZero))))) 226266e564dSmrg { 227266e564dSmrg /* 228266e564dSmrg * Free the connection. 229266e564dSmrg */ 230266e564dSmrg 231266e564dSmrg _IceFreeConnection (iceConn); 232266e564dSmrg 233266e564dSmrg status = IceClosedNow; 234266e564dSmrg } 235266e564dSmrg 236266e564dSmrg return (status); 237266e564dSmrg} 238266e564dSmrg 239266e564dSmrg 240a3129944Smrg 241266e564dSmrgvoid 242c5629e66Smrg_IceFreeConnection ( 243c5629e66Smrg IceConn iceConn 244c5629e66Smrg) 245266e564dSmrg{ 246266e564dSmrg if (iceConn->listen_obj == NULL) 247266e564dSmrg { 248266e564dSmrg /* 249266e564dSmrg * This iceConn was created with IceOpenConnection. 250266e564dSmrg * We keep track of all open IceConn's, so we need 251266e564dSmrg * to remove it from the list. 252266e564dSmrg */ 253266e564dSmrg 254266e564dSmrg int i; 255266e564dSmrg 256266e564dSmrg for (i = 0; i < _IceConnectionCount; i++) 257266e564dSmrg if (_IceConnectionObjs[i] == iceConn) 258266e564dSmrg break; 259266e564dSmrg 260266e564dSmrg if (i < _IceConnectionCount) 261266e564dSmrg { 262266e564dSmrg if (i < _IceConnectionCount - 1) 263266e564dSmrg { 264266e564dSmrg _IceConnectionObjs[i] = 265266e564dSmrg _IceConnectionObjs[_IceConnectionCount - 1]; 266266e564dSmrg _IceConnectionStrings[i] = 267266e564dSmrg _IceConnectionStrings[_IceConnectionCount - 1]; 268266e564dSmrg } 269266e564dSmrg 270266e564dSmrg _IceConnectionCount--; 271266e564dSmrg } 272266e564dSmrg } 273266e564dSmrg 274266e564dSmrg if (iceConn->trans_conn) 275266e564dSmrg _IceTransClose (iceConn->trans_conn); 276266e564dSmrg 277a3129944Smrg free (iceConn->connection_string); 278a3129944Smrg free (iceConn->vendor); 279a3129944Smrg free (iceConn->release); 280a3129944Smrg free (iceConn->inbuf); 281a3129944Smrg free (iceConn->outbuf); 282a3129944Smrg free (iceConn->scratch); 283a3129944Smrg free (iceConn->process_msg_info); 284a3129944Smrg free (iceConn->connect_to_you); 285a3129944Smrg free (iceConn->protosetup_to_you); 286a3129944Smrg free (iceConn->connect_to_me); 287a3129944Smrg free (iceConn->protosetup_to_me); 288fb5e8d76Smrg free (iceConn); 289266e564dSmrg} 290266e564dSmrg 291266e564dSmrg 292266e564dSmrg 293266e564dSmrg 294