~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/table/concurrent.cc

  • Committer: Brian Aker
  • Date: 2010-10-24 19:39:04 UTC
  • mfrom: (1874.3.4 refactor)
  • Revision ID: brian@tangent.org-20101024193904-6c5a62rtd14bx9q4
Merge for "how do we make sure concurrent, are only concurrent"

Show diffs side-by-side

added added

removed removed

Lines of Context:
36
36
namespace table
37
37
{
38
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
 
39
197
} /* namespace table */
40
198
} /* namespace drizzled */