Blame src/shutdown.c

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