summaryrefslogtreecommitdiff
path: root/mysys
diff options
context:
space:
mode:
Diffstat (limited to 'mysys')
-rw-r--r--mysys/Makefile.am2
-rw-r--r--mysys/array.c17
-rw-r--r--mysys/base64.c5
-rw-r--r--mysys/hash.c5
-rw-r--r--mysys/mf_keycache.c5
-rw-r--r--mysys/my_create.c21
-rw-r--r--mysys/my_delete.c1
-rw-r--r--mysys/my_getsystime.c39
-rw-r--r--mysys/my_handler.c75
-rw-r--r--mysys/my_handler_errors.h67
-rw-r--r--mysys/my_pread.c2
-rw-r--r--mysys/my_thr_init.c1
-rw-r--r--mysys/thr_lock.c3
13 files changed, 134 insertions, 109 deletions
diff --git a/mysys/Makefile.am b/mysys/Makefile.am
index 27cae5c6363..7bb98770d06 100644
--- a/mysys/Makefile.am
+++ b/mysys/Makefile.am
@@ -20,7 +20,7 @@ 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_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 \
diff --git a/mysys/array.c b/mysys/array.c
index 8ecc6a6cfd0..039d9b4a2c2 100644
--- a/mysys/array.c
+++ b/mysys/array.c
@@ -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);
@@ -236,7 +237,7 @@ my_bool allocate_dynamic(DYNAMIC_ARRAY *array, uint max_elements)
if (max_elements >= array->max_element)
{
uint size;
- char *new_ptr;
+ uchar *new_ptr;
size= (max_elements + array->alloc_increment)/array->alloc_increment;
size*= array->alloc_increment;
if (array->buffer == (uchar *)(array + 1))
@@ -245,16 +246,16 @@ my_bool allocate_dynamic(DYNAMIC_ARRAY *array, uint max_elements)
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))))
+ if (!(new_ptr= (uchar *) my_malloc(size *
+ array->size_of_element,
+ MYF(MY_WME))))
DBUG_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))))
+ else if (!(new_ptr= (uchar*) my_realloc(array->buffer,size*
+ array->size_of_element,
+ MYF(MY_WME | MY_ALLOW_ZERO_PTR))))
DBUG_RETURN(TRUE);
array->buffer= new_ptr;
array->max_element= size;
diff --git a/mysys/base64.c b/mysys/base64.c
index dbe8927290d..6157dcaa5af 100644
--- a/mysys/base64.c
+++ b/mysys/base64.c
@@ -256,6 +256,7 @@ main(void)
char * str;
char * dst;
+ require(src);
for (j= 0; j<src_len; j++)
{
char c= rand();
@@ -265,6 +266,7 @@ main(void)
/* Encode */
needed_length= base64_needed_encoded_length(src_len);
str= (char *) malloc(needed_length);
+ require(str);
for (k= 0; k < needed_length; k++)
str[k]= 0xff; /* Fill memory to check correct NUL termination */
require(base64_encode(src, src_len, str) == 0);
@@ -272,7 +274,8 @@ main(void)
/* Decode */
dst= (char *) malloc(base64_needed_decoded_length(strlen(str)));
- dst_len= base64_decode(str, strlen(str), dst);
+ require(dst);
+ dst_len= base64_decode(str, strlen(str), dst, NULL);
require(dst_len == src_len);
if (memcmp(src, dst, src_len) != 0)
diff --git a/mysys/hash.c b/mysys/hash.c
index 4532b06b533..9166ae6f788 100644
--- a/mysys/hash.c
+++ b/mysys/hash.c
@@ -46,7 +46,7 @@ static uint calc_hash(const HASH *hash, const uchar *key, size_t length)
}
my_bool
-_hash_init(HASH *hash,CHARSET_INFO *charset,
+_hash_init(HASH *hash,uint growth_size, CHARSET_INFO *charset,
ulong size, size_t key_offset, size_t key_length,
hash_get_key get_key,
void (*free_element)(void*),uint flags CALLER_INFO_PROTO)
@@ -55,7 +55,8 @@ _hash_init(HASH *hash,CHARSET_INFO *charset,
DBUG_PRINT("enter",("hash: 0x%lx size: %u", (long) hash, (uint) size));
hash->records=0;
- if (my_init_dynamic_array_ci(&hash->array,sizeof(HASH_LINK),size,0))
+ if (my_init_dynamic_array_ci(&hash->array, sizeof(HASH_LINK), size,
+ growth_size))
{
hash->free=0; /* Allow call to hash_free */
DBUG_RETURN(1);
diff --git a/mysys/mf_keycache.c b/mysys/mf_keycache.c
index 2fcf397766d..81066a51f7b 100644
--- a/mysys/mf_keycache.c
+++ b/mysys/mf_keycache.c
@@ -102,6 +102,7 @@
*/
#include "mysys_priv.h"
+#include "mysys_err.h"
#include <keycache.h>
#include "my_static.h"
#include <m_string.h>
@@ -431,7 +432,7 @@ int init_key_cache(KEY_CACHE *keycache, uint key_cache_block_size,
/* Allocate memory for cache page buffers */
if ((keycache->block_mem=
my_large_malloc((size_t) blocks * keycache->key_cache_block_size,
- MYF(MY_WME))))
+ MYF(0))))
{
/*
Allocate memory for blocks, hash_links and hash entries;
@@ -446,6 +447,7 @@ int init_key_cache(KEY_CACHE *keycache, uint key_cache_block_size,
if (blocks < 8)
{
my_errno= ENOMEM;
+ my_error(EE_OUTOFMEMORY, MYF(0), blocks * keycache->key_cache_block_size);
goto err;
}
blocks= blocks / 4*3;
@@ -2535,7 +2537,6 @@ 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
diff --git a/mysys/my_create.c b/mysys/my_create.c
index 454ccf6ab7d..5c9a1e027d2 100644
--- a/mysys/my_create.c
+++ b/mysys/my_create.c
@@ -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
@@ -34,7 +35,7 @@
File my_create(const char *FileName, int CreateFlags, int access_flags,
myf MyFlags)
{
- int fd;
+ int fd, rc;
DBUG_ENTER("my_create");
DBUG_PRINT("my",("Name: '%s' CreateFlags: %d AccessFlags: %d MyFlags: %d",
FileName, CreateFlags, access_flags, MyFlags));
@@ -59,6 +60,20 @@ File my_create(const char *FileName, int CreateFlags, int access_flags,
fd= -1;
}
- DBUG_RETURN(my_register_filename(fd, FileName, FILE_BY_CREATE,
- EE_CANTCREATEFILE, MyFlags));
+ rc= my_register_filename(fd, FileName, FILE_BY_CREATE,
+ EE_CANTCREATEFILE, MyFlags);
+ /*
+ my_register_filename() may fail on some platforms even if the call to
+ *open() above succeeds. In this case, don't leave the stale file because
+ callers assume the file to not exist if my_create() fails, so they don't
+ do any cleanups.
+ */
+ if (unlikely(fd >= 0 && rc < 0))
+ {
+ int tmp= my_errno;
+ my_delete(FileName, MyFlags);
+ my_errno= tmp;
+ }
+
+ DBUG_RETURN(rc);
} /* my_create */
diff --git a/mysys/my_delete.c b/mysys/my_delete.c
index 4d1115410cb..22425ed95fd 100644
--- a/mysys/my_delete.c
+++ b/mysys/my_delete.c
@@ -15,6 +15,7 @@
#include "mysys_priv.h"
#include "mysys_err.h"
+#include <my_sys.h>
int my_delete(const char *name, myf MyFlags)
{
diff --git a/mysys/my_getsystime.c b/mysys/my_getsystime.c
index 57167711074..64480c4aa7a 100644
--- a/mysys/my_getsystime.c
+++ b/mysys/my_getsystime.c
@@ -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"
@@ -36,7 +41,7 @@ ulonglong my_getsystime()
{
QueryPerformanceCounter(&t_cnt);
return ((t_cnt.QuadPart / query_performance_frequency * 10000000) +
- (t_cnt.QuadPart % query_performance_frequency * 10000000 /
+ ((t_cnt.QuadPart % query_performance_frequency) * 10000000 /
query_performance_frequency) + query_performance_offset);
}
return 0;
@@ -103,21 +108,14 @@ 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= ((newtime / query_performance_frequency * 10000000) +
- (newtime % query_performance_frequency * 10000000 /
- query_performance_frequency));
- }
- else
- newtime= (GetTickCount() * 1000); /* GetTickCount only returns millisec. */
- 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
@@ -156,19 +154,11 @@ 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= ((newtime / query_performance_frequency * 10000000) +
- (newtime % query_performance_frequency * 10000000 /
- query_performance_frequency));
- }
- else
- newtime= (GetTickCount() * 1000); /* GetTickCount only returns millisec. */
- (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
@@ -189,6 +179,7 @@ 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
diff --git a/mysys/my_handler.c b/mysys/my_handler.c
index 3bac59f409c..7a3b8269190 100644
--- a/mysys/my_handler.c
+++ b/mysys/my_handler.c
@@ -20,6 +20,7 @@
#include <my_base.h>
#include <my_handler.h>
#include <my_sys.h>
+#include "my_handler_errors.h"
int ha_compare_text(CHARSET_INFO *charset_info, const uchar *a, uint a_length,
const uchar *b, uint b_length, my_bool part_key,
@@ -568,71 +569,6 @@ HA_KEYSEG *ha_find_null(HA_KEYSEG *keyseg, const uchar *a)
/*
- 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",
- "Internal (unspecified) error in handler",
- "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",
- "No savepoint with that name",
- "Non unique key block size",
- "The table does not exist in engine",
- "The table already existed in storage engine",
- "Could not connect to storage engine",
- "Unexpected null pointer found when using spatial index",
- "The table changed in storage engine",
- "There's no partition in table for the given value",
- "Row-based binlogging of row failed",
- "Index needed in foreign key constraint",
- "Upholding foreign key constraints would lead to a duplicate key error in "
- "some other table",
- "Table needs to be upgraded before it can be used",
- "Table is read only",
- "Failed to get next auto increment value",
- "Failed to set row auto increment value",
- "Unknown (generic) error from engine",
- "Record is the same",
- "It is not possible to log this statement",
- "The table is of a new format not supported by this version",
- "Got a fatal error during initialzaction of handler",
- "File to short; Expected more data in file",
- "Read page with wrong checksum"
-};
-
-
-/*
Register handler error messages for usage with my_error()
NOTES
@@ -640,9 +576,16 @@ static const char *handler_error_messages[]=
will ignore calls to register already registered error numbers.
*/
-
void my_handler_error_register(void)
{
+ /*
+ If you got compilation error here about compile_time_assert array, check
+ that every HA_ERR_xxx constant has a corresponding error message in
+ handler_error_messages[] list (check mysys/ma_handler_errors.h and
+ include/my_base.h).
+ */
+ compile_time_assert(HA_ERR_FIRST + array_elements(handler_error_messages) ==
+ HA_ERR_LAST + 1);
my_error_register(handler_error_messages, HA_ERR_FIRST,
HA_ERR_FIRST+ array_elements(handler_error_messages)-1);
}
diff --git a/mysys/my_handler_errors.h b/mysys/my_handler_errors.h
new file mode 100644
index 00000000000..e360af8c57e
--- /dev/null
+++ b/mysys/my_handler_errors.h
@@ -0,0 +1,67 @@
+
+/*
+ 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",
+ "Internal (unspecified) error in handler",
+ "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",
+ "No savepoint with that name",
+ "Non unique key block size",
+ "The table does not exist in engine",
+ "The table already existed in storage engine",
+ "Could not connect to storage engine",
+ "Unexpected null pointer found when using spatial index",
+ "The table changed in storage engine",
+ "There's no partition in table for the given value",
+ "Row-based binlogging of row failed",
+ "Index needed in foreign key constraint",
+ "Upholding foreign key constraints would lead to a duplicate key error in "
+ "some other table",
+ "Table needs to be upgraded before it can be used",
+ "Table is read only",
+ "Failed to get next auto increment value",
+ "Failed to set row auto increment value",
+ "Unknown (generic) error from engine",
+ "Record is the same",
+ "It is not possible to log this statement",
+ "The event was corrupt, leading to illegal data being read",
+ "The table is of a new format not supported by this version",
+ "The event could not be processed no other hanlder error happened",
+ "Got a fatal error during initialzaction of handler",
+ "File to short; Expected more data in file",
+ "Read page with wrong checksum"
+};
+
diff --git a/mysys/my_pread.c b/mysys/my_pread.c
index 093a5a7a40c..146e07773e6 100644
--- a/mysys/my_pread.c
+++ b/mysys/my_pread.c
@@ -75,7 +75,7 @@ size_t my_pread(File Filedes, uchar *Buffer, size_t Count, my_off_t offset,
if ((error= ((readbytes= pread(Filedes, Buffer, Count, offset)) != Count)))
{
#endif
- my_errno= errno;
+ my_errno= errno ? errno : -1;
if (errno == 0 || (readbytes != (size_t) -1 &&
(MyFlags & (MY_NABP | MY_FNABP))))
my_errno= HA_ERR_FILE_TOO_SHORT;
diff --git a/mysys/my_thr_init.c b/mysys/my_thr_init.c
index aadb86d39ed..f5fee06916e 100644
--- a/mysys/my_thr_init.c
+++ b/mysys/my_thr_init.c
@@ -332,6 +332,7 @@ void my_thread_end(void)
/* tmp->dbug is allocated inside DBUG library */
if (tmp->dbug)
{
+ DBUG_POP();
free(tmp->dbug);
tmp->dbug=0;
}
diff --git a/mysys/thr_lock.c b/mysys/thr_lock.c
index 6decd6a6a27..e2db389dca6 100644
--- a/mysys/thr_lock.c
+++ b/mysys/thr_lock.c
@@ -409,6 +409,8 @@ wait_for_lock(struct st_lock_list *wait, THR_LOCK_DATA *data,
wait->last= &data->next;
}
+ statistic_increment(locks_waited, &THR_LOCK_lock);
+
/* Set up control struct to allow others to abort locks */
thread_var->current_mutex= &data->lock->mutex;
thread_var->current_cond= cond;
@@ -473,7 +475,6 @@ wait_for_lock(struct st_lock_list *wait, THR_LOCK_DATA *data,
else
{
result= THR_LOCK_SUCCESS;
- statistic_increment(locks_waited, &THR_LOCK_lock);
if (data->lock->get_status)
(*data->lock->get_status)(data->status_param, 0);
check_locks(data->lock,"got wait_for_lock",0);