diff options
Diffstat (limited to 'mysys')
-rw-r--r-- | mysys/CMakeLists.txt | 2 | ||||
-rw-r--r-- | mysys/Makefile.am | 35 | ||||
-rw-r--r-- | mysys/charset-def.c | 4 | ||||
-rw-r--r-- | mysys/errors.c | 2 | ||||
-rw-r--r-- | mysys/hash.c | 9 | ||||
-rw-r--r-- | mysys/lf_hash.c | 15 | ||||
-rw-r--r-- | mysys/mf_keycache.c | 146 | ||||
-rw-r--r-- | mysys/mf_strip.c | 45 | ||||
-rw-r--r-- | mysys/my_copy.c | 7 | ||||
-rw-r--r-- | mysys/my_getopt.c | 6 | ||||
-rw-r--r-- | mysys/my_largepage.c | 2 | ||||
-rw-r--r-- | mysys/my_redel.c | 3 | ||||
-rw-r--r-- | mysys/my_seek.c | 16 | ||||
-rw-r--r-- | mysys/my_static.c | 7 | ||||
-rw-r--r-- | mysys/my_thr_init.c | 7 | ||||
-rw-r--r-- | mysys/my_wincond.c | 1 | ||||
-rw-r--r-- | mysys/thr_lock.c | 22 | ||||
-rw-r--r-- | mysys/thr_mutex.c | 31 | ||||
-rw-r--r-- | mysys/tree.c | 8 | ||||
-rw-r--r-- | mysys/typelib.c | 5 |
20 files changed, 205 insertions, 168 deletions
diff --git a/mysys/CMakeLists.txt b/mysys/CMakeLists.txt index 8552eae3974..e9873fb0525 100644 --- a/mysys/CMakeLists.txt +++ b/mysys/CMakeLists.txt @@ -29,7 +29,7 @@ SET(MYSYS_SOURCES array.c charset-def.c charset.c checksum.c default.c default_ errors.c hash.c list.c md5.c mf_brkhant.c mf_cache.c mf_dirname.c mf_fn_ext.c mf_format.c mf_getdate.c mf_iocache.c mf_iocache2.c mf_keycache.c my_safehash.c mf_keycaches.c mf_loadpath.c mf_pack.c mf_path.c mf_qsort.c mf_qsort2.c - mf_radix.c mf_same.c mf_sort.c mf_soundex.c mf_strip.c mf_arr_appstr.c mf_tempdir.c + mf_radix.c mf_same.c mf_sort.c mf_soundex.c mf_arr_appstr.c mf_tempdir.c mf_tempfile.c mf_unixpath.c mf_wcomp.c mf_wfile.c mulalloc.c my_access.c my_aes.c my_alarm.c my_alloc.c my_append.c my_bit.c my_bitmap.c my_chmod.c my_chsize.c my_clock.c my_compress.c my_conio.c my_copy.c my_crc32.c my_create.c my_delete.c diff --git a/mysys/Makefile.am b/mysys/Makefile.am index f958d1821da..5137566c158 100644 --- a/mysys/Makefile.am +++ b/mysys/Makefile.am @@ -1,4 +1,4 @@ -# Copyright (C) 2000-2006 MySQL AB +# Copyright (C) 2000-2006 MySQL AB, 2009 Sun Microsystems, Inc. # # 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 @@ -20,32 +20,32 @@ INCLUDES = @ZLIB_INCLUDES@ -I$(top_builddir)/include \ -I$(top_srcdir)/include -I$(srcdir) pkglib_LIBRARIES = libmysys.a LDADD = libmysys.a $(top_builddir)/strings/libmystrings.a $(top_builddir)/dbug/libdbug.a -noinst_HEADERS = mysys_priv.h my_static.h my_handler_errors.h my_safehash.h +noinst_HEADERS = mysys_priv.h my_static.h my_handler_errors.h \ + my_safehash.h libmysys_a_SOURCES = my_init.c my_getwd.c mf_getdate.c my_mmap.c \ mf_path.c mf_loadpath.c my_file.c \ my_open.c my_create.c my_dup.c my_seek.c my_read.c \ my_pread.c my_write.c my_getpagesize.c \ - my_safehash.c \ - mf_keycache.c mf_keycaches.c my_crc32.c \ + my_crc32.c \ mf_iocache.c mf_iocache2.c mf_cache.c mf_tempfile.c \ mf_tempdir.c my_lock.c mf_brkhant.c my_alarm.c \ my_malloc.c my_realloc.c my_once.c mulalloc.c \ my_alloc.c safemalloc.c my_new.cc \ - my_vle.c my_atomic.c lf_hash.c \ - lf_dynarray.c lf_alloc-pin.c \ + my_vle.c my_atomic.c \ + my_safehash.c lf_hash.c lf_dynarray.c lf_alloc-pin.c \ + my_rnd.c my_uuid.c my_chmod.c \ my_fopen.c my_fstream.c my_getsystime.c \ - my_rnd.c my_uuid.c \ my_error.c errors.c my_div.c my_messnc.c \ mf_format.c mf_same.c mf_dirname.c mf_fn_ext.c \ my_symlink.c my_symlink2.c \ - mf_pack.c mf_unixpath.c mf_strip.c mf_arr_appstr.c \ + mf_pack.c mf_unixpath.c mf_arr_appstr.c \ mf_wcomp.c mf_wfile.c my_gethwaddr.c \ mf_qsort.c mf_qsort2.c mf_sort.c \ ptr_cmp.c mf_radix.c queues.c my_getncpus.c \ tree.c trie.c list.c hash.c array.c string.c typelib.c \ my_copy.c my_append.c my_lib.c \ my_delete.c my_rename.c my_redel.c \ - my_chsize.c my_chmod.c my_clock.c \ + my_chsize.c my_clock.c \ my_quick.c my_lockmem.c my_static.c \ my_sync.c my_getopt.c my_mkdir.c \ default_modify.c default.c \ @@ -57,12 +57,19 @@ libmysys_a_SOURCES = my_init.c my_getwd.c mf_getdate.c my_mmap.c \ my_memmem.c stacktrace.c \ my_windac.c my_access.c base64.c my_libwrap.c \ wqueue.c -if THREAD -libmysys_a_SOURCES+= thr_alarm.c thr_lock.c my_pthread.c my_thr_init.c \ - thr_mutex.c thr_rwlock.c waiting_threads.c + +if NEED_THREAD +# mf_keycache is used only in the server, so it is safe to leave the file +# out of the non-threaded library. +# In fact, it will currently not compile without thread support. +libmysys_a_SOURCES += mf_keycache.c mf_keycaches.c endif -EXTRA_DIST = CMakeLists.txt mf_soundex.c \ + +EXTRA_DIST = thr_alarm.c thr_lock.c my_pthread.c my_thr_init.c \ + thr_mutex.c thr_rwlock.c waiting_threads.c \ + CMakeLists.txt mf_soundex.c \ my_conio.c my_wincond.c my_winthread.c +libmysys_a_LIBADD = @THREAD_LOBJECTS@ # test_dir_DEPENDENCIES= $(LIBRARIES) # testhash_DEPENDENCIES= $(LIBRARIES) # test_charset_DEPENDENCIES= $(LIBRARIES) @@ -76,6 +83,8 @@ DEFS = -DDEFAULT_BASEDIR=\"$(prefix)\" \ -DDEFAULT_SYSCONFDIR="\"$(sysconfdir)\"" \ @DEFS@ +libmysys_a_DEPENDENCIES= @THREAD_LOBJECTS@ + # I hope this always does the right thing. Otherwise this is only test programs FLAGS=$(DEFS) $(INCLUDES) $(CPPFLAGS) $(CFLAGS) @NOINST_LDFLAGS@ diff --git a/mysys/charset-def.c b/mysys/charset-def.c index 63bbceef29b..5c68258ada1 100644 --- a/mysys/charset-def.c +++ b/mysys/charset-def.c @@ -42,6 +42,7 @@ extern CHARSET_INFO my_charset_ucs2_roman_uca_ci; extern CHARSET_INFO my_charset_ucs2_persian_uca_ci; extern CHARSET_INFO my_charset_ucs2_esperanto_uca_ci; extern CHARSET_INFO my_charset_ucs2_hungarian_uca_ci; +extern CHARSET_INFO my_charset_ucs2_croatian_uca_ci; #endif #ifdef HAVE_CHARSET_utf8 @@ -63,6 +64,7 @@ extern CHARSET_INFO my_charset_utf8_roman_uca_ci; extern CHARSET_INFO my_charset_utf8_persian_uca_ci; extern CHARSET_INFO my_charset_utf8_esperanto_uca_ci; extern CHARSET_INFO my_charset_utf8_hungarian_uca_ci; +extern CHARSET_INFO my_charset_utf8_croatian_uca_ci; #ifdef HAVE_UTF8_GENERAL_CS extern CHARSET_INFO my_charset_utf8_general_cs; #endif @@ -152,6 +154,7 @@ my_bool init_compiled_charsets(myf flags __attribute__((unused))) add_compiled_collation(&my_charset_ucs2_persian_uca_ci); add_compiled_collation(&my_charset_ucs2_esperanto_uca_ci); add_compiled_collation(&my_charset_ucs2_hungarian_uca_ci); + add_compiled_collation(&my_charset_ucs2_croatian_uca_ci); #endif #endif @@ -186,6 +189,7 @@ my_bool init_compiled_charsets(myf flags __attribute__((unused))) add_compiled_collation(&my_charset_utf8_persian_uca_ci); add_compiled_collation(&my_charset_utf8_esperanto_uca_ci); add_compiled_collation(&my_charset_utf8_hungarian_uca_ci); + add_compiled_collation(&my_charset_utf8_croatian_uca_ci); #endif #endif diff --git a/mysys/errors.c b/mysys/errors.c index 7c80fc0f89f..fc63ac9d936 100644 --- a/mysys/errors.c +++ b/mysys/errors.c @@ -51,6 +51,7 @@ const char * NEAR globerrs[GLOBERRS]= "File '%s' not found (Errcode: %d)", "File '%s' (fileno: %d) was not closed", "Can't change mode for file '%s' to 0x%lx (Error: %d)", + "Can't do seek on file '%s' (Errcode: %d)", "Warning: Can't copy ownership for file '%s' (Error: %d)" }; @@ -93,6 +94,7 @@ void init_glob_errs() EE(EE_FILENOTFOUND) = "File '%s' not found (Errcode: %d)"; EE(EE_FILE_NOT_CLOSED) = "File '%s' (fileno: %d) was not closed"; EE(EE_CANT_CHMOD) = "Can't change mode for file '%s' to 0x%lx (Error: %d)"; + EE(EE_CANT_SEEK) = "Can't do seek on file '%s' (Errcode: %d)"; EE(EE_CANT_COPY_OWNERSHIP)= "Warning: Can't copy ownership for file '%s' (Error: %d)"; } #endif diff --git a/mysys/hash.c b/mysys/hash.c index 136c2854bbe..0e22ddcf215 100644 --- a/mysys/hash.c +++ b/mysys/hash.c @@ -338,13 +338,8 @@ my_bool my_hash_insert(HASH *info, const uchar *record) { int flag; size_t idx,halfbuff,hash_nr,first_index; - uchar *ptr_to_rec,*ptr_to_rec2; - HASH_LINK *data,*empty,*gpos,*gpos2,*pos; - - LINT_INIT(gpos); - LINT_INIT(gpos2); - LINT_INIT(ptr_to_rec); - LINT_INIT(ptr_to_rec2); + uchar *UNINIT_VAR(ptr_to_rec),*UNINIT_VAR(ptr_to_rec2); + HASH_LINK *data,*empty,*UNINIT_VAR(gpos),*UNINIT_VAR(gpos2),*pos; if (info->flags & HASH_UNIQUE) { diff --git a/mysys/lf_hash.c b/mysys/lf_hash.c index ce7056af995..6569bafc00d 100644 --- a/mysys/lf_hash.c +++ b/mysys/lf_hash.c @@ -124,8 +124,8 @@ retry: we found a deleted node - be nice, help the other thread and remove this deleted node */ - if (my_atomic_casptr((void **)cursor->prev, - (void **)&cursor->curr, cursor->next)) + if (my_atomic_casptr((void **) cursor->prev, + (void **)(char*) &cursor->curr, cursor->next)) _lf_alloc_free(pins, cursor->curr); else { @@ -171,7 +171,8 @@ static LF_SLIST *linsert(LF_SLIST * volatile *head, CHARSET_INFO *cs, node->link= (intptr)cursor.curr; DBUG_ASSERT(node->link != (intptr)node); /* no circular references */ DBUG_ASSERT(cursor.prev != &node->link); /* no circular references */ - if (my_atomic_casptr((void **)cursor.prev, (void **)&cursor.curr, node)) + if (my_atomic_casptr((void **) cursor.prev, + (void **)(char*) &cursor.curr, node)) { res= 1; /* inserted ok */ break; @@ -218,13 +219,13 @@ static int ldelete(LF_SLIST * volatile *head, CHARSET_INFO *cs, uint32 hashnr, else { /* mark the node deleted */ - if (my_atomic_casptr((void **)&(cursor.curr->link), - (void **)&cursor.next, + if (my_atomic_casptr((void **) (char*) &(cursor.curr->link), + (void **) (char*) &cursor.next, (void *)(((intptr)cursor.next) | 1))) { /* and remove it from the list */ if (my_atomic_casptr((void **)cursor.prev, - (void **)&cursor.curr, cursor.next)) + (void **)(char*)&cursor.curr, cursor.next)) _lf_alloc_free(pins, cursor.curr); else { @@ -493,7 +494,7 @@ static int initialize_bucket(LF_HASH *hash, LF_SLIST * volatile *node, my_free((void *)dummy, MYF(0)); dummy= cur; } - my_atomic_casptr((void **)node, (void **)&tmp, dummy); + my_atomic_casptr((void **)node, (void **)(char*) &tmp, dummy); /* note that if the CAS above failed (after linsert() succeeded), it would mean that some other thread has executed linsert() for diff --git a/mysys/mf_keycache.c b/mysys/mf_keycache.c index ece6c35888d..0630d194234 100644 --- a/mysys/mf_keycache.c +++ b/mysys/mf_keycache.c @@ -13,7 +13,8 @@ along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -/* +/** + @file These functions handle keyblock cacheing for ISAM and MyISAM tables. One cache can handle many files. @@ -36,7 +37,9 @@ blocks_unused is the sum of never used blocks in the pool and of currently free blocks. blocks_used is the number of blocks fetched from the pool and as such gives the maximum number of in-use blocks at any time. +*/ +/* Key Cache Locking ================= @@ -368,8 +371,8 @@ static inline uint next_power(uint value) */ int init_key_cache(KEY_CACHE *keycache, uint key_cache_block_size, - size_t use_mem, uint division_limit, - uint age_threshold) + size_t use_mem, uint division_limit, + uint age_threshold) { ulong blocks, hash_links; size_t length; @@ -560,8 +563,8 @@ err: */ int resize_key_cache(KEY_CACHE *keycache, uint key_cache_block_size, - size_t use_mem, uint division_limit, - uint age_threshold) + size_t use_mem, uint division_limit, + uint age_threshold) { int blocks; DBUG_ENTER("resize_key_cache"); @@ -760,6 +763,13 @@ void end_key_cache(KEY_CACHE *keycache, my_bool cleanup) (ulong) keycache->global_cache_r_requests, (ulong) keycache->global_cache_read)); + /* + Reset these values to be able to detect a disabled key cache. + See Bug#44068 (RESTORE can disable the MyISAM Key Cache). + */ + keycache->blocks_used= 0; + keycache->blocks_unused= 0; + if (cleanup) { pthread_mutex_destroy(&keycache->cache_lock); @@ -1343,7 +1353,11 @@ static void unreg_request(KEY_CACHE *keycache, DBUG_ASSERT(block->prev_changed && *block->prev_changed == block); DBUG_ASSERT(!block->next_used); DBUG_ASSERT(!block->prev_used); - if (! --block->requests) + /* + Unregister the request, but do not link erroneous blocks into the + LRU ring. + */ + if (!--block->requests && !(block->status & BLOCK_ERROR)) { my_bool hot; if (block->hits_left) @@ -1425,8 +1439,7 @@ static void wait_for_readers(KEY_CACHE *keycache, #ifdef THREAD struct st_my_thread_var *thread= my_thread_var; DBUG_ASSERT(block->status & (BLOCK_READ | BLOCK_IN_USE)); - DBUG_ASSERT(!(block->status & (BLOCK_ERROR | BLOCK_IN_FLUSH | - BLOCK_CHANGED))); + DBUG_ASSERT(!(block->status & (BLOCK_IN_FLUSH | BLOCK_CHANGED))); DBUG_ASSERT(block->hash_link); DBUG_ASSERT(block->hash_link->block == block); /* Linked in file_blocks or changed_blocks hash. */ @@ -1716,6 +1729,7 @@ restart: - block assigned but not yet read from file (invalid data). */ +#ifdef THREAD if (keycache->in_resize) { /* This is a request during a resize operation */ @@ -1957,6 +1971,9 @@ restart: } DBUG_RETURN(0); } +#else /* THREAD */ + DBUG_ASSERT(!keycache->in_resize); +#endif if (page_status == PAGE_READ && (block->status & (BLOCK_IN_EVICTION | BLOCK_IN_SWITCH | @@ -2210,9 +2227,9 @@ restart: thread might change the block->hash_link value */ error= my_pwrite(block->hash_link->file, - block->buffer+block->offset, + block->buffer + block->offset, block->length - block->offset, - block->hash_link->diskpos+ block->offset, + block->hash_link->diskpos + block->offset, MYF(MY_NABP | MY_WAIT_IF_FULL)); keycache_pthread_mutex_lock(&keycache->cache_lock); @@ -2536,7 +2553,6 @@ uchar *key_cache_read(KEY_CACHE *keycache, reg1 BLOCK_LINK *block; uint read_length; uint offset; - uint status; int page_st; /* @@ -2571,9 +2587,11 @@ uchar *key_cache_read(KEY_CACHE *keycache, do { /* Cache could be disabled in a later iteration. */ - if (!keycache->can_be_used) - goto no_key_cache; + { + KEYCACHE_DBUG_PRINT("key_cache_read", ("keycache cannot be used")); + goto no_key_cache; + } /* Start reading at the beginning of the cache block. */ filepos-= offset; /* Do not read beyond the end of the cache block. */ @@ -2634,7 +2652,7 @@ uchar *key_cache_read(KEY_CACHE *keycache, } /* block status may have added BLOCK_ERROR in the above 'if'. */ - if (!((status= block->status) & BLOCK_ERROR)) + if (!(block->status & BLOCK_ERROR)) { #ifndef THREAD if (! return_buffer) @@ -2660,14 +2678,22 @@ uchar *key_cache_read(KEY_CACHE *keycache, remove_reader(block); - /* - Link the block into the LRU ring if it's the last submitted - request for the block. This enables eviction for the block. - */ - unreg_request(keycache, block, 1); + /* Error injection for coverage testing. */ + DBUG_EXECUTE_IF("key_cache_read_block_error", + block->status|= BLOCK_ERROR;); - if (status & BLOCK_ERROR) + /* Do not link erroneous blocks into the LRU ring, but free them. */ + if (!(block->status & BLOCK_ERROR)) + { + /* + Link the block into the LRU ring if it's the last submitted + request for the block. This enables eviction for the block. + */ + unreg_request(keycache, block, 1); + } + else { + free_block(keycache, block); error= 1; break; } @@ -2677,7 +2703,7 @@ uchar *key_cache_read(KEY_CACHE *keycache, if (return_buffer) DBUG_RETURN(block->buffer); #endif - next_block: + next_block: buff+= read_length; filepos+= read_length+offset; offset= 0; @@ -2685,6 +2711,7 @@ uchar *key_cache_read(KEY_CACHE *keycache, } while ((length-= read_length)); goto end; } + KEYCACHE_DBUG_PRINT("key_cache_read", ("keycache not initialized")); no_key_cache: /* Key cache is not used */ @@ -2705,6 +2732,7 @@ end: dec_counter_for_resize_op(keycache); keycache_pthread_mutex_unlock(&keycache->cache_lock); } + DBUG_PRINT("exit", ("error: %d", error )); DBUG_RETURN(error ? (uchar*) 0 : start); } @@ -2913,19 +2941,27 @@ int key_cache_insert(KEY_CACHE *keycache, DBUG_ASSERT(block->status & (BLOCK_READ | BLOCK_IN_USE)); } /* end of if (!(block->status & BLOCK_ERROR)) */ - remove_reader(block); - /* - Link the block into the LRU ring if it's the last submitted - request for the block. This enables eviction for the block. - */ - unreg_request(keycache, block, 1); - - error= (block->status & BLOCK_ERROR); + /* Error injection for coverage testing. */ + DBUG_EXECUTE_IF("key_cache_insert_block_error", + block->status|= BLOCK_ERROR; errno=EIO;); - if (error) + /* Do not link erroneous blocks into the LRU ring, but free them. */ + if (!(block->status & BLOCK_ERROR)) + { + /* + Link the block into the LRU ring if it's the last submitted + request for the block. This enables eviction for the block. + */ + unreg_request(keycache, block, 1); + } + else + { + free_block(keycache, block); + error= 1; break; + } buff+= read_length; filepos+= read_length+offset; @@ -3206,14 +3242,24 @@ int key_cache_write(KEY_CACHE *keycache, */ remove_reader(block); - /* - Link the block into the LRU ring if it's the last submitted - request for the block. This enables eviction for the block. - */ - unreg_request(keycache, block, 1); + /* Error injection for coverage testing. */ + DBUG_EXECUTE_IF("key_cache_write_block_error", + block->status|= BLOCK_ERROR;); - if (block->status & BLOCK_ERROR) + /* Do not link erroneous blocks into the LRU ring, but free them. */ + if (!(block->status & BLOCK_ERROR)) + { + /* + Link the block into the LRU ring if it's the last submitted + request for the block. This enables eviction for the block. + */ + unreg_request(keycache, block, 1); + } + else { + /* Pretend a "clean" block to avoid complications. */ + block->status&= ~(BLOCK_CHANGED); + free_block(keycache, block); error= 1; break; } @@ -3288,8 +3334,9 @@ static void free_block(KEY_CACHE *keycache, BLOCK_LINK *block) { KEYCACHE_THREAD_TRACE("free block"); KEYCACHE_DBUG_PRINT("free_block", - ("block %u to be freed, hash_link %p", - BLOCK_NUMBER(block), block->hash_link)); + ("block %u to be freed, hash_link %p status: %u", + BLOCK_NUMBER(block), block->hash_link, + block->status)); /* Assert that the block is not free already. And that it is in a clean state. Note that the block might just be assigned to a hash_link and @@ -3371,10 +3418,14 @@ static void free_block(KEY_CACHE *keycache, BLOCK_LINK *block) if (block->status & BLOCK_IN_EVICTION) return; - /* Here the block must be in the LRU ring. Unlink it again. */ - DBUG_ASSERT(block->next_used && block->prev_used && - *block->prev_used == block); - unlink_block(keycache, block); + /* Error blocks are not put into the LRU ring. */ + if (!(block->status & BLOCK_ERROR)) + { + /* Here the block must be in the LRU ring. Unlink it again. */ + DBUG_ASSERT(block->next_used && block->prev_used && + *block->prev_used == block); + unlink_block(keycache, block); + } if (block->temperature == BLOCK_WARM) keycache->warm_blocks--; block->temperature= BLOCK_COLD; @@ -3463,8 +3514,7 @@ static int flush_cached_blocks(KEY_CACHE *keycache, (BLOCK_READ | BLOCK_IN_FLUSH | BLOCK_CHANGED | BLOCK_IN_USE)); block->status|= BLOCK_IN_FLUSHWRITE; keycache_pthread_mutex_unlock(&keycache->cache_lock); - error= my_pwrite(file, - block->buffer+block->offset, + error= my_pwrite(file, block->buffer+block->offset, block->length - block->offset, block->hash_link->diskpos+ block->offset, MYF(MY_NABP | MY_WAIT_IF_FULL)); @@ -3491,7 +3541,6 @@ static int flush_cached_blocks(KEY_CACHE *keycache, right queue anyway. */ link_to_file_list(keycache, block, file, 1); - } block->status&= ~BLOCK_IN_FLUSH; /* @@ -3527,7 +3576,7 @@ static int flush_cached_blocks(KEY_CACHE *keycache, /* - flush all key blocks for a file to disk, but don't do any mutex locks. + Flush all key blocks for a file to disk, but don't do any mutex locks. SYNOPSIS flush_key_blocks_int() @@ -3693,7 +3742,6 @@ restart: { /* It's a temporary file */ DBUG_ASSERT(!(block->status & BLOCK_REASSIGNED)); - /* free_block() must not be called with BLOCK_CHANGED. Note that we must not change the BLOCK_CHANGED flag outside of @@ -4404,8 +4452,8 @@ static void keycache_debug_print(const char * fmt,...) va_start(args,fmt); if (keycache_debug_log) { - VOID(vfprintf(keycache_debug_log, fmt, args)); - VOID(fputc('\n',keycache_debug_log)); + (void) vfprintf(keycache_debug_log, fmt, args); + (void) fputc('\n',keycache_debug_log); } va_end(args); } diff --git a/mysys/mf_strip.c b/mysys/mf_strip.c deleted file mode 100644 index b33620b1b2d..00000000000 --- a/mysys/mf_strip.c +++ /dev/null @@ -1,45 +0,0 @@ -/* Copyright (C) 2000 MySQL AB - - 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 - the Free Software Foundation; version 2 of the License. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - -/* T|mmer en str{ng p{ slut_space */ - -#include "mysys_priv.h" - -/* - strip_sp(char * str) - Strips end-space from string and returns new length. -*/ - -size_t strip_sp(register char * str) -{ - reg2 char * found; - reg3 char * start; - - start=found=str; - - while (*str) - { - if (*str != ' ') - { - while (*++str && *str != ' ') {}; - if (!*str) - return (size_t) (str-start); /* Return stringlength */ - } - found=str; - while (*++str == ' ') {}; - } - *found= '\0'; /* Stripp at first space */ - return (size_t) (found-start); -} /* strip_sp */ diff --git a/mysys/my_copy.c b/mysys/my_copy.c index 62f60e9ce95..adc891358d4 100644 --- a/mysys/my_copy.c +++ b/mysys/my_copy.c @@ -89,6 +89,13 @@ int my_copy(const char *from, const char *to, myf MyFlags) goto err; } + /* sync the destination file */ + if (MyFlags & MY_SYNC) + { + if (my_sync(to_file, MyFlags)) + goto err; + } + if (my_close(from_file,MyFlags) | my_close(to_file,MyFlags)) DBUG_RETURN(-1); /* Error on close */ diff --git a/mysys/my_getopt.c b/mysys/my_getopt.c index 3d961c3bcee..98d3b9756ed 100644 --- a/mysys/my_getopt.c +++ b/mysys/my_getopt.c @@ -1017,10 +1017,12 @@ static void init_one_value(const struct my_option *option, uchar* *variable, case GET_LL: *((longlong*) variable)= (longlong) getopt_ll_limit_value((longlong) value, option, NULL); break; - case GET_ULL: /* Fall through */ - case GET_SET: + case GET_ULL: *((ulonglong*) variable)= (ulonglong) getopt_ull_limit_value((ulonglong) value, option, NULL); break; + case GET_SET: + *((ulonglong*) variable)= (ulonglong) value; + break; case GET_DOUBLE: *((double*) variable)= (double) value; break; diff --git a/mysys/my_largepage.c b/mysys/my_largepage.c index a20111396cb..b50a606c8d8 100644 --- a/mysys/my_largepage.c +++ b/mysys/my_largepage.c @@ -121,7 +121,7 @@ uchar* my_large_malloc_int(size_t size, myf my_flags) DBUG_ENTER("my_large_malloc_int"); /* Align block size to my_large_page_size */ - size = ((size - 1) & ~(my_large_page_size - 1)) + my_large_page_size; + size= MY_ALIGN(size, (size_t) my_large_page_size); shmid = shmget(IPC_PRIVATE, size, SHM_HUGETLB | SHM_R | SHM_W); if (shmid < 0) diff --git a/mysys/my_redel.c b/mysys/my_redel.c index 6b0ceb85950..598a728393d 100644 --- a/mysys/my_redel.c +++ b/mysys/my_redel.c @@ -77,9 +77,6 @@ end: int my_copystat(const char *from, const char *to, int MyFlags) { struct stat statbuf; -#if !defined(__WIN__) && !defined(__NETWARE__) - int res; -#endif if (stat((char*) from, &statbuf)) { diff --git a/mysys/my_seek.c b/mysys/my_seek.c index 4e18b510a1e..4ca5393e640 100644 --- a/mysys/my_seek.c +++ b/mysys/my_seek.c @@ -14,6 +14,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "mysys_priv.h" +#include "mysys_err.h" /* Seek to a position in a file. @@ -42,8 +43,7 @@ actual error. */ -my_off_t my_seek(File fd, my_off_t pos, int whence, - myf MyFlags __attribute__((unused))) +my_off_t my_seek(File fd, my_off_t pos, int whence, myf MyFlags) { reg1 os_off_t newpos= -1; DBUG_ENTER("my_seek"); @@ -68,7 +68,9 @@ my_off_t my_seek(File fd, my_off_t pos, int whence, newpos= lseek(fd, pos, whence); if (newpos == (os_off_t) -1) { - my_errno=errno; + my_errno= errno; + if (MyFlags & MY_WME) + my_error(EE_CANT_SEEK, MYF(0), my_filename(fd), my_errno); DBUG_PRINT("error",("lseek: %lu errno: %d", (ulong) newpos,errno)); DBUG_RETURN(MY_FILEPOS_ERROR); } @@ -83,7 +85,7 @@ my_off_t my_seek(File fd, my_off_t pos, int whence, /* Tell current position of file */ /* ARGSUSED */ -my_off_t my_tell(File fd, myf MyFlags __attribute__((unused))) +my_off_t my_tell(File fd, myf MyFlags) { os_off_t pos; DBUG_ENTER("my_tell"); @@ -95,7 +97,11 @@ my_off_t my_tell(File fd, myf MyFlags __attribute__((unused))) pos=lseek(fd, 0L, MY_SEEK_CUR); #endif if (pos == (os_off_t) -1) - my_errno=errno; + { + my_errno= errno; + if (MyFlags & MY_WME) + my_error(EE_CANT_SEEK, MYF(0), my_filename(fd), my_errno); + } DBUG_PRINT("exit",("pos: %lu", (ulong) pos)); DBUG_RETURN((my_off_t) pos); } /* my_tell */ diff --git a/mysys/my_static.c b/mysys/my_static.c index c33d05420c9..0ef5656b76f 100644 --- a/mysys/my_static.c +++ b/mysys/my_static.c @@ -104,6 +104,13 @@ static const char *proc_info_dummy(void *a __attribute__((unused)), /* this is to be able to call set_thd_proc_info from the C code */ const char *(*proc_info_hook)(void *, const char *, const char *, const char *, const unsigned int)= proc_info_dummy; +#if defined(ENABLED_DEBUG_SYNC) +/** + Global pointer to be set if callback function is defined + (e.g. in mysqld). See sql/debug_sync.cc. +*/ +void (*debug_sync_C_callback_ptr)(const char *, size_t); +#endif /* defined(ENABLED_DEBUG_SYNC) */ #ifdef __WIN__ /* from my_getsystime.c */ diff --git a/mysys/my_thr_init.c b/mysys/my_thr_init.c index 716552bc31b..e105b48f386 100644 --- a/mysys/my_thr_init.c +++ b/mysys/my_thr_init.c @@ -134,10 +134,11 @@ my_bool my_thread_global_init(void) pthread_attr_t dummy_thread_attr; pthread_attr_init(&dummy_thread_attr); - pthread_attr_setdetachstate(&dummy_thread_attr, PTHREAD_CREATE_DETACHED); + pthread_attr_setdetachstate(&dummy_thread_attr, PTHREAD_CREATE_JOINABLE); - pthread_create(&dummy_thread,&dummy_thread_attr, - nptl_pthread_exit_hack_handler, NULL); + if (pthread_create(&dummy_thread,&dummy_thread_attr, + nptl_pthread_exit_hack_handler, NULL) == 0) + (void)pthread_join(dummy_thread, NULL); } #endif /* TARGET_OS_LINUX */ diff --git a/mysys/my_wincond.c b/mysys/my_wincond.c index 8b548a64079..b869b22bdea 100644 --- a/mysys/my_wincond.c +++ b/mysys/my_wincond.c @@ -121,7 +121,6 @@ int pthread_cond_timedwait(pthread_cond_t *cond, pthread_mutex_t *mutex, LeaveCriticalSection(&cond->lock_waiting); LeaveCriticalSection(mutex); - result= WaitForMultipleObjects(2, cond->events, FALSE, timeout); EnterCriticalSection(&cond->lock_waiting); diff --git a/mysys/thr_lock.c b/mysys/thr_lock.c index 3eabde85a58..c830c4ed0cc 100644 --- a/mysys/thr_lock.c +++ b/mysys/thr_lock.c @@ -420,6 +420,28 @@ wait_for_lock(struct st_lock_list *wait, THR_LOCK_DATA *data, my_bool can_deadlock= test(data->owner->info->n_cursors); DBUG_ENTER("wait_for_lock"); + /* + One can use this to signal when a thread is going to wait for a lock. + See debug_sync.cc. + + Beware of waiting for a signal here. The lock has aquired its mutex. + While waiting on a signal here, the locking thread could not aquire + the mutex to release the lock. One could lock up the table + completely. + + In detail it works so: When thr_lock() tries to acquire a table + lock, it locks the lock->mutex, checks if it can have the lock, and + if not, it calls wait_for_lock(). Here it unlocks the table lock + while waiting on a condition. The sync point is located before this + wait for condition. If we have a waiting action here, we hold the + the table locks mutex all the time. Any attempt to look at the table + lock by another thread blocks it immediately on lock->mutex. This + can easily become an unexpected and unobvious blockage. So be + warned: Do not request a WAIT_FOR action for the 'wait_for_lock' + sync point unless you really know what you do. + */ + DEBUG_SYNC_C("wait_for_lock"); + if (!in_wait_list) { (*wait->last)=data; /* Wait for lock */ diff --git a/mysys/thr_mutex.c b/mysys/thr_mutex.c index b5abf987461..5ab1e443a88 100644 --- a/mysys/thr_mutex.c +++ b/mysys/thr_mutex.c @@ -36,6 +36,7 @@ #undef pthread_mutex_init #undef pthread_mutex_lock #undef pthread_mutex_unlock +#undef pthread_mutex_trylock #undef pthread_mutex_destroy #undef pthread_cond_wait #undef pthread_cond_timedwait @@ -838,31 +839,9 @@ static void print_deadlock_warning(safe_mutex_t *new_mutex, DBUG_VOID_RETURN; } +#elif defined(MY_PTHREAD_FASTMUTEX) -#endif /* THREAD && SAFE_MUTEX */ - -#if defined(THREAD) && defined(MY_PTHREAD_FASTMUTEX) && !defined(SAFE_MUTEX) - -#include "mysys_priv.h" -#include "my_static.h" -#include <m_string.h> - -#include <m_ctype.h> -#include <hash.h> -#include <myisampack.h> -#include <mysys_err.h> -#include <my_sys.h> - -#undef pthread_mutex_t -#undef pthread_mutex_init -#undef pthread_mutex_lock -#undef pthread_mutex_trylock -#undef pthread_mutex_unlock -#undef pthread_mutex_destroy -#undef pthread_cond_wait -#undef pthread_cond_timedwait - -ulong mutex_delay(ulong delayloops) +static ulong mutex_delay(ulong delayloops) { ulong i; volatile ulong j; @@ -943,6 +922,6 @@ void fastmutex_global_init(void) cpu_count= sysconf(_SC_NPROCESSORS_CONF); #endif } - -#endif /* SAFE_MUTEX_DEFINED */ + +#endif /* defined(MY_PTHREAD_FASTMUTEX) */ #endif /* THREAD */ diff --git a/mysys/tree.c b/mysys/tree.c index ef33f75b7c6..e4854581204 100644 --- a/mysys/tree.c +++ b/mysys/tree.c @@ -77,13 +77,13 @@ static void rb_insert(TREE *tree,TREE_ELEMENT ***parent, static void rb_delete_fixup(TREE *tree,TREE_ELEMENT ***parent); - /* The actuall code for handling binary trees */ +/* The actual code for handling binary trees */ #ifndef DBUG_OFF static int test_rb_tree(TREE_ELEMENT *element); #endif -void init_tree(TREE *tree, ulong default_alloc_size, ulong memory_limit, +void init_tree(TREE *tree, size_t default_alloc_size, size_t memory_limit, int size, qsort_cmp2 compare, my_bool with_delete, tree_element_free free_element, void *custom_arg) { @@ -96,7 +96,7 @@ void init_tree(TREE *tree, ulong default_alloc_size, ulong memory_limit, bzero((uchar*) &tree->null_element,sizeof(tree->null_element)); tree->root= &tree->null_element; tree->compare=compare; - tree->size_of_element=size > 0 ? (uint) size : 0; + tree->size_of_element= size > 0 ? (uint) size : 0; tree->memory_limit=memory_limit; tree->free=free_element; tree->allocated=0; @@ -127,7 +127,7 @@ void init_tree(TREE *tree, ulong default_alloc_size, ulong memory_limit, } if (!(tree->with_delete=with_delete)) { - init_alloc_root(&tree->mem_root, (uint) default_alloc_size, 0); + init_alloc_root(&tree->mem_root, default_alloc_size, 0); tree->mem_root.min_malloc=(sizeof(TREE_ELEMENT)+tree->size_of_element); } DBUG_VOID_RETURN; diff --git a/mysys/typelib.c b/mysys/typelib.c index 26bfdaee2c2..97acd476c20 100644 --- a/mysys/typelib.c +++ b/mysys/typelib.c @@ -190,7 +190,10 @@ my_ulonglong find_typeset(char *x, TYPELIB *lib, int *err) { (*err)++; i= x; - while (*x && *x != field_separator) x++; + while (*x && *x != field_separator) + x++; + if (x[0] && x[1]) /* skip separator if found */ + x++; if ((find= find_type(i, lib, 2 | 8) - 1) < 0) DBUG_RETURN(0); result|= (ULL(1) << find); |