diff options
author | Kaleb Keithley <kaleb@freedesktop.org> | 2003-11-14 15:54:36 +0000 |
---|---|---|
committer | Kaleb Keithley <kaleb@freedesktop.org> | 2003-11-14 15:54:36 +0000 |
commit | ee452992357329f7af846eba8f5bbe61c5d27bfa (patch) | |
tree | 6566d7217c47e446e454f5ab461d9b15f8e4c480 /src/shutdown.c |
R6.6 is the Xorg base-lineXORG-MAINXORG-STABLE
Diffstat (limited to 'src/shutdown.c')
-rw-r--r-- | src/shutdown.c | 325 |
1 files changed, 325 insertions, 0 deletions
diff --git a/src/shutdown.c b/src/shutdown.c new file mode 100644 index 0000000..94a7eb9 --- /dev/null +++ b/src/shutdown.c @@ -0,0 +1,325 @@ +/* $Xorg: shutdown.c,v 1.4 2001/02/09 02:03:26 xorgcvs Exp $ */ +/****************************************************************************** + + +Copyright 1993, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + +Author: Ralph Mor, X Consortium +******************************************************************************/ + +#include <X11/ICE/ICElib.h> +#include "ICElibint.h" + + +Status +IceProtocolShutdown (iceConn, majorOpcode) + +IceConn iceConn; +int majorOpcode; + +{ + if (iceConn->proto_ref_count == 0 || iceConn->process_msg_info == NULL || + majorOpcode < 1 || majorOpcode > _IceLastMajorOpcode) + { + return (0); + } + else + { + /* + * Make sure this majorOpcode is really being used. + */ + + int i; + + for (i = iceConn->his_min_opcode; i <= iceConn->his_max_opcode; i++) + { + if (iceConn->process_msg_info[ + i - iceConn->his_min_opcode].in_use && + iceConn->process_msg_info[ + i - iceConn->his_min_opcode].my_opcode == majorOpcode) + break; + } + + if (i > iceConn->his_max_opcode) + { + return (0); + } + else + { + /* + * OK, we can shut down the protocol. + */ + + iceConn->process_msg_info[ + i - iceConn->his_min_opcode].in_use = False; + iceConn->proto_ref_count--; + + return (1); + } + } +} + + + +void +IceSetShutdownNegotiation (iceConn, negotiate) + +IceConn iceConn; +Bool negotiate; + +{ + iceConn->skip_want_to_close = negotiate ? False : True; +} + + + +Bool +IceCheckShutdownNegotiation (iceConn) + +IceConn iceConn; + +{ + return (iceConn->skip_want_to_close ? False : True); +} + + + +IceCloseStatus +IceCloseConnection (iceConn) + +IceConn iceConn; + +{ + int refCountReachedZero; + IceCloseStatus status; + + /* + * If this connection object was never valid, we can close + * it right now. This happens if IceAcceptConnection was + * called, but after calling IceProcessMessages several times + * the connection was rejected (because of authentication or + * some other reason). + */ + + if (iceConn->listen_obj && + iceConn->connection_status != IceConnectAccepted) + { + _IceConnectionClosed (iceConn); /* invoke watch procs */ + _IceFreeConnection (iceConn); + return (IceClosedNow); + } + + + /*--------------------------------------------------------------- + + ACTIONS: + + A = Invoke Watch Procedures + B = Set free-asap bit + C = Free connection + D = Initialize shutdown negotiation + N = do nothing + + + ACTION TABLE: + + IO free- dispatch protocol shutdown + error asap bit level refcount negotiation ACTION + occured set reached 0 reached 0 + + 0 0 0 0 0 N + 0 0 0 0 1 N + 0 0 0 1 0 AB + 0 0 0 1 1 N + 0 0 1 0 0 N + 0 0 1 0 1 N + 0 0 1 1 0 AC + 0 0 1 1 1 D + 0 1 0 0 0 N + 0 1 0 0 1 N + 0 1 0 1 0 N + 0 1 0 1 1 N + 0 1 1 0 0 C + 0 1 1 0 1 D + 0 1 1 1 0 C + 0 1 1 1 1 D + 1 0 0 0 0 AB + 1 0 0 0 1 AB + 1 0 0 1 0 AB + 1 0 0 1 1 AB + 1 0 1 0 0 AC + 1 0 1 0 1 AC + 1 0 1 1 0 AC + 1 0 1 1 1 AC + 1 1 0 0 0 N + 1 1 0 0 1 N + 1 1 0 1 0 N + 1 1 0 1 1 N + 1 1 1 0 0 C + 1 1 1 0 1 C + 1 1 1 1 0 C + 1 1 1 1 1 C + + ---------------------------------------------------------------*/ + + if (iceConn->open_ref_count > 0) + iceConn->open_ref_count--; + + refCountReachedZero = iceConn->open_ref_count == 0 && + iceConn->proto_ref_count == 0; + + status = IceConnectionInUse; + + if (!iceConn->free_asap && (!iceConn->io_ok || + (iceConn->io_ok && refCountReachedZero && + iceConn->skip_want_to_close))) + { + /* + * Invoke the watch procedures now. + */ + + _IceConnectionClosed (iceConn); + status = IceClosedNow; /* may be overwritten by IceClosedASAP */ + } + + if (!iceConn->free_asap && iceConn->dispatch_level != 0 && + (!iceConn->io_ok || + (iceConn->io_ok && refCountReachedZero && + iceConn->skip_want_to_close))) + { + /* + * Set flag so we free the connection as soon as possible. + */ + + iceConn->free_asap = True; + status = IceClosedASAP; + } + + if (iceConn->io_ok && iceConn->dispatch_level == 0 && + !iceConn->skip_want_to_close && refCountReachedZero) + { + /* + * Initiate shutdown negotiation. + */ + + IceSimpleMessage (iceConn, 0, ICE_WantToClose); + IceFlush (iceConn); + + iceConn->want_to_close = 1; + + status = IceStartedShutdownNegotiation; + } + else if (iceConn->dispatch_level == 0 && + (!iceConn->io_ok || (iceConn->io_ok && iceConn->skip_want_to_close && + (iceConn->free_asap || (!iceConn->free_asap && refCountReachedZero))))) + { + /* + * Free the connection. + */ + + _IceFreeConnection (iceConn); + + status = IceClosedNow; + } + + return (status); +} + + + +void +_IceFreeConnection (iceConn) + +IceConn iceConn; + +{ + if (iceConn->listen_obj == NULL) + { + /* + * This iceConn was created with IceOpenConnection. + * We keep track of all open IceConn's, so we need + * to remove it from the list. + */ + + int i; + + for (i = 0; i < _IceConnectionCount; i++) + if (_IceConnectionObjs[i] == iceConn) + break; + + if (i < _IceConnectionCount) + { + if (i < _IceConnectionCount - 1) + { + _IceConnectionObjs[i] = + _IceConnectionObjs[_IceConnectionCount - 1]; + _IceConnectionStrings[i] = + _IceConnectionStrings[_IceConnectionCount - 1]; + } + + _IceConnectionCount--; + } + } + + if (iceConn->trans_conn) + _IceTransClose (iceConn->trans_conn); + + if (iceConn->connection_string) + free (iceConn->connection_string); + + if (iceConn->vendor) + free (iceConn->vendor); + + if (iceConn->release) + free (iceConn->release); + + if (iceConn->inbuf) + free (iceConn->inbuf); + + if (iceConn->outbuf) + free (iceConn->outbuf); + + if (iceConn->scratch) + free (iceConn->scratch); + + if (iceConn->process_msg_info) + free ((char *) iceConn->process_msg_info); + + if (iceConn->connect_to_you) + free ((char *) iceConn->connect_to_you); + + if (iceConn->protosetup_to_you) + free ((char *) iceConn->protosetup_to_you); + + if (iceConn->connect_to_me) + free ((char *) iceConn->connect_to_me); + + if (iceConn->protosetup_to_me) + free ((char *) iceConn->protosetup_to_me); + + free ((char *) iceConn); +} + + + + |