]>
git.saurik.com Git - apt.git/blob - apt-pkg/acquire.cc
1 // -*- mode: cpp; mode: fold -*-
3 // $Id: acquire.cc,v 1.3 1998/10/22 04:56:43 jgg Exp $
4 /* ######################################################################
6 Acquire - File Acquiration
8 The core element for the schedual system is the concept of a named
9 queue. Each queue is unique and each queue has a name derived from the
10 URI. The degree of paralization can be controled by how the queue
11 name is derived from the URI.
13 ##################################################################### */
15 // Include Files /*{{{*/
17 #pragma implementation "apt-pkg/acquire.h"
19 #include <apt-pkg/acquire.h>
20 #include <apt-pkg/acquire-item.h>
21 #include <apt-pkg/acquire-worker.h>
22 #include <apt-pkg/configuration.h>
23 #include <apt-pkg/error.h>
27 // Acquire::pkgAcquire - Constructor /*{{{*/
28 // ---------------------------------------------------------------------
30 pkgAcquire::pkgAcquire()
37 string Mode
= _config
->Find("Acquire::Queue-Mode","host");
38 if (strcasecmp(Mode
.c_str(),"host") == 0)
39 QueueMode
= QueueHost
;
40 if (strcasecmp(Mode
.c_str(),"access") == 0)
41 QueueMode
= QueueAccess
;
43 Debug
= _config
->FindB("Debug::pkgAcquire",false);
46 // Acquire::~pkgAcquire - Destructor /*{{{*/
47 // ---------------------------------------------------------------------
49 pkgAcquire::~pkgAcquire()
51 while (Items
.size() != 0)
56 MethodConfig
*Jnk
= Configs
;
57 Configs
= Configs
->Next
;
64 Queues
= Queues
->Next
;
69 // Acquire::Add - Add a new item /*{{{*/
70 // ---------------------------------------------------------------------
72 void pkgAcquire::Add(Item
*Itm
)
77 // Acquire::Remove - Remove a item /*{{{*/
78 // ---------------------------------------------------------------------
80 void pkgAcquire::Remove(Item
*Itm
)
82 for (vector
<Item
*>::iterator I
= Items
.begin(); I
< Items
.end(); I
++)
89 // Acquire::Add - Add a worker /*{{{*/
90 // ---------------------------------------------------------------------
92 void pkgAcquire::Add(Worker
*Work
)
94 Work
->NextAcquire
= Workers
;
98 // Acquire::Remove - Remove a worker /*{{{*/
99 // ---------------------------------------------------------------------
101 void pkgAcquire::Remove(Worker
*Work
)
103 Worker
**I
= &Workers
;
107 *I
= (*I
)->NextAcquire
;
109 I
= &(*I
)->NextAcquire
;
113 // Acquire::Enqueue - Queue an URI for fetching /*{{{*/
114 // ---------------------------------------------------------------------
116 void pkgAcquire::Enqueue(Item
*Itm
,string URI
,string Description
)
118 // Determine which queue to put the item in
119 string Name
= QueueName(URI
);
120 if (Name
.empty() == true)
123 // Find the queue structure
125 for (; I
!= 0 && I
->Name
!= Name
; I
= I
->Next
);
128 I
= new Queue(Name
,this);
133 // Queue it into the named queue
134 I
->Enqueue(Itm
,URI
,Description
);
140 clog
<< "Fetching " << URI
<< endl
;
141 clog
<< " to " << Itm
->DestFile
<< endl
;
142 clog
<< " Queue is: " << QueueName(URI
) << endl
;
146 // Acquire::Dequeue - Remove an item from all queues /*{{{*/
147 // ---------------------------------------------------------------------
149 void pkgAcquire::Dequeue(Item
*Itm
)
152 for (; I
!= 0; I
= I
->Next
)
157 // Acquire::QueueName - Return the name of the queue for this URI /*{{{*/
158 // ---------------------------------------------------------------------
159 /* The string returned depends on the configuration settings and the
160 method parameters. Given something like http://foo.org/bar it can
161 return http://foo.org or http */
162 string
pkgAcquire::QueueName(string URI
)
164 const MethodConfig
*Config
= GetConfig(URIAccess(URI
));
168 /* Single-Instance methods get exactly one queue per URI. This is
169 also used for the Access queue method */
170 if (Config
->SingleInstance
== true || QueueMode
== QueueAccess
)
171 return URIAccess(URI
);
174 string::iterator I
= URI
.begin();
175 for (; I
< URI
.end() && *I
!= ':'; I
++);
176 for (; I
< URI
.end() && (*I
== '/' || *I
== ':'); I
++);
177 for (; I
< URI
.end() && *I
!= '/'; I
++);
179 return string(URI
,0,I
- URI
.begin());
182 // Acquire::GetConfig - Fetch the configuration information /*{{{*/
183 // ---------------------------------------------------------------------
184 /* This locates the configuration structure for an access method. If
185 a config structure cannot be found a Worker will be created to
187 pkgAcquire::MethodConfig
*pkgAcquire::GetConfig(string Access
)
189 // Search for an existing config
191 for (Conf
= Configs
; Conf
!= 0; Conf
= Conf
->Next
)
192 if (Conf
->Access
== Access
)
195 // Create the new config class
196 Conf
= new MethodConfig
;
197 Conf
->Access
= Access
;
198 Conf
->Next
= Configs
;
201 // Create the worker to fetch the configuration
203 if (Work
.Start() == false)
209 // Acquire::SetFds - Deal with readable FDs /*{{{*/
210 // ---------------------------------------------------------------------
211 /* Collect FDs that have activity monitors into the fd sets */
212 void pkgAcquire::SetFds(int &Fd
,fd_set
*RSet
,fd_set
*WSet
)
214 for (Worker
*I
= Workers
; I
!= 0; I
= I
->NextAcquire
)
216 if (I
->InReady
== true && I
->InFd
>= 0)
220 FD_SET(I
->InFd
,RSet
);
222 if (I
->OutReady
== true && I
->OutFd
>= 0)
226 FD_SET(I
->OutFd
,WSet
);
231 // Acquire::RunFds - Deal with active FDs /*{{{*/
232 // ---------------------------------------------------------------------
233 /* Dispatch active FDs over to the proper workers */
234 void pkgAcquire::RunFds(fd_set
*RSet
,fd_set
*WSet
)
236 for (Worker
*I
= Workers
; I
!= 0; I
= I
->NextAcquire
)
238 if (I
->InFd
>= 0 && FD_ISSET(I
->InFd
,RSet
) != 0)
240 if (I
->OutFd
>= 0 && FD_ISSET(I
->OutFd
,WSet
) != 0)
245 // Acquire::Run - Run the fetch sequence /*{{{*/
246 // ---------------------------------------------------------------------
247 /* This runs the queues. It manages a select loop for all of the
248 Worker tasks. The workers interact with the queues and items to
249 manage the actual fetch. */
250 bool pkgAcquire::Run()
252 for (Queue
*I
= Queues
; I
!= 0; I
= I
->Next
)
255 // Run till all things have been acquired
263 SetFds(Highest
,&RFds
,&WFds
);
265 if (select(Highest
+1,&RFds
,&WFds
,0,0) <= 0)
266 return _error
->Errno("select","Select has failed");
271 for (Queue
*I
= Queues
; I
!= 0; I
= I
->Next
)
278 // Acquire::MethodConfig::MethodConfig - Constructor /*{{{*/
279 // ---------------------------------------------------------------------
281 pkgAcquire::MethodConfig::MethodConfig()
283 SingleInstance
= false;
291 // Queue::Queue - Constructor /*{{{*/
292 // ---------------------------------------------------------------------
294 pkgAcquire::Queue::Queue(string Name
,pkgAcquire
*Owner
) : Name(Name
),
302 // Queue::~Queue - Destructor /*{{{*/
303 // ---------------------------------------------------------------------
305 pkgAcquire::Queue::~Queue()
317 // Queue::Enqueue - Queue an item to the queue /*{{{*/
318 // ---------------------------------------------------------------------
320 void pkgAcquire::Queue::Enqueue(Item
*Owner
,string URI
,string Description
)
323 QItem
*I
= new QItem
;
328 Items
->Owner
= Owner
;
330 Items
->Description
= Description
;
331 Owner
->QueueCounter
++;
334 // Queue::Dequeue - Remove and item from the queue /*{{{*/
335 // ---------------------------------------------------------------------
337 void pkgAcquire::Queue::Dequeue(Item
*Owner
)
342 if ((*I
)->Owner
== Owner
)
346 Owner
->QueueCounter
--;
354 // Queue::Startup - Start the worker processes /*{{{*/
355 // ---------------------------------------------------------------------
357 bool pkgAcquire::Queue::Startup()
361 pkgAcquire::MethodConfig
*Cnf
= Owner
->GetConfig(URIAccess(Name
));
365 Workers
= new Worker(this,Cnf
);
367 if (Workers
->Start() == false)
370 Workers
->QueueItem(Items
);
375 // Queue::Shutdown - Shutdown the worker processes /*{{{*/
376 // ---------------------------------------------------------------------
378 bool pkgAcquire::Queue::Shutdown()
380 // Delete all of the workers
383 pkgAcquire::Worker
*Jnk
= Workers
;
384 Workers
= Workers
->NextQueue
;