00001
00002
00003
00004
00005
00006 #include "mythhttppool.h"
00007 #include "mythhttphandler.h"
00008 #include "mythlogging.h"
00009
00010 #define LOC QString("MythHttpPool: ")
00011
00012 MythHttpPool *MythHttpPool::singleton;
00013
00014 MythHttpPool::MythHttpPool(uint max_connections) :
00015 m_maxConnections(max_connections)
00016 {
00017 }
00018
00019 MythHttpPool::~MythHttpPool()
00020 {
00021 while (!m_hostToHandler.empty())
00022 {
00023 HostToHandler::iterator it = m_hostToHandler.begin();
00024 MythHttpHandler *h = *it;
00025 m_hostToHandler.erase(it);
00026 h->deleteLater();
00027 }
00028 }
00029
00030 void MythHttpPool::AddUrlRequest(const QUrl &url, MythHttpListener *listener)
00031 {
00032 QMutexLocker locker(&m_lock);
00033
00034 LOG(VB_NETWORK, LOG_DEBUG, LOC + QString("AddUrlRequest(%1, 0x%2)")
00035 .arg(url.toString()).arg((quint64)listener,0,16));
00036
00037 bool in_queue = m_urlToListener.find(url) != m_urlToListener.end();
00038
00039 m_urlToListener.insert(url, listener);
00040 set<MythHttpListener*>::iterator lit = m_listeners.find(listener);
00041 if (lit == m_listeners.end())
00042 m_listeners.insert(listener);
00043
00044 if (in_queue)
00045 return;
00046
00047 HostToHandler::iterator it = m_hostToHandler.find(url.host());
00048
00049 if (it != m_hostToHandler.end())
00050 {
00051 (*it)->AddUrlRequest(url);
00052 }
00053 else if ((uint)m_hostToHandler.size() < m_maxConnections)
00054 {
00055 MythHttpHandler *hh = new MythHttpHandler(this);
00056 m_hostToHandler[url.host()] = hh;
00057 hh->AddUrlRequest(url);
00058 }
00059 else
00060 {
00061 HostToHandler::iterator it = m_hostToHandler.begin();
00062 for (; it != m_hostToHandler.end(); ++it)
00063 {
00064 if (!(*it)->HasPendingRequests())
00065 break;
00066 }
00067 if (it != m_hostToHandler.end())
00068 {
00069 MythHttpHandler *hh = *it;
00070 m_hostToHandler.erase(it);
00071 m_hostToHandler[url.host()] = hh;
00072 hh->AddUrlRequest(url);
00073 }
00074 else
00075 {
00076 m_httpQueue.push_back(HttpRequest(url,listener));
00077 }
00078 }
00079 }
00080
00081 void MythHttpPool::RemoveUrlRequest(const QUrl &url, MythHttpListener *listener)
00082 {
00083 QMutexLocker locker(&m_lock);
00084
00085 LOG(VB_NETWORK, LOG_DEBUG, LOC + QString("RemoveUrlRequest(%1, 0x%2)")
00086 .arg(url.toString()).arg((quint64)listener,0,16));
00087 }
00088
00089 void MythHttpPool::RemoveListener(MythHttpListener *listener)
00090 {
00091 QMutexLocker locker(&m_lock);
00092
00093 LOG(VB_NETWORK, LOG_DEBUG, LOC + QString("RemoveListener(0x%1)")
00094 .arg((quint64)listener,0,16));
00095 set<MythHttpListener*>::iterator it = m_listeners.find(listener);
00096 if (it != m_listeners.end())
00097 m_listeners.erase(it);
00098 }
00099
00100 void MythHttpPool::Update(QHttp::Error error,
00101 const QString &error_str,
00102 const QUrl &url,
00103 uint http_status_id,
00104 const QString &http_status_str,
00105 const QByteArray &data)
00106 {
00107 QMutexLocker locker(&m_lock);
00108
00109 UrlToListener::iterator it = m_urlToListener.find(url);
00110 for (; (it != m_urlToListener.end()) && (it.key() == url); ++it)
00111 {
00112 if (m_listeners.find(*it) != m_listeners.end())
00113 {
00114 (*it)->Update(error, error_str, url,
00115 http_status_id, http_status_str,
00116 data);
00117 }
00118 }
00119
00120 m_urlToListener.remove(url);
00121 }
00122
00123 void MythHttpPool::Done(const QString &host, MythHttpHandler *handler)
00124 {
00125 QMutexLocker locker(&m_lock);
00126
00127 LOG(VB_NETWORK, LOG_DEBUG, LOC + QString("Done(%1, 0x%2)")
00128 .arg(host).arg((quint64)handler,0,16));
00129
00130 HostToHandler::iterator it = m_hostToHandler.find(host);
00131 if (handler != *it)
00132 {
00133 LOG(VB_GENERAL, LOG_ERR, LOC + QString("Done(%1, 0x%2)")
00134 .arg(host).arg((quint64)handler,0,16));
00135 return;
00136 }
00137
00138 while (!m_httpQueue.empty())
00139 {
00140 QUrl url = m_httpQueue.front().m_url;
00141 MythHttpListener *listener = m_httpQueue.front().m_listener;
00142 m_httpQueue.pop_front();
00143
00144 if (m_listeners.find(listener) == m_listeners.end())
00145 continue;
00146
00147 if (url.host() != host)
00148 {
00149 m_hostToHandler.erase(it);
00150 m_hostToHandler[url.host()] = handler;
00151 }
00152 handler->AddUrlRequest(url);
00153 break;
00154 }
00155 }
00156
00157 MythHttpPool *MythHttpPool::GetSingleton()
00158 {
00159 static QMutex lock;
00160 QMutexLocker locker(&lock);
00161 if (!singleton)
00162 singleton = new MythHttpPool();
00163 return singleton;
00164 }