summaryrefslogtreecommitdiff
path: root/sql/ha_blackhole.cc
diff options
context:
space:
mode:
Diffstat (limited to 'sql/ha_blackhole.cc')
-rw-r--r--sql/ha_blackhole.cc130
1 files changed, 120 insertions, 10 deletions
diff --git a/sql/ha_blackhole.cc b/sql/ha_blackhole.cc
index 3f4285ec595..e477686d18e 100644
--- a/sql/ha_blackhole.cc
+++ b/sql/ha_blackhole.cc
@@ -22,6 +22,14 @@
#ifdef HAVE_BLACKHOLE_DB
#include "ha_blackhole.h"
+/* Static declarations for shared structures */
+
+static pthread_mutex_t blackhole_mutex;
+static HASH blackhole_open_tables;
+static int blackhole_init= FALSE;
+
+static st_blackhole_share *get_share(const char *table_name);
+static void free_share(st_blackhole_share *share);
/* Blackhole storage engine handlerton */
@@ -30,7 +38,7 @@ handlerton blackhole_hton= {
SHOW_OPTION_YES,
"/dev/null storage engine (anything you write to it disappears)",
DB_TYPE_BLACKHOLE_DB,
- NULL,
+ blackhole_db_init,
0, /* slot */
0, /* savepoint size. */
NULL, /* close_connection */
@@ -70,15 +78,18 @@ const char **ha_blackhole::bas_ext() const
int ha_blackhole::open(const char *name, int mode, uint test_if_locked)
{
DBUG_ENTER("ha_blackhole::open");
- thr_lock_init(&thr_lock);
- thr_lock_data_init(&thr_lock,&lock,NULL);
+
+ if (!(share= get_share(name)))
+ DBUG_RETURN(HA_ERR_OUT_OF_MEM);
+
+ thr_lock_data_init(&share->lock, &lock, NULL);
DBUG_RETURN(0);
}
int ha_blackhole::close(void)
{
DBUG_ENTER("ha_blackhole::close");
- thr_lock_delete(&thr_lock);
+ free_share(share);
DBUG_RETURN(0);
}
@@ -161,17 +172,23 @@ int ha_blackhole::external_lock(THD *thd, int lock_type)
}
-uint ha_blackhole::lock_count(void) const
-{
- DBUG_ENTER("ha_blackhole::lock_count");
- DBUG_RETURN(0);
-}
-
THR_LOCK_DATA **ha_blackhole::store_lock(THD *thd,
THR_LOCK_DATA **to,
enum thr_lock_type lock_type)
{
DBUG_ENTER("ha_blackhole::store_lock");
+ if (lock_type != TL_IGNORE && lock.type == TL_UNLOCK)
+ {
+ if ((lock_type >= TL_WRITE_CONCURRENT_INSERT &&
+ lock_type <= TL_WRITE) && !thd->in_lock_tables)
+ lock_type = TL_WRITE_ALLOW_WRITE;
+
+ if (lock_type == TL_READ_NO_INSERT && !thd->in_lock_tables)
+ lock_type = TL_READ;
+
+ lock.type= lock_type;
+ }
+ *to++= &lock;
DBUG_RETURN(to);
}
@@ -226,4 +243,97 @@ int ha_blackhole::index_last(byte * buf)
DBUG_RETURN(HA_ERR_END_OF_FILE);
}
+
+static st_blackhole_share *get_share(const char *table_name)
+{
+ st_blackhole_share *share;
+ uint length;
+
+ length= (uint) strlen(table_name);
+ pthread_mutex_lock(&blackhole_mutex);
+
+ if (!(share= (st_blackhole_share*) hash_search(&blackhole_open_tables,
+ (byte*) table_name, length)))
+ {
+ if (!(share= (st_blackhole_share*) my_malloc(sizeof(st_blackhole_share) +
+ length,
+ MYF(MY_WME | MY_ZEROFILL))))
+ goto error;
+
+ share->table_name_length= length;
+ strmov(share->table_name, table_name);
+
+ if (my_hash_insert(&blackhole_open_tables, (byte*) share))
+ {
+ my_free((gptr) share, MYF(0));
+ share= NULL;
+ goto error;
+ }
+
+ thr_lock_init(&share->lock);
+ }
+ share->use_count++;
+
+error:
+ pthread_mutex_unlock(&blackhole_mutex);
+ return share;
+}
+
+static void free_share(st_blackhole_share *share)
+{
+ pthread_mutex_lock(&blackhole_mutex);
+ if (!--share->use_count)
+ hash_delete(&blackhole_open_tables, (byte*) share);
+ pthread_mutex_unlock(&blackhole_mutex);
+}
+
+
+static byte* blackhole_get_key(st_blackhole_share *share, uint *length,
+ my_bool not_used __attribute__((unused)))
+{
+ *length= share->table_name_length;
+ return (byte*) share->table_name;
+}
+
+
+static void blackhole_free_key(st_blackhole_share *share)
+{
+ thr_lock_delete(&share->lock);
+ my_free((gptr) share, MYF(0));
+}
+
+
+bool blackhole_db_init()
+{
+ DBUG_ENTER("blackhole_db_init");
+ if (pthread_mutex_init(&blackhole_mutex, MY_MUTEX_INIT_FAST))
+ goto error;
+ if (hash_init(&blackhole_open_tables, &my_charset_bin, 32, 0, 0,
+ (hash_get_key) blackhole_get_key,
+ (hash_free_key) blackhole_free_key, 0))
+ {
+ VOID(pthread_mutex_destroy(&blackhole_mutex));
+ }
+ else
+ {
+ blackhole_init= TRUE;
+ DBUG_RETURN(FALSE);
+ }
+error:
+ have_blackhole_db= SHOW_OPTION_DISABLED; // If we couldn't use handler
+ DBUG_RETURN(TRUE);
+}
+
+
+bool blackhole_db_end()
+{
+ if (blackhole_init)
+ {
+ hash_free(&blackhole_open_tables);
+ VOID(pthread_mutex_destroy(&blackhole_mutex));
+ }
+ blackhole_init= 0;
+ return FALSE;
+}
+
#endif /* HAVE_BLACKHOLE_DB */