1/* -*- c-basic-offset: 2 -*- */
2/*
3 Copyright(C) 2015 Kouhei Sutou <kou@clear-code.com>
4
5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
9
10 This library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
14
15 You should have received a copy of the GNU Lesser General Public
16 License along with this library; if not, write to the Free Software
17 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18*/
19
20#include "mrn_context_pool.hpp"
21#include "mrn_lock.hpp"
22
23#include <time.h>
24
25namespace mrn {
26 // for debug
27#define MRN_CLASS_NAME "mrn::ContextPool::Impl"
28
29 class ContextPool::Impl {
30 public:
31 Impl(mysql_mutex_t *mutex)
32 : mutex_(mutex),
33 pool_(NULL),
34 last_pull_time_(0) {
35 }
36
37 ~Impl(void) {
38 clear();
39 }
40
41 grn_ctx *pull(void) {
42 MRN_DBUG_ENTER_METHOD();
43 grn_ctx *ctx = NULL;
44
45 {
46 time_t now;
47 time(&now);
48
49 mrn::Lock lock(mutex_);
50 if (pool_) {
51 ctx = static_cast<grn_ctx *>(pool_->data);
52 list_pop(pool_);
53 if ((uint) (now - last_pull_time_) >= CLEAR_THREATHOLD_IN_SECONDS) {
54 clear();
55 }
56 }
57 last_pull_time_ = now;
58 }
59
60 if (!ctx) {
61 ctx = grn_ctx_open(0);
62 }
63
64 DBUG_RETURN(ctx);
65 }
66
67 void release(grn_ctx *ctx) {
68 MRN_DBUG_ENTER_METHOD();
69
70 {
71 mrn::Lock lock(mutex_);
72 list_push(pool_, ctx);
73 grn_ctx_use(ctx, NULL);
74 }
75
76 DBUG_VOID_RETURN;
77 }
78
79 private:
80 static const unsigned int CLEAR_THREATHOLD_IN_SECONDS = 60 * 5;
81
82 mysql_mutex_t *mutex_;
83 LIST *pool_;
84 time_t last_pull_time_;
85
86 void clear(void) {
87 MRN_DBUG_ENTER_METHOD();
88 while (pool_) {
89 grn_ctx *ctx = static_cast<grn_ctx *>(pool_->data);
90 grn_ctx_close(ctx);
91 list_pop(pool_);
92 }
93 DBUG_VOID_RETURN;
94 }
95 };
96
97 // For debug
98#undef MRN_CLASS_NAME
99#define MRN_CLASS_NAME "mrn::ContextPool"
100
101 ContextPool::ContextPool(mysql_mutex_t *mutex)
102 : impl_(new Impl(mutex)) {
103 }
104
105 ContextPool::~ContextPool(void) {
106 delete impl_;
107 }
108
109 grn_ctx *ContextPool::pull(void) {
110 MRN_DBUG_ENTER_METHOD();
111 grn_ctx *ctx = impl_->pull();
112 DBUG_RETURN(ctx);
113 }
114
115 void ContextPool::release(grn_ctx *ctx) {
116 MRN_DBUG_ENTER_METHOD();
117 impl_->release(ctx);
118 DBUG_VOID_RETURN;
119 }
120}
121