// -*- mode: cpp; mode: fold -*-
// Description /*{{{*/
-// $Id: acquire.cc,v 1.48 2001/05/22 04:17:18 jgg Exp $
+// $Id: acquire.cc,v 1.50 2004/03/17 05:17:11 mdz Exp $
/* ######################################################################
Acquire - File Acquiration
##################################################################### */
/*}}}*/
// Include Files /*{{{*/
-#ifdef __GNUG__
-#pragma implementation "apt-pkg/acquire.h"
-#endif
#include <apt-pkg/acquire.h>
#include <apt-pkg/acquire-item.h>
#include <apt-pkg/acquire-worker.h>
#include <apti18n.h>
#include <iostream>
+#include <sstream>
#include <dirent.h>
#include <sys/time.h>
void pkgAcquire::Shutdown()
{
while (Items.size() != 0)
+ {
+ if (Items[0]->Status == Item::StatFetching)
+ Items[0]->Status = Item::StatError;
delete Items[0];
+ }
while (Queues != 0)
{
{
Dequeue(Itm);
- for (ItemIterator I = Items.begin(); I != Items.end(); I++)
+ for (ItemIterator I = Items.begin(); I != Items.end();)
{
if (*I == Itm)
{
Items.erase(I);
I = Items.begin();
}
+ else
+ I++;
}
}
/*}}}*/
Item.Owner->Status = Item::StatIdle;
// Queue it into the named queue
- I->Enqueue(Item);
- ToFetch++;
-
+ if(I->Enqueue(Item))
+ ToFetch++;
+
// Some trace stuff
if (Debug == true)
{
Worker Work(Conf);
if (Work.Start() == false)
return 0;
-
+
+ /* if a method uses DownloadLimit, we switch to SingleInstance mode */
+ if(_config->FindI("Acquire::"+Access+"::DlLimit",0) > 0)
+ Conf->SingleInstance = true;
+
return Conf;
}
/*}}}*/
/* This runs the queues. It manages a select loop for all of the
Worker tasks. The workers interact with the queues and items to
manage the actual fetch. */
-pkgAcquire::RunResult pkgAcquire::Run()
+pkgAcquire::RunResult pkgAcquire::Run(int PulseIntervall)
{
Running = true;
// Run till all things have been acquired
struct timeval tv;
tv.tv_sec = 0;
- tv.tv_usec = 500000;
+ tv.tv_usec = PulseIntervall;
while (ToFetch > 0)
{
fd_set RFds;
// Timeout, notify the log class
if (Res == 0 || (Log != 0 && Log->Update == true))
{
- tv.tv_usec = 500000;
+ tv.tv_usec = PulseIntervall;
for (Worker *I = Workers; I != 0; I = I->NextAcquire)
I->Pulse();
if (Log != 0 && Log->Pulse(this) == false)
Total += (*I)->PartialSize;
return Total;
}
- /*}}}*/
+
// Acquire::UriBegin - Start iterator for the uri list /*{{{*/
// ---------------------------------------------------------------------
/* */
// Queue::Enqueue - Queue an item to the queue /*{{{*/
// ---------------------------------------------------------------------
/* */
-void pkgAcquire::Queue::Enqueue(ItemDesc &Item)
+bool pkgAcquire::Queue::Enqueue(ItemDesc &Item)
{
QItem **I = &Items;
- for (; *I != 0; I = &(*I)->Next);
-
+ // move to the end of the queue and check for duplicates here
+ for (; *I != 0; I = &(*I)->Next)
+ if (Item.URI == (*I)->URI)
+ {
+ Item.Owner->Status = Item::StatDone;
+ return false;
+ }
+
// Create a new item
QItem *Itm = new QItem;
*Itm = Item;
Item.Owner->QueueCounter++;
if (Items->Next == 0)
Cycle();
+ return true;
}
/*}}}*/
// Queue::Dequeue - Remove an item from the queue /*{{{*/
Time = NewTime;
}
+ int fd = _config->FindI("APT::Status-Fd",-1);
+ if(fd > 0)
+ {
+ ostringstream status;
+
+ char msg[200];
+ long i = CurrentItems < TotalItems ? CurrentItems + 1 : CurrentItems;
+ unsigned long ETA =
+ (unsigned long)((TotalBytes - CurrentBytes) / CurrentCPS);
+
+ // only show the ETA if it makes sense
+ if (ETA > 0 && ETA < 172800 /* two days */ )
+ snprintf(msg,sizeof(msg), _("Retrieving file %li of %li (%s remaining)"), i, TotalItems, TimeToStr(ETA).c_str());
+ else
+ snprintf(msg,sizeof(msg), _("Retrieving file %li of %li"), i, TotalItems);
+
+
+
+ // build the status str
+ status << "dlstatus:" << i
+ << ":" << (CurrentBytes/float(TotalBytes)*100.0)
+ << ":" << msg
+ << endl;
+ write(fd, status.str().c_str(), status.str().size());
+ }
+
return true;
}
/*}}}*/