Exemple #1
0
/*
 * Every so often, walked the linked list
 * and figure out how many lines one string
 * appears (given as the startup param)
 */
DWORD WINAPI SearchThreadFunc(LPVOID n)
{
	int i;
	char *szSearch = (char *)n;

	for (i=0; i<20; i++)
	{
		int		nFoundCount = 0;
		Node   *next = NULL;

		AcquireReadLock(&gpList->lock);
		next = Next(gpList, next);
		while (next)
		{
			if (strstr(next->szBuffer, szSearch))
				nFoundCount++;
			next = Next(gpList, next);
		}

		ReleaseReadLock(&gpList->lock);

		printf("Found %d lines with '%s'\n", nFoundCount, szSearch);
		Sleep((rand() % 30));
	}
    return 0;
}
Exemple #2
0
PWAH_HANDLE
WINAPI
WahReferenceContextByHandle(IN PWAH_HANDLE_TABLE Table,
                            IN HANDLE Handle)
{
    PWAH_HANDLE HashHandle;
    PWAH_SEARCH_TABLE SearchTable;
    PWAH_HASH_TABLE HashTable;
    PVLONG Count;

    /* Get the current Search Table */
    SearchTable = WSH_SEARCH_TABLE_FROM_HANDLE(Handle, Table);

    /* Lock it */
    AcquireReadLock(SearchTable, &Count);

    /* Get the hash table and handle */
    HashTable = SearchTable->HashTable;

    /* Check if it's valid, and if it's the one we want */
    if ((HashTable) && 
        (HashHandle = WSH_HASH_FROM_HANDLE(Handle, HashTable)) &&
        (HashHandle->Handle == Handle))
    {
        /* Reference the handle */
        InterlockedIncrement(&HashHandle->RefCount);
    }
    else
    {
        /* Invalid handle */
        HashHandle = NULL;
    }

    /* Release the lock */
    ReleaseReadLock(SearchTable, Count);

    /* Return */
    return HashHandle;
}
Exemple #3
0
PWAH_HANDLE
WINAPI
WahInsertHandleContext(IN PWAH_HANDLE_TABLE Table,
                       IN PWAH_HANDLE Handle)
{
    PWAH_HANDLE *HashHandle, OldHandle;
    PVLONG Count;
    PWAH_HASH_TABLE HashTable, NewHashTable;
    DWORD HandleCount, i;
    PWAH_SEARCH_TABLE SearchTable;

    /* Get the current Search Table */
    SearchTable = WSH_SEARCH_TABLE_FROM_HANDLE(Handle->Handle, Table);

    /* Start loop */
    do
    {
        /* Get reader lock */
        AcquireReadLock(SearchTable, &Count);

        /* Get the hash table */
        HashTable = SearchTable->HashTable;

        /* Make sure we are not expanding, and that the table is there */
        if (!(SearchTable->Expanding) && (HashTable))
        {
            /* Get the hash handle */
            HashHandle = &WSH_HASH_FROM_HANDLE(Handle->Handle, HashTable);

            /* Do the insert */
            if (InterlockedCompareExchangePointer((PVOID*)HashHandle,
                                                  Handle,
                                                  NULL) == NULL)
            {
                /* Success, release the reader lock */
                ReleaseReadLock(SearchTable, Count);

                /* Save old handle */
                OldHandle = Handle;
                break;
            }
        }

        /* Release the read lock since we're done with it now */
        ReleaseReadLock(SearchTable, Count);

        /* We need the writer lock to expand/create the table */
        AcquireWriteLock(SearchTable);

        /* Mark the table in use */
        SearchTable->Expanding = TRUE;

        /* Wait for all the readers to finish */
        TryWaitForReaders(SearchTable);

        /* Start loop */
        do
        {
            /* Get the hash table again */
            HashTable = SearchTable->HashTable;

            /* Check if exists now */
            if (HashTable)
            {
                /* It does! Do what we wanted to do earlier. Get the hash... */
                HashHandle = &WSH_HASH_FROM_HANDLE(Handle->Handle, HashTable);

                /* Check if it doesn't exist */
                if (!(*HashHandle))
                {
                    /* Write it (no need for interlock, we have the RW lock) */
                    OldHandle = Handle;
                    *HashHandle = Handle;
                    break;
                }
                else if ((*HashHandle)->Handle == Handle->Handle)
                {
                    /* Handle matches, write it (see comment above) */
                    OldHandle = *HashHandle;
                    *HashHandle = Handle;
                    break;
                }

                /* No go, we need to expand the table. Remember the size now */
                HandleCount = HashTable->Size;
            }
            else
            {
                /* Table is empty, we have to create it */
                HandleCount = 0;
            }

ExpandTable:
            /* Find a free prime */
            for (i = 0; HandleCount >= SockPrimes[i]; i++);

            /* Check if we found one */
            if (SockPrimes[i] != 0xFFFFFFFF)
            {
                /* Use the prime */
                HandleCount = SockPrimes[i];
            }
            else
            {
                /* No primes left. Table is quite large, so simply double it */
                HandleCount *= 2;
            }

            /* Allocate the table */
            NewHashTable = HeapAlloc(GlobalHeap,
                                     0,
                                     FIELD_OFFSET(WSH_HASH_TABLE,
                                                  Handles[HandleCount]));

            /* Hopefully we have one now */
            if (NewHashTable)
            {
                /* Set its size */
                NewHashTable->Size = HandleCount;

                /* Initialize it */
                RtlZeroMemory(NewHashTable->Handles, HandleCount * sizeof(PVOID));

                /* Insert us first */
                WSH_HASH_FROM_HANDLE(Handle->Handle, NewHashTable) = Handle;

                /* Now check if our old table had entries in it */
                if (HashTable)
                {
                    /* We need to move them */
                    for (i = 0; i < HashTable->Size; i++)
                    {
                        /* Make sure the hash handle exists */
                        if (HashTable->Handles[i])
                        {
                            /* Get it */
                            HashHandle = &WSH_HASH_FROM_HANDLE(HashTable->
                                                               Handles[i]->Handle,
                                                               NewHashTable);

                            /* Check if it has a value */
                            if (!(*HashHandle))
                            {
                                /* It's empty, so just write the handle */
                                *HashHandle = HashTable->Handles[i];
                            }
                            else
                            {
                                /* Not empty :/... that implies a collision */
                                HeapFree(GlobalHeap, 0, NewHashTable);
                                goto ExpandTable;
                            }
                        }
                    }

                    /* Write the new hash table */
                    SearchTable->HashTable = NewHashTable;

                    /* Wait for everyone to be done with it, then free it */
                    TryWaitForReaders(SearchTable);
                    HeapFree(GlobalHeap, 0, HashTable);
                }
                else
                {
                    /* It was empty, nothing to worry about */
                    SearchTable->HashTable = NewHashTable;
                }

                /* Save the old handle */
                OldHandle = Handle;
            }
            else
            {
                /* There was no old handle */
                OldHandle = Handle;
            }
        } while (0);

        /* Mark us as free, and release the write lock */
        SearchTable->Expanding = FALSE;
        ReleaseWriteLock(SearchTable);
        break;
    } while (1);

    /* Return the old handle */
    return OldHandle;
}