/*static char *SCCSID = "@(#)ntfywait.c	6.2 92/01/31";*/
#define _BTXT _BTXT
/*
 ***	Ntfywait.c - wait for directory to change
 *
 *	Copyright Microsoft, 1988.
 */

#define INCL_DOSERRORS
#include <os2def.h>
#include <bse.h>
#include "api.h"
#include "const.h"
#include "chain.h"
#include "misc.h"
#include "buf.h"
#include "dir.h"
#include "pbmacros.h"
#include "volume.h"
#include "storage.h"
#include "tables.h"
#include "lw.h"
#include "frame.h"
#include "fsdata.h"
#include "notify.h"
#include "pr_misc.h"

#ifdef DEBUG
#include "pr_debug.h"
#endif


/***	NotifyWait - wait for changes
 *
 *	This routine sets up the NOTIFY structure to indicate the number of
 *	changes that we need to wait for and then blocks on cusNeeded.  It will
 *	be awakened by NotifyScan or NotifyRmdir.  If psbd is 0, then it was
 *	awakened because the directory was removed.
 *
 *	Returns:    Error value, 0 if all ok
 *		    pnot->cusChanges cleared
 *		    *pcMatch set to number of changes
 *		    This routine may BLOCK.
 *
 *	HISTORY
 *	    19-Sep-89 by JR (John Rogers, JohnRo@Microsoft)
 *		- Avoid warnings from Microsoft C 5.2 (on slash-slash comments).
 */

int
NotifyWait(PNOTIFY pnot,	    /* ptr to NOTIFY struct to wait on */
	   PUSHORT pcMatch,	    /* ptr to number of changes to wait for */
				    /* also output value of changes seen */
	   ULONG timeout,	    /* number of millisec to wait */
	   PFRAME pfrm)
{
    register int ret = 0;

    if (pnot->bFlagsNtfy & NF_CLOSED)
	return ERROR_FINDNOTIFY_HANDLE_CLOSED;

    if (pnot->cusNeeded != -1) {    /* someone already waiting on this handle */
	return ERROR_FINDNOTIFY_HANDLE_IN_USE;
    }

    if (pnot->psbd != 0) {
	if (pnot->cusChanges < *pcMatch) {

	    pnot->bFlagsNtfy |= NF_ACTIVE;  /* mark active FindNotify* */
	    pnot->cusNeeded = *pcMatch;	    /* tell NotifyScan what we need */
					    /* then wait for it to happen */
	    MAYBLOCK (ret = ProcBlockTime (&pnot->cusNeeded, timeout))

	    if (ret == ERROR_SEM_TIMEOUT)
		ret = ERROR_FINDNOTIFY_TIMEOUT;
	    if (pnot->cusChanges < *pcMatch)
		*pcMatch = pnot->cusChanges;	/* didn't get requested num. */
						/* of changes, tell caller */
						/* how many we did get. */
	    pnot->bFlagsNtfy &= ~NF_ACTIVE; /* we are no longer active */

	    /* check for a pending close */
	    if (pnot->bFlagsNtfy & NF_CLOSED) {
		ProcRun (&pnot->cusNeeded);	/* wake up pending close */
		ret = ERROR_FINDNOTIFY_HANDLE_CLOSED;
	    }
	}
	pnot->cusChanges -= *pcMatch;	/* update change count for next time */
	pnot->cusNeeded = -1;		/* no one waiting now */
    }

    if (ret == 0 && pnot->psbd == 0)
	ret = ERROR_NOTIFY_OBJECT_REMOVED;  /* our directory was deleted! */

    return ret;
}
