/*static char *SCCSID = "@(#)ntfyclos.c	6.2 92/01/31";*/
#define _BTXT _BTXT
/*
 **	NtfyClos.C - Close a directory monitor handle
 *
 *	Copyright Microsoft, 1988.
 *
 *	HISTORY
 *	    19-Sep-89 by JR (John Rogers, JohnRo@Microsoft)
 *		- Avoid warnings from Microsoft C 5.2 (on slash-slash comments).
 */

#define INCL_DOSERRORS
#include <os2def.h>
#include <bse.h>

#include "heap.h"
#include "api.h"
#include "const.h"
#include "chain.h"
#include "misc.h"
#include "buf.h"
#include "dir.h"
#include "volume.h"
#include "storage.h"
#include "tables.h"
#include "frame.h"
#include "notify.h"
#include "pbmacros.h"
#include "lw.h"
#include "fsdata.h"
#include "pr_heap.h"
#include "pr_misc.h"
#include "pr_debug.h"


/*
 ***	NotifyClose - Close a directory monitor handle
 *
 *	This routine is called by FS_FindNotifyFirst or FS_FindNotifyClose
 *	to decommission the NOTIFY structure.  We remove the NOTIFY struct
 *	from the notify list of the relevant SUBDIR structure.  We also free
 *	the heap space allocated to store the filename pattern.
 *
 *	Returns:	no return value
 *			pnot removed from notify list
 *			ppsPattern freed
 */

void
NotifyClose(PNOTIFY pnot, PFRAME pfrm)	     /* ptr to NOTIFY struct */
{
    PNOTIFY pnotNext;		/* ptr to next NOTIFY struct in list */
    PSUBDIR psbd;		/* ptr to SUBDIR structure */

    if (pnot->bFlagsNtfy & NF_CLOSED)	/* another thread already closing */
	return;

    /* so others won't start FindNotify operations */
    pnot->bFlagsNtfy |= NF_CLOSED;

    if ((psbd = pnot->psbd) != 0) {
	/*
	 * first we have to check to see if another thread is waiting or active
	 */
	if (pnot->bFlagsNtfy & NF_ACTIVE) {
	    if (pnot->cusNeeded != -1)
		ProcRun (&pnot->cusNeeded);   /* wake up waiting thread */

	    /* we have to wait for active thread to clear */
	    MAYBLOCK (ProcBlockTime (&pnot->cusNeeded, TO_FOREVER));
	}

	if ((pnotNext = pnot->dcpNext) == pnot) {
	    /*
	     * only one item in the ring, so we are the last one and must turn
	     * out the lights.
	     */
	    psbd->dcpNotifyChain.pFwd = NULL;	    /* the list is now empty */
	    psbd->dcpNotifyChain.pBak = NULL;	    /* the list is now empty */

	} else {
	    /*
	     * remove this one from the list and update the list head\tail if
	     * necessary.
	     */
	    pnotNext->dcpPrev = pnot->dcpPrev;
	    pnot->dcpPrev->dcpNext = pnotNext;
	    if ((PNOTIFY)psbd->dcpNotifyChain.pFwd == pnot)
		psbd->dcpNotifyChain.pFwd = pnot->dcpNext;
	    if ((PNOTIFY)psbd->dcpNotifyChain.pBak == pnot)
		psbd->dcpNotifyChain.pBak = pnot->dcpPrev;
	}
    }

    if (pnot->ppsPattern)
	RetHeap(pnot->ppsPattern);	    /* free the pattern string memory */
}
