~drizzle-trunk/drizzle/development

1843.8.5 by Brian Aker
Added concurrent type.
1
/* -*- mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; -*-
2
 *  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
3
 *
4
 *  Copyright (C) 2010 Brian Aker
5
 *
6
 *  This program is free software; you can redistribute it and/or modify
7
 *  it under the terms of the GNU General Public License as published by
8
 *  the Free Software Foundation; either version 2 of the License, or
9
 *  (at your option) any later version.
10
 *
11
 *  This program is distributed in the hope that it will be useful,
12
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 *  GNU General Public License for more details.
15
 *
16
 *  You should have received a copy of the GNU General Public License
17
 *  along with this program; if not, write to the Free Software
18
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
19
 */
20
2173.2.1 by Monty Taylor
Fixes incorrect usage of include
21
#include <config.h>
1843.8.5 by Brian Aker
Added concurrent type.
22
23
#include <sys/types.h>
24
#include <sys/stat.h>
25
#include <fcntl.h>
26
2173.2.1 by Monty Taylor
Fixes incorrect usage of include
27
#include <drizzled/session.h>
28
#include <plugin/myisam/myisam.h>
2263.3.11 by Olaf van der Spek
Open Tables
29
#include <drizzled/open_tables_state.h>
2173.2.1 by Monty Taylor
Fixes incorrect usage of include
30
#include <drizzled/plugin/transactional_storage_engine.h>
2069.4.4 by Brian Aker
Create a shared form of the instance which is a bit more heavier weight then
31
#include <drizzled/table/instance.h>
2173.2.1 by Monty Taylor
Fixes incorrect usage of include
32
#include <drizzled/table.h>
2241.2.14 by Olaf van der Spek
Refactor
33
#include <drizzled/table_list.h>
34
35
namespace drizzled {
36
namespace table {
1843.8.5 by Brian Aker
Added concurrent type.
37
1874.3.3 by Brian Aker
shuffle some functions out of sql_base.cc
38
/*
39
  Open table which is already name-locked by this thread.
40
41
  SYNOPSIS
42
  reopen_name_locked_table()
43
  session         Thread handle
44
  table_list  TableList object for table to be open, TableList::table
45
  member should point to Table object which was used for
46
  name-locking.
47
  link_in     true  - if Table object for table to be opened should be
48
  linked into Session::open_tables list.
49
  false - placeholder used for name-locking is already in
50
  this list so we only need to preserve Table::next
51
  pointer.
52
53
  NOTE
2275.3.1 by Olaf van der Spek
Remove table::Cache::singleton()
54
  This function assumes that its caller already acquired table::Cache::mutex() mutex.
1874.3.3 by Brian Aker
shuffle some functions out of sql_base.cc
55
56
  RETURN VALUE
57
  false - Success
58
  true  - Error
59
*/
60
61
bool Concurrent::reopen_name_locked_table(TableList* table_list, Session *session)
62
{
2275.3.1 by Olaf van der Spek
Remove table::Cache::singleton()
63
  safe_mutex_assert_owner(table::Cache::mutex().native_handle());
1874.3.3 by Brian Aker
shuffle some functions out of sql_base.cc
64
1910.2.8 by Brian Aker
Enapsulate Kill.
65
  if (session->getKilled())
1874.3.3 by Brian Aker
shuffle some functions out of sql_base.cc
66
    return true;
67
2087.4.2 by Brian Aker
Modify TableIdentifier to fit with the rest of the identifiers.
68
  identifier::Table identifier(table_list->getSchemaName(), table_list->getTableName());
1874.3.4 by Brian Aker
Merge with trunk.
69
  if (open_unireg_entry(session, table_list->getTableName(), identifier))
1874.3.3 by Brian Aker
shuffle some functions out of sql_base.cc
70
  {
71
    intern_close_table();
72
    return true;
73
  }
74
75
  /*
76
    We want to prevent other connections from opening this table until end
77
    of statement as it is likely that modifications of table's metadata are
78
    not yet finished (for example CREATE TRIGGER have to change .TRG cursor,
79
    or we might want to drop table if CREATE TABLE ... SELECT fails).
80
    This also allows us to assume that no other connection will sneak in
81
    before we will get table-level lock on this table.
82
  */
83
  getMutableShare()->resetVersion();
84
  in_use = session;
85
2263.3.3 by Olaf van der Spek
Use open_tables
86
  tablenr= session->open_tables.current_tablenr++;
1874.3.3 by Brian Aker
shuffle some functions out of sql_base.cc
87
  used_fields= 0;
88
  const_table= 0;
89
  null_row= false;
90
  maybe_null= false;
91
  force_index= false;
92
  status= STATUS_NO_RECORD;
93
94
  return false;
95
}
96
97
98
/*
99
  Load a table definition from cursor and open unireg table
100
101
  SYNOPSIS
102
  open_unireg_entry()
103
  session			Thread handle
104
  entry		Store open table definition here
105
  table_list		TableList with db, table_name
106
  alias		Alias name
107
  cache_key		Key for share_cache
108
  cache_key_length	length of cache_key
109
110
  NOTES
111
  Extra argument for open is taken from session->open_options
2275.3.1 by Olaf van der Spek
Remove table::Cache::singleton()
112
  One must have a lock on table::Cache::mutex() when calling this function
1874.3.3 by Brian Aker
shuffle some functions out of sql_base.cc
113
114
  RETURN
115
  0	ok
116
#	Error
117
*/
118
119
int table::Concurrent::open_unireg_entry(Session *session,
120
                                         const char *alias,
2087.4.2 by Brian Aker
Modify TableIdentifier to fit with the rest of the identifiers.
121
                                         identifier::Table &identifier)
1874.3.3 by Brian Aker
shuffle some functions out of sql_base.cc
122
{
123
  int error;
1938.4.1 by Brian Aker
Fix style on naming of shared_ptr for tableshare.
124
  TableShare::shared_ptr share;
1874.3.3 by Brian Aker
shuffle some functions out of sql_base.cc
125
  uint32_t discover_retry_count= 0;
126
2275.3.1 by Olaf van der Spek
Remove table::Cache::singleton()
127
  safe_mutex_assert_owner(table::Cache::mutex().native_handle());
1874.3.3 by Brian Aker
shuffle some functions out of sql_base.cc
128
retry:
2187.7.5 by Brian Aker
Merge in modifications such that we check both schema and table for
129
  if (not (share= table::instance::Shared::make_shared(session, identifier, error)))
1910.2.10 by Brian Aker
Move event cleanup out to the destructor.
130
  {
1874.3.3 by Brian Aker
shuffle some functions out of sql_base.cc
131
    return 1;
1910.2.10 by Brian Aker
Move event cleanup out to the destructor.
132
  }
1874.3.3 by Brian Aker
shuffle some functions out of sql_base.cc
133
134
  while ((error= share->open_table_from_share(session,
135
                                              identifier,
136
                                              alias,
137
                                              (uint32_t) (HA_OPEN_KEYFILE |
138
                                                          HA_OPEN_RNDFILE |
139
                                                          HA_GET_INDEX |
140
                                                          HA_TRY_READ_ONLY),
141
                                              session->open_options, *this)))
142
  {
143
    if (error == 7)                             // Table def changed
144
    {
145
      share->resetVersion();                        // Mark share as old
146
      if (discover_retry_count++)               // Retry once
147
      {
2069.4.4 by Brian Aker
Create a shared form of the instance which is a bit more heavier weight then
148
        table::instance::release(share);
1874.3.3 by Brian Aker
shuffle some functions out of sql_base.cc
149
        return 1;
150
      }
151
152
      /*
153
        TODO->
154
        Here we should wait until all threads has released the table.
155
        For now we do one retry. This may cause a deadlock if there
156
        is other threads waiting for other tables used by this thread.
157
158
        Proper fix would be to if the second retry failed:
159
        - Mark that table def changed
160
        - Return from open table
161
        - Close all tables used by this thread
162
        - Start waiting that the share is released
163
        - Retry by opening all tables again
164
      */
165
166
      /*
167
        TO BE FIXED
168
        To avoid deadlock, only wait for release if no one else is
169
        using the share.
170
      */
171
      if (share->getTableCount() != 1)
172
      {
2069.4.4 by Brian Aker
Create a shared form of the instance which is a bit more heavier weight then
173
        table::instance::release(share);
1874.3.3 by Brian Aker
shuffle some functions out of sql_base.cc
174
        return 1;
175
      }
2069.4.4 by Brian Aker
Create a shared form of the instance which is a bit more heavier weight then
176
1874.3.3 by Brian Aker
shuffle some functions out of sql_base.cc
177
      /* Free share and wait until it's released by all threads */
2069.4.4 by Brian Aker
Create a shared form of the instance which is a bit more heavier weight then
178
      table::instance::release(share);
1874.3.3 by Brian Aker
shuffle some functions out of sql_base.cc
179
1910.2.8 by Brian Aker
Enapsulate Kill.
180
      if (not session->getKilled())
1874.3.3 by Brian Aker
shuffle some functions out of sql_base.cc
181
      {
2318.6.104 by Olaf van der Spek
Refactor
182
        drizzle_reset_errors(*session, true);         // Clear warnings
1874.3.3 by Brian Aker
shuffle some functions out of sql_base.cc
183
        session->clear_error();                 // Clear error message
184
        goto retry;
185
      }
2069.4.4 by Brian Aker
Create a shared form of the instance which is a bit more heavier weight then
186
1874.3.3 by Brian Aker
shuffle some functions out of sql_base.cc
187
      return 1;
188
    }
189
2069.4.4 by Brian Aker
Create a shared form of the instance which is a bit more heavier weight then
190
    table::instance::release(share);
1874.3.3 by Brian Aker
shuffle some functions out of sql_base.cc
191
192
    return 1;
193
  }
194
195
  return 0;
196
}
197
1903.1.1 by Brian Aker
Merge of partial set of patches for locks.
198
void table::Concurrent::release(void)
199
{
200
  // During an ALTER TABLE we could see the proto go away when the
201
  // definition is pushed out of this table object. In this case we would
202
  // not release from the cache because we were not in the cache. We just
203
  // delete if this happens.
204
  if (getShare()->getType() == message::Table::STANDARD)
205
  {
2069.4.4 by Brian Aker
Create a shared form of the instance which is a bit more heavier weight then
206
    table::instance::release(getMutableShare());
1903.1.1 by Brian Aker
Merge of partial set of patches for locks.
207
  }
208
  else
209
  {
210
    delete _share;
211
  }
212
  _share= NULL;
213
}
214
1843.8.5 by Brian Aker
Added concurrent type.
215
} /* namespace table */
216
} /* namespace drizzled */