summaryrefslogtreecommitdiffstats
path: root/src/util/db/dbconnectionpool.h
blob: 1ecfd8ed511f81f6aea81406aaa553dd13daeef6 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
#ifndef MIXXX_DBCONNECTIONPOOL_H
#define MIXXX_DBCONNECTIONPOOL_H


#include <QAtomicInt>
#include <QThreadStorage>

#include "util/db/dbconnection.h"
#include "util/memory.h"
#include "util/assert.h"


namespace mixxx {

class DbConnectionPool;
typedef std::shared_ptr<DbConnectionPool> DbConnectionPoolPtr;

class DbConnectionPool final {
  public:
    // Creates a new pool of database connections (one per thread) that
    // all use the same connection parameters. Unique connection names
    // will be generated based on the given connection name that serves
    // as the base name (= common prefix).
    static DbConnectionPoolPtr create(
            const DbConnection::Params& params,
            const QString& connectionName) {
        return std::make_shared<DbConnectionPool>(params, connectionName);
    }

    // NOTE(uklotzde): Should be private, but must be public for invocation
    // from std::make_shared()!
    DbConnectionPool(
            const DbConnection::Params& params,
            const QString& connectionName);

    // Prefer to use DbConnectionPooler instead of the
    // following functions. Only if there is no appropriate
    // scoping possible then use these functions directly.
    bool createThreadLocalConnection();
    void destroyThreadLocalConnection();

  private:
    DbConnectionPool(const DbConnectionPool&) = delete;
    DbConnectionPool(const DbConnectionPool&&) = delete;

    // Returns a database connection for the current thread, that has
    // previously been created by instantiating DbConnectionPooler. The
    // returned connection is only valid within the current thread! It
    // will be closed and removed from the pool upon the destruction of
    // the owning DbConnectionPooler or as a very last resort implicitly
    // when the current thread terminates. Since all connections need
    // to be created through DbConnectionPooler the latter case should
    // never happen.
    friend class DbConnectionPooled;
    const DbConnection* threadLocalConnection() const {
        return m_threadLocalConnections.localData();
    }

    const DbConnection m_prototypeConnection;

    QAtomicInt m_connectionCounter;

    QThreadStorage<DbConnection*> m_threadLocalConnections;

};

} // namespace mixxx


#endif // MIXXX_DBCONNECTIONPOOL_H