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 }