예제 #1
0
  public void run() {
    // Create a file channel for the file
    try {
      _parent.addToActive(this);
      file = new RandomAccessFile(Globals.ourHome + outFile, "rwd");
      channel = file.getChannel();

      // Create a segment downloader for each segment and run them simultaneously
      for (int i = 0; i < nSeg; i++) {
        segDownloads.add(new SegDownloader(this, peers.get(i % peers.size()) + "/" + path, i));
        (new Thread(segDownloads.get(segDownloads.size() - 1))).start();
      }

      // Wait for a download thread to either finish or fail, and update our bookkeeping
      try {
        while (!done) {
          // Get a new segment downloader off the stopped list.
          SegDownloader s = bstopped.take();

          // Give a new path to every download thread that failed.
          if (s.status() == Dstatus.FAILED) {
            synchronized (s) {
              s.dlPath = getNewPath();
              removeStopped(s);
              s.notify();
            }
          }

          // Check if that segment finishes off the download.
          else if (s.status() == Dstatus.FINISHED) {
            if (nSeg == doneSegs) {
              done = true;
              percentDone = 100;
              System.out.println("Download " + Globals.ourHome + outFile + " Finished!");

              // "Notify" the waiters that we're done.
              while (waiters > 0 && waitToken.take()) {
                waiters--;
              }
            }
          } else throw new RuntimeException("Impossible");
        }
      } catch (InterruptedException e) {
        status = Dstatus.FAILED;
      }

    } catch (IOException e) {
      Log.info("Could not open file for download!");
      status = Dstatus.FAILED;
    } catch (InterruptedException e) {
      // TODO Auto-generated catch block
      status = Dstatus.FAILED;
    }
  }
예제 #2
0
 public void removeActive(SegDownloader s) {
   try {
     if (doneSegs < nSeg) active.take();
   } catch (InterruptedException e) {
     // Nothing
   }
 }
예제 #3
0
 // Only call this from a downloader thread.
 //	If the active queue is full, the downloader will
 //	block until a spot frees up.
 public void addActive(SegDownloader s) {
   try {
     active.put(s);
   } catch (InterruptedException e) {
     // TODO Auto-generated catch block
     e.printStackTrace();
   }
 }
예제 #4
0
 public synchronized void addStopped(SegDownloader s) {
   try {
     bstopped.put(s);
   } catch (InterruptedException e) {
     // TODO Auto-generated catch block
     e.printStackTrace();
   }
 }
예제 #5
0
 // Wait on this download to finish. Implemented by trying to push something to the
 //	blocking queue. Since the pusher waits until the queue has space, only empty
 //	the queue if the download is finished.
 public void waitForMe() {
   waiters++;
   try {
     waitToken.put(true);
   } catch (InterruptedException e) {
     // TODO Auto-generated catch block
     e.printStackTrace();
   }
 }
예제 #6
0
  ChunkDownload(
      String dpath, String output, List<String> recentPeers, int segments, Download parent) {
    done = false;
    path = dpath;
    nSeg = segments;
    peers = recentPeers;
    segFin = new boolean[nSeg];
    doneSegs = 0;
    status = Dstatus.DOWNLOADING;
    outFile = output;
    _parent = parent;

    segDownloads = new ArrayList<SegDownloader>(segments);
    bstopped = new ArrayBlockingQueue<SegDownloader>(segments);
    active = new ArrayBlockingQueue<SegDownloader>(maxThreads);

    // Helping variables to allow a thread to blocking wait on this download.
    waitToken = new ArrayBlockingQueue<Boolean>(1);
    waitToken.add(true);
    waiters = 0;

    percentDone = 0;
  }
예제 #7
0
 public synchronized void removeStopped(SegDownloader s) {
   bstopped.remove(s);
 }