~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/table/cache.cc

  • Committer: Mark Atwood
  • Date: 2012-01-04 16:59:32 UTC
  • mfrom: (2478.2.3 real-key-use-catalog)
  • Revision ID: me@mark.atwood.name-20120104165932-cm0xqs4by0u3p4cy
mergeĀ lp:~stewart/drizzle/key-use-catalog

Show diffs side-by-side

added added

removed removed

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