X-Git-Url: https://git.saurik.com/apt.git/blobdiff_plain/a656821931a863ffcf46a719a57206eb0d2b11b3..7049d16d301fc4a26f27d3cd39c95a01003aabb6:/apt-pkg/acquire.cc diff --git a/apt-pkg/acquire.cc b/apt-pkg/acquire.cc index 9a546c7e2..80624f9d3 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.15 1998/11/13 07:08:54 jgg Exp $ +// $Id: acquire.cc,v 1.29 1999/03/16 00:43:55 jgg Exp $ /* ###################################################################### Acquire - File Acquiration @@ -21,7 +21,7 @@ #include #include #include -#include +#include #include #include @@ -130,7 +130,8 @@ void pkgAcquire::Remove(Worker *Work) void pkgAcquire::Enqueue(ItemDesc &Item) { // Determine which queue to put the item in - string Name = QueueName(Item.URI); + const MethodConfig *Config; + string Name = QueueName(Item.URI,Config); if (Name.empty() == true) return; @@ -147,6 +148,9 @@ void pkgAcquire::Enqueue(ItemDesc &Item) I->Startup(); } + // See if this is a local only URI + if (Config->LocalOnly == true && Item.Owner->Complete == false) + Item.Owner->Local = true; Item.Owner->Status = Item::StatIdle; // Queue it into the named queue @@ -158,7 +162,7 @@ void pkgAcquire::Enqueue(ItemDesc &Item) { clog << "Fetching " << Item.URI << endl; clog << " to " << Item.Owner->DestFile << endl; - clog << " Queue is: " << QueueName(Item.URI) << endl; + clog << " Queue is: " << Name << endl; } } /*}}}*/ @@ -184,11 +188,11 @@ void pkgAcquire::Dequeue(Item *Itm) /* The string returned depends on the configuration settings and the method parameters. Given something like http://foo.org/bar it can return http://foo.org or http */ -string pkgAcquire::QueueName(string Uri) +string pkgAcquire::QueueName(string Uri,MethodConfig const *&Config) { URI U(Uri); - const MethodConfig *Config = GetConfig(U.Access); + Config = GetConfig(U.Access); if (Config == 0) return string(); @@ -293,7 +297,13 @@ bool pkgAcquire::Run() FD_ZERO(&WFds); SetFds(Highest,&RFds,&WFds); - int Res = select(Highest+1,&RFds,&WFds,0,&tv); + int Res; + do + { + Res = select(Highest+1,&RFds,&WFds,0,&tv); + } + while (Res < 0 && errno == EINTR); + if (Res < 0) { _error->Errno("select","Select has failed"); @@ -386,18 +396,6 @@ bool pkgAcquire::Clean(string Dir) return true; } /*}}}*/ -// Acquire::MethodConfig::MethodConfig - Constructor /*{{{*/ -// --------------------------------------------------------------------- -/* */ -pkgAcquire::MethodConfig::MethodConfig() -{ - SingleInstance = false; - PreScan = false; - Pipeline = false; - SendConfig = false; - Next = 0; -} - /*}}}*/ // Acquire::TotalNeeded - Number of bytes to fetch /*{{{*/ // --------------------------------------------------------------------- /* This is the total number of bytes needed */ @@ -421,6 +419,35 @@ unsigned long pkgAcquire::FetchNeeded() return Total; } /*}}}*/ +// pkgAcquire::UriBegin - Start iterator for the uri list /*{{{*/ +// --------------------------------------------------------------------- +/* */ +pkgAcquire::UriIterator pkgAcquire::UriBegin() +{ + return UriIterator(Queues); +} + /*}}}*/ +// pkgAcquire::UriEnd - End iterator for the uri list /*{{{*/ +// --------------------------------------------------------------------- +/* */ +pkgAcquire::UriIterator pkgAcquire::UriEnd() +{ + return UriIterator(0); +} + /*}}}*/ + +// Acquire::MethodConfig::MethodConfig - Constructor /*{{{*/ +// --------------------------------------------------------------------- +/* */ +pkgAcquire::MethodConfig::MethodConfig() +{ + SingleInstance = false; + Pipeline = false; + SendConfig = false; + LocalOnly = false; + Next = 0; +} + /*}}}*/ // Queue::Queue - Constructor /*{{{*/ // --------------------------------------------------------------------- @@ -431,6 +458,8 @@ pkgAcquire::Queue::Queue(string Name,pkgAcquire *Owner) : Name(Name), Items = 0; Next = 0; Workers = 0; + MaxPipeDepth = 1; + PipeDepth = 0; } /*}}}*/ // Queue::~Queue - Destructor /*{{{*/ @@ -453,11 +482,14 @@ pkgAcquire::Queue::~Queue() /* */ void pkgAcquire::Queue::Enqueue(ItemDesc &Item) { + QItem **I = &Items; + for (; *I != 0; I = &(*I)->Next); + // Create a new item - QItem *I = new QItem; - I->Next = Items; - Items = I; - *I = Item; + QItem *Itm = new QItem; + *Itm = Item; + Itm->Next = 0; + *I = Itm; Item.Owner->QueueCounter++; if (Items->Next == 0) @@ -466,9 +498,12 @@ void pkgAcquire::Queue::Enqueue(ItemDesc &Item) /*}}}*/ // Queue::Dequeue - Remove an item from the queue /*{{{*/ // --------------------------------------------------------------------- -/* We return true if we hit something*/ +/* We return true if we hit something */ bool pkgAcquire::Queue::Dequeue(Item *Owner) { + if (Owner->Status == pkgAcquire::Item::StatFetching) + return _error->Error("Tried to dequeue a fetching object"); + bool Res = false; QItem **I = &Items; @@ -506,6 +541,14 @@ bool pkgAcquire::Queue::Startup() if (Workers->Start() == false) return false; + /* When pipelining we commit 10 items. This needs to change when we + added other source retry to have cycle maintain a pipeline depth + on its own. */ + if (Cnf->Pipeline == true) + MaxPipeDepth = 10; + else + MaxPipeDepth = 1; + return Cycle(); } /*}}}*/ @@ -526,7 +569,7 @@ bool pkgAcquire::Queue::Shutdown() return true; } /*}}}*/ -// Queue::Finditem - Find a URI in the item list /*{{{*/ +// Queue::FindItem - Find a URI in the item list /*{{{*/ // --------------------------------------------------------------------- /* */ pkgAcquire::Queue::QItem *pkgAcquire::Queue::FindItem(string URI,pkgAcquire::Worker *Owner) @@ -544,6 +587,10 @@ pkgAcquire::Queue::QItem *pkgAcquire::Queue::FindItem(string URI,pkgAcquire::Wor main queue too.*/ bool pkgAcquire::Queue::ItemDone(QItem *Itm) { + PipeDepth--; + if (Itm->Owner->Status == pkgAcquire::Item::StatFetching) + Itm->Owner->Status = pkgAcquire::Item::StatDone; + if (Itm->Owner->QueueCounter <= 1) Owner->Dequeue(Itm->Owner); else @@ -557,32 +604,44 @@ bool pkgAcquire::Queue::ItemDone(QItem *Itm) /*}}}*/ // Queue::Cycle - Queue new items into the method /*{{{*/ // --------------------------------------------------------------------- -/* This locates a new idle item and sends it to the worker */ +/* This locates a new idle item and sends it to the worker. If pipelining + is enabled then it keeps the pipe full. */ bool pkgAcquire::Queue::Cycle() { if (Items == 0 || Workers == 0) return true; + if (PipeDepth < 0) + return _error->Error("Pipedepth failure"); + // Look for a queable item QItem *I = Items; - for (; I != 0; I = I->Next) - if (I->Owner->Status == pkgAcquire::Item::StatIdle) - break; - - // Nothing to do, queue is idle. - if (I == 0) - return true; + while (PipeDepth < (signed)MaxPipeDepth) + { + for (; I != 0; I = I->Next) + if (I->Owner->Status == pkgAcquire::Item::StatIdle) + break; + + // Nothing to do, queue is idle. + if (I == 0) + return true; + + I->Worker = Workers; + I->Owner->Status = pkgAcquire::Item::StatFetching; + PipeDepth++; + if (Workers->QueueItem(I) == false) + return false; + } - I->Worker = Workers; - I->Owner->Status = pkgAcquire::Item::StatFetching; - return Workers->QueueItem(I); + return true; } /*}}}*/ // Queue::Bump - Fetch any pending objects if we are idle /*{{{*/ // --------------------------------------------------------------------- -/* */ +/* This is called when an item in multiple queues is dequeued */ void pkgAcquire::Queue::Bump() { + Cycle(); } /*}}}*/ @@ -603,6 +662,8 @@ void pkgAcquireStatus::Pulse(pkgAcquire *Owner) { TotalBytes = 0; CurrentBytes = 0; + TotalItems = 0; + CurrentItems = 0; // Compute the total number of bytes to fetch unsigned int Unknown = 0; @@ -610,6 +671,10 @@ void pkgAcquireStatus::Pulse(pkgAcquire *Owner) for (pkgAcquire::Item **I = Owner->ItemsBegin(); I != Owner->ItemsEnd(); I++, Count++) { + TotalItems++; + if ((*I)->Status == pkgAcquire::Item::StatDone) + CurrentItems++; + // Totally ignore local items if ((*I)->Local == true) continue; @@ -641,21 +706,16 @@ void pkgAcquireStatus::Pulse(pkgAcquire *Owner) if (NewTime.tv_sec - Time.tv_sec == 6 && NewTime.tv_usec > Time.tv_usec || NewTime.tv_sec - Time.tv_sec > 6) { - // Compute the delta time with full accuracy - long usdiff = NewTime.tv_usec - Time.tv_usec; - long sdiff = NewTime.tv_sec - Time.tv_sec; + double Delta = NewTime.tv_sec - Time.tv_sec + + (NewTime.tv_usec - Time.tv_usec)/1000000.0; - // Borrow - if (usdiff < 0) - { - usdiff += 1000000; - sdiff--; - } - // Compute the CPS value - CurrentCPS = (CurrentBytes - LastBytes)/(sdiff + usdiff/1000000.0); + if (Delta < 0.01) + CurrentCPS = 0; + else + CurrentCPS = (CurrentBytes - LastBytes)/Delta; LastBytes = CurrentBytes; - ElapsedTime = NewTime.tv_sec - StartTime.tv_sec; + ElapsedTime = (unsigned long)Delta; Time = NewTime; } } @@ -673,6 +733,8 @@ void pkgAcquireStatus::Start() TotalBytes = 0; FetchedBytes = 0; ElapsedTime = 0; + TotalItems = 0; + CurrentItems = 0; } /*}}}*/ // AcquireStatus::Stop - Finished downloading /*{{{*/ @@ -694,9 +756,12 @@ void pkgAcquireStatus::Stop() usdiff += 1000000; sdiff--; } - + // Compute the CPS value - CurrentCPS = FetchedBytes/(sdiff + usdiff/1000000.0); + if (sdiff == 0 && usdiff == 0) + CurrentCPS = 0; + else + CurrentCPS = FetchedBytes/(sdiff + usdiff/1000000.0); LastBytes = CurrentBytes; ElapsedTime = sdiff; }