File indexing completed on 2025-01-05 04:37:19

0001 /*
0002     SPDX-FileCopyrightText: 2005 Joris Guisson <joris.guisson@gmail.com>
0003 
0004     SPDX-License-Identifier: GPL-2.0-or-later
0005 */
0006 #include "downloadthread.h"
0007 #include "socketgroup.h"
0008 #include "socketmonitor.h"
0009 #include "trafficshapedsocket.h"
0010 #include "wakeuppipe.h"
0011 #include <QtGlobal>
0012 #include <math.h>
0013 #include <util/functions.h>
0014 #include <util/log.h>
0015 
0016 using namespace bt;
0017 
0018 namespace net
0019 {
0020 Uint32 DownloadThread::dcap = 0;
0021 Uint32 DownloadThread::sleep_time = 50;
0022 
0023 DownloadThread::DownloadThread(SocketMonitor *sm)
0024     : NetworkThread(sm)
0025     , wake_up(new WakeUpPipe())
0026 {
0027 }
0028 
0029 DownloadThread::~DownloadThread()
0030 {
0031 }
0032 
0033 void DownloadThread::update()
0034 {
0035     if (waitForSocketReady() > 0) {
0036         bool group_limits = false;
0037         sm->lock();
0038 
0039         TimeStamp now = bt::Now();
0040         Uint32 num_ready = 0;
0041         SocketMonitor::Itr itr = sm->begin();
0042         while (itr != sm->end()) {
0043             TrafficShapedSocket *s = *itr;
0044             if (!s->socketDevice()) {
0045                 ++itr;
0046                 continue;
0047             }
0048 
0049             if (s->socketDevice()->ready(this, Poll::INPUT)) {
0050                 // add to the correct group
0051                 Uint32 gid = s->downloadGroupID();
0052                 if (gid > 0)
0053                     group_limits = true;
0054 
0055                 SocketGroup *g = groups.find(gid);
0056                 if (!g)
0057                     g = groups.find(0);
0058 
0059                 g->add(s);
0060                 num_ready++;
0061             }
0062             ++itr;
0063         }
0064 
0065         if (num_ready > 0)
0066             doGroups(num_ready, now, dcap);
0067         sm->unlock();
0068 
0069         // to prevent huge CPU usage sleep a bit if we are limited (either by a global limit or a group limit)
0070         if (dcap > 0 || group_limits) {
0071             TimeStamp diff = now - prev_run_time;
0072             if (diff < sleep_time)
0073                 msleep(sleep_time - diff);
0074         }
0075         prev_run_time = now;
0076     }
0077 }
0078 
0079 void DownloadThread::setSleepTime(Uint32 stime)
0080 {
0081     sleep_time = stime;
0082 }
0083 
0084 bool DownloadThread::doGroup(SocketGroup *g, Uint32 &allowance, bt::TimeStamp now)
0085 {
0086     return g->download(allowance, now);
0087 }
0088 
0089 int DownloadThread::waitForSocketReady()
0090 {
0091     sm->lock();
0092 
0093     reset();
0094     // Add the wake up pipe
0095     add(qSharedPointerCast<PollClient>(wake_up));
0096 
0097     // fill the poll vector with all sockets
0098     SocketMonitor::Itr itr = sm->begin();
0099     while (itr != sm->end()) {
0100         TrafficShapedSocket *s = *itr;
0101         if (s && s->socketDevice()) {
0102             s->socketDevice()->prepare(this, Poll::INPUT);
0103         }
0104         ++itr;
0105     }
0106     sm->unlock();
0107     return poll();
0108 }
0109 
0110 void DownloadThread::wakeUp()
0111 {
0112     wake_up->wakeUp();
0113 }
0114 }