ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

nbnamecache.c
Go to the documentation of this file.
00001 /* Copyright (c) 2003 Juan Lang
00002  *
00003  * This library is free software; you can redistribute it and/or
00004  * modify it under the terms of the GNU Lesser General Public
00005  * License as published by the Free Software Foundation; either
00006  * version 2.1 of the License, or (at your option) any later version.
00007  *
00008  * This library is distributed in the hope that it will be useful,
00009  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00010  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00011  * Lesser General Public License for more details.
00012  *
00013  * You should have received a copy of the GNU Lesser General Public
00014  * License along with this library; if not, write to the Free Software
00015  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
00016  *
00017  * This implementation uses a linked list, because I don't have a decent
00018  * hash table implementation handy.  This is somewhat inefficient, but it's
00019  * rather more efficient than not having a name cache at all.
00020  */
00021 
00022 #include "config.h"
00023 #include "wine/port.h"
00024 
00025 #include "nbnamecache.h"
00026 
00027 typedef struct _NBNameCacheNode
00028 {
00029     DWORD expireTime;
00030     NBNameCacheEntry *entry;
00031     struct _NBNameCacheNode *next;
00032 } NBNameCacheNode;
00033 
00034 struct NBNameCache
00035 {
00036     HANDLE heap;
00037     CRITICAL_SECTION cs;
00038     DWORD entryExpireTimeMS;
00039     NBNameCacheNode *head;
00040 };
00041 
00042 /* Unlinks the node pointed to by *prev, and frees any associated memory.
00043  * If that node's next pointed to another node, *prev now points to it.
00044  * Assumes the caller owns cache's lock.
00045  */
00046 static void NBNameCacheUnlinkNode(struct NBNameCache *cache,
00047  NBNameCacheNode **prev)
00048 {
00049     if (cache && prev && *prev)
00050     {
00051         NBNameCacheNode *next = (*prev)->next;
00052 
00053         HeapFree(cache->heap, 0, (*prev)->entry);
00054         HeapFree(cache->heap, 0, *prev);
00055         *prev = next;
00056     }
00057 }
00058 
00059 /* Walks the list beginning with cache->head looking for the node with name
00060  * name.  If the node is found, returns a pointer to the next pointer of the
00061  * node _prior_ to the found node (or head if head points to it).  Thus, if the
00062  * node's all you want, dereference the return value twice.  If you want to
00063  * modify the list, modify the referent of the return value.
00064  * While it's at it, deletes nodes whose time has expired (except the node
00065  * you're looking for, of course).
00066  * Returns NULL if the node isn't found.
00067  * Assumes the caller owns cache's lock.
00068  */
00069 static NBNameCacheNode **NBNameCacheWalk(struct NBNameCache *cache,
00070  const char name[NCBNAMSZ])
00071 {
00072     NBNameCacheNode **ret = NULL;
00073 
00074     if (cache && cache->head)
00075     {
00076         NBNameCacheNode **ptr;
00077 
00078         ptr = &cache->head;
00079         while (ptr && *ptr && (*ptr)->entry)
00080         {
00081             if (!memcmp((*ptr)->entry->name, name, NCBNAMSZ - 1))
00082                 ret = ptr;
00083             else
00084             {
00085                 if (GetTickCount() > (*ptr)->expireTime)
00086                     NBNameCacheUnlinkNode(cache, ptr);
00087             }
00088             if (*ptr)
00089                 ptr = &(*ptr)->next;
00090         }
00091     }
00092     return ret;
00093 }
00094 
00095 struct NBNameCache *NBNameCacheCreate(HANDLE heap, DWORD entryExpireTimeMS)
00096 {
00097     struct NBNameCache *cache;
00098     
00099     
00100     if (!heap)
00101         heap = GetProcessHeap();
00102     cache = HeapAlloc(heap, 0, sizeof(struct NBNameCache));
00103     if (cache)
00104     {
00105         cache->heap = heap;
00106         InitializeCriticalSection(&cache->cs);
00107         cache->cs.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": NBNameCache.cs");
00108         cache->entryExpireTimeMS = entryExpireTimeMS;
00109         cache->head = NULL;
00110     }
00111     return cache;
00112 }
00113 
00114 BOOL NBNameCacheAddEntry(struct NBNameCache *cache, NBNameCacheEntry *entry)
00115 {
00116     BOOL ret;
00117 
00118     if (cache && entry)
00119     {
00120         NBNameCacheNode **node;
00121 
00122         EnterCriticalSection(&cache->cs);
00123         node = NBNameCacheWalk(cache, (char*)entry->name);
00124         if (node)
00125         {
00126             (*node)->expireTime = GetTickCount() +
00127              cache->entryExpireTimeMS;
00128             HeapFree(cache->heap, 0, (*node)->entry);
00129             (*node)->entry = entry;
00130             ret = TRUE;
00131         }
00132         else
00133         {
00134             NBNameCacheNode *newNode = HeapAlloc(cache->heap, 0, sizeof(NBNameCacheNode));
00135             if (newNode)
00136             {
00137                 newNode->expireTime = GetTickCount() +
00138                  cache->entryExpireTimeMS;
00139                 newNode->entry = entry;
00140                 newNode->next = cache->head;
00141                 cache->head = newNode;
00142                 ret = TRUE;
00143             }
00144             else
00145                 ret = FALSE;
00146         }
00147         LeaveCriticalSection(&cache->cs);
00148     }
00149     else
00150         ret = FALSE;
00151     return ret;
00152 }
00153 
00154 const NBNameCacheEntry *NBNameCacheFindEntry(struct NBNameCache *cache,
00155  const UCHAR name[NCBNAMSZ])
00156 {
00157     const NBNameCacheEntry *ret;
00158     UCHAR printName[NCBNAMSZ];
00159 
00160     memcpy(printName, name, NCBNAMSZ - 1);
00161     printName[NCBNAMSZ - 1] = '\0';
00162     if (cache)
00163     {
00164         NBNameCacheNode **node;
00165 
00166         EnterCriticalSection(&cache->cs);
00167         node = NBNameCacheWalk(cache, (const char *)name);
00168         if (node)
00169             ret = (*node)->entry;
00170         else
00171             ret = NULL;
00172         LeaveCriticalSection(&cache->cs);
00173     }
00174     else
00175         ret = NULL;
00176     return ret;
00177 }
00178 
00179 void NBNameCacheDestroy(struct NBNameCache *cache)
00180 {
00181     if (cache)
00182     {
00183         cache->cs.DebugInfo->Spare[0] = 0;
00184         DeleteCriticalSection(&cache->cs);
00185         while (cache->head)
00186             NBNameCacheUnlinkNode(cache, &cache->head);
00187         HeapFree(cache->heap, 0, cache);
00188     }
00189 }

Generated on Sun May 27 2012 04:25:27 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.