~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/table/cache.cc

  • Committer: Andrew Hutchings
  • Date: 2011-02-01 10:23:22 UTC
  • mto: (2136.1.1 build)
  • mto: This revision was merged to the branch mainline in revision 2137.
  • Revision ID: andrew@linuxjedi.co.uk-20110201102322-oxztcyrjzg3c7yta
Fix counters cleanup

Show diffs side-by-side

added added

removed removed

Lines of Context:
18
18
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
19
19
 */
20
20
 
21
 
#include <config.h>
22
 
#include <drizzled/table/cache.h>
 
21
#include "config.h"
23
22
 
24
23
#include <sys/types.h>
25
24
#include <sys/stat.h>
26
25
#include <fcntl.h>
27
26
 
28
 
#include <drizzled/identifier.h>
29
 
#include <drizzled/open_tables_state.h>
30
 
#include <drizzled/pthread_globals.h>
31
 
#include <drizzled/session.h>
32
 
#include <drizzled/sql_base.h>
33
 
#include <drizzled/sys_var.h>
34
 
#include <drizzled/table.h>
35
 
#include <drizzled/table/concurrent.h>
36
 
#include <drizzled/table/unused.h>
37
 
 
38
 
namespace drizzled {
39
 
namespace table {
40
 
 
41
 
CacheMap Cache::cache;
42
 
boost::mutex Cache::_mutex;
43
 
 
44
 
CacheMap& getCache()
45
 
{
46
 
  return Cache::getCache();
 
27
 
 
28
#include "drizzled/identifier.h"
 
29
#include "drizzled/table.h"
 
30
#include "drizzled/session.h"
 
31
#include "drizzled/table/concurrent.h"
 
32
 
 
33
#include "drizzled/table/cache.h"
 
34
#include "drizzled/table/unused.h"
 
35
 
 
36
#include "drizzled/pthread_globals.h"
 
37
 
 
38
namespace drizzled
 
39
{
 
40
 
 
41
class Session;
 
42
 
 
43
namespace table
 
44
{
 
45
 
 
46
CacheMap &getCache(void)
 
47
{
 
48
  return Cache::singleton().getCache();
47
49
}
48
50
 
49
51
/*
54
56
  entry         Table to remove
55
57
 
56
58
  NOTE
57
 
  We need to have a lock on table::Cache::mutex() when calling this
 
59
  We need to have a lock on table::Cache::singleton().mutex() when calling this
58
60
*/
59
61
 
60
62
static void free_cache_entry(table::Concurrent *table)
76
78
  for (CacheMap::const_iterator iter= ppp.first;
77
79
         iter != ppp.second; ++iter)
78
80
  {
79
 
    table::Concurrent *found_table= iter->second;
 
81
    table::Concurrent *found_table= (*iter).second;
80
82
 
81
83
    if (found_table == arg)
82
84
    {
103
105
 
104
106
    for (table::CacheMap::const_iterator iter= ppp.first; iter != ppp.second; ++iter)
105
107
    {
106
 
      Table *search= iter->second;
 
108
      Table *search= (*iter).second;
107
109
      if (search->in_use == table->in_use)
108
110
        continue;                               // Name locked by this thread
109
111
      /*
142
144
       iter != table::getCache().end();
143
145
       iter++)
144
146
  {
145
 
    table::Concurrent *table= iter->second;
 
147
    table::Concurrent *table= (*iter).second;
146
148
 
147
149
    if (not schema_identifier.getPath().compare(table->getShare()->getSchemaName()))
148
150
    {
162
164
  close_thread_tables() is called.
163
165
 
164
166
  PREREQUISITES
165
 
  Lock on table::Cache::mutex()()
 
167
  Lock on table::Cache::singleton().mutex()()
166
168
 
167
169
  RETURN
168
170
  0  This thread now have exclusive access to this table and no other thread
170
172
  1  Table is in use by another thread
171
173
*/
172
174
 
173
 
bool Cache::removeTable(Session& session, const identifier::Table &identifier, uint32_t flags)
 
175
bool Cache::removeTable(Session *session, identifier::Table &identifier, uint32_t flags)
174
176
{
175
177
  const identifier::Table::Key &key(identifier.getKey());
176
 
  bool result= false;
 
178
  bool result= false; 
177
179
  bool signalled= false;
178
180
 
179
181
  for (;;)
186
188
    for (table::CacheMap::const_iterator iter= ppp.first;
187
189
         iter != ppp.second; ++iter)
188
190
    {
189
 
      table::Concurrent *table= iter->second;
 
191
      table::Concurrent *table= (*iter).second;
190
192
      Session *in_use;
191
193
 
192
194
      table->getMutableShare()->resetVersion();         /* Free when thread is ready */
194
196
      {
195
197
        table::getUnused().relink(table);
196
198
      }
197
 
      else if (in_use != &session)
 
199
      else if (in_use != session)
198
200
      {
199
201
        /*
200
202
          Mark that table is going to be deleted from cache. This will
201
203
          force threads that are in lockTables() (but not yet
202
204
          in thr_multi_lock()) to abort it's locks, close all tables and retry
203
205
        */
 
206
        in_use->some_tables_deleted= true;
204
207
        if (table->is_name_opened())
205
208
        {
206
209
          result= true;
208
211
        /*
209
212
          Now we must abort all tables locks used by this thread
210
213
          as the thread may be waiting to get a lock for another table.
211
 
          Note that we need to hold table::Cache::mutex() while going through the
 
214
          Note that we need to hold table::Cache::singleton().mutex() while going through the
212
215
          list. So that the other thread cannot change it. The other
213
 
          thread must also hold table::Cache::mutex() whenever changing the
 
216
          thread must also hold table::Cache::singleton().mutex() whenever changing the
214
217
          open_tables list. Aborting the MERGE lock after a child was
215
218
          closed and before the parent is closed would be fatal.
216
219
        */
217
 
        for (Table *session_table= in_use->open_tables.open_tables_;
 
220
        for (Table *session_table= in_use->open_tables;
218
221
             session_table ;
219
222
             session_table= session_table->getNext())
220
223
        {
221
224
          /* Do not handle locks of MERGE children. */
222
225
          if (session_table->db_stat)   // If table is open
223
 
            signalled|= session.abortLockForThread(session_table);
 
226
            signalled|= session->abortLockForThread(session_table);
224
227
        }
225
228
      }
226
229
      else
241
244
        reopen their tables
242
245
      */
243
246
      locking::broadcast_refresh();
244
 
      if (not (flags & RTFC_CHECK_KILLED_FLAG) || not session.getKilled())
 
247
      if (not (flags & RTFC_CHECK_KILLED_FLAG) || not session->getKilled())
245
248
      {
246
249
        dropping_tables++;
247
250
        if (likely(signalled))
248
251
        {
249
 
          boost::mutex::scoped_lock scoped(table::Cache::mutex(), boost::adopt_lock_t());
 
252
          boost_unique_lock_t scoped(table::Cache::singleton().mutex(), boost::adopt_lock_t());
250
253
          COND_refresh.wait(scoped);
251
254
          scoped.release();
252
255
        }
260
263
            ensure that the thread actually hears our signal
261
264
            before we go to sleep. Thus we wait for a short time
262
265
            and then we retry another loop in the
263
 
            table::Cache::removeTable routine.
 
266
            table::Cache::singleton().removeTable routine.
264
267
          */
265
 
          boost::xtime xt;
266
 
          xtime_get(&xt, boost::TIME_UTC);
267
 
          xt.sec += 10;
268
 
          boost::mutex::scoped_lock scoped(table::Cache::mutex(), boost::adopt_lock_t());
 
268
          boost::xtime xt; 
 
269
          xtime_get(&xt, boost::TIME_UTC); 
 
270
          xt.sec += 10; 
 
271
          boost_unique_lock_t scoped(table::Cache::singleton().mutex(), boost::adopt_lock_t());
269
272
          COND_refresh.timed_wait(scoped, xt);
270
273
          scoped.release();
271
274
        }
280
283
}
281
284
 
282
285
 
283
 
void Cache::insert(table::Concurrent* arg)
 
286
bool Cache::insert(table::Concurrent *arg)
284
287
{
285
288
  CacheMap::iterator returnable= cache.insert(std::make_pair(arg->getShare()->getCacheKey(), arg));
286
 
        assert(returnable != cache.end());
 
289
 
 
290
  return not (returnable == cache.end());
287
291
}
288
292
 
289
293
} /* namespace table */