Click here to Skip to main content
15,884,298 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
Hi All,
Why my QueueUserWorkItem is not at all working. My code is here:

C++
typedef struct
{
    PCHAR URL[MAX_URL] ;
    PCHAR DestinationPath ;
}MAINDATA, *PMAINDATA ;

int main(int argc, char * argv[])
{
	PMAINDATA	pData ;
		
	BOOL bQuwi ;
	DWORD dwIndex ;
	PCHAR pURL ;

        pData = (PMAINDATA)malloc(sizeof(MAINDATA)) ;
	pData->DestinationPath = NULL ;
	pData->URL[0] = 0 ;

        do
	{
	
		if(argc < 3)
		{
			printf("Main Error-> Not Enough Arguments\n") ;
			break ;
		}
		printf("START\n") ;
		pData->DestinationPath = argv[2] ;
		while((pURL = (PCHAR)GetNext_FileList(pContext)) != NULL)
		{
			TempURL = StrDupA(pURL) ;
			pData->URL[dwIndex] = (PCHAR)TempURL ;
			dwIndex++ ;
		}
		dwTotalNumberOfURL = dwIndex ;

		bQuwi = QueueUserWorkItem(MyThreadProc,(PVOID) pData,      
                                                             WT_EXECUTEDEFAULT) ;
		if ( !bQuwi )
			printf("Main: QueueUserWorkItem Failed\n");

		printf("SUCCESS\n") ;
	
	}while(FALSE) ;
        return 0 ;
}

DWORD CALLBACK MyThreadProc( LPVOID lpParam ) 
{ 
    PMAINDATA pData ;
    
	pData = (PMAINDATA)lpParam ;

	DownloadFile(pData->URL, pData->DestinationPath) ;
    
    return 0 ; 
} 


I have not submitted the whole code. So please bypass the declaration and free memory errors. The only problem I am facing is that QUWI is not calling my "MyThreadProc" function although it is returning TRUE.
Posted
Updated 16-Feb-12 22:36pm
v4

The problem with QueueUserWorkItem is most likely that your main() exits before the worker thread gets a chance to run. Try adding a long Sleep() to your main() after the QueueUserWorkItem() call, or better, synchronize the worker with main(). E.g. something like this:

C++
#include <windows.h>
#include <stdio.h>

// The synchronization object.
// Usually, this would be passed to the worker thread as part of
// context data but to simplify the example I put it here.
HANDLE g_syncEventHandle = 0;

DWORD CALLBACK MyThreadProc( LPVOID lpParam );

int main(int argc, char * argv[])
{
  g_syncEventHandle = CreateEvent(0, TRUE, FALSE, 0);

  BOOL b = QueueUserWorkItem(MyThreadProc, 0, WT_EXECUTEDEFAULT);
  if ( !b )
    printf("Error: QueueUserWorkItem Failed\n");
  else
    printf("SUCCESS - user work item queued\n") ;

  // Go and do other things here

  // Now the main thread is ready to terminate.
  // Before doing so, check that the worker is done.
  WaitForSingleObject(g_syncEventHandle, INFINITE);

  // And remember to clean up
  CloseHandle(g_syncEventHandle);

  printf("main() done\n");
  return 0 ;
}

DWORD CALLBACK MyThreadProc( LPVOID lpParam ) 
{ 
  printf("In " __FUNCTION__ "\n", GetCurrentThreadId());

  // Pretend to do stuff
  Sleep(5000);

  printf("In " __FUNCTION__ " after Sleep()\n", GetCurrentThreadId());

  // Tell the caller thread you're done.
  SetEvent(g_syncEventHandle);

  // And return
  return 0 ; 
}
 
Share this answer
 
v2
Comments
bjorn_ht 17-Feb-12 5:29am    
And pls ignore the calls to GetCurrentThreadId() in the printf() statements in MyThreadProc(). They don't belong there.
Abhineet Ayan Verma 17-Feb-12 5:53am    
Thanks man, Thanks for your great help.
Does the code compile without errors and warnings? I Don't think so. Increasing the compiler warn level may help you finding some problems (Project settings with VC).

C++
pData->URL[0] = 0 ;

This will initialize the first element of the array, but not the others. Possible soure for problems.

C++
TempURL = StrDupA(pURL) ;

TempURL is not defined (compiler error). StrDup() returns a pointer to allocated memory and must be freed later using LocalFree(). Without freeing, you have memory leaks.

C++
pData->URL[dwIndex] = (PCHAR)TempURL ;

This generates a compiler warning, because dwIndex is not initialized. Your code will probably crash.

C++
dwTotalNumberOfURL = dwIndex ;

dwTotalNumberOfURL is not defined (compiler error). Not necessary. Can use dwIndex contains instead.

pData is allocated but not freed. Another memory leak.

C++
DownloadFile(pData->URL, pData->DestinationPath) ;

pData->URL is an array of PCHAR pointers. You did not show the code for DownloadFile() but it may be expects a PCHAR rather PCHAR*. If it expects a PCHAR* it would be OK.

You should initialize dwIndex, fill your struct with NULL bytes, and free up memory at the end of your function:
C++
DWORD dwIndex = 0;
// You may also omit the allocation. The array can be also on the stack.
pData = (PMAINDATA)malloc(sizeof(MAINDATA)) ;
ZeroMemory(pData, sizeof(MAINDATA));
// No longer necessary
//pData->DestinationPath = NULL ;
//pData->URL[0] = 0 ;
...
pData->URL[dwIndex] = (PCHAR)StrDupA(pURL) ;
...
for (DWORD i = 0; i < dwIndex && pData->URL[dwIndex]; i++)
    LocalFree(pData->URL[dwIndex]);
free(pData);
return 0;


I did not know if I found all. There are too many.
 
Share this answer
 
Comments
CPallini 17-Feb-12 3:32am    
My 5.
Abhineet Ayan Verma 17-Feb-12 4:21am    
I have not submitted the whole code as it is long. What you have pointed is all implemented in my Code. Can you please answer as to what is the problem with my QueueUserWorkItem Method? It is a Bool value and it is returning 1 but even then it is not calling the function "MyThreadProc" and goes to next line in Main itself.
Jochen Arndt 17-Feb-12 5:06am    
OK. Please try to state the next time. It will help to focus the real problem.

How did you determine that your thread is not called? Have you added a trace command? The return value indicates that the thread has been started. So it should be active in the background downloading files.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

  Print Answers RSS
Top Experts
Last 24hrsThis month


CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900