Example #1
0
/*
 * Slowly load the contents of "List.c" into the
 * linked list.
 */
DWORD WINAPI LoadThreadFunc(LPVOID n)
{
	int nBatchCount;
	Node *pNode;

	FILE* fp = fopen("List.c", "r");
	if (!fp)
	{
		fprintf(stderr, "ReadWrit.c not found\n");
		exit(EXIT_FAILURE);
	}

	pNode = GlobalAlloc(GPTR, sizeof(Node));
	nBatchCount = (rand() % 10) + 2;
	AcquireWriteLock(&gpList->lock);

	while (fgets(pNode->szBuffer, sizeof(Node), fp))
	{
		AddHead(gpList, pNode);

		// Try not to hog the lock
		if (--nBatchCount == 0)
		{
			ReleaseWriteLock(&gpList->lock);
			Sleep(rand() % 5);
			nBatchCount = (rand() % 10) + 2;
			AcquireWriteLock(&gpList->lock);
		}
		pNode = GlobalAlloc(GPTR, sizeof(Node));
	}

	ReleaseWriteLock(&gpList->lock);
	return 0;
}
Example #2
0
BOOL
WINAPI
WahEnumerateHandleContexts(IN PWAH_HANDLE_TABLE Table,
                           IN PWAH_HANDLE_ENUMERATE_PROC Callback,
                           IN PVOID Context)
{
    DWORD i, j;
    PWAH_SEARCH_TABLE SearchTable;
    PWAH_HASH_TABLE HashTable;
    PWAH_HANDLE Handle;
    BOOL GoOn = TRUE;

    /* Loop the table */
    for (i = 0; i <= Table->Mask; i++)
    {
        /* Get the Search table */
        SearchTable = &Table->SearchTables[i];

        /* Lock it */
        AcquireWriteLock(SearchTable);

        /* Mark us as expanding and wait for everyone */
        SearchTable->Expanding = TRUE;
        TryWaitForReaders(SearchTable);

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

        /* Make sure it exists */
        if (HashTable)
        {
            /* Loop every handle in it */
            for (j = 0; j < HashTable->Size; j++)
            {
                /* Get this handle */
                Handle = HashTable->Handles[j];
                if (!Handle) continue;

                /* Call the callback proc */
                GoOn = Callback(Context, Handle);
                if (!GoOn) break;
            }
        }

        /* Disable the expansion bit and release the lock */
        SearchTable->Expanding = FALSE;
        ReleaseWriteLock(SearchTable);

        /* Check again if we should leave */
        if (!GoOn) break;
    }

    /* return */
    return GoOn;
}
Example #3
0
BOOL DeleteList(List *pList)
{
	AcquireWriteLock(&pList->lock);
	while (DeleteHead(pList))
		;
	ReleaseWriteLock(&pList->lock);

	DestroyRWLock(&gpList->lock);

    GlobalFree(pList);

	return TRUE;
}
Example #4
0
/*
 * Every so often, delete some entries in the list.
 */
DWORD WINAPI DeleteThreadFunc(LPVOID n)
{
	int i;

	for (i=0; i<100; i++)
	{
		Sleep(1);
		AcquireWriteLock(&gpList->lock);
		DeleteHead(gpList);
		DeleteHead(gpList);
		DeleteHead(gpList);
		ReleaseWriteLock(&gpList->lock);
	}

    return 0;
}
Example #5
0
DWORD
WINAPI
WahRemoveHandleContext(IN PWAH_HANDLE_TABLE Table,
                       IN PWAH_HANDLE Handle)
{
    PWAH_HANDLE *HashHandle;
    PWAH_SEARCH_TABLE SearchTable;
    PWAH_HASH_TABLE HashTable;
    DWORD ErrorCode = ERROR_SUCCESS;

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

    /* Lock it */
    AcquireWriteLock(SearchTable);

    /* Get the hash table and handle */
    HashTable = SearchTable->HashTable;
    HashHandle = &WSH_HASH_FROM_HANDLE(Handle->Handle, HashTable);

    /* Make sure we have a handle, and write the new pointer */
    if (HashHandle && (InterlockedCompareExchangePointer((PVOID*)HashHandle,
                                                         NULL,
                                                         Handle) == Handle))
    {
        /* Wait for everyone to be done with it */
        TryWaitForReaders(SearchTable);
    }
    else
    {
        /* Invalid handle */
        ErrorCode = ERROR_INVALID_PARAMETER;
    }

    /* Release the lock */
    ReleaseWriteLock(SearchTable);

    /* Return */
    return ErrorCode;
}
Example #6
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;
}