windows-nt/Source/XPSP1/NT/base/mvdm/wow16/ddeml/dmgq.c

211 lines
5.1 KiB
C
Raw Normal View History

2020-09-26 03:20:57 -05:00
/****************************** Module Header ******************************\
* Module Name: DMGQ.C
*
* DDE Manager queue control functions.
*
* Created: 9/1/89 Sanford Staab
* Modified:5/31/90 Rich Gartland, Aldus (Windows 3.0 port)
*
* This is a general queue manager - yes another one!
* Queues are each allocated within their own segment and have a
* QST structure associated with that heap. Each queue item
* is allocated within the heap segment. The offset of the items
* address combined with an instance count is used as the item ID.
* This is both unique and allows for instant location of an item.
* New items are added to the head of the queue which is a doubly linked
* list. The next links point to more recent entries, the prev pointers
* to older entries. The next of the head is the tail. The prev of the
* tail is the head. All pointers are far.
* Queue Data may be of any structure type that begins identical to
* a QUEUEITEM structure. Functions that require an cbItem perameter
* should be given the size of the specialized queue item structure.
*
* Copyright (c) 1988, 1989 Microsoft Corporation
\***************************************************************************/
#include "ddemlp.h"
/***************************** Private Function ****************************\
*
* Creates a Queue for items of cbItem.
* Returns NULL on error.
*
*
* History:
* Created 9/1/89 Sanfords
\***************************************************************************/
PQST CreateQ(cbItem)
WORD cbItem;
{
QST cq;
PQST pQ;
cq.cItems = 0;
cq.instLast = 0;
cq.cbItem = cbItem;
cq.pqiHead = NULL;
if (!(cq.hheap = DmgCreateHeap(sizeof(QST) + cbItem << 3)))
return(NULL);
if (!(pQ = (PQST)FarAllocMem(cq.hheap, sizeof(QST)))) {
DmgDestroyHeap(cq.hheap);
return(0);
}
*pQ = cq;
return(pQ);
}
/***************************** Private Function ****************************\
*
*
* History:
* Created 9/1/89 Sanfords
\***************************************************************************/
BOOL DestroyQ(pQ)
PQST pQ;
{
if (pQ)
DmgDestroyHeap(pQ->hheap);
return(TRUE);
}
/***************************** Private Function ****************************\
*
* returns a long pointer to the queue item data created. The new item
* is added to the head of the queue. The queue's cbItem specified at
* creation is used for allocation.
*
*
* History:
* Created 9/1/89 Sanfords
\***************************************************************************/
PQUEUEITEM Addqi(pQ)
PQST pQ;
{
PQUEUEITEM pqi;
if ((pqi = (PQUEUEITEM)FarAllocMem(pQ->hheap, pQ->cbItem)) == NULL) {
return(NULL);
}
SEMENTER();
if (pQ->cItems == 0) {
pQ->pqiHead = pqi->prev = pqi->next = pqi;
} else {
pqi->prev = pQ->pqiHead;
pqi->next = pQ->pqiHead->next;
pQ->pqiHead->next->prev = pqi;
pQ->pqiHead->next = pqi;
pQ->pqiHead = pqi;
}
SEMLEAVE();
pQ->cItems++;
pqi->inst = ++pQ->instLast;
return(pqi);
}
/***************************** Private Function ****************************\
*
* The id given is an external LONG id, not an item instance number.
* If id is QID_NEWEST, the head item is deleted.
* If id is QID_OLDEST, the tail item is deleted.
*
*
* History:
* Created 9/1/89 Sanfords
\***************************************************************************/
void Deleteqi(pQ, id)
PQST pQ;
DWORD id;
{
PQUEUEITEM pqi;
SEMENTER();
pqi = Findqi(pQ, id);
if (pqi == NULL) {
SEMLEAVE();
return;
}
pqi->prev->next = pqi->next;
pqi->next->prev = pqi->prev;
if (pqi == pQ->pqiHead)
pQ->pqiHead = pqi->prev;
if (!(--pQ->cItems))
pQ->pqiHead = NULL;
FarFreeMem((LPSTR)pqi);
SEMLEAVE();
}
/***************************** Private Function ****************************\
*
* The id given is an external LONG id, not an item instance number.
*
* if id == QID_NEWEST, returns the head queue data item.
* if id == QID_OLDEST == 0L, returns the tail queue data item.
* if the id is not found or the queue is empty, NULL is returned.
* if found, pqi is returned.
*
*
* History:
* Created 9/1/89 Sanfords
\***************************************************************************/
PQUEUEITEM Findqi(pQ, id)
PQST pQ;
DWORD id;
{
PQUEUEITEM pqi;
SEMCHECKIN();
if (pQ == NULL || pQ->pqiHead == NULL)
return(NULL);
if (id == QID_OLDEST)
return(pQ->pqiHead->next);
if (id == QID_NEWEST)
return(pQ->pqiHead);
if (id) {
pqi = PFROMID(pQ, id);
if (pqi->inst == HIWORD(id)) {
return(pqi);
}
return(NULL);
}
}
/*
* useful for traversing queues and deleting particular stuff in them.
*/
PQUEUEITEM FindNextQi(
PQST pQ,
PQUEUEITEM pqi,
BOOL fDelete)
{
PQUEUEITEM pqiNext;
if (pqi == NULL) {
return(pQ->cItems ? pQ->pqiHead : NULL);
}
pqiNext = pqi->next;
if (fDelete) {
Deleteqi(pQ, MAKEID(pqi));
}
return(pqiNext != pQ->pqiHead && pQ->cItems ? pqiNext : NULL);
}