1
/* -*- mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; -*-
2
* vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
4
* Copyright (C) 2010 Brian Aker
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.
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.
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
23
#include <sys/types.h>
27
#include "drizzled/session.h"
28
#include "plugin/myisam/myisam.h"
29
#include "drizzled/plugin/transactional_storage_engine.h"
31
#include "drizzled/table.h"
40
Open table which is already name-locked by this thread.
43
reopen_name_locked_table()
45
table_list TableList object for table to be open, TableList::table
46
member should point to Table object which was used for
48
link_in true - if Table object for table to be opened should be
49
linked into Session::open_tables list.
50
false - placeholder used for name-locking is already in
51
this list so we only need to preserve Table::next
55
This function assumes that its caller already acquired table::Cache::singleton().mutex() mutex.
62
bool Concurrent::reopen_name_locked_table(TableList* table_list, Session *session)
64
safe_mutex_assert_owner(table::Cache::singleton().mutex().native_handle());
66
if (session->getKilled())
69
TableIdentifier identifier(table_list->getSchemaName(), table_list->getTableName());
70
if (open_unireg_entry(session, table_list->getTableName(), identifier))
77
We want to prevent other connections from opening this table until end
78
of statement as it is likely that modifications of table's metadata are
79
not yet finished (for example CREATE TRIGGER have to change .TRG cursor,
80
or we might want to drop table if CREATE TABLE ... SELECT fails).
81
This also allows us to assume that no other connection will sneak in
82
before we will get table-level lock on this table.
84
getMutableShare()->resetVersion();
87
tablenr= session->current_tablenr++;
93
status= STATUS_NO_RECORD;
100
Load a table definition from cursor and open unireg table
104
session Thread handle
105
entry Store open table definition here
106
table_list TableList with db, table_name
108
cache_key Key for share_cache
109
cache_key_length length of cache_key
112
Extra argument for open is taken from session->open_options
113
One must have a lock on table::Cache::singleton().mutex() when calling this function
120
int table::Concurrent::open_unireg_entry(Session *session,
122
TableIdentifier &identifier)
125
TableShare::shared_ptr share;
126
uint32_t discover_retry_count= 0;
128
safe_mutex_assert_owner(table::Cache::singleton().mutex().native_handle());
130
if (not (share= TableShare::getShareCreate(session,
137
while ((error= share->open_table_from_share(session,
140
(uint32_t) (HA_OPEN_KEYFILE |
144
session->open_options, *this)))
146
if (error == 7) // Table def changed
148
share->resetVersion(); // Mark share as old
149
if (discover_retry_count++) // Retry once
151
TableShare::release(share);
157
Here we should wait until all threads has released the table.
158
For now we do one retry. This may cause a deadlock if there
159
is other threads waiting for other tables used by this thread.
161
Proper fix would be to if the second retry failed:
162
- Mark that table def changed
163
- Return from open table
164
- Close all tables used by this thread
165
- Start waiting that the share is released
166
- Retry by opening all tables again
171
To avoid deadlock, only wait for release if no one else is
174
if (share->getTableCount() != 1)
176
TableShare::release(share);
179
/* Free share and wait until it's released by all threads */
180
TableShare::release(share);
182
if (not session->getKilled())
184
drizzle_reset_errors(session, 1); // Clear warnings
185
session->clear_error(); // Clear error message
191
TableShare::release(share);
199
void table::Concurrent::release(void)
201
// During an ALTER TABLE we could see the proto go away when the
202
// definition is pushed out of this table object. In this case we would
203
// not release from the cache because we were not in the cache. We just
204
// delete if this happens.
205
if (getShare()->getType() == message::Table::STANDARD)
207
TableShare::release(getMutableShare());
216
} /* namespace table */
217
} /* namespace drizzled */