72
72
Change to use malloc() ONLY when using LOCK TABLES command or when
73
73
we are forced to use mysql_lock_merge.
75
#include <drizzled/server_includes.h>
77
76
#include <drizzled/error.h>
78
#include <drizzled/my_hash.h>
79
#include <drizzled/thr_lock.h>
77
#include <mysys/hash.h>
78
#include <mysys/thr_lock.h>
80
79
#include <drizzled/session.h>
81
80
#include <drizzled/sql_base.h>
82
81
#include <drizzled/lock.h>
83
#include "drizzled/pthread_globals.h"
84
#include "drizzled/internal/my_sys.h"
97
84
@defgroup Locking Locking
214
session->set_proc_info("Notify start statement");
216
* Here, we advise all storage engines involved in the
217
* statement that we are starting a new statement
219
if (sql_lock->table_count)
221
size_t num_tables= sql_lock->table_count;
222
plugin::StorageEngine *engine;
223
set<size_t> involved_slots;
224
for (size_t x= 1; x <= num_tables; x++, tables++)
226
engine= (*tables)->cursor->engine;
227
if (involved_slots.count(engine->getId()) > 0)
228
continue; /* already added to involved engines */
229
involved_engines.push_back(engine);
230
involved_slots.insert(engine->getId());
233
for_each(involved_engines.begin(),
234
involved_engines.end(),
235
bind2nd(mem_fun(&plugin::StorageEngine::startStatement), session));
238
session->set_proc_info("External lock");
240
* Here, the call to lock_external() informs the
241
* all engines for all tables used in this statement
242
* of the type of lock that Drizzle intends to take on a
200
session->set_proc_info("System lock");
245
201
if (sql_lock->table_count && lock_external(session, sql_lock->table,
246
202
sql_lock->table_count))
301
257
type for other tables preserved.
303
259
reset_lock_data_and_free(&sql_lock);
306
* Notify all involved engines that the
307
* SQL statement has ended
309
for_each(involved_engines.begin(),
310
involved_engines.end(),
311
bind2nd(mem_fun(&plugin::StorageEngine::endStatement), session));
313
261
if (flags & DRIZZLE_LOCK_NOTIFY_IF_NEED_REOPEN)
346
295
(*tables)->reginfo.lock_type <= TL_READ_NO_INSERT))
347
296
lock_type=F_RDLCK;
349
if ((error=(*tables)->cursor->ha_external_lock(session,lock_type)))
298
if ((error=(*tables)->file->ha_external_lock(session,lock_type)))
351
print_lock_error(error, (*tables)->cursor->engine->getName().c_str());
300
print_lock_error(error, (*tables)->file->engine->getName().c_str());
355
(*tables)->cursor->ha_external_lock(session, F_UNLCK);
304
(*tables)->file->ha_external_lock(session, F_UNLCK);
356
305
(*tables)->current_lock=F_UNLCK;
482
Find duplicate lock in tables.
484
Temporary tables are ignored here like they are ignored in
485
get_lock_data(). If we allow two opens on temporary tables later,
486
both functions should be checked.
488
@param session The current thread.
489
@param needle The table to check for duplicate lock.
490
@param haystack The list of tables to search for the dup lock.
493
This is mainly meant for MERGE tables in INSERT ... SELECT
494
situations. The 'real', underlying tables can be found only after
495
the MERGE tables are opened. This function assumes that the tables are
499
NULL No duplicate lock found.
501
!NULL First table from 'haystack' that matches a lock on 'needle'.
504
TableList *mysql_lock_have_duplicate(Session *session, TableList *needle,
507
DRIZZLE_LOCK *mylock;
511
THR_LOCK_DATA **lock_locks;
512
THR_LOCK_DATA **table_lock_data;
513
THR_LOCK_DATA **end_data;
514
THR_LOCK_DATA **lock_data2;
515
THR_LOCK_DATA **end_data2;
518
Table may not be defined for derived or view tables.
519
Table may not be part of a lock for delayed operations.
521
if (! (table= needle->table) || ! table->lock_count)
524
/* A temporary table does not have locks. */
525
if (table->s->tmp_table == NON_TRANSACTIONAL_TMP_TABLE)
528
/* Get command lock or LOCK TABLES lock. Maybe empty for INSERT DELAYED. */
529
if (!(mylock= session->lock))
532
/* If we have less than two tables, we cannot have duplicates. */
533
if (mylock->table_count < 2)
536
lock_locks= mylock->locks;
537
lock_tables= mylock->table;
539
/* Prepare table related variables that don't change in loop. */
540
assert((table->lock_position < mylock->table_count) &&
541
(table == lock_tables[table->lock_position]));
542
table_lock_data= lock_locks + table->lock_data_start;
543
end_data= table_lock_data + table->lock_count;
545
for (; haystack; haystack= haystack->next_global)
547
if (haystack->placeholder())
549
table2= haystack->table;
550
if (table2->s->tmp_table == NON_TRANSACTIONAL_TMP_TABLE)
553
/* All tables in list must be in lock. */
554
assert((table2->lock_position < mylock->table_count) &&
555
(table2 == lock_tables[table2->lock_position]));
557
for (lock_data2= lock_locks + table2->lock_data_start,
558
end_data2= lock_data2 + table2->lock_count;
559
lock_data2 < end_data2;
562
THR_LOCK_DATA **lock_data;
563
THR_LOCK *lock2= (*lock_data2)->lock;
565
for (lock_data= table_lock_data;
566
lock_data < end_data;
569
if ((*lock_data)->lock == lock2)
531
580
/** Unlock a set of external. */
533
582
static int unlock_external(Session *session, Table **table,uint32_t count)
540
589
if ((*table)->current_lock != F_UNLCK)
542
591
(*table)->current_lock = F_UNLCK;
543
if ((error=(*table)->cursor->ha_external_lock(session, F_UNLCK)))
592
if ((error=(*table)->file->ha_external_lock(session, F_UNLCK)))
545
594
error_code=error;
546
print_lock_error(error_code, (*table)->cursor->engine->getName().c_str());
595
print_lock_error(error_code, (*table)->file->engine->getName().c_str());
1048
1095
session->global_read_lock= 0;
1051
static inline bool must_wait(bool is_not_commit)
1053
return (global_read_lock &&
1055
global_read_lock_blocks_commit));
1098
#define must_wait (global_read_lock && \
1100
global_read_lock_blocks_commit))
1058
1102
bool wait_if_global_read_lock(Session *session, bool abort_on_refresh,
1059
1103
bool is_not_commit)
1087
1131
old_message=session->enter_cond(&COND_global_read_lock, &LOCK_global_read_lock,
1088
1132
"Waiting for release of readlock");
1089
while (must_wait(is_not_commit) && ! session->killed &&
1133
while (must_wait && ! session->killed &&
1090
1134
(!abort_on_refresh || session->version == refresh_version))
1092
1136
(void) pthread_cond_wait(&COND_global_read_lock, &LOCK_global_read_lock);