summaryrefslogtreecommitdiff
path: root/sql/mdl.h
diff options
context:
space:
mode:
Diffstat (limited to 'sql/mdl.h')
-rw-r--r--sql/mdl.h52
1 files changed, 38 insertions, 14 deletions
diff --git a/sql/mdl.h b/sql/mdl.h
index 55d6ddf845b..31ac4e81377 100644
--- a/sql/mdl.h
+++ b/sql/mdl.h
@@ -1,6 +1,7 @@
#ifndef MDL_H
#define MDL_H
/* Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2020, 2021, MariaDB
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -16,6 +17,7 @@
51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA */
#include "sql_plist.h"
+#include "ilist.h"
#include <my_sys.h>
#include <m_string.h>
#include <mysql_com.h>
@@ -355,7 +357,7 @@ enum enum_mdl_duration {
or "name".
*/
-class MDL_key
+struct MDL_key
{
public:
#ifdef HAVE_PSI_INTERFACE
@@ -537,18 +539,23 @@ public:
/** A lock is requested based on a fully qualified name and type. */
MDL_key key;
+ const char *m_src_file;
+ uint m_src_line;
+
public:
static void *operator new(size_t size, MEM_ROOT *mem_root) throw ()
{ return alloc_root(mem_root, size); }
static void operator delete(void *, MEM_ROOT *) {}
- void init(MDL_key::enum_mdl_namespace namespace_arg,
+ void init_with_source(MDL_key::enum_mdl_namespace namespace_arg,
const char *db_arg, const char *name_arg,
enum_mdl_type mdl_type_arg,
- enum_mdl_duration mdl_duration_arg);
- void init(const MDL_key *key_arg, enum_mdl_type mdl_type_arg,
- enum_mdl_duration mdl_duration_arg);
+ enum_mdl_duration mdl_duration_arg,
+ const char *src_file, uint src_line);
+ void init_by_key_with_source(const MDL_key *key_arg, enum_mdl_type mdl_type_arg,
+ enum_mdl_duration mdl_duration_arg,
+ const char *src_file, uint src_line);
/** Set type of lock request. Can be only applied to pending locks. */
inline void set_type(enum_mdl_type type_arg)
{
@@ -613,6 +620,12 @@ public:
typedef void (*mdl_cached_object_release_hook)(void *);
+#define MDL_REQUEST_INIT(R, P1, P2, P3, P4, P5) \
+ (*R).init_with_source(P1, P2, P3, P4, P5, __FILE__, __LINE__)
+
+#define MDL_REQUEST_INIT_BY_KEY(R, P1, P2, P3) \
+ (*R).init_by_key_with_source(P1, P2, P3, __FILE__, __LINE__)
+
/**
An abstract class for inspection of a connected
@@ -677,7 +690,7 @@ public:
threads/contexts.
*/
-class MDL_ticket : public MDL_wait_for_subgraph
+class MDL_ticket : public MDL_wait_for_subgraph, public ilist_node<>
{
public:
/**
@@ -686,15 +699,9 @@ public:
*/
MDL_ticket *next_in_context;
MDL_ticket **prev_in_context;
- /**
- Pointers for participating in the list of satisfied/pending requests
- for the lock. Externally accessible.
- */
- MDL_ticket *next_in_lock;
- MDL_ticket **prev_in_lock;
public:
#ifdef WITH_WSREP
- void wsrep_report(bool debug);
+ void wsrep_report(bool debug) const;
#endif /* WITH_WSREP */
bool has_pending_conflicting_lock() const;
@@ -721,6 +728,11 @@ public:
/** Implement MDL_wait_for_subgraph interface. */
virtual bool accept_visitor(MDL_wait_for_graph_visitor *dvisitor);
virtual uint get_deadlock_weight() const;
+ /**
+ Status of lock request represented by the ticket as reflected in P_S.
+ */
+ enum enum_psi_status { PENDING = 0, GRANTED,
+ PRE_ACQUIRE_NOTIFY, POST_RELEASE_NOTIFY };
private:
friend class MDL_context;
@@ -734,9 +746,15 @@ private:
m_duration(duration_arg),
#endif
m_ctx(ctx_arg),
- m_lock(NULL)
+ m_lock(NULL),
+ m_psi(NULL)
{}
+ virtual ~MDL_ticket()
+ {
+ DBUG_ASSERT(m_psi == NULL);
+ }
+
static MDL_ticket *create(MDL_context *ctx_arg, enum_mdl_type type_arg
#ifndef DBUG_OFF
, enum_mdl_duration duration_arg
@@ -763,6 +781,8 @@ private:
*/
MDL_lock *m_lock;
+ PSI_metadata_lock *m_psi;
+
private:
MDL_ticket(const MDL_ticket &); /* not implemented */
MDL_ticket &operator=(const MDL_ticket &); /* not implemented */
@@ -885,6 +905,10 @@ public:
m_tickets[MDL_TRANSACTION].is_empty() &&
m_tickets[MDL_EXPLICIT].is_empty());
}
+ bool has_explicit_locks() const
+ {
+ return !m_tickets[MDL_EXPLICIT].is_empty();
+ }
inline bool has_transactional_locks() const
{
return !m_tickets[MDL_TRANSACTION].is_empty();