X-Git-Url: https://git.saurik.com/apt.git/blobdiff_plain/b4fc9b6f648694ecb0d161cb14859da88b36881c..6e7c6c3f58193fd5db3d9d598ac65a1571522a58:/apt-pkg/acquire.cc diff --git a/apt-pkg/acquire.cc b/apt-pkg/acquire.cc index ae3ba2e01..daea234d3 100644 --- a/apt-pkg/acquire.cc +++ b/apt-pkg/acquire.cc @@ -1,6 +1,6 @@ // -*- 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 @@ -13,9 +13,6 @@ ##################################################################### */ /*}}}*/ // Include Files /*{{{*/ -#ifdef __GNUG__ -#pragma implementation "apt-pkg/acquire.h" -#endif #include #include #include @@ -26,6 +23,7 @@ #include #include +#include #include #include @@ -87,7 +85,11 @@ pkgAcquire::~pkgAcquire() void pkgAcquire::Shutdown() { while (Items.size() != 0) + { + if (Items[0]->Status == Item::StatFetching) + Items[0]->Status = Item::StatError; delete Items[0]; + } while (Queues != 0) { @@ -113,13 +115,15 @@ void pkgAcquire::Remove(Item *Itm) { 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++; } } /*}}}*/ @@ -186,9 +190,9 @@ void pkgAcquire::Enqueue(ItemDesc &Item) 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) { @@ -259,7 +263,11 @@ pkgAcquire::MethodConfig *pkgAcquire::GetConfig(string Access) Worker Work(Conf); if (Work.Start() == false) return 0; - + + /* if a method uses DownloadLimit, we switch to SingleInstance mode */ + if(_config->FindI("Acquire::"+Access+"::Dl-Limit",0) > 0) + Conf->SingleInstance = true; + return Conf; } /*}}}*/ @@ -306,7 +314,7 @@ void pkgAcquire::RunFds(fd_set *RSet,fd_set *WSet) /* 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; @@ -321,7 +329,7 @@ pkgAcquire::RunResult pkgAcquire::Run() // 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; @@ -351,7 +359,7 @@ pkgAcquire::RunResult pkgAcquire::Run() // 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) @@ -436,8 +444,9 @@ bool pkgAcquire::Clean(string Dir) unlink(Dir->d_name); }; - chdir(StartDir.c_str()); closedir(D); + if (chdir(StartDir.c_str()) != 0) + return _error->Errno("chdir",_("Unable to change to %s"),StartDir.c_str()); return true; } /*}}}*/ @@ -475,7 +484,7 @@ double pkgAcquire::PartialPresent() Total += (*I)->PartialSize; return Total; } - /*}}}*/ + // Acquire::UriBegin - Start iterator for the uri list /*{{{*/ // --------------------------------------------------------------------- /* */ @@ -538,11 +547,17 @@ pkgAcquire::Queue::~Queue() // 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; @@ -552,6 +567,7 @@ void pkgAcquire::Queue::Enqueue(ItemDesc &Item) Item.Owner->QueueCounter++; if (Items->Next == 0) Cycle(); + return true; } /*}}}*/ // Queue::Dequeue - Remove an item from the queue /*{{{*/ @@ -604,7 +620,7 @@ bool pkgAcquire::Queue::Startup() added other source retry to have cycle maintain a pipeline depth on its own. */ if (Cnf->Pipeline == true) - MaxPipeDepth = 10; + MaxPipeDepth = 1000; else MaxPipeDepth = 1; } @@ -781,7 +797,7 @@ bool pkgAcquireStatus::Pulse(pkgAcquire *Owner) // Compute the CPS struct timeval NewTime; gettimeofday(&NewTime,0); - if (NewTime.tv_sec - Time.tv_sec == 6 && NewTime.tv_usec > Time.tv_usec || + if ((NewTime.tv_sec - Time.tv_sec == 6 && NewTime.tv_usec > Time.tv_usec) || NewTime.tv_sec - Time.tv_sec > 6) { double Delta = NewTime.tv_sec - Time.tv_sec + @@ -797,6 +813,32 @@ bool pkgAcquireStatus::Pulse(pkgAcquire *Owner) 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; } /*}}}*/