=== modified file 'include/mysql/plugin.h'
--- include/mysql/plugin.h	2014-07-08 10:54:47 +0000
+++ include/mysql/plugin.h	2014-10-22 10:40:35 +0000
@@ -730,9 +730,47 @@
 */
 void thd_wakeup_subsequent_commits(MYSQL_THD thd, int wakeup_error);
 
+/**
+   THD specific for plugin(s)
+
+   This API provides pthread_getspecific like functionality to plugin authors.
+   This is a functional alternative to the declarative MYSQL_THDVAR
+
+   A plugin should at init call thd_key_create that create a key that
+   will have storage in each THD. The key should be used by all threads
+   and can be used concurrently from all threads.
+
+   A plugin should at deinit call thd_key_delete.
+
+   NOTE: this API is also safe when using pool-of-threads in which case
+   pthread_getspecific is not as actual OS thread may change.
+*/
+  typedef int MYSQL_THD_KEY_T;
+
+  /**
+   * create THD specific storage
+   * @return 0 on success
+   *    else errno is returned
+   */
+  int thd_key_create(MYSQL_THD_KEY_T *key);
+
+  /**
+   * delete THD specific storage
+   */
+  void thd_key_delete(MYSQL_THD_KEY_T *key);
+
+  /**
+   * get/set thd specific storage
+   *  - first time this is called from a thread it will return 0
+   *  - this call is thread-safe in that different threads may call this
+   *    simultaneously if operating on different THDs.
+   *  - this call acquires no mutexes and is implemented as an array lookup
+   */
+  void* thd_get_specific(MYSQL_THD thd, MYSQL_THD_KEY_T key);
+  void thd_set_specific(MYSQL_THD thd, MYSQL_THD_KEY_T key, void *value);
+
 #ifdef __cplusplus
 }
 #endif
 
 #endif
-

=== modified file 'sql/sql_plugin.cc'
--- sql/sql_plugin.cc	2014-09-30 17:31:14 +0000
+++ sql/sql_plugin.cc	2014-10-22 10:42:54 +0000
@@ -4100,3 +4100,48 @@
     (backup++)->restore();
 }
 
+
+/****************************************************************************
+  thd specifics
+****************************************************************************/
+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;
+  char namebuf[256];
+  mysql_rwlock_wrlock(&LOCK_system_variables_hash);
+  snprintf(namebuf, sizeof(namebuf), "thd_key_%u", thd_key_no++);
+  st_bookmark *bookmark= register_var(NULL, namebuf, flags);
+  mysql_rwlock_unlock(&LOCK_system_variables_hash);
+  if (bookmark)
+  {
+    *key= bookmark->offset;
+    return 0;
+  }
+  return ENOMEM;
+}
+
+/**
+ * delete THD specific storage
+ */
+void thd_key_delete(MYSQL_THD_KEY_T *key)
+{
+  /* it seem like deleting of a THDLOCAL variable slot is not implemented */
+  *key= INVALID_THD_KEY;
+}
+
+void* thd_get_specific(MYSQL_THD thd, MYSQL_THD_KEY_T key)
+{
+  DBUG_ASSERT(key != INVALID_THD_KEY);
+  char **ptr= mysql_sys_var_str(thd, key);
+  return reinterpret_cast<void*>(* ptr);
+}
+
+void thd_set_specific(MYSQL_THD thd, MYSQL_THD_KEY_T key, void *value)
+{
+  DBUG_ASSERT(key != INVALID_THD_KEY);
+  char **ptr= mysql_sys_var_str(thd, key);
+  memcpy(ptr, &value, sizeof(void*));
+}

