Merge lp://staging/~clint-fewbar/drizzle/refactor-lock into lp://staging/~drizzle-trunk/drizzle/development
- refactor-lock
- Merge into development
Status: | Superseded |
---|---|
Proposed branch: | lp://staging/~clint-fewbar/drizzle/refactor-lock |
Merge into: | lp://staging/~drizzle-trunk/drizzle/development |
Diff against target: |
1657 lines 15 files modified
drizzled/cursor.h (+1/-1) drizzled/join.cc (+4/-4) drizzled/join.h (+1/-1) drizzled/lock.cc (+337/-343) drizzled/lock.h (+181/-12) drizzled/open_tables_state.h (+3/-2) drizzled/select_create.h (+3/-2) drizzled/select_send.h (+1/-5) drizzled/session.cc (+2/-14) drizzled/session.h (+64/-8) drizzled/sql_base.cc (+17/-26) drizzled/sql_insert.cc (+16/-17) drizzled/sql_table.cc (+3/-7) drizzled/statement/alter_table.cc (+1/-5) drizzled/table.h (+2/-2) |
To merge this branch: | bzr merge lp://staging/~clint-fewbar/drizzle/refactor-lock |
Related bugs: | |
Related blueprints: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Monty Taylor | Needs Fixing | ||
Review via email: mp+9569@code.staging.launchpad.net |
This proposal has been superseded by a proposal from 2009-10-21.
Commit message
Description of the change
Clint Byrum (clint-fewbar) wrote : | # |
Monty Taylor (mordred) wrote : | # |
Looking really good. A few minor issues to work out:
in lock.cc, add a using namespace drizzled; right after using namespace std; Then you can remove the drizzled:: prefix throughout that file.
+drizzled::Lock *Session:
+ uint32_t flags, bool *need_reopen)
+int Session:
+void Session:
+void Session:
+bool Session:
+int Session:
This looks like it should actually live in session.cc? Or is there a reason there here?
In:
+void Session:
+void Session:
+bool Session:
Seems like you could replace:
drizzled::Lock *sql_lock= new (nothrow) drizzled::Lock;
with
drizzled::Lock sql_lock;
no?
+ memmove((table+x), (table+x+1),
+ (old_tables - x) * sizeof(Table*));
+ memmove((locks + tbl->lock_
+ (locks + lock_data_end),
+ (lock_count - lock_data_end) *
+ sizeof(
The line-continuation style here should be:
+ memmove((table+x), (table+x+1),
+ (old_tables - x) * sizeof(Table*));
Is it possible for this:
drizzled:
to be
drizzled:
I won't die if it isn't. Oh! My! No it's not.
+ delete a;
+ delete b;
I'm not sure how I feel about that- but something tells me there are bigger implications to changing that.
Clint Byrum (clint-fewbar) wrote : | # |
On Aug 6, 2009, at 3:13 PM, Monty Taylor wrote:
> Review: Needs Fixing
> Looking really good. A few minor issues to work out:
>
> in lock.cc, add a using namespace drizzled; right after using
> namespace std; Then you can remove the drizzled:: prefix throughout
> that file.
>
> +drizzled::Lock *Session:
> + uint32_t flags, bool
> *need_reopen)
> +int Session:
> +void Session:
> +void Session:
> +bool Session:
> +int Session:
>
> This looks like it should actually live in session.cc? Or is there a
> reason there here?
>
The only reason I didn't do that was to keep the functions where they
originally lived, and some abiguity in the coding standards. The only
place this is mentioned (just checked again to make sure it hasn't
changed recently) is here:
http://
which states
"All new classes get their own .h and .cc files. We will need to pull
apart the mess that exists today, but that is a long term goal."
So, if that needs to happen now as part of this change, I'll go ahead
and move all of those methods to another file, however, I was thinking
that should be done as part of the larger effort to cleanup all the
rest of the functions in the file that need to be renamed and probably
done as methods of Session or TableList, namely:
TableList *mysql_
*needle,
bool lock_global_
void unlock_
bool wait_if_
void start_waiting_
bool make_global_
int lock_and_
*table_list);
int lock_table_
check_in_use);
void unlock_
bool wait_for_
*table_list);
bool lock_table_
void unlock_
bool lock_table_
*table_list);
> In:
>
> +void Session:
> +void Session:
> +bool Session:
>
> Seems like you could replace:
>
> drizzled::Lock *sql_lock= new (nothrow) drizzled::Lock;
> with
> drizzled::Lock sql_lock;
> no?
>
Yes, done and tested.
It raises a question which is actually more obvious with the explicit
new/delete;
If initLockData() were to put 'this' into some other structure on the
heap, that would cause bad things to happen as 'this' will be deleted.
So, is there a way to get ...
- 1106. By Clint Byrum
-
statically declaring when appropriate and some formatting fixes
- 1107. By Clint Byrum
-
merging trunk
Unmerged revisions
- 1107. By Clint Byrum
-
merging trunk
- 1106. By Clint Byrum
-
statically declaring when appropriate and some formatting fixes
- 1105. By Clint Byrum
-
_external functions refactored as methods of Session
- 1104. By Clint Byrum
-
removing irrelevant comment
- 1103. By Clint Byrum
-
moving method to lock.cc
- 1102. By Clint Byrum
-
comment fix
- 1101. By Clint Byrum
-
formatting and doxygen fixes
- 1100. By Clint Byrum
-
merging w/ trunk
- 1099. By Clint Byrum
-
cleanups for coding standards
- 1098. By Clint Byrum
-
Refactoring DRIZZLE_LOCK into drizzled::Lock
Preview Diff
1 | === modified file 'drizzled/cursor.h' |
2 | --- drizzled/cursor.h 2009-10-16 10:27:33 +0000 |
3 | +++ drizzled/cursor.h 2009-10-21 06:25:19 +0000 |
4 | @@ -602,7 +602,7 @@ |
5 | or partitioned. |
6 | |
7 | @note that one can NOT rely on table->in_use in store_lock(). It may |
8 | - refer to a different thread if called from mysql_lock_abort_for_thread(). |
9 | + refer to a different thread if called from Session::abortLockForThread(). |
10 | |
11 | @note If the table is MERGE, store_lock() can return less locks |
12 | than lock_count() claimed. This can happen when the MERGE children |
13 | |
14 | === modified file 'drizzled/join.cc' |
15 | --- drizzled/join.cc 2009-10-06 19:51:49 +0000 |
16 | +++ drizzled/join.cc 2009-10-21 06:25:19 +0000 |
17 | @@ -569,7 +569,7 @@ |
18 | return 1; |
19 | } |
20 | if (const_tables && !(select_options & SELECT_NO_UNLOCK)) |
21 | - mysql_unlock_some_tables(session, table, const_tables); |
22 | + session->unlockSomeTables(table, const_tables); |
23 | if (!conds && outer_join) |
24 | { |
25 | /* Handle the case where we have an OUTER JOIN without a WHERE */ |
26 | @@ -1757,8 +1757,8 @@ |
27 | is called after all rows are sent, but before EOF packet is sent. |
28 | |
29 | For a simple SELECT with no subqueries this function performs a full |
30 | - cleanup of the JOIN and calls mysql_unlock_read_tables to free used base |
31 | - tables. |
32 | + cleanup of the JOIN and calls drizzled::Lock::unlockReadTables() to |
33 | + free used base tables. |
34 | |
35 | If a JOIN is executed for a subquery or if it has a subquery, we can't |
36 | do the full cleanup and need to do a partial cleanup only. |
37 | @@ -1829,7 +1829,7 @@ |
38 | TODO: unlock tables even if the join isn't top level select in the |
39 | tree. |
40 | */ |
41 | - mysql_unlock_read_tables(session, lock); // Don't free join->lock |
42 | + lock->unlockReadTables(session); // Don't free join->lock |
43 | lock= 0; |
44 | } |
45 | |
46 | |
47 | === modified file 'drizzled/join.h' |
48 | --- drizzled/join.h 2009-08-20 21:45:52 +0000 |
49 | +++ drizzled/join.h 2009-10-21 06:25:19 +0000 |
50 | @@ -174,7 +174,7 @@ |
51 | uint64_t select_options; |
52 | select_result *result; |
53 | Tmp_Table_Param tmp_table_param; |
54 | - DRIZZLE_LOCK *lock; |
55 | + drizzled::Lock *lock; |
56 | |
57 | JOIN *tmp_join; /**< copy of this JOIN to be used with temporary tables */ |
58 | ROLLUP rollup; /**< Used with rollup */ |
59 | |
60 | === modified file 'drizzled/lock.cc' |
61 | --- drizzled/lock.cc 2009-08-11 03:02:59 +0000 |
62 | +++ drizzled/lock.cc 2009-10-21 06:25:19 +0000 |
63 | @@ -1,3 +1,4 @@ |
64 | +// vim:ts=2 sts=2 sw=2:et ai: |
65 | /* Copyright (C) 2000-2006 MySQL AB |
66 | |
67 | This program is free software; you can redistribute it and/or modify |
68 | @@ -27,18 +28,18 @@ |
69 | |
70 | When not using LOCK TABLES: |
71 | |
72 | - - For each SQL statement mysql_lock_tables() is called for all involved |
73 | + - For each SQL statement Session::lockTables() is called for all involved |
74 | tables. |
75 | - - mysql_lock_tables() will call |
76 | + - Session::lockTables() will call |
77 | table_handler->external_lock(session,locktype) for each table. |
78 | This is followed by a call to thr_multi_lock() for all tables. |
79 | |
80 | - - When statement is done, we call mysql_unlock_tables(). |
81 | + - When statement is done, we call Session::unlockTables(). |
82 | This will call thr_multi_unlock() followed by |
83 | table_handler->external_lock(session, F_UNLCK) for each table. |
84 | |
85 | - - Note that mysql_unlock_tables() may be called several times as |
86 | - MySQL in some cases can free some tables earlier than others. |
87 | + - Note that drizzled::Lock::unlockTables() may be called several times as |
88 | + Drizzle in some cases can free some tables earlier than others. |
89 | |
90 | - The above is true both for normal and temporary tables. |
91 | |
92 | @@ -47,8 +48,8 @@ |
93 | |
94 | When using LOCK TABLES: |
95 | |
96 | - - LOCK Table will call mysql_lock_tables() for all tables. |
97 | - mysql_lock_tables() will call |
98 | + - LOCK Table will call Session::lockTables() for all tables. |
99 | + Session::lockTables() will call |
100 | table_handler->external_lock(session,locktype) for each table. |
101 | This is followed by a call to thr_multi_lock() for all tables. |
102 | |
103 | @@ -60,7 +61,7 @@ |
104 | |
105 | - When statement is done, we will call ha_commit_stmt(session); |
106 | |
107 | - - When calling UNLOCK TABLES we call mysql_unlock_tables() for all |
108 | + - When calling UNLOCK TABLES we call drizzled::Lock::unlockTables() for all |
109 | tables used in LOCK TABLES |
110 | |
111 | If table_handler->external_lock(session, locktype) fails, we call |
112 | @@ -85,224 +86,210 @@ |
113 | @{ |
114 | */ |
115 | |
116 | +using namespace std; |
117 | + |
118 | extern HASH open_cache; |
119 | |
120 | -static DRIZZLE_LOCK *get_lock_data(Session *session, Table **table, |
121 | - uint32_t count, |
122 | - bool should_lock, Table **write_locked); |
123 | -static int lock_external(Session *session, Table **table,uint32_t count); |
124 | -static int unlock_external(Session *session, Table **table,uint32_t count); |
125 | static void print_lock_error(int error, const char *); |
126 | |
127 | -/* |
128 | - Lock tables. |
129 | - |
130 | - SYNOPSIS |
131 | - mysql_lock_tables() |
132 | - session The current thread. |
133 | - tables An array of pointers to the tables to lock. |
134 | - count The number of tables to lock. |
135 | - flags Options: |
136 | - DRIZZLE_LOCK_IGNORE_GLOBAL_READ_LOCK Ignore a global read lock |
137 | - DRIZZLE_LOCK_IGNORE_FLUSH Ignore a flush tables. |
138 | - DRIZZLE_LOCK_NOTIFY_IF_NEED_REOPEN Instead of reopening altered |
139 | - or dropped tables by itself, |
140 | - mysql_lock_tables() should |
141 | - notify upper level and rely |
142 | - on caller doing this. |
143 | - need_reopen Out parameter, TRUE if some tables were altered |
144 | - or deleted and should be reopened by caller. |
145 | - |
146 | - RETURN |
147 | - A lock structure pointer on success. |
148 | - NULL on error or if some tables should be reopen. |
149 | -*/ |
150 | |
151 | /* Map the return value of thr_lock to an error from errmsg.txt */ |
152 | static int thr_lock_errno_to_mysql[]= |
153 | { 0, 1, ER_LOCK_WAIT_TIMEOUT, ER_LOCK_DEADLOCK }; |
154 | |
155 | |
156 | -/** |
157 | - Reset lock type in lock data and free. |
158 | - |
159 | - @param mysql_lock Lock structures to reset. |
160 | - |
161 | - @note After a locking error we want to quit the locking of the table(s). |
162 | - The test case in the bug report for Bug #18544 has the following |
163 | - cases: 1. Locking error in lock_external() due to InnoDB timeout. |
164 | - 2. Locking error in get_lock_data() due to missing write permission. |
165 | - 3. Locking error in wait_if_global_read_lock() due to lock conflict. |
166 | - |
167 | - @note In all these cases we have already set the lock type into the lock |
168 | - data of the open table(s). If the table(s) are in the open table |
169 | - cache, they could be reused with the non-zero lock type set. This |
170 | - could lead to ignoring a different lock type with the next lock. |
171 | - |
172 | - @note Clear the lock type of all lock data. This ensures that the next |
173 | - lock request will set its lock type properly. |
174 | -*/ |
175 | - |
176 | -static void reset_lock_data_and_free(DRIZZLE_LOCK **mysql_lock) |
177 | -{ |
178 | - DRIZZLE_LOCK *sql_lock= *mysql_lock; |
179 | +drizzled::Lock::~Lock() |
180 | +{ |
181 | + resetLockData(); |
182 | +} |
183 | + |
184 | +void drizzled::Lock::resetLockData() |
185 | +{ |
186 | THR_LOCK_DATA **ldata, **ldata_end; |
187 | |
188 | + |
189 | /* Clear the lock type of all lock data to avoid reusage. */ |
190 | - for (ldata= sql_lock->locks, ldata_end= ldata + sql_lock->lock_count; |
191 | - ldata < ldata_end; |
192 | - ldata++) |
193 | + if (locks) |
194 | { |
195 | - /* Reset lock type. */ |
196 | - (*ldata)->type= TL_UNLOCK; |
197 | + for (ldata= locks, ldata_end= ldata + lock_count; |
198 | + ldata < ldata_end; |
199 | + ldata++) |
200 | + { |
201 | + /* Reset lock type. */ |
202 | + (*ldata)->type= TL_UNLOCK; |
203 | + } |
204 | + free(locks); |
205 | } |
206 | - free((unsigned char*) sql_lock); |
207 | - *mysql_lock= 0; |
208 | -} |
209 | - |
210 | - |
211 | -DRIZZLE_LOCK *mysql_lock_tables(Session *session, Table **tables, uint32_t count, |
212 | +} |
213 | + |
214 | +drizzled::Lock *Session::lockTables(Table **tables, uint32_t count, |
215 | + uint32_t flags, bool *need_reopen) |
216 | +{ |
217 | + drizzled::Lock *sql_lock= new (nothrow) drizzled::Lock; |
218 | + |
219 | + if (sql_lock && sql_lock->lockTables(this, tables, count, flags, need_reopen)) |
220 | + { |
221 | + return sql_lock; |
222 | + } |
223 | + |
224 | + delete sql_lock; |
225 | + |
226 | + return NULL; |
227 | +} |
228 | + |
229 | +bool drizzled::Lock::lockTables(Session *session, Table **tables, uint32_t count, |
230 | uint32_t flags, bool *need_reopen) |
231 | { |
232 | - DRIZZLE_LOCK *sql_lock; |
233 | Table *write_lock_used; |
234 | int rc; |
235 | + bool failed_locks= false; |
236 | |
237 | *need_reopen= false; |
238 | |
239 | - for (;;) |
240 | + try |
241 | { |
242 | - if (! (sql_lock= get_lock_data(session, tables, count, true, |
243 | - &write_lock_used))) |
244 | - break; |
245 | - |
246 | - if (global_read_lock && write_lock_used && |
247 | - ! (flags & DRIZZLE_LOCK_IGNORE_GLOBAL_READ_LOCK)) |
248 | - { |
249 | - /* |
250 | - Someone has issued LOCK ALL TABLES FOR READ and we want a write lock |
251 | - Wait until the lock is gone |
252 | - */ |
253 | - if (wait_if_global_read_lock(session, 1, 1)) |
254 | - { |
255 | - /* Clear the lock type of all lock data to avoid reusage. */ |
256 | - reset_lock_data_and_free(&sql_lock); |
257 | - break; |
258 | - } |
259 | - if (session->version != refresh_version) |
260 | - { |
261 | - /* Clear the lock type of all lock data to avoid reusage. */ |
262 | - reset_lock_data_and_free(&sql_lock); |
263 | - goto retry; |
264 | - } |
265 | - } |
266 | - |
267 | - session->set_proc_info("System lock"); |
268 | - if (sql_lock->table_count && lock_external(session, sql_lock->table, |
269 | - sql_lock->table_count)) |
270 | - { |
271 | - /* Clear the lock type of all lock data to avoid reusage. */ |
272 | - reset_lock_data_and_free(&sql_lock); |
273 | - break; |
274 | - } |
275 | - session->set_proc_info("Table lock"); |
276 | - /* Copy the lock data array. thr_multi_lock() reorders its contens. */ |
277 | - memcpy(sql_lock->locks + sql_lock->lock_count, sql_lock->locks, |
278 | - sql_lock->lock_count * sizeof(*sql_lock->locks)); |
279 | - /* Lock on the copied half of the lock data array. */ |
280 | - rc= thr_lock_errno_to_mysql[(int) thr_multi_lock(sql_lock->locks + |
281 | - sql_lock->lock_count, |
282 | - sql_lock->lock_count, |
283 | - session->lock_id)]; |
284 | - if (rc > 1) /* a timeout or a deadlock */ |
285 | - { |
286 | - if (sql_lock->table_count) |
287 | - unlock_external(session, sql_lock->table, sql_lock->table_count); |
288 | - reset_lock_data_and_free(&sql_lock); |
289 | - my_error(rc, MYF(0)); |
290 | - break; |
291 | - } |
292 | - else if (rc == 1) /* aborted */ |
293 | - { |
294 | - session->some_tables_deleted=1; // Try again |
295 | - sql_lock->lock_count= 0; // Locks are already freed |
296 | - // Fall through: unlock, reset lock data, free and retry |
297 | - } |
298 | - else if (!session->some_tables_deleted || (flags & DRIZZLE_LOCK_IGNORE_FLUSH)) |
299 | - { |
300 | - /* |
301 | - Thread was killed or lock aborted. Let upper level close all |
302 | - used tables and retry or give error. |
303 | - */ |
304 | - break; |
305 | - } |
306 | - else if (!session->open_tables) |
307 | - { |
308 | - // Only using temporary tables, no need to unlock |
309 | - session->some_tables_deleted= 0; |
310 | - break; |
311 | - } |
312 | - session->set_proc_info(0); |
313 | - |
314 | - /* going to retry, unlock all tables */ |
315 | - if (sql_lock->lock_count) |
316 | - thr_multi_unlock(sql_lock->locks, sql_lock->lock_count); |
317 | - |
318 | - if (sql_lock->table_count) |
319 | - unlock_external(session, sql_lock->table, sql_lock->table_count); |
320 | - |
321 | - /* |
322 | - If thr_multi_lock fails it resets lock type for tables, which |
323 | - were locked before (and including) one that caused error. Lock |
324 | - type for other tables preserved. |
325 | - */ |
326 | - reset_lock_data_and_free(&sql_lock); |
327 | + for (;;) |
328 | + { |
329 | + if (! initLockData(session, tables, count, true, &write_lock_used)) |
330 | + { |
331 | + throw exception(); |
332 | + } |
333 | + |
334 | + if (global_read_lock && write_lock_used && |
335 | + ! (flags & DRIZZLE_LOCK_IGNORE_GLOBAL_READ_LOCK)) |
336 | + { |
337 | + /* |
338 | + Someone has issued LOCK ALL TABLES FOR READ and we want a write lock |
339 | + Wait until the lock is gone |
340 | + */ |
341 | + if (wait_if_global_read_lock(session, 1, 1)) |
342 | + { |
343 | + /* Clear the lock type of all lock data to avoid reusage. */ |
344 | + throw exception(); |
345 | + } |
346 | + if (session->version != refresh_version) |
347 | + { |
348 | + /* Clear the lock type of all lock data to avoid reusage. */ |
349 | + resetLockData(); |
350 | + goto retry; |
351 | + } |
352 | + } |
353 | + |
354 | + session->set_proc_info("System lock"); |
355 | + if (table_count && session->lockExternal(table, table_count)) |
356 | + { |
357 | + /* Clear the lock type of all lock data to avoid reusage. */ |
358 | + throw exception(); |
359 | + } |
360 | + session->set_proc_info("Table lock"); |
361 | + /* Copy the lock data array. thr_multi_lock() reorders its contens. */ |
362 | + memcpy(locks + lock_count, locks, |
363 | + lock_count * sizeof(*locks)); |
364 | + /* Lock on the copied half of the lock data array. */ |
365 | + rc= thr_lock_errno_to_mysql[(int) thr_multi_lock(locks + |
366 | + lock_count, |
367 | + lock_count, |
368 | + session->lock_id)]; |
369 | + if (rc > 1) /* a timeout or a deadlock */ |
370 | + { |
371 | + if (table_count) |
372 | + (void)session->unlockExternal(table, table_count); // return is advisory |
373 | + my_error(rc, MYF(0)); |
374 | + throw exception(); |
375 | + } |
376 | + else if (rc == 1) /* aborted */ |
377 | + { |
378 | + session->some_tables_deleted=1; // Try again |
379 | + lock_count= 0; // Locks are already freed |
380 | + // Fall through: unlock, reset lock data, free and retry |
381 | + } |
382 | + else if (!session->some_tables_deleted || (flags & DRIZZLE_LOCK_IGNORE_FLUSH)) |
383 | + { |
384 | + /* |
385 | + Thread was killed or lock aborted. Let upper level close all |
386 | + used tables and retry or give error. |
387 | + */ |
388 | + break; |
389 | + } |
390 | + else if (!session->open_tables) |
391 | + { |
392 | + // Only using temporary tables, no need to unlock |
393 | + session->some_tables_deleted= 0; |
394 | + break; |
395 | + } |
396 | + session->set_proc_info(0); |
397 | + |
398 | + /* going to retry, unlock all tables */ |
399 | + if (lock_count) |
400 | + thr_multi_unlock(locks, lock_count); |
401 | + |
402 | + if (table_count) |
403 | + (void)session->unlockExternal(table, table_count); |
404 | + |
405 | + /* |
406 | + If thr_multi_lock fails it resets lock type for tables, which |
407 | + were locked before (and including) one that caused error. Lock |
408 | + type for other tables preserved. |
409 | + */ |
410 | + resetLockData(); |
411 | retry: |
412 | - if (flags & DRIZZLE_LOCK_NOTIFY_IF_NEED_REOPEN) |
413 | - { |
414 | - *need_reopen= true; |
415 | - break; |
416 | + if (flags & DRIZZLE_LOCK_NOTIFY_IF_NEED_REOPEN) |
417 | + { |
418 | + *need_reopen= true; |
419 | + break; |
420 | + } |
421 | + if (wait_for_tables(session)) |
422 | + break; // Couldn't open tables |
423 | } |
424 | - if (wait_for_tables(session)) |
425 | - break; // Couldn't open tables |
426 | + } |
427 | + catch (...) |
428 | + { |
429 | + failed_locks= true; |
430 | } |
431 | + |
432 | session->set_proc_info(0); |
433 | if (session->killed) |
434 | { |
435 | session->send_kill_message(); |
436 | - if (sql_lock) |
437 | + if (! failed_locks) |
438 | { |
439 | - mysql_unlock_tables(session,sql_lock); |
440 | - sql_lock= NULL; |
441 | + unlockTables(session); |
442 | } |
443 | + return false; |
444 | } |
445 | |
446 | session->set_time_after_lock(); |
447 | - return (sql_lock); |
448 | + |
449 | + if (failed_locks) |
450 | + { |
451 | + return false; |
452 | + } |
453 | + |
454 | + return true; |
455 | } |
456 | |
457 | |
458 | -static int lock_external(Session *session, Table **tables, uint32_t count) |
459 | +int Session::lockExternal(Table **tables, uint32_t count) |
460 | { |
461 | - register uint32_t i; |
462 | + register uint32_t x; |
463 | int lock_type,error; |
464 | - for (i=1 ; i <= count ; i++, tables++) |
465 | + for (x= 1; x <= count; x++, tables++) |
466 | { |
467 | assert((*tables)->reginfo.lock_type >= TL_READ); |
468 | - lock_type=F_WRLCK; /* Lock exclusive */ |
469 | + lock_type= F_WRLCK; /* Lock exclusive */ |
470 | if ((*tables)->db_stat & HA_READ_ONLY || |
471 | - ((*tables)->reginfo.lock_type >= TL_READ && |
472 | - (*tables)->reginfo.lock_type <= TL_READ_NO_INSERT)) |
473 | - lock_type=F_RDLCK; |
474 | + ((*tables)->reginfo.lock_type >= TL_READ && |
475 | + (*tables)->reginfo.lock_type <= TL_READ_NO_INSERT)) |
476 | + lock_type= F_RDLCK; |
477 | |
478 | - if ((error=(*tables)->file->ha_external_lock(session,lock_type))) |
479 | + if ((error= (*tables)->file->ha_external_lock(this,lock_type))) |
480 | { |
481 | print_lock_error(error, (*tables)->file->engine->getName().c_str()); |
482 | - while (--i) |
483 | + while (--x) |
484 | { |
485 | tables--; |
486 | - (*tables)->file->ha_external_lock(session, F_UNLCK); |
487 | - (*tables)->current_lock=F_UNLCK; |
488 | + (*tables)->file->ha_external_lock(this, F_UNLCK); |
489 | + (*tables)->current_lock= F_UNLCK; |
490 | } |
491 | return error; |
492 | } |
493 | @@ -312,168 +299,192 @@ |
494 | (*tables)->current_lock= lock_type; |
495 | } |
496 | } |
497 | + |
498 | return 0; |
499 | } |
500 | |
501 | - |
502 | -void mysql_unlock_tables(Session *session, DRIZZLE_LOCK *sql_lock) |
503 | -{ |
504 | - if (sql_lock->lock_count) |
505 | - thr_multi_unlock(sql_lock->locks,sql_lock->lock_count); |
506 | - if (sql_lock->table_count) |
507 | - unlock_external(session,sql_lock->table,sql_lock->table_count); |
508 | - free((unsigned char*) sql_lock); |
509 | +void Session::unlockTables() |
510 | +{ |
511 | + |
512 | + if (lock) |
513 | + { |
514 | + lock->unlockTables(this); |
515 | + delete lock; |
516 | + lock= 0; |
517 | + } |
518 | + |
519 | +} |
520 | + |
521 | +void drizzled::Lock::unlockTables(Session *session) |
522 | +{ |
523 | + if (lock_count) |
524 | + thr_multi_unlock(locks,lock_count); |
525 | + if (table_count) |
526 | + session->unlockExternal(table, table_count); |
527 | + |
528 | return; |
529 | } |
530 | |
531 | -/** |
532 | - Unlock some of the tables locked by mysql_lock_tables. |
533 | - |
534 | - This will work even if get_lock_data fails (next unlock will free all) |
535 | -*/ |
536 | - |
537 | -void mysql_unlock_some_tables(Session *session, Table **table, uint32_t count) |
538 | +void Session::unlockSomeTables(Table **table,uint32_t count) |
539 | { |
540 | - DRIZZLE_LOCK *sql_lock; |
541 | + drizzled::Lock sql_lock; |
542 | Table *write_lock_used; |
543 | - if ((sql_lock= get_lock_data(session, table, count, false, |
544 | - &write_lock_used))) |
545 | - mysql_unlock_tables(session, sql_lock); |
546 | + |
547 | + if (sql_lock.initLockData(this, table, count, false, &write_lock_used)) |
548 | + { |
549 | + sql_lock.unlockTables(this); |
550 | + } |
551 | + |
552 | } |
553 | |
554 | |
555 | -/** |
556 | - unlock all tables locked for read. |
557 | -*/ |
558 | - |
559 | -void mysql_unlock_read_tables(Session *session, DRIZZLE_LOCK *sql_lock) |
560 | +void drizzled::Lock::unlockReadTables(Session *session) |
561 | { |
562 | - uint32_t i,found; |
563 | + uint32_t x,found; |
564 | |
565 | /* Move all write locks first */ |
566 | - THR_LOCK_DATA **lock=sql_lock->locks; |
567 | - for (i=found=0 ; i < sql_lock->lock_count ; i++) |
568 | + THR_LOCK_DATA **lock= locks; |
569 | + for (x= found= 0; x < lock_count; x++) |
570 | { |
571 | - if (sql_lock->locks[i]->type >= TL_WRITE_ALLOW_READ) |
572 | + if (locks[x]->type >= TL_WRITE_ALLOW_READ) |
573 | { |
574 | - std::swap(*lock, sql_lock->locks[i]); |
575 | + swap(*lock, locks[x]); |
576 | lock++; |
577 | found++; |
578 | } |
579 | } |
580 | /* unlock the read locked tables */ |
581 | - if (i != found) |
582 | + if (x != found) |
583 | { |
584 | - thr_multi_unlock(lock,i-found); |
585 | - sql_lock->lock_count= found; |
586 | + thr_multi_unlock(lock, x - found); |
587 | + lock_count= found; |
588 | } |
589 | |
590 | /* Then do the same for the external locks */ |
591 | /* Move all write locked tables first */ |
592 | - Table **table=sql_lock->table; |
593 | - for (i=found=0 ; i < sql_lock->table_count ; i++) |
594 | + Table **tbl= table; |
595 | + for (x= found= 0; x < table_count; x++) |
596 | { |
597 | - assert(sql_lock->table[i]->lock_position == i); |
598 | - if ((uint32_t) sql_lock->table[i]->reginfo.lock_type >= TL_WRITE_ALLOW_READ) |
599 | + assert(table[x]->lock_position == x); |
600 | + if ((uint32_t) table[x]->reginfo.lock_type >= TL_WRITE_ALLOW_READ) |
601 | { |
602 | - std::swap(*table, sql_lock->table[i]); |
603 | - table++; |
604 | + swap(*tbl, table[x]); |
605 | + tbl++; |
606 | found++; |
607 | } |
608 | } |
609 | /* Unlock all read locked tables */ |
610 | - if (i != found) |
611 | + if (x != found) |
612 | { |
613 | - unlock_external(session,table,i-found); |
614 | - sql_lock->table_count=found; |
615 | + session->unlockExternal(tbl, x-found); |
616 | + table_count= found; |
617 | } |
618 | /* Fix the lock positions in Table */ |
619 | - table= sql_lock->table; |
620 | + tbl= table; |
621 | found= 0; |
622 | - for (i= 0; i < sql_lock->table_count; i++) |
623 | + for (x= 0; x < table_count; x++) |
624 | { |
625 | - Table *tbl= *table; |
626 | - tbl->lock_position= table - sql_lock->table; |
627 | - tbl->lock_data_start= found; |
628 | - found+= tbl->lock_count; |
629 | - table++; |
630 | + Table *tbl2= *tbl; |
631 | + tbl2->lock_position= tbl - table; |
632 | + tbl2->lock_data_start= found; |
633 | + found+= tbl2->lock_count; |
634 | + tbl++; |
635 | } |
636 | return; |
637 | } |
638 | |
639 | - |
640 | -/** |
641 | - Try to find the table in the list of locked tables. |
642 | - In case of success, unlock the table and remove it from this list. |
643 | - |
644 | - @note This function has a legacy side effect: the table is |
645 | - unlocked even if it is not found in the locked list. |
646 | - It's not clear if this side effect is intentional or still |
647 | - desirable. It might lead to unmatched calls to |
648 | - unlock_external(). Moreover, a discrepancy can be left |
649 | - unnoticed by the storage engine, because in |
650 | - unlock_external() we call handler::external_lock(F_UNLCK) only |
651 | - if table->current_lock is not F_UNLCK. |
652 | - |
653 | - @param session thread context |
654 | - @param locked list of locked tables |
655 | - @param table the table to unlock |
656 | - @param always_unlock specify explicitly if the legacy side |
657 | - effect is desired. |
658 | -*/ |
659 | - |
660 | -void mysql_lock_remove(Session *session, Table *table) |
661 | -{ |
662 | - mysql_unlock_some_tables(session, &table, /* table count */ 1); |
663 | -} |
664 | - |
665 | - |
666 | -/** Abort all other threads waiting to get lock in table. */ |
667 | - |
668 | -void mysql_lock_abort(Session *session, Table *table) |
669 | -{ |
670 | - DRIZZLE_LOCK *locked; |
671 | +void Session::removeTableLock(Table *table) |
672 | +{ |
673 | + unlockSomeTables(&table, /* table count */ 1); |
674 | +} |
675 | + |
676 | +void drizzled::Lock::removeTable(Session *session, Table *tbl, bool always_unlock) |
677 | +{ |
678 | + register uint32_t x; |
679 | + for (x= 0; x < table_count; x++) |
680 | + { |
681 | + if (table[x] == tbl) |
682 | + { |
683 | + uint32_t j, removed_locks, old_tables; |
684 | + Table *tbl2; |
685 | + uint32_t lock_data_end; |
686 | + |
687 | + assert(tbl->lock_position == x); |
688 | + |
689 | + /* Unlock if not yet unlocked */ |
690 | + if (always_unlock == false) |
691 | + session->unlockSomeTables(&tbl, /* table count */ 1); |
692 | + |
693 | + /* Decrement table_count in advance, making below expressions easier */ |
694 | + old_tables= --table_count; |
695 | + |
696 | + /* The table has 'removed_locks' lock data elements in locks */ |
697 | + removed_locks= tbl->lock_count; |
698 | + |
699 | + /* Move down all table pointers above 'i'. */ |
700 | + memmove((table+x), (table+x+1), |
701 | + (old_tables - x) * sizeof(Table*)); |
702 | + |
703 | + lock_data_end= tbl->lock_data_start + tbl->lock_count; |
704 | + /* Move down all lock data pointers above 'tbl->lock_data_end-1' */ |
705 | + memmove((locks + tbl->lock_data_start), |
706 | + (locks + lock_data_end), |
707 | + (lock_count - lock_data_end) * |
708 | + sizeof(THR_LOCK_DATA*)); |
709 | + |
710 | + /* |
711 | + Fix moved table elements. |
712 | + lock_position is the index in the 'table' array, |
713 | + it must be fixed by one. |
714 | + table->lock_data_start is pointer to the lock data for this table |
715 | + in the 'locks' array, they must be fixed by 'removed_locks', |
716 | + the lock data count of the removed table. |
717 | + */ |
718 | + for (j= x; j < old_tables; j++) |
719 | + { |
720 | + tbl2= table[j]; |
721 | + tbl2->lock_position--; |
722 | + assert(tbl2->lock_position == j); |
723 | + tbl2->lock_data_start-= removed_locks; |
724 | + } |
725 | + |
726 | + /* Finally adjust lock_count. */ |
727 | + lock_count-= removed_locks; |
728 | + break; |
729 | + } |
730 | + } |
731 | +} |
732 | + |
733 | + |
734 | +void Session::abortLock(Table *table) |
735 | +{ |
736 | + drizzled::Lock locked; |
737 | Table *write_lock_used; |
738 | |
739 | - if ((locked= get_lock_data(session, &table, 1, false, |
740 | - &write_lock_used))) |
741 | + if (locked.initLockData(this, &table, 1, false, &write_lock_used)) |
742 | { |
743 | - for (uint32_t x= 0; x < locked->lock_count; x++) |
744 | - thr_abort_locks(locked->locks[x]->lock); |
745 | - free((unsigned char*) locked); |
746 | + for (uint32_t x= 0; x < locked.getLockCount(); x++) |
747 | + thr_abort_locks(locked.getLock(x)->lock); |
748 | } |
749 | } |
750 | |
751 | |
752 | -/** |
753 | - Abort one thread / table combination. |
754 | - |
755 | - @param session Thread handler |
756 | - @param table Table that should be removed from lock queue |
757 | - |
758 | - @retval |
759 | - 0 Table was not locked by another thread |
760 | - @retval |
761 | - 1 Table was locked by at least one other thread |
762 | -*/ |
763 | - |
764 | -bool mysql_lock_abort_for_thread(Session *session, Table *table) |
765 | +bool Session::abortLockForThread(Table *table) |
766 | { |
767 | - DRIZZLE_LOCK *locked; |
768 | + drizzled::Lock locked; |
769 | Table *write_lock_used; |
770 | bool result= false; |
771 | |
772 | - if ((locked= get_lock_data(session, &table, 1, false, |
773 | - &write_lock_used))) |
774 | + if (locked.initLockData(this, &table, 1, false, &write_lock_used)) |
775 | { |
776 | - for (uint32_t i=0; i < locked->lock_count; i++) |
777 | + for (uint32_t x= 0; x < locked.getLockCount(); x++) |
778 | { |
779 | - if (thr_abort_locks_for_thread(locked->locks[i]->lock, |
780 | + if (thr_abort_locks_for_thread(locked.getLock(x)->lock, |
781 | table->in_use->thread_id)) |
782 | result= true; |
783 | } |
784 | - free((unsigned char*) locked); |
785 | } |
786 | + |
787 | return result; |
788 | } |
789 | |
790 | @@ -504,7 +515,7 @@ |
791 | TableList *mysql_lock_have_duplicate(Session *session, TableList *needle, |
792 | TableList *haystack) |
793 | { |
794 | - DRIZZLE_LOCK *mylock; |
795 | + drizzled::Lock *mylock; |
796 | Table **lock_tables; |
797 | Table *table; |
798 | Table *table2; |
799 | @@ -530,14 +541,14 @@ |
800 | goto end; |
801 | |
802 | /* If we have less than two tables, we cannot have duplicates. */ |
803 | - if (mylock->table_count < 2) |
804 | + if (mylock->getTableCount() < 2) |
805 | goto end; |
806 | |
807 | - lock_locks= mylock->locks; |
808 | - lock_tables= mylock->table; |
809 | + lock_locks= mylock->getLocks(); |
810 | + lock_tables= mylock->getTable(); |
811 | |
812 | /* Prepare table related variables that don't change in loop. */ |
813 | - assert((table->lock_position < mylock->table_count) && |
814 | + assert((table->lock_position < mylock->getTableCount()) && |
815 | (table == lock_tables[table->lock_position])); |
816 | table_lock_data= lock_locks + table->lock_data_start; |
817 | end_data= table_lock_data + table->lock_count; |
818 | @@ -551,7 +562,7 @@ |
819 | continue; |
820 | |
821 | /* All tables in list must be in lock. */ |
822 | - assert((table2->lock_position < mylock->table_count) && |
823 | + assert((table2->lock_position < mylock->getTableCount()) && |
824 | (table2 == lock_tables[table2->lock_position])); |
825 | |
826 | for (lock_data2= lock_locks + table2->lock_data_start, |
827 | @@ -577,58 +588,45 @@ |
828 | } |
829 | |
830 | |
831 | -/** Unlock a set of external. */ |
832 | - |
833 | -static int unlock_external(Session *session, Table **table,uint32_t count) |
834 | +int Session::unlockExternal(Table **table,uint32_t count) |
835 | { |
836 | int error,error_code; |
837 | |
838 | - error_code=0; |
839 | + error_code= 0; |
840 | do |
841 | { |
842 | if ((*table)->current_lock != F_UNLCK) |
843 | { |
844 | - (*table)->current_lock = F_UNLCK; |
845 | - if ((error=(*table)->file->ha_external_lock(session, F_UNLCK))) |
846 | + (*table)->current_lock= F_UNLCK; |
847 | + if ((error= (*table)->file->ha_external_lock(this, F_UNLCK))) |
848 | { |
849 | - error_code=error; |
850 | - print_lock_error(error_code, (*table)->file->engine->getName().c_str()); |
851 | + error_code= error; |
852 | + print_lock_error(error_code, (*table)->file->engine->getName().c_str()); |
853 | } |
854 | } |
855 | table++; |
856 | } while (--count); |
857 | + |
858 | return error_code; |
859 | } |
860 | |
861 | |
862 | -/** |
863 | - Get lock structures from table structs and initialize locks. |
864 | - |
865 | - @param session Thread handler |
866 | - @param table_ptr Pointer to tables that should be locks |
867 | - @param should_lock One of: |
868 | - - false : If we should send TL_IGNORE to store lock |
869 | - - true : Store lock info in Table |
870 | - @param write_lock_used Store pointer to last table with WRITE_ALLOW_WRITE |
871 | -*/ |
872 | - |
873 | -static DRIZZLE_LOCK *get_lock_data(Session *session, Table **table_ptr, uint32_t count, |
874 | - bool should_lock, Table **write_lock_used) |
875 | +bool drizzled::Lock::initLockData(Session *session, Table **table_ptr, uint32_t count, |
876 | + bool should_lock, Table **write_lock_used) |
877 | { |
878 | - uint32_t i,tables,lock_count; |
879 | - DRIZZLE_LOCK *sql_lock; |
880 | - THR_LOCK_DATA **locks, **locks_buf, **locks_start; |
881 | + uint32_t x,tables,tbl_count; |
882 | + THR_LOCK_DATA **lcks, **locks_buf, **locks_start; |
883 | Table **to, **table_buf; |
884 | |
885 | - *write_lock_used=0; |
886 | - for (i= tables= lock_count= 0 ; i < count ; i++) |
887 | + *write_lock_used= 0; |
888 | + for (x= tables= tbl_count= 0; x < count; x++) |
889 | { |
890 | - Table *t= table_ptr[i]; |
891 | + Table *t= table_ptr[x]; |
892 | |
893 | if (t->s->tmp_table != NON_TRANSACTIONAL_TMP_TABLE) |
894 | { |
895 | tables++; |
896 | - lock_count++; |
897 | + tbl_count++; |
898 | } |
899 | } |
900 | |
901 | @@ -638,47 +636,43 @@ |
902 | update the table values. So the second part of the array is copied |
903 | from the first part immediately before calling thr_multi_lock(). |
904 | */ |
905 | - if (!(sql_lock= (DRIZZLE_LOCK*) |
906 | - malloc(sizeof(*sql_lock) + |
907 | - sizeof(THR_LOCK_DATA*) * tables * 2 + |
908 | - sizeof(table_ptr) * lock_count))) |
909 | - return NULL; |
910 | - locks= locks_buf= sql_lock->locks= (THR_LOCK_DATA**) (sql_lock + 1); |
911 | - to= table_buf= sql_lock->table= (Table**) (locks + tables * 2); |
912 | - sql_lock->table_count= lock_count; |
913 | + lcks= locks= locks_buf= (THR_LOCK_DATA**) malloc(sizeof(THR_LOCK_DATA*) * tables * 2 + sizeof(table_ptr) * tbl_count); |
914 | + to= table_buf= table= (Table**) (lcks + tables * 2); |
915 | + table_count= tbl_count; |
916 | |
917 | - for (i=0 ; i < count ; i++) |
918 | + for (x= 0; x < count; x++) |
919 | { |
920 | - Table *table; |
921 | + Table *tbl; |
922 | enum thr_lock_type lock_type; |
923 | |
924 | - if ((table=table_ptr[i])->s->tmp_table == NON_TRANSACTIONAL_TMP_TABLE) |
925 | + tbl= table_ptr[x]; |
926 | + if (tbl->s->tmp_table == NON_TRANSACTIONAL_TMP_TABLE) |
927 | continue; |
928 | - lock_type= table->reginfo.lock_type; |
929 | + lock_type= tbl->reginfo.lock_type; |
930 | assert (lock_type != TL_WRITE_DEFAULT); |
931 | if (lock_type >= TL_WRITE_ALLOW_WRITE) |
932 | { |
933 | - *write_lock_used=table; |
934 | - if (table->db_stat & HA_READ_ONLY) |
935 | + *write_lock_used= tbl; |
936 | + if (tbl->db_stat & HA_READ_ONLY) |
937 | { |
938 | - my_error(ER_OPEN_AS_READONLY,MYF(0),table->alias); |
939 | + my_error(ER_OPEN_AS_READONLY,MYF(0),tbl->alias); |
940 | /* Clear the lock type of the lock data that are stored already. */ |
941 | - sql_lock->lock_count= locks - sql_lock->locks; |
942 | - reset_lock_data_and_free(&sql_lock); |
943 | - return NULL; |
944 | + lock_count= lcks - locks; |
945 | + resetLockData(); |
946 | + return false; |
947 | } |
948 | } |
949 | - locks_start= locks; |
950 | - locks= table->file->store_lock(session, locks, |
951 | + locks_start= lcks; |
952 | + lcks= tbl->file->store_lock(session, lcks, |
953 | should_lock == false ? TL_IGNORE : lock_type); |
954 | if (should_lock) |
955 | { |
956 | - table->lock_position= (uint32_t) (to - table_buf); |
957 | - table->lock_data_start= (uint32_t) (locks_start - locks_buf); |
958 | - table->lock_count= (uint32_t) (locks - locks_start); |
959 | - assert(table->lock_count == 1); |
960 | + tbl->lock_position= (uint32_t) (to - table_buf); |
961 | + tbl->lock_data_start= (uint32_t) (locks_start - locks_buf); |
962 | + tbl->lock_count= (uint32_t) (lcks - locks_start); |
963 | + assert(tbl->lock_count == 1); |
964 | } |
965 | - *to++= table; |
966 | + *to++= tbl; |
967 | } |
968 | /* |
969 | We do not use 'tables', because there are cases where store_lock() |
970 | @@ -694,9 +688,9 @@ |
971 | we may allocate too much, but better safe than memory overrun. |
972 | And in the FLUSH case, the memory is released quickly anyway. |
973 | */ |
974 | - sql_lock->lock_count= locks - locks_buf; |
975 | + lock_count= lcks - locks_buf; |
976 | |
977 | - return sql_lock; |
978 | + return true; |
979 | } |
980 | |
981 | |
982 | |
983 | === modified file 'drizzled/lock.h' |
984 | --- drizzled/lock.h 2009-08-11 03:02:59 +0000 |
985 | +++ drizzled/lock.h 2009-10-21 06:25:19 +0000 |
986 | @@ -16,6 +16,11 @@ |
987 | * along with this program; if not, write to the Free Software |
988 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
989 | */ |
990 | +/** |
991 | + * @file |
992 | + * drizzled::Lock class definition and related functions for drizzle |
993 | + * |
994 | + */ |
995 | |
996 | #ifndef DRIZZLED_LOCK_H |
997 | #define DRIZZLED_LOCK_H |
998 | @@ -25,24 +30,188 @@ |
999 | class Session; |
1000 | class Table; |
1001 | class TableList; |
1002 | -typedef struct drizzled_lock_st DRIZZLE_LOCK; |
1003 | - |
1004 | -DRIZZLE_LOCK *mysql_lock_tables(Session *session, Table **table, uint32_t count, |
1005 | - uint32_t flags, bool *need_reopen); |
1006 | -/* mysql_lock_tables() and open_table() flags bits */ |
1007 | + |
1008 | +namespace drizzled |
1009 | +{ |
1010 | + /** |
1011 | + @defgroup Locking Locking |
1012 | + @{ |
1013 | + */ |
1014 | + /** |
1015 | + * Encapsulates THR_LOCK_DATA structures and Table list |
1016 | + */ |
1017 | + class Lock |
1018 | + { |
1019 | + public: |
1020 | + /** |
1021 | + * creates lock object and locks list of tables passed in |
1022 | + * |
1023 | + * @notes this used to be mysql_lock_tables |
1024 | + * |
1025 | + * @param[in] session thread handler |
1026 | + * @param[in] tables An array of pointers to the tables to lock. |
1027 | + * @param[in] count The number of tables to lock. |
1028 | + * |
1029 | + * @param[in] flag Options: |
1030 | + * DRIZZLE_LOCK_IGNORE_GLOBAL_READ_LOCK Ignore a global read lock |
1031 | + * DRIZZLE_LOCK_IGNORE_FLUSH Ignore a flush tables. |
1032 | + * DRIZZLE_LOCK_NOTIFY_IF_NEED_REOPEN Instead of reopening altered |
1033 | + * or dropped tables by itself, |
1034 | + * Session::lock_tables() should |
1035 | + * notify upper level and rely |
1036 | + * on caller doing this. |
1037 | + * @param[out] need_reopen TRUE if some tables were altered |
1038 | + * or deleted and should be reopened by caller. |
1039 | + * |
1040 | + * @return true if locking was successful, false it if was not |
1041 | + * |
1042 | + * @notes the meat of this used to be mysql_lock_tables() |
1043 | + * |
1044 | + */ |
1045 | + bool lockTables(Session *session,Table **table, uint32_t count, |
1046 | + uint32_t flags, bool *need_reopen); |
1047 | + |
1048 | + /** |
1049 | + * Get lock structures from table structs and initialize locks. |
1050 | + * |
1051 | + * @notes used in place of no defunct get_lock_data() |
1052 | + * @param session Thread handler |
1053 | + * @param table_ptr Pointer to tables that should be locks |
1054 | + * @param should_lock One of: |
1055 | + * - false : If we should send TL_IGNORE to store lock |
1056 | + * - true : Store lock info in Table |
1057 | + * @param write_lock_used Store pointer to last table with WRITE_ALLOW_WRITE |
1058 | + * |
1059 | + * @notes was get_lock_data() |
1060 | + */ |
1061 | + bool initLockData(Session *session, Table **table_ptr, uint32_t count, |
1062 | + bool should_lock, Table **write_lock_used); |
1063 | + |
1064 | + /** |
1065 | + * create a lock structure by merging two others |
1066 | + */ |
1067 | + Lock(Lock *a, Lock *b); |
1068 | + |
1069 | + Lock() |
1070 | + : |
1071 | + table(NULL), |
1072 | + table_count(0), |
1073 | + lock_count(0), |
1074 | + locks(NULL) |
1075 | + {} |
1076 | + |
1077 | + ~Lock(); |
1078 | + |
1079 | + /** |
1080 | + * calls thr_unlock_multi() on locks, and Session::unlockExternal for table |
1081 | + * |
1082 | + * @param[in] session Session object for unlockExternal |
1083 | + */ |
1084 | + void unlockTables(Session *session); |
1085 | + |
1086 | + /** |
1087 | + * unlock all READ-locked tables associated with this Lock object |
1088 | + * |
1089 | + * @param[in] session Session object used for unlockExternal |
1090 | + * |
1091 | + */ |
1092 | + void unlockReadTables(Session *session); |
1093 | + |
1094 | + /** |
1095 | + * remove a single table from from list of tables in this lock |
1096 | + * |
1097 | + * @param[in] session thread handler associated |
1098 | + * @param[in] tbl Table object specifying which table to remove |
1099 | + * @param[in] always_unlock false to only try to unlock the table using Session::unlockSomeTables |
1100 | + */ |
1101 | + void removeTable(Session *session, Table *tbl, bool always_unlock); |
1102 | + |
1103 | + /** |
1104 | + * @return pointer to list of locks |
1105 | + * @retval NULL list is empty |
1106 | + */ |
1107 | + inline THR_LOCK_DATA **getLocks() const |
1108 | + { |
1109 | + return locks; |
1110 | + } |
1111 | + |
1112 | + /** |
1113 | + * @return pointer to list of tables |
1114 | + * @retval NULL list is empty |
1115 | + */ |
1116 | + inline Table **getTable() const |
1117 | + { |
1118 | + return table; |
1119 | + } |
1120 | + |
1121 | + /** |
1122 | + * @return the lock at offset in locks list |
1123 | + */ |
1124 | + inline const THR_LOCK_DATA *getLock(uint32_t offset) const |
1125 | + { |
1126 | + return locks[offset]; |
1127 | + } |
1128 | + |
1129 | + /** |
1130 | + * @return the number of THR_LOCK_DATA structures in locks list |
1131 | + */ |
1132 | + inline const uint32_t getLockCount() const |
1133 | + { |
1134 | + return lock_count; |
1135 | + } |
1136 | + |
1137 | + /** |
1138 | + * @return table_count |
1139 | + */ |
1140 | + inline const uint32_t getTableCount() const |
1141 | + { |
1142 | + return table_count; |
1143 | + } |
1144 | + |
1145 | + private: |
1146 | + Table **table; ///< pointer to list of locked tables |
1147 | + uint32_t table_count; ///< the number of Table objects in table |
1148 | + uint32_t lock_count; ///< The number of THR_LOCK_DATA structures in locks |
1149 | + THR_LOCK_DATA **locks; ///< pointer to list of THR_LOCK_DATA structures |
1150 | + |
1151 | + /** |
1152 | + * private copy constructor to prevent copying |
1153 | + */ |
1154 | + Lock(Lock &other); |
1155 | + |
1156 | + /** |
1157 | + * Reset lock type in lock data and free. |
1158 | + * |
1159 | + * @note After a locking error we want to quit the locking of the table(s). |
1160 | + * The test case in the bug report for MySQL Bug #18544 has the following |
1161 | + * cases: |
1162 | + * 1. Locking error in Session::lockExternal() due to InnoDB timeout. |
1163 | + * 2. Locking error in drizzled::Lock::initLockData() due to missing write permission. |
1164 | + * 3. Locking error in wait_if_global_read_lock() due to lock conflict. |
1165 | + * |
1166 | + * @note In all these cases we have already set the lock type into the lock |
1167 | + * data of the open table(s). If the table(s) are in the open table |
1168 | + * cache, they could be reused with the non-zero lock type set. This |
1169 | + * could lead to ignoring a different lock type with the next lock. |
1170 | + * |
1171 | + * @note Clear the lock type of all lock data. This ensures that the next |
1172 | + * lock request will set its lock type properly. |
1173 | + */ |
1174 | + void resetLockData(); |
1175 | + }; |
1176 | +} |
1177 | +/** |
1178 | + @} end of group Locking |
1179 | + */ |
1180 | + |
1181 | +/* Session::lockTables() and open_table() flags bits */ |
1182 | #define DRIZZLE_LOCK_IGNORE_GLOBAL_READ_LOCK 0x0001 |
1183 | #define DRIZZLE_LOCK_IGNORE_FLUSH 0x0002 |
1184 | #define DRIZZLE_LOCK_NOTIFY_IF_NEED_REOPEN 0x0004 |
1185 | #define DRIZZLE_OPEN_TEMPORARY_ONLY 0x0008 |
1186 | |
1187 | -void mysql_unlock_tables(Session *session, DRIZZLE_LOCK *sql_lock); |
1188 | -void mysql_unlock_read_tables(Session *session, DRIZZLE_LOCK *sql_lock); |
1189 | -void mysql_unlock_some_tables(Session *session, Table **table, uint32_t count); |
1190 | -void mysql_lock_remove(Session *session, Table *table); |
1191 | -void mysql_lock_abort(Session *session, Table *table); |
1192 | -bool mysql_lock_abort_for_thread(Session *session, Table *table); |
1193 | TableList *mysql_lock_have_duplicate(Session *session, TableList *needle, |
1194 | - TableList *haystack); |
1195 | + TableList *haystack); |
1196 | bool lock_global_read_lock(Session *session); |
1197 | void unlock_global_read_lock(Session *session); |
1198 | bool wait_if_global_read_lock(Session *session, bool abort_on_refresh, |
1199 | |
1200 | === modified file 'drizzled/open_tables_state.h' |
1201 | --- drizzled/open_tables_state.h 2009-07-10 06:40:04 +0000 |
1202 | +++ drizzled/open_tables_state.h 2009-10-21 06:25:19 +0000 |
1203 | @@ -17,6 +17,7 @@ |
1204 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
1205 | */ |
1206 | |
1207 | +#include <drizzled/lock.h> |
1208 | |
1209 | #ifndef DRIZZLED_OPEN_TABLES_STATE_H |
1210 | #define DRIZZLED_OPEN_TABLES_STATE_H |
1211 | @@ -59,14 +60,14 @@ |
1212 | the 'LOCK_TABLES' chapter of the MySQL manual. |
1213 | See also lock_tables() for details. |
1214 | */ |
1215 | - DRIZZLE_LOCK *lock; |
1216 | + drizzled::Lock *lock; |
1217 | |
1218 | /* |
1219 | CREATE-SELECT keeps an extra lock for the table being |
1220 | created. This field is used to keep the extra lock available for |
1221 | lower level routines, which would otherwise miss that lock. |
1222 | */ |
1223 | - DRIZZLE_LOCK *extra_lock; |
1224 | + drizzled::Lock *extra_lock; |
1225 | |
1226 | ulong version; |
1227 | uint32_t current_tablenr; |
1228 | |
1229 | === modified file 'drizzled/select_create.h' |
1230 | --- drizzled/select_create.h 2009-09-15 21:01:42 +0000 |
1231 | +++ drizzled/select_create.h 2009-10-21 06:25:19 +0000 |
1232 | @@ -29,9 +29,9 @@ |
1233 | AlterInfo *alter_info; |
1234 | Field **field; |
1235 | /* lock data for tmp table */ |
1236 | - DRIZZLE_LOCK *m_lock; |
1237 | + drizzled::Lock *m_lock; |
1238 | /* m_lock or session->extra_lock */ |
1239 | - DRIZZLE_LOCK **m_plock; |
1240 | + drizzled::Lock **m_plock; |
1241 | public: |
1242 | select_create (TableList *table_arg, |
1243 | HA_CREATE_INFO *create_info_par, |
1244 | @@ -54,6 +54,7 @@ |
1245 | bool send_eof(); |
1246 | void abort(); |
1247 | virtual bool can_rollback_data() { return 1; } |
1248 | + void unlock_tables(); |
1249 | |
1250 | // Needed for access from local class MY_HOOKS in prepare(), since session is proteted. |
1251 | const Session *get_session(void) { return session; } |
1252 | |
1253 | === modified file 'drizzled/select_send.h' |
1254 | --- drizzled/select_send.h 2009-10-01 17:56:07 +0000 |
1255 | +++ drizzled/select_send.h 2009-10-21 06:25:19 +0000 |
1256 | @@ -42,11 +42,7 @@ |
1257 | drizzled::plugin::StorageEngine::releaseTemporaryLatches(session); |
1258 | |
1259 | /* Unlock tables before sending packet to gain some speed */ |
1260 | - if (session->lock) |
1261 | - { |
1262 | - mysql_unlock_tables(session, session->lock); |
1263 | - session->lock= 0; |
1264 | - } |
1265 | + session->unlockTables(); |
1266 | session->my_eof(); |
1267 | is_result_set_started= 0; |
1268 | return false; |
1269 | |
1270 | === modified file 'drizzled/session.cc' |
1271 | --- drizzled/session.cc 2009-10-12 23:23:18 +0000 |
1272 | +++ drizzled/session.cc 2009-10-21 06:25:19 +0000 |
1273 | @@ -2075,20 +2075,8 @@ |
1274 | transaction.stmt.reset(); |
1275 | } |
1276 | |
1277 | - if (lock) |
1278 | - { |
1279 | - /* |
1280 | - For RBR we flush the pending event just before we unlock all the |
1281 | - tables. This means that we are at the end of a topmost |
1282 | - statement, so we ensure that the STMT_END_F flag is set on the |
1283 | - pending event. For statements that are *inside* stored |
1284 | - functions, the pending event will not be flushed: that will be |
1285 | - handled either before writing a query log event (inside |
1286 | - binlog_query()) or when preparing a pending event. |
1287 | - */ |
1288 | - mysql_unlock_tables(this, lock); |
1289 | - lock= 0; |
1290 | - } |
1291 | + unlockTables(); |
1292 | + |
1293 | /* |
1294 | Note that we need to hold LOCK_open while changing the |
1295 | open_tables list. Another thread may work on it. |
1296 | |
1297 | === modified file 'drizzled/session.h' |
1298 | --- drizzled/session.h 2009-10-16 00:38:56 +0000 |
1299 | +++ drizzled/session.h 2009-10-21 06:25:19 +0000 |
1300 | @@ -93,14 +93,6 @@ |
1301 | /* for VIEW ... WITH CHECK OPTION */ |
1302 | } COPY_INFO; |
1303 | |
1304 | -typedef struct drizzled_lock_st |
1305 | -{ |
1306 | - Table **table; |
1307 | - uint32_t table_count; |
1308 | - uint32_t lock_count; |
1309 | - THR_LOCK_DATA **locks; |
1310 | -} DRIZZLE_LOCK; |
1311 | - |
1312 | #include <drizzled/lex_column.h> |
1313 | |
1314 | class select_result; |
1315 | @@ -1230,6 +1222,70 @@ |
1316 | return connect_microseconds; |
1317 | } |
1318 | |
1319 | + /** |
1320 | + * If there are any locks associated with this session, unlock and destroy |
1321 | + * the lock object. |
1322 | + */ |
1323 | + void unlockTables(); |
1324 | + drizzled::Lock *lockTables(Table **tables, uint32_t count, |
1325 | + uint32_t flags, bool *need_reopen); |
1326 | + |
1327 | + /** |
1328 | + * Lock tables in storage engine |
1329 | + * |
1330 | + * @param table list of tables to lock |
1331 | + * @param count number of tables in list |
1332 | + * @return return code from ha_external_lock if error ocurred |
1333 | + * @retval 0 No errors ocurred |
1334 | + */ |
1335 | + int lockExternal(Table **table,uint32_t count); |
1336 | + |
1337 | + /** |
1338 | + * Unlock tables in storage engine |
1339 | + * |
1340 | + * @param table list of tables to unlock |
1341 | + * @param count number of tables to unlock |
1342 | + * @return return code from ha_external_unlock if error ocurred |
1343 | + * @retval 0 No errors ocurred |
1344 | + */ |
1345 | + int unlockExternal(Table **table, uint32_t count); |
1346 | + |
1347 | + /** |
1348 | + * Unlock some of the tables locked by Session::lockTables. |
1349 | + * |
1350 | + * @note This will work even if drizzled::Lock::initLockData fails (next |
1351 | + * unlock will free all) |
1352 | + * |
1353 | + * @note this used to be mysql_unlock_some_tables |
1354 | + */ |
1355 | + void unlockSomeTables(Table **table, uint32_t count); |
1356 | + |
1357 | + /** |
1358 | + * Calls Session::unlockSomeTables with a single table |
1359 | + * |
1360 | + * @param table the table to unlock |
1361 | + */ |
1362 | + void removeTableLock(Table *table); |
1363 | + |
1364 | + /** |
1365 | + * Abort all threads waiting on lock |
1366 | + * |
1367 | + * @param table[in] table to abort locks for |
1368 | + */ |
1369 | + void abortLock(Table *table); |
1370 | + |
1371 | + /** |
1372 | + * Abort one thread / table combination. |
1373 | + * |
1374 | + * @param table Table that should be removed from lock queue |
1375 | + * |
1376 | + * @retval |
1377 | + * false Table was not locked by another thread |
1378 | + * @retval |
1379 | + * true Table was locked by at least one other thread |
1380 | + */ |
1381 | + bool abortLockForThread(Table *table); |
1382 | + |
1383 | private: |
1384 | /** Microsecond timestamp of when Session connected */ |
1385 | uint64_t connect_microseconds; |
1386 | |
1387 | === modified file 'drizzled/sql_base.cc' |
1388 | --- drizzled/sql_base.cc 2009-10-16 10:27:33 +0000 |
1389 | +++ drizzled/sql_base.cc 2009-10-21 06:25:19 +0000 |
1390 | @@ -1496,7 +1496,6 @@ |
1391 | return(error); |
1392 | } |
1393 | |
1394 | - |
1395 | /** |
1396 | Close all instances of a table open by this thread and replace |
1397 | them with exclusive name-locks. |
1398 | @@ -1520,15 +1519,11 @@ |
1399 | |
1400 | safe_mutex_assert_owner(&LOCK_open); /* Adjust locks at the end of ALTER TABLEL */ |
1401 | |
1402 | - if (lock) |
1403 | - { |
1404 | - /* |
1405 | - If we are not under LOCK TABLES we should have only one table |
1406 | - open and locked so it makes sense to remove the lock at once. |
1407 | - */ |
1408 | - mysql_unlock_tables(this, lock); |
1409 | - lock= 0; |
1410 | - } |
1411 | + /* |
1412 | + If we are not under LOCK TABLES we should have only one table |
1413 | + open and locked so it makes sense to remove the lock at once. |
1414 | + */ |
1415 | + unlockTables(); |
1416 | |
1417 | /* |
1418 | Note that open table list may contain a name-lock placeholder |
1419 | @@ -1624,7 +1619,7 @@ |
1420 | *prev=0; |
1421 | if (tables != tables_ptr) // Should we get back old locks |
1422 | { |
1423 | - DRIZZLE_LOCK *local_lock; |
1424 | + drizzled::Lock *local_lock= new (nothrow) drizzled::Lock; |
1425 | /* |
1426 | We should always get these locks. Anyway, we must not go into |
1427 | wait_for_tables() as it tries to acquire LOCK_open, which is |
1428 | @@ -1632,12 +1627,8 @@ |
1429 | */ |
1430 | some_tables_deleted= false; |
1431 | |
1432 | - if ((local_lock= mysql_lock_tables(this, tables, (uint32_t) (tables_ptr - tables), |
1433 | - flags, ¬_used))) |
1434 | - { |
1435 | - /* unused */ |
1436 | - } |
1437 | - else |
1438 | + if (local_lock && !local_lock->lockTables(this, tables, (uint32_t) (tables_ptr - tables), |
1439 | + flags, ¬_used)) |
1440 | { |
1441 | /* |
1442 | This case should only happen if there is a bug in the reopen logic. |
1443 | @@ -1699,8 +1690,8 @@ |
1444 | lock on it. This will also give them a chance to close their |
1445 | instances of this table. |
1446 | */ |
1447 | - mysql_lock_abort(this, ulcktbl); |
1448 | - mysql_lock_remove(this, ulcktbl); |
1449 | + abortLock(ulcktbl); |
1450 | + removeTableLock(ulcktbl); |
1451 | ulcktbl->lock_count= 0; |
1452 | } |
1453 | if ((ulcktbl != table) && ulcktbl->db_stat) |
1454 | @@ -1856,7 +1847,7 @@ |
1455 | if (!strcmp(table->s->table_name.str, table_name) && |
1456 | !strcmp(table->s->db.str, db)) |
1457 | { |
1458 | - mysql_lock_remove(session, table); |
1459 | + session->removeTableLock(table); |
1460 | |
1461 | if (!found) |
1462 | { |
1463 | @@ -1903,7 +1894,7 @@ |
1464 | !strcmp(table->s->db.str, db)) |
1465 | { |
1466 | /* If MERGE child, forward lock handling to parent. */ |
1467 | - mysql_lock_abort(session, table); |
1468 | + session->abortLock(table); |
1469 | break; |
1470 | } |
1471 | } |
1472 | @@ -2254,7 +2245,7 @@ |
1473 | |
1474 | assert(lock == 0); // You must lock everything at once |
1475 | if ((table->reginfo.lock_type= lock_type) != TL_UNLOCK) |
1476 | - if (! (lock= mysql_lock_tables(this, &table_list->table, 1, 0, &refresh))) |
1477 | + if (! (lock= lockTables(&table_list->table, 1, 0, &refresh))) |
1478 | table= 0; |
1479 | } |
1480 | |
1481 | @@ -2317,8 +2308,8 @@ |
1482 | *(ptr++)= table->table; |
1483 | } |
1484 | |
1485 | - if (!(session->lock= mysql_lock_tables(session, start, (uint32_t) (ptr - start), |
1486 | - lock_flag, need_reopen))) |
1487 | + if (! (session->lock= session->lockTables(start, static_cast<uint32_t>(ptr - start), |
1488 | + lock_flag, need_reopen))) |
1489 | { |
1490 | return -1; |
1491 | } |
1492 | @@ -4686,7 +4677,7 @@ |
1493 | { |
1494 | /* |
1495 | Mark that table is going to be deleted from cache. This will |
1496 | - force threads that are in mysql_lock_tables() (but not yet |
1497 | + force threads that are in Session::lockTables() (but not yet |
1498 | in thr_multi_lock()) to abort it's locks, close all tables and retry |
1499 | */ |
1500 | in_use->some_tables_deleted= true; |
1501 | @@ -4709,7 +4700,7 @@ |
1502 | { |
1503 | /* Do not handle locks of MERGE children. */ |
1504 | if (session_table->db_stat) // If table is open |
1505 | - signalled|= mysql_lock_abort_for_thread(session, session_table); |
1506 | + signalled|= session->abortLockForThread(session_table); |
1507 | } |
1508 | } |
1509 | else |
1510 | |
1511 | === modified file 'drizzled/sql_insert.cc' |
1512 | --- drizzled/sql_insert.cc 2009-10-01 17:56:07 +0000 |
1513 | +++ drizzled/sql_insert.cc 2009-10-21 06:25:19 +0000 |
1514 | @@ -1458,7 +1458,7 @@ |
1515 | message::Table *table_proto, |
1516 | AlterInfo *alter_info, |
1517 | List<Item> *items, |
1518 | - DRIZZLE_LOCK **lock) |
1519 | + drizzled::Lock **lock) |
1520 | { |
1521 | Table tmp_table; // Used during 'CreateField()' |
1522 | TableShare share; |
1523 | @@ -1581,12 +1581,13 @@ |
1524 | } |
1525 | |
1526 | table->reginfo.lock_type=TL_WRITE; |
1527 | - if (! ((*lock)= mysql_lock_tables(session, &table, 1, |
1528 | - DRIZZLE_LOCK_IGNORE_FLUSH, ¬_used))) |
1529 | + if (! ((*lock)= session->lockTables(&table, 1, |
1530 | + DRIZZLE_LOCK_IGNORE_FLUSH, ¬_used))) |
1531 | { |
1532 | if (*lock) |
1533 | { |
1534 | - mysql_unlock_tables(session, *lock); |
1535 | + (*lock)->unlockTables(session); |
1536 | + delete *lock; |
1537 | *lock= 0; |
1538 | } |
1539 | |
1540 | @@ -1602,7 +1603,7 @@ |
1541 | int |
1542 | select_create::prepare(List<Item> &values, Select_Lex_Unit *u) |
1543 | { |
1544 | - DRIZZLE_LOCK *extra_lock= NULL; |
1545 | + drizzled::Lock *extra_lock= NULL; |
1546 | /* |
1547 | For row-based replication, the CREATE-SELECT statement is written |
1548 | in two pieces: the first one contain the CREATE TABLE statement |
1549 | @@ -1729,17 +1730,21 @@ |
1550 | |
1551 | table->file->extra(HA_EXTRA_NO_IGNORE_DUP_KEY); |
1552 | table->file->extra(HA_EXTRA_WRITE_CANNOT_REPLACE); |
1553 | + unlock_tables(); |
1554 | + } |
1555 | + return tmp; |
1556 | +} |
1557 | + |
1558 | +void select_create::unlock_tables() |
1559 | +{ |
1560 | if (m_plock) |
1561 | { |
1562 | - mysql_unlock_tables(session, *m_plock); |
1563 | - *m_plock= NULL; |
1564 | + (*m_plock)->unlockTables(session); |
1565 | + delete *m_plock; |
1566 | m_plock= NULL; |
1567 | } |
1568 | - } |
1569 | - return tmp; |
1570 | } |
1571 | |
1572 | - |
1573 | void select_create::abort() |
1574 | { |
1575 | |
1576 | @@ -1762,13 +1767,7 @@ |
1577 | select_insert::abort(); |
1578 | session->transaction.stmt.modified_non_trans_table= false; |
1579 | |
1580 | - |
1581 | - if (m_plock) |
1582 | - { |
1583 | - mysql_unlock_tables(session, *m_plock); |
1584 | - *m_plock= NULL; |
1585 | - m_plock= NULL; |
1586 | - } |
1587 | + unlock_tables(); |
1588 | |
1589 | if (table) |
1590 | { |
1591 | |
1592 | === modified file 'drizzled/sql_table.cc' |
1593 | --- drizzled/sql_table.cc 2009-10-16 10:27:33 +0000 |
1594 | +++ drizzled/sql_table.cc 2009-10-21 06:25:19 +0000 |
1595 | @@ -1968,7 +1968,7 @@ |
1596 | |
1597 | table->file->extra(function); |
1598 | /* Mark all tables that are in use as 'old' */ |
1599 | - mysql_lock_abort(session, table); /* end threads waiting on lock */ |
1600 | + session->abortLock(table); /* end threads waiting on lock */ |
1601 | |
1602 | /* Wait until all there are no other threads that has this table open */ |
1603 | remove_table_from_cache(session, table->s->db.str, |
1604 | @@ -1998,11 +1998,7 @@ |
1605 | |
1606 | wait_while_table_is_used(this, table, HA_EXTRA_FORCE_REOPEN); |
1607 | /* Close lock if this is not got with LOCK TABLES */ |
1608 | - if (lock) |
1609 | - { |
1610 | - mysql_unlock_tables(this, lock); |
1611 | - lock= NULL; // Start locked threads |
1612 | - } |
1613 | + unlockTables(); |
1614 | /* Close all copies of 'table'. This also frees all LOCK TABLES lock */ |
1615 | unlink_open_table(table); |
1616 | |
1617 | @@ -2144,7 +2140,7 @@ |
1618 | pthread_mutex_lock(&LOCK_open); /* Lock type is TL_WRITE and we lock to repair the table */ |
1619 | const char *old_message=session->enter_cond(&COND_refresh, &LOCK_open, |
1620 | "Waiting to get writelock"); |
1621 | - mysql_lock_abort(session,table->table); |
1622 | + session->abortLock(table->table); |
1623 | remove_table_from_cache(session, table->table->s->db.str, |
1624 | table->table->s->table_name.str, |
1625 | RTFC_WAIT_OTHER_THREAD_FLAG | |
1626 | |
1627 | === modified file 'drizzled/statement/alter_table.cc' |
1628 | --- drizzled/statement/alter_table.cc 2009-10-12 23:23:18 +0000 |
1629 | +++ drizzled/statement/alter_table.cc 2009-10-21 06:25:19 +0000 |
1630 | @@ -1028,11 +1028,7 @@ |
1631 | goto err1; |
1632 | |
1633 | /* Close lock if this is a transactional table */ |
1634 | - if (session->lock) |
1635 | - { |
1636 | - mysql_unlock_tables(session, session->lock); |
1637 | - session->lock= 0; |
1638 | - } |
1639 | + session->unlockTables(); |
1640 | |
1641 | /* Remove link to old table and rename the new one */ |
1642 | session->close_temporary_table(table, true, true); |
1643 | |
1644 | === modified file 'drizzled/table.h' |
1645 | --- drizzled/table.h 2009-10-16 10:27:33 +0000 |
1646 | +++ drizzled/table.h 2009-10-21 06:25:19 +0000 |
1647 | @@ -95,8 +95,8 @@ |
1648 | const char *alias; /**< alias or table name if no alias */ |
1649 | unsigned char *null_flags; |
1650 | |
1651 | - uint32_t lock_position; /**< Position in DRIZZLE_LOCK.table */ |
1652 | - uint32_t lock_data_start; /**< Start pos. in DRIZZLE_LOCK.locks */ |
1653 | + uint32_t lock_position; /**< Position in drizzled::Lock.table */ |
1654 | + uint32_t lock_data_start; /**< Start pos. in drizzled::Lock.locks */ |
1655 | uint32_t lock_count; /**< Number of locks */ |
1656 | uint32_t used_fields; |
1657 | uint32_t status; /* What's in record[0] */ |
* Refactors DRIZZLE_LOCK into drizzled::Lock
* Refactors major global locking functions as methods of either Session or drizzled::Lock