Exemple #1
0
PTHREADDATA GetThreadData(void)
{
   PTHREADDATA ThreadData;
   DWORD LastError;

   LastError = GetLastError();
   ThreadData = TlsGetValue(TlsIndex);
   if (ThreadData == NULL)
     {
	ThreadData = (PTHREADDATA)calloc(1, sizeof(THREADDATA));
	if (ThreadData != NULL)
	  {
	     TlsSetValue(TlsIndex, (LPVOID)ThreadData);

	     InitThreadData(ThreadData);
	  }
	else
	  {
	    _amsg_exit(_RT_THREAD); /* write message and die */
	  }
     }

   SetLastError(LastError);

   return ThreadData;
}
void WINAPI _export ShowInfoMenu(void)
{
  FarDialogItem DialogItems[1];
  memset(DialogItems,0,sizeof(DialogItems));
  DialogItems[0].Type=DI_LISTBOX; DialogItems[0].Flags=DIF_LISTWRAPMODE;
  ThreadData Thread={FALSE,NULL,NULL,NULL,PlgOpt.RefreshInterval};
  InitThreadData(&Thread);
  InfoMenuData params={{&Thread,0,{-1,-1},{L"",L""},INVALID_HANDLE_VALUE,false,InfoMenuDialogKeyProc,MACRO_INFO_MENU,true,false},0,NULL,true,true};
  CFarDialog dialog;
  dialog.Execute(Info.ModuleNumber,-1,-1,0,0,_T("InfoMenu"),DialogItems,sizeofa(DialogItems),0,0,InfoMenuProc,(LONG_PTR)&params);
  FreeThreadData(&Thread);
  free(params.id);
}
Exemple #3
0
int CreateThreadData(void)
{
   PTHREADDATA ThreadData;

   TlsIndex = TlsAlloc();
   if (TlsIndex == (unsigned long)-1)
     return FALSE;

   ThreadData = (PTHREADDATA)calloc(1, sizeof(THREADDATA));
   if (ThreadData == NULL)
     return FALSE;

   if(!TlsSetValue(TlsIndex, (LPVOID)ThreadData))
     return FALSE;

   InitThreadData(ThreadData);

   return TRUE;
}
Exemple #4
0
static
VOID
TestResourceWithThreads(
    IN PERESOURCE Res)
{
    NTSTATUS Status = STATUS_SUCCESS;
    THREAD_DATA ThreadDataShared;
    THREAD_DATA ThreadDataShared2;
    THREAD_DATA ThreadDataExclusive;
    THREAD_DATA ThreadDataSharedStarve;
    THREAD_DATA ThreadDataSharedWait;
    LARGE_INTEGER Timeout;
    Timeout.QuadPart = -10 * 1000 * 10; /* 10 ms */

    InitThreadData(&ThreadDataShared, Res, ExAcquireResourceSharedLite);
    InitThreadData(&ThreadDataShared2, Res, ExAcquireResourceSharedLite);
    InitThreadData(&ThreadDataExclusive, Res, ExAcquireResourceExclusiveLite);
    InitThreadData(&ThreadDataSharedStarve, Res, ExAcquireSharedStarveExclusive);
    InitThreadData(&ThreadDataSharedWait, Res, ExAcquireSharedWaitForExclusive);

    /* have a thread acquire the resource shared */
    Status = StartThread(&ThreadDataShared, NULL, FALSE, TRUE);
    ok_eq_hex(Status, STATUS_SUCCESS);
    CheckResourceStatus(Res, FALSE, 0LU, 0LU, 0LU);
    ok_eq_int(Res->ActiveCount, 1);

    /* a second thread should be able to acquire the resource shared */
    Status = StartThread(&ThreadDataShared2, NULL, FALSE, TRUE);
    ok_eq_hex(Status, STATUS_SUCCESS);
    CheckResourceStatus(Res, FALSE, 0LU, 0LU, 0LU);
    ok_eq_int(Res->ActiveCount, 2);
    FinishThread(&ThreadDataShared2);
    CheckResourceStatus(Res, FALSE, 0LU, 0LU, 0LU);
    ok_eq_int(Res->ActiveCount, 1);

    /* now have a thread that tries to acquire the resource exclusive -- it should fail */
    Status = StartThread(&ThreadDataExclusive, NULL, FALSE, FALSE);
    ok_eq_hex(Status, STATUS_SUCCESS);
    CheckResourceStatus(Res, FALSE, 0LU, 0LU, 0LU);
    ok_eq_int(Res->ActiveCount, 1);
    FinishThread(&ThreadDataExclusive);
    CheckResourceStatus(Res, FALSE, 0LU, 0LU, 0LU);
    ok_eq_int(Res->ActiveCount, 1);

    /* as above, but this time it should block */
    Status = StartThread(&ThreadDataExclusive, &Timeout, TRUE, TRUE);
    ok_eq_hex(Status, STATUS_TIMEOUT);
    CheckResourceStatus(Res, FALSE, 0LU, 1LU, 0LU);
    ok_eq_int(Res->ActiveCount, 1);

    /* now try another shared one -- it should fail */
    Status = StartThread(&ThreadDataShared2, NULL, FALSE, FALSE);
    ok_eq_hex(Status, STATUS_SUCCESS);
    CheckResourceStatus(Res, FALSE, 0LU, 1LU, 0LU);
    ok_eq_int(Res->ActiveCount, 1);
    FinishThread(&ThreadDataShared2);

    /* same for ExAcquireSharedWaitForExclusive */
    Status = StartThread(&ThreadDataSharedWait, NULL, FALSE, FALSE);
    ok_eq_hex(Status, STATUS_SUCCESS);
    CheckResourceStatus(Res, FALSE, 0LU, 1LU, 0LU);
    ok_eq_int(Res->ActiveCount, 1);
    FinishThread(&ThreadDataSharedWait);

    /* ExAcquireSharedStarveExclusive must get access though! */
    Status = StartThread(&ThreadDataSharedStarve, NULL, TRUE, TRUE);
    ok_eq_hex(Status, STATUS_SUCCESS);
    CheckResourceStatus(Res, FALSE, 0LU, 1LU, 0LU);
    ok_eq_int(Res->ActiveCount, 2);
    FinishThread(&ThreadDataSharedStarve);
    CheckResourceStatus(Res, FALSE, 0LU, 1LU, 0LU);
    ok_eq_int(Res->ActiveCount, 1);

    /* block another shared one */
    Status = StartThread(&ThreadDataShared2, &Timeout, TRUE, TRUE);
    ok_eq_hex(Status, STATUS_TIMEOUT);
    CheckResourceStatus(Res, FALSE, 0LU, 1LU, 1LU);
    ok_eq_int(Res->ActiveCount, 1);

    /* finish the very first one */
    FinishThread(&ThreadDataShared);

    /* now the blocked exclusive one should get the resource */
    Status = KeWaitForSingleObject(&ThreadDataExclusive.OutEvent, Executive, KernelMode, FALSE, NULL);
    ok_eq_hex(Status, STATUS_SUCCESS);
    CheckResourceStatus(Res, FALSE, 0LU, 0LU, 1LU);
    ok_eq_int(Res->ActiveCount, 1);
    ok_eq_uint((Res->Flag & ResourceOwnedExclusive) != 0, 1);

    FinishThread(&ThreadDataExclusive);
    CheckResourceStatus(Res, FALSE, 0LU, 0LU, 0LU);

    /* now the blocked shared one should resume */
    Status = KeWaitForSingleObject(&ThreadDataShared2.OutEvent, Executive, KernelMode, FALSE, NULL);
    ok_eq_hex(Status, STATUS_SUCCESS);
    CheckResourceStatus(Res, FALSE, 0LU, 0LU, 0LU);
    ok_eq_int(Res->ActiveCount, 1);
    FinishThread(&ThreadDataShared2);
    CheckResourceStatus(Res, FALSE, 0LU, 0LU, 0LU);
    ok_eq_int(Res->ActiveCount, 0);
}
Exemple #5
0
static
VOID
TestFastMutexConcurrent(
    PFAST_MUTEX Mutex)
{
    NTSTATUS Status;
    THREAD_DATA ThreadData;
    THREAD_DATA ThreadData2;
    THREAD_DATA ThreadDataUnsafe;
    THREAD_DATA ThreadDataTry;
    LARGE_INTEGER Timeout;
    Timeout.QuadPart = -10 * 1000 * 10; /* 10 ms */

    InitThreadData(&ThreadData, Mutex, ExAcquireFastMutex, NULL, ExReleaseFastMutex);
    InitThreadData(&ThreadData2, Mutex, ExAcquireFastMutex, NULL, ExReleaseFastMutex);
    InitThreadData(&ThreadDataUnsafe, Mutex, ExAcquireFastMutexUnsafe, NULL, ExReleaseFastMutexUnsafe);
    InitThreadData(&ThreadDataTry, Mutex, NULL, ExTryToAcquireFastMutex, ExReleaseFastMutex);

    /* have a thread acquire the mutex */
    Status = StartThread(&ThreadData, NULL, PASSIVE_LEVEL, FALSE, FALSE);
    ok_eq_hex(Status, STATUS_SUCCESS);
    CheckMutex(Mutex, 0L, ThreadData.Thread, 0LU, PASSIVE_LEVEL, PASSIVE_LEVEL);
    /* have a second thread try to acquire it -- should fail */
    Status = StartThread(&ThreadDataTry, NULL, PASSIVE_LEVEL, TRUE, FALSE);
    ok_eq_hex(Status, STATUS_SUCCESS);
    CheckMutex(Mutex, 0L, ThreadData.Thread, 0LU, PASSIVE_LEVEL, PASSIVE_LEVEL);
    FinishThread(&ThreadDataTry);

    /* have another thread acquire it -- should block */
    Status = StartThread(&ThreadData2, &Timeout, APC_LEVEL, FALSE, FALSE);
    ok_eq_hex(Status, STATUS_TIMEOUT);
    CheckMutex(Mutex, -1L, ThreadData.Thread, 1LU, PASSIVE_LEVEL, PASSIVE_LEVEL);

    /* finish the first thread -- now the second should become available */
    FinishThread(&ThreadData);
    Status = KeWaitForSingleObject(&ThreadData2.OutEvent, Executive, KernelMode, FALSE, NULL);
    ok_eq_hex(Status, STATUS_SUCCESS);
    CheckMutex(Mutex, 0L, ThreadData2.Thread, 1LU, APC_LEVEL, PASSIVE_LEVEL);

    /* block two more threads */
    Status = StartThread(&ThreadDataUnsafe, &Timeout, APC_LEVEL, FALSE, FALSE);
    ok_eq_hex(Status, STATUS_TIMEOUT);
    CheckMutex(Mutex, -1L, ThreadData2.Thread, 2LU, APC_LEVEL, PASSIVE_LEVEL);

    Status = StartThread(&ThreadData, &Timeout, PASSIVE_LEVEL, FALSE, FALSE);
    ok_eq_hex(Status, STATUS_TIMEOUT);
    CheckMutex(Mutex, -2L, ThreadData2.Thread, 3LU, APC_LEVEL, PASSIVE_LEVEL);

    /* finish 1 */
    FinishThread(&ThreadData2);
    Status = KeWaitForSingleObject(&ThreadDataUnsafe.OutEvent, Executive, KernelMode, FALSE, NULL);
    ok_eq_hex(Status, STATUS_SUCCESS);
    CheckMutex(Mutex, -1L, ThreadDataUnsafe.Thread, 3LU, APC_LEVEL, PASSIVE_LEVEL);

    /* finish 2 */
    FinishThread(&ThreadDataUnsafe);
    Status = KeWaitForSingleObject(&ThreadData.OutEvent, Executive, KernelMode, FALSE, NULL);
    ok_eq_hex(Status, STATUS_SUCCESS);
    CheckMutex(Mutex, 0L, ThreadData.Thread, 3LU, PASSIVE_LEVEL, PASSIVE_LEVEL);

    /* finish 3 */
    FinishThread(&ThreadData);

    CheckMutex(Mutex, 1L, NULL, 3LU, PASSIVE_LEVEL, PASSIVE_LEVEL);
}