diff --git a/sql/sql_plugin.cc b/sql/sql_plugin.cc index 994a09a8177..27d62387a8c 100644 --- a/sql/sql_plugin.cc +++ b/sql/sql_plugin.cc @@ -622,7 +622,10 @@ static plugin_ref intern_plugin_lock(LEX *lex, plugin_ref rc CALLER_INFO_PROTO) { plugin_ref plugin; #ifdef DBUG_OFF - /* built-in plugins don't need ref counting */ + /* + In optimized builds we don't do reference counting for built-in + (plugin->plugin_dl == 0) plugins. + */ if (!pi->plugin_dl) DBUG_RETURN(pi); @@ -655,6 +658,26 @@ plugin_ref plugin_lock(THD *thd, plugin_ref ptr CALLER_INFO_PROTO) LEX *lex= thd ? thd->lex : 0; plugin_ref rc; DBUG_ENTER("plugin_lock"); + +#ifdef DBUG_OFF + /* + In optimized builds we don't do reference counting for built-in + (plugin->plugin_dl == 0) plugins. + + Note that we access plugin->plugin_dl outside of LOCK_plugin, and for + dynamic plugins a 'plugin' could correspond to plugin that was unloaded + meanwhile! But because st_plugin_int is always allocated on + plugin_mem_root, the pointer can never be invalid - the memory is never + freed. + Of course, the memory that 'plugin' points to can be overwritten by + another plugin being loaded, but plugin->plugin_dl can never change + from zero to non-zero or vice versa. + That is, it's always safe to check for plugin->plugin_dl==0 even + without a mutex. + */ + if (! plugin_dlib(ptr)) + DBUG_RETURN(ptr); +#endif pthread_mutex_lock(&LOCK_plugin); rc= my_intern_plugin_lock_ci(lex, ptr); pthread_mutex_unlock(&LOCK_plugin);