code: def task_done (self, url_data):
          
          with self.all_tasks_done:
              log.debug(LOG_CACHE, "task_done %s", url_data.url)
              self.finished_tasks += 1
              self.unfinished_tasks -= 1
              self.in_progress -= 1
              if self.unfinished_tasks <= 0:
                  if self.unfinished_tasks < 0:
                      raise ValueError('task_done() called too many times')
                  self.all_tasks_done.notifyAll()
docs: Indicate that a formerly enqueued task is complete.
  
          Used by Queue consumer threads.  For each get() used to fetch a task,
          a subsequent call to task_done() tells the queue that the processing
          on the task is complete.
  
          If a join() is currently blocking, it will resume when all items
          have been processed (meaning that a task_done() call was received
          for every item that had been put() into the queue).
  
          Raises a ValueError if called more times than there were items
          placed in the queue.