#include "printing/backend/cups_connection_pool.h"
#include <cups/cups.h>
#include "base/check.h"
#include "base/containers/queue.h"
#include "base/logging.h"
#include "base/sequence_checker.h"
#include "printing/backend/cups_connection.h"
#include "printing/backend/cups_deleters.h"
#include "printing/backend/cups_helper.h"
namespace printing {
namespace {
constexpr int kNumCupsConnections = 5;
CupsConnectionPool* g_cups_connection_pool_singleton = nullptr;
}
CupsConnectionPool::CupsConnectionPool() = default;
CupsConnectionPool::~CupsConnectionPool() = default;
void CupsConnectionPool::Create() {
DCHECK(!g_cups_connection_pool_singleton);
const int port = ippPort();
const char* server = cupsServer();
g_cups_connection_pool_singleton = new CupsConnectionPool();
VLOG(1) << "Creating CUPS connection pool seeded with " << kNumCupsConnections
<< " connections";
for (auto i = 0; i < kNumCupsConnections; ++i) {
ScopedHttpPtr connection = HttpConnect2(
server, port, nullptr, AF_UNSPEC, HTTP_ENCRYPTION_NEVER,
0, kCupsTimeoutMs, nullptr);
if (!connection) {
LOG(ERROR) << "Unable to create CUPS connection: "
<< cupsLastErrorString();
break;
}
g_cups_connection_pool_singleton->AddConnection(std::move(connection));
}
}
CupsConnectionPool* CupsConnectionPool::GetInstance() {
return g_cups_connection_pool_singleton;
}
ScopedHttpPtr CupsConnectionPool::TakeConnection() {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
if (connections_.empty())
return nullptr;
ScopedHttpPtr connection = std::move(connections_.front());
connections_.pop();
return connection;
}
void CupsConnectionPool::AddConnection(ScopedHttpPtr connection) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
DCHECK(connection);
connections_.emplace(std::move(connection));
}
}