4d0b8f024a4654c1f61c8c4b7e16320719f7fea4vboxsync/* $Id$ */
4d0b8f024a4654c1f61c8c4b7e16320719f7fea4vboxsync/** @file
4d0b8f024a4654c1f61c8c4b7e16320719f7fea4vboxsync * IPRT - Handle Tables.
4d0b8f024a4654c1f61c8c4b7e16320719f7fea4vboxsync */
4d0b8f024a4654c1f61c8c4b7e16320719f7fea4vboxsync
4d0b8f024a4654c1f61c8c4b7e16320719f7fea4vboxsync/*
506922036e4604028e862309a96bb403eee83a48vboxsync * Copyright (C) 2008-2013 Oracle Corporation
4d0b8f024a4654c1f61c8c4b7e16320719f7fea4vboxsync *
4d0b8f024a4654c1f61c8c4b7e16320719f7fea4vboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
4d0b8f024a4654c1f61c8c4b7e16320719f7fea4vboxsync * available from http://www.virtualbox.org. This file is free software;
4d0b8f024a4654c1f61c8c4b7e16320719f7fea4vboxsync * you can redistribute it and/or modify it under the terms of the GNU
4d0b8f024a4654c1f61c8c4b7e16320719f7fea4vboxsync * General Public License (GPL) as published by the Free Software
4d0b8f024a4654c1f61c8c4b7e16320719f7fea4vboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
4d0b8f024a4654c1f61c8c4b7e16320719f7fea4vboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
4d0b8f024a4654c1f61c8c4b7e16320719f7fea4vboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
4d0b8f024a4654c1f61c8c4b7e16320719f7fea4vboxsync *
4d0b8f024a4654c1f61c8c4b7e16320719f7fea4vboxsync * The contents of this file may alternatively be used under the terms
4d0b8f024a4654c1f61c8c4b7e16320719f7fea4vboxsync * of the Common Development and Distribution License Version 1.0
4d0b8f024a4654c1f61c8c4b7e16320719f7fea4vboxsync * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
4d0b8f024a4654c1f61c8c4b7e16320719f7fea4vboxsync * VirtualBox OSE distribution, in which case the provisions of the
4d0b8f024a4654c1f61c8c4b7e16320719f7fea4vboxsync * CDDL are applicable instead of those of the GPL.
4d0b8f024a4654c1f61c8c4b7e16320719f7fea4vboxsync *
4d0b8f024a4654c1f61c8c4b7e16320719f7fea4vboxsync * You may elect to license modified versions of this file under the
4d0b8f024a4654c1f61c8c4b7e16320719f7fea4vboxsync * terms and conditions of either the GPL or the CDDL or both.
4d0b8f024a4654c1f61c8c4b7e16320719f7fea4vboxsync */
4d0b8f024a4654c1f61c8c4b7e16320719f7fea4vboxsync
aa4bcf0a4b2db3ac352b56a291d49cb8d4b66d32vboxsync
4d0b8f024a4654c1f61c8c4b7e16320719f7fea4vboxsync/*******************************************************************************
4d0b8f024a4654c1f61c8c4b7e16320719f7fea4vboxsync* Header Files *
4d0b8f024a4654c1f61c8c4b7e16320719f7fea4vboxsync*******************************************************************************/
4d0b8f024a4654c1f61c8c4b7e16320719f7fea4vboxsync#include <iprt/handletable.h>
aa4bcf0a4b2db3ac352b56a291d49cb8d4b66d32vboxsync#include "internal/iprt.h"
aa4bcf0a4b2db3ac352b56a291d49cb8d4b66d32vboxsync
4d0b8f024a4654c1f61c8c4b7e16320719f7fea4vboxsync#include <iprt/mem.h>
4d0b8f024a4654c1f61c8c4b7e16320719f7fea4vboxsync#include <iprt/spinlock.h>
4d0b8f024a4654c1f61c8c4b7e16320719f7fea4vboxsync#include <iprt/err.h>
4d0b8f024a4654c1f61c8c4b7e16320719f7fea4vboxsync#include <iprt/assert.h>
4d0b8f024a4654c1f61c8c4b7e16320719f7fea4vboxsync#include <iprt/param.h>
4d0b8f024a4654c1f61c8c4b7e16320719f7fea4vboxsync#include <iprt/string.h>
09034c53c75eab7ea04021a749b98e7f78fae85avboxsync#include <iprt/asm.h>
4d0b8f024a4654c1f61c8c4b7e16320719f7fea4vboxsync#include "internal/magics.h"
cc66247640b520463f925a5533fc9e5de06aa982vboxsync#include "handletable.h"
4d0b8f024a4654c1f61c8c4b7e16320719f7fea4vboxsync
4d0b8f024a4654c1f61c8c4b7e16320719f7fea4vboxsync
4d0b8f024a4654c1f61c8c4b7e16320719f7fea4vboxsync
09034c53c75eab7ea04021a749b98e7f78fae85avboxsyncRTDECL(int) RTHandleTableCreateEx(PRTHANDLETABLE phHandleTable, uint32_t fFlags, uint32_t uBase, uint32_t cMax,
09034c53c75eab7ea04021a749b98e7f78fae85avboxsync PFNRTHANDLETABLERETAIN pfnRetain, void *pvUser)
4d0b8f024a4654c1f61c8c4b7e16320719f7fea4vboxsync{
c9968c45b31bd2bf5bb6feb365f86ffba15241d7vboxsync PRTHANDLETABLEINT pThis;
c9968c45b31bd2bf5bb6feb365f86ffba15241d7vboxsync uint32_t cLevel1;
c9968c45b31bd2bf5bb6feb365f86ffba15241d7vboxsync size_t cb;
c9968c45b31bd2bf5bb6feb365f86ffba15241d7vboxsync
09034c53c75eab7ea04021a749b98e7f78fae85avboxsync /*
09034c53c75eab7ea04021a749b98e7f78fae85avboxsync * Validate input.
09034c53c75eab7ea04021a749b98e7f78fae85avboxsync */
09034c53c75eab7ea04021a749b98e7f78fae85avboxsync AssertPtrReturn(phHandleTable, VERR_INVALID_POINTER);
09034c53c75eab7ea04021a749b98e7f78fae85avboxsync *phHandleTable = NIL_RTHANDLETABLE;
09034c53c75eab7ea04021a749b98e7f78fae85avboxsync AssertPtrNullReturn(pfnRetain, VERR_INVALID_POINTER);
09034c53c75eab7ea04021a749b98e7f78fae85avboxsync AssertReturn(!(fFlags & ~RTHANDLETABLE_FLAGS_MASK), VERR_INVALID_PARAMETER);
506922036e4604028e862309a96bb403eee83a48vboxsync AssertReturn(RT_BOOL(fFlags & RTHANDLETABLE_FLAGS_LOCKED) + RT_BOOL(fFlags & RTHANDLETABLE_FLAGS_LOCKED_IRQ_SAFE) < 2,
506922036e4604028e862309a96bb403eee83a48vboxsync VERR_INVALID_PARAMETER);
09034c53c75eab7ea04021a749b98e7f78fae85avboxsync AssertReturn(cMax > 0, VERR_INVALID_PARAMETER);
09034c53c75eab7ea04021a749b98e7f78fae85avboxsync AssertReturn(UINT32_MAX - cMax >= uBase, VERR_INVALID_PARAMETER);
09034c53c75eab7ea04021a749b98e7f78fae85avboxsync
09034c53c75eab7ea04021a749b98e7f78fae85avboxsync /*
09034c53c75eab7ea04021a749b98e7f78fae85avboxsync * Adjust the cMax value so it is a multiple of the 2nd level tables.
09034c53c75eab7ea04021a749b98e7f78fae85avboxsync */
09034c53c75eab7ea04021a749b98e7f78fae85avboxsync if (cMax >= UINT32_MAX - RTHT_LEVEL2_ENTRIES)
09034c53c75eab7ea04021a749b98e7f78fae85avboxsync cMax = UINT32_MAX - RTHT_LEVEL2_ENTRIES + 1;
09034c53c75eab7ea04021a749b98e7f78fae85avboxsync cMax = ((cMax + RTHT_LEVEL2_ENTRIES - 1) / RTHT_LEVEL2_ENTRIES) * RTHT_LEVEL2_ENTRIES;
09034c53c75eab7ea04021a749b98e7f78fae85avboxsync
c9968c45b31bd2bf5bb6feb365f86ffba15241d7vboxsync cLevel1 = cMax / RTHT_LEVEL2_ENTRIES;
09034c53c75eab7ea04021a749b98e7f78fae85avboxsync Assert(cLevel1 * RTHT_LEVEL2_ENTRIES == cMax);
09034c53c75eab7ea04021a749b98e7f78fae85avboxsync
09034c53c75eab7ea04021a749b98e7f78fae85avboxsync /*
09034c53c75eab7ea04021a749b98e7f78fae85avboxsync * Allocate the structure, include the 1st level lookup table
09034c53c75eab7ea04021a749b98e7f78fae85avboxsync * if it's below the threshold size.
09034c53c75eab7ea04021a749b98e7f78fae85avboxsync */
c9968c45b31bd2bf5bb6feb365f86ffba15241d7vboxsync cb = sizeof(RTHANDLETABLEINT);
09034c53c75eab7ea04021a749b98e7f78fae85avboxsync if (cLevel1 < RTHT_LEVEL1_DYN_ALLOC_THRESHOLD)
09034c53c75eab7ea04021a749b98e7f78fae85avboxsync cb = RT_ALIGN(cb, sizeof(void *)) + cLevel1 * sizeof(void *);
c9968c45b31bd2bf5bb6feb365f86ffba15241d7vboxsync pThis = (PRTHANDLETABLEINT)RTMemAllocZ(cb);
09034c53c75eab7ea04021a749b98e7f78fae85avboxsync if (!pThis)
09034c53c75eab7ea04021a749b98e7f78fae85avboxsync return VERR_NO_MEMORY;
09034c53c75eab7ea04021a749b98e7f78fae85avboxsync
09034c53c75eab7ea04021a749b98e7f78fae85avboxsync /*
09034c53c75eab7ea04021a749b98e7f78fae85avboxsync * Initialize it.
09034c53c75eab7ea04021a749b98e7f78fae85avboxsync */
09034c53c75eab7ea04021a749b98e7f78fae85avboxsync pThis->u32Magic = RTHANDLETABLE_MAGIC;
09034c53c75eab7ea04021a749b98e7f78fae85avboxsync pThis->fFlags = fFlags;
09034c53c75eab7ea04021a749b98e7f78fae85avboxsync pThis->uBase = uBase;
09034c53c75eab7ea04021a749b98e7f78fae85avboxsync pThis->cCur = 0;
09034c53c75eab7ea04021a749b98e7f78fae85avboxsync pThis->hSpinlock = NIL_RTSPINLOCK;
09034c53c75eab7ea04021a749b98e7f78fae85avboxsync if (cLevel1 < RTHT_LEVEL1_DYN_ALLOC_THRESHOLD)
09034c53c75eab7ea04021a749b98e7f78fae85avboxsync pThis->papvLevel1 = (void **)((uint8_t *)pThis + RT_ALIGN(sizeof(*pThis), sizeof(void *)));
09034c53c75eab7ea04021a749b98e7f78fae85avboxsync else
210e87cc03f92d54681b81a81cc1fdbd48a9d2c8vboxsync pThis->papvLevel1 = NULL;
09034c53c75eab7ea04021a749b98e7f78fae85avboxsync pThis->pfnRetain = pfnRetain;
09034c53c75eab7ea04021a749b98e7f78fae85avboxsync pThis->pvRetainUser = pvUser;
09034c53c75eab7ea04021a749b98e7f78fae85avboxsync pThis->cMax = cMax;
09034c53c75eab7ea04021a749b98e7f78fae85avboxsync pThis->cCurAllocated = 0;
09034c53c75eab7ea04021a749b98e7f78fae85avboxsync pThis->cLevel1 = cLevel1 < RTHT_LEVEL1_DYN_ALLOC_THRESHOLD ? cLevel1 : 0;
09034c53c75eab7ea04021a749b98e7f78fae85avboxsync pThis->iFreeHead = NIL_RTHT_INDEX;
09034c53c75eab7ea04021a749b98e7f78fae85avboxsync pThis->iFreeTail = NIL_RTHT_INDEX;
506922036e4604028e862309a96bb403eee83a48vboxsync if (fFlags & (RTHANDLETABLE_FLAGS_LOCKED | RTHANDLETABLE_FLAGS_LOCKED_IRQ_SAFE))
09034c53c75eab7ea04021a749b98e7f78fae85avboxsync {
506922036e4604028e862309a96bb403eee83a48vboxsync int rc;
506922036e4604028e862309a96bb403eee83a48vboxsync if (fFlags & RTHANDLETABLE_FLAGS_LOCKED_IRQ_SAFE)
506922036e4604028e862309a96bb403eee83a48vboxsync rc = RTSpinlockCreate(&pThis->hSpinlock, RTSPINLOCK_FLAGS_INTERRUPT_SAFE, "RTHandleTableCreateEx");
506922036e4604028e862309a96bb403eee83a48vboxsync else
506922036e4604028e862309a96bb403eee83a48vboxsync rc = RTSpinlockCreate(&pThis->hSpinlock, RTSPINLOCK_FLAGS_INTERRUPT_UNSAFE, "RTHandleTableCreateEx");
09034c53c75eab7ea04021a749b98e7f78fae85avboxsync if (RT_FAILURE(rc))
09034c53c75eab7ea04021a749b98e7f78fae85avboxsync {
09034c53c75eab7ea04021a749b98e7f78fae85avboxsync RTMemFree(pThis);
09034c53c75eab7ea04021a749b98e7f78fae85avboxsync return rc;
09034c53c75eab7ea04021a749b98e7f78fae85avboxsync }
09034c53c75eab7ea04021a749b98e7f78fae85avboxsync }
09034c53c75eab7ea04021a749b98e7f78fae85avboxsync
09034c53c75eab7ea04021a749b98e7f78fae85avboxsync *phHandleTable = pThis;
09034c53c75eab7ea04021a749b98e7f78fae85avboxsync return VINF_SUCCESS;
4d0b8f024a4654c1f61c8c4b7e16320719f7fea4vboxsync}
aa4bcf0a4b2db3ac352b56a291d49cb8d4b66d32vboxsyncRT_EXPORT_SYMBOL(RTHandleTableCreateEx);
4d0b8f024a4654c1f61c8c4b7e16320719f7fea4vboxsync
4d0b8f024a4654c1f61c8c4b7e16320719f7fea4vboxsync
09034c53c75eab7ea04021a749b98e7f78fae85avboxsyncRTDECL(int) RTHandleTableCreate(PRTHANDLETABLE phHandleTable)
4d0b8f024a4654c1f61c8c4b7e16320719f7fea4vboxsync{
210e87cc03f92d54681b81a81cc1fdbd48a9d2c8vboxsync return RTHandleTableCreateEx(phHandleTable, RTHANDLETABLE_FLAGS_LOCKED, 1, 65534, NULL, NULL);
4d0b8f024a4654c1f61c8c4b7e16320719f7fea4vboxsync}
aa4bcf0a4b2db3ac352b56a291d49cb8d4b66d32vboxsyncRT_EXPORT_SYMBOL(RTHandleTableCreate);
4d0b8f024a4654c1f61c8c4b7e16320719f7fea4vboxsync
4d0b8f024a4654c1f61c8c4b7e16320719f7fea4vboxsync
09034c53c75eab7ea04021a749b98e7f78fae85avboxsyncRTDECL(int) RTHandleTableDestroy(RTHANDLETABLE hHandleTable, PFNRTHANDLETABLEDELETE pfnDelete, void *pvUser)
4d0b8f024a4654c1f61c8c4b7e16320719f7fea4vboxsync{
c9968c45b31bd2bf5bb6feb365f86ffba15241d7vboxsync PRTHANDLETABLEINT pThis;
c9968c45b31bd2bf5bb6feb365f86ffba15241d7vboxsync uint32_t i1;
c9968c45b31bd2bf5bb6feb365f86ffba15241d7vboxsync uint32_t i;
c9968c45b31bd2bf5bb6feb365f86ffba15241d7vboxsync
09034c53c75eab7ea04021a749b98e7f78fae85avboxsync /*
ad27e1d5e48ca41245120c331cc88b50464813cevboxsync * Validate input, quietly ignore the NIL handle.
09034c53c75eab7ea04021a749b98e7f78fae85avboxsync */
09034c53c75eab7ea04021a749b98e7f78fae85avboxsync if (hHandleTable == NIL_RTHANDLETABLE)
09034c53c75eab7ea04021a749b98e7f78fae85avboxsync return VINF_SUCCESS;
c9968c45b31bd2bf5bb6feb365f86ffba15241d7vboxsync pThis = (PRTHANDLETABLEINT)hHandleTable;
09034c53c75eab7ea04021a749b98e7f78fae85avboxsync AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
09034c53c75eab7ea04021a749b98e7f78fae85avboxsync AssertReturn(pThis->u32Magic == RTHANDLETABLE_MAGIC, VERR_INVALID_HANDLE);
09034c53c75eab7ea04021a749b98e7f78fae85avboxsync AssertPtrNullReturn(pfnDelete, VERR_INVALID_POINTER);
09034c53c75eab7ea04021a749b98e7f78fae85avboxsync
09034c53c75eab7ea04021a749b98e7f78fae85avboxsync /*
09034c53c75eab7ea04021a749b98e7f78fae85avboxsync * Mark the thing as invalid / deleted.
09034c53c75eab7ea04021a749b98e7f78fae85avboxsync * Then kill the lock.
09034c53c75eab7ea04021a749b98e7f78fae85avboxsync */
f0ed7ab5e7f8d2f73b5aa08e46eb3a04cbb31cb2vboxsync rtHandleTableLock(pThis);
09034c53c75eab7ea04021a749b98e7f78fae85avboxsync ASMAtomicWriteU32(&pThis->u32Magic, ~RTHANDLETABLE_MAGIC);
f0ed7ab5e7f8d2f73b5aa08e46eb3a04cbb31cb2vboxsync rtHandleTableUnlock(pThis);
09034c53c75eab7ea04021a749b98e7f78fae85avboxsync
09034c53c75eab7ea04021a749b98e7f78fae85avboxsync if (pThis->hSpinlock != NIL_RTSPINLOCK)
09034c53c75eab7ea04021a749b98e7f78fae85avboxsync {
f0ed7ab5e7f8d2f73b5aa08e46eb3a04cbb31cb2vboxsync rtHandleTableLock(pThis);
f0ed7ab5e7f8d2f73b5aa08e46eb3a04cbb31cb2vboxsync rtHandleTableUnlock(pThis);
09034c53c75eab7ea04021a749b98e7f78fae85avboxsync
09034c53c75eab7ea04021a749b98e7f78fae85avboxsync RTSpinlockDestroy(pThis->hSpinlock);
09034c53c75eab7ea04021a749b98e7f78fae85avboxsync pThis->hSpinlock = NIL_RTSPINLOCK;
09034c53c75eab7ea04021a749b98e7f78fae85avboxsync }
09034c53c75eab7ea04021a749b98e7f78fae85avboxsync
09034c53c75eab7ea04021a749b98e7f78fae85avboxsync if (pfnDelete)
09034c53c75eab7ea04021a749b98e7f78fae85avboxsync {
09034c53c75eab7ea04021a749b98e7f78fae85avboxsync /*
09034c53c75eab7ea04021a749b98e7f78fae85avboxsync * Walk all the tables looking for used handles.
09034c53c75eab7ea04021a749b98e7f78fae85avboxsync */
09034c53c75eab7ea04021a749b98e7f78fae85avboxsync uint32_t cLeft = pThis->cCurAllocated;
09034c53c75eab7ea04021a749b98e7f78fae85avboxsync if (pThis->fFlags & RTHANDLETABLE_FLAGS_CONTEXT)
09034c53c75eab7ea04021a749b98e7f78fae85avboxsync {
c9968c45b31bd2bf5bb6feb365f86ffba15241d7vboxsync for (i1 = 0; cLeft > 0 && i1 < pThis->cLevel1; i1++)
09034c53c75eab7ea04021a749b98e7f78fae85avboxsync {
09034c53c75eab7ea04021a749b98e7f78fae85avboxsync PRTHTENTRYCTX paTable = (PRTHTENTRYCTX)pThis->papvLevel1[i1];
09034c53c75eab7ea04021a749b98e7f78fae85avboxsync if (paTable)
c9968c45b31bd2bf5bb6feb365f86ffba15241d7vboxsync for (i = 0; i < RTHT_LEVEL2_ENTRIES; i++)
09034c53c75eab7ea04021a749b98e7f78fae85avboxsync if (!RTHT_IS_FREE(paTable[i].pvObj))
09034c53c75eab7ea04021a749b98e7f78fae85avboxsync {
09034c53c75eab7ea04021a749b98e7f78fae85avboxsync pfnDelete(hHandleTable, pThis->uBase + i + i1 * RTHT_LEVEL2_ENTRIES,
09034c53c75eab7ea04021a749b98e7f78fae85avboxsync paTable[i].pvObj, paTable[i].pvCtx, pvUser);
09034c53c75eab7ea04021a749b98e7f78fae85avboxsync Assert(cLeft > 0);
09034c53c75eab7ea04021a749b98e7f78fae85avboxsync cLeft--;
09034c53c75eab7ea04021a749b98e7f78fae85avboxsync }
09034c53c75eab7ea04021a749b98e7f78fae85avboxsync }
09034c53c75eab7ea04021a749b98e7f78fae85avboxsync }
09034c53c75eab7ea04021a749b98e7f78fae85avboxsync else
09034c53c75eab7ea04021a749b98e7f78fae85avboxsync {
c9968c45b31bd2bf5bb6feb365f86ffba15241d7vboxsync for (i1 = 0; cLeft > 0 && i1 < pThis->cLevel1; i1++)
09034c53c75eab7ea04021a749b98e7f78fae85avboxsync {
09034c53c75eab7ea04021a749b98e7f78fae85avboxsync PRTHTENTRY paTable = (PRTHTENTRY)pThis->papvLevel1[i1];
09034c53c75eab7ea04021a749b98e7f78fae85avboxsync if (paTable)
c9968c45b31bd2bf5bb6feb365f86ffba15241d7vboxsync for (i = 0; i < RTHT_LEVEL2_ENTRIES; i++)
09034c53c75eab7ea04021a749b98e7f78fae85avboxsync if (!RTHT_IS_FREE(paTable[i].pvObj))
09034c53c75eab7ea04021a749b98e7f78fae85avboxsync {
09034c53c75eab7ea04021a749b98e7f78fae85avboxsync pfnDelete(hHandleTable, pThis->uBase + i + i1 * RTHT_LEVEL2_ENTRIES,
09034c53c75eab7ea04021a749b98e7f78fae85avboxsync paTable[i].pvObj, NULL, pvUser);
09034c53c75eab7ea04021a749b98e7f78fae85avboxsync Assert(cLeft > 0);
09034c53c75eab7ea04021a749b98e7f78fae85avboxsync cLeft--;
09034c53c75eab7ea04021a749b98e7f78fae85avboxsync }
09034c53c75eab7ea04021a749b98e7f78fae85avboxsync }
09034c53c75eab7ea04021a749b98e7f78fae85avboxsync }
09034c53c75eab7ea04021a749b98e7f78fae85avboxsync Assert(!cLeft);
09034c53c75eab7ea04021a749b98e7f78fae85avboxsync }
09034c53c75eab7ea04021a749b98e7f78fae85avboxsync
09034c53c75eab7ea04021a749b98e7f78fae85avboxsync /*
09034c53c75eab7ea04021a749b98e7f78fae85avboxsync * Free the memory.
09034c53c75eab7ea04021a749b98e7f78fae85avboxsync */
c9968c45b31bd2bf5bb6feb365f86ffba15241d7vboxsync for (i1 = 0; i1 < pThis->cLevel1; i1++)
09034c53c75eab7ea04021a749b98e7f78fae85avboxsync if (pThis->papvLevel1[i1])
09034c53c75eab7ea04021a749b98e7f78fae85avboxsync {
09034c53c75eab7ea04021a749b98e7f78fae85avboxsync RTMemFree(pThis->papvLevel1[i1]);
09034c53c75eab7ea04021a749b98e7f78fae85avboxsync pThis->papvLevel1[i1] = NULL;
09034c53c75eab7ea04021a749b98e7f78fae85avboxsync }
09034c53c75eab7ea04021a749b98e7f78fae85avboxsync
09034c53c75eab7ea04021a749b98e7f78fae85avboxsync if (pThis->cMax / RTHT_LEVEL2_ENTRIES >= RTHT_LEVEL1_DYN_ALLOC_THRESHOLD)
09034c53c75eab7ea04021a749b98e7f78fae85avboxsync RTMemFree(pThis->papvLevel1);
09034c53c75eab7ea04021a749b98e7f78fae85avboxsync
09034c53c75eab7ea04021a749b98e7f78fae85avboxsync RTMemFree(pThis);
09034c53c75eab7ea04021a749b98e7f78fae85avboxsync
09034c53c75eab7ea04021a749b98e7f78fae85avboxsync return VINF_SUCCESS;
4d0b8f024a4654c1f61c8c4b7e16320719f7fea4vboxsync}
aa4bcf0a4b2db3ac352b56a291d49cb8d4b66d32vboxsyncRT_EXPORT_SYMBOL(RTHandleTableDestroy);
4d0b8f024a4654c1f61c8c4b7e16320719f7fea4vboxsync