mirror of
https://github.com/MariaDB/server.git
synced 2026-05-15 19:37:16 +02:00
Merge a88-113-38-195.elisa-laajakaista.fi:/home/my/bk/mysql-5.1-main
into a88-113-38-195.elisa-laajakaista.fi:/home/my/bk/mysql-5.1-marvel client/mysqltest.c: Auto merged mysql-test/r/change_user.result: Auto merged mysql-test/t/change_user.test: Auto merged sql/handler.cc: Auto merged sql/handler.h: Auto merged sql/item_func.cc: Auto merged sql/log.cc: Auto merged sql/mysql_priv.h: Auto merged sql/mysqld.cc: Auto merged sql/set_var.cc: Auto merged sql/sql_class.cc: Auto merged sql/sql_parse.cc: Auto merged sql/sql_select.cc: Auto merged sql/sql_show.cc: Auto merged sql/sql_table.cc: Auto merged sql/sql_test.cc: Auto merged sql/sql_yacc.yy: Auto merged sql/table.h: Auto merged
This commit is contained in:
commit
abf0761539
93 changed files with 918 additions and 449 deletions
|
|
@ -63,7 +63,8 @@ my_bool init_dynamic_array2(DYNAMIC_ARRAY *array, uint element_size,
|
|||
array->size_of_element=element_size;
|
||||
if ((array->buffer= init_buffer))
|
||||
DBUG_RETURN(FALSE);
|
||||
if (!(array->buffer=(uchar*) my_malloc_ci(element_size*init_alloc,MYF(MY_WME))))
|
||||
if (!(array->buffer=(uchar*) my_malloc_ci(element_size*init_alloc,
|
||||
MYF(MY_WME))))
|
||||
{
|
||||
array->max_element=0;
|
||||
DBUG_RETURN(TRUE);
|
||||
|
|
@ -179,7 +180,7 @@ uchar *pop_dynamic(DYNAMIC_ARRAY *array)
|
|||
}
|
||||
|
||||
/*
|
||||
Replace elemnent in array with given element and index
|
||||
Replace element in array with given element and index
|
||||
|
||||
SYNOPSIS
|
||||
set_dynamic()
|
||||
|
|
@ -200,42 +201,69 @@ my_bool set_dynamic(DYNAMIC_ARRAY *array, uchar* element, uint idx)
|
|||
{
|
||||
if (idx >= array->elements)
|
||||
{
|
||||
if (idx >= array->max_element)
|
||||
{
|
||||
uint size;
|
||||
char *new_ptr;
|
||||
size=(idx+array->alloc_increment)/array->alloc_increment;
|
||||
size*= array->alloc_increment;
|
||||
if (array->buffer == (uchar *)(array + 1))
|
||||
{
|
||||
/*
|
||||
In this senerio, the buffer is statically preallocated,
|
||||
so we have to create an all-new malloc since we overflowed
|
||||
*/
|
||||
if (!(new_ptr= (char *) my_malloc(size *
|
||||
array->size_of_element,
|
||||
MYF(MY_WME))))
|
||||
return 0;
|
||||
memcpy(new_ptr, array->buffer,
|
||||
array->elements * array->size_of_element);
|
||||
}
|
||||
else
|
||||
if (!(new_ptr=(char*) my_realloc(array->buffer,size*
|
||||
array->size_of_element,
|
||||
MYF(MY_WME | MY_ALLOW_ZERO_PTR))))
|
||||
return TRUE;
|
||||
array->buffer= (uchar*) new_ptr;
|
||||
array->max_element=size;
|
||||
}
|
||||
if (idx >= array->max_element && allocate_dynamic(array, idx))
|
||||
return TRUE;
|
||||
bzero((uchar*) (array->buffer+array->elements*array->size_of_element),
|
||||
(idx - array->elements)*array->size_of_element);
|
||||
(idx - array->elements)*array->size_of_element);
|
||||
array->elements=idx+1;
|
||||
}
|
||||
memcpy(array->buffer+(idx * array->size_of_element),element,
|
||||
(size_t) array->size_of_element);
|
||||
(size_t) array->size_of_element);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Ensure that dynamic array has enough elements
|
||||
|
||||
SYNOPSIS
|
||||
allocate_dynamic()
|
||||
array
|
||||
max_elements Numbers of elements that is needed
|
||||
|
||||
NOTES
|
||||
Any new allocated element are NOT initialized
|
||||
|
||||
RETURN VALUE
|
||||
FALSE Ok
|
||||
TRUE Allocation of new memory failed
|
||||
*/
|
||||
|
||||
my_bool allocate_dynamic(DYNAMIC_ARRAY *array, uint max_elements)
|
||||
{
|
||||
if (max_elements >= array->max_element)
|
||||
{
|
||||
uint size;
|
||||
uchar *new_ptr;
|
||||
size= (max_elements + array->alloc_increment)/array->alloc_increment;
|
||||
size*= array->alloc_increment;
|
||||
if (array->buffer == (uchar *)(array + 1))
|
||||
{
|
||||
/*
|
||||
In this senerio, the buffer is statically preallocated,
|
||||
so we have to create an all-new malloc since we overflowed
|
||||
*/
|
||||
if (!(new_ptr= (uchar *) my_malloc(size *
|
||||
array->size_of_element,
|
||||
MYF(MY_WME))))
|
||||
return 0;
|
||||
memcpy(new_ptr, array->buffer,
|
||||
array->elements * array->size_of_element);
|
||||
}
|
||||
else
|
||||
|
||||
|
||||
if (!(new_ptr= (uchar*) my_realloc(array->buffer,size*
|
||||
array->size_of_element,
|
||||
MYF(MY_WME | MY_ALLOW_ZERO_PTR))))
|
||||
return TRUE;
|
||||
array->buffer= new_ptr;
|
||||
array->max_element= size;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Get an element from array by given index
|
||||
|
||||
|
|
|
|||
|
|
@ -1701,6 +1701,7 @@ int my_b_flush_io_cache(IO_CACHE *info, int need_append_buffer_lock)
|
|||
my_bool append_cache;
|
||||
my_off_t pos_in_file;
|
||||
DBUG_ENTER("my_b_flush_io_cache");
|
||||
DBUG_PRINT("enter", ("cache: 0x%lx", (long) info));
|
||||
|
||||
if (!(append_cache = (info->type == SEQ_READ_APPEND)))
|
||||
need_append_buffer_lock=0;
|
||||
|
|
|
|||
|
|
@ -105,6 +105,7 @@
|
|||
#include <keycache.h>
|
||||
#include "my_static.h"
|
||||
#include <m_string.h>
|
||||
#include <my_bit.h>
|
||||
#include <errno.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
|
|
@ -1262,12 +1263,12 @@ static void unlink_block(KEY_CACHE *keycache, BLOCK_LINK *block)
|
|||
|
||||
KEYCACHE_THREAD_TRACE("unlink_block");
|
||||
#if defined(KEYCACHE_DEBUG)
|
||||
KEYCACHE_DBUG_ASSERT(keycache->blocks_available != 0);
|
||||
keycache->blocks_available--;
|
||||
KEYCACHE_DBUG_PRINT("unlink_block",
|
||||
("unlinked block %u status=%x #requests=%u #available=%u",
|
||||
BLOCK_NUMBER(block), block->status,
|
||||
block->requests, keycache->blocks_available));
|
||||
KEYCACHE_DBUG_ASSERT(keycache->blocks_available >= 0);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
@ -2360,9 +2361,9 @@ restart:
|
|||
(block->hash_link->diskpos == filepos)));
|
||||
*page_st=page_status;
|
||||
KEYCACHE_DBUG_PRINT("find_key_block",
|
||||
("fd: %d pos: %lu block->status: %u page_status: %u",
|
||||
("fd: %d pos: %lu block->status: %u page_status: %d",
|
||||
file, (ulong) filepos, block->status,
|
||||
(uint) page_status));
|
||||
page_status));
|
||||
|
||||
#if !defined(DBUG_OFF) && defined(EXTRA_DEBUG)
|
||||
DBUG_EXECUTE("check_keycache2",
|
||||
|
|
@ -2513,10 +2514,10 @@ static void read_block(KEY_CACHE *keycache,
|
|||
*/
|
||||
|
||||
uchar *key_cache_read(KEY_CACHE *keycache,
|
||||
File file, my_off_t filepos, int level,
|
||||
uchar *buff, uint length,
|
||||
uint block_length __attribute__((unused)),
|
||||
int return_buffer __attribute__((unused)))
|
||||
File file, my_off_t filepos, int level,
|
||||
uchar *buff, uint length,
|
||||
uint block_length __attribute__((unused)),
|
||||
int return_buffer __attribute__((unused)))
|
||||
{
|
||||
my_bool locked_and_incremented= FALSE;
|
||||
int error=0;
|
||||
|
|
@ -2534,12 +2535,12 @@ uchar *key_cache_read(KEY_CACHE *keycache,
|
|||
uint status;
|
||||
int page_st;
|
||||
|
||||
/*
|
||||
/*
|
||||
When the key cache is once initialized, we use the cache_lock to
|
||||
reliably distinguish the cases of normal operation, resizing, and
|
||||
disabled cache. We always increment and decrement
|
||||
'cnt_for_resize_op' so that a resizer can wait for pending I/O.
|
||||
*/
|
||||
*/
|
||||
keycache_pthread_mutex_lock(&keycache->cache_lock);
|
||||
/*
|
||||
Cache resizing has two phases: Flushing and re-initializing. In
|
||||
|
|
@ -2976,9 +2977,10 @@ int key_cache_write(KEY_CACHE *keycache,
|
|||
int error=0;
|
||||
DBUG_ENTER("key_cache_write");
|
||||
DBUG_PRINT("enter",
|
||||
("fd: %u pos: %lu length: %u block_length: %u key_block_length: %u",
|
||||
(uint) file, (ulong) filepos, length, block_length,
|
||||
keycache ? keycache->key_cache_block_size : 0));
|
||||
("fd: %u pos: %lu length: %u block_length: %u"
|
||||
" key_block_length: %u",
|
||||
(uint) file, (ulong) filepos, length, block_length,
|
||||
keycache ? keycache->key_cache_block_size : 0));
|
||||
|
||||
if (!dont_write)
|
||||
{
|
||||
|
|
@ -3184,7 +3186,6 @@ int key_cache_write(KEY_CACHE *keycache,
|
|||
a flush.
|
||||
*/
|
||||
block->status&= ~BLOCK_FOR_UPDATE;
|
||||
|
||||
set_if_smaller(block->offset, offset);
|
||||
set_if_bigger(block->length, read_length+offset);
|
||||
|
||||
|
|
|
|||
|
|
@ -136,6 +136,7 @@ File create_temp_file(char *to, const char *dir, const char *prefix,
|
|||
if (org_file >= 0 && file < 0)
|
||||
{
|
||||
int tmp=my_errno;
|
||||
close(org_file);
|
||||
(void) my_delete(to, MYF(MY_WME | ME_NOINPUT));
|
||||
my_errno=tmp;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,11 +17,10 @@
|
|||
#include <my_pthread.h>
|
||||
|
||||
#ifndef HAVE_INLINE
|
||||
/*
|
||||
the following will cause all inline functions to be instantiated
|
||||
*/
|
||||
/* the following will cause all inline functions to be instantiated */
|
||||
#define HAVE_INLINE
|
||||
#define static extern
|
||||
#undef STATIC_INLINE
|
||||
#define STATIC_INLINE extern
|
||||
#endif
|
||||
|
||||
#include <my_atomic.h>
|
||||
|
|
@ -35,7 +34,7 @@
|
|||
*/
|
||||
int my_atomic_initialize()
|
||||
{
|
||||
DBUG_ASSERT(sizeof(intptr) == sizeof(void *));
|
||||
compile_time_assert(sizeof(intptr) == sizeof(void *));
|
||||
/* currently the only thing worth checking is SMP/UP issue */
|
||||
#ifdef MY_ATOMIC_MODE_DUMMY
|
||||
return my_getncpus() == 1 ? MY_ATOMIC_OK : MY_ATOMIC_NOT_1CPU;
|
||||
|
|
|
|||
100
mysys/my_bit.c
100
mysys/my_bit.c
|
|
@ -13,23 +13,18 @@
|
|||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||
|
||||
/* Some useful bit functions */
|
||||
#include <my_global.h>
|
||||
|
||||
#include "mysys_priv.h"
|
||||
#ifndef HAVE_INLINE
|
||||
/* the following will cause all inline functions to be instantiated */
|
||||
#define HAVE_INLINE
|
||||
#undef STATIC_INLINE
|
||||
#define STATIC_INLINE extern
|
||||
#endif
|
||||
|
||||
/*
|
||||
Find smallest X in 2^X >= value
|
||||
This can be used to divide a number with value by doing a shift instead
|
||||
*/
|
||||
#include <my_bit.h>
|
||||
|
||||
uint my_bit_log2(ulong value)
|
||||
{
|
||||
uint bit;
|
||||
for (bit=0 ; value > 1 ; value>>=1, bit++) ;
|
||||
return bit;
|
||||
}
|
||||
|
||||
static char nbits[256] = {
|
||||
const char _my_bits_nbits[256] = {
|
||||
0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4,
|
||||
1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
|
||||
1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
|
||||
|
|
@ -48,60 +43,29 @@ static char nbits[256] = {
|
|||
4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8,
|
||||
};
|
||||
|
||||
uint my_count_bits(ulonglong v)
|
||||
{
|
||||
#if SIZEOF_LONG_LONG > 4
|
||||
/* The following code is a bit faster on 16 bit machines than if we would
|
||||
only shift v */
|
||||
ulong v2=(ulong) (v >> 32);
|
||||
return (uint) (uchar) (nbits[(uchar) v] +
|
||||
nbits[(uchar) (v >> 8)] +
|
||||
nbits[(uchar) (v >> 16)] +
|
||||
nbits[(uchar) (v >> 24)] +
|
||||
nbits[(uchar) (v2)] +
|
||||
nbits[(uchar) (v2 >> 8)] +
|
||||
nbits[(uchar) (v2 >> 16)] +
|
||||
nbits[(uchar) (v2 >> 24)]);
|
||||
#else
|
||||
return (uint) (uchar) (nbits[(uchar) v] +
|
||||
nbits[(uchar) (v >> 8)] +
|
||||
nbits[(uchar) (v >> 16)] +
|
||||
nbits[(uchar) (v >> 24)]);
|
||||
#endif
|
||||
}
|
||||
|
||||
uint my_count_bits_ushort(ushort v)
|
||||
{
|
||||
return nbits[v];
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Next highest power of two
|
||||
|
||||
SYNOPSIS
|
||||
my_round_up_to_next_power()
|
||||
v Value to check
|
||||
|
||||
RETURN
|
||||
Next or equal power of 2
|
||||
Note: 0 will return 0
|
||||
|
||||
NOTES
|
||||
Algorithm by Sean Anderson, according to:
|
||||
http://graphics.stanford.edu/~seander/bithacks.html
|
||||
(Orignal code public domain)
|
||||
|
||||
Comments shows how this works with 01100000000000000000000000001011
|
||||
perl -e 'print map{", 0x".unpack H2,pack B8,unpack b8,chr$_}(0..255)'
|
||||
*/
|
||||
const uchar _my_bits_reverse_table[256]={
|
||||
0x00, 0x80, 0x40, 0xC0, 0x20, 0xA0, 0x60, 0xE0, 0x10, 0x90, 0x50, 0xD0, 0x30,
|
||||
0xB0, 0x70, 0xF0, 0x08, 0x88, 0x48, 0xC8, 0x28, 0xA8, 0x68, 0xE8, 0x18, 0x98,
|
||||
0x58, 0xD8, 0x38, 0xB8, 0x78, 0xF8, 0x04, 0x84, 0x44, 0xC4, 0x24, 0xA4, 0x64,
|
||||
0xE4, 0x14, 0x94, 0x54, 0xD4, 0x34, 0xB4, 0x74, 0xF4, 0x0C, 0x8C, 0x4C, 0xCC,
|
||||
0x2C, 0xAC, 0x6C, 0xEC, 0x1C, 0x9C, 0x5C, 0xDC, 0x3C, 0xBC, 0x7C, 0xFC, 0x02,
|
||||
0x82, 0x42, 0xC2, 0x22, 0xA2, 0x62, 0xE2, 0x12, 0x92, 0x52, 0xD2, 0x32, 0xB2,
|
||||
0x72, 0xF2, 0x0A, 0x8A, 0x4A, 0xCA, 0x2A, 0xAA, 0x6A, 0xEA, 0x1A, 0x9A, 0x5A,
|
||||
0xDA, 0x3A, 0xBA, 0x7A, 0xFA, 0x06, 0x86, 0x46, 0xC6, 0x26, 0xA6, 0x66, 0xE6,
|
||||
0x16, 0x96, 0x56, 0xD6, 0x36, 0xB6, 0x76, 0xF6, 0x0E, 0x8E, 0x4E, 0xCE, 0x2E,
|
||||
0xAE, 0x6E, 0xEE, 0x1E, 0x9E, 0x5E, 0xDE, 0x3E, 0xBE, 0x7E, 0xFE, 0x01, 0x81,
|
||||
0x41, 0xC1, 0x21, 0xA1, 0x61, 0xE1, 0x11, 0x91, 0x51, 0xD1, 0x31, 0xB1, 0x71,
|
||||
0xF1, 0x09, 0x89, 0x49, 0xC9, 0x29, 0xA9, 0x69, 0xE9, 0x19, 0x99, 0x59, 0xD9,
|
||||
0x39, 0xB9, 0x79, 0xF9, 0x05, 0x85, 0x45, 0xC5, 0x25, 0xA5, 0x65, 0xE5, 0x15,
|
||||
0x95, 0x55, 0xD5, 0x35, 0xB5, 0x75, 0xF5, 0x0D, 0x8D, 0x4D, 0xCD, 0x2D, 0xAD,
|
||||
0x6D, 0xED, 0x1D, 0x9D, 0x5D, 0xDD, 0x3D, 0xBD, 0x7D, 0xFD, 0x03, 0x83, 0x43,
|
||||
0xC3, 0x23, 0xA3, 0x63, 0xE3, 0x13, 0x93, 0x53, 0xD3, 0x33, 0xB3, 0x73, 0xF3,
|
||||
0x0B, 0x8B, 0x4B, 0xCB, 0x2B, 0xAB, 0x6B, 0xEB, 0x1B, 0x9B, 0x5B, 0xDB, 0x3B,
|
||||
0xBB, 0x7B, 0xFB, 0x07, 0x87, 0x47, 0xC7, 0x27, 0xA7, 0x67, 0xE7, 0x17, 0x97,
|
||||
0x57, 0xD7, 0x37, 0xB7, 0x77, 0xF7, 0x0F, 0x8F, 0x4F, 0xCF, 0x2F, 0xAF, 0x6F,
|
||||
0xEF, 0x1F, 0x9F, 0x5F, 0xDF, 0x3F, 0xBF, 0x7F, 0xFF
|
||||
};
|
||||
|
||||
uint32 my_round_up_to_next_power(uint32 v)
|
||||
{
|
||||
v--; /* 01100000000000000000000000001010 */
|
||||
v|= v >> 1; /* 01110000000000000000000000001111 */
|
||||
v|= v >> 2; /* 01111100000000000000000000001111 */
|
||||
v|= v >> 4; /* 01111111110000000000000000001111 */
|
||||
v|= v >> 8; /* 01111111111111111100000000001111 */
|
||||
v|= v >> 16; /* 01111111111111111111111111111111 */
|
||||
return v+1; /* 10000000000000000000000000000000 */
|
||||
}
|
||||
|
|
|
|||
|
|
@ -38,6 +38,7 @@
|
|||
#include "mysys_priv.h"
|
||||
#include <my_bitmap.h>
|
||||
#include <m_string.h>
|
||||
#include <my_bit.h>
|
||||
|
||||
void create_last_word_mask(MY_BITMAP *map)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -181,7 +181,8 @@ int packfrm(uchar *data, size_t len,
|
|||
if (my_compress((uchar*)data, &org_len, &comp_len))
|
||||
goto err;
|
||||
|
||||
DBUG_PRINT("info", ("org_len: %lu comp_len: %lu", (ulong) org_len, (ulong) comp_len));
|
||||
DBUG_PRINT("info", ("org_len: %lu comp_len: %lu", (ulong) org_len,
|
||||
(ulong) comp_len));
|
||||
DBUG_DUMP("compressed", data, org_len);
|
||||
|
||||
error= 2;
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@
|
|||
#include <my_dir.h>
|
||||
#include "mysys_err.h"
|
||||
#include <errno.h>
|
||||
#include <my_sys.h>
|
||||
#if defined(__WIN__)
|
||||
#include <share.h>
|
||||
#endif
|
||||
|
|
@ -52,6 +53,13 @@ File my_create(const char *FileName, int CreateFlags, int access_flags,
|
|||
fd = open(FileName, access_flags);
|
||||
#endif
|
||||
|
||||
if ((MyFlags & MY_SYNC_DIR) && (fd >=0) &&
|
||||
my_sync_dir_by_file(FileName, MyFlags))
|
||||
{
|
||||
my_close(fd, MyFlags);
|
||||
fd= -1;
|
||||
}
|
||||
|
||||
DBUG_RETURN(my_register_filename(fd, FileName, FILE_BY_CREATE,
|
||||
EE_CANTCREATEFILE, MyFlags));
|
||||
} /* my_create */
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@
|
|||
|
||||
#include "mysys_priv.h"
|
||||
#include "mysys_err.h"
|
||||
#include <my_sys.h>
|
||||
|
||||
int my_delete(const char *name, myf MyFlags)
|
||||
{
|
||||
|
|
@ -29,6 +30,9 @@ int my_delete(const char *name, myf MyFlags)
|
|||
my_error(EE_DELETE,MYF(ME_BELL+ME_WAITTANG+(MyFlags & ME_NOINPUT)),
|
||||
name,errno);
|
||||
}
|
||||
else if ((MyFlags & MY_SYNC_DIR) &&
|
||||
my_sync_dir_by_file(name, MyFlags))
|
||||
err= -1;
|
||||
DBUG_RETURN(err);
|
||||
} /* my_delete */
|
||||
|
||||
|
|
|
|||
|
|
@ -84,11 +84,6 @@ int my_error(int nr, myf MyFlags, ...)
|
|||
if (nr <= meh_p->meh_last)
|
||||
break;
|
||||
|
||||
#ifdef SHARED_LIBRARY
|
||||
if ((meh_p == &my_errmsgs_globerrs) && ! globerrs[0])
|
||||
init_glob_errs();
|
||||
#endif
|
||||
|
||||
/* get the error message string. Default, if NULL or empty string (""). */
|
||||
if (! (format= (meh_p && (nr >= meh_p->meh_first)) ?
|
||||
meh_p->meh_errmsgs[nr - meh_p->meh_first] : NULL) || ! *format)
|
||||
|
|
|
|||
|
|
@ -17,6 +17,11 @@
|
|||
/* thus to get the current time we should use the system function
|
||||
with the highest possible resolution */
|
||||
|
||||
/*
|
||||
TODO: in functions my_micro_time() and my_micro_time_and_time() there
|
||||
exists some common code that should be merged into a function.
|
||||
*/
|
||||
|
||||
#include "mysys_priv.h"
|
||||
#include "my_static.h"
|
||||
|
||||
|
|
@ -35,9 +40,9 @@ ulonglong my_getsystime()
|
|||
if (query_performance_frequency)
|
||||
{
|
||||
QueryPerformanceCounter(&t_cnt);
|
||||
return (t_cnt.QuadPart / query_performance_frequency * 10000000+
|
||||
t_cnt.QuadPart % query_performance_frequency * 10000000/
|
||||
query_performance_frequency+query_performance_offset);
|
||||
return ((t_cnt.QuadPart / query_performance_frequency * 10000000) +
|
||||
((t_cnt.QuadPart % query_performance_frequency) * 10000000 /
|
||||
query_performance_frequency) + query_performance_offset);
|
||||
}
|
||||
return 0;
|
||||
#elif defined(__NETWARE__)
|
||||
|
|
@ -103,21 +108,18 @@ time_t my_time(myf flags __attribute__((unused)))
|
|||
|
||||
ulonglong my_micro_time()
|
||||
{
|
||||
ulonglong newtime;
|
||||
#if defined(__WIN__)
|
||||
if (query_performance_frequency)
|
||||
{
|
||||
QueryPerformanceCounter((LARGE_INTEGER*) &newtime);
|
||||
newtime/= (query_performance_frequency * 1000000);
|
||||
}
|
||||
else
|
||||
newtime= (GetTickCount() * 1000); /* GetTickCount only returns milliseconds */
|
||||
return newtime;
|
||||
ulonglong newtime;
|
||||
GetSystemTimeAsFileTime((FILETIME*)&newtime);
|
||||
return (newtime/10);
|
||||
#elif defined(HAVE_GETHRTIME)
|
||||
return gethrtime()/1000;
|
||||
#else
|
||||
ulonglong newtime;
|
||||
struct timeval t;
|
||||
/* The following loop is here because gettimeofday may fail on some systems */
|
||||
/*
|
||||
The following loop is here because gettimeofday may fail on some systems
|
||||
*/
|
||||
while (gettimeofday(&t, NULL) != 0)
|
||||
{}
|
||||
newtime= (ulonglong)t.tv_sec * 1000000 + t.tv_usec;
|
||||
|
|
@ -131,18 +133,18 @@ ulonglong my_micro_time()
|
|||
|
||||
SYNOPSIS
|
||||
my_micro_time_and_time()
|
||||
time_arg Will be set to seconds since epoch (00:00:00 UTC, January 1,
|
||||
1970)
|
||||
time_arg Will be set to seconds since epoch (00:00:00 UTC,
|
||||
January 1, 1970)
|
||||
|
||||
NOTES
|
||||
This function is to be useful when we need both the time and microtime.
|
||||
For example in MySQL this is used to get the query time start of a query and
|
||||
to measure the time of a query (for the slow query log)
|
||||
For example in MySQL this is used to get the query time start of a query
|
||||
and to measure the time of a query (for the slow query log)
|
||||
|
||||
IMPLEMENTATION
|
||||
Value of time is as in time() call.
|
||||
Value of microtime is same as my_micro_time(), which may be totally unrealated
|
||||
to time()
|
||||
Value of microtime is same as my_micro_time(), which may be totally
|
||||
unrealated to time()
|
||||
|
||||
RETURN
|
||||
Value in microseconds from some undefined point in time
|
||||
|
|
@ -152,21 +154,15 @@ ulonglong my_micro_time()
|
|||
|
||||
ulonglong my_micro_time_and_time(time_t *time_arg)
|
||||
{
|
||||
ulonglong newtime;
|
||||
#if defined(__WIN__)
|
||||
if (query_performance_frequency)
|
||||
{
|
||||
QueryPerformanceCounter((LARGE_INTEGER*) &newtime);
|
||||
newtime/= (query_performance_frequency * 1000000);
|
||||
}
|
||||
else
|
||||
newtime= (GetTickCount() * 1000); /* GetTickCount only returns milliseconds */
|
||||
(void) time(time_arg);
|
||||
return newtime;
|
||||
ulonglong newtime;
|
||||
GetSystemTimeAsFileTime((FILETIME*)&newtime);
|
||||
*time_arg= (time_t) ((newtime - OFFSET_TO_EPOCH) / 10000000);
|
||||
return (newtime/10);
|
||||
#elif defined(HAVE_GETHRTIME)
|
||||
/*
|
||||
Solaris has a very slow time() call. We optimize this by using the very fast
|
||||
gethrtime() call and only calling time() every 1/2 second
|
||||
Solaris has a very slow time() call. We optimize this by using the very
|
||||
fast gethrtime() call and only calling time() every 1/2 second
|
||||
*/
|
||||
static hrtime_t prev_gethrtime= 0;
|
||||
static time_t cur_time= 0;
|
||||
|
|
@ -183,8 +179,11 @@ ulonglong my_micro_time_and_time(time_t *time_arg)
|
|||
pthread_mutex_unlock(&THR_LOCK_time);
|
||||
return cur_gethrtime/1000;
|
||||
#else
|
||||
ulonglong newtime;
|
||||
struct timeval t;
|
||||
/* The following loop is here because gettimeofday may fail on some systems */
|
||||
/*
|
||||
The following loop is here because gettimeofday may fail on some systems
|
||||
*/
|
||||
while (gettimeofday(&t, NULL) != 0)
|
||||
{}
|
||||
*time_arg= t.tv_sec;
|
||||
|
|
@ -203,8 +202,8 @@ ulonglong my_micro_time_and_time(time_t *time_arg)
|
|||
|
||||
NOTES
|
||||
This function returns the current time. The microtime argument is only used
|
||||
if my_micro_time() uses a function that can safely be converted to the current
|
||||
time.
|
||||
if my_micro_time() uses a function that can safely be converted to the
|
||||
current time.
|
||||
|
||||
RETURN
|
||||
current time
|
||||
|
|
|
|||
|
|
@ -16,9 +16,12 @@
|
|||
MA 02111-1307, USA */
|
||||
|
||||
#include <my_global.h>
|
||||
#include "my_handler.h"
|
||||
#include <m_ctype.h>
|
||||
#include <my_base.h>
|
||||
#include <my_handler.h>
|
||||
#include <my_sys.h>
|
||||
|
||||
int mi_compare_text(CHARSET_INFO *charset_info, uchar *a, uint a_length,
|
||||
int ha_compare_text(CHARSET_INFO *charset_info, uchar *a, uint a_length,
|
||||
uchar *b, uint b_length, my_bool part_key,
|
||||
my_bool skip_end_space)
|
||||
{
|
||||
|
|
@ -174,7 +177,7 @@ int ha_key_cmp(register HA_KEYSEG *keyseg, register uchar *a,
|
|||
next_key_length=key_length-b_length-pack_length;
|
||||
|
||||
if (piks &&
|
||||
(flag=mi_compare_text(keyseg->charset,a,a_length,b,b_length,
|
||||
(flag=ha_compare_text(keyseg->charset,a,a_length,b,b_length,
|
||||
(my_bool) ((nextflag & SEARCH_PREFIX) &&
|
||||
next_key_length <= 0),
|
||||
(my_bool)!(nextflag & SEARCH_PREFIX))))
|
||||
|
|
@ -187,7 +190,7 @@ int ha_key_cmp(register HA_KEYSEG *keyseg, register uchar *a,
|
|||
{
|
||||
uint length=(uint) (end-a), a_length=length, b_length=length;
|
||||
if (piks &&
|
||||
(flag= mi_compare_text(keyseg->charset, a, a_length, b, b_length,
|
||||
(flag= ha_compare_text(keyseg->charset, a, a_length, b, b_length,
|
||||
(my_bool) ((nextflag & SEARCH_PREFIX) &&
|
||||
next_key_length <= 0),
|
||||
(my_bool)!(nextflag & SEARCH_PREFIX))))
|
||||
|
|
@ -235,7 +238,7 @@ int ha_key_cmp(register HA_KEYSEG *keyseg, register uchar *a,
|
|||
next_key_length=key_length-b_length-pack_length;
|
||||
|
||||
if (piks &&
|
||||
(flag= mi_compare_text(keyseg->charset,a,a_length,b,b_length,
|
||||
(flag= ha_compare_text(keyseg->charset,a,a_length,b,b_length,
|
||||
(my_bool) ((nextflag & SEARCH_PREFIX) &&
|
||||
next_key_length <= 0),
|
||||
(my_bool) ((nextflag & (SEARCH_FIND |
|
||||
|
|
@ -482,12 +485,15 @@ end:
|
|||
|
||||
DESCRIPTION
|
||||
Find the first NULL value in index-suffix values tuple.
|
||||
TODO Consider optimizing this fuction or its use so we don't search for
|
||||
NULL values in completely NOT NULL index suffixes.
|
||||
|
||||
TODO
|
||||
Consider optimizing this function or its use so we don't search for
|
||||
NULL values in completely NOT NULL index suffixes.
|
||||
|
||||
RETURN
|
||||
First key part that has NULL as value in values tuple, or the last key part
|
||||
(with keyseg->type==HA_TYPE_END) if values tuple doesn't contain NULLs.
|
||||
First key part that has NULL as value in values tuple, or the last key
|
||||
part (with keyseg->type==HA_TYPE_END) if values tuple doesn't contain
|
||||
NULLs.
|
||||
*/
|
||||
|
||||
HA_KEYSEG *ha_find_null(HA_KEYSEG *keyseg, uchar *a)
|
||||
|
|
@ -557,3 +563,69 @@ HA_KEYSEG *ha_find_null(HA_KEYSEG *keyseg, uchar *a)
|
|||
}
|
||||
return keyseg;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Errors a handler can give you
|
||||
*/
|
||||
|
||||
static const char *handler_error_messages[]=
|
||||
{
|
||||
"Didn't find key on read or update",
|
||||
"Duplicate key on write or update",
|
||||
"Undefined handler error 122",
|
||||
"Someone has changed the row since it was read (while the table was locked to prevent it)",
|
||||
"Wrong index given to function",
|
||||
"Undefined handler error 125",
|
||||
"Index file is crashed",
|
||||
"Record file is crashed",
|
||||
"Out of memory in engine",
|
||||
"Undefined handler error 129",
|
||||
"Incorrect file format",
|
||||
"Command not supported by database",
|
||||
"Old database file",
|
||||
"No record read before update",
|
||||
"Record was already deleted (or record file crashed)",
|
||||
"No more room in record file",
|
||||
"No more room in index file",
|
||||
"No more records (read after end of file)",
|
||||
"Unsupported extension used for table",
|
||||
"Too big row",
|
||||
"Wrong create options",
|
||||
"Duplicate unique key or constraint on write or update",
|
||||
"Unknown character set used in table",
|
||||
"Conflicting table definitions in sub-tables of MERGE table",
|
||||
"Table is crashed and last repair failed",
|
||||
"Table was marked as crashed and should be repaired",
|
||||
"Lock timed out; Retry transaction",
|
||||
"Lock table is full; Restart program with a larger locktable",
|
||||
"Updates are not allowed under a read only transactions",
|
||||
"Lock deadlock; Retry transaction",
|
||||
"Foreign key constraint is incorrectly formed",
|
||||
"Cannot add a child row",
|
||||
"Cannot delete a parent row",
|
||||
"Unknown handler error"
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
Register handler error messages for usage with my_error()
|
||||
|
||||
NOTES
|
||||
This is safe to call multiple times as my_error_register()
|
||||
will ignore calls to register already registered error numbers.
|
||||
*/
|
||||
|
||||
|
||||
void my_handler_error_register(void)
|
||||
{
|
||||
my_error_register(handler_error_messages, HA_ERR_FIRST,
|
||||
HA_ERR_FIRST+ array_elements(handler_error_messages)-1);
|
||||
}
|
||||
|
||||
|
||||
void my_handler_error_unregister(void)
|
||||
{
|
||||
my_error_unregister(HA_ERR_FIRST,
|
||||
HA_ERR_FIRST+ array_elements(handler_error_messages)-1);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -43,6 +43,7 @@ static void netware_init();
|
|||
|
||||
my_bool my_init_done= 0;
|
||||
uint mysys_usage_id= 0; /* Incremented for each my_init() */
|
||||
ulong my_thread_stack_size= 65536;
|
||||
|
||||
static ulong atoi_octal(const char *str)
|
||||
{
|
||||
|
|
@ -76,6 +77,7 @@ my_bool my_init(void)
|
|||
mysys_usage_id++;
|
||||
my_umask= 0660; /* Default umask for new files */
|
||||
my_umask_dir= 0700; /* Default umask for new directories */
|
||||
init_glob_errs();
|
||||
#if defined(THREAD) && defined(SAFE_MUTEX)
|
||||
safe_mutex_global_init(); /* Must be called early */
|
||||
#endif
|
||||
|
|
@ -343,6 +345,30 @@ static void my_win_init(void)
|
|||
|
||||
_tzset();
|
||||
|
||||
/* The following is used by time functions */
|
||||
#define OFFSET_TO_EPOC ((__int64) 134774 * 24 * 60 * 60 * 1000 * 1000 * 10)
|
||||
#define MS 10000000
|
||||
{
|
||||
FILETIME ft;
|
||||
LARGE_INTEGER li, t_cnt;
|
||||
DBUG_ASSERT(sizeof(LARGE_INTEGER) == sizeof(query_performance_frequency));
|
||||
if (QueryPerformanceFrequency((LARGE_INTEGER *)&query_performance_frequency) == 0)
|
||||
query_performance_frequency= 0;
|
||||
else
|
||||
{
|
||||
GetSystemTimeAsFileTime(&ft);
|
||||
li.LowPart= ft.dwLowDateTime;
|
||||
li.HighPart= ft.dwHighDateTime;
|
||||
query_performance_offset= li.QuadPart-OFFSET_TO_EPOC;
|
||||
QueryPerformanceCounter(&t_cnt);
|
||||
query_performance_offset-= (t_cnt.QuadPart /
|
||||
query_performance_frequency * MS +
|
||||
t_cnt.QuadPart %
|
||||
query_performance_frequency * MS /
|
||||
query_performance_frequency);
|
||||
}
|
||||
}
|
||||
|
||||
/* apre la chiave HKEY_LOCAL_MACHINES\software\MySQL */
|
||||
if (RegOpenKeyEx(HKEY_LOCAL_MACHINE,(LPCTSTR)targetKey,0,
|
||||
KEY_READ,&hSoftMysql) != ERROR_SUCCESS)
|
||||
|
|
@ -380,27 +406,6 @@ static void my_win_init(void)
|
|||
/* chiude la chiave */
|
||||
RegCloseKey(hSoftMysql) ;
|
||||
|
||||
/* The following is used by time functions */
|
||||
#define OFFSET_TO_EPOC ((__int64) 134774 * 24 * 60 * 60 * 1000 * 1000 * 10)
|
||||
#define MS 10000000
|
||||
{
|
||||
FILETIME ft;
|
||||
LARGE_INTEGER li, t_cnt;
|
||||
DBUG_ASSERT(sizeof(LARGE_INTEGER) == sizeof(query_performance_frequency));
|
||||
if (QueryPerformanceFrequency((LARGE_INTEGER *)&query_performance_frequency))
|
||||
query_performance_frequency= 0;
|
||||
else
|
||||
{
|
||||
GetSystemTimeAsFileTime(&ft);
|
||||
li.LowPart= ft.dwLowDateTime;
|
||||
li.HighPart= ft.dwHighDateTime;
|
||||
query_performance_offset= li.QuadPart-OFFSET_TO_EPOC;
|
||||
QueryPerformanceCounter(&t_cnt);
|
||||
query_performance_offset-= (t_cnt.QuadPart / query_performance_frequency * MS +
|
||||
t_cnt.QuadPart % query_performance_frequency * MS /
|
||||
query_performance_frequency);
|
||||
}
|
||||
}
|
||||
DBUG_VOID_RETURN ;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -71,6 +71,7 @@ File my_open(const char *FileName, int Flags, myf MyFlags)
|
|||
#else
|
||||
fd = open((char *) FileName, Flags);
|
||||
#endif
|
||||
|
||||
DBUG_RETURN(my_register_filename(fd, FileName, FILE_BY_OPEN,
|
||||
EE_FILENOTFOUND, MyFlags));
|
||||
} /* my_open */
|
||||
|
|
@ -124,61 +125,66 @@ int my_close(File fd, myf MyFlags)
|
|||
|
||||
SYNOPSIS
|
||||
my_register_filename()
|
||||
fd
|
||||
FileName
|
||||
type_file_type
|
||||
fd File number opened, -1 if error on open
|
||||
FileName File name
|
||||
type_file_type How file was created
|
||||
error_message_number Error message number if caller got error (fd == -1)
|
||||
MyFlags Flags for my_close()
|
||||
|
||||
RETURN
|
||||
-1 error
|
||||
# Filenumber
|
||||
|
||||
*/
|
||||
|
||||
File my_register_filename(File fd, const char *FileName, enum file_type
|
||||
type_of_file, uint error_message_number, myf MyFlags)
|
||||
{
|
||||
DBUG_ENTER("my_register_filename");
|
||||
if ((int) fd >= 0)
|
||||
{
|
||||
if ((uint) fd >= my_file_limit)
|
||||
{
|
||||
#if defined(THREAD) && !defined(HAVE_PREAD)
|
||||
(void) my_close(fd,MyFlags);
|
||||
my_errno=EMFILE;
|
||||
if (MyFlags & (MY_FFNF | MY_FAE | MY_WME))
|
||||
my_error(EE_OUT_OF_FILERESOURCES, MYF(ME_BELL+ME_WAITTANG),
|
||||
FileName, my_errno);
|
||||
return(-1);
|
||||
#endif
|
||||
my_errno= EMFILE;
|
||||
#else
|
||||
thread_safe_increment(my_file_opened,&THR_LOCK_open);
|
||||
return(fd); /* safeguard */
|
||||
}
|
||||
pthread_mutex_lock(&THR_LOCK_open);
|
||||
if ((my_file_info[fd].name = (char*) my_strdup(FileName,MyFlags)))
|
||||
{
|
||||
my_file_opened++;
|
||||
my_file_total_opened++;
|
||||
my_file_info[fd].type = type_of_file;
|
||||
#if defined(THREAD) && !defined(HAVE_PREAD)
|
||||
pthread_mutex_init(&my_file_info[fd].mutex,MY_MUTEX_INIT_FAST);
|
||||
DBUG_RETURN(fd); /* safeguard */
|
||||
#endif
|
||||
pthread_mutex_unlock(&THR_LOCK_open);
|
||||
DBUG_PRINT("exit",("fd: %d",fd));
|
||||
return(fd);
|
||||
}
|
||||
pthread_mutex_unlock(&THR_LOCK_open);
|
||||
else
|
||||
{
|
||||
pthread_mutex_lock(&THR_LOCK_open);
|
||||
if ((my_file_info[fd].name = (char*) my_strdup(FileName,MyFlags)))
|
||||
{
|
||||
my_file_opened++;
|
||||
my_file_total_opened++;
|
||||
my_file_info[fd].type = type_of_file;
|
||||
#if defined(THREAD) && !defined(HAVE_PREAD)
|
||||
pthread_mutex_init(&my_file_info[fd].mutex,MY_MUTEX_INIT_FAST);
|
||||
#endif
|
||||
pthread_mutex_unlock(&THR_LOCK_open);
|
||||
DBUG_PRINT("exit",("fd: %d",fd));
|
||||
DBUG_RETURN(fd);
|
||||
}
|
||||
pthread_mutex_unlock(&THR_LOCK_open);
|
||||
my_errno= ENOMEM;
|
||||
}
|
||||
(void) my_close(fd, MyFlags);
|
||||
my_errno=ENOMEM;
|
||||
}
|
||||
else
|
||||
my_errno=errno;
|
||||
DBUG_PRINT("error",("Got error %d on open",my_errno));
|
||||
if (MyFlags & (MY_FFNF | MY_FAE | MY_WME)) {
|
||||
if (my_errno == EMFILE) {
|
||||
DBUG_PRINT("error",("print err: %d",EE_OUT_OF_FILERESOURCES));
|
||||
my_error(EE_OUT_OF_FILERESOURCES, MYF(ME_BELL+ME_WAITTANG),
|
||||
FileName, my_errno);
|
||||
} else {
|
||||
DBUG_PRINT("error",("print err: %d",error_message_number));
|
||||
my_error(error_message_number, MYF(ME_BELL+ME_WAITTANG),
|
||||
FileName, my_errno);
|
||||
}
|
||||
my_errno= errno;
|
||||
|
||||
DBUG_PRINT("error",("Got error %d on open", my_errno));
|
||||
if (MyFlags & (MY_FFNF | MY_FAE | MY_WME))
|
||||
{
|
||||
if (my_errno == EMFILE)
|
||||
error_message_number= EE_OUT_OF_FILERESOURCES;
|
||||
DBUG_PRINT("error",("print err: %d",error_message_number));
|
||||
my_error(error_message_number, MYF(ME_BELL+ME_WAITTANG),
|
||||
FileName, my_errno);
|
||||
}
|
||||
return(fd);
|
||||
DBUG_RETURN(-1);
|
||||
}
|
||||
|
||||
#ifdef __WIN__
|
||||
|
|
|
|||
|
|
@ -63,12 +63,12 @@ size_t my_pread(File Filedes, uchar *Buffer, size_t Count, my_off_t offset,
|
|||
pthread_mutex_unlock(&my_file_info[Filedes].mutex);
|
||||
#else
|
||||
if ((error= ((readbytes= pread(Filedes, Buffer, Count, offset)) != Count)))
|
||||
my_errno= errno;
|
||||
my_errno= errno ? errno : -1;
|
||||
#endif
|
||||
if (error || readbytes != Count)
|
||||
{
|
||||
DBUG_PRINT("warning",("Read only %d bytes off %u from %d, errno: %d",
|
||||
(int) readbytes, (uint) Count,Filedes,my_errno));
|
||||
(int) readbytes, (uint) Count,Filedes,my_errno));
|
||||
#ifdef THREAD
|
||||
if ((readbytes == 0 || readbytes == (size_t) -1) && errno == EINTR)
|
||||
{
|
||||
|
|
@ -115,7 +115,7 @@ size_t my_pread(File Filedes, uchar *Buffer, size_t Count, my_off_t offset,
|
|||
RETURN
|
||||
(size_t) -1 Error
|
||||
# Number of bytes read
|
||||
*/
|
||||
*/
|
||||
|
||||
size_t my_pwrite(int Filedes, const uchar *Buffer, size_t Count,
|
||||
my_off_t offset, myf MyFlags)
|
||||
|
|
|
|||
|
|
@ -22,6 +22,16 @@
|
|||
|
||||
/* My memory re allocator */
|
||||
|
||||
/**
|
||||
@brief wrapper around realloc()
|
||||
|
||||
@param oldpoint pointer to currently allocated area
|
||||
@param size new size requested, must be >0
|
||||
@param my_flags flags
|
||||
|
||||
@note if size==0 realloc() may return NULL; my_realloc() treats this as an
|
||||
error which is not the intention of realloc()
|
||||
*/
|
||||
void* my_realloc(void* oldpoint, size_t size, myf my_flags)
|
||||
{
|
||||
void *point;
|
||||
|
|
@ -29,6 +39,7 @@ void* my_realloc(void* oldpoint, size_t size, myf my_flags)
|
|||
DBUG_PRINT("my",("ptr: 0x%lx size: %lu my_flags: %d", (long) oldpoint,
|
||||
(ulong) size, my_flags));
|
||||
|
||||
DBUG_ASSERT(size > 0);
|
||||
if (!oldpoint && (my_flags & MY_ALLOW_ZERO_PTR))
|
||||
DBUG_RETURN(my_malloc(size,my_flags));
|
||||
#ifdef USE_HALLOC
|
||||
|
|
|
|||
|
|
@ -16,8 +16,9 @@
|
|||
#include "mysys_priv.h"
|
||||
#include <my_dir.h>
|
||||
#include "mysys_err.h"
|
||||
|
||||
#include "m_string.h"
|
||||
#undef my_rename
|
||||
|
||||
/* On unix rename deletes to file if it exists */
|
||||
|
||||
int my_rename(const char *from, const char *to, myf MyFlags)
|
||||
|
|
@ -60,5 +61,19 @@ int my_rename(const char *from, const char *to, myf MyFlags)
|
|||
if (MyFlags & (MY_FAE+MY_WME))
|
||||
my_error(EE_LINK, MYF(ME_BELL+ME_WAITTANG),from,to,my_errno);
|
||||
}
|
||||
else if (MyFlags & MY_SYNC_DIR)
|
||||
{
|
||||
#ifdef NEED_EXPLICIT_SYNC_DIR
|
||||
/* do only the needed amount of syncs: */
|
||||
char dir_from[FN_REFLEN], dir_to[FN_REFLEN];
|
||||
size_t dir_from_length, dir_to_length;
|
||||
dirname_part(dir_from, from, &dir_from_length);
|
||||
dirname_part(dir_to, to, &dir_to_length);
|
||||
if (my_sync_dir(dir_from, MyFlags) ||
|
||||
(strcmp(dir_from, dir_to) &&
|
||||
my_sync_dir(dir_to, MyFlags)))
|
||||
error= -1;
|
||||
#endif
|
||||
}
|
||||
DBUG_RETURN(error);
|
||||
} /* my_rename */
|
||||
|
|
|
|||
|
|
@ -84,6 +84,8 @@ int my_symlink(const char *content, const char *linkname, myf MyFlags)
|
|||
if (MyFlags & MY_WME)
|
||||
my_error(EE_CANT_SYMLINK, MYF(0), linkname, content, errno);
|
||||
}
|
||||
else if ((MyFlags & MY_SYNC_DIR) && my_sync_dir_by_file(linkname, MyFlags))
|
||||
result= -1;
|
||||
DBUG_RETURN(result);
|
||||
#endif /* HAVE_READLINK */
|
||||
}
|
||||
|
|
|
|||
|
|
@ -48,6 +48,16 @@ int my_sync(File fd, myf my_flags)
|
|||
|
||||
do
|
||||
{
|
||||
#if defined(F_FULLFSYNC)
|
||||
/*
|
||||
In Mac OS X >= 10.3 this call is safer than fsync() (it forces the
|
||||
disk's cache and guarantees ordered writes).
|
||||
*/
|
||||
if (!(res= fcntl(fd, F_FULLFSYNC, 0)))
|
||||
break; /* ok */
|
||||
/* Some file systems don't support F_FULLFSYNC and fail above: */
|
||||
DBUG_PRINT("info",("fcntl(F_FULLFSYNC) failed, falling back"));
|
||||
#endif
|
||||
#if defined(HAVE_FDATASYNC)
|
||||
res= fdatasync(fd);
|
||||
#elif defined(HAVE_FSYNC)
|
||||
|
|
@ -55,6 +65,7 @@ int my_sync(File fd, myf my_flags)
|
|||
#elif defined(__WIN__)
|
||||
res= _commit(fd);
|
||||
#else
|
||||
#error Cannot find a way to sync a file, durability in danger
|
||||
res= 0; /* No sync (strange OS) */
|
||||
#endif
|
||||
} while (res == -1 && errno == EINTR);
|
||||
|
|
@ -66,10 +77,79 @@ int my_sync(File fd, myf my_flags)
|
|||
my_errno= -1; /* Unknown error */
|
||||
if ((my_flags & MY_IGNORE_BADFD) &&
|
||||
(er == EBADF || er == EINVAL || er == EROFS))
|
||||
{
|
||||
DBUG_PRINT("info", ("ignoring errno %d", er));
|
||||
res= 0;
|
||||
}
|
||||
else if (my_flags & MY_WME)
|
||||
my_error(EE_SYNC, MYF(ME_BELL+ME_WAITTANG), my_filename(fd), my_errno);
|
||||
}
|
||||
DBUG_RETURN(res);
|
||||
} /* my_sync */
|
||||
|
||||
|
||||
static const char cur_dir_name[]= {FN_CURLIB, 0};
|
||||
/*
|
||||
Force directory information to disk.
|
||||
|
||||
SYNOPSIS
|
||||
my_sync_dir()
|
||||
dir_name the name of the directory
|
||||
my_flags flags (MY_WME etc)
|
||||
|
||||
RETURN
|
||||
0 if ok, !=0 if error
|
||||
*/
|
||||
int my_sync_dir(const char *dir_name, myf my_flags)
|
||||
{
|
||||
#ifdef NEED_EXPLICIT_SYNC_DIR
|
||||
DBUG_ENTER("my_sync_dir");
|
||||
DBUG_PRINT("my",("Dir: '%s' my_flags: %d", dir_name, my_flags));
|
||||
File dir_fd;
|
||||
int res= 0;
|
||||
const char *correct_dir_name;
|
||||
/* Sometimes the path does not contain an explicit directory */
|
||||
correct_dir_name= (dir_name[0] == 0) ? cur_dir_name : dir_name;
|
||||
/*
|
||||
Syncing a dir may give EINVAL on tmpfs on Linux, which is ok.
|
||||
EIO on the other hand is very important. Hence MY_IGNORE_BADFD.
|
||||
*/
|
||||
if ((dir_fd= my_open(correct_dir_name, O_RDONLY, MYF(my_flags))) >= 0)
|
||||
{
|
||||
if (my_sync(dir_fd, MYF(my_flags | MY_IGNORE_BADFD)))
|
||||
res= 2;
|
||||
if (my_close(dir_fd, MYF(my_flags)))
|
||||
res= 3;
|
||||
}
|
||||
else
|
||||
res= 1;
|
||||
DBUG_RETURN(res);
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Force directory information to disk.
|
||||
|
||||
SYNOPSIS
|
||||
my_sync_dir_by_file()
|
||||
file_name the name of a file in the directory
|
||||
my_flags flags (MY_WME etc)
|
||||
|
||||
RETURN
|
||||
0 if ok, !=0 if error
|
||||
*/
|
||||
int my_sync_dir_by_file(const char *file_name, myf my_flags)
|
||||
{
|
||||
#ifdef NEED_EXPLICIT_SYNC_DIR
|
||||
char dir_name[FN_REFLEN];
|
||||
size_t dir_name_length;
|
||||
dirname_part(dir_name, file_name, &dir_name_length);
|
||||
return my_sync_dir(dir_name, my_flags);
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -430,6 +430,29 @@ void TERMINATE(FILE *file, uint flag)
|
|||
}
|
||||
|
||||
|
||||
/*
|
||||
Report where a piece of memory was allocated
|
||||
|
||||
This is usefull to call from withing a debugger
|
||||
*/
|
||||
|
||||
|
||||
void sf_malloc_report_allocated(void *memory)
|
||||
{
|
||||
struct st_irem *irem;
|
||||
for (irem= sf_malloc_root ; irem ; irem=irem->next)
|
||||
{
|
||||
char *data= (((char*) irem) + ALIGN_SIZE(sizeof(struct st_irem)) +
|
||||
sf_malloc_prehunc);
|
||||
if (data <= (char*) memory && (char*) memory <= data + irem->datasize)
|
||||
{
|
||||
printf("%u bytes at 0x%lx, allocated at line %u in '%s'\n",
|
||||
irem->datasize, (long) data, irem->linenum, irem->filename);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Returns 0 if chunk is ok */
|
||||
|
||||
static int _checkchunk(register struct st_irem *irem, const char *filename,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue