[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Question: Are there any limitations on using libapt-pkg-dev in a thread (pthread_create)?



Dear Sir / Madam,

I started using libapt-pkg-dev C++ library (ver. 0.5.4) and found a very odd behavior:
If I called upon apt-get calls (using the library) they executed successfully.
However, if I called upon apt-get calls (using the library) within a thread func as follows:
1. call pthread_create(...pthread-myfunc,argv);
2. void pthread-myfunc()
{
	const char *cmd[3];
	cmd[0] = "apt-get";		
	cmd[1] = "update";
	cmd[2] = 0;
	dprintf(3,"Call apt-get update.");
	if (!apt_get(cmd))
	{
		dprintf(3,"Upgrade(): failed apt-get update.");
	}
}
The thread hanged.
It hanged after doing a fork, when the main thread was waiting on select() call with timeout 0 (which means : wait for input stream forever,
and indeed it will be waiting for ever, if executed within pthread-myfunc).

3. I tried another library's functionality which (again) involved a forked process while the main thread is waiting on a read() for input stream
and the results were similar: If I executed this call within a pthread-myfunc , the thread hanged because the main thread was blocked on a read() forever.
(If I executed the same functionality in the main(), it would execute successfully)

Following is a copy of library's code with dprintf comments to illustrate the problem:

Could you please tell me how to solve this problem, so that I could call upon library's methods within pthread-myfunc.
Is it a known issue?
Thank you,
  Orna Haber.
  ohaber@troikanetworks.com
tel 818 3703053.



   // Fork gzip
   int Process = ExecFork();
   if (Process == 0)
   {
      close(GzOut[0]);
      dup2(From.Fd(),STDIN_FILENO);
      dup2(GzOut[1],STDOUT_FILENO);
      From.Close();
      close(GzOut[1]);
      SetCloseExec(STDIN_FILENO,false);
      SetCloseExec(STDOUT_FILENO,false);
      
      const char *Args[3];
      Args[0] = "/bin/gzip";		
      Args[1] = "-d";
      Args[2] = 0;
      execv(Args[0],(char **)Args);
      _exit(100);
   }
   From.Close();
   close(GzOut[1]);
   
   FileFd FromGz(GzOut[0]);  // For autoclose   
   FileFd To("myTar2.tar",FileFd::WriteEmpty);   /*simplify: Itm->DestFile*/
   // To.EraseOnFailure(); I would like to see any result.
   if (_error->PendingError() == true)
      return false;
   
   // Read data from gzip, generate checksums and write
//   Hashes Hash; simplify
   bool Failed = false;
   while (1) 
   {
      unsigned char Buffer[4*1024];
      unsigned long Count;
      dprintf(3,"GZipObj::StartGzip() going to read()");
      Count = read( GzOut[0] ,Buffer,sizeof(Buffer));	<< The thread will block here!
	dprintf(3,"return from read.");




Reply to: