* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-/* $Id: handle.c,v 1.58 2004/08/15 16:39:09 chorns Exp $
+/* $Id: handle.c,v 1.59 2004/08/20 23:46:21 navaraf Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
ACCESS_MASK GrantedAccess;
} HANDLE_REP, *PHANDLE_REP;
-#define HANDLE_BLOCK_ENTRIES ((PAGE_SIZE-sizeof(LIST_ENTRY))/sizeof(HANDLE_REP))
+#define HANDLE_BLOCK_ENTRIES \
+ (((4 * PAGE_SIZE) - \
+ (sizeof(LIST_ENTRY) + sizeof(ULONG))) / sizeof(HANDLE_REP))
#define OB_HANDLE_FLAG_MASK 0x00000007
#define OB_HANDLE_FLAG_AUDIT 0x00000004
(PVOID)((ULONG_PTR)(Entry) & ~OB_HANDLE_FLAG_MASK)
/*
- * PURPOSE: Defines a page's worth of handles
+ * PURPOSE: Defines a 4 page's worth of handles
*/
typedef struct
{
LIST_ENTRY entry;
+ ULONG allocation_hint;
+ ULONG allocation_count;
HANDLE_REP handles[HANDLE_BLOCK_ENTRIES];
} HANDLE_BLOCK, *PHANDLE_BLOCK;
/* FUNCTIONS ***************************************************************/
-static PHANDLE_REP ObpGetObjectByHandle(PHANDLE_TABLE HandleTable, HANDLE h)
+static PHANDLE_REP
+ObpGetObjectByHandle(PHANDLE_TABLE HandleTable, HANDLE h, HANDLE_BLOCK **Block)
/*
* FUNCTION: Get the data structure for a handle
* ARGUMENTS:
}
blk = CONTAINING_RECORD(current,HANDLE_BLOCK,entry);
+ if (Block)
+ *Block = blk;
DPRINT("object: %p\n",&(blk->handles[handle%HANDLE_BLOCK_ENTRIES]));
return(&(blk->handles[handle%HANDLE_BLOCK_ENTRIES]));
}
KeAcquireSpinLock(&Process->HandleTable.ListLock, &oldIrql);
HandleRep = ObpGetObjectByHandle(&Process->HandleTable,
- Handle);
+ Handle,
+ NULL);
if (HandleRep == NULL)
{
KeReleaseSpinLock(&Process->HandleTable.ListLock, oldIrql);
KeAcquireSpinLock(&Process->HandleTable.ListLock, &oldIrql);
HandleRep = ObpGetObjectByHandle(&Process->HandleTable,
- Handle);
+ Handle,
+ NULL);
if (HandleRep == NULL)
{
KeReleaseSpinLock(&Process->HandleTable.ListLock, oldIrql);
KeAcquireSpinLock(&SourceProcess->HandleTable.ListLock, &oldIrql);
SourceHandleRep = ObpGetObjectByHandle(&SourceProcess->HandleTable,
- SourceHandle);
+ SourceHandle,
+ NULL);
if (SourceHandleRep == NULL)
{
KeReleaseSpinLock(&SourceProcess->HandleTable.ListLock, oldIrql);
{
KeAcquireSpinLock(&SourceProcess->HandleTable.ListLock, &oldIrql);
SourceHandleRep = ObpGetObjectByHandle(&SourceProcess->HandleTable,
- SourceHandle);
+ SourceHandle,
+ NULL);
if (SourceHandleRep == NULL)
{
KeReleaseSpinLock(&SourceProcess->HandleTable.ListLock, oldIrql);
KIRQL oldIrql;
PHANDLE_TABLE HandleTable;
POBJECT_HEADER Header;
+ HANDLE_BLOCK *Block;
DPRINT("ObDeleteHandle(Handle %x)\n",Handle);
KeAcquireSpinLock(&HandleTable->ListLock, &oldIrql);
- Rep = ObpGetObjectByHandle(HandleTable, Handle);
+ Rep = ObpGetObjectByHandle(HandleTable, Handle, &Block);
if (Rep == NULL)
{
KeReleaseSpinLock(&HandleTable->ListLock, oldIrql);
InterlockedDecrement(&Header->HandleCount);
Rep->ObjectBody = NULL;
+ Block->allocation_count--;
+ Block->allocation_hint = (ULONG_PTR)Handle % HANDLE_BLOCK_ENTRIES;
+
KeReleaseSpinLock(&HandleTable->ListLock, oldIrql);
if ((Header->ObjectType != NULL) &&
{
LIST_ENTRY* current;
unsigned int handle=1;
- unsigned int i;
+ unsigned int Loop, Index, MaxIndex;
HANDLE_BLOCK* new_blk = NULL;
PHANDLE_TABLE HandleTable;
KIRQL oldlvl;
DPRINT("Current %x\n",current);
- for (i=0;i<HANDLE_BLOCK_ENTRIES;i++)
+ if (blk->allocation_count == HANDLE_BLOCK_ENTRIES)
{
- DPRINT("Considering slot %d containing %x\n",i,blk->handles[i]);
- if (blk->handles[i].ObjectBody == NULL)
- {
- blk->handles[i].ObjectBody = OB_POINTER_TO_ENTRY(ObjectBody);
- if (Inherit)
- blk->handles[i].ObjectBody = (PVOID)((ULONG_PTR)blk->handles[i].ObjectBody | OB_HANDLE_FLAG_INHERIT);
- blk->handles[i].GrantedAccess = GrantedAccess;
- KeReleaseSpinLock(&HandleTable->ListLock, oldlvl);
- *HandleReturn = (HANDLE)((handle + i) << 2);
- return(STATUS_SUCCESS);
- }
+ handle = handle + HANDLE_BLOCK_ENTRIES;
+ current = current->Flink;
+ continue;
+ }
+
+ Index = blk->allocation_hint;
+ MaxIndex = HANDLE_BLOCK_ENTRIES;
+ for (Loop = 0; Loop < 2; Loop++)
+ {
+ for (Index = 0; Index < MaxIndex; Index++)
+ {
+ DPRINT("Considering slot %d containing %x\n", Index, blk->handles[Index]);
+ if (blk->handles[Index].ObjectBody == NULL)
+ {
+ blk->handles[Index].ObjectBody = OB_POINTER_TO_ENTRY(ObjectBody);
+ if (Inherit)
+ blk->handles[Index].ObjectBody = (PVOID)((ULONG_PTR)blk->handles[Index].ObjectBody | OB_HANDLE_FLAG_INHERIT);
+ blk->handles[Index].GrantedAccess = GrantedAccess;
+ blk->allocation_hint = Index + 1;
+ blk->allocation_count++;
+ KeReleaseSpinLock(&HandleTable->ListLock, oldlvl);
+ *HandleReturn = (HANDLE)((handle + Index) << 2);
+ return(STATUS_SUCCESS);
+ }
+ }
+ Index = 0;
+ MaxIndex = blk->allocation_hint;
}
handle = handle + HANDLE_BLOCK_ENTRIES;
if (Inherit)
new_blk->handles[0].ObjectBody = (PVOID)((ULONG_PTR)new_blk->handles[0].ObjectBody | OB_HANDLE_FLAG_INHERIT);
new_blk->handles[0].GrantedAccess = GrantedAccess;
+ new_blk->allocation_hint = 1;
+ new_blk->allocation_count++;
KeReleaseSpinLock(&HandleTable->ListLock, oldlvl);
*HandleReturn = (HANDLE)(handle << 2);
return(STATUS_SUCCESS);
KeAcquireSpinLock(&Process->HandleTable.ListLock, &oldIrql);
HandleRep = ObpGetObjectByHandle(&Process->HandleTable,
- Handle);
+ Handle,
+ NULL);
if (HandleRep == NULL)
{
KeReleaseSpinLock(&Process->HandleTable.ListLock, oldIrql);
KeAcquireSpinLock(&PsGetCurrentProcess()->HandleTable.ListLock,
&oldIrql);
HandleRep = ObpGetObjectByHandle(&PsGetCurrentProcess()->HandleTable,
- Handle);
+ Handle,
+ NULL);
if (HandleRep == NULL || HandleRep->ObjectBody == 0)
{
KeReleaseSpinLock(&PsGetCurrentProcess()->HandleTable.ListLock,