winpr-thread:

- added the unit test: TestThreadExitThread
  - fix: ensure thread_list to be up to date before to call ExitThread()
  - possibly resolved: Problems with serial redirection #2389
This commit is contained in:
Emmanuel Ledoux 2015-05-22 18:28:10 +02:00 committed by eledoux
parent 7a1485a2e4
commit 6f5de27081
3 changed files with 68 additions and 2 deletions

View File

@ -6,7 +6,8 @@ set(${MODULE_PREFIX}_DRIVER ${MODULE_NAME}.c)
set(${MODULE_PREFIX}_TESTS
TestThreadCommandLineToArgv.c
TestThreadCreateProcess.c)
TestThreadCreateProcess.c
TestThreadExitThread.c)
create_test_sourcelist(${MODULE_PREFIX}_SRCS
${${MODULE_PREFIX}_DRIVER}

View File

@ -0,0 +1,53 @@
// Copyright © 2015 Hewlett-Packard Development Company, L.P.
#include <winpr/file.h>
#include <winpr/synch.h>
#include <winpr/thread.h>
static void* thread_func(void* arg)
{
/* exists of the thread the quickest as possible */
ExitThread(0);
return NULL;
}
int TestThreadExitThread(int argc, char* argv[])
{
HANDLE thread;
QWORD waitResult;
int i;
/* FIXME: create some noise to better guaranty the test validity and
* decrease the number of loops */
for (i=0; i<10000; i++)
{
thread = CreateThread(NULL,
0,
(LPTHREAD_START_ROUTINE)thread_func,
NULL,
0,
NULL);
if (thread == INVALID_HANDLE_VALUE)
{
fprintf(stderr, "Got an invalid thread!\n");
return -1;
}
waitResult = WaitForSingleObject(thread, 1000);
if (waitResult != WAIT_OBJECT_0)
{
/* When the thread exits before the internal thread_list
* was updated, ExitThread() is not able to retrieve the
* related WINPR_THREAD object and is not able to signal
* the end of the thread. Therefore WaitForSingleObject
* never get the signal.
*/
fprintf(stderr, "Didn't quit the main thread correctly\n");
return -1;
}
CloseHandle(thread);
}
return 0;
}

View File

@ -294,6 +294,18 @@ static void* thread_launcher(void* arg)
goto exit;
}
/* pthread_create(3) doesn't guaranty the thread ID to be set
* before to invoke the start_routine() even if this seems to be
* actually done.*/
thread->thread = pthread_self();
/* also done by winpr_StartThread(). This ensures thread_list
* was updated before the thread could exit */
if (!ListDictionary_Add(thread_list, &thread->thread, thread))
{
WLog_ERR(TAG, "Thread function argument is %p", fkt);
goto exit;
}
rc = fkt(thread->lpParameter);
}
@ -328,7 +340,7 @@ static BOOL winpr_StartThread(WINPR_THREAD *thread)
if (pthread_create(&thread->thread, &attr, thread_launcher, thread))
goto error;
if (!ListDictionary_Add(thread_list, &thread->thread, thread))
if (!ListDictionary_Add(thread_list, &thread->thread, thread)) /* also done by thread_launcher() */
goto error;
pthread_attr_destroy(&attr);
dump_thread(thread);