diff options
Diffstat (limited to 'sql')
-rw-r--r-- | sql/sql_plugin.cc | 48 | ||||
-rw-r--r-- | sql/sql_plugin_services.h | 9 |
2 files changed, 57 insertions, 0 deletions
diff --git a/sql/sql_plugin.cc b/sql/sql_plugin.cc index 207804c53f6..0e6f2ce4ec3 100644 --- a/sql/sql_plugin.cc +++ b/sql/sql_plugin.cc @@ -4085,3 +4085,51 @@ static void restore_ptr_backup(uint n, st_ptr_backup *backup) (backup++)->restore(); } +/**************************************************************************** + thd specifics service, see include/mysql/service_thd_specifics.h +****************************************************************************/ +static const int INVALID_THD_KEY= -1; +static uint thd_key_no = 42; + +int thd_key_create(MYSQL_THD_KEY_T *key) +{ + int flags= PLUGIN_VAR_THDLOCAL | PLUGIN_VAR_STR | + PLUGIN_VAR_NOSYSVAR | PLUGIN_VAR_NOCMDOPT; + char namebuf[256]; + snprintf(namebuf, sizeof(namebuf), "%u", thd_key_no++); + mysql_rwlock_wrlock(&LOCK_system_variables_hash); + // non-letters in the name as an extra safety + st_bookmark *bookmark= register_var("\a\v\a\t\a\r", namebuf, flags); + mysql_rwlock_unlock(&LOCK_system_variables_hash); + if (bookmark) + { + *key= bookmark->offset; + return 0; + } + return ENOMEM; +} + +void thd_key_delete(MYSQL_THD_KEY_T *key) +{ + *key= INVALID_THD_KEY; +} + +void* thd_getspecific(MYSQL_THD thd, MYSQL_THD_KEY_T key) +{ + DBUG_ASSERT(key != INVALID_THD_KEY); + if (key == INVALID_THD_KEY || (!thd && !(thd= current_thd))) + return 0; + + return *(void**)(intern_sys_var_ptr(thd, key, true)); +} + +int thd_setspecific(MYSQL_THD thd, MYSQL_THD_KEY_T key, void *value) +{ + DBUG_ASSERT(key != INVALID_THD_KEY); + if (key == INVALID_THD_KEY || (!thd && !(thd= current_thd))) + return EINVAL; + + memcpy(intern_sys_var_ptr(thd, key, true), &value, sizeof(void*)); + return 0; +} + diff --git a/sql/sql_plugin_services.h b/sql/sql_plugin_services.h index 399de854218..c99691ab579 100644 --- a/sql/sql_plugin_services.h +++ b/sql/sql_plugin_services.h @@ -139,6 +139,14 @@ static struct wsrep_service_st wsrep_handler = { wsrep_unlock_rollback }; +static struct thd_specifics_service_st thd_specifics_handler= +{ + thd_key_create, + thd_key_delete, + thd_getspecific, + thd_setspecific +}; + static struct st_service_ref list_of_services[]= { { "my_snprintf_service", VERSION_my_snprintf, &my_snprintf_handler }, @@ -153,6 +161,7 @@ static struct st_service_ref list_of_services[]= { "logger_service", VERSION_logger, &logger_service_handler }, { "thd_autoinc_service", VERSION_thd_autoinc, &thd_autoinc_handler }, { "wsrep_service", VERSION_wsrep, &wsrep_handler }, + { "thd_specifics_service", VERSION_thd_specifics, &thd_specifics_handler }, { "thd_error_context_service", VERSION_thd_error_context, &thd_error_conext_handler }, }; |