/* cleanup.c */

/*		Copyright © 1989 by Donald T. Meyer, Stormgate Software
 *		All Rights Reserved
 */



#include "rxil.h"



/* NAME
 *		RxilCleanup
 *
 * SYNOPSIS
 *		RxilCleanup( rdef )
 *
 *		struct RxilDef *rdef;
 *
 * FUNCTION
 *		Cleanup the entire ARexx port.
 *		This will set the Abort flag, then wait till all ARexx program
 *		invocations which we have made are completed.
 *		At this time, all ARexx message ports will be closed.
 *		Any remaining RxilInvocation structures which were allocated
 *		via RxilCreateRxi() and not yet deleted via RxilDeleteRxi()
 *		will be cleaned up and freed.
 *		The ARexx library will be closed.
 *		Finally, the RexxDef structure itself will be freed.
 *
 * INPUTS
 *		rdef = pointer to the RxilDef structure returned by a call to
 *			RxilInit().
 *
 * RESULT
 *		None
 *
 * SIDES
 *
 * HISTORY
 *		01-Aug-89	Creation.
 *
 * BUGS
 *
 * SEE ALSO
 *		RxilInit(), RxilPending()
 */
 
void RxilCleanup( struct RxilDef *rdef )
{
	if( rdef == NULL )
	{
		return;
	}


	/* Deal with any commands or functions which we have launched that
	 * have not yet returned
	 */

	while( RxilPending() == TRUE )	/* till all replys are back */
	{
		/* Setting this flag will cause the routines which check the
		 * rexx port to refuse to accept further commands.
		 */
		rdef->Abort = TRUE;
 
		Wait( rdef->SigBit );
 
		RxilCheckPort();
	}


	/* Now that all invocation messages are back, we can do a default
	 * handling of each return.  The structures are then deleted.
	 *
	 * Since the variable 'invocations' contains a pointer to the
	 * first RxilInvocation structure on the list, we can use it
	 * directly to walk the list.  When we delete a structure, the
	 * deletion routine will put the next structure's address into
	 * 'invocations' (if there is a next structure).
	 */
 	while( rdef->Invocations )	/* scan list */
	{
		if( rdef->Invocations->State == RXIL_STATE_RETURNED )
		{
			RxilCleanupReturn( rdef->Invocations );
		}

		RxilDeleteRxi( rdef->Invocations );
	}
 
 
	/* Close and remove the ports */
 
	if( rdef->PublicPort )
	{
		RxilDeletePort( rdef->PublicPort );
		rdef->PublicPort = NULL;
	}
 
	if( rdef->SecretPort )
	{
		RxilDeletePort( rdef->SecretPort );
		rdef->SecretPort = NULL;
	}

	/* Close the library */
	if( RexxSysBase )
	{
		CloseLibrary( (struct Library *)RexxSysBase );
		RexxSysBase = NULL;
	}

	FreeMem( rdef, sizeof(struct RxilDef) );
}

