~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/table/concurrent.cc

  • Committer: Stewart Smith
  • Date: 2010-11-03 03:27:09 UTC
  • mto: (1902.1.1 build) (1910.1.2 build)
  • mto: This revision was merged to the branch mainline in revision 1903.
  • Revision ID: stewart@flamingspork.com-20101103032709-oyvfrc6eb8fzj0mr
fix docs warning: docs/unlock.rst:2: (WARNING/2) Title underline too short.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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
 
 
21
#include "config.h"
 
22
 
 
23
#include <sys/types.h>
 
24
#include <sys/stat.h>
 
25
#include <fcntl.h>
 
26
 
 
27
#include "drizzled/session.h"
 
28
#include "plugin/myisam/myisam.h"
 
29
#include "drizzled/plugin/transactional_storage_engine.h"
 
30
 
 
31
#include "drizzled/table.h"
 
32
 
 
33
namespace drizzled
 
34
{
 
35
 
 
36
namespace table
 
37
{
 
38
 
 
39
/*
 
40
  Open table which is already name-locked by this thread.
 
41
 
 
42
  SYNOPSIS
 
43
  reopen_name_locked_table()
 
44
  session         Thread handle
 
45
  table_list  TableList object for table to be open, TableList::table
 
46
  member should point to Table object which was used for
 
47
  name-locking.
 
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
 
52
  pointer.
 
53
 
 
54
  NOTE
 
55
  This function assumes that its caller already acquired LOCK_open mutex.
 
56
 
 
57
  RETURN VALUE
 
58
  false - Success
 
59
  true  - Error
 
60
*/
 
61
 
 
62
bool Concurrent::reopen_name_locked_table(TableList* table_list, Session *session)
 
63
{
 
64
  safe_mutex_assert_owner(LOCK_open.native_handle());
 
65
 
 
66
  if (session->killed)
 
67
    return true;
 
68
 
 
69
  TableIdentifier identifier(table_list->getSchemaName(), table_list->getTableName());
 
70
  if (open_unireg_entry(session, table_list->getTableName(), identifier))
 
71
  {
 
72
    intern_close_table();
 
73
    return true;
 
74
  }
 
75
 
 
76
  /*
 
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.
 
83
  */
 
84
  getMutableShare()->resetVersion();
 
85
  in_use = session;
 
86
 
 
87
  tablenr= session->current_tablenr++;
 
88
  used_fields= 0;
 
89
  const_table= 0;
 
90
  null_row= false;
 
91
  maybe_null= false;
 
92
  force_index= false;
 
93
  status= STATUS_NO_RECORD;
 
94
 
 
95
  return false;
 
96
}
 
97
 
 
98
 
 
99
/*
 
100
  Load a table definition from cursor and open unireg table
 
101
 
 
102
  SYNOPSIS
 
103
  open_unireg_entry()
 
104
  session                       Thread handle
 
105
  entry         Store open table definition here
 
106
  table_list            TableList with db, table_name
 
107
  alias         Alias name
 
108
  cache_key             Key for share_cache
 
109
  cache_key_length      length of cache_key
 
110
 
 
111
  NOTES
 
112
  Extra argument for open is taken from session->open_options
 
113
  One must have a lock on LOCK_open when calling this function
 
114
 
 
115
  RETURN
 
116
  0     ok
 
117
#       Error
 
118
*/
 
119
 
 
120
int table::Concurrent::open_unireg_entry(Session *session,
 
121
                                         const char *alias,
 
122
                                         TableIdentifier &identifier)
 
123
{
 
124
  int error;
 
125
  TableSharePtr share;
 
126
  uint32_t discover_retry_count= 0;
 
127
 
 
128
  safe_mutex_assert_owner(LOCK_open.native_handle());
 
129
retry:
 
130
  if (not (share= TableShare::getShareCreate(session,
 
131
                                             identifier,
 
132
                                             &error)))
 
133
    return 1;
 
134
 
 
135
  while ((error= share->open_table_from_share(session,
 
136
                                              identifier,
 
137
                                              alias,
 
138
                                              (uint32_t) (HA_OPEN_KEYFILE |
 
139
                                                          HA_OPEN_RNDFILE |
 
140
                                                          HA_GET_INDEX |
 
141
                                                          HA_TRY_READ_ONLY),
 
142
                                              session->open_options, *this)))
 
143
  {
 
144
    if (error == 7)                             // Table def changed
 
145
    {
 
146
      share->resetVersion();                        // Mark share as old
 
147
      if (discover_retry_count++)               // Retry once
 
148
      {
 
149
        TableShare::release(share);
 
150
        return 1;
 
151
      }
 
152
 
 
153
      /*
 
154
        TODO->
 
155
        Here we should wait until all threads has released the table.
 
156
        For now we do one retry. This may cause a deadlock if there
 
157
        is other threads waiting for other tables used by this thread.
 
158
 
 
159
        Proper fix would be to if the second retry failed:
 
160
        - Mark that table def changed
 
161
        - Return from open table
 
162
        - Close all tables used by this thread
 
163
        - Start waiting that the share is released
 
164
        - Retry by opening all tables again
 
165
      */
 
166
 
 
167
      /*
 
168
        TO BE FIXED
 
169
        To avoid deadlock, only wait for release if no one else is
 
170
        using the share.
 
171
      */
 
172
      if (share->getTableCount() != 1)
 
173
      {
 
174
        TableShare::release(share);
 
175
        return 1;
 
176
      }
 
177
      /* Free share and wait until it's released by all threads */
 
178
      TableShare::release(share);
 
179
 
 
180
      if (!session->killed)
 
181
      {
 
182
        drizzle_reset_errors(session, 1);         // Clear warnings
 
183
        session->clear_error();                 // Clear error message
 
184
        goto retry;
 
185
      }
 
186
      return 1;
 
187
    }
 
188
 
 
189
    TableShare::release(share);
 
190
 
 
191
    return 1;
 
192
  }
 
193
 
 
194
  return 0;
 
195
}
 
196
 
 
197
} /* namespace table */
 
198
} /* namespace drizzled */