summaryrefslogtreecommitdiff
path: root/mysys
diff options
context:
space:
mode:
Diffstat (limited to 'mysys')
-rw-r--r--[-rwxr-xr-x]mysys/CMakeLists.txt22
-rw-r--r--mysys/Makefile.am29
-rw-r--r--mysys/array.c25
-rw-r--r--mysys/base64.c68
-rw-r--r--mysys/charset-def.c1
-rw-r--r--mysys/default.c16
-rw-r--r--mysys/default_modify.c58
-rw-r--r--mysys/errors.c6
-rw-r--r--mysys/hash.c2
-rwxr-xr-xmysys/make-ccc2
-rw-r--r--mysys/mf_dirname.c5
-rw-r--r--mysys/mf_format.c3
-rw-r--r--mysys/mf_iocache2.c48
-rw-r--r--mysys/mf_keycache.c43
-rw-r--r--mysys/mf_pack.c27
-rw-r--r--mysys/mf_path.c2
-rw-r--r--mysys/mf_tempdir.c30
-rw-r--r--mysys/mf_tempfile.c15
-rw-r--r--mysys/my_access.c106
-rw-r--r--mysys/my_alloc.c1
-rw-r--r--mysys/my_append.c1
-rw-r--r--mysys/my_atomic.c46
-rw-r--r--mysys/my_bit.c30
-rw-r--r--mysys/my_bitmap.c1038
-rw-r--r--mysys/my_clock.c5
-rw-r--r--mysys/my_compress.c129
-rw-r--r--mysys/my_copy.c3
-rw-r--r--mysys/my_create.c12
-rw-r--r--mysys/my_dup.c3
-rw-r--r--mysys/my_error.c16
-rw-r--r--mysys/my_file.c30
-rw-r--r--mysys/my_gethostbyname.c2
-rw-r--r--mysys/my_getncpus.c39
-rw-r--r--mysys/my_getopt.c6
-rw-r--r--mysys/my_getwd.c49
-rw-r--r--mysys/my_init.c17
-rw-r--r--mysys/my_lib.c121
-rw-r--r--mysys/my_lock.c10
-rw-r--r--mysys/my_lread.c54
-rw-r--r--mysys/my_lwrite.c47
-rw-r--r--mysys/my_malloc.c2
-rw-r--r--mysys/my_memmem.c18
-rw-r--r--mysys/my_mkdir.c2
-rw-r--r--mysys/my_mmap.c5
-rw-r--r--mysys/my_net.c4
-rw-r--r--mysys/my_once.c2
-rw-r--r--mysys/my_open.c38
-rw-r--r--mysys/my_os2cond.c162
-rw-r--r--mysys/my_os2dirsrch.c184
-rw-r--r--mysys/my_os2dirsrch.h88
-rw-r--r--mysys/my_os2dlfcn.c74
-rw-r--r--mysys/my_os2dlfcn.h039
-rw-r--r--mysys/my_os2file64.c394
-rw-r--r--mysys/my_os2mutex.c83
-rw-r--r--mysys/my_os2thread.c128
-rw-r--r--mysys/my_os2tls.c151
-rw-r--r--mysys/my_pread.c70
-rw-r--r--mysys/my_pthread.c9
-rw-r--r--mysys/my_redel.c5
-rw-r--r--mysys/my_rename.c1
-rw-r--r--mysys/my_seek.c2
-rw-r--r--mysys/my_sleep.c2
-rw-r--r--mysys/my_static.c9
-rw-r--r--mysys/my_symlink2.c2
-rw-r--r--mysys/my_thr_init.c8
-rw-r--r--mysys/my_vle.c112
-rw-r--r--mysys/mysys_priv.h2
-rw-r--r--mysys/ptr_cmp.c2
-rw-r--r--mysys/queues.c465
-rw-r--r--mysys/raid.cc798
-rw-r--r--mysys/raid2.c31
-rw-r--r--mysys/safemalloc.c2
-rw-r--r--mysys/string.c6
-rw-r--r--mysys/test_dir.c1
-rw-r--r--mysys/testhash.c2
-rw-r--r--mysys/thr_alarm.c161
-rw-r--r--mysys/thr_lock.c230
-rw-r--r--mysys/thr_mutex.c77
-rw-r--r--mysys/trie.c236
79 files changed, 2753 insertions, 3021 deletions
diff --git a/mysys/CMakeLists.txt b/mysys/CMakeLists.txt
index 77933d57d21..ddbb5f5c328 100755..100644
--- a/mysys/CMakeLists.txt
+++ b/mysys/CMakeLists.txt
@@ -1,18 +1,3 @@
-# Copyright (C) 2006 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-
SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -DSAFEMALLOC -DSAFE_MUTEX")
SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -DSAFEMALLOC -DSAFE_MUTEX")
@@ -24,7 +9,7 @@ SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -DSAFEMALLOC -DSAFE_MUTEX")
SET(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -DUSE_TLS")
SET(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -DUSE_TLS")
-INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/zlib ${CMAKE_SOURCE_DIR}/include ${CMAKE_SOURCE_DIR}/mysys )
+INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/zlib ${CMAKE_SOURCE_DIR}/include)
ADD_LIBRARY(mysys array.c charset-def.c charset.c checksum.c default.c default_modify.c
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
@@ -35,11 +20,10 @@ ADD_LIBRARY(mysys array.c charset-def.c charset.c checksum.c default.c default_m
my_clock.c my_compress.c my_conio.c my_copy.c my_crc32.c my_create.c my_delete.c
my_div.c my_error.c my_file.c my_fopen.c my_fstream.c my_gethostbyname.c
my_gethwaddr.c my_getopt.c my_getsystime.c my_getwd.c my_handler.c my_init.c
- my_lib.c my_lock.c my_lockmem.c my_lread.c my_lwrite.c my_malloc.c my_messnc.c
+ my_lib.c my_lock.c my_lockmem.c my_malloc.c my_messnc.c
my_mkdir.c my_mmap.c my_net.c my_once.c my_open.c my_pread.c my_pthread.c
my_quick.c my_read.c my_realloc.c my_redel.c my_rename.c my_seek.c my_sleep.c
my_static.c my_symlink.c my_symlink2.c my_sync.c my_thr_init.c my_wincond.c
my_windac.c my_winsem.c my_winthread.c my_write.c ptr_cmp.c queues.c
rijndael.c safemalloc.c sha1.c string.c thr_alarm.c thr_lock.c thr_mutex.c
- thr_rwlock.c tree.c typelib.c base64.c my_memmem.c
- my_getpagesize.c)
+ thr_rwlock.c tree.c typelib.c my_vle.c base64.c my_memmem.c my_getpagesize.c)
diff --git a/mysys/Makefile.am b/mysys/Makefile.am
index 8f810598a47..fd6a0f76332 100644
--- a/mysys/Makefile.am
+++ b/mysys/Makefile.am
@@ -19,12 +19,8 @@ MYSQLBASEdir= $(prefix)
INCLUDES = @ZLIB_INCLUDES@ -I$(top_builddir)/include \
-I$(top_srcdir)/include -I$(srcdir)
pkglib_LIBRARIES = libmysys.a
-LDADD = libmysys.a ../dbug/libdbug.a \
- ../strings/libmystrings.a
-noinst_HEADERS = mysys_priv.h my_static.h \
- my_os2cond.c my_os2dirsrch.c my_os2dirsrch.h \
- my_os2dlfcn.c my_os2file64.c my_os2mutex.c \
- my_os2thread.c my_os2tls.c
+LDADD = libmysys.a $(top_builddir)/strings/libmystrings.a $(top_builddir)/dbug/libdbug.a
+noinst_HEADERS = mysys_priv.h my_static.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 \
@@ -34,6 +30,7 @@ libmysys_a_SOURCES = my_init.c my_getwd.c mf_getdate.c my_mmap.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 \
my_fopen.c my_fstream.c my_getsystime.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 \
@@ -41,15 +38,15 @@ libmysys_a_SOURCES = my_init.c my_getwd.c mf_getdate.c my_mmap.c \
mf_pack.c mf_unixpath.c mf_strip.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 \
- tree.c list.c hash.c array.c string.c typelib.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_lread.c my_lwrite.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 \
- my_compress.c checksum.c raid.cc \
+ my_compress.c checksum.c \
my_net.c my_semaphore.c my_port.c my_sleep.c \
charset.c charset-def.c my_bitmap.c my_bit.c md5.c \
my_gethostbyname.c rijndael.c my_aes.c sha1.c \
@@ -57,14 +54,14 @@ libmysys_a_SOURCES = my_init.c my_getwd.c mf_getdate.c my_mmap.c \
my_memmem.c \
my_windac.c my_access.c base64.c my_libwrap.c
EXTRA_DIST = thr_alarm.c thr_lock.c my_pthread.c my_thr_init.c \
- thr_mutex.c thr_rwlock.c mf_soundex.c my_conio.c \
- my_wincond.c my_winsem.c my_winthread.c CMakeLists.txt
+ thr_mutex.c thr_rwlock.c \
+ CMakeLists.txt mf_soundex.c \
+ my_conio.c my_wincond.c my_winsem.c my_winthread.c
libmysys_a_LIBADD = @THREAD_LOBJECTS@
# test_dir_DEPENDENCIES= $(LIBRARIES)
# testhash_DEPENDENCIES= $(LIBRARIES)
# test_charset_DEPENDENCIES= $(LIBRARIES)
# charset2html_DEPENDENCIES= $(LIBRARIES)
-EXTRA_PROGRAMS =
DEFS = -DDEFAULT_BASEDIR=\"$(prefix)\" \
-DDATADIR="\"$(MYSQLDATAdir)\"" \
-DDEFAULT_CHARSET_HOME="\"$(MYSQLBASEdir)\"" \
@@ -84,6 +81,12 @@ FLAGS=$(DEFS) $(INCLUDES) $(CPPFLAGS) $(CFLAGS) @NOINST_LDFLAGS@
# which automaticly removes the object files you use to compile a final program
#
+test_bitmap$(EXEEXT): my_bitmap.c $(LIBRARIES)
+ $(LINK) $(FLAGS) -DMAIN ./my_bitmap.c $(LDADD) $(LIBS)
+
+test_priority_queue$(EXEEXT): queues.c $(LIBRARIES)
+ $(LINK) $(FLAGS) -DMAIN ./queues.c $(LDADD) $(LIBS)
+
test_thr_alarm$(EXEEXT): thr_alarm.c $(LIBRARIES)
$(CP) $(srcdir)/thr_alarm.c ./test_thr_alarm.c
$(LINK) $(FLAGS) -DMAIN ./test_thr_alarm.c $(LDADD) $(LIBS)
diff --git a/mysys/array.c b/mysys/array.c
index e3ebe8ddb42..8f4a6087c00 100644
--- a/mysys/array.c
+++ b/mysys/array.c
@@ -277,3 +277,28 @@ void freeze_size(DYNAMIC_ARRAY *array)
array->max_element=elements;
}
}
+
+
+/*
+ Get the index of a dynamic element
+
+ SYNOPSIS
+ get_index_dynamic()
+ array Array
+ element Whose element index
+
+*/
+
+int get_index_dynamic(DYNAMIC_ARRAY *array, gptr element)
+{
+ uint ret;
+ if (array->buffer > element)
+ return -1;
+
+ ret= (element - array->buffer) / array->size_of_element;
+ if (ret > array->elements)
+ return -1;
+
+ return ret;
+
+}
diff --git a/mysys/base64.c b/mysys/base64.c
index 6a6b7eae359..9354256f667 100644
--- a/mysys/base64.c
+++ b/mysys/base64.c
@@ -13,8 +13,10 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-#include <base64.h>
+#include <my_global.h>
#include <m_string.h> /* strchr() */
+#include <m_ctype.h> /* my_isspace() */
+#include <base64.h>
#ifndef MAIN
@@ -114,7 +116,6 @@ pos(unsigned char c)
} \
if (i == size) \
{ \
- i= size + 1; \
break; \
} \
}
@@ -123,44 +124,69 @@ pos(unsigned char c)
/*
Decode a base64 string
- Note: We require that dst is pre-allocated to correct size.
- See base64_needed_decoded_length().
+ SYNOPSIS
+ base64_decode()
+ src Pointer to base64-encoded string
+ len Length of string at 'src'
+ dst Pointer to location where decoded data will be stored
+ end_ptr Pointer to variable that will refer to the character
+ after the end of the encoded data that were decoded. Can
+ be NULL.
+
+ DESCRIPTION
+
+ The base64-encoded data in the range ['src','*end_ptr') will be
+ decoded and stored starting at 'dst'. The decoding will stop
+ after 'len' characters have been read from 'src', or when padding
+ occurs in the base64-encoded data. In either case: if 'end_ptr' is
+ non-null, '*end_ptr' will be set to point to the character after
+ the last read character, even in the presence of error.
+
+ NOTE
+ We require that 'dst' is pre-allocated to correct size.
- RETURN Number of bytes produced in dst or -1 in case of failure
+ SEE ALSO
+ base64_needed_decoded_length().
+
+ RETURN VALUE
+ Number of bytes written at 'dst' or -1 in case of failure
*/
int
-base64_decode(const char *src, size_t size, void *dst)
+base64_decode(const char *src_base, size_t len,
+ void *dst, const char **end_ptr)
{
char b[3];
size_t i= 0;
char *dst_base= (char *)dst;
+ char const *src= src_base;
char *d= dst_base;
size_t j;
- while (i < size)
+ while (i < len)
{
unsigned c= 0;
size_t mark= 0;
- SKIP_SPACE(src, i, size);
+ SKIP_SPACE(src, i, len);
c += pos(*src++);
c <<= 6;
i++;
- SKIP_SPACE(src, i, size);
+ SKIP_SPACE(src, i, len);
c += pos(*src++);
c <<= 6;
i++;
- SKIP_SPACE(src, i, size);
+ SKIP_SPACE(src, i, len);
- if (* src != '=')
+ if (*src != '=')
c += pos(*src++);
else
{
- i= size;
+ src += 2; /* There should be two bytes padding */
+ i= len;
mark= 2;
c <<= 6;
goto end;
@@ -168,13 +194,14 @@ base64_decode(const char *src, size_t size, void *dst)
c <<= 6;
i++;
- SKIP_SPACE(src, i, size);
+ SKIP_SPACE(src, i, len);
if (*src != '=')
c += pos(*src++);
else
{
- i= size;
+ src += 1; /* There should be one byte padding */
+ i= len;
mark= 1;
goto end;
}
@@ -189,11 +216,14 @@ base64_decode(const char *src, size_t size, void *dst)
*d++= b[j];
}
- if (i != size)
- {
- return -1;
- }
- return d - dst_base;
+ if (end_ptr != NULL)
+ *end_ptr= src;
+
+ /*
+ The variable 'i' is set to 'len' when padding has been read, so it
+ does not actually reflect the number of bytes read from 'src'.
+ */
+ return i != len ? -1 : d - dst_base;
}
diff --git a/mysys/charset-def.c b/mysys/charset-def.c
index 394fe6de1f3..71833550ff4 100644
--- a/mysys/charset-def.c
+++ b/mysys/charset-def.c
@@ -77,6 +77,7 @@ my_bool init_compiled_charsets(myf flags __attribute__((unused)))
CHARSET_INFO *cs;
add_compiled_collation(&my_charset_bin);
+ add_compiled_collation(&my_charset_filename);
add_compiled_collation(&my_charset_latin1);
add_compiled_collation(&my_charset_latin1_bin);
diff --git a/mysys/default.c b/mysys/default.c
index 97c52d01031..b68ff8e1779 100644
--- a/mysys/default.c
+++ b/mysys/default.c
@@ -243,7 +243,8 @@ err:
handle_option_ctx structure.
group_name The name of the group the option belongs to.
option The very option to be processed. It is already
- prepared to be used in argv (has -- prefix)
+ prepared to be used in argv (has -- prefix). If it
+ is NULL, we are handling a new group (section).
DESCRIPTION
This handler checks whether a group is one of the listed and adds an option
@@ -262,6 +263,9 @@ static int handle_default_option(void *in_ctx, const char *group_name,
char *tmp;
struct handle_option_ctx *ctx= (struct handle_option_ctx *) in_ctx;
+ if (!option)
+ return 0;
+
if (find_type((char *)group_name, ctx->group, 3))
{
if (!(tmp= alloc_root(ctx->alloc, (uint) strlen(option) + 1)))
@@ -600,7 +604,7 @@ static int search_default_file_with_ext(Process_option_func opt_handler,
strmov(name,config_file);
}
fn_format(name,name,"","",4);
-#if !defined(__WIN__) && !defined(OS2) && !defined(__NETWARE__)
+#if !defined(__WIN__) && !defined(__NETWARE__)
{
MY_STAT stat_info;
if (!my_stat(name,&stat_info,MYF(0)))
@@ -718,6 +722,10 @@ static int search_default_file_with_ext(Process_option_func opt_handler,
end[0]=0;
strnmov(curr_gr, ptr, min((uint) (end-ptr)+1, 4096));
+
+ /* signal that a new group is found */
+ opt_handler(handler_ctx, curr_gr, NULL);
+
continue;
}
if (!found_group)
@@ -1002,10 +1010,6 @@ static void init_default_directories()
#elif defined(__NETWARE__)
*ptr++= "sys:/etc/";
#else
-#if defined(__EMX__) || defined(OS2)
- if ((env= getenv("ETC")))
- *ptr++= env;
-#endif
*ptr++= "/etc/";
#endif
if ((env= getenv(STRINGIFY_ARG(DEFAULT_HOME_ENV))))
diff --git a/mysys/default_modify.c b/mysys/default_modify.c
index be40d3b3660..f58d3e0da86 100644
--- a/mysys/default_modify.c
+++ b/mysys/default_modify.c
@@ -39,11 +39,13 @@ static char *add_option(char *dst, const char *option_value,
SYNOPSYS
modify_defaults_file()
file_location The location of configuration file to edit
- option option to look for
- option value The value of the option we would like to set
- section_name the name of the section
- remove_option This is true if we want to remove the option.
- False otherwise.
+ option The name of the option to look for (can be NULL)
+ option value The value of the option we would like to set (can be NULL)
+ section_name The name of the section (must be NOT NULL)
+ remove_option This defines what we want to remove:
+ - MY_REMOVE_NONE -- nothing to remove;
+ - MY_REMOVE_OPTION -- remove the specified option;
+ - MY_REMOVE_SECTION -- remove the specified section;
IMPLEMENTATION
We open the option file first, then read the file line-by-line,
looking for the section we need. At the same time we put these lines
@@ -66,7 +68,9 @@ int modify_defaults_file(const char *file_location, const char *option,
FILE *cnf_file;
MY_STAT file_stat;
char linebuff[BUFF_SIZE], *src_ptr, *dst_ptr, *file_buffer;
- uint opt_len, optval_len, sect_len, nr_newlines= 0, buffer_size;
+ uint opt_len= 0;
+ uint optval_len= 0;
+ uint sect_len, nr_newlines= 0, buffer_size;
my_bool in_section= FALSE, opt_applied= 0;
uint reserve_extended;
uint new_opt_len;
@@ -80,8 +84,11 @@ int modify_defaults_file(const char *file_location, const char *option,
if (my_fstat(fileno(cnf_file), &file_stat, MYF(0)))
goto malloc_err;
- opt_len= (uint) strlen(option);
- optval_len= (uint) strlen(option_value);
+ if (option && option_value)
+ {
+ opt_len= (uint) strlen(option);
+ optval_len= (uint) strlen(option_value);
+ }
new_opt_len= opt_len + 1 + optval_len + NEWLINE_LEN;
@@ -118,8 +125,8 @@ int modify_defaults_file(const char *file_location, const char *option,
continue;
}
- /* correct the option */
- if (in_section && !strncmp(src_ptr, option, opt_len) &&
+ /* correct the option (if requested) */
+ if (option && in_section && !strncmp(src_ptr, option, opt_len) &&
(*(src_ptr + opt_len) == '=' ||
my_isspace(&my_charset_latin1, *(src_ptr + opt_len)) ||
*(src_ptr + opt_len) == '\0'))
@@ -142,7 +149,12 @@ int modify_defaults_file(const char *file_location, const char *option,
}
else
{
- /* If going to new group and we have option to apply, do it now */
+ /*
+ If we are going to the new group and have an option to apply, do
+ it now. If we are removing a single option or the whole section
+ this will only trigger opt_applied flag.
+ */
+
if (in_section && !opt_applied && *src_ptr == '[')
{
dst_ptr= add_option(dst_ptr, option_value, option, remove_option);
@@ -152,7 +164,10 @@ int modify_defaults_file(const char *file_location, const char *option,
for (; nr_newlines; nr_newlines--)
dst_ptr= strmov(dst_ptr, NEWLINE);
- dst_ptr= strmov(dst_ptr, linebuff);
+
+ /* Skip the section if MY_REMOVE_SECTION was given */
+ if (!in_section || remove_option != MY_REMOVE_SECTION)
+ dst_ptr= strmov(dst_ptr, linebuff);
}
/* Look for a section */
if (*src_ptr == '[')
@@ -166,18 +181,31 @@ int modify_defaults_file(const char *file_location, const char *option,
{}
if (*src_ptr != ']')
+ {
+ in_section= FALSE;
continue; /* Missing closing parenthesis. Assume this was no group */
+ }
+
+ if (remove_option == MY_REMOVE_SECTION)
+ dst_ptr= dst_ptr - strlen(linebuff);
+
in_section= TRUE;
}
else
in_section= FALSE; /* mark that this section is of no interest to us */
}
}
- /* File ended. */
- if (!opt_applied && !remove_option && in_section)
+
+ /*
+ File ended. Apply an option or set opt_applied flag (in case of
+ MY_REMOVE_SECTION) so that the changes are saved. Do not do anything
+ if we are removing non-existent option.
+ */
+
+ if (!opt_applied && in_section && (remove_option != MY_REMOVE_OPTION))
{
/* New option still remains to apply at the end */
- if (*(dst_ptr - 1) != '\n')
+ if (!remove_option && *(dst_ptr - 1) != '\n')
dst_ptr= strmov(dst_ptr, NEWLINE);
dst_ptr= add_option(dst_ptr, option_value, option, remove_option);
opt_applied= 1;
diff --git a/mysys/errors.c b/mysys/errors.c
index 857de1325d4..889cf6d7fe3 100644
--- a/mysys/errors.c
+++ b/mysys/errors.c
@@ -38,7 +38,7 @@ const char * NEAR globerrs[GLOBERRS]=
"Can't get working dirctory (Errcode: %d)",
"Can't change dir to '%s' (Errcode: %d)",
"Warning: '%s' had %d links",
- "%d files and %d streams is left open\n",
+ "Warning: %d files and %d streams is left open\n",
"Disk is full writing '%s' (Errcode: %d). Waiting for someone to free space... Retry in %d secs",
"Can't create directory '%s' (Errcode: %d)",
"Character set '%s' is not a compiled character set and is not specified in the '%s' file",
@@ -49,6 +49,7 @@ const char * NEAR globerrs[GLOBERRS]=
"Can't sync file '%s' to disk (Errcode: %d)",
"Collation '%s' is not a compiled collation and is not specified in the '%s' file",
"File '%s' not found (Errcode: %d)",
+ "File '%s' (fileno: %d) was not closed"
};
void init_glob_errs(void)
@@ -77,7 +78,7 @@ void init_glob_errs()
EE(EE_GETWD) = "Can't get working dirctory (Errcode: %d)";
EE(EE_SETWD) = "Can't change dir to '%s' (Errcode: %d)";
EE(EE_LINK_WARNING) = "Warning: '%s' had %d links";
- EE(EE_OPEN_WARNING) = "%d files and %d streams is left open\n";
+ EE(EE_OPEN_WARNING) = "Warning: %d files and %d streams is left open\n";
EE(EE_DISK_FULL) = "Disk is full writing '%s'. Waiting for someone to free space...";
EE(EE_CANT_MKDIR) ="Can't create directory '%s' (Errcode: %d)";
EE(EE_UNKNOWN_CHARSET)= "Character set '%s' is not a compiled character set and is not specified in the %s file";
@@ -88,5 +89,6 @@ void init_glob_errs()
EE(EE_SYNC)= "Can't sync file '%s' to disk (Errcode: %d)";
EE(EE_UNKNOWN_COLLATION)= "Collation '%s' is not a compiled collation and is not specified in the %s file";
EE(EE_FILENOTFOUND) = "File '%s' not found (Errcode: %d)";
+ EE(EE_FILE_NOT_CLOSED) = "File '%s' (fileno: %d) was not closed";
}
#endif
diff --git a/mysys/hash.c b/mysys/hash.c
index 0c949b3a0d8..60168e01e20 100644
--- a/mysys/hash.c
+++ b/mysys/hash.c
@@ -108,7 +108,7 @@ static inline void hash_free_elements(HASH *hash)
void hash_free(HASH *hash)
{
DBUG_ENTER("hash_free");
- DBUG_PRINT("enter",("hash: 0x%lxd", (long) hash));
+ DBUG_PRINT("enter",("hash: 0x%lx", (long) hash));
hash_free_elements(hash);
hash->free= 0;
diff --git a/mysys/make-ccc b/mysys/make-ccc
index 9c54185682a..b34bd80e1d1 100755
--- a/mysys/make-ccc
+++ b/mysys/make-ccc
@@ -1,4 +1,4 @@
rm -f .deps/* raid.o mf_iocache.o libmysys.a
-ccc -DDEFAULT_BASEDIR="\"/usr/local/mysql\"" -DDATADIR="\"/usr/local/mysql/var\"" -DHAVE_CONFIG_H -I./../include -I../include -I.. -DDBUG_OFF -fast -O3 -fomit-frame-pointer -c array.c checksum.c default.c errors.c getopt.c getopt1.c getvar.c hash.c list.c mf_brkhant.c mf_cache.c mf_casecnv.c mf_dirname.c mf_fn_ext.c mf_format.c mf_getdate.c mf_keycache.c mf_loadpath.c mf_pack.c mf_pack2.c mf_path.c mf_qsort.c mf_qsort2.c mf_radix.c mf_reccache.c mf_same.c mf_sort.c mf_soundex.c mf_stripp.c mf_unixpath.c mf_wcomp.c mf_wfile.c mulalloc.c my_alarm.c my_alloc.c my_append.c my_chsize.c my_clock.c my_compress.c my_copy.c my_create.c my_delete.c my_div.c my_error.c my_fopen.c my_fstream.c my_getwd.c my_init.c my_lib.c my_lockmem.c my_lread.c my_lwrite.c my_malloc.c my_messnc.c my_mkdir.c my_net.c my_once.c my_open.c my_pread.c my_pthread.c my_quick.c my_read.c my_realloc.c my_redel.c my_rename.c my_seek.c my_static.c my_tempnam.c my_thr_init.c my_write.c ptr_cmp.c queues.c safemalloc.c string.c thr_alarm.c thr_lock.c thr_mutex.c thr_rwlock.c tree.c typelib.c
+ccc -DDEFAULT_BASEDIR="\"/usr/local/mysql\"" -DDATADIR="\"/usr/local/mysql/var\"" -DHAVE_CONFIG_H -I./../include -I../include -I.. -DDBUG_OFF -fast -O3 -fomit-frame-pointer -c array.c checksum.c default.c errors.c getopt.c getopt1.c getvar.c hash.c list.c mf_brkhant.c mf_cache.c mf_casecnv.c mf_dirname.c mf_fn_ext.c mf_format.c mf_getdate.c mf_keycache.c mf_loadpath.c mf_pack.c mf_pack2.c mf_path.c mf_qsort.c mf_qsort2.c mf_radix.c mf_reccache.c mf_same.c mf_sort.c mf_soundex.c mf_stripp.c mf_unixpath.c mf_wcomp.c mf_wfile.c mulalloc.c my_alarm.c my_alloc.c my_append.c my_chsize.c my_clock.c my_compress.c my_copy.c my_create.c my_delete.c my_div.c my_error.c my_fopen.c my_fstream.c my_getwd.c my_init.c my_lib.c my_lockmem.c my_malloc.c my_messnc.c my_mkdir.c my_net.c my_once.c my_open.c my_pread.c my_pthread.c my_quick.c my_read.c my_realloc.c my_redel.c my_rename.c my_seek.c my_static.c my_tempnam.c my_thr_init.c my_write.c ptr_cmp.c queues.c safemalloc.c string.c thr_alarm.c thr_lock.c thr_mutex.c thr_rwlock.c tree.c typelib.c
make raid.o mf_iocache.o my_lock.o
ar -cr libmysys.a array.o raid.o mf_iocache.o my_lock.o
diff --git a/mysys/mf_dirname.c b/mysys/mf_dirname.c
index d1672e55b65..87a4a453734 100644
--- a/mysys/mf_dirname.c
+++ b/mysys/mf_dirname.c
@@ -74,7 +74,7 @@ uint dirname_part(my_string to, const char *name)
to Store result here. Must be at least of size
min(FN_REFLEN, strlen(from) + 1) to make room
for adding FN_LIBCHAR at the end.
- from Original filename
+ from Original filename. May be == to
from_end Pointer at end of filename (normally end \0)
IMPLEMENTATION
@@ -102,6 +102,7 @@ char *convert_dirname(char *to, const char *from, const char *from_end)
#ifdef BACKSLASH_MBTAIL
CHARSET_INFO *fs= fs_character_set();
#endif
+ DBUG_ENTER("convert_dirname");
/* We use -2 here, becasue we need place for the last FN_LIBCHAR */
if (!from_end || (from_end - from) > FN_REFLEN-2)
@@ -150,5 +151,5 @@ char *convert_dirname(char *to, const char *from, const char *from_end)
*to++=FN_LIBCHAR;
*to=0;
}
- return to; /* Pointer to end of dir */
+ DBUG_RETURN(to); /* Pointer to end of dir */
} /* convert_dirname */
diff --git a/mysys/mf_format.c b/mysys/mf_format.c
index 7a861c9f1e6..3e5eeef6420 100644
--- a/mysys/mf_format.c
+++ b/mysys/mf_format.c
@@ -53,7 +53,8 @@ my_string fn_format(my_string to, const char *name, const char *dir,
if (flag & MY_UNPACK_FILENAME)
(void) unpack_dirname(dev,dev); /* Replace ~/.. with dir */
- if ((pos= (char*) strchr(name,FN_EXTCHAR)) != NullS)
+ if (!(flag & MY_APPEND_EXT) &&
+ (pos= (char*) strchr(name,FN_EXTCHAR)) != NullS)
{
if ((flag & MY_REPLACE_EXT) == 0) /* If we should keep old ext */
{
diff --git a/mysys/mf_iocache2.c b/mysys/mf_iocache2.c
index 429954a9162..7b3393da4f5 100644
--- a/mysys/mf_iocache2.c
+++ b/mysys/mf_iocache2.c
@@ -23,6 +23,54 @@
#include <stdarg.h>
#include <m_ctype.h>
+/*
+ Copy contents of an IO_CACHE to a file.
+
+ SYNOPSIS
+ my_b_copy_to_file()
+ cache IO_CACHE to copy from
+ file File to copy to
+
+ DESCRIPTION
+ Copy the contents of the cache to the file. The cache will be
+ re-inited to a read cache and will read from the beginning of the
+ cache.
+
+ If a failure to write fully occurs, the cache is only copied
+ partially.
+
+ TODO
+ Make this function solid by handling partial reads from the cache
+ in a correct manner: it should be atomic.
+
+ RETURN VALUE
+ 0 All OK
+ 1 An error occured
+*/
+int
+my_b_copy_to_file(IO_CACHE *cache, FILE *file)
+{
+ byte buf[IO_SIZE];
+ uint bytes_in_cache;
+ DBUG_ENTER("my_b_copy_to_file");
+
+ /* Reinit the cache to read from the beginning of the cache */
+ if (reinit_io_cache(cache, READ_CACHE, 0L, FALSE, FALSE))
+ DBUG_RETURN(1);
+ bytes_in_cache= my_b_bytes_in_cache(cache);
+ while (bytes_in_cache > 0) {
+ uint const read_bytes= min(bytes_in_cache, sizeof(buf));
+ DBUG_PRINT("debug", ("Remaining %u bytes - Reading %u bytes",
+ bytes_in_cache, read_bytes));
+ if (my_b_read(cache, buf, read_bytes))
+ DBUG_RETURN(1);
+ if (my_fwrite(file, buf, read_bytes, MYF(MY_WME | MY_NABP)) == (uint) -1)
+ DBUG_RETURN(1);
+ bytes_in_cache -= read_bytes;
+ }
+ DBUG_RETURN(0);
+}
+
my_off_t my_b_append_tell(IO_CACHE* info)
{
/*
diff --git a/mysys/mf_keycache.c b/mysys/mf_keycache.c
index 3c4197f847e..ff202e7b313 100644
--- a/mysys/mf_keycache.c
+++ b/mysys/mf_keycache.c
@@ -83,14 +83,6 @@
#define KEYCACHE_DEBUG_LOG "my_key_cache_debug.log"
*/
-#if defined(MSDOS) && !defined(M_IC80386)
-/* we nead much memory */
-#undef my_malloc_lock
-#undef my_free_lock
-#define my_malloc_lock(A,B) halloc((long) (A/IO_SIZE),IO_SIZE)
-#define my_free_lock(A,B) hfree(A)
-#endif /* defined(MSDOS) && !defined(M_IC80386) */
-
#define STRUCT_PTR(TYPE, MEMBER, a) \
(TYPE *) ((char *) (a) - offsetof(TYPE, MEMBER))
@@ -261,15 +253,9 @@ static int keycache_pthread_cond_signal(pthread_cond_t *cond);
#define keycache_pthread_cond_signal pthread_cond_signal
#endif /* defined(KEYCACHE_DEBUG) */
-static uint next_power(uint value)
+static inline uint next_power(uint value)
{
- uint old_value= 1;
- while (value)
- {
- old_value= value;
- value&= value-1;
- }
- return (old_value << 1);
+ return (uint) my_round_up_to_next_power((uint32) value) << 1;
}
@@ -483,8 +469,10 @@ int resize_key_cache(KEY_CACHE *keycache, uint key_cache_block_size,
uint age_threshold)
{
int blocks;
+#ifdef THREAD
struct st_my_thread_var *thread;
KEYCACHE_WQUEUE *wqueue;
+#endif
DBUG_ENTER("resize_key_cache");
if (!keycache->key_cache_inited)
@@ -549,7 +537,7 @@ finish:
}
#endif
keycache_pthread_mutex_unlock(&keycache->cache_lock);
- return blocks;
+ DBUG_RETURN(blocks);
}
@@ -1115,8 +1103,12 @@ static void unreg_request(KEY_CACHE *keycache,
static inline void remove_reader(BLOCK_LINK *block)
{
+#ifdef THREAD
if (! --block->hash_link->requests && block->condvar)
keycache_pthread_cond_signal(block->condvar);
+#else
+ --block->hash_link->requests;
+#endif
}
@@ -1125,7 +1117,8 @@ static inline void remove_reader(BLOCK_LINK *block)
signals on its termination
*/
-static inline void wait_for_readers(KEY_CACHE *keycache, BLOCK_LINK *block)
+static inline void wait_for_readers(KEY_CACHE *keycache __attribute__((unused)),
+ BLOCK_LINK *block)
{
#ifdef THREAD
struct st_my_thread_var *thread= my_thread_var;
@@ -1222,7 +1215,6 @@ static HASH_LINK *get_hash_link(KEY_CACHE *keycache,
int file, my_off_t filepos)
{
reg1 HASH_LINK *hash_link, **start;
- KEYCACHE_PAGE page;
#if defined(KEYCACHE_DEBUG)
int cnt;
#endif
@@ -1277,6 +1269,7 @@ restart:
#ifdef THREAD
/* Wait for a free hash link */
struct st_my_thread_var *thread= my_thread_var;
+ KEYCACHE_PAGE page;
KEYCACHE_DBUG_PRINT("get_hash_link", ("waiting"));
page.file= file;
page.filepos= filepos;
@@ -1601,8 +1594,10 @@ restart:
/* Remove the hash link for this page from the hash table */
unlink_hash(keycache, block->hash_link);
/* All pending requests for this page must be resubmitted */
+#ifdef THREAD
if (block->wqueue[COND_FOR_SAVED].last_thread)
release_queue(&block->wqueue[COND_FOR_SAVED]);
+#endif
}
link_to_file_list(keycache, block, file,
(my_bool)(block->hash_link ? 1 : 0));
@@ -1682,7 +1677,7 @@ restart:
portion is less than read_length, but not less than min_length.
*/
-static void read_block(KEY_CACHE *keycache,
+static void read_block(KEY_CACHE *keycache __attribute__((unused)),
BLOCK_LINK *block, uint read_length,
uint min_length, my_bool primary)
{
@@ -1720,8 +1715,10 @@ static void read_block(KEY_CACHE *keycache,
KEYCACHE_DBUG_PRINT("read_block",
("primary request: new page in cache"));
/* Signal that all pending requests for this page now can be processed */
+#ifdef THREAD
if (block->wqueue[COND_FOR_REQUESTED].last_thread)
release_queue(&block->wqueue[COND_FOR_REQUESTED]);
+#endif
}
else
{
@@ -1986,9 +1983,11 @@ int key_cache_insert(KEY_CACHE *keycache,
block->length= read_length+offset;
KEYCACHE_DBUG_PRINT("key_cache_insert",
("primary request: new page in cache"));
+#ifdef THREAD
/* Signal that all pending requests for this now can be processed. */
if (block->wqueue[COND_FOR_REQUESTED].last_thread)
release_queue(&block->wqueue[COND_FOR_REQUESTED]);
+#endif
}
remove_reader(block);
@@ -2232,9 +2231,11 @@ static void free_block(KEY_CACHE *keycache, BLOCK_LINK *block)
/* Keep track of the number of currently unused blocks. */
keycache->blocks_unused++;
+#ifdef THREAD
/* All pending requests for this page must be resubmitted. */
if (block->wqueue[COND_FOR_SAVED].last_thread)
release_queue(&block->wqueue[COND_FOR_SAVED]);
+#endif
}
@@ -2288,12 +2289,14 @@ static int flush_cached_blocks(KEY_CACHE *keycache,
if (!last_errno)
last_errno= errno ? errno : -1;
}
+ #ifdef THREAD
/*
Let to proceed for possible waiting requests to write to the block page.
It might happen only during an operation to resize the key cache.
*/
if (block->wqueue[COND_FOR_SAVED].last_thread)
release_queue(&block->wqueue[COND_FOR_SAVED]);
+#endif
/* type will never be FLUSH_IGNORE_CHANGED here */
if (! (type == FLUSH_KEEP || type == FLUSH_FORCE_WRITE))
{
diff --git a/mysys/mf_pack.c b/mysys/mf_pack.c
index d14c24f35d7..1b83c6fda10 100644
--- a/mysys/mf_pack.c
+++ b/mysys/mf_pack.c
@@ -106,16 +106,27 @@ void pack_dirname(my_string to, const char *from)
} /* pack_dirname */
- /* remove unwanted chars from dirname */
- /* if "/../" removes prev dir; "/~/" removes all before ~ */
- /* "//" is same as "/", except on Win32 at start of a file */
- /* "/./" is removed */
- /* Unpacks home_dir if "~/.." used */
- /* Unpacks current dir if if "./.." used */
+/*
+ remove unwanted chars from dirname
-uint cleanup_dirname(register my_string to, const char *from)
- /* to may be == from */
+ SYNOPSIS
+ cleanup_dirname()
+ to Store result here
+ from Dirname to fix. May be same as to
+
+ IMPLEMENTATION
+ "/../" removes prev dir
+ "/~/" removes all before ~
+ //" is same as "/", except on Win32 at start of a file
+ "/./" is removed
+ Unpacks home_dir if "~/.." used
+ Unpacks current dir if if "./.." used
+ RETURN
+ # length of new name
+*/
+
+uint cleanup_dirname(register my_string to, const char *from)
{
reg5 uint length;
reg2 my_string pos;
diff --git a/mysys/mf_path.c b/mysys/mf_path.c
index 9af6173b417..00e6b2046b9 100644
--- a/mysys/mf_path.c
+++ b/mysys/mf_path.c
@@ -72,7 +72,7 @@ my_string my_path(my_string to, const char *progname,
/* test if file without filename is found in path */
/* Returns to if found and to has dirpart if found, else NullS */
-#if defined(MSDOS) || defined(__WIN__) || defined(__EMX__) || defined(OS2)
+#if defined(__WIN__)
#define F_OK 0
#define PATH_SEP ';'
#define PROGRAM_EXTENSION ".exe"
diff --git a/mysys/mf_tempdir.c b/mysys/mf_tempdir.c
index c24e2a0101b..8d3fc40e96d 100644
--- a/mysys/mf_tempdir.c
+++ b/mysys/mf_tempdir.c
@@ -16,7 +16,7 @@
#include "mysys_priv.h"
#include <m_string.h>
-#if defined( __WIN__) || defined(OS2) || defined(__NETWARE__)
+#if defined( __WIN__) || defined(__NETWARE__)
#define DELIM ';'
#else
#define DELIM ':'
@@ -27,14 +27,17 @@ my_bool init_tmpdir(MY_TMPDIR *tmpdir, const char *pathlist)
char *end, *copy;
char buff[FN_REFLEN];
DYNAMIC_ARRAY t_arr;
+ DBUG_ENTER("init_tmpdir");
+ DBUG_PRINT("enter", ("pathlist: %s", pathlist ? pathlist : "NULL"));
+
pthread_mutex_init(&tmpdir->mutex, MY_MUTEX_INIT_FAST);
if (my_init_dynamic_array(&t_arr, sizeof(char*), 1, 5))
- return TRUE;
+ goto err;
if (!pathlist || !pathlist[0])
{
/* Get default temporary directory */
pathlist=getenv("TMPDIR"); /* Use this if possible */
-#if defined( __WIN__) || defined(OS2) || defined(__NETWARE__)
+#if defined( __WIN__) || defined(__NETWARE__)
if (!pathlist)
pathlist=getenv("TEMP");
if (!pathlist)
@@ -45,12 +48,13 @@ my_bool init_tmpdir(MY_TMPDIR *tmpdir, const char *pathlist)
}
do
{
+ uint length;
end=strcend(pathlist, DELIM);
- convert_dirname(buff, pathlist, end);
- if (!(copy=my_strdup(buff, MYF(MY_WME))))
- return TRUE;
- if (insert_dynamic(&t_arr, (gptr)&copy))
- return TRUE;
+ strmake(buff, pathlist, (uint) (end-pathlist));
+ length= cleanup_dirname(buff, buff);
+ if (!(copy= my_strndup(buff, length, MYF(MY_WME))) ||
+ insert_dynamic(&t_arr, (gptr) &copy))
+ DBUG_RETURN(TRUE);
pathlist=end+1;
}
while (*end);
@@ -58,12 +62,20 @@ my_bool init_tmpdir(MY_TMPDIR *tmpdir, const char *pathlist)
tmpdir->list=(char **)t_arr.buffer;
tmpdir->max=t_arr.elements-1;
tmpdir->cur=0;
- return FALSE;
+ DBUG_RETURN(FALSE);
+
+err:
+ delete_dynamic(&t_arr); /* Safe to free */
+ pthread_mutex_destroy(&tmpdir->mutex);
+ DBUG_RETURN(TRUE);
}
+
char *my_tmpdir(MY_TMPDIR *tmpdir)
{
char *dir;
+ if (!tmpdir->max)
+ return tmpdir->list[0];
pthread_mutex_lock(&tmpdir->mutex);
dir=tmpdir->list[tmpdir->cur];
tmpdir->cur= (tmpdir->cur == tmpdir->max) ? 0 : tmpdir->cur+1;
diff --git a/mysys/mf_tempfile.c b/mysys/mf_tempfile.c
index 431674c5d61..6c412157937 100644
--- a/mysys/mf_tempfile.c
+++ b/mysys/mf_tempfile.c
@@ -23,7 +23,7 @@
#endif
#ifdef HAVE_TEMPNAM
-#if !defined(MSDOS) && !defined(OS2) && !defined(__NETWARE__)
+#if !defined(__NETWARE__)
extern char **environ;
#endif
#endif
@@ -120,16 +120,7 @@ File create_temp_file(char *to, const char *dir, const char *prefix,
to[1]= 0;
dir=to;
}
-#ifdef OS2
- /* changing environ variable doesn't work with VACPP */
- char buffer[256], *end;
- buffer[sizeof(buffer)-1]= 0;
- end= strxnmov(buffer, sizeof(buffer)-1, (char*) "TMP=", dir, NullS);
- /* remove ending backslash */
- if (end[-1] == '\\')
- end[-1]= 0;
- putenv(buffer);
-#elif !defined(__NETWARE__)
+#if !defined(__NETWARE__)
old_env= (char**) environ;
if (dir)
{ /* Don't use TMPDIR if dir is given */
@@ -151,7 +142,7 @@ File create_temp_file(char *to, const char *dir, const char *prefix,
{
DBUG_PRINT("error",("Got error: %d from tempnam",errno));
}
-#if !defined(OS2) && !defined(__NETWARE__)
+#if !defined(__NETWARE__)
environ=(const char**) old_env;
#endif
}
diff --git a/mysys/my_access.c b/mysys/my_access.c
index 9ee20cc942b..210946d50a8 100644
--- a/mysys/my_access.c
+++ b/mysys/my_access.c
@@ -53,24 +53,111 @@ int my_access(const char *path, int amode)
#endif /* __WIN__ */
-#if defined(MSDOS) || defined(__WIN__) || defined(__EMX__)
/*
List of file names that causes problem on windows
NOTE that one can also not have file names of type CON.TXT
+
+ NOTE: it is important to keep "CLOCK$" on the first place,
+ we skip it in check_if_legal_tablename.
*/
-
static const char *reserved_names[]=
{
- "CON", "PRN", "AUX", "NUL", "COM1", "COM2", "COM3", "COM4", "COM5", "COM6",
- "COM7", "COM8", "COM9", "LPT1", "LPT2", "LPT3", "LPT4", "LPT5", "LPT6",
- "LPT7", "LPT8", "LPT9", "CLOCK$",
+ "CLOCK$",
+ "CON", "PRN", "AUX", "NUL",
+ "COM1", "COM2", "COM3", "COM4", "COM5", "COM6", "COM7", "COM8", "COM9",
+ "LPT1", "LPT2", "LPT3", "LPT4", "LPT5", "LPT6", "LPT7", "LPT8", "LPT9",
NullS
};
#define MAX_RESERVED_NAME_LENGTH 6
+
+/*
+ Looks up a null-terminated string in a list,
+ case insensitively.
+
+ SYNOPSIS
+ str_list_find()
+ list list of items
+ str item to find
+
+ RETURN
+ 0 ok
+ 1 reserved file name
+*/
+static int str_list_find(const char **list, const char *str)
+{
+ const char **name;
+ for (name= list; *name; name++)
+ {
+ if (!my_strcasecmp(&my_charset_latin1, *name, str))
+ return 1;
+ }
+ return 0;
+}
+
+
+/*
+ A map for faster reserved_names lookup,
+ helps to avoid loops in many cases.
+ 1 - can be the first letter
+ 2 - can be the second letter
+ 4 - can be the third letter
+*/
+static char reserved_map[256]=
+{
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ................ */
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ................ */
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* !"#$%&'()*+,-./ */
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0123456789:;<=>? */
+ 0,1,0,1,0,0,0,0,0,0,0,0,7,4,5,2, /* @ABCDEFGHIJKLMNO */
+ 3,0,2,0,4,2,0,0,4,0,0,0,0,0,0,0, /* PQRSTUVWXYZ[\]^_ */
+ 0,1,0,1,0,0,0,0,0,0,0,0,7,4,5,2, /* bcdefghijklmno */
+ 3,0,2,0,4,2,0,0,4,0,0,0,0,0,0,0, /* pqrstuvwxyz{|}~. */
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ................ */
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ................ */
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ................ */
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ................ */
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ................ */
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ................ */
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ................ */
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 /* ................ */
+};
+
+
+/*
+ Check if a table name may cause problems
+
+ SYNOPSIS
+ check_if_legal_tablename
+ name Table name (without any extensions)
+
+ DESCRIPTION
+ We don't check 'CLOCK$' because dollar sign is encoded as @0024,
+ making table file name 'CLOCK@0024', which is safe.
+ This is why we start lookup from the second element
+ (i.e. &reserver_name[1])
+
+ RETURN
+ 0 ok
+ 1 reserved file name
+*/
+
+int check_if_legal_tablename(const char *name)
+{
+ DBUG_ENTER("check_if_legal_tablename");
+ DBUG_RETURN((reserved_map[(uchar) name[0]] & 1) &&
+ (reserved_map[(uchar) name[1]] & 2) &&
+ (reserved_map[(uchar) name[2]] & 4) &&
+ str_list_find(&reserved_names[1], name));
+}
+
+
+#if defined(__WIN__) || defined(__EMX__)
+
+
/*
Check if a path will access a reserverd file name that may cause problems
@@ -110,12 +197,5 @@ int check_if_legal_filename(const char *path)
}
DBUG_RETURN(0);
}
-#endif
-
-#ifdef OS2
-int check_if_legal_filename(const char *path)
-{
- return 0;
-}
-#endif /* OS2 */
+#endif /* defined(__WIN__) || defined(__EMX__) */
diff --git a/mysys/my_alloc.c b/mysys/my_alloc.c
index cfa2dd6216d..5a0ac7b87f7 100644
--- a/mysys/my_alloc.c
+++ b/mysys/my_alloc.c
@@ -396,6 +396,7 @@ char *strdup_root(MEM_ROOT *root,const char *str)
return strmake_root(root, str, (uint) strlen(str));
}
+
char *strmake_root(MEM_ROOT *root,const char *str, uint len)
{
char *pos;
diff --git a/mysys/my_append.c b/mysys/my_append.c
index 274f2110575..ddd3c91e832 100644
--- a/mysys/my_append.c
+++ b/mysys/my_append.c
@@ -13,7 +13,6 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-#define USES_TYPES /* sys/types is included */
#include "mysys_priv.h"
#include <sys/stat.h>
#include <m_string.h>
diff --git a/mysys/my_atomic.c b/mysys/my_atomic.c
new file mode 100644
index 00000000000..6a30267eb80
--- /dev/null
+++ b/mysys/my_atomic.c
@@ -0,0 +1,46 @@
+/* Copyright (C) 2006 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 */
+
+#include <my_global.h>
+#include <my_pthread.h>
+
+#ifndef HAVE_INLINE
+/*
+ the following will cause all inline functions to be instantiated
+*/
+#define HAVE_INLINE
+#define static extern
+#endif
+
+#include <my_atomic.h>
+
+/*
+ checks that the current build of atomic ops
+ can run on this machine
+
+ RETURN
+ ATOMIC_xxx values, see my_atomic.h
+*/
+int my_atomic_initialize()
+{
+ DBUG_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;
+#else
+ return MY_ATOMIC_OK;
+#endif
+}
+
diff --git a/mysys/my_bit.c b/mysys/my_bit.c
index 81d63246e7a..5a9b1187c83 100644
--- a/mysys/my_bit.c
+++ b/mysys/my_bit.c
@@ -75,3 +75,33 @@ 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
+*/
+
+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 */
+}
diff --git a/mysys/my_bitmap.c b/mysys/my_bitmap.c
index 2cf16111f67..b96bea0ed78 100644
--- a/mysys/my_bitmap.c
+++ b/mysys/my_bitmap.c
@@ -19,26 +19,69 @@
API limitations (or, rather asserted safety assumptions,
to encourage correct programming)
- * the size of the used bitmap is less than ~(uint) 0
- * it's a multiple of 8 (for efficiency reasons)
- * when arguments are a bitmap and a bit number, the number
- must be within bitmap size
- * bitmap_set_prefix() is an exception - one can use ~0 to set all bits
- * when both arguments are bitmaps, they must be of the same size
- * bitmap_intersect() is an exception :)
- (for for Bitmap::intersect(ulonglong map2buff))
-
- If THREAD is defined all bitmap operations except bitmap_init/bitmap_free
- are thread-safe.
+ * the internal size is a set of 32 bit words
+ * the number of bits specified in creation can be any number > 0
+ * there are THREAD safe versions of most calls called bitmap_lock_*
+ many of those are not used and not compiled normally but the code
+ already exist for them in an #ifdef:ed part. These can only be used
+ if THREAD was specified in bitmap_init
TODO:
Make assembler THREAD safe versions of these using test-and-set instructions
+
+ Original version created by Sergei Golubchik 2001 - 2004.
+ New version written and test program added and some changes to the interface
+ was made by Mikael Ronström 2005, with assistance of Tomas Ulin and Mats
+ Kindahl.
*/
#include "mysys_priv.h"
#include <my_bitmap.h>
#include <m_string.h>
+void create_last_word_mask(MY_BITMAP *map)
+{
+ /* Get the number of used bits (1..8) in the last byte */
+ unsigned int const used= 1U + ((map->n_bits-1U) & 0x7U);
+
+ /*
+ Create a mask with the upper 'unused' bits set and the lower 'used'
+ bits clear. The bits within each byte is stored in big-endian order.
+ */
+ unsigned char const mask= (~((1 << used) - 1)) & 255;
+
+ /*
+ The first bytes are to be set to zero since they represent real bits
+ in the bitvector. The last bytes are set to 0xFF since they represent
+ bytes not used by the bitvector. Finally the last byte contains bits
+ as set by the mask above.
+ */
+ unsigned char *ptr= (unsigned char*)&map->last_word_mask;
+
+ map->last_word_ptr= map->bitmap + no_words_in_map(map)-1;
+ switch (no_bytes_in_map(map) & 3) {
+ case 1:
+ map->last_word_mask= ~0U;
+ ptr[0]= mask;
+ return;
+ case 2:
+ map->last_word_mask= ~0U;
+ ptr[0]= 0;
+ ptr[1]= mask;
+ return;
+ case 3:
+ map->last_word_mask= 0U;
+ ptr[2]= mask;
+ ptr[3]= 0xFFU;
+ return;
+ case 0:
+ map->last_word_mask= 0U;
+ ptr[3]= mask;
+ return;
+ }
+}
+
+
static inline void bitmap_lock(MY_BITMAP *map __attribute__((unused)))
{
#ifdef THREAD
@@ -56,29 +99,43 @@ static inline void bitmap_unlock(MY_BITMAP *map __attribute__((unused)))
}
-my_bool bitmap_init(MY_BITMAP *map, uchar *buf, uint bitmap_size,
- my_bool thread_safe)
+my_bool bitmap_init(MY_BITMAP *map, my_bitmap_map *buf, uint n_bits,
+ my_bool thread_safe __attribute__((unused)))
{
DBUG_ENTER("bitmap_init");
-
- DBUG_ASSERT((bitmap_size & 7) == 0);
- bitmap_size/=8;
- if (!(map->bitmap=buf) &&
- !(map->bitmap= (uchar*) my_malloc(bitmap_size +
- (thread_safe ?
- sizeof(pthread_mutex_t) : 0),
- MYF(MY_WME | MY_ZEROFILL))))
- DBUG_RETURN(1);
- map->bitmap_size=bitmap_size;
-#ifdef THREAD
- if (thread_safe)
+ if (!buf)
{
- map->mutex=(pthread_mutex_t *)(map->bitmap+bitmap_size);
- pthread_mutex_init(map->mutex, MY_MUTEX_INIT_FAST);
+ uint size_in_bytes= bitmap_buffer_size(n_bits);
+ uint extra= 0;
+#ifdef THREAD
+ if (thread_safe)
+ {
+ size_in_bytes= ALIGN_SIZE(size_in_bytes);
+ extra= sizeof(pthread_mutex_t);
+ }
+ map->mutex= 0;
+#endif
+ if (!(buf= (my_bitmap_map*) my_malloc(size_in_bytes+extra, MYF(MY_WME))))
+ DBUG_RETURN(1);
+#ifdef THREAD
+ if (thread_safe)
+ {
+ map->mutex= (pthread_mutex_t *) ((char*) buf + size_in_bytes);
+ pthread_mutex_init(map->mutex, MY_MUTEX_INIT_FAST);
+ }
+#endif
}
+#ifdef THREAD
else
- map->mutex=0;
+ {
+ DBUG_ASSERT(thread_safe == 0);
+ }
#endif
+
+ map->bitmap= buf;
+ map->n_bits= n_bits;
+ create_last_word_mask(map);
+ bitmap_clear_all(map);
DBUG_RETURN(0);
}
@@ -99,15 +156,6 @@ void bitmap_free(MY_BITMAP *map)
}
-void bitmap_set_bit(MY_BITMAP *map, uint bitmap_bit)
-{
- DBUG_ASSERT(map->bitmap && bitmap_bit < map->bitmap_size*8);
- bitmap_lock(map);
- bitmap_fast_set_bit(map, bitmap_bit);
- bitmap_unlock(map);
-}
-
-
/*
test if bit already set and set it if it was not (thread unsafe method)
@@ -123,7 +171,7 @@ void bitmap_set_bit(MY_BITMAP *map, uint bitmap_bit)
my_bool bitmap_fast_test_and_set(MY_BITMAP *map, uint bitmap_bit)
{
- uchar *byte= map->bitmap + (bitmap_bit / 8);
+ uchar *byte= (uchar*)map->bitmap + (bitmap_bit / 8);
uchar bit= 1 << ((bitmap_bit) & 7);
uchar res= (*byte) & bit;
*byte|= bit;
@@ -147,182 +195,177 @@ my_bool bitmap_fast_test_and_set(MY_BITMAP *map, uint bitmap_bit)
my_bool bitmap_test_and_set(MY_BITMAP *map, uint bitmap_bit)
{
my_bool res;
- DBUG_ASSERT(map->bitmap && bitmap_bit < map->bitmap_size*8);
+ DBUG_ASSERT(map->bitmap && bitmap_bit < map->n_bits);
bitmap_lock(map);
res= bitmap_fast_test_and_set(map, bitmap_bit);
bitmap_unlock(map);
return res;
}
-uint bitmap_set_next(MY_BITMAP *map)
-{
- uchar *bitmap=map->bitmap;
- uint bit_found = MY_BIT_NONE;
- uint bitmap_size=map->bitmap_size;
- uint i;
+/*
+ test if bit already set and clear it if it was set(thread unsafe method)
- DBUG_ASSERT(map->bitmap);
- bitmap_lock(map);
- for (i=0; i < bitmap_size ; i++, bitmap++)
- {
- if (*bitmap != 0xff)
- { /* Found slot with free bit */
- uint b;
- for (b=0; ; b++)
- {
- if (!(*bitmap & (1 << b)))
- {
- *bitmap |= 1<<b;
- bit_found = (i*8)+b;
- break;
- }
- }
- break; /* Found bit */
- }
- }
- bitmap_unlock(map);
- return bit_found;
-}
+ SYNOPSIS
+ bitmap_fast_test_and_set()
+ MAP bit map struct
+ BIT bit number
+ RETURN
+ 0 bit was not set
+ !=0 bit was set
+*/
-void bitmap_clear_bit(MY_BITMAP *map, uint bitmap_bit)
+my_bool bitmap_fast_test_and_clear(MY_BITMAP *map, uint bitmap_bit)
{
- DBUG_ASSERT(map->bitmap && bitmap_bit < map->bitmap_size*8);
- bitmap_lock(map);
- bitmap_fast_clear_bit(map, bitmap_bit);
- bitmap_unlock(map);
+ uchar *byte= (uchar*) map->bitmap + (bitmap_bit / 8);
+ uchar bit= 1 << ((bitmap_bit) & 7);
+ uchar res= (*byte) & bit;
+ *byte&= ~bit;
+ return res;
}
-void bitmap_set_prefix(MY_BITMAP *map, uint prefix_size)
+my_bool bitmap_test_and_clear(MY_BITMAP *map, uint bitmap_bit)
{
- uint prefix_bytes, prefix_bits;
-
- DBUG_ASSERT(map->bitmap &&
- (prefix_size <= map->bitmap_size*8 || prefix_size == (uint) ~0));
+ my_bool res;
+ DBUG_ASSERT(map->bitmap && bitmap_bit < map->n_bits);
bitmap_lock(map);
- set_if_smaller(prefix_size, map->bitmap_size*8);
- if ((prefix_bytes= prefix_size / 8))
- memset(map->bitmap, 0xff, prefix_bytes);
- if ((prefix_bits= prefix_size & 7))
- map->bitmap[prefix_bytes++]= (1 << prefix_bits)-1;
- if (prefix_bytes < map->bitmap_size)
- bzero(map->bitmap+prefix_bytes, map->bitmap_size-prefix_bytes);
+ res= bitmap_fast_test_and_clear(map, bitmap_bit);
bitmap_unlock(map);
+ return res;
}
-void bitmap_clear_all(MY_BITMAP *map)
+uint bitmap_set_next(MY_BITMAP *map)
{
- bitmap_set_prefix(map, 0);
+ uint bit_found;
+ DBUG_ASSERT(map->bitmap);
+ if ((bit_found= bitmap_get_first(map)) != MY_BIT_NONE)
+ bitmap_set_bit(map, bit_found);
+ return bit_found;
}
-void bitmap_set_all(MY_BITMAP *map)
+void bitmap_set_prefix(MY_BITMAP *map, uint prefix_size)
{
- bitmap_set_prefix(map, ~0);
+ uint prefix_bytes, prefix_bits, d;
+ uchar *m= (uchar *)map->bitmap;
+
+ DBUG_ASSERT(map->bitmap &&
+ (prefix_size <= map->n_bits || prefix_size == (uint) ~0));
+ set_if_smaller(prefix_size, map->n_bits);
+ if ((prefix_bytes= prefix_size / 8))
+ memset(m, 0xff, prefix_bytes);
+ m+= prefix_bytes;
+ if ((prefix_bits= prefix_size & 7))
+ *m++= (1 << prefix_bits)-1;
+ if ((d= no_bytes_in_map(map)-prefix_bytes))
+ bzero(m, d);
}
my_bool bitmap_is_prefix(const MY_BITMAP *map, uint prefix_size)
{
- uint prefix_bits= prefix_size & 7, res= 0;
- uchar *m= map->bitmap, *end_prefix= map->bitmap+prefix_size/8,
- *end= map->bitmap+map->bitmap_size;
-
- DBUG_ASSERT(map->bitmap && prefix_size <= map->bitmap_size*8);
+ uint prefix_bits= prefix_size & 0x7, res;
+ uchar *m= (uchar*)map->bitmap;
+ uchar *end_prefix= m+prefix_size/8;
+ uchar *end;
+ DBUG_ASSERT(m && prefix_size <= map->n_bits);
+ end= m+no_bytes_in_map(map);
- bitmap_lock((MY_BITMAP *)map);
while (m < end_prefix)
if (*m++ != 0xff)
- goto ret;
+ return 0;
+ *map->last_word_ptr&= ~map->last_word_mask; /*Clear bits*/
+ res= 0;
if (prefix_bits && *m++ != (1 << prefix_bits)-1)
goto ret;
while (m < end)
if (*m++ != 0)
goto ret;
-
- res=1;
+ res= 1;
ret:
- bitmap_unlock((MY_BITMAP *)map);
- return res;
+ return res;
}
-my_bool bitmap_is_clear_all(const MY_BITMAP *map)
-{
- return bitmap_is_prefix(map, 0);
-}
-
my_bool bitmap_is_set_all(const MY_BITMAP *map)
{
- return bitmap_is_prefix(map, map->bitmap_size*8);
+ my_bitmap_map *data_ptr= map->bitmap;
+ my_bitmap_map *end= map->last_word_ptr;
+ *map->last_word_ptr |= map->last_word_mask;
+ for (; data_ptr <= end; data_ptr++)
+ if (*data_ptr != 0xFFFFFFFF)
+ return FALSE;
+ return TRUE;
}
-my_bool bitmap_is_set(const MY_BITMAP *map, uint bitmap_bit)
+my_bool bitmap_is_clear_all(const MY_BITMAP *map)
{
- DBUG_ASSERT(map->bitmap && bitmap_bit < map->bitmap_size*8);
- return bitmap_fast_is_set(map, bitmap_bit);
+ my_bitmap_map *data_ptr= map->bitmap;
+ my_bitmap_map *end;
+ if (*map->last_word_ptr & ~map->last_word_mask)
+ return FALSE;
+ end= map->last_word_ptr;
+ for (; data_ptr < end; data_ptr++)
+ if (*data_ptr)
+ return FALSE;
+ return TRUE;
}
+/* Return TRUE if map1 is a subset of map2 */
my_bool bitmap_is_subset(const MY_BITMAP *map1, const MY_BITMAP *map2)
{
- uint res=0;
- uchar *m1=map1->bitmap, *m2=map2->bitmap, *end;
+ my_bitmap_map *m1= map1->bitmap, *m2= map2->bitmap, *end;
DBUG_ASSERT(map1->bitmap && map2->bitmap &&
- map1->bitmap_size==map2->bitmap_size);
- bitmap_lock((MY_BITMAP *)map1);
- bitmap_lock((MY_BITMAP *)map2);
-
- end= m1+map1->bitmap_size;
+ map1->n_bits==map2->n_bits);
- while (m1 < end)
+ end= map1->last_word_ptr;
+ *map1->last_word_ptr &= ~map1->last_word_mask;
+ *map2->last_word_ptr &= ~map2->last_word_mask;
+ while (m1 <= end)
{
if ((*m1++) & ~(*m2++))
- goto ret;
+ return 0;
}
-
- res=1;
-ret:
- bitmap_unlock((MY_BITMAP *)map2);
- bitmap_unlock((MY_BITMAP *)map1);
- return res;
+ return 1;
}
+/* True if bitmaps has any common bits */
-my_bool bitmap_cmp(const MY_BITMAP *map1, const MY_BITMAP *map2)
+my_bool bitmap_is_overlapping(const MY_BITMAP *map1, const MY_BITMAP *map2)
{
- uint res;
+ my_bitmap_map *m1= map1->bitmap, *m2= map2->bitmap, *end;
DBUG_ASSERT(map1->bitmap && map2->bitmap &&
- map1->bitmap_size==map2->bitmap_size);
- bitmap_lock((MY_BITMAP *)map1);
- bitmap_lock((MY_BITMAP *)map2);
+ map1->n_bits==map2->n_bits);
- res= memcmp(map1->bitmap, map2->bitmap, map1->bitmap_size)==0;
-
- bitmap_unlock((MY_BITMAP *)map2);
- bitmap_unlock((MY_BITMAP *)map1);
- return res;
+ end= map1->last_word_ptr;
+ *map1->last_word_ptr &= ~map1->last_word_mask;
+ *map2->last_word_ptr &= ~map2->last_word_mask;
+ while (m1 <= end)
+ {
+ if ((*m1++) & (*m2++))
+ return 1;
+ }
+ return 0;
}
void bitmap_intersect(MY_BITMAP *map, const MY_BITMAP *map2)
{
- uchar *to=map->bitmap, *from=map2->bitmap, *end;
- uint len=map->bitmap_size, len2=map2->bitmap_size;
+ my_bitmap_map *to= map->bitmap, *from= map2->bitmap, *end;
+ uint len= no_words_in_map(map), len2 = no_words_in_map(map2);
DBUG_ASSERT(map->bitmap && map2->bitmap);
- bitmap_lock(map);
- bitmap_lock((MY_BITMAP *)map2);
end= to+min(len,len2);
-
+ *map2->last_word_ptr&= ~map2->last_word_mask; /*Clear last bits in map2*/
while (to < end)
*to++ &= *from++;
@@ -332,9 +375,6 @@ void bitmap_intersect(MY_BITMAP *map, const MY_BITMAP *map2)
while (to < end)
*to++=0;
}
-
- bitmap_unlock((MY_BITMAP *)map2);
- bitmap_unlock(map);
}
@@ -361,8 +401,8 @@ void bitmap_intersect(MY_BITMAP *map, const MY_BITMAP *map2)
void bitmap_set_above(MY_BITMAP *map, uint from_byte, uint use_bit)
{
uchar use_byte= use_bit ? 0xff : 0;
- uchar *to= map->bitmap + from_byte;
- uchar *end= map->bitmap + map->bitmap_size;
+ uchar *to= (uchar *)map->bitmap + from_byte;
+ uchar *end= (uchar *)map->bitmap + (map->n_bits+7)/8;
while (to < end)
*to++= use_byte;
@@ -371,37 +411,283 @@ void bitmap_set_above(MY_BITMAP *map, uint from_byte, uint use_bit)
void bitmap_subtract(MY_BITMAP *map, const MY_BITMAP *map2)
{
- uchar *to=map->bitmap, *from=map2->bitmap, *end;
+ my_bitmap_map *to= map->bitmap, *from= map2->bitmap, *end;
+ DBUG_ASSERT(map->bitmap && map2->bitmap &&
+ map->n_bits==map2->n_bits);
+
+ end= map->last_word_ptr;
+
+ while (to <= end)
+ *to++ &= ~(*from++);
+}
+
+
+void bitmap_union(MY_BITMAP *map, const MY_BITMAP *map2)
+{
+ my_bitmap_map *to= map->bitmap, *from= map2->bitmap, *end;
+
+ DBUG_ASSERT(map->bitmap && map2->bitmap &&
+ map->n_bits==map2->n_bits);
+ end= map->last_word_ptr;
+
+ while (to <= end)
+ *to++ |= *from++;
+}
+
+
+void bitmap_xor(MY_BITMAP *map, const MY_BITMAP *map2)
+{
+ my_bitmap_map *to= map->bitmap, *from= map2->bitmap, *end= map->last_word_ptr;
+ DBUG_ASSERT(map->bitmap && map2->bitmap &&
+ map->n_bits==map2->n_bits);
+ while (to <= end)
+ *to++ ^= *from++;
+}
+
+
+void bitmap_invert(MY_BITMAP *map)
+{
+ my_bitmap_map *to= map->bitmap, *end;
+
+ DBUG_ASSERT(map->bitmap);
+ end= map->last_word_ptr;
+
+ while (to <= end)
+ *to++ ^= 0xFFFFFFFF;
+}
+
+
+uint bitmap_bits_set(const MY_BITMAP *map)
+{
+ uchar *m= (uchar*)map->bitmap;
+ uchar *end= m + no_bytes_in_map(map);
+ uint res= 0;
+
+ DBUG_ASSERT(map->bitmap);
+ *map->last_word_ptr&= ~map->last_word_mask; /*Reset last bits to zero*/
+ while (m < end)
+ res+= my_count_bits_ushort(*m++);
+ return res;
+}
+
+
+void bitmap_copy(MY_BITMAP *map, const MY_BITMAP *map2)
+{
+ my_bitmap_map *to= map->bitmap, *from= map2->bitmap, *end;
DBUG_ASSERT(map->bitmap && map2->bitmap &&
- map->bitmap_size==map2->bitmap_size);
+ map->n_bits==map2->n_bits);
+ end= map->last_word_ptr;
+ while (to <= end)
+ *to++ = *from++;
+}
+
+
+uint bitmap_get_first_set(const MY_BITMAP *map)
+{
+ uchar *byte_ptr;
+ uint i,j,k;
+ my_bitmap_map *data_ptr, *end= map->last_word_ptr;
+
+ DBUG_ASSERT(map->bitmap);
+ data_ptr= map->bitmap;
+ *map->last_word_ptr &= ~map->last_word_mask;
+
+ for (i=0; data_ptr <= end; data_ptr++, i++)
+ {
+ if (*data_ptr)
+ {
+ byte_ptr= (uchar*)data_ptr;
+ for (j=0; ; j++, byte_ptr++)
+ {
+ if (*byte_ptr)
+ {
+ for (k=0; ; k++)
+ {
+ if (*byte_ptr & (1 << k))
+ return (i*32) + (j*8) + k;
+ }
+ DBUG_ASSERT(0);
+ }
+ }
+ DBUG_ASSERT(0);
+ }
+ }
+ return MY_BIT_NONE;
+}
+
+
+uint bitmap_get_first(const MY_BITMAP *map)
+{
+ uchar *byte_ptr;
+ uint i,j,k;
+ my_bitmap_map *data_ptr, *end= map->last_word_ptr;
+
+ DBUG_ASSERT(map->bitmap);
+ data_ptr= map->bitmap;
+ *map->last_word_ptr|= map->last_word_mask;
+
+ for (i=0; data_ptr <= end; data_ptr++, i++)
+ {
+ if (*data_ptr != 0xFFFFFFFF)
+ {
+ byte_ptr= (uchar*)data_ptr;
+ for (j=0; ; j++, byte_ptr++)
+ {
+ if (*byte_ptr != 0xFF)
+ {
+ for (k=0; ; k++)
+ {
+ if (!(*byte_ptr & (1 << k)))
+ return (i*32) + (j*8) + k;
+ }
+ DBUG_ASSERT(0);
+ }
+ }
+ DBUG_ASSERT(0);
+ }
+ }
+ return MY_BIT_NONE;
+}
+
+
+uint bitmap_lock_set_next(MY_BITMAP *map)
+{
+ uint bit_found;
bitmap_lock(map);
- bitmap_lock((MY_BITMAP *)map2);
+ bit_found= bitmap_set_next(map);
+ bitmap_unlock(map);
+ return bit_found;
+}
- end= to+map->bitmap_size;
- while (to < end)
- *to++ &= ~(*from++);
+void bitmap_lock_clear_bit(MY_BITMAP *map, uint bitmap_bit)
+{
+ bitmap_lock(map);
+ DBUG_ASSERT(map->bitmap && bitmap_bit < map->n_bits);
+ bitmap_clear_bit(map, bitmap_bit);
+ bitmap_unlock(map);
+}
- bitmap_unlock((MY_BITMAP *)map2);
+
+#ifdef NOT_USED
+my_bool bitmap_lock_is_prefix(const MY_BITMAP *map, uint prefix_size)
+{
+ my_bool res;
+ bitmap_lock((MY_BITMAP *)map);
+ res= bitmap_is_prefix(map, prefix_size);
+ bitmap_unlock((MY_BITMAP *)map);
+ return res;
+}
+
+
+void bitmap_lock_set_all(MY_BITMAP *map)
+{
+ bitmap_lock(map);
+ bitmap_set_all(map);
bitmap_unlock(map);
}
-void bitmap_union(MY_BITMAP *map, const MY_BITMAP *map2)
+void bitmap_lock_clear_all(MY_BITMAP *map)
{
- uchar *to=map->bitmap, *from=map2->bitmap, *end;
+ bitmap_lock(map);
+ bitmap_clear_all(map);
+ bitmap_unlock(map);
+}
- DBUG_ASSERT(map->bitmap && map2->bitmap &&
- map->bitmap_size==map2->bitmap_size);
+
+void bitmap_lock_set_prefix(MY_BITMAP *map, uint prefix_size)
+{
bitmap_lock(map);
+ bitmap_set_prefix(map, prefix_size);
+ bitmap_unlock(map);
+}
+
+
+my_bool bitmap_lock_is_clear_all(const MY_BITMAP *map)
+{
+ uint res;
+ bitmap_lock((MY_BITMAP *)map);
+ res= bitmap_is_clear_all(map);
+ bitmap_unlock((MY_BITMAP *)map);
+ return res;
+}
+
+
+my_bool bitmap_lock_is_set_all(const MY_BITMAP *map)
+{
+ uint res;
+ bitmap_lock((MY_BITMAP *)map);
+ res= bitmap_is_set_all(map);
+ bitmap_unlock((MY_BITMAP *)map);
+ return res;
+}
+
+
+my_bool bitmap_lock_is_set(const MY_BITMAP *map, uint bitmap_bit)
+{
+ my_bool res;
+ DBUG_ASSERT(map->bitmap && bitmap_bit < map->n_bits);
+ bitmap_lock((MY_BITMAP *)map);
+ res= bitmap_is_set(map, bitmap_bit);
+ bitmap_unlock((MY_BITMAP *)map);
+ return res;
+}
+
+
+my_bool bitmap_lock_is_subset(const MY_BITMAP *map1, const MY_BITMAP *map2)
+{
+ uint res;
+ bitmap_lock((MY_BITMAP *)map1);
bitmap_lock((MY_BITMAP *)map2);
+ res= bitmap_is_subset(map1, map2);
+ bitmap_unlock((MY_BITMAP *)map2);
+ bitmap_unlock((MY_BITMAP *)map1);
+ return res;
+}
- end= to+map->bitmap_size;
- while (to < end)
- *to++ |= *from++;
+my_bool bitmap_lock_cmp(const MY_BITMAP *map1, const MY_BITMAP *map2)
+{
+ uint res;
+ DBUG_ASSERT(map1->bitmap && map2->bitmap &&
+ map1->n_bits==map2->n_bits);
+ bitmap_lock((MY_BITMAP *)map1);
+ bitmap_lock((MY_BITMAP *)map2);
+ res= bitmap_cmp(map1, map2);
+ bitmap_unlock((MY_BITMAP *)map2);
+ bitmap_unlock((MY_BITMAP *)map1);
+ return res;
+}
+
+
+void bitmap_lock_intersect(MY_BITMAP *map, const MY_BITMAP *map2)
+{
+ bitmap_lock(map);
+ bitmap_lock((MY_BITMAP *)map2);
+ bitmap_intersect(map, map2);
+ bitmap_unlock((MY_BITMAP *)map2);
+ bitmap_unlock(map);
+}
+
+
+void bitmap_lock_subtract(MY_BITMAP *map, const MY_BITMAP *map2)
+{
+ bitmap_lock(map);
+ bitmap_lock((MY_BITMAP *)map2);
+ bitmap_subtract(map, map2);
+ bitmap_unlock((MY_BITMAP *)map2);
+ bitmap_unlock(map);
+}
+
+
+void bitmap_lock_union(MY_BITMAP *map, const MY_BITMAP *map2)
+{
+ bitmap_lock(map);
+ bitmap_lock((MY_BITMAP *)map2);
+ bitmap_union(map, map2);
bitmap_unlock((MY_BITMAP *)map2);
bitmap_unlock(map);
}
@@ -414,19 +700,12 @@ void bitmap_union(MY_BITMAP *map, const MY_BITMAP *map2)
RETURN
Number of set bits in the bitmap.
*/
-
-uint bitmap_bits_set(const MY_BITMAP *map)
-{
- uchar *m= map->bitmap;
- uchar *end= m + map->bitmap_size;
- uint res= 0;
-
- DBUG_ASSERT(map->bitmap);
+uint bitmap_lock_bits_set(const MY_BITMAP *map)
+{
+ uint res;
bitmap_lock((MY_BITMAP *)map);
- while (m < end)
- {
- res+= my_count_bits_ushort(*m++);
- }
+ DBUG_ASSERT(map->bitmap);
+ res= bitmap_bits_set(map);
bitmap_unlock((MY_BITMAP *)map);
return res;
}
@@ -439,33 +718,412 @@ uint bitmap_bits_set(const MY_BITMAP *map)
RETURN
Number of first unset bit in the bitmap or MY_BIT_NONE if all bits are set.
*/
+uint bitmap_lock_get_first(const MY_BITMAP *map)
+{
+ uint res;
+ bitmap_lock((MY_BITMAP*)map);
+ res= bitmap_get_first(map);
+ bitmap_unlock((MY_BITMAP*)map);
+ return res;
+}
-uint bitmap_get_first(const MY_BITMAP *map)
+
+uint bitmap_lock_get_first_set(const MY_BITMAP *map)
+{
+ uint res;
+ bitmap_lock((MY_BITMAP*)map);
+ res= bitmap_get_first_set(map);
+ bitmap_unlock((MY_BITMAP*)map);
+ return res;
+}
+
+
+void bitmap_lock_set_bit(MY_BITMAP *map, uint bitmap_bit)
+{
+ DBUG_ASSERT(map->bitmap && bitmap_bit < map->n_bits);
+ bitmap_lock(map);
+ bitmap_set_bit(map, bitmap_bit);
+ bitmap_unlock(map);
+}
+
+
+void bitmap_lock_flip_bit(MY_BITMAP *map, uint bitmap_bit)
+{
+ DBUG_ASSERT(map->bitmap && bitmap_bit < map->n_bits);
+ bitmap_lock(map);
+ bitmap_flip_bit(map, bitmap_bit);
+ bitmap_unlock(map);
+}
+#endif
+#ifdef MAIN
+
+uint get_rand_bit(uint bitsize)
+{
+ return (rand() % bitsize);
+}
+
+bool test_set_get_clear_bit(MY_BITMAP *map, uint bitsize)
+{
+ uint i, test_bit;
+ uint no_loops= bitsize > 128 ? 128 : bitsize;
+ for (i=0; i < no_loops; i++)
+ {
+ test_bit= get_rand_bit(bitsize);
+ bitmap_set_bit(map, test_bit);
+ if (!bitmap_is_set(map, test_bit))
+ goto error1;
+ bitmap_clear_bit(map, test_bit);
+ if (bitmap_is_set(map, test_bit))
+ goto error2;
+ }
+ return FALSE;
+error1:
+ printf("Error in set bit, bit %u, bitsize = %u", test_bit, bitsize);
+ return TRUE;
+error2:
+ printf("Error in clear bit, bit %u, bitsize = %u", test_bit, bitsize);
+ return TRUE;
+}
+
+bool test_flip_bit(MY_BITMAP *map, uint bitsize)
+{
+ uint i, test_bit;
+ uint no_loops= bitsize > 128 ? 128 : bitsize;
+ for (i=0; i < no_loops; i++)
+ {
+ test_bit= get_rand_bit(bitsize);
+ bitmap_flip_bit(map, test_bit);
+ if (!bitmap_is_set(map, test_bit))
+ goto error1;
+ bitmap_flip_bit(map, test_bit);
+ if (bitmap_is_set(map, test_bit))
+ goto error2;
+ }
+ return FALSE;
+error1:
+ printf("Error in flip bit 1, bit %u, bitsize = %u", test_bit, bitsize);
+ return TRUE;
+error2:
+ printf("Error in flip bit 2, bit %u, bitsize = %u", test_bit, bitsize);
+ return TRUE;
+}
+
+bool test_operators(MY_BITMAP *map __attribute__((unused)),
+ uint bitsize __attribute__((unused)))
+{
+ return FALSE;
+}
+
+bool test_get_all_bits(MY_BITMAP *map, uint bitsize)
{
- uchar *bitmap=map->bitmap;
- uint bit_found = MY_BIT_NONE;
- uint bitmap_size=map->bitmap_size;
uint i;
+ bitmap_set_all(map);
+ if (!bitmap_is_set_all(map))
+ goto error1;
+ if (!bitmap_is_prefix(map, bitsize))
+ goto error5;
+ bitmap_clear_all(map);
+ if (!bitmap_is_clear_all(map))
+ goto error2;
+ if (!bitmap_is_prefix(map, 0))
+ goto error6;
+ for (i=0; i<bitsize;i++)
+ bitmap_set_bit(map, i);
+ if (!bitmap_is_set_all(map))
+ goto error3;
+ for (i=0; i<bitsize;i++)
+ bitmap_clear_bit(map, i);
+ if (!bitmap_is_clear_all(map))
+ goto error4;
+ return FALSE;
+error1:
+ printf("Error in set_all, bitsize = %u", bitsize);
+ return TRUE;
+error2:
+ printf("Error in clear_all, bitsize = %u", bitsize);
+ return TRUE;
+error3:
+ printf("Error in bitmap_is_set_all, bitsize = %u", bitsize);
+ return TRUE;
+error4:
+ printf("Error in bitmap_is_clear_all, bitsize = %u", bitsize);
+ return TRUE;
+error5:
+ printf("Error in set_all through set_prefix, bitsize = %u", bitsize);
+ return TRUE;
+error6:
+ printf("Error in clear_all through set_prefix, bitsize = %u", bitsize);
+ return TRUE;
+}
- DBUG_ASSERT(map->bitmap);
- bitmap_lock((MY_BITMAP *)map);
- for (i=0; i < bitmap_size ; i++, bitmap++)
+bool test_compare_operators(MY_BITMAP *map, uint bitsize)
+{
+ uint i, j, test_bit1, test_bit2, test_bit3,test_bit4;
+ uint no_loops= bitsize > 128 ? 128 : bitsize;
+ MY_BITMAP map2_obj, map3_obj;
+ MY_BITMAP *map2= &map2_obj, *map3= &map3_obj;
+ my_bitmap_map map2buf[1024];
+ my_bitmap_map map3buf[1024];
+ bitmap_init(&map2_obj, map2buf, bitsize, FALSE);
+ bitmap_init(&map3_obj, map3buf, bitsize, FALSE);
+ bitmap_clear_all(map2);
+ bitmap_clear_all(map3);
+ for (i=0; i < no_loops; i++)
{
- if (*bitmap != 0xff)
- { /* Found slot with free bit */
- uint b;
- for (b=0; ; b++)
- {
- if (!(*bitmap & (1 << b)))
- {
- bit_found = (i*8)+b;
- break;
- }
- }
- break; /* Found bit */
+ test_bit1=get_rand_bit(bitsize);
+ bitmap_set_prefix(map, test_bit1);
+ test_bit2=get_rand_bit(bitsize);
+ bitmap_set_prefix(map2, test_bit2);
+ bitmap_intersect(map, map2);
+ test_bit3= test_bit2 < test_bit1 ? test_bit2 : test_bit1;
+ bitmap_set_prefix(map3, test_bit3);
+ if (!bitmap_cmp(map, map3))
+ goto error1;
+ bitmap_clear_all(map);
+ bitmap_clear_all(map2);
+ bitmap_clear_all(map3);
+ test_bit1=get_rand_bit(bitsize);
+ test_bit2=get_rand_bit(bitsize);
+ test_bit3=get_rand_bit(bitsize);
+ bitmap_set_prefix(map, test_bit1);
+ bitmap_set_prefix(map2, test_bit2);
+ test_bit3= test_bit2 > test_bit1 ? test_bit2 : test_bit1;
+ bitmap_set_prefix(map3, test_bit3);
+ bitmap_union(map, map2);
+ if (!bitmap_cmp(map, map3))
+ goto error2;
+ bitmap_clear_all(map);
+ bitmap_clear_all(map2);
+ bitmap_clear_all(map3);
+ test_bit1=get_rand_bit(bitsize);
+ test_bit2=get_rand_bit(bitsize);
+ test_bit3=get_rand_bit(bitsize);
+ bitmap_set_prefix(map, test_bit1);
+ bitmap_set_prefix(map2, test_bit2);
+ bitmap_xor(map, map2);
+ test_bit3= test_bit2 > test_bit1 ? test_bit2 : test_bit1;
+ test_bit4= test_bit2 < test_bit1 ? test_bit2 : test_bit1;
+ bitmap_set_prefix(map3, test_bit3);
+ for (j=0; j < test_bit4; j++)
+ bitmap_clear_bit(map3, j);
+ if (!bitmap_cmp(map, map3))
+ goto error3;
+ bitmap_clear_all(map);
+ bitmap_clear_all(map2);
+ bitmap_clear_all(map3);
+ test_bit1=get_rand_bit(bitsize);
+ test_bit2=get_rand_bit(bitsize);
+ test_bit3=get_rand_bit(bitsize);
+ bitmap_set_prefix(map, test_bit1);
+ bitmap_set_prefix(map2, test_bit2);
+ bitmap_subtract(map, map2);
+ if (test_bit2 < test_bit1)
+ {
+ bitmap_set_prefix(map3, test_bit1);
+ for (j=0; j < test_bit2; j++)
+ bitmap_clear_bit(map3, j);
}
+ if (!bitmap_cmp(map, map3))
+ goto error4;
+ bitmap_clear_all(map);
+ bitmap_clear_all(map2);
+ bitmap_clear_all(map3);
+ test_bit1=get_rand_bit(bitsize);
+ bitmap_set_prefix(map, test_bit1);
+ bitmap_invert(map);
+ bitmap_set_all(map3);
+ for (j=0; j < test_bit1; j++)
+ bitmap_clear_bit(map3, j);
+ if (!bitmap_cmp(map, map3))
+ goto error5;
+ bitmap_clear_all(map);
+ bitmap_clear_all(map3);
}
- bitmap_unlock((MY_BITMAP *)map);
- return bit_found;
+ return FALSE;
+error1:
+ printf("intersect error bitsize=%u,size1=%u,size2=%u", bitsize,
+ test_bit1,test_bit2);
+ return TRUE;
+error2:
+ printf("union error bitsize=%u,size1=%u,size2=%u", bitsize,
+ test_bit1,test_bit2);
+ return TRUE;
+error3:
+ printf("xor error bitsize=%u,size1=%u,size2=%u", bitsize,
+ test_bit1,test_bit2);
+ return TRUE;
+error4:
+ printf("subtract error bitsize=%u,size1=%u,size2=%u", bitsize,
+ test_bit1,test_bit2);
+ return TRUE;
+error5:
+ printf("invert error bitsize=%u,size=%u", bitsize,
+ test_bit1);
+ return TRUE;
}
+bool test_count_bits_set(MY_BITMAP *map, uint bitsize)
+{
+ uint i, bit_count=0, test_bit;
+ uint no_loops= bitsize > 128 ? 128 : bitsize;
+ for (i=0; i < no_loops; i++)
+ {
+ test_bit=get_rand_bit(bitsize);
+ if (!bitmap_is_set(map, test_bit))
+ {
+ bitmap_set_bit(map, test_bit);
+ bit_count++;
+ }
+ }
+ if (bit_count==0 && bitsize > 0)
+ goto error1;
+ if (bitmap_bits_set(map) != bit_count)
+ goto error2;
+ return FALSE;
+error1:
+ printf("No bits set bitsize = %u", bitsize);
+ return TRUE;
+error2:
+ printf("Wrong count of bits set, bitsize = %u", bitsize);
+ return TRUE;
+}
+
+bool test_get_first_bit(MY_BITMAP *map, uint bitsize)
+{
+ uint i, test_bit;
+ uint no_loops= bitsize > 128 ? 128 : bitsize;
+ for (i=0; i < no_loops; i++)
+ {
+ test_bit=get_rand_bit(bitsize);
+ bitmap_set_bit(map, test_bit);
+ if (bitmap_get_first_set(map) != test_bit)
+ goto error1;
+ bitmap_set_all(map);
+ bitmap_clear_bit(map, test_bit);
+ if (bitmap_get_first(map) != test_bit)
+ goto error2;
+ bitmap_clear_all(map);
+ }
+ return FALSE;
+error1:
+ printf("get_first_set error bitsize=%u,prefix_size=%u",bitsize,test_bit);
+ return TRUE;
+error2:
+ printf("get_first error bitsize= %u, prefix_size= %u",bitsize,test_bit);
+ return TRUE;
+}
+
+bool test_get_next_bit(MY_BITMAP *map, uint bitsize)
+{
+ uint i, j, test_bit;
+ uint no_loops= bitsize > 128 ? 128 : bitsize;
+ for (i=0; i < no_loops; i++)
+ {
+ test_bit=get_rand_bit(bitsize);
+ for (j=0; j < test_bit; j++)
+ bitmap_set_next(map);
+ if (!bitmap_is_prefix(map, test_bit))
+ goto error1;
+ bitmap_clear_all(map);
+ }
+ return FALSE;
+error1:
+ printf("get_next error bitsize= %u, prefix_size= %u", bitsize,test_bit);
+ return TRUE;
+}
+
+bool test_prefix(MY_BITMAP *map, uint bitsize)
+{
+ uint i, j, test_bit;
+ uint no_loops= bitsize > 128 ? 128 : bitsize;
+ for (i=0; i < no_loops; i++)
+ {
+ test_bit=get_rand_bit(bitsize);
+ bitmap_set_prefix(map, test_bit);
+ if (!bitmap_is_prefix(map, test_bit))
+ goto error1;
+ bitmap_clear_all(map);
+ for (j=0; j < test_bit; j++)
+ bitmap_set_bit(map, j);
+ if (!bitmap_is_prefix(map, test_bit))
+ goto error2;
+ bitmap_set_all(map);
+ for (j=bitsize - 1; ~(j-test_bit); j--)
+ bitmap_clear_bit(map, j);
+ if (!bitmap_is_prefix(map, test_bit))
+ goto error3;
+ bitmap_clear_all(map);
+ }
+ return FALSE;
+error1:
+ printf("prefix1 error bitsize = %u, prefix_size = %u", bitsize,test_bit);
+ return TRUE;
+error2:
+ printf("prefix2 error bitsize = %u, prefix_size = %u", bitsize,test_bit);
+ return TRUE;
+error3:
+ printf("prefix3 error bitsize = %u, prefix_size = %u", bitsize,test_bit);
+ return TRUE;
+}
+
+
+bool do_test(uint bitsize)
+{
+ MY_BITMAP map;
+ my_bitmap_map buf[1024];
+ if (bitmap_init(&map, buf, bitsize, FALSE))
+ {
+ printf("init error for bitsize %d", bitsize);
+ goto error;
+ }
+ if (test_set_get_clear_bit(&map,bitsize))
+ goto error;
+ bitmap_clear_all(&map);
+ if (test_flip_bit(&map,bitsize))
+ goto error;
+ bitmap_clear_all(&map);
+ if (test_operators(&map,bitsize))
+ goto error;
+ bitmap_clear_all(&map);
+ if (test_get_all_bits(&map, bitsize))
+ goto error;
+ bitmap_clear_all(&map);
+ if (test_compare_operators(&map,bitsize))
+ goto error;
+ bitmap_clear_all(&map);
+ if (test_count_bits_set(&map,bitsize))
+ goto error;
+ bitmap_clear_all(&map);
+ if (test_get_first_bit(&map,bitsize))
+ goto error;
+ bitmap_clear_all(&map);
+ if (test_get_next_bit(&map,bitsize))
+ goto error;
+ if (test_prefix(&map,bitsize))
+ goto error;
+ return FALSE;
+error:
+ printf("\n");
+ return TRUE;
+}
+
+int main()
+{
+ int i;
+ for (i= 1; i < 4096; i++)
+ {
+ printf("Start test for bitsize=%u\n",i);
+ if (do_test(i))
+ return -1;
+ }
+ printf("OK\n");
+ return 0;
+}
+
+/*
+ In directory mysys:
+ make test_bitmap
+ will build the bitmap tests and ./test_bitmap will execute it
+*/
+
+#endif
diff --git a/mysys/my_clock.c b/mysys/my_clock.c
index c5fa516a622..adc755028d5 100644
--- a/mysys/my_clock.c
+++ b/mysys/my_clock.c
@@ -13,17 +13,16 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-#define USES_TYPES
#include "my_global.h"
-#if !defined(_MSC_VER) && !defined(__BORLANDC__) && !defined(OS2) && !defined(__NETWARE__)
+#if !defined(_MSC_VER) && !defined(__BORLANDC__) && !defined(__NETWARE__)
#include "mysys_priv.h"
#include <sys/times.h>
#endif
long my_clock(void)
{
-#if !defined(MSDOS) && !defined(__WIN__) && !defined(OS2) && !defined(__NETWARE__)
+#if !defined(__WIN__) && !defined(__NETWARE__)
struct tms tmsbuf;
VOID(times(&tmsbuf));
return (tmsbuf.tms_utime + tmsbuf.tms_stime);
diff --git a/mysys/my_compress.c b/mysys/my_compress.c
index c054bf155b1..45e60552592 100644
--- a/mysys/my_compress.c
+++ b/mysys/my_compress.c
@@ -94,4 +94,133 @@ my_bool my_uncompress (byte *packet, ulong *len, ulong *complen)
}
DBUG_RETURN(0);
}
+
+/*
+ Internal representation of the frm blob
+*/
+
+struct frm_blob_header
+{
+ uint ver; /* Version of header */
+ uint orglen; /* Original length of compressed data */
+ uint complen; /* Compressed length of data, 0=uncompressed */
+};
+
+struct frm_blob_struct
+{
+ struct frm_blob_header head;
+ char data[1];
+};
+
+/*
+ packfrm is a method used to compress the frm file for storage in a
+ handler. This method was developed for the NDB handler and has been moved
+ here to serve also other uses.
+
+ SYNOPSIS
+ packfrm()
+ data Data reference to frm file data
+ len Length of frm file data
+ out:pack_data Reference to the pointer to the packed frm data
+ out:pack_len Length of packed frm file data
+
+ RETURN VALUES
+ 0 Success
+ >0 Failure
+*/
+
+int packfrm(const void *data, uint len,
+ const void **pack_data, uint *pack_len)
+{
+ int error;
+ ulong org_len, comp_len;
+ uint blob_len;
+ struct frm_blob_struct *blob;
+ DBUG_ENTER("packfrm");
+ DBUG_PRINT("enter", ("data: 0x%lx, len: %d", (long) data, len));
+
+ error= 1;
+ org_len= len;
+ if (my_compress((byte*)data, &org_len, &comp_len))
+ goto err;
+
+ DBUG_PRINT("info", ("org_len: %lu comp_len: %lu", org_len, comp_len));
+ DBUG_DUMP("compressed", (char*)data, org_len);
+
+ error= 2;
+ blob_len= sizeof(struct frm_blob_header)+org_len;
+ if (!(blob= (struct frm_blob_struct*) my_malloc(blob_len,MYF(MY_WME))))
+ goto err;
+
+ /* Store compressed blob in machine independent format */
+ int4store((char*)(&blob->head.ver), 1);
+ int4store((char*)(&blob->head.orglen), comp_len);
+ int4store((char*)(&blob->head.complen), org_len);
+
+ /* Copy frm data into blob, already in machine independent format */
+ memcpy(blob->data, data, org_len);
+
+ *pack_data= blob;
+ *pack_len= blob_len;
+ error= 0;
+
+ DBUG_PRINT("exit", ("pack_data: 0x%lx pack_len: %d",
+ (long) *pack_data, *pack_len));
+err:
+ DBUG_RETURN(error);
+
+}
+
+/*
+ unpackfrm is a method used to decompress the frm file received from a
+ handler. This method was developed for the NDB handler and has been moved
+ here to serve also other uses for other clustered storage engines.
+
+ SYNOPSIS
+ unpackfrm()
+ pack_data Data reference to packed frm file data
+ out:unpack_data Reference to the pointer to the unpacked frm data
+ out:unpack_len Length of unpacked frm file data
+
+ RETURN VALUES¨
+ 0 Success
+ >0 Failure
+*/
+
+int unpackfrm(const void **unpack_data, uint *unpack_len,
+ const void *pack_data)
+{
+ const struct frm_blob_struct *blob= (struct frm_blob_struct*)pack_data;
+ byte *data;
+ ulong complen, orglen, ver;
+ DBUG_ENTER("unpackfrm");
+ DBUG_PRINT("enter", ("pack_data: 0x%lx", (long) pack_data));
+
+ complen= uint4korr((char*)&blob->head.complen);
+ orglen= uint4korr((char*)&blob->head.orglen);
+ ver= uint4korr((char*)&blob->head.ver);
+
+ DBUG_PRINT("blob",("ver: %lu complen: %lu orglen: %lu",
+ ver,complen,orglen));
+ DBUG_DUMP("blob->data", (char*) blob->data, complen);
+
+ if (ver != 1)
+ DBUG_RETURN(1);
+ if (!(data= my_malloc(max(orglen, complen), MYF(MY_WME))))
+ DBUG_RETURN(2);
+ memcpy(data, blob->data, complen);
+
+
+ if (my_uncompress(data, &complen, &orglen))
+ {
+ my_free((char*)data, MYF(0));
+ DBUG_RETURN(3);
+ }
+
+ *unpack_data= data;
+ *unpack_len= complen;
+
+ DBUG_PRINT("exit", ("frmdata: 0x%lx len: %d", (long) *unpack_data, *unpack_len));
+ DBUG_RETURN(0);
+}
#endif /* HAVE_COMPRESS */
diff --git a/mysys/my_copy.c b/mysys/my_copy.c
index 6143700befc..80a68f61b12 100644
--- a/mysys/my_copy.c
+++ b/mysys/my_copy.c
@@ -13,7 +13,6 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-#define USES_TYPES /* sys/types is included */
#include "mysys_priv.h"
#include <my_dir.h> /* for stat */
#include <m_string.h>
@@ -94,7 +93,7 @@ int my_copy(const char *from, const char *to, myf MyFlags)
if (MyFlags & MY_HOLD_ORIGINAL_MODES && !new_file_stat)
DBUG_RETURN(0); /* File copyed but not stat */
VOID(chmod(to, stat_buff.st_mode & 07777)); /* Copy modes */
-#if !defined(MSDOS) && !defined(__WIN__) && !defined(__EMX__) && !defined(OS2) && !defined(__NETWARE__)
+#if !defined(__WIN__) && !defined(__NETWARE__)
VOID(chown(to, stat_buff.st_uid,stat_buff.st_gid)); /* Copy ownership */
#endif
#if !defined(VMS) && !defined(__ZTC__)
diff --git a/mysys/my_create.c b/mysys/my_create.c
index d612926c1a5..5639459f5a9 100644
--- a/mysys/my_create.c
+++ b/mysys/my_create.c
@@ -13,12 +13,11 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-#define USES_TYPES
#include "mysys_priv.h"
#include <my_dir.h>
#include "mysys_err.h"
#include <errno.h>
-#if defined(MSDOS) || defined(__WIN__) || defined(__EMX__) || defined(OS2)
+#if defined(__WIN__)
#include <share.h>
#endif
@@ -40,19 +39,12 @@ File my_create(const char *FileName, int CreateFlags, int access_flags,
DBUG_PRINT("my",("Name: '%s' CreateFlags: %d AccessFlags: %d MyFlags: %d",
FileName, CreateFlags, access_flags, MyFlags));
-#if !defined(NO_OPEN_3) && !defined(__EMX__)
+#if !defined(NO_OPEN_3)
fd = open((my_string) FileName, access_flags | O_CREAT,
CreateFlags ? CreateFlags : my_umask);
#elif defined(VMS)
fd = open((my_string) FileName, access_flags | O_CREAT, 0,
"ctx=stm","ctx=bin");
-#elif defined(MSDOS) || defined(__EMX__) || defined(OS2)
- if (access_flags & O_SHARE)
- fd = sopen((my_string) FileName, access_flags | O_CREAT | O_BINARY,
- SH_DENYNO, MY_S_IREAD | MY_S_IWRITE);
- else
- fd = open((my_string) FileName, access_flags | O_CREAT | O_BINARY,
- MY_S_IREAD | MY_S_IWRITE);
#elif defined(__WIN__)
fd= my_sopen((my_string) FileName, access_flags | O_CREAT | O_BINARY,
SH_DENYNO, MY_S_IREAD | MY_S_IWRITE);
diff --git a/mysys/my_dup.c b/mysys/my_dup.c
index 2c6a42726e4..55f5e0c0099 100644
--- a/mysys/my_dup.c
+++ b/mysys/my_dup.c
@@ -13,12 +13,11 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-#define USES_TYPES
#include "mysys_priv.h"
#include "mysys_err.h"
#include <my_dir.h>
#include <errno.h>
-#if defined(MSDOS) || defined(__WIN__) || defined(__EMX__)
+#if defined(__WIN__)
#include <share.h>
#endif
diff --git a/mysys/my_error.c b/mysys/my_error.c
index 836f851322b..48392fe84c3 100644
--- a/mysys/my_error.c
+++ b/mysys/my_error.c
@@ -52,8 +52,10 @@ static struct my_err_head
int meh_first; /* error number matching array slot 0 */
int meh_last; /* error number matching last slot */
} my_errmsgs_globerrs = {NULL, globerrs, EE_ERROR_FIRST, EE_ERROR_LAST};
+
static struct my_err_head *my_errmsgs_list= &my_errmsgs_globerrs;
+
/*
Error message to user
@@ -75,7 +77,6 @@ int my_error(int nr, myf MyFlags, ...)
va_list args;
char ebuff[ERRMSGSIZE + 20];
DBUG_ENTER("my_error");
-
DBUG_PRINT("my", ("nr: %d MyFlags: %d errno: %d", nr, MyFlags, errno));
/* Search for the error messages array, which could contain the message. */
@@ -101,6 +102,7 @@ int my_error(int nr, myf MyFlags, ...)
DBUG_RETURN((*error_handler_hook)(nr, ebuff, MyFlags));
}
+
/*
Error as printf
@@ -249,3 +251,15 @@ const char **my_error_unregister(int first, int last)
return errmsgs;
}
+
+
+void my_error_unregister_all(void)
+{
+ struct my_err_head *list, *next;
+ for (list= my_errmsgs_globerrs.meh_next; list; list= next)
+ {
+ next= list->meh_next;
+ my_free((gptr) list, MYF(0));
+ }
+ my_errmsgs_list= &my_errmsgs_globerrs;
+}
diff --git a/mysys/my_file.c b/mysys/my_file.c
index c97a512f8a1..44bacf55307 100644
--- a/mysys/my_file.c
+++ b/mysys/my_file.c
@@ -32,7 +32,7 @@
May be more or less than max_file_limit!
*/
-#if defined(HAVE_GETRLIMIT) && defined(RLIMIT_NOFILE) && !defined(HAVE_mit_thread)
+#if defined(HAVE_GETRLIMIT) && defined(RLIMIT_NOFILE)
#ifndef RLIM_INFINITY
#define RLIM_INFINITY ((uint) 0xffffffff)
@@ -71,25 +71,6 @@ static uint set_max_open_files(uint max_file_limit)
DBUG_RETURN(max_file_limit);
}
-#elif defined (OS2)
-
-static uint set_max_open_files(uint max_file_limit)
-{
- LONG cbReqCount;
- ULONG cbCurMaxFH0;
- APIRET ulrc;
- DBUG_ENTER("set_max_open_files");
-
- /* get current limit */
- cbReqCount = 0;
- DosSetRelMaxFH( &cbReqCount, &cbCurMaxFH0);
-
- /* set new limit */
- if ((cbReqCount = max_file_limit - cbCurMaxFH0) > 0)
- ulrc = DosSetRelMaxFH( &cbReqCount, &cbCurMaxFH);
- DBUG_RETURN(cbCurMaxFH0);
-}
-
#else
static int set_max_open_files(uint max_file_limit)
{
@@ -125,7 +106,10 @@ uint my_set_max_open_files(uint files)
DBUG_RETURN(MY_NFILE);
/* Copy any initialized files */
- memcpy((char*) tmp, (char*) my_file_info, sizeof(*tmp) * my_file_limit);
+ memcpy((char*) tmp, (char*) my_file_info,
+ sizeof(*tmp) * min(my_file_limit, files));
+ bzero((char*) (tmp + my_file_limit),
+ max((int) (files- my_file_limit), 0)*sizeof(*tmp));
my_free_open_file_info(); /* Free if already allocated */
my_file_info= tmp;
my_file_limit= files;
@@ -139,8 +123,12 @@ void my_free_open_file_info()
DBUG_ENTER("my_free_file_info");
if (my_file_info != my_file_info_default)
{
+ /* Copy data back for my_print_open_files */
+ memcpy((char*) my_file_info_default, my_file_info,
+ sizeof(*my_file_info_default)* MY_NFILE);
my_free((char*) my_file_info, MYF(0));
my_file_info= my_file_info_default;
+ my_file_limit= MY_NFILE;
}
DBUG_VOID_RETURN;
}
diff --git a/mysys/my_gethostbyname.c b/mysys/my_gethostbyname.c
index 434a00bab11..067fdfee9db 100644
--- a/mysys/my_gethostbyname.c
+++ b/mysys/my_gethostbyname.c
@@ -18,7 +18,7 @@
/* Thread safe version of gethostbyname_r() */
#include "mysys_priv.h"
-#if !defined(MSDOS) && !defined(__WIN__)
+#if !defined(__WIN__)
#include <netdb.h>
#endif
#include <my_net.h>
diff --git a/mysys/my_getncpus.c b/mysys/my_getncpus.c
new file mode 100644
index 00000000000..82e87dee2e4
--- /dev/null
+++ b/mysys/my_getncpus.c
@@ -0,0 +1,39 @@
+/* Copyright (C) 2006 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 */
+
+/* get the number of (online) CPUs */
+
+#include "mysys_priv.h"
+#include <unistd.h>
+
+static int ncpus=0;
+
+#ifdef _SC_NPROCESSORS_ONLN
+int my_getncpus()
+{
+ if (!ncpus)
+ ncpus= sysconf(_SC_NPROCESSORS_ONLN);
+ return ncpus;
+}
+
+#else
+/* unknown */
+int my_getncpus()
+{
+ return 2;
+}
+
+#endif
+
diff --git a/mysys/my_getopt.c b/mysys/my_getopt.c
index 250c10e8479..c7bd2dd0a0c 100644
--- a/mysys/my_getopt.c
+++ b/mysys/my_getopt.c
@@ -490,7 +490,7 @@ invalid value '%s'\n",
}
get_one_option(optp->id, optp, argument);
- (*argc)--; /* option handled (short or long), decrease argument count */
+ (*argc)--; /* option handled (short or long), decrease argument count */
}
else /* non-option found */
(*argv)[argvpos++]= cur_arg;
@@ -940,8 +940,8 @@ void my_print_variables(const struct my_option *options)
(*getopt_get_addr)("", 0, optp) : optp->value);
if (value)
{
- printf("%s", optp->name);
- length= (uint) strlen(optp->name);
+ printf("%s ", optp->name);
+ length= (uint) strlen(optp->name)+1;
for (; length < name_space; length++)
putchar(' ');
switch ((optp->var_type & GET_TYPE_MASK)) {
diff --git a/mysys/my_getwd.c b/mysys/my_getwd.c
index 3870a5d61b0..c258db8b126 100644
--- a/mysys/my_getwd.c
+++ b/mysys/my_getwd.c
@@ -21,19 +21,11 @@
#ifdef HAVE_GETWD
#include <sys/param.h>
#endif
-#if defined(MSDOS) || defined(__WIN__)
+#if defined(__WIN__)
#include <m_ctype.h>
#include <dos.h>
#include <direct.h>
#endif
-#if defined(OS2)
-#include <direct.h>
-#endif
-
-#ifdef __EMX__
-/* chdir2 support also drive change */
-#define chdir _chdir2
-#endif
/* Gets current working directory in buff. Directory is allways ended
with FN_LIBCHAR */
@@ -46,11 +38,9 @@ int my_getwd(my_string buf, uint size, myf MyFlags)
DBUG_ENTER("my_getwd");
DBUG_PRINT("my",("buf: 0x%lx size: %d MyFlags %d", (long) buf,size,MyFlags));
-#if ! defined(MSDOS)
if (curr_dir[0]) /* Current pos is saved here */
VOID(strmake(buf,&curr_dir[0],size-1));
else
-#endif
{
#if defined(HAVE_GETCWD)
if (!getcwd(buf,size-2) && MyFlags & MY_WME)
@@ -94,48 +84,13 @@ int my_setwd(const char *dir, myf MyFlags)
int res;
size_s length;
my_string start,pos;
-#if defined(VMS) || defined(MSDOS) || defined(OS2)
+#if defined(VMS)
char buff[FN_REFLEN];
#endif
DBUG_ENTER("my_setwd");
DBUG_PRINT("my",("dir: '%s' MyFlags %d", dir, MyFlags));
start=(my_string) dir;
-#if defined(MSDOS) || defined(OS2) /* OS2/MSDOS chdir can't change drive */
-#if !defined(_DDL) && !defined(WIN32)
- if ((pos=(char*) strchr(dir,FN_DEVCHAR)) != 0)
- {
- uint drive,drives;
-
- pos++; /* Skip FN_DEVCHAR */
- drive=(uint) (my_toupper(&my_charset_latin1,dir[0])-'A'+1);
- drives= (uint) -1;
- if ((pos-(byte*) dir) == 2 && drive > 0 && drive < 32)
- {
-#ifdef OS2
- _chdrive(drive);
- drives = _getdrive();
-#else
- _dos_setdrive(drive,&drives);
- _dos_getdrive(&drives);
-#endif
- }
- if (drive != drives)
- {
- *pos='\0'; /* Dir is now only drive */
- my_errno=errno;
- my_error(EE_SETWD,MYF(ME_BELL+ME_WAITTANG),dir,ENOENT);
- DBUG_RETURN(-1);
- }
- dir=pos; /* drive changed, change now path */
- }
-#endif
- if (*((pos=strend(dir)-1)) == FN_LIBCHAR && pos != dir)
- {
- strmov(buff,dir)[-1]=0; /* Remove last '/' */
- dir=buff;
- }
-#endif /* MSDOS*/
if (! dir[0] || (dir[0] == FN_LIBCHAR && dir[1] == 0))
dir=FN_ROOTDIR;
#ifdef VMS
diff --git a/mysys/my_init.c b/mysys/my_init.c
index cc4bef10e8d..a553d13eaa0 100644
--- a/mysys/my_init.c
+++ b/mysys/my_init.c
@@ -86,13 +86,10 @@ my_bool my_init(void)
#endif
if (my_thread_global_init())
return 1;
-#if !defined( __WIN__) && !defined(OS2) && !defined(__NETWARE__)
+#if !defined( __WIN__) && !defined(__NETWARE__)
sigfillset(&my_signals); /* signals blocked by mf_brkhant */
#endif
#endif /* THREAD */
-#ifdef UNIXWARE_7
- (void) isatty(0); /* Go around connect() bug in UW7 */
-#endif
{
DBUG_ENTER("my_init");
DBUG_PROCESS((char*) (my_progname ? my_progname : "unknown"));
@@ -133,7 +130,10 @@ void my_end(int infoflag)
*/
FILE *info_file= DBUG_FILE;
my_bool print_info= (info_file != stderr);
- DBUG_ENTER("my_end");
+ /* We do not use DBUG_ENTER here, as after cleanup DBUG is no longer
+ operational, so we cannot use DBUG_RETURN.
+ */
+ DBUG_PRINT("info",("Shutting down"));
if (!info_file)
{
info_file= stderr;
@@ -149,9 +149,11 @@ void my_end(int infoflag)
sprintf(errbuff[0],EE(EE_OPEN_WARNING),my_file_opened,my_stream_opened);
(void) my_message_no_curses(EE_OPEN_WARNING,errbuff[0],ME_BELL);
DBUG_PRINT("error",("%s",errbuff[0]));
+ my_print_open_files();
}
}
free_charsets();
+ my_error_unregister_all();
my_once_free();
if ((infoflag & MY_GIVE_INFO) || print_info)
@@ -179,7 +181,7 @@ Voluntary context switches %ld, Involuntary context switches %ld\n",
rus.ru_msgsnd, rus.ru_msgrcv, rus.ru_nsignals,
rus.ru_nvcsw, rus.ru_nivcsw);
#endif
-#if ( defined(MSDOS) || defined(__NETWARE__) ) && !defined(__WIN__)
+#if defined(__NETWARE__) && !defined(__WIN__)
fprintf(info_file,"\nRun time: %.1f\n",(double) clock()/CLOCKS_PER_SEC);
#endif
#if defined(SAFEMALLOC)
@@ -206,7 +208,8 @@ Voluntary context switches %ld, Involuntary context switches %ld\n",
Check on destroying of mutexes. A few may be left that will get cleaned
up by C++ destructors
*/
- safe_mutex_end(infoflag & MY_GIVE_INFO ? stderr : (FILE *) 0);
+ safe_mutex_end((infoflag & (MY_GIVE_INFO | MY_CHECK_ERROR)) ? stderr :
+ (FILE *) 0);
#endif /* defined(SAFE_MUTEX) */
#endif /* THREAD */
diff --git a/mysys/my_lib.c b/mysys/my_lib.c
index 75e31c4d555..86b1c2d5851 100644
--- a/mysys/my_lib.c
+++ b/mysys/my_lib.c
@@ -14,9 +14,8 @@
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/* TODO: check for overun of memory for names. */
-/* Convert MSDOS-TIME to standar time_t */
+/* Convert MSDOS-TIME to standar time_t (still needed?) */
-#define USES_TYPES /* sys/types is included */
#include "mysys_priv.h"
#include <m_string.h>
#include <my_dir.h> /* Structs used by my_dir,includes sys/types */
@@ -25,9 +24,7 @@
# include <dirent.h>
# define NAMLEN(dirent) strlen((dirent)->d_name)
#else
-#ifndef OS2
# define dirent direct
-#endif
# define NAMLEN(dirent) (dirent)->d_namlen
# if defined(HAVE_SYS_NDIR_H)
# include <sys/ndir.h>
@@ -38,7 +35,7 @@
# if defined(HAVE_NDIR_H)
# include <ndir.h>
# endif
-# if defined(MSDOS) || defined(__WIN__)
+# if defined(__WIN__)
# include <dos.h>
# ifdef __BORLANDC__
# include <dir.h>
@@ -51,10 +48,6 @@
#include <descrip.h>
#endif
-#ifdef OS2
-#include "my_os2dirsrch.h"
-#endif
-
#if defined(THREAD) && defined(HAVE_READDIR_R)
#define READDIR(A,B,C) ((errno=readdir_r(A,B,&C)) != 0 || !C)
#else
@@ -99,7 +92,7 @@ static int comp_names(struct fileinfo *a, struct fileinfo *b)
} /* comp_names */
-#if !defined(MSDOS) && !defined(__WIN__)
+#if !defined(__WIN__)
MY_DIR *my_dir(const char *path, myf MyFlags)
{
@@ -352,7 +345,7 @@ my_string directory_file_name (my_string dst, const char *src)
#endif /* VMS */
} /* directory_file_name */
-#elif defined(WIN32)
+#else
/*
*****************************************************************************
@@ -391,7 +384,7 @@ MY_DIR *my_dir(const char *path, myf MyFlags)
*tmp_file++= '.'; /* From current dev-dir */
if (tmp_file[-1] != FN_LIBCHAR)
*tmp_file++ =FN_LIBCHAR;
- tmp_file[0]='*'; /* MSDOS needs this !??? */
+ tmp_file[0]='*'; /* Windows needs this !??? */
tmp_file[1]='.';
tmp_file[2]='*';
tmp_file[3]='\0';
@@ -514,109 +507,7 @@ error:
DBUG_RETURN((MY_DIR *) NULL);
} /* my_dir */
-#else /* MSDOS and not WIN32 */
-
-
-/******************************************************************************
-** At MSDOS you always get stat of files, but time is in packed MSDOS-format
-******************************************************************************/
-
-MY_DIR *my_dir(const char* path, myf MyFlags)
-{
- char *buffer;
- MY_DIR *result= 0;
- FILEINFO finfo;
- DYNAMIC_ARRAY *dir_entries_storage;
- MEM_ROOT *names_storage;
- struct find_t find;
- ushort mode;
- char tmp_path[FN_REFLEN],*tmp_file,attrib;
- DBUG_ENTER("my_dir");
- DBUG_PRINT("my",("path: '%s' stat: %d MyFlags: %d",path,MyFlags));
-
- /* Put LIB-CHAR as last path-character if not there */
-
- tmp_file=tmp_path;
- if (!*path)
- *tmp_file++ ='.'; /* From current dir */
- tmp_file= strmov(tmp_file,path);
- if (tmp_file[-1] == FN_DEVCHAR)
- *tmp_file++= '.'; /* From current dev-dir */
- if (tmp_file[-1] != FN_LIBCHAR)
- *tmp_file++ =FN_LIBCHAR;
- tmp_file[0]='*'; /* MSDOS needs this !??? */
- tmp_file[1]='.';
- tmp_file[2]='*';
- tmp_file[3]='\0';
-
- if (_dos_findfirst(tmp_path,_A_NORMAL | _A_SUBDIR, &find))
- goto error;
-
- if (!(buffer= my_malloc(ALIGN_SIZE(sizeof(MY_DIR)) +
- ALIGN_SIZE(sizeof(DYNAMIC_ARRAY)) +
- sizeof(MEM_ROOT), MyFlags)))
- goto error;
-
- dir_entries_storage= (DYNAMIC_ARRAY*)(buffer + ALIGN_SIZE(sizeof(MY_DIR)));
- names_storage= (MEM_ROOT*)(buffer + ALIGN_SIZE(sizeof(MY_DIR)) +
- ALIGN_SIZE(sizeof(DYNAMIC_ARRAY)));
-
- if (my_init_dynamic_array(dir_entries_storage, sizeof(FILEINFO),
- ENTRIES_START_SIZE, ENTRIES_INCREMENT))
- {
- my_free((gptr) buffer,MYF(0));
- goto error;
- }
- init_alloc_root(names_storage, NAMES_START_SIZE, NAMES_START_SIZE);
-
- /* MY_DIR structure is allocated and completly initialized at this point */
- result= (MY_DIR*)buffer;
-
- do
- {
- if (!(finfo.name= strdup_root(names_storage, find.name)))
- goto error;
-
- if (MyFlags & MY_WANT_STAT)
- {
- if (!(finfo.mystat= (MY_STAT*)alloc_root(names_storage,
- sizeof(MY_STAT))))
- goto error;
-
- bzero(finfo.mystat, sizeof(MY_STAT));
- finfo.mystat->st_size= find.size;
- mode= MY_S_IREAD; attrib= find.attrib;
- if (!(attrib & _A_RDONLY))
- mode|= MY_S_IWRITE;
- if (attrib & _A_SUBDIR)
- mode|= MY_S_IFDIR;
- finfo.mystat->st_mode= mode;
- finfo.mystat->st_mtime= ((uint32) find.wr_date << 16) + find.wr_time;
- }
- else
- finfo.mystat= NULL;
-
- if (push_dynamic(dir_entries_storage, (gptr)&finfo))
- goto error;
-
- } while (_dos_findnext(&find) == 0);
-
- result->dir_entry= (FILEINFO *)dir_entries_storage->buffer;
- result->number_off_files= dir_entries_storage->elements;
-
- if (!(MyFlags & MY_DONT_SORT))
- qsort((void *) result->dir_entry, result->number_off_files,
- sizeof(FILEINFO), (qsort_cmp) comp_names);
- DBUG_RETURN(result);
-
-error:
- my_dirend(result);
- if (MyFlags & MY_FAE+MY_WME)
- my_error(EE_DIR,MYF(ME_BELL+ME_WAITTANG),path,errno);
- DBUG_RETURN((MY_DIR *) NULL);
-} /* my_dir */
-
-#endif /* WIN32 && MSDOS */
+#endif /* __WIN__ */
/****************************************************************************
** File status
diff --git a/mysys/my_lock.c b/mysys/my_lock.c
index a07f0c072a0..c0522ee849d 100644
--- a/mysys/my_lock.c
+++ b/mysys/my_lock.c
@@ -25,11 +25,6 @@
#ifdef __WIN__
#include <sys/locking.h>
#endif
-#ifdef __EMX__
-#define INCL_BASE
-#define INCL_NOPMAPI
-#include <os2emx.h>
-#endif
#ifdef __NETWARE__
#include <nks/fsio.h>
#endif
@@ -102,11 +97,6 @@ int my_lock(File fd, int locktype, my_off_t start, my_off_t length,
DBUG_RETURN(0);
}
}
-#elif defined(__EMX__) || defined(OS2)
-
- if (!_lock64( fd, locktype, start, length, MyFlags))
- DBUG_RETURN(0);
-
#elif defined(HAVE_LOCKING)
/* Windows */
{
diff --git a/mysys/my_lread.c b/mysys/my_lread.c
deleted file mode 100644
index 1399b197119..00000000000
--- a/mysys/my_lread.c
+++ /dev/null
@@ -1,54 +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 */
-
-#include "mysys_priv.h"
-#include "mysys_err.h"
-
- /* Read a chunk of bytes from a file */
-
-uint32 my_lread(int Filedes, byte *Buffer, uint32 Count, myf MyFlags)
- /* File descriptor */
- /* Buffer must be at least count bytes */
- /* Max number of bytes returnd */
- /* Flags on what to do on error */
-{
- uint32 readbytes;
- DBUG_ENTER("my_lread");
- DBUG_PRINT("my",("Fd: %d Buffer: 0x%lx Count: %lu MyFlags: %d",
- Filedes, (long) Buffer, (ulong) Count, MyFlags));
-
- DBUG_PRINT("error", ("Deprecated my_lread() function should not be used."));
-
- /* Temp hack to get count to int32 while read wants int */
- if ((readbytes = (uint32) read(Filedes, Buffer, (uint) Count)) != Count)
- {
- my_errno=errno;
- if (MyFlags & (MY_WME | MY_FAE | MY_FNABP))
- {
- if (readbytes == MY_FILE_ERROR)
- my_error(EE_READ, MYF(ME_BELL+ME_WAITTANG),
- my_filename(Filedes),errno);
- else
- if (MyFlags & (MY_NABP | MY_FNABP))
- my_error(EE_EOFERR, MYF(ME_BELL+ME_WAITTANG),
- my_filename(Filedes),errno);
- }
- if (readbytes == MY_FILE_ERROR || MyFlags & (MY_NABP | MY_FNABP))
- DBUG_RETURN((uint32) -1); /* Return med felkod */
- }
- if (MyFlags & (MY_NABP | MY_FNABP))
- DBUG_RETURN(0); /* Ok vid l{sning */
- DBUG_RETURN(readbytes);
-} /* my_lread */
diff --git a/mysys/my_lwrite.c b/mysys/my_lwrite.c
deleted file mode 100644
index d26825397e3..00000000000
--- a/mysys/my_lwrite.c
+++ /dev/null
@@ -1,47 +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 */
-
-#include "mysys_priv.h"
-#include "mysys_err.h"
-
- /* Write a chunk of bytes to a file */
-
-uint32 my_lwrite(int Filedes, const byte *Buffer, uint32 Count, myf MyFlags)
-{
- uint32 writenbytes;
- DBUG_ENTER("my_lwrite");
- DBUG_PRINT("my",("Fd: %d Buffer: 0x%lx Count: %lu MyFlags: %d",
- Filedes, (long) Buffer, (ulong) Count, MyFlags));
-
- DBUG_PRINT("error", ("Deprecated my_lwrite() function should not be used."));
-
- /* Temp hack to get count to int32 while write wants int */
- if ((writenbytes = (uint32) write(Filedes, Buffer, (uint) Count)) != Count)
- {
- my_errno=errno;
- if (writenbytes == (uint32) -1 || MyFlags & (MY_NABP | MY_FNABP))
- {
- if (MyFlags & (MY_WME | MY_FAE | MY_FNABP))
- {
- my_error(EE_WRITE, MYF(ME_BELL+ME_WAITTANG),
- my_filename(Filedes),errno);
- }
- DBUG_RETURN((uint32) -1); /* Return med felkod */
- }
- }
- if (MyFlags & (MY_NABP | MY_FNABP))
- DBUG_RETURN(0); /* Ok vid l{sning */
- DBUG_RETURN(writenbytes);
-} /* my_lwrite */
diff --git a/mysys/my_malloc.c b/mysys/my_malloc.c
index 3baf55d4c57..3601a533480 100644
--- a/mysys/my_malloc.c
+++ b/mysys/my_malloc.c
@@ -82,7 +82,7 @@ char *my_strdup(const char *from, myf my_flags)
}
-char *my_strdup_with_length(const char *from, uint length, myf my_flags)
+char *my_strndup(const char *from, uint length, myf my_flags)
{
gptr ptr;
if ((ptr=my_malloc(length+1,my_flags)) != 0)
diff --git a/mysys/my_memmem.c b/mysys/my_memmem.c
index 682a1314f09..9230337409d 100644
--- a/mysys/my_memmem.c
+++ b/mysys/my_memmem.c
@@ -1,4 +1,20 @@
-#include "my_base.h"
+/* 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 */
+
+#include <my_global.h>
+#include <m_string.h>
/*
my_memmem, port of a GNU extension.
diff --git a/mysys/my_mkdir.c b/mysys/my_mkdir.c
index 25176e4b823..676c6c1cd51 100644
--- a/mysys/my_mkdir.c
+++ b/mysys/my_mkdir.c
@@ -26,7 +26,7 @@ int my_mkdir(const char *dir, int Flags, myf MyFlags)
DBUG_ENTER("my_dir");
DBUG_PRINT("enter",("dir: %s",dir));
-#if defined(__WIN__) || defined(OS2)
+#if defined(__WIN__)
if (mkdir((char*) dir))
#else
if (mkdir((char*) dir, Flags & my_umask_dir))
diff --git a/mysys/my_mmap.c b/mysys/my_mmap.c
index 147bdfdcbf2..023a06fd896 100644
--- a/mysys/my_mmap.c
+++ b/mysys/my_mmap.c
@@ -35,22 +35,19 @@ static SECURITY_ATTRIBUTES mmap_security_attributes=
void *my_mmap(void *addr, size_t len, int prot,
int flags, int fd, my_off_t offset)
{
- DWORD flProtect=0;
HANDLE hFileMap;
LPVOID ptr;
HANDLE hFile= (HANDLE)_get_osfhandle(fd);
if (hFile == INVALID_HANDLE_VALUE)
return MAP_FAILED;
- flProtect|=SEC_COMMIT;
-
hFileMap=CreateFileMapping(hFile, &mmap_security_attributes,
PAGE_READWRITE, 0, (DWORD) len, NULL);
if (hFileMap == 0)
return MAP_FAILED;
ptr=MapViewOfFile(hFileMap,
- flags & PROT_WRITE ? FILE_MAP_WRITE : FILE_MAP_READ,
+ prot & PROT_WRITE ? FILE_MAP_WRITE : FILE_MAP_READ,
(DWORD)(offset >> 32), (DWORD)offset, len);
/*
diff --git a/mysys/my_net.c b/mysys/my_net.c
index 136d987f500..81d977210f8 100644
--- a/mysys/my_net.c
+++ b/mysys/my_net.c
@@ -19,7 +19,7 @@
#include <m_string.h>
/* for thread safe my_inet_ntoa */
-#if !defined(MSDOS) && !defined(__WIN__)
+#if !defined(__WIN__)
#include <netdb.h>
#ifdef HAVE_SYS_SOCKET_H
#include <sys/socket.h>
@@ -30,7 +30,7 @@
#ifdef HAVE_ARPA_INET_H
#include <arpa/inet.h>
#endif
-#endif /* !defined(MSDOS) && !defined(__WIN__) */
+#endif /* !defined(__WIN__) */
void my_inet_ntoa(struct in_addr in, char *buf)
{
diff --git a/mysys/my_once.c b/mysys/my_once.c
index d83eba95b9d..fcb5af3ccbd 100644
--- a/mysys/my_once.c
+++ b/mysys/my_once.c
@@ -74,6 +74,8 @@ gptr my_once_alloc(unsigned int Size, myf MyFlags)
point= (gptr) ((char*) next+ (next->size-next->left));
next->left-= Size;
+ if (MyFlags & MY_ZEROFILL)
+ bzero(point, Size);
return(point);
} /* my_once_alloc */
diff --git a/mysys/my_open.c b/mysys/my_open.c
index 2ba84f92ac2..21bdedddc48 100644
--- a/mysys/my_open.c
+++ b/mysys/my_open.c
@@ -13,12 +13,11 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-#define USES_TYPES
#include "mysys_priv.h"
#include "mysys_err.h"
#include <my_dir.h>
#include <errno.h>
-#if defined(MSDOS) || defined(__WIN__) || defined(__EMX__) || defined(OS2)
+#if defined(__WIN__)
#include <share.h>
#endif
@@ -44,7 +43,7 @@ File my_open(const char *FileName, int Flags, myf MyFlags)
DBUG_ENTER("my_open");
DBUG_PRINT("my",("Name: '%s' Flags: %d MyFlags: %d",
FileName, Flags, MyFlags));
-#if defined(MSDOS) || defined(__WIN__) || defined(__EMX__) || defined(OS2)
+#if defined(__WIN__)
/*
Check that we don't try to open or create a file name that may
cause problems for us in the future (like PRN)
@@ -167,9 +166,17 @@ File my_register_filename(File fd, const char *FileName, enum file_type
else
my_errno=errno;
DBUG_PRINT("error",("Got error %d on open",my_errno));
- if (MyFlags & (MY_FFNF | MY_FAE | MY_WME))
- my_error(error_message_number, MYF(ME_BELL+ME_WAITTANG),
+ 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);
+ }
+ }
return(fd);
}
@@ -350,3 +357,24 @@ File my_sopen(const char *path, int oflag, int shflag, int pmode)
return fh; /* return handle */
}
#endif /* __WIN__ */
+
+
+#ifdef EXTRA_DEBUG
+
+void my_print_open_files(void)
+{
+ if (my_file_opened | my_stream_opened)
+ {
+ uint i;
+ for (i= 0 ; i < my_file_limit ; i++)
+ {
+ if (my_file_info[i].type != UNOPEN)
+ {
+ fprintf(stderr, EE(EE_FILE_NOT_CLOSED), my_file_info[i].name, i);
+ fputc('\n', stderr);
+ }
+ }
+ }
+}
+
+#endif
diff --git a/mysys/my_os2cond.c b/mysys/my_os2cond.c
deleted file mode 100644
index f0cf91404d2..00000000000
--- a/mysys/my_os2cond.c
+++ /dev/null
@@ -1,162 +0,0 @@
-/* Copyright (C) Yuri Dario & 2000 MySQL AB
- All the above parties has a full, independent copyright to
- the following code, including the right to use the code in
- any manner without any demands from the other parties.
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; version 2
- of the License.
-
- This library 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
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
-
-/*****************************************************************************
-** The following is a simple implementation of posix conditions
-*****************************************************************************/
-
-#undef SAFE_MUTEX /* Avoid safe_mutex redefinitions */
-#include "mysys_priv.h"
-#if defined(THREAD) && defined(OS2)
-#include <m_string.h>
-#include <process.h>
-#include <sys/timeb.h>
-
-int pthread_cond_init(pthread_cond_t *cond, const pthread_condattr_t *attr)
-{
- cond->waiting= 0;
- /* Warp3 FP29 or Warp4 FP4 or better required */
- if (DosCreateEventSem(NULL, &cond->semaphore, 0x0800, 0))
- return ENOMEM;
- return 0;
-}
-
-int pthread_cond_destroy(pthread_cond_t *cond)
-{
- for (;;)
- {
- APIRET rc;
- if ((rc= DosCloseEventSem(cond->semaphore)) != 301)
- return rc ? EINVAL : 0;
- DosPostEventSem(cond->semaphore);
- }
-}
-
-
-int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex)
-{
- int rval= 0;
- cond->waiting++;
- if (mutex)
- pthread_mutex_unlock(mutex);
- if (DosWaitEventSem(cond->semaphore, SEM_INDEFINITE_WAIT))
- rval= EINVAL;
- if (mutex)
- pthread_mutex_lock(mutex);
- cond->waiting--;
- return rval;
-}
-
-int pthread_cond_timedwait(pthread_cond_t *cond, pthread_mutex_t *mutex,
- struct timespec *abstime)
-{
- struct timeb curtime;
- int result;
- long timeout;
- int rval= 0;
-
- _ftime(&curtime);
- timeout= ((long) (abstime->ts_sec - curtime.time) * 1000L +
- (long) ((abstime->ts_nsec / 1000) - curtime.millitm) / 1000L);
- if (timeout < 0) /* Some safety */
- timeout= 0L;
-
- cond->waiting++;
-
- if (mutex)
- pthread_mutex_unlock(mutex);
- if (DosWaitEventSem(cond->semaphore, timeout) != 0)
- rval= ETIMEDOUT;
- if (mutex)
- pthread_mutex_lock(mutex);
-
- cond->waiting--;
-
- return rval;
-}
-
-
-int pthread_cond_signal(pthread_cond_t *cond)
-{
- /* Bring the next thread off the condition queue: */
- DosPostEventSem(cond->semaphore);
- return 0;
-}
-
-
-int pthread_cond_broadcast(pthread_cond_t *cond)
-{
- int i;
- /* Enter a loop to bring all threads off the condition queue */
- for (i= cond->waiting; i--;)
- DosPostEventSem(cond->semaphore);
- return 0;
-}
-
-
-int pthread_attr_init(pthread_attr_t *connect_att)
-{
- connect_att->dwStackSize= 0;
- connect_att->dwCreatingFlag= 0;
- connect_att->priority= 0;
- return 0;
-}
-
-int pthread_attr_setstacksize(pthread_attr_t *connect_att, DWORD stack)
-{
- connect_att->dwStackSize= stack;
- return 0;
-}
-
-int pthread_attr_setprio(pthread_attr_t *connect_att, int priority)
-{
- connect_att->priority= priority;
- return 0;
-}
-
-int pthread_attr_destroy(pthread_attr_t *connect_att)
-{
- bzero((gptr) connect_att, sizeof(*connect_att));
- return 0;
-}
-
-/****************************************************************************
-** Fix localtime_r() to be a bit safer
-****************************************************************************/
-
-struct tm *localtime_r(const time_t *timep, struct tm *tmp)
-{
- if (*timep == (time_t) - 1) /* This will crash win32 */
- {
- bzero(tmp, sizeof(*tmp));
- }
- else
- {
- struct tm *res= localtime(timep);
- if (!res) /* Wrong date */
- {
- bzero(tmp, sizeof(*tmp)); /* Keep things safe */
- return 0;
- }
- *tmp= *res;
- }
- return tmp;
-}
-#endif /* __WIN__ */
diff --git a/mysys/my_os2dirsrch.c b/mysys/my_os2dirsrch.c
deleted file mode 100644
index 27e774c8e04..00000000000
--- a/mysys/my_os2dirsrch.c
+++ /dev/null
@@ -1,184 +0,0 @@
-/* Copyright (C) Yuri Dario & 2000-2003 MySQL AB
- All the above parties has a full, independent copyright to
- the following code, including the right to use the code in
- any manner without any demands from the other parties.
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; version 2
- of the License.
-
- This library 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
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
-
-
-/* Win32 directory search emulation */
-
-#if defined(OS2)
-
-long _findfirst( char* path, struct _finddata_t* dos_file)
-{
- HDIR hdir = HDIR_CREATE;
- APIRET rc;
- FILEFINDBUF3 buf3;
- ULONG entries = 1;
-
-#ifdef _DEBUG
- printf( "_findfirst path %s\n", path);
-#endif
-
- memset( &buf3, 0, sizeof( buf3));
- rc = DosFindFirst(
- path, /* The ASCIIZ path name of the file or subdirectory to be found. */
- &hdir, /* The handle associated with this DosFindFirst request. */
- FILE_NORMAL | FILE_DIRECTORY, /* Attribute value that determines the file objects to be searched for. */
- &buf3, /* Result buffer. */
- sizeof( buf3), /* The length, in bytes, of pfindbuf. */
- &entries, /* Pointer to the number of entries: */
- FIL_STANDARD); /* The level of file information required. */
-
-#ifdef _DEBUG
- printf( "_findfirst rc=%d hdir=%d entries=%d->%s\n", rc, hdir, entries,
- buf3.achName);
-#endif
-
- if (rc /* && entries == 0 */)
- return -1;
-
- if (dos_file)
- {
- memset( dos_file, 0, sizeof( struct _finddata_t));
- strcpy( dos_file->name, buf3.achName);
- dos_file->size = buf3.cbFile;
- dos_file->attrib = buf3.attrFile;
- }
- return (ULONG) hdir;
-}
-
-
-long _findnext( long hdir, struct _finddata_t* dos_file)
-{
- APIRET rc;
- FILEFINDBUF3 buf3;
- ULONG entries = 1;
-
- memset( &buf3, 0, sizeof( buf3));
- rc = DosFindNext(hdir,
- &buf3, /* Result buffer. */
- sizeof( buf3), /* Length, in bytes, of pfindbuf. */
- &entries); /* Pointer to the number of entries */
-
-#ifdef _DEBUG
- printf( "_findnext rc=%d hdir=%d entries=%d->%s\n", rc, hdir, entries,
- buf3.achName);
-#endif
-
- if (rc /* && entries == 0 */)
- return -1;
-
- if (dos_file)
- {
- memset( dos_file, 0, sizeof( struct _finddata_t));
- strcpy( dos_file->name, buf3.achName);
- dos_file->size = buf3.cbFile;
- dos_file->attrib = buf3.attrFile;
- }
- return 0;
-}
-
-void _findclose( long hdir)
-{
- APIRET rc;
-
- rc = DosFindClose( hdir);
-#ifdef _DEBUG
- printf( "_findclose rc=%d hdir=%d\n", rc, hdir);
-#endif
-}
-
-DIR* opendir(char* path)
-{
- DIR* dir = (DIR*) calloc(1, sizeof( DIR));
- char buffer[260];
- APIRET rc;
- ULONG entries = 1;
-
- strmov(strmov(buffer, path), "*.*");
-
-#ifdef _DEBUG
- printf( "_findfirst path %s\n", buffer);
-#endif
-
- dir->hdir = HDIR_CREATE;
- memset( &dir->buf3, 0, sizeof( dir->buf3));
- rc = DosFindFirst(
- buffer, /* Address of the ASCIIZ path name of the file or subdirectory to be found. */
- &dir->hdir, /* Address of the handle associated with this DosFindFirst request. */
- FILE_NORMAL | FILE_DIRECTORY, /* Attribute value that determines the file objects to be searched for. */
- &dir->buf3, /* Result buffer. */
- sizeof( dir->buf3), /* The length, in bytes, of pfindbuf. */
- &entries, /* Pointer to the number of entries: */
- FIL_STANDARD); /* The level of file information required. */
-
-#ifdef _DEBUG
- printf( "opendir rc=%d hdir=%d entries=%d->%s\n", rc, dir->hdir, entries, dir->buf3.achName);
-#endif
-
- if (rc /* && entries == 0 */)
- return NULL;
-
- return dir;
-}
-
-
-struct dirent* readdir( DIR* dir)
-{
- APIRET rc;
- ULONG entries = 1;
-
- if (!dir->buf3.achName[0]) /* file not found on previous query */
- return NULL;
-
- /* copy last file name */
- strcpy( dir->ent.d_name, dir->buf3.achName);
-
- /* query next file */
- memset( &dir->buf3, 0, sizeof( dir->buf3));
- rc= DosFindNext(
- dir->hdir,
- &dir->buf3, /* Result buffer. */
- sizeof(dir->buf3), /* Length, in bytes, of pfindbuf. */
- &entries); /* Pointer to the number of entries */
-
-#ifdef _DEBUG
- printf( "_findnext rc=%d hdir=%d entries=%d->%s\n", rc, dir->hdir, entries,
- dir->buf3.achName);
-#endif
-
- if (rc /* && entries == 0 */)
- *dir->buf3.achName= 0; /* reset name for next query */
-
- return &dir->ent;
-}
-
-
-int closedir (DIR *dir)
-{
- APIRET rc;
-
- rc = DosFindClose( dir->hdir);
-#ifdef _DEBUG
- printf( "_findclose rc=%d hdir=%d\n", rc, dir->hdir);
-#endif
- free(dir);
- return 0;
-}
-
-#endif /* OS2 */
diff --git a/mysys/my_os2dirsrch.h b/mysys/my_os2dirsrch.h
deleted file mode 100644
index e3af6740769..00000000000
--- a/mysys/my_os2dirsrch.h
+++ /dev/null
@@ -1,88 +0,0 @@
-/* Copyright (C) Yuri Dario & 2000 MySQL AB
- All the above parties has a full, independent copyright to
- the following code, including the right to use the code in
- any manner without any demands from the other parties.
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; version 2
- of the License.
-
- This library 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
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
-
-/* Win32 directory search emulation */
-
-#ifndef __MY_OS2DIRSRCH2_H__
-#define __MY_OS2DIRSRCH2_H__
-
-#ifdef __cplusplus_00
-extern "C" {
-#endif
-
-struct _finddata_t
-{
- unsigned attrib;
-#ifdef NOT_USED
- unsigned long time_create; /* -1 for FAT file systems */
- unsigned long time_access; /* -1 for FAT file systems */
- unsigned long time_write;
-#endif
- unsigned long size;
- char name[260];
-#ifdef NOT_USED
- uint16 wr_date;
- uint16 wr_time;
-#endif
-};
-
-
-struct dirent
-{
-#ifdef NOT_USED
- unsigned attrib;
- unsigned long time_create; /* -1 for FAT file systems */
- unsigned long time_access; /* -1 for FAT file systems */
- unsigned long time_write;
- unsigned long size;
-#endif
- char d_name[260];
-#ifdef NOT_USED
- uint16 wr_date;
- uint16 wr_time;
-#endif
-};
-
-struct DIR
-{
- HDIR hdir;
- FILEFINDBUF3 buf3;
- struct dirent ent;
-};
-
-DIR *opendir ( char *);
-struct dirent *readdir (DIR *);
-int closedir (DIR *);
-
-#ifdef NOT_USED
-#define _A_NORMAL FILE_NORMAL
-#define _A_SUBDIR FILE_DIRECTORY
-#define _A_RDONLY FILE_READONLY
-
-long _findfirst( char*, struct _finddata_t*);
-long _findnext( long, struct _finddata_t*);
-void _findclose( long);
-#endif
-
-#ifdef __cplusplus_00
-}
-#endif
-
-#endif /* __MY_OS2DIRSRCH2_H__ */
diff --git a/mysys/my_os2dlfcn.c b/mysys/my_os2dlfcn.c
deleted file mode 100644
index 74be940d0d4..00000000000
--- a/mysys/my_os2dlfcn.c
+++ /dev/null
@@ -1,74 +0,0 @@
-/* Copyright (C) Yuri Dario & 2000 MySQL AB
- All the above parties has a full, independent copyright to
- the following code, including the right to use the code in
- any manner without any demands from the other parties.
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; version 2
- of the License.
-
- This library 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
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
-
-/*
- * dlfcn::Unix dynamic loading for OS/2
- *
- * Compatibility layer for dynamic loading.
- * Only minimal implementation
- *
-*/
-
-#define RTLD_LAZY 0
-#define RTLD_NOW 0
-
-void* dlopen( char* path, int flag);
-char* dlerror( void);
-void* dlsym( void* hmod, char* fn);
-void dlclose( void* hmod);
-
-char fail[ 256];
-
-void* dlopen( char* path, int flag)
-{
- APIRET rc;
- HMODULE hmod;
-
- rc = DosLoadModule( fail, sizeof( fail), path, &hmod);
- if (rc)
- return NULL;
-
- return (void*) hmod;
-}
-
-char* dlerror( void)
-{
- return fail;
-}
-
-void* dlsym( void* hmod, char* fn)
-{
- APIRET rc;
- PFN addr;
-
- rc = DosQueryProcAddr( (HMODULE) hmod, 0l, fn, &addr);
- if (rc)
- return NULL;
-
- return (void*) addr;
-}
-
-void dlclose( void* hmod)
-{
- APIRET rc;
-
- rc = DosFreeModule( (HMODULE) hmod);
-
-}
diff --git a/mysys/my_os2dlfcn.h0 b/mysys/my_os2dlfcn.h0
deleted file mode 100644
index ec05eebc47b..00000000000
--- a/mysys/my_os2dlfcn.h0
+++ /dev/null
@@ -1,39 +0,0 @@
-/* Copyright (C) Yuri Dario & 2000 MySQL AB
- All the above parties has a full, independent copyright to
- the following code, including the right to use the code in
- any manner without any demands from the other parties.
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; version 2
- of the License.
-
- This library 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
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
-/*
- * dlfcn::Unix dynamic loading for OS/2
- *
- * Compatibility layer for dynamic loading.
- * Only minimal implementation
- *
-*/
-
-#ifndef __DLFCN_H__
-#define __DLFCN_H__
-
-#define RTLD_LAZY 0
-#define RTLD_NOW 0
-
-void* dlopen( char* path, int flag);
-char* dlerror( void);
-void* dlsym( void* hmod, char* fn);
-void dlclose( void* hmod);
-
-#endif
diff --git a/mysys/my_os2file64.c b/mysys/my_os2file64.c
deleted file mode 100644
index 52156903b80..00000000000
--- a/mysys/my_os2file64.c
+++ /dev/null
@@ -1,394 +0,0 @@
-/* Copyright (C) Yuri Dario & 2000 MySQL AB
- All the above parties has a full, independent copyright to
- the following code, including the right to use the code in
- any manner without any demands from the other parties.
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; version 2
- of the License.
-
- This library 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
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
-
-void _OS2errno( APIRET rc);
-longlong _lseek64( int fd, longlong offset, int seektype);
-int _lock64( int fd, int locktype, my_off_t start,
- my_off_t length, myf MyFlags);
-int _sopen64( const char *name, int oflag, int shflag, int mask);
-
-/*
- This class is used to define a global c++ variable, that
- is initialized before main() gets called.
-*/
-
-class File64bit
-{
- public:
- File64bit(); /* default constructor */
-} initFile64bit;
-
-static APIRET (* APIENTRY _DosOpenL)(PCSZ pszFileName,
- PHFILE phf,
- PULONG pulAction,
- LONGLONG cbFile,
- ULONG ulAttribute,
- ULONG fsOpenFlags,
- ULONG fsOpenMode,
- PEAOP2 peaop2);
-static APIRET (* APIENTRY _DosSetFilePtrL)(HFILE hFile,
- LONGLONG ib,
- ULONG method,
- PLONGLONG ibActual);
-static APIRET (* APIENTRY _DosSetFileLocksL)(HFILE hFile,
- PFILELOCKL pflUnlock,
- PFILELOCKL pflLock,
- ULONG timeout,
- ULONG flags);
-
-#define EIO EINVAL
-#define ESPIPE EBADSEEK
-
-
-static unsigned char const errno_tab[] =
-{
- 0 , EINVAL, ENOENT, ENOENT, EMFILE, /* 0..4 */
- EACCES, EBADF, EIO, ENOMEM, EIO, /* 5..9 */
- EINVAL, ENOEXEC,EINVAL, EINVAL, EINVAL, /* 10..14 */
- ENOENT, EBUSY, EXDEV, ENOENT, EROFS, /* 15..19 */
- EIO, EIO, EIO, EIO, EIO, /* 20..24 */
- EIO, EIO, EIO, ENOSPC, EIO, /* 25..29 */
- EIO, EIO, EACCES, EACCES, EIO, /* 30..34 */
- EIO, EIO, EIO, EIO, ENOSPC, /* 35..39 */
- EIO, EIO, EIO, EIO, EIO, /* 40..44 */
- EIO, EIO, EIO, EIO, EIO, /* 45..49 */
- EIO, EIO, EIO, EIO, EBUSY, /* 50..54 */
- EIO, EIO, EIO, EIO, EIO, /* 55..59 */
- EIO, ENOSPC, ENOSPC, EIO, EIO, /* 60..64 */
- EACCES, EIO, EIO, EIO, EIO, /* 65..69 */
- EIO, EIO, EIO, EROFS, EIO, /* 70..74 */
- EIO, EIO, EIO, EIO, EIO, /* 75..79 */
- EEXIST, EIO, ENOENT, EIO, EIO, /* 80..84 */
- EIO, EIO, EINVAL, EIO, EAGAIN, /* 85..89 */
- EIO, EIO, EIO, EIO, EIO, /* 90..94 */
- EINTR, EIO, EIO, EIO, EACCES, /* 95..99 */
- ENOMEM, EINVAL, EINVAL, ENOMEM, EINVAL, /* 100..104 */
- EINVAL, ENOMEM, EIO, EACCES, EPIPE, /* 105..109 */
- ENOENT, E2BIG, ENOSPC, ENOMEM, EBADF, /* 110..114 */
- EINVAL, EINVAL, EINVAL, EINVAL, EINVAL, /* 115..119 */
- EINVAL, EINVAL, EINVAL, ENOENT, EINVAL, /* 120..124 */
- ENOENT, ENOENT, ENOENT, ECHILD, ECHILD, /* 125..129 */
- EACCES, EINVAL, ESPIPE, EINVAL, EINVAL, /* 130..134 */
- EINVAL, EINVAL, EINVAL, EINVAL, EINVAL, /* 135..139 */
- EINVAL, EINVAL, EBUSY, EINVAL, EINVAL, /* 140..144 */
- EINVAL, EINVAL, EINVAL, EBUSY, EINVAL, /* 145..149 */
- EINVAL, EINVAL, ENOMEM, EINVAL, EINVAL, /* 150..154 */
- EINVAL, EINVAL, EINVAL, EINVAL, EINVAL, /* 155..159 */
- EINVAL, EINVAL, EINVAL, EINVAL, EAGAIN, /* 160..164 */
- EINVAL, EINVAL, EACCES, EINVAL, EINVAL, /* 165..169 */
- EBUSY, EINVAL, EINVAL, EINVAL, EINVAL, /* 170..174 */
- EINVAL, EINVAL, EINVAL, EINVAL, EINVAL, /* 175..179 */
- EINVAL, EINVAL, EINVAL, EINVAL, ECHILD, /* 180..184 */
- EINVAL, EINVAL, ENOENT, EINVAL, EINVAL, /* 185..189 */
- ENOEXEC,ENOEXEC,ENOEXEC,ENOEXEC,ENOEXEC, /* 190..194 */
- ENOEXEC,ENOEXEC,ENOEXEC,ENOEXEC,ENOEXEC, /* 195..199 */
- ENOEXEC,ENOEXEC,ENOEXEC,ENOENT, EINVAL, /* 200..204 */
- EINVAL, ENAMETOOLONG, EINVAL, EINVAL, EINVAL, /* 205..209 */
- EINVAL, EINVAL, EACCES, ENOEXEC,ENOEXEC, /* 210..214 */
- EINVAL, EINVAL, EINVAL, EINVAL, EINVAL, /* 215..219 */
- EINVAL, EINVAL, EINVAL, EINVAL, EINVAL, /* 220..224 */
- EINVAL, EINVAL, EINVAL, ECHILD, EINVAL, /* 225..229 */
- EINVAL, EBUSY, EAGAIN, ENOTCONN, EINVAL, /* 230..234 */
- EINVAL, EINVAL, EINVAL, EINVAL, EINVAL, /* 235..239 */
- EINVAL, EINVAL, EINVAL, EINVAL, EINVAL, /* 240..244 */
- EINVAL, EINVAL, EINVAL, EINVAL, EINVAL, /* 245..249 */
- EACCES, EACCES, EINVAL, ENOENT, EINVAL, /* 250..254 */
- EINVAL, EINVAL, EINVAL, EINVAL, EINVAL, /* 255..259 */
- EINVAL, EINVAL, EINVAL, EINVAL, EINVAL, /* 260..264 */
- EINVAL, EINVAL, EINVAL, EINVAL, EINVAL, /* 265..269 */
- EINVAL, EINVAL, EINVAL, EINVAL, EINVAL, /* 270..274 */
- EINVAL, EINVAL, EINVAL, EINVAL, EINVAL, /* 275..279 */
- EINVAL, EINVAL, EINVAL, EINVAL, EEXIST, /* 280..284 */
- EEXIST, EINVAL, EINVAL, EINVAL, EINVAL, /* 285..289 */
- ENOMEM, EMFILE, EINVAL, EINVAL, EINVAL, /* 290..294 */
- EINVAL, EINVAL, EINVAL, EINVAL, EINVAL, /* 295..299 */
- EINVAL, EBUSY, EINVAL, ESRCH, EINVAL, /* 300..304 */
- ESRCH, EINVAL, EINVAL, EINVAL, ESRCH, /* 305..309 */
- EINVAL, ENOMEM, EINVAL, EINVAL, EINVAL, /* 310..314 */
- EINVAL, E2BIG, ENOENT, EIO, EIO, /* 315..319 */
- EINVAL, EINVAL, EINVAL, EINVAL, EAGAIN, /* 320..324 */
- EINVAL, EINVAL, EINVAL, EIO, ENOENT, /* 325..329 */
- EACCES, EACCES, EACCES, ENOENT, ENOMEM /* 330..334 */
-};
-
-/*
- * Initialize 64bit file access: dynamic load of WSeB API
-*/
- File64bit :: File64bit()
-{
- HMODULE hDoscalls;
-
- if (DosQueryModuleHandle("DOSCALLS", &hDoscalls) != NO_ERROR)
- return;
-
- if (DosQueryProcAddr(hDoscalls, 981, NULL, (PFN *)&_DosOpenL) != NO_ERROR)
- return;
-
- if (DosQueryProcAddr(hDoscalls, 988, NULL, (PFN *)&_DosSetFilePtrL) != NO_ERROR) {
- _DosOpenL = NULL;
- return;
- }
-
- if (DosQueryProcAddr(hDoscalls, 986, NULL, (PFN *)&_DosSetFileLocksL) != NO_ERROR) {
- _DosOpenL = NULL;
- _DosSetFilePtrL = NULL;
- return;
- }
- /* notify success */
-#ifdef MYSQL_SERVER
- printf( "WSeB 64bit file API loaded.\n");
-#endif
-}
-
-void _OS2errno( APIRET rc)
-{
- if (rc >= sizeof (errno_tab))
- errno = EINVAL;
- else
- errno = errno_tab[rc];
-}
-
-
-longlong _lseek64( int fd, longlong offset, int seektype)
-{
- APIRET rc;
- longlong actual;
-
- if (_DosSetFilePtrL)
- rc = _DosSetFilePtrL( fd, offset, seektype, &actual);
- else
- {
- ULONG ulActual;
- rc = DosSetFilePtr( fd, (long) offset, seektype, &ulActual);
- actual = ulActual;
- }
-
- if (!rc)
- return( actual); /* NO_ERROR */
-
- _OS2errno( rc); /* set errno */
- return(-1); /* seek failed */
-}
-
-
-inline APIRET _SetFileLocksL(HFILE hFile,
- PFILELOCKL pflUnlock,
- PFILELOCKL pflLock,
- ULONG timeout,
- ULONG flags)
-{
- if (_DosSetFileLocksL)
- {
- APIRET rc;
- rc = _DosSetFileLocksL( hFile, pflUnlock, pflLock, timeout, flags);
-
- /*
- on FAT/HPFS/LAN a INVALID_PARAMETER is returned, seems that
- only JFS can handle >2GB ranges.
- */
- if (rc != 87)
- return rc;
- /* got INVALID_PARAMETER, fallback to standard call */
- }
-
- FILELOCK flUnlock = { pflUnlock->lOffset, pflUnlock->lRange };
- FILELOCK flLock = { pflLock->lOffset, pflLock->lRange };
- return DosSetFileLocks( hFile, &flUnlock, &flLock, timeout, flags);
-}
-
-
-int _lock64( int fd, int locktype, my_off_t start,
- my_off_t length, myf MyFlags)
-{
- FILELOCKL LockArea = {0,0}, UnlockArea = {0,0};
- ULONG readonly = 0;
- APIRET rc = -1;
-
- switch (locktype) {
- case F_UNLCK:
- UnlockArea.lOffset = start;
- UnlockArea.lRange = length ? length : LONGLONG_MAX;
- break;
-
- case F_RDLCK:
- case F_WRLCK:
- LockArea.lOffset = start;
- LockArea.lRange = length ? length : LONGLONG_MAX;
- readonly = (locktype == F_RDLCK ? 1 : 0);
- break;
-
- default:
- errno = EINVAL;
- rc = -1;
- break;
- }
-
- if (MyFlags & MY_DONT_WAIT)
- {
- rc = _SetFileLocksL( fd, &UnlockArea, &LockArea, 0, readonly);
- /* printf("fd %d, locktype %d, rc %d (dont_wait)\n", fd, locktype, rc); */
- if (rc == 33) { /* Lock Violation */
-
- DBUG_PRINT("info",("Was locked, trying with timeout"));
- rc = _SetFileLocksL( fd, &UnlockArea, &LockArea, 1 * 1000, readonly);
- /* printf( "fd %d, locktype %d, rc %d (dont_wait with timeout)\n", fd, locktype, rc); */
- }
- }
- else
- {
- while (rc = _SetFileLocksL( fd, &UnlockArea, &LockArea, 0, readonly) &&
- (rc == 33))
- {
- printf(".");
- DosSleep(1 * 1000);
- }
- /* printf( "fd %d, locktype %d, rc %d (wait2)\n", fd, locktype, rc); */
- }
- if (!rc)
- return(0); /* NO_ERROR */
- _OS2errno( rc); /* set errno */
- return(-1); /* lock failed */
-}
-
-
-int sopen(const char *name, int oflag, int shflag, int mask)
-{
- int fail_errno;
- APIRET rc = 0;
- HFILE hf = 0;
- ULONG ulAction = 0;
- LONGLONG cbFile = 0;
- ULONG ulAttribute = FILE_NORMAL;
- ULONG fsOpenFlags = 0;
- ULONG fsOpenMode = 0;
-
- /* Extract the access mode and sharing mode bits. */
- fsOpenMode = (shflag & 0xFF) | (oflag & 0x03);
-
- /*
- Translate ERROR_OPEN_FAILED to ENOENT unless O_EXCL is set (see
- below).
- */
- fail_errno = ENOENT;
-
- /*
- Compute `open_flag' depending on `flags'. Note that _SO_CREAT is
- set for O_CREAT.
- */
-
- if (oflag & O_CREAT)
- {
- if (oflag & O_EXCL)
- {
- fsOpenFlags = OPEN_ACTION_FAIL_IF_EXISTS | OPEN_ACTION_CREATE_IF_NEW;
- fail_errno = EEXIST;
- }
- else if (oflag & O_TRUNC)
- fsOpenFlags = OPEN_ACTION_REPLACE_IF_EXISTS | OPEN_ACTION_CREATE_IF_NEW;
- else
- fsOpenFlags = OPEN_ACTION_OPEN_IF_EXISTS | OPEN_ACTION_CREATE_IF_NEW;
-
- if (mask & S_IWRITE)
- ulAttribute = FILE_NORMAL;
- else
- ulAttribute = FILE_READONLY;
-
- }
- else if (oflag & O_TRUNC)
- fsOpenFlags = OPEN_ACTION_REPLACE_IF_EXISTS | OPEN_ACTION_FAIL_IF_NEW;
- else
- fsOpenFlags = OPEN_ACTION_OPEN_IF_EXISTS | OPEN_ACTION_FAIL_IF_NEW;
-
- /* Try to open the file and handle errors. */
- if (_DosOpenL)
- rc = _DosOpenL( name, &hf, &ulAction, cbFile,
- ulAttribute, fsOpenFlags, fsOpenMode, NULL);
- else
- rc = DosOpen( name, &hf, &ulAction, (LONG) cbFile,
- ulAttribute, fsOpenFlags, fsOpenMode, NULL);
-
- if (rc == ERROR_OPEN_FAILED)
- {
- errno = fail_errno;
- return -1;
- }
- if (rc != 0)
- {
- _OS2errno( rc); /* set errno */
- return -1;
- }
- if (oflag & O_APPEND)
- _lseek64( hf, 0L, SEEK_END);
- return hf;
-}
-
-
-int read(int fd, void *buffer, unsigned int count)
-{
- APIRET rc;
- ULONG actual;
-
- rc= DosRead( fd, (PVOID) buffer, count, &actual);
-
- if (!rc)
- return( actual); /* NO_ERROR */
- _OS2errno( rc); /* set errno */
- return(-1); /* read failed */
-}
-
-
-int write(int fd, const void *buffer, unsigned int count)
-{
- APIRET rc;
- ULONG actual;
-
- rc = DosWrite( fd, (PVOID) buffer, count, &actual);
-
- if (!rc)
- return( actual); /* NO_ERROR */
- _OS2errno( rc); /* set errno */
- return(-1); /* write failed */
-}
-
-
-int close( int fd)
-{
- APIRET rc;
- ULONG actual;
-
- rc = DosClose( fd);
-
- if (!rc)
- return( 0); /* NO_ERROR */
- _OS2errno( rc); /* set errno */
- return(-1); /* close failed */
-}
-
-
-int open( const char *name, int oflag)
-{
- return sopen( name, oflag, OPEN_SHARE_DENYNONE, S_IREAD | S_IWRITE);
-}
-
-
-int open( const char *name, int oflag, int mask)
-{
- return sopen( name, oflag, OPEN_SHARE_DENYNONE, mask);
-}
diff --git a/mysys/my_os2mutex.c b/mysys/my_os2mutex.c
deleted file mode 100644
index 5010d6e8dd5..00000000000
--- a/mysys/my_os2mutex.c
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * Copyright (c) 1995 John Birrell <jb@cimlogic.com.au>.
- * All rights reserved.
- *
- * Modified and extended by Antony T Curtis <antony.curtis@olcs.net>
- * for use with OS/2.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by John Birrell.
- * 4. Neither the name of the author nor the names of any co-contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- */
-#include <stdlib.h>
-#include <errno.h>
-#ifdef _THREAD_SAFE
-
-int
-pthread_mutex_init(pthread_mutex_t * mutex,
- const pthread_mutexattr_t * mutex_attr)
-{
- (void) DosCreateMutexSem(NULL,mutex,0,0);
- return (0); /* Return the completion status: */
-}
-
-
-int
-pthread_mutex_destroy(pthread_mutex_t * mutex)
-{
- APIRET rc;
-
- do
- {
- rc = DosCloseMutexSem(*mutex);
- if (rc == 301) DosReleaseMutexSem(*mutex);
- } while (rc == 301);
-
- *mutex = 0;
- return (0); /* Return the completion status: */
-}
-
-
-int
-pthread_mutex_lock(pthread_mutex_t * mutex)
-{
- APIRET rc;
-
- rc = DosRequestMutexSem(*mutex,SEM_INDEFINITE_WAIT);
- if (rc)
- return(EINVAL);
- return (0); /* Return the completion status: */
-}
-
-
-int
-pthread_mutex_unlock(pthread_mutex_t * mutex)
-{
- (void) DosReleaseMutexSem(*mutex);
- return (0); /* Return the completion status: */
-}
-#endif
diff --git a/mysys/my_os2thread.c b/mysys/my_os2thread.c
deleted file mode 100644
index e34fd18d596..00000000000
--- a/mysys/my_os2thread.c
+++ /dev/null
@@ -1,128 +0,0 @@
-/* Copyright (C) Yuri Dario & 2000 MySQL AB
- All the above parties has a full, independent copyright to
- the following code, including the right to use the code in
- any manner without any demands from the other parties.
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; version 2
- of the License.
-
- This library 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
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
-
-/*****************************************************************************
-** Simulation of posix threads calls for OS/2
-*****************************************************************************/
-
-#include "mysys_priv.h"
-#if defined(THREAD) && defined(OS2)
-#include <m_string.h>
-#include <process.h>
-
-static pthread_mutex_t THR_LOCK_thread;
-
-struct pthread_map
-{
- HANDLE pthreadself;
- pthread_handler func;
- void * param;
-};
-
-void win_pthread_init(void)
-{
- pthread_mutex_init(&THR_LOCK_thread,NULL);
-}
-
-/*
-** We have tried to use '_beginthreadex' instead of '_beginthread' here
-** but in this case the program leaks about 512 characters for each
-** created thread !
-** As we want to save the created thread handler for other threads to
-** use and to be returned by pthread_self() (instead of the Win32 pseudo
-** handler), we have to go trough pthread_start() to catch the returned handler
-** in the new thread.
-*/
-
-pthread_handler_t pthread_start(void *param)
-{
- DBUG_ENTER("pthread_start");
- pthread_handler func=((struct pthread_map *) param)->func;
- void *func_param=((struct pthread_map *) param)->param;
- my_thread_init(); /* Will always succeed in windows */
- pthread_mutex_lock(&THR_LOCK_thread); /* Wait for beginthread to return */
- win_pthread_self=((struct pthread_map *) param)->pthreadself;
- pthread_mutex_unlock(&THR_LOCK_thread);
- free((char*) param); /* Free param from create */
- /* pthread_exit((void*) (*func)(func_param)); */
- (*func)(func_param);
- DBUG_RETURN(0);
-}
-
-
-int pthread_create(pthread_t *thread_id, pthread_attr_t *attr,
- pthread_handler func, void *param)
-{
- HANDLE hThread;
- struct pthread_map *map;
- DBUG_ENTER("pthread_create");
-
- if (!(map=(struct pthread_map *)malloc(sizeof(*map))))
- DBUG_RETURN(-1);
- map->func=func;
- map->param=param;
- pthread_mutex_lock(&THR_LOCK_thread);
-#ifdef __BORLANDC__
- hThread=(HANDLE)_beginthread((void(_USERENTRY *)(void *)) pthread_start,
- attr->dwStackSize ? attr->dwStackSize :
- 65535, (void*) map);
-#elif defined( OS2)
- hThread=(HANDLE)_beginthread((void( _Optlink *)(void *)) pthread_start, NULL,
- attr->dwStackSize ? attr->dwStackSize :
- 65535, (void*) map);
-#else
- hThread=(HANDLE)_beginthread((void( __cdecl *)(void *)) pthread_start,
- attr->dwStackSize ? attr->dwStackSize :
- 65535, (void*) map);
-#endif
- DBUG_PRINT("info", ("hThread=%lu",(long) hThread));
- *thread_id=map->pthreadself=hThread;
- pthread_mutex_unlock(&THR_LOCK_thread);
-
- if (hThread == (HANDLE) -1)
- {
- int error=errno;
- DBUG_PRINT("error",
- ("Can't create thread to handle request (error %d)",error));
- DBUG_RETURN(error ? error : -1);
- }
-#ifdef OS2
- my_pthread_setprio(hThread, attr->priority);
-#else
- VOID(SetThreadPriority(hThread, attr->priority)) ;
-#endif
- DBUG_RETURN(0);
-}
-
-
-void pthread_exit(void *a)
-{
- _endthread();
-}
-
-/* This is neaded to get the macro pthread_setspecific to work */
-
-int win_pthread_setspecific(void *a,void *b,uint length)
-{
- memcpy(a,b,length);
- return 0;
-}
-
-#endif
diff --git a/mysys/my_os2tls.c b/mysys/my_os2tls.c
deleted file mode 100644
index 49100c65516..00000000000
--- a/mysys/my_os2tls.c
+++ /dev/null
@@ -1,151 +0,0 @@
-/* Copyright (C) Yuri Dario & 2000 MySQL AB
- All the above parties has a full, independent copyright to
- the following code, including the right to use the code in
- any manner without any demands from the other parties.
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; version 2
- of the License.
-
- This library 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
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
-
-DWORD TlsAlloc( void);
-BOOL TlsFree( DWORD);
-PVOID TlsGetValue( DWORD);
-BOOL TlsSetValue( DWORD, PVOID);
-
-#define TLS_MINIMUM_AVAILABLE 64
-
-
-PULONG tls_storage; /* TLS local storage */
-DWORD tls_bits[2]; /* TLS in-use bits */
-pthread_mutex_t tls_mutex; /* TLS mutex for in-use bits */
-
-
-DWORD TlsAlloc( void)
-{
- DWORD index = -1;
- DWORD mask, tibidx;
- int i;
-
- if (tls_storage == NULL)
- {
-
- APIRET rc;
-
- /* allocate memory for TLS storage */
- rc = DosAllocThreadLocalMemory( 1, &tls_storage);
- if (rc)
- fprintf( stderr, "DosAllocThreadLocalMemory error: return code = %u\n",
- rc);
- /* create a mutex */
- if (pthread_mutex_init( &tls_mutex, NULL))
- fprintf( stderr, "Failed to init TLS mutex\n");
- }
-
- pthread_mutex_lock( &tls_mutex);
-
- tibidx = 0;
- if (tls_bits[0] == 0xFFFFFFFF)
- {
- if (tls_bits[1] == 0xFFFFFFFF)
- {
- fprintf( stderr, "tid#%d, no more TLS bits available\n", _threadid);
- pthread_mutex_unlock( &tls_mutex);
- return -1;
- }
- tibidx = 1;
- }
-
- for (i=0; i<32; i++)
- {
- mask = (1 << i);
- if ((tls_bits[ tibidx] & mask) == 0)
- {
- tls_bits[ tibidx] |= mask;
- index = (tibidx*32) + i;
- break;
- }
- }
- tls_storage[index] = 0;
-
- pthread_mutex_unlock( &tls_mutex);
- /* fprintf( stderr, "tid#%d, TlsAlloc index %d\n", _threadid, index); */
- return index;
-}
-
-BOOL TlsFree( DWORD index)
-{
- int tlsidx;
- DWORD mask;
-
- if (index >= TLS_MINIMUM_AVAILABLE)
- return NULL;
-
- pthread_mutex_lock( &tls_mutex);
-
- tlsidx = 0;
- if (index > 32)
- tlsidx++;
-
- mask = (1 << index);
- if (tls_bits[ tlsidx] & mask)
- {
- tls_bits[tlsidx] &= ~mask;
- tls_storage[index] = 0;
- pthread_mutex_unlock( &tls_mutex);
- return TRUE;
- }
-
- pthread_mutex_unlock( &tls_mutex);
- return FALSE;
-}
-
-
-PVOID TlsGetValue( DWORD index)
-{
- if (index >= TLS_MINIMUM_AVAILABLE)
- return NULL;
-
- /* verify if memory has been allocated for this thread */
- if (*tls_storage == NULL)
- {
- /* allocate memory for indexes */
- *tls_storage = (ULONG)calloc( TLS_MINIMUM_AVAILABLE, sizeof(int));
- /* fprintf(stderr, "tid#%d, tls_storage %x\n", _threadid, *tls_storage); */
- }
-
- ULONG* tls_array = (ULONG*) *tls_storage;
- return (PVOID) tls_array[index];
-}
-
-
-BOOL TlsSetValue( DWORD index, PVOID val)
-{
-
- /* verify if memory has been allocated for this thread */
- if (*tls_storage == NULL)
- {
- /* allocate memory for indexes */
- *tls_storage = (ULONG)calloc( TLS_MINIMUM_AVAILABLE, sizeof(int));
- /* fprintf(stderr, "tid#%d, tls_storage %x\n", _threadid, *tls_storage); */
- }
-
- if (index >= TLS_MINIMUM_AVAILABLE)
- return FALSE;
-
- ULONG* tls_array = (ULONG*) *tls_storage;
- /* fprintf( stderr, "tid#%d, TlsSetValue array %08x index %d -> %08x (old)\n", _threadid, tls_array, index, tls_array[ index]); */
- tls_array[ index] = (ULONG) val;
- /* fprintf( stderr, "tid#%d, TlsSetValue array %08x index %d -> %08x\n", _threadid, tls_array, index, val); */
- return TRUE;
-}
diff --git a/mysys/my_pread.c b/mysys/my_pread.c
index 2d42a6ebbc4..7a09c21e039 100644
--- a/mysys/my_pread.c
+++ b/mysys/my_pread.c
@@ -26,7 +26,7 @@ uint my_pread(File Filedes, byte *Buffer, uint Count, my_off_t offset,
myf MyFlags)
{
uint readbytes;
- int error;
+ int error= 0;
DBUG_ENTER("my_pread");
DBUG_PRINT("my",("Fd: %d Seek: %lu Buffer: 0x%lx Count: %u MyFlags: %d",
Filedes, (ulong) offset, (long) Buffer, Count, MyFlags));
@@ -37,17 +37,40 @@ uint my_pread(File Filedes, byte *Buffer, uint Count, my_off_t offset,
errno=0; /* Linux doesn't reset this */
#endif
#ifndef HAVE_PREAD
+ off_t old_offset;
+
pthread_mutex_lock(&my_file_info[Filedes].mutex);
- readbytes= (uint) -1;
- error= (lseek(Filedes, offset, MY_SEEK_SET) == -1L ||
- (readbytes = (uint) read(Filedes, Buffer, Count)) != Count);
+ /*
+ As we cannot change the file pointer, we save the old position,
+ before seeking to the given offset
+ */
+
+ error= (old_offset= (off_t)lseek(Filedes, 0L, MY_SEEK_CUR)) == -1L ||
+ lseek(Filedes, offset, MY_SEEK_SET) == -1L;
+
+ if (!error) /* Seek was successful */
+ {
+ if ((readbytes = (uint) read(Filedes, Buffer, Count)) == -1L)
+ my_errno= errno;
+
+ /*
+ We should seek back, even if read failed. If this fails,
+ we will return an error. If read failed as well, we will
+ save the errno from read, not from lseek().
+ */
+ if ((error= (lseek(Filedes, old_offset, MY_SEEK_SET) == -1L)) &&
+ readbytes != -1L)
+ my_errno= errno;
+ }
+
pthread_mutex_unlock(&my_file_info[Filedes].mutex);
#else
- error=((readbytes = (uint) pread(Filedes, Buffer, Count, offset)) != Count);
+ if ((error= ((readbytes =
+ (uint) pread(Filedes, Buffer, Count, offset)) != Count)))
+ my_errno= errno;
#endif
- if (error)
+ if (error || readbytes != Count)
{
- my_errno=errno;
DBUG_PRINT("warning",("Read only %d bytes off %u from %d, errno: %d",
(int) readbytes, Count,Filedes,my_errno));
#ifdef THREAD
@@ -92,17 +115,41 @@ uint my_pwrite(int Filedes, const byte *Buffer, uint Count, my_off_t offset,
for (;;)
{
#ifndef HAVE_PREAD
- int error;
+ int error= 0;
+ off_t old_offset;
writenbytes= (uint) -1;
pthread_mutex_lock(&my_file_info[Filedes].mutex);
- error=(lseek(Filedes, offset, MY_SEEK_SET) != -1L &&
- (writenbytes = (uint) write(Filedes, Buffer, Count)) == Count);
+
+ /*
+ As we cannot change the file pointer, we save the old position,
+ before seeking to the given offset
+ */
+ error= ((old_offset= (off_t)lseek(Filedes, 0L, MY_SEEK_CUR)) == -1L ||
+ lseek(Filedes, offset, MY_SEEK_SET) == -1L);
+
+ if (!error) /* Seek was successful */
+ {
+ if ((writenbytes = (uint) write(Filedes, Buffer, Count)) == -1L)
+ my_errno= errno;
+
+ /*
+ We should seek back, even if write failed. If this fails,
+ we will return an error. If write failed as well, we will
+ save the errno from write, not from lseek().
+ */
+ if ((error= (lseek(Filedes, old_offset, MY_SEEK_SET) == -1L)) &&
+ writenbytes != -1L)
+ my_errno= errno;
+ }
pthread_mutex_unlock(&my_file_info[Filedes].mutex);
- if (error)
+
+ if (!error && writenbytes == Count)
break;
#else
if ((writenbytes = (uint) pwrite(Filedes, Buffer, Count,offset)) == Count)
break;
+ else
+ my_errno= errno;
#endif
if ((int) writenbytes != -1)
{ /* Safegueard */
@@ -111,7 +158,6 @@ uint my_pwrite(int Filedes, const byte *Buffer, uint Count, my_off_t offset,
Count-=writenbytes;
offset+=writenbytes;
}
- my_errno=errno;
DBUG_PRINT("error",("Write only %d bytes",writenbytes));
#ifndef NO_BACKGROUND
#ifdef THREAD
diff --git a/mysys/my_pthread.c b/mysys/my_pthread.c
index fe3480ea10f..844112991f6 100644
--- a/mysys/my_pthread.c
+++ b/mysys/my_pthread.c
@@ -23,7 +23,7 @@
#include <m_string.h>
#include <thr_alarm.h>
-#if (defined(__BSD__) || defined(_BSDI_VERSION)) && !defined(HAVE_mit_thread)
+#if (defined(__BSD__) || defined(_BSDI_VERSION))
#define SCHED_POLICY SCHED_RR
#else
#define SCHED_POLICY SCHED_OTHER
@@ -75,9 +75,6 @@ void my_pthread_attr_setprio(pthread_attr_t *attr, int priority)
#ifdef HAVE_NONPOSIX_PTHREAD_GETSPECIFIC
#undef pthread_getspecific
-#ifdef HAVE_UNIXWARE7_THREADS
-#define pthread_getspecific thr_getspecific
-#endif
void *my_pthread_getspecific_imp(pthread_key_t key)
{
@@ -189,7 +186,7 @@ struct tm *gmtime_r(const time_t *clock, struct tm *res)
** Author: Gary Wisniewski <garyw@spidereye.com.au>, much modified by Monty
****************************************************************************/
-#if !defined(HAVE_SIGWAIT) && !defined(HAVE_mit_thread) && !defined(sigwait) && !defined(__WIN__) && !defined(HAVE_rts_threads) && !defined(HAVE_NONPOSIX_SIGWAIT) && !defined(HAVE_DEC_3_2_THREADS) && !defined(OS2)
+#if !defined(HAVE_SIGWAIT) && !defined(sigwait) && !defined(__WIN__) && !defined(HAVE_rts_threads) && !defined(HAVE_NONPOSIX_SIGWAIT) && !defined(HAVE_DEC_3_2_THREADS)
#if !defined(DONT_USE_SIGSUSPEND)
@@ -428,7 +425,7 @@ int sigwait(sigset_t *setp, int *sigp)
** Patches for AIX and DEC OSF/1 3.2
*****************************************************************************/
-#if (defined(HAVE_NONPOSIX_PTHREAD_MUTEX_INIT) && !defined(HAVE_UNIXWARE7_THREADS)) || defined(HAVE_DEC_3_2_THREADS)
+#if defined(HAVE_NONPOSIX_PTHREAD_MUTEX_INIT)
#include <netdb.h>
diff --git a/mysys/my_redel.c b/mysys/my_redel.c
index 1e3cfceb495..606d301e1d0 100644
--- a/mysys/my_redel.c
+++ b/mysys/my_redel.c
@@ -13,7 +13,6 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-#define USES_TYPES /* sys/types is included */
#include "mysys_priv.h"
#include <my_dir.h>
#include <m_string.h>
@@ -89,14 +88,14 @@ int my_copystat(const char *from, const char *to, int MyFlags)
return 1;
VOID(chmod(to, statbuf.st_mode & 07777)); /* Copy modes */
-#if !defined(MSDOS) && !defined(__WIN__) && !defined(__EMX__) && !defined(OS2) && !defined(__NETWARE__)
+#if !defined(__WIN__) && !defined(__NETWARE__)
if (statbuf.st_nlink > 1 && MyFlags & MY_LINK_WARNING)
{
if (MyFlags & MY_LINK_WARNING)
my_error(EE_LINK_WARNING,MYF(ME_BELL+ME_WAITTANG),from,statbuf.st_nlink);
}
VOID(chown(to, statbuf.st_uid, statbuf.st_gid)); /* Copy ownership */
-#endif /* MSDOS */
+#endif /* !__WIN__ && !__NETWARE__ */
#ifndef VMS
#ifndef __ZTC__
diff --git a/mysys/my_rename.c b/mysys/my_rename.c
index c4aeb95b2c0..6a6aa6a5796 100644
--- a/mysys/my_rename.c
+++ b/mysys/my_rename.c
@@ -13,7 +13,6 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-#define USES_TYPES
#include "mysys_priv.h"
#include <my_dir.h>
#include "mysys_err.h"
diff --git a/mysys/my_seek.c b/mysys/my_seek.c
index fd2344e0d36..e59e205b5f3 100644
--- a/mysys/my_seek.c
+++ b/mysys/my_seek.c
@@ -43,7 +43,7 @@
my_off_t my_seek(File fd, my_off_t pos, int whence,
myf MyFlags __attribute__((unused)))
{
- reg1 os_off_t newpos;
+ reg1 os_off_t newpos= -1;
DBUG_ENTER("my_seek");
DBUG_PRINT("my",("Fd: %d Hpos: %lu Pos: %lu Whence: %d MyFlags: %d",
fd, (ulong) (((ulonglong) pos) >> 32), (ulong) pos,
diff --git a/mysys/my_sleep.c b/mysys/my_sleep.c
index 50e6fae17fc..87170e4af41 100644
--- a/mysys/my_sleep.c
+++ b/mysys/my_sleep.c
@@ -24,8 +24,6 @@ void my_sleep(ulong m_seconds)
delay(m_seconds/1000+1);
#elif defined(__WIN__)
Sleep(m_seconds/1000+1); /* Sleep() has millisecond arg */
-#elif defined(OS2)
- DosSleep(m_seconds/1000+1);
#elif defined(HAVE_SELECT)
struct timeval t;
t.tv_sec= m_seconds / 1000000L;
diff --git a/mysys/my_static.c b/mysys/my_static.c
index 694e5058bb0..95521c49ab7 100644
--- a/mysys/my_static.c
+++ b/mysys/my_static.c
@@ -18,7 +18,7 @@
a shared library
*/
-#if !defined(stdin) || defined(OS2)
+#if !defined(stdin)
#include "mysys_priv.h"
#include "my_static.h"
#include "my_alarm.h"
@@ -91,13 +91,6 @@ struct st_irem *sf_malloc_root = NULL;
int volatile my_have_got_alarm=0; /* declare variable to reset */
ulong my_time_to_wait_for_lock=2; /* In seconds */
- /*
- We need to have this define here as otherwise linking will fail
- on OSF1 when compiling --without-raid --with-debug
- */
-
-const char *raid_type_string[]={"none","striped"};
-
/* from errors.c */
#ifdef SHARED_LIBRARY
char * NEAR globerrs[GLOBERRS]; /* my_error_messages is here */
diff --git a/mysys/my_symlink2.c b/mysys/my_symlink2.c
index 2ad08ef67de..279672be11c 100644
--- a/mysys/my_symlink2.c
+++ b/mysys/my_symlink2.c
@@ -33,9 +33,11 @@ File my_create_with_symlink(const char *linkname, const char *filename,
int create_link;
char abs_linkname[FN_REFLEN];
DBUG_ENTER("my_create_with_symlink");
+ DBUG_PRINT("enter", ("linkname: %s filename: %s", linkname, filename));
if (my_disable_symlinks)
{
+ DBUG_PRINT("info", ("Symlinks disabled"));
/* Create only the file, not the link and file */
create_link= 0;
if (linkname)
diff --git a/mysys/my_thr_init.c b/mysys/my_thr_init.c
index b44e5ced99f..d83aa95b0ef 100644
--- a/mysys/my_thr_init.c
+++ b/mysys/my_thr_init.c
@@ -269,12 +269,12 @@ void my_thread_end(void)
tmp->dbug=0;
}
#endif
-#if !defined(__bsdi__) && !defined(__OpenBSD__) || defined(HAVE_mit_thread)
+#if !defined(__bsdi__) && !defined(__OpenBSD__)
/* bsdi and openbsd 3.5 dumps core here */
pthread_cond_destroy(&tmp->suspend);
#endif
pthread_mutex_destroy(&tmp->mutex);
-#if (!defined(__WIN__) && !defined(OS2)) || defined(USE_TLS)
+#if !defined(__WIN__) || defined(USE_TLS)
free(tmp);
#else
tmp->init= 0;
@@ -293,7 +293,7 @@ void my_thread_end(void)
pthread_mutex_unlock(&THR_LOCK_threads);
}
/* The following free has to be done, even if my_thread_var() is 0 */
-#if (!defined(__WIN__) && !defined(OS2)) || defined(USE_TLS)
+#if !defined(__WIN__) || defined(USE_TLS)
pthread_setspecific(THR_KEY_mysys,0);
#endif
}
@@ -324,7 +324,7 @@ long my_thread_id()
{
#if defined(HAVE_PTHREAD_GETSEQUENCE_NP)
return pthread_getsequence_np(pthread_self());
-#elif (defined(__sun) || defined(__sgi) || defined(__linux__)) && !defined(HAVE_mit_thread)
+#elif (defined(__sun) || defined(__sgi) || defined(__linux__))
return pthread_self();
#else
return my_thread_var->id;
diff --git a/mysys/my_vle.c b/mysys/my_vle.c
new file mode 100644
index 00000000000..5b93ba69bd9
--- /dev/null
+++ b/mysys/my_vle.c
@@ -0,0 +1,112 @@
+/*
+ Copyright (C) 2005 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
+*/
+
+/*
+ Variable length encoding.
+
+ A method to store an arbitrary-size non-negative integer. We let the
+ most significant bit of the number indicate that the next byte
+ should be contatenated to form the real number.
+*/
+
+#include "my_vle.h"
+
+/*
+ Function to encode an unsigned long as VLE. The bytes for the VLE
+ will be written to the location pointed to by 'out'. The maximum
+ number of bytes written will be 'max'.
+
+ PARAMETERS
+
+ out Pointer to beginning of where to store VLE bytes.
+ max Maximum number of bytes to write.
+ n Number to encode.
+
+ RETURN VALUE
+ On success, one past the end of the array containing the VLE
+ bytes. On failure, the 'out' pointer is returned.
+*/
+
+byte*
+my_vle_encode(byte* out, my_size_t max, ulong n)
+{
+ byte buf[my_vle_sizeof(n)];
+ byte *ptr= buf;
+ my_size_t len;
+
+ do
+ {
+ *ptr++= (byte) (n & 0x7F);
+ n>>= 7;
+ }
+ while (n > 0);
+
+ len= ptr - buf;
+
+ if (len <= max)
+ {
+ /*
+ The bytes are stored in reverse order in 'buf'. Let's write them
+ in correct order to the output buffer and set the MSB at the
+ same time.
+ */
+ while (ptr-- > buf)
+ {
+ byte v= *ptr;
+ if (ptr > buf)
+ v|= 0x80;
+ *out++= v;
+ }
+ }
+
+ return out;
+}
+
+/*
+ Function to decode a VLE representation of an integral value.
+
+
+ PARAMETERS
+
+ result_ptr Pointer to an unsigned long where the value will be written.
+ vle Pointer to the VLE bytes.
+
+ RETURN VALUE
+
+ One-past the end of the VLE bytes. The routine will never read
+ more than sizeof(*result_ptr) + 1 bytes.
+*/
+
+byte const*
+my_vle_decode(ulong *result_ptr, byte const *vle)
+{
+ ulong result= 0;
+ my_size_t cnt= 1;
+
+ do
+ {
+ result<<= 7;
+ result|= (*vle & 0x7F);
+ }
+ while ((*vle++ & 0x80) && ++cnt <= sizeof(*result_ptr) + 1);
+
+ if (cnt <= sizeof(*result_ptr) + 1)
+ *result_ptr= result;
+
+ return vle;
+}
diff --git a/mysys/mysys_priv.h b/mysys/mysys_priv.h
index 8a636e94626..709cfed969a 100644
--- a/mysys/mysys_priv.h
+++ b/mysys/mysys_priv.h
@@ -40,3 +40,5 @@ extern pthread_mutex_t THR_LOCK_charset;
#ifndef EDQUOT
#define EDQUOT (-1)
#endif
+
+void my_error_unregister_all(void);
diff --git a/mysys/ptr_cmp.c b/mysys/ptr_cmp.c
index a3bc3702c34..96c56645e94 100644
--- a/mysys/ptr_cmp.c
+++ b/mysys/ptr_cmp.c
@@ -184,7 +184,7 @@ my_off_t my_get_ptr(byte *ptr, uint pack_length)
case 4: pos= (my_off_t) mi_uint4korr(ptr); break;
case 3: pos= (my_off_t) mi_uint3korr(ptr); break;
case 2: pos= (my_off_t) mi_uint2korr(ptr); break;
- case 1: pos= (my_off_t) mi_uint2korr(ptr); break;
+ case 1: pos= (my_off_t) *(uchar*) ptr; break;
default: DBUG_ASSERT(0);
}
return pos;
diff --git a/mysys/queues.c b/mysys/queues.c
index 7809c97131c..5970922284f 100644
--- a/mysys/queues.c
+++ b/mysys/queues.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2000 MySQL AB
+/* Copyright (C) 2000, 2005 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
@@ -16,6 +16,10 @@
/*
Code for generell handling of priority Queues.
Implemention of queues from "Algoritms in C" by Robert Sedgewick.
+ An optimisation of _downheap suggested in Exercise 7.51 in "Data
+ Structures & Algorithms in C++" by Mark Allen Weiss, Second Edition
+ was implemented by Mikael Ronstrom 2005. Also the O(N) algorithm
+ of queue_fix was implemented.
*/
#include "mysys_priv.h"
@@ -62,6 +66,46 @@ int init_queue(QUEUE *queue, uint max_elements, uint offset_to_key,
}
+
+/*
+ Init queue, uses init_queue internally for init work but also accepts
+ auto_extent as parameter
+
+ SYNOPSIS
+ init_queue_ex()
+ queue Queue to initialise
+ max_elements Max elements that will be put in queue
+ offset_to_key Offset to key in element stored in queue
+ Used when sending pointers to compare function
+ max_at_top Set to 1 if you want biggest element on top.
+ compare Compare function for elements, takes 3 arguments.
+ first_cmp_arg First argument to compare function
+ auto_extent When the queue is full and there is insert operation
+ extend the queue.
+
+ NOTES
+ Will allocate max_element pointers for queue array
+
+ RETURN
+ 0 ok
+ 1 Could not allocate memory
+*/
+
+int init_queue_ex(QUEUE *queue, uint max_elements, uint offset_to_key,
+ pbool max_at_top, int (*compare) (void *, byte *, byte *),
+ void *first_cmp_arg, uint auto_extent)
+{
+ int ret;
+ DBUG_ENTER("init_queue_ex");
+
+ if ((ret= init_queue(queue, max_elements, offset_to_key, max_at_top, compare,
+ first_cmp_arg)))
+ DBUG_RETURN(ret);
+
+ queue->auto_extent= auto_extent;
+ DBUG_RETURN(0);
+}
+
/*
Reinitialize queue for other usage
@@ -181,6 +225,31 @@ void queue_insert(register QUEUE *queue, byte *element)
queue->root[idx]= element;
}
+/*
+ Does safe insert. If no more space left on the queue resize it.
+ Return codes:
+ 0 - OK
+ 1 - Cannot allocate more memory
+ 2 - auto_extend is 0, the operation would
+
+*/
+
+int queue_insert_safe(register QUEUE *queue, byte *element)
+{
+
+ if (queue->elements == queue->max_elements)
+ {
+ if (!queue->auto_extent)
+ return 2;
+ else if (resize_queue(queue, queue->max_elements + queue->auto_extent))
+ return 1;
+ }
+
+ queue_insert(queue, element);
+ return 0;
+}
+
+
/* Remove item from queue */
/* Returns pointer to removed element */
@@ -203,8 +272,64 @@ void queue_replaced(QUEUE *queue)
}
#endif
- /* Fix heap when index have changed */
+#ifndef OLD_VERSION
+
+void _downheap(register QUEUE *queue, uint idx)
+{
+ byte *element;
+ uint elements,half_queue,offset_to_key, next_index;
+ bool first= TRUE;
+ uint start_idx= idx;
+
+ offset_to_key=queue->offset_to_key;
+ element=queue->root[idx];
+ half_queue=(elements=queue->elements) >> 1;
+
+ while (idx <= half_queue)
+ {
+ int cmp;
+ next_index=idx+idx;
+ if (next_index < elements &&
+ (queue->compare(queue->first_cmp_arg,
+ queue->root[next_index]+offset_to_key,
+ queue->root[next_index+1]+offset_to_key) ^
+ queue->max_at_top) > 0)
+ next_index++;
+ if (first &&
+ (((cmp=queue->compare(queue->first_cmp_arg,
+ queue->root[next_index]+offset_to_key,
+ element+offset_to_key)) == 0) ||
+ ((cmp ^ queue->max_at_top) > 0)))
+ {
+ queue->root[idx]= element;
+ return;
+ }
+ queue->root[idx]=queue->root[next_index];
+ idx=next_index;
+ first= FALSE;
+ }
+
+ next_index= idx >> 1;
+ while (next_index > start_idx)
+ {
+ if ((queue->compare(queue->first_cmp_arg,
+ queue->root[next_index]+offset_to_key,
+ element+offset_to_key) ^
+ queue->max_at_top) < 0)
+ break;
+ queue->root[idx]=queue->root[next_index];
+ idx=next_index;
+ next_index= idx >> 1;
+ }
+ queue->root[idx]=element;
+}
+#else
+ /*
+ The old _downheap version is kept for comparisons with the benchmark
+ suit or new benchmarks anyone wants to run for comparisons.
+ */
+ /* Fix heap when index have changed */
void _downheap(register QUEUE *queue, uint idx)
{
byte *element;
@@ -236,20 +361,336 @@ void _downheap(register QUEUE *queue, uint idx)
}
-static int queue_fix_cmp(QUEUE *queue, void **a, void **b)
-{
- return queue->compare(queue->first_cmp_arg,
- (byte*) (*a)+queue->offset_to_key,
- (byte*) (*b)+queue->offset_to_key);
-}
+#endif
/*
- Fix heap when every element was changed,
- actually, it can be done better, in linear time, not in n*log(n)
+ Fix heap when every element was changed.
*/
void queue_fix(QUEUE *queue)
{
- qsort2(queue->root+1,queue->elements, sizeof(void *),
- (qsort2_cmp)queue_fix_cmp, queue);
+ uint i;
+ for (i= queue->elements >> 1; i > 0; i--)
+ _downheap(queue, i);
+}
+
+#ifdef MAIN
+ /*
+ A test program for the priority queue implementation.
+ It can also be used to benchmark changes of the implementation
+ Build by doing the following in the directory mysys
+ make test_priority_queue
+ ./test_priority_queue
+
+ Written by Mikael Ronström, 2005
+ */
+
+static uint num_array[1025];
+static uint tot_no_parts= 0;
+static uint tot_no_loops= 0;
+static uint expected_part= 0;
+static uint expected_num= 0;
+static bool max_ind= 0;
+static bool fix_used= 0;
+static ulonglong start_time= 0;
+
+static bool is_divisible_by(uint num, uint divisor)
+{
+ uint quotient= num / divisor;
+ if (quotient * divisor == num)
+ return TRUE;
+ return FALSE;
+}
+
+void calculate_next()
+{
+ uint part= expected_part, num= expected_num;
+ uint no_parts= tot_no_parts;
+ if (max_ind)
+ {
+ do
+ {
+ while (++part <= no_parts)
+ {
+ if (is_divisible_by(num, part) &&
+ (num <= ((1 << 21) + part)))
+ {
+ expected_part= part;
+ expected_num= num;
+ return;
+ }
+ }
+ part= 0;
+ } while (--num);
+ }
+ else
+ {
+ do
+ {
+ while (--part > 0)
+ {
+ if (is_divisible_by(num, part))
+ {
+ expected_part= part;
+ expected_num= num;
+ return;
+ }
+ }
+ part= no_parts + 1;
+ } while (++num);
+ }
+}
+
+void calculate_end_next(uint part)
+{
+ uint no_parts= tot_no_parts, num;
+ num_array[part]= 0;
+ if (max_ind)
+ {
+ expected_num= 0;
+ for (part= no_parts; part > 0 ; part--)
+ {
+ if (num_array[part])
+ {
+ num= num_array[part] & 0x3FFFFF;
+ if (num >= expected_num)
+ {
+ expected_num= num;
+ expected_part= part;
+ }
+ }
+ }
+ if (expected_num == 0)
+ expected_part= 0;
+ }
+ else
+ {
+ expected_num= 0xFFFFFFFF;
+ for (part= 1; part <= no_parts; part++)
+ {
+ if (num_array[part])
+ {
+ num= num_array[part] & 0x3FFFFF;
+ if (num <= expected_num)
+ {
+ expected_num= num;
+ expected_part= part;
+ }
+ }
+ }
+ if (expected_num == 0xFFFFFFFF)
+ expected_part= 0;
+ }
+ return;
+}
+static int test_compare(void *null_arg, byte *a, byte *b)
+{
+ uint a_num= (*(uint*)a) & 0x3FFFFF;
+ uint b_num= (*(uint*)b) & 0x3FFFFF;
+ uint a_part, b_part;
+ if (a_num > b_num)
+ return +1;
+ if (a_num < b_num)
+ return -1;
+ a_part= (*(uint*)a) >> 22;
+ b_part= (*(uint*)b) >> 22;
+ if (a_part < b_part)
+ return +1;
+ if (a_part > b_part)
+ return -1;
+ return 0;
+}
+
+bool check_num(uint num_part)
+{
+ uint part= num_part >> 22;
+ uint num= num_part & 0x3FFFFF;
+ if (part == expected_part)
+ if (num == expected_num)
+ return FALSE;
+ printf("Expect part %u Expect num 0x%x got part %u num 0x%x max_ind %u fix_used %u \n",
+ expected_part, expected_num, part, num, max_ind, fix_used);
+ return TRUE;
+}
+
+
+void perform_insert(QUEUE *queue)
+{
+ uint i= 1, no_parts= tot_no_parts;
+ uint backward_start= 0;
+
+ expected_part= 1;
+ expected_num= 1;
+
+ if (max_ind)
+ backward_start= 1 << 21;
+
+ do
+ {
+ uint num= (i + backward_start);
+ if (max_ind)
+ {
+ while (!is_divisible_by(num, i))
+ num--;
+ if (max_ind && (num > expected_num ||
+ (num == expected_num && i < expected_part)))
+ {
+ expected_num= num;
+ expected_part= i;
+ }
+ }
+ num_array[i]= num + (i << 22);
+ if (fix_used)
+ queue_element(queue, i-1)= (byte*)&num_array[i];
+ else
+ queue_insert(queue, (byte*)&num_array[i]);
+ } while (++i <= no_parts);
+ if (fix_used)
+ {
+ queue->elements= no_parts;
+ queue_fix(queue);
+ }
+}
+
+bool perform_ins_del(QUEUE *queue, bool max_ind)
+{
+ uint i= 0, no_loops= tot_no_loops, j= tot_no_parts;
+ do
+ {
+ uint num_part= *(uint*)queue_top(queue);
+ uint part= num_part >> 22;
+ if (check_num(num_part))
+ return TRUE;
+ if (j++ >= no_loops)
+ {
+ calculate_end_next(part);
+ queue_remove(queue, (uint) 0);
+ }
+ else
+ {
+ calculate_next();
+ if (max_ind)
+ num_array[part]-= part;
+ else
+ num_array[part]+= part;
+ queue_top(queue)= (byte*)&num_array[part];
+ queue_replaced(queue);
+ }
+ } while (++i < no_loops);
+ return FALSE;
+}
+
+bool do_test(uint no_parts, uint l_max_ind, bool l_fix_used)
+{
+ QUEUE queue;
+ bool result;
+ max_ind= l_max_ind;
+ fix_used= l_fix_used;
+ init_queue(&queue, no_parts, 0, max_ind, test_compare, NULL);
+ tot_no_parts= no_parts;
+ tot_no_loops= 1024;
+ perform_insert(&queue);
+ if ((result= perform_ins_del(&queue, max_ind)))
+ delete_queue(&queue);
+ if (result)
+ {
+ printf("Error\n");
+ return TRUE;
+ }
+ return FALSE;
+}
+
+static void start_measurement()
+{
+ start_time= my_getsystime();
}
+
+static void stop_measurement()
+{
+ ulonglong stop_time= my_getsystime();
+ uint time_in_micros;
+ stop_time-= start_time;
+ stop_time/= 10; /* Convert to microseconds */
+ time_in_micros= (uint)stop_time;
+ printf("Time expired is %u microseconds \n", time_in_micros);
+}
+
+static void benchmark_test()
+{
+ QUEUE queue_real;
+ QUEUE *queue= &queue_real;
+ uint i, add;
+ fix_used= TRUE;
+ max_ind= FALSE;
+ tot_no_parts= 1024;
+ init_queue(queue, tot_no_parts, 0, max_ind, test_compare, NULL);
+ /*
+ First benchmark whether queue_fix is faster than using queue_insert
+ for sizes of 16 partitions.
+ */
+ for (tot_no_parts= 2, add=2; tot_no_parts < 128;
+ tot_no_parts+= add, add++)
+ {
+ printf("Start benchmark queue_fix, tot_no_parts= %u \n", tot_no_parts);
+ start_measurement();
+ for (i= 0; i < 128; i++)
+ {
+ perform_insert(queue);
+ queue_remove_all(queue);
+ }
+ stop_measurement();
+
+ fix_used= FALSE;
+ printf("Start benchmark queue_insert\n");
+ start_measurement();
+ for (i= 0; i < 128; i++)
+ {
+ perform_insert(queue);
+ queue_remove_all(queue);
+ }
+ stop_measurement();
+ }
+ /*
+ Now benchmark insertion and deletion of 16400 elements.
+ Used in consecutive runs this shows whether the optimised _downheap
+ is faster than the standard implementation.
+ */
+ printf("Start benchmarking _downheap \n");
+ start_measurement();
+ perform_insert(queue);
+ for (i= 0; i < 65536; i++)
+ {
+ uint num, part;
+ num= *(uint*)queue_top(queue);
+ num+= 16;
+ part= num >> 22;
+ num_array[part]= num;
+ queue_top(queue)= (byte*)&num_array[part];
+ queue_replaced(queue);
+ }
+ for (i= 0; i < 16; i++)
+ queue_remove(queue, (uint) 0);
+ queue_remove_all(queue);
+ stop_measurement();
+}
+
+int main()
+{
+ int i, add= 1;
+ for (i= 1; i < 1024; i+=add, add++)
+ {
+ printf("Start test for priority queue of size %u\n", i);
+ if (do_test(i, 0, 1))
+ return -1;
+ if (do_test(i, 1, 1))
+ return -1;
+ if (do_test(i, 0, 0))
+ return -1;
+ if (do_test(i, 1, 0))
+ return -1;
+ }
+ benchmark_test();
+ printf("OK\n");
+ return 0;
+}
+#endif
diff --git a/mysys/raid.cc b/mysys/raid.cc
deleted file mode 100644
index c70c01fde4b..00000000000
--- a/mysys/raid.cc
+++ /dev/null
@@ -1,798 +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 */
-
-/*
-
- RAID support for MySQL. Raid 0 (stiping) only implemented yet.
-
- Why RAID? Why it must be in MySQL?
-
- This is because then you can:
- 1. Have bigger tables than your OS limit. In time of writing this
- we are hitting to 2GB limit under linux/ext2
- 2. You can get more speed from IO bottleneck by putting
- Raid dirs on different physical disks.
- 3. Getting more fault tolerance (not implemented yet)
-
- Why not to use RAID:
-
- 1. You are losing some processor power to calculate things,
- do more syscalls and interrupts.
-
- Functionality is supplied by two classes: RaidFd and RaidName.
- RaidFd supports funtionality over file descriptors like
- open/create/write/seek/close. RaidName supports functionality
- like rename/delete where we have no relations to filedescriptors.
- RaidName can be prorably unchanged for different Raid levels. RaidFd
- have to be virtual I think ;).
- You can speed up some calls in MySQL code by skipping RAID code.
- For example LOAD DATA INFILE never needs to read RAID-ed files.
- This can be done adding proper "#undef my_read" or similar undef-s
- in your code. Check out the raid.h!
-
- Some explanation about _seek_vector[]
- This is seek cache. RAID seeks too much and we cacheing this. We
- fool it and just storing new position in file to _seek_vector.
- When there is no seeks to do, we are putting RAID_SEEK_DONE into it.
- Any other value requires seeking to that position.
-
- TODO:
-
-
- - Implement other fancy things like RAID 1 (mirroring) and RAID 5.
- Should not to be very complex.
-
- - Optimize big blob writes by resorting write buffers and writing
- big chunks at once instead of doing many syscalls. - after thinking I
- found this is useless. This is because same thing one can do with just
- increasing RAID_CHUNKSIZE. Monty, what do you think? tonu.
-
- - If needed, then implement missing syscalls. One known to miss is stat();
-
- - Make and use a thread safe dynamic_array buffer. The used one
- will not work if needs to be extended at the same time someone is
- accessing it.
-
-
- tonu@mysql.com & monty@mysql.com
-*/
-
-#ifdef USE_PRAGMA_IMPLEMENTATION
-#pragma implementation // gcc: Class implementation
-#endif
-
-#include "mysys_priv.h"
-#include <my_dir.h>
-#include <m_string.h>
-#include <assert.h>
-
-#if defined(USE_RAID) && !defined(MYSQL_CLIENT)
-
-#define RAID_SEEK_DONE ~(off_t) 0
-#define RAID_SIZE_UNKNOWN ~(my_off_t) 0
-
-DYNAMIC_ARRAY RaidFd::_raid_map;
-
-
-/* --------------- C compatibility ---------------*/
-
-extern "C" {
-
- void init_raid(void)
- {
- /* Allocate memory for global file to raid map */
- my_init_dynamic_array(&RaidFd::_raid_map, sizeof(RaidFd*), 4096, 1024);
- }
- void end_raid(void)
- {
- /* Free memory used by raid */
- delete_dynamic(&RaidFd::_raid_map);
- }
-
- bool is_raid(File fd)
- {
- return RaidFd::IsRaid(fd);
- }
-
- File my_raid_create(const char *FileName, int CreateFlags, int access_flags,
- uint raid_type, uint raid_chunks, ulong raid_chunksize,
- myf MyFlags)
- {
- DBUG_ENTER("my_raid_create");
- DBUG_PRINT("enter",("Filename: %s CreateFlags: %d access_flags: %d MyFlags: %d",
- FileName, CreateFlags, access_flags, MyFlags));
- if (raid_type)
- {
- RaidFd *raid = new RaidFd(raid_type, raid_chunks , raid_chunksize);
- File res = raid->Create(FileName,CreateFlags,access_flags,MyFlags);
- if (res < 0 || set_dynamic(&RaidFd::_raid_map,(char*) &raid,res))
- {
- delete raid;
- DBUG_RETURN(-1);
- }
- DBUG_RETURN(res);
- }
- else
- DBUG_RETURN(my_create(FileName, CreateFlags, access_flags, MyFlags));
- }
-
- File my_raid_open(const char *FileName, int Flags,
- uint raid_type, uint raid_chunks, ulong raid_chunksize,
- myf MyFlags)
- {
- DBUG_ENTER("my_raid_open");
- DBUG_PRINT("enter",("Filename: %s Flags: %d MyFlags: %d",
- FileName, Flags, MyFlags));
- if (raid_type)
- {
- RaidFd *raid = new RaidFd(raid_type, raid_chunks , raid_chunksize);
- File res = raid->Open(FileName,Flags,MyFlags);
- if (res < 0 || set_dynamic(&RaidFd::_raid_map,(char*) &raid,res))
- {
- delete raid;
- DBUG_RETURN(-1);
- }
- DBUG_RETURN(res);
- }
- else
- DBUG_RETURN(my_open(FileName, Flags, MyFlags));
- }
-
- my_off_t my_raid_seek(File fd, my_off_t pos,int whence,myf MyFlags)
- {
- DBUG_ENTER("my_raid_seek");
- DBUG_PRINT("enter",("Fd: %d pos: %lu whence: %d MyFlags: %d",
- fd, (ulong) pos, whence, MyFlags));
-
- if (is_raid(fd))
- {
- assert(pos != MY_FILEPOS_ERROR);
-
- RaidFd *raid= (*dynamic_element(&RaidFd::_raid_map,fd,RaidFd**));
- DBUG_RETURN(raid->Seek(pos,whence,MyFlags));
- }
- else
- DBUG_RETURN(my_seek(fd, pos, whence, MyFlags));
- }
-
- my_off_t my_raid_tell(File fd,myf MyFlags)
- {
- DBUG_ENTER("my_raid_tell");
- DBUG_PRINT("enter",("Fd: %d MyFlags: %d",
- fd, MyFlags));
- if (is_raid(fd))
- {
- RaidFd *raid= (*dynamic_element(&RaidFd::_raid_map,fd,RaidFd**));
- DBUG_RETURN(raid->Tell(MyFlags));
- }
- else
- DBUG_RETURN(my_tell(fd, MyFlags));
- }
-
- uint my_raid_write(File fd,const byte *Buffer, uint Count, myf MyFlags)
- {
- DBUG_ENTER("my_raid_write");
- DBUG_PRINT("enter",("Fd: %d Buffer: 0x%lx Count: %u MyFlags: %d",
- fd, Buffer, Count, MyFlags));
- if (is_raid(fd))
- {
- RaidFd *raid= (*dynamic_element(&RaidFd::_raid_map,fd,RaidFd**));
- DBUG_RETURN(raid->Write(Buffer,Count,MyFlags));
- } else
- DBUG_RETURN(my_write(fd,Buffer,Count,MyFlags));
- }
-
- uint my_raid_read(File fd, byte *Buffer, uint Count, myf MyFlags)
- {
- DBUG_ENTER("my_raid_read");
- DBUG_PRINT("enter",("Fd: %d Buffer: 0x%lx Count: %u MyFlags: %d",
- fd, Buffer, Count, MyFlags));
- if (is_raid(fd))
- {
- RaidFd *raid= (*dynamic_element(&RaidFd::_raid_map,fd,RaidFd**));
- DBUG_RETURN(raid->Read(Buffer,Count,MyFlags));
- } else
- DBUG_RETURN(my_read(fd,Buffer,Count,MyFlags));
- }
-
- uint my_raid_pread(File Filedes, byte *Buffer, uint Count, my_off_t offset,
- myf MyFlags)
- {
- DBUG_ENTER("my_raid_pread");
- DBUG_PRINT("enter",
- ("Fd: %d Buffer: 0x%lx Count: %u offset: %u MyFlags: %d",
- Filedes, Buffer, Count, offset, MyFlags));
- if (is_raid(Filedes))
- {
- assert(offset != MY_FILEPOS_ERROR);
-
- RaidFd *raid= (*dynamic_element(&RaidFd::_raid_map,Filedes,RaidFd**));
- /* Returning value isn't important because real seek is done later. */
- raid->Seek(offset,MY_SEEK_SET,MyFlags);
- DBUG_RETURN(raid->Read(Buffer,Count,MyFlags));
- }
- else
- DBUG_RETURN(my_pread(Filedes, Buffer, Count, offset, MyFlags));
- }
-
- uint my_raid_pwrite(int Filedes, const byte *Buffer, uint Count,
- my_off_t offset, myf MyFlags)
- {
- DBUG_ENTER("my_raid_pwrite");
- DBUG_PRINT("enter",
- ("Fd: %d Buffer: 0x %lx Count: %u offset: %u MyFlags: %d",
- Filedes, Buffer, Count, offset, MyFlags));
- if (is_raid(Filedes))
- {
- assert(offset != MY_FILEPOS_ERROR);
-
- RaidFd *raid= (*dynamic_element(&RaidFd::_raid_map,Filedes,RaidFd**));
- /* Returning value isn't important because real seek is done later. */
- raid->Seek(offset,MY_SEEK_SET,MyFlags);
- DBUG_RETURN(raid->Write(Buffer,Count,MyFlags));
- }
- else
- DBUG_RETURN(my_pwrite(Filedes, Buffer, Count, offset, MyFlags));
- }
-
- int my_raid_lock(File fd, int locktype, my_off_t start, my_off_t length,
- myf MyFlags)
- {
- DBUG_ENTER("my_raid_lock");
- DBUG_PRINT("enter",("Fd: %d start: %u length: %u MyFlags: %d",
- fd, start, length, MyFlags));
- if (my_disable_locking)
- DBUG_RETURN(0);
- if (is_raid(fd))
- {
- RaidFd *raid= (*dynamic_element(&RaidFd::_raid_map,fd,RaidFd**));
- DBUG_RETURN(raid->Lock(locktype, start, length, MyFlags));
- }
- else
- DBUG_RETURN(my_lock(fd, locktype, start, length, MyFlags));
- }
-
- int my_raid_close(File fd, myf MyFlags)
- {
- DBUG_ENTER("my_raid_close");
- DBUG_PRINT("enter",("Fd: %d MyFlags: %d",
- fd, MyFlags));
- if (is_raid(fd))
- {
- RaidFd *raid= (*dynamic_element(&RaidFd::_raid_map,fd,RaidFd**));
- RaidFd *tmp=0;
- set_dynamic(&RaidFd::_raid_map,(char*) &tmp,fd);
- int res = raid->Close(MyFlags);
- delete raid;
- DBUG_RETURN(res);
- }
- else
- DBUG_RETURN(my_close(fd, MyFlags));
- }
-
- int my_raid_chsize(File fd, my_off_t newlength, int filler, myf MyFlags)
- {
- DBUG_ENTER("my_raid_chsize");
- DBUG_PRINT("enter",("Fd: %d newlength: %u MyFlags: %d",
- fd, newlength, MyFlags));
- if (is_raid(fd))
- {
- RaidFd *raid= (*dynamic_element(&RaidFd::_raid_map,fd,RaidFd**));
- DBUG_RETURN(raid->Chsize(fd, newlength, filler, MyFlags));
- }
- else
- DBUG_RETURN(my_chsize(fd, newlength, filler, MyFlags));
- }
-
- int my_raid_rename(const char *from, const char *to,
- uint raid_chunks, myf MyFlags)
- {
- char from_tmp[FN_REFLEN];
- char to_tmp[FN_REFLEN];
- DBUG_ENTER("my_raid_rename");
-
- uint from_pos = dirname_length(from);
- uint to_pos = dirname_length(to);
- memcpy(from_tmp, from, from_pos);
- memcpy(to_tmp, to, to_pos);
- for (uint i = 0 ; i < raid_chunks ; i++ )
- {
- sprintf(from_tmp+from_pos,"%02x/%s", i, from + from_pos);
- sprintf(to_tmp+to_pos,"%02x/%s", i, to+ to_pos);
- /* Convert if not unix */
- unpack_filename(from_tmp, from_tmp);
- unpack_filename(to_tmp,to_tmp);
- if (my_rename(from_tmp, to_tmp, MyFlags))
- DBUG_RETURN(-1);
- }
- DBUG_RETURN(0);
- }
-
- int my_raid_delete(const char *from, uint raid_chunks, myf MyFlags)
- {
- char from_tmp[FN_REFLEN];
- uint from_pos = dirname_length(from);
- DBUG_ENTER("my_raid_delete");
-
- if (!raid_chunks)
- DBUG_RETURN(my_delete(from,MyFlags));
- for (uint i = 0 ; i < raid_chunks ; i++ )
- {
- memcpy(from_tmp, from, from_pos);
- sprintf(from_tmp+from_pos,"%02x/%s", i, from + from_pos);
- /* Convert if not unix */
- unpack_filename(from_tmp, from_tmp);
- if (my_delete(from_tmp, MyFlags))
- DBUG_RETURN(-1);
- }
- DBUG_RETURN(0);
- }
-
- int my_raid_redel(const char *old_name, const char *new_name,
- uint raid_chunks, myf MyFlags)
- {
- char new_name_buff[FN_REFLEN], old_name_buff[FN_REFLEN];
- char *new_end, *old_end;
- uint i,old_length,new_length;
- int error=0;
- DBUG_ENTER("my_raid_redel");
-
- old_end=old_name_buff+dirname_part(old_name_buff,old_name);
- old_length=dirname_length(old_name);
- new_end=new_name_buff+dirname_part(new_name_buff,new_name);
- new_length=dirname_length(new_name);
- for (i=0 ; i < raid_chunks ; i++)
- {
- MY_STAT status;
- sprintf(new_end,"%02x",i);
- if (my_stat(new_name_buff,&status, MYF(0)))
- {
- DBUG_PRINT("info",("%02x exists, skipping directory creation",i));
- }
- else
- {
- if (my_mkdir(new_name_buff,0777,MYF(0)))
- {
- DBUG_PRINT("error",("mkdir failed for %02x",i));
- DBUG_RETURN(-1);
- }
- }
- strxmov(strend(new_end),"/",new_name+new_length,NullS);
- sprintf(old_end,"%02x/%s",i, old_name+old_length);
- if (my_redel(old_name_buff, new_name_buff, MyFlags))
- error=1;
- }
- DBUG_RETURN(error);
- }
-}
-
-int my_raid_fstat(int fd, MY_STAT *stat_area, myf MyFlags )
-{
- DBUG_ENTER("my_raid_fstat");
- if (is_raid(fd))
- {
- RaidFd *raid= (*dynamic_element(&RaidFd::_raid_map,fd,RaidFd**));
- DBUG_RETURN(raid->Fstat(fd, stat_area, MyFlags));
- }
- else
- DBUG_RETURN(my_fstat(fd, stat_area, MyFlags));
-}
-
-
-/* -------------- RaidFd base class begins ----------------*/
-/*
- RaidFd - raided file is identified by file descriptor
- this is useful when we open/write/read/close files
-*/
-
-
-bool RaidFd::
-IsRaid(File fd)
-{
- DBUG_ENTER("RaidFd::IsRaid");
- DBUG_RETURN((uint) fd < _raid_map.elements &&
- *dynamic_element(&RaidFd::_raid_map,fd,RaidFd**));
-}
-
-
-RaidFd::
-RaidFd(uint raid_type, uint raid_chunks, ulong raid_chunksize)
- :_raid_type(raid_type), _raid_chunks(raid_chunks),
- _raid_chunksize(raid_chunksize), _position(0), _size(RAID_SIZE_UNKNOWN),
- _fd_vector(0)
-{
- DBUG_ENTER("RaidFd::RaidFd");
- DBUG_PRINT("enter",("RaidFd_type: %u Disks: %u Chunksize: %d",
- raid_type, raid_chunks, raid_chunksize));
-
- /* TODO: Here we should add checks if the malloc fails */
- _seek_vector=0; /* In case of errors */
- my_multi_malloc(MYF(MY_WME),
- &_seek_vector,sizeof(off_t)*_raid_chunks,
- &_fd_vector, sizeof(File) *_raid_chunks,
- NullS);
- if (!RaidFd::_raid_map.buffer)
- { /* Not initied */
- pthread_mutex_lock(&THR_LOCK_open); /* Ensure that no other thread */
- if (!RaidFd::_raid_map.buffer) /* has done init in between */
- init_raid();
- pthread_mutex_unlock(&THR_LOCK_open);
- }
- DBUG_VOID_RETURN;
-}
-
-
-RaidFd::
-~RaidFd() {
- DBUG_ENTER("RaidFd::~RaidFd");
- /* We don't have to free _fd_vector ! */
- my_free((char*) _seek_vector, MYF(MY_ALLOW_ZERO_PTR));
- DBUG_VOID_RETURN;
-}
-
-
-File RaidFd::
-Create(const char *FileName, int CreateFlags, int access_flags, myf MyFlags)
-{
- char RaidFdFileName[FN_REFLEN];
- DBUG_ENTER("RaidFd::Create");
- DBUG_PRINT("enter",
- ("FileName: %s CreateFlags: %d access_flags: %d MyFlags: %d",
- FileName, CreateFlags, access_flags, MyFlags));
- char DirName[FN_REFLEN];
- uint pos = dirname_part(DirName, FileName);
- MY_STAT status;
- if (!_seek_vector)
- DBUG_RETURN(-1); /* Not enough memory */
-
- uint i = _raid_chunks-1;
- do
- {
- /* Create subdir */
- (void)sprintf(RaidFdFileName,"%s%02x", DirName,i);
- unpack_dirname(RaidFdFileName,RaidFdFileName); /* Convert if not unix */
- if (my_stat(RaidFdFileName,&status, MYF(0)))
- {
- DBUG_PRINT("info",("%02x exists, skipping directory creation",i));
- }
- else
- {
- if (my_mkdir(RaidFdFileName,0777,MYF(0)))
- {
- DBUG_PRINT("error",("mkdir failed for %d",i));
- goto error;
- }
- }
- /* Create file */
- sprintf(RaidFdFileName,"%s%02x/%s",DirName, i, FileName + pos);
- unpack_filename(RaidFdFileName,RaidFdFileName); /* Convert if not unix */
- _fd = my_create(RaidFdFileName, CreateFlags ,access_flags, (myf)MyFlags);
- if (_fd < 0)
- goto error;
- _fd_vector[i]=_fd;
- _seek_vector[i]=RAID_SEEK_DONE;
- } while (i--);
- _size=0;
- DBUG_RETURN(_fd); /* Last filenr is pointer to map */
-
-error:
- {
- int save_errno=my_errno;
- while (++i < _raid_chunks)
- {
- my_close(_fd_vector[i],MYF(0));
- sprintf(RaidFdFileName,"%s%02x/%s",DirName, i, FileName + pos);
- unpack_filename(RaidFdFileName,RaidFdFileName);
- my_delete(RaidFdFileName,MYF(0));
- }
- my_errno=save_errno;
- }
- DBUG_RETURN(-1);
-}
-
-
-File RaidFd::
-Open(const char *FileName, int Flags, myf MyFlags)
-{
- DBUG_ENTER("RaidFd::Open");
- DBUG_PRINT("enter",("FileName: %s Flags: %d MyFlags: %d",
- FileName, Flags, MyFlags));
- char DirName[FN_REFLEN];
- uint pos = dirname_part(DirName, FileName);
- if (!_seek_vector)
- DBUG_RETURN(-1); /* Not enough memory */
-
- for( uint i = 0 ; i < _raid_chunks ; i++ )
- {
- char RaidFdFileName[FN_REFLEN];
- sprintf(RaidFdFileName,"%s%02x/%s",DirName, i, FileName + pos);
- unpack_filename(RaidFdFileName,RaidFdFileName); /* Convert if not unix */
- _fd = my_open(RaidFdFileName, Flags, MyFlags);
- if (_fd < 0)
- {
- int save_errno=my_errno;
- while (i-- != 0)
- my_close(_fd_vector[i],MYF(0));
- my_errno=save_errno;
- DBUG_RETURN(_fd);
- }
- _fd_vector[i]=_fd;
- _seek_vector[i]=RAID_SEEK_DONE;
- }
- Seek(0L,MY_SEEK_END,MYF(0)); // Trick. We just need to know, how big the file is
- DBUG_PRINT("info",("MYD file logical size: %llu", _size));
- DBUG_RETURN(_fd);
-}
-
-
-int RaidFd::
-Write(const byte *Buffer, uint Count, myf MyFlags)
-{
- DBUG_ENTER("RaidFd::Write");
- DBUG_PRINT("enter",("Count: %d MyFlags: %d",
- Count, MyFlags));
- const byte *bufptr = Buffer;
- uint res=0, GotBytes, ReadNowCount;
-
- // Loop until data is written
- do {
- Calculate();
- // Do seeks when neccessary
- if (_seek_vector[_this_block] != RAID_SEEK_DONE)
- {
- if (my_seek(_fd_vector[_this_block], _seek_vector[_this_block],
- MY_SEEK_SET,
- MyFlags) == MY_FILEPOS_ERROR)
- DBUG_RETURN(-1);
- _seek_vector[_this_block]=RAID_SEEK_DONE;
- }
- ReadNowCount = min(Count, _remaining_bytes);
- GotBytes = my_write(_fd_vector[_this_block], bufptr, ReadNowCount,
- MyFlags);
- DBUG_PRINT("loop",("Wrote bytes: %d", GotBytes));
- if (GotBytes == MY_FILE_ERROR)
- DBUG_RETURN(-1);
- res+= GotBytes;
- if (MyFlags & (MY_NABP | MY_FNABP))
- GotBytes=ReadNowCount;
- bufptr += GotBytes;
- Count -= GotBytes;
- _position += GotBytes;
- } while(Count);
- set_if_bigger(_size,_position);
- DBUG_RETURN(res);
-}
-
-
-int RaidFd::
-Read(const byte *Buffer, uint Count, myf MyFlags)
-{
- DBUG_ENTER("RaidFd::Read");
- DBUG_PRINT("enter",("Count: %d MyFlags: %d",
- Count, MyFlags));
- byte *bufptr = (byte *)Buffer;
- uint res= 0, GotBytes, ReadNowCount;
-
- // Loop until all data is read (Note that Count may be 0)
- while (Count)
- {
- Calculate();
- // Do seek when neccessary
- if (_seek_vector[_this_block] != RAID_SEEK_DONE)
- {
- if (my_seek(_fd_vector[_this_block], _seek_vector[_this_block],
- MY_SEEK_SET,
- MyFlags) == MY_FILEPOS_ERROR)
- DBUG_RETURN(-1);
- _seek_vector[_this_block]=RAID_SEEK_DONE;
- }
- // and read
- ReadNowCount = min(Count, _remaining_bytes);
- GotBytes = my_read(_fd_vector[_this_block], bufptr, ReadNowCount,
- MyFlags & ~(MY_NABP | MY_FNABP));
- DBUG_PRINT("loop",("Got bytes: %u", GotBytes));
- if (GotBytes == MY_FILE_ERROR)
- DBUG_RETURN(-1);
- if (!GotBytes) // End of file.
- {
- DBUG_RETURN((MyFlags & (MY_NABP | MY_FNABP)) ? -1 : (int) res);
- }
- res+= GotBytes;
- bufptr += GotBytes;
- Count -= GotBytes;
- _position += GotBytes;
- }
- DBUG_RETURN((MyFlags & (MY_NABP | MY_FNABP)) ? 0 : res);
-}
-
-
-int RaidFd::
-Lock(int locktype, my_off_t start, my_off_t length, myf MyFlags)
-{
- DBUG_ENTER("RaidFd::Lock");
- DBUG_PRINT("enter",("locktype: %d start: %lu length: %lu MyFlags: %d",
- locktype, start, length, MyFlags));
- my_off_t bufptr = start;
- // Loop until all data is locked
- while(length)
- {
- Calculate();
- for (uint i = _this_block ; (i < _raid_chunks) && length ; i++ )
- {
- uint ReadNowCount = min(length, _remaining_bytes);
- uint GotBytes = my_lock(_fd_vector[i], locktype, bufptr, ReadNowCount,
- MyFlags);
- if ((int) GotBytes == -1)
- DBUG_RETURN(-1);
- bufptr += ReadNowCount;
- length -= ReadNowCount;
- Calculate();
- }
- }
- DBUG_RETURN(0);
-}
-
-
-int RaidFd::
-Close(myf MyFlags)
-{
- DBUG_ENTER("RaidFd::Close");
- DBUG_PRINT("enter",("MyFlags: %d",
- MyFlags));
- for (uint i = 0 ; i < _raid_chunks ; ++i )
- {
- int err = my_close(_fd_vector[i], MyFlags);
- if (err != 0)
- DBUG_RETURN(err);
- }
- /* _fd_vector is erased when RaidFd is released */
- DBUG_RETURN(0);
-}
-
-
-my_off_t RaidFd::
-Seek(my_off_t pos,int whence,myf MyFlags)
-{
- DBUG_ENTER("RaidFd::Seek");
- DBUG_PRINT("enter",("Pos: %lu Whence: %d MyFlags: %d",
- (ulong) pos, whence, MyFlags));
- switch (whence) {
- case MY_SEEK_CUR:
- // FIXME: This is wrong, what is going on there
- // Just I am relied on fact that MySQL 3.23.7 never uses MY_SEEK_CUR
- // for anything else except things like ltell()
- break;
- case MY_SEEK_SET:
- if ( _position != pos) // we can be already in right place
- {
- uint i;
- off_t _rounds;
- _position = pos;
- Calculate();
- _rounds = _total_block / _raid_chunks; // INT() assumed
- _rounds*= _raid_chunksize;
- for (i = 0; i < _raid_chunks ; i++ )
- if ( i < _this_block )
- _seek_vector[i] = _rounds + _raid_chunksize;
- else if ( i == _this_block )
- _seek_vector[i] = _rounds + _raid_chunksize -_remaining_bytes;
- else // if ( i > _this_block )
- _seek_vector[i] = _rounds;
- }
- break;
- case MY_SEEK_END:
- if (_size==RAID_SIZE_UNKNOWN) // We don't know table size yet
- {
- uint i;
- _position = 0;
- for (i = 0; i < _raid_chunks ; i++ )
- {
- my_off_t newpos = my_seek(_fd_vector[i], 0L, MY_SEEK_END, MyFlags);
- if (newpos == MY_FILEPOS_ERROR)
- DBUG_RETURN (MY_FILEPOS_ERROR);
- _seek_vector[i]=RAID_SEEK_DONE;
- _position += newpos;
- }
- _size=_position;
- }
- else if (_position != _size) // Aren't we also already in the end?
- {
- uint i;
- off_t _rounds;
- _position = _size;
- Calculate();
- _rounds = _total_block / _raid_chunks; // INT() assumed
- _rounds*= _raid_chunksize;
- for (i = 0; i < _raid_chunks ; i++ )
- if ( i < _this_block )
- _seek_vector[i] = _rounds + _raid_chunksize;
- else if ( i == _this_block )
- _seek_vector[i] = _rounds + _raid_chunksize - _remaining_bytes;
- else // if ( i > _this_block )
- _seek_vector[i] = _rounds;
- _position=_size;
- }
- }
- DBUG_RETURN(_position);
-}
-
-
-my_off_t RaidFd::
-Tell(myf MyFlags)
-{
- DBUG_ENTER("RaidFd::Tell");
- DBUG_PRINT("enter",("MyFlags: %d _position %d",
- MyFlags,_position));
- DBUG_RETURN(_position);
-}
-
-int RaidFd::
-Chsize(File fd, my_off_t newlength, int filler, myf MyFlags)
-{
- DBUG_ENTER("RaidFd::Chsize");
- DBUG_PRINT("enter",("Fd: %d, newlength: %d, MyFlags: %d",
- fd, newlength,MyFlags));
- _position = newlength;
- Calculate();
- uint _rounds = _total_block / _raid_chunks; // INT() assumed
- for (uint i = 0; i < _raid_chunks ; i++ )
- {
- int newpos;
- if ( i < _this_block )
- newpos = my_chsize(_fd_vector[i],
- _this_block * _raid_chunksize + (_rounds + 1) *
- _raid_chunksize, filler, MyFlags);
- else if ( i == _this_block )
- newpos = my_chsize(_fd_vector[i],
- _this_block * _raid_chunksize + _rounds *
- _raid_chunksize + (newlength % _raid_chunksize),
- filler, MyFlags);
- else // this means: i > _this_block
- newpos = my_chsize(_fd_vector[i],
- _this_block * _raid_chunksize + _rounds *
- _raid_chunksize, filler, MyFlags);
- if (newpos)
- DBUG_RETURN(1);
- }
- DBUG_RETURN(0);
-}
-
-
-int RaidFd::
-Fstat(int fd, MY_STAT *stat_area, myf MyFlags )
-{
- DBUG_ENTER("RaidFd::Fstat");
- DBUG_PRINT("enter",("fd: %d MyFlags: %d",fd,MyFlags));
- uint i;
- int error=0;
- MY_STAT status;
- stat_area->st_size=0;
- stat_area->st_mtime=0;
- stat_area->st_atime=0;
- stat_area->st_ctime=0;
-
- for(i=0 ; i < _raid_chunks ; i++)
- {
- if (my_fstat(_fd_vector[i],&status,MyFlags))
- error=1;
- stat_area->st_size+=status.st_size;
- set_if_bigger(stat_area->st_mtime,status.st_mtime);
- set_if_bigger(stat_area->st_atime,status.st_atime);
- set_if_bigger(stat_area->st_ctime,status.st_ctime);
- }
- DBUG_RETURN(error);
-}
-
-#endif /* defined(USE_RAID) && !defined(MYSQL_CLIENT) */
diff --git a/mysys/raid2.c b/mysys/raid2.c
deleted file mode 100644
index 4feace7410f..00000000000
--- a/mysys/raid2.c
+++ /dev/null
@@ -1,31 +0,0 @@
-/* Copyright (C) 2002 MySQL AB
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; version 2
- of the License.
-
- This library 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
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA */
-
-/*
- RAID support for MySQL. For full comments, check raid.cc
- This is in a separate file to not cause problems on OS that can't
- put C++ files in archives.
-*/
-
-#include "mysys_priv.h"
-
-const char *raid_type_string[]={"none","striped"};
-
-const char *my_raid_type(int raid_type)
-{
- return raid_type_string[raid_type];
-}
diff --git a/mysys/safemalloc.c b/mysys/safemalloc.c
index f43c860adb0..da15b02345b 100644
--- a/mysys/safemalloc.c
+++ b/mysys/safemalloc.c
@@ -524,7 +524,7 @@ char *_my_strdup(const char *from, const char *filename, uint lineno,
} /* _my_strdup */
-char *_my_strdup_with_length(const char *from, uint length,
+char *_my_strndup(const char *from, uint length,
const char *filename, uint lineno,
myf MyFlags)
{
diff --git a/mysys/string.c b/mysys/string.c
index e64156d430e..86de7bfcf69 100644
--- a/mysys/string.c
+++ b/mysys/string.c
@@ -114,6 +114,12 @@ my_bool dynstr_append_mem(DYNAMIC_STRING *str, const char *append,
return FALSE;
}
+my_bool dynstr_trunc(DYNAMIC_STRING *str, int n)
+{
+ str->length-=n;
+ str->str[str->length]= '\0';
+ return FALSE;
+}
void dynstr_free(DYNAMIC_STRING *str)
{
diff --git a/mysys/test_dir.c b/mysys/test_dir.c
index f1e4987371b..54e6c99e21e 100644
--- a/mysys/test_dir.c
+++ b/mysys/test_dir.c
@@ -15,7 +15,6 @@
/* TODO: Test all functions */
-#define USES_TYPES
#include "mysys_priv.h"
#include "my_dir.h"
diff --git a/mysys/testhash.c b/mysys/testhash.c
index fd2bc73b2ae..0961558afd3 100644
--- a/mysys/testhash.c
+++ b/mysys/testhash.c
@@ -249,7 +249,6 @@ err:
static int get_options(int argc, char **argv)
{
char *pos,*progname;
- DEBUGGER_OFF;
progname= argv[0];
@@ -269,7 +268,6 @@ static int get_options(int argc, char **argv)
printf("Usage: %s [-?ABIKLWv] [-m#] [-t#]\n",progname);
exit(0);
case '#':
- DEBUGGER_ON;
DBUG_PUSH (++pos);
break;
}
diff --git a/mysys/thr_alarm.c b/mysys/thr_alarm.c
index acb4ac5dbf9..170ee8a1b73 100644
--- a/mysys/thr_alarm.c
+++ b/mysys/thr_alarm.c
@@ -14,8 +14,7 @@
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/* To avoid problems with alarms in debug code, we disable DBUG here */
-#undef DBUG_OFF
-#define DBUG_OFF
+#define FORCE_DBUG_OFF
#include <my_global.h>
#if defined(THREAD) && !defined(DONT_USE_THR_ALARM)
@@ -41,7 +40,7 @@ volatile my_bool alarm_thread_running= 0;
static sig_handler process_alarm_part2(int sig);
-#if !defined(__WIN__) && !defined(__EMX__) && !defined(OS2)
+#if !defined(__WIN__)
static pthread_mutex_t LOCK_alarm;
static pthread_cond_t COND_alarm;
@@ -276,7 +275,7 @@ sig_handler process_alarm(int sig __attribute__((unused)))
if (!pthread_equal(pthread_self(),alarm_thread))
{
#if defined(MAIN) && !defined(__bsdi__)
- printf("thread_alarm\n"); fflush(stdout);
+ printf("thread_alarm in process_alarm\n"); fflush(stdout);
#endif
#ifdef DONT_REMEMBER_SIGNAL
my_sigset(THR_CLIENT_ALARM,process_alarm); /* int. thread system calls */
@@ -563,145 +562,6 @@ static void *alarm_handler(void *arg __attribute__((unused)))
#endif /* USE_ALARM_THREAD */
/*****************************************************************************
- thr_alarm for OS/2
-*****************************************************************************/
-
-#elif defined(__EMX__) || defined(OS2)
-
-#define INCL_BASE
-#define INCL_NOPMAPI
-#include <os2.h>
-
-static pthread_mutex_t LOCK_alarm;
-static sigset_t full_signal_set;
-static QUEUE alarm_queue;
-pthread_t alarm_thread;
-
-#ifdef USE_ALARM_THREAD
-static pthread_cond_t COND_alarm;
-static void *alarm_handler(void *arg);
-#define reschedule_alarms() pthread_cond_signal(&COND_alarm)
-#else
-#define reschedule_alarms() pthread_kill(alarm_thread,THR_SERVER_ALARM)
-#endif
-
-sig_handler process_alarm(int sig __attribute__((unused)))
-{
- sigset_t old_mask;
- ALARM *alarm_data;
- DBUG_PRINT("info",("sig: %d active alarms: %d",sig,alarm_queue.elements));
-}
-
-
-/*
- Remove another thread from the alarm
-*/
-
-void thr_alarm_kill(pthread_t thread_id)
-{
- uint i;
-
- pthread_mutex_lock(&LOCK_alarm);
- for (i=0 ; i < alarm_queue.elements ; i++)
- {
- if (pthread_equal(((ALARM*) queue_element(&alarm_queue,i))->thread,
- thread_id))
- {
- ALARM *tmp=(ALARM*) queue_remove(&alarm_queue,i);
- tmp->expire_time=0;
- queue_insert(&alarm_queue,(byte*) tmp);
- reschedule_alarms();
- break;
- }
- }
- pthread_mutex_unlock(&LOCK_alarm);
-}
-
-bool thr_alarm(thr_alarm_t *alrm, uint sec, ALARM *alarm)
-{
- APIRET rc;
- if (alarm_aborted)
- {
- alarm->alarmed.crono=0;
- alarm->alarmed.event=0;
- return 1;
- }
- if (rc = DosCreateEventSem(NULL,(HEV *) &alarm->alarmed.event,
- DC_SEM_SHARED,FALSE))
- {
- printf("Error creating event semaphore! [%d] \n",rc);
- alarm->alarmed.crono=0;
- alarm->alarmed.event=0;
- return 1;
- }
- if (rc = DosAsyncTimer((long) sec*1000L, (HSEM) alarm->alarmed.event,
- (HTIMER *) &alarm->alarmed.crono))
- {
- printf("Error starting async timer! [%d] \n",rc);
- DosCloseEventSem((HEV) alarm->alarmed.event);
- alarm->alarmed.crono=0;
- alarm->alarmed.event=0;
- return 1;
- } /* endif */
- (*alrm)= &alarm->alarmed;
- return 1;
-}
-
-
-bool thr_got_alarm(thr_alarm_t *alrm_ptr)
-{
- thr_alarm_t alrm= *alrm_ptr;
- APIRET rc;
-
- if (alrm->crono)
- {
- rc = DosWaitEventSem((HEV) alrm->event, SEM_IMMEDIATE_RETURN);
- if (rc == 0) {
- DosCloseEventSem((HEV) alrm->event);
- alrm->crono = 0;
- alrm->event = 0;
- } /* endif */
- }
- return !alrm->crono || alarm_aborted;
-}
-
-
-void thr_end_alarm(thr_alarm_t *alrm_ptr)
-{
- thr_alarm_t alrm= *alrm_ptr;
- if (alrm->crono)
- {
- DosStopTimer((HTIMER) alrm->crono);
- DosCloseEventSem((HEV) alrm->event);
- alrm->crono = 0;
- alrm->event = 0;
- }
-}
-
-void end_thr_alarm(my_bool free_structures)
-{
- DBUG_ENTER("end_thr_alarm");
- alarm_aborted=1; /* No more alarms */
- DBUG_VOID_RETURN;
-}
-
-void init_thr_alarm(uint max_alarm)
-{
- DBUG_ENTER("init_thr_alarm");
- alarm_aborted=0; /* Yes, Gimmie alarms */
- DBUG_VOID_RETURN;
-}
-
-void thr_alarm_info(ALARM_INFO *info)
-{
- bzero((char*) info, sizeof(*info));
-}
-
-void resize_thr_alarm(uint max_alarms)
-{
-}
-
-/*****************************************************************************
thr_alarm for win95
*****************************************************************************/
@@ -901,10 +761,8 @@ static sig_handler print_signal_warning(int sig)
#ifdef DONT_REMEMBER_SIGNAL
my_sigset(sig,print_signal_warning); /* int. thread system calls */
#endif
-#ifndef OS2
if (sig == SIGALRM)
alarm(2); /* reschedule alarm */
-#endif
}
#endif /* USE_ONE_SIGNAL_HAND */
@@ -921,7 +779,6 @@ static void *signal_hand(void *arg __attribute__((unused)))
VOID(pthread_cond_signal(&COND_thread_count)); /* Tell main we are ready */
pthread_mutex_unlock(&LOCK_thread_count);
-#ifndef OS2
sigemptyset(&set); /* Catch all signals */
sigaddset(&set,SIGINT);
sigaddset(&set,SIGQUIT);
@@ -938,7 +795,6 @@ static void *signal_hand(void *arg __attribute__((unused)))
#else
puts("Starting signal handling thread");
#endif
-#endif /* OS2 */
printf("server alarm: %d thread alarm: %d\n",
THR_SERVER_ALARM,THR_CLIENT_ALARM);
DBUG_PRINT("info",("Starting signal and alarm handling thread"));
@@ -961,9 +817,7 @@ static void *signal_hand(void *arg __attribute__((unused)))
case SIGINT:
case SIGQUIT:
case SIGTERM:
-#ifndef OS2
case SIGHUP:
-#endif
printf("Aborting nicely\n");
end_thr_alarm(0);
break;
@@ -973,13 +827,11 @@ static void *signal_hand(void *arg __attribute__((unused)))
exit(1);
return 0; /* Keep some compilers happy */
#endif
-#ifndef OS2
#ifdef USE_ONE_SIGNAL_HAND
case THR_SERVER_ALARM:
process_alarm(sig);
break;
#endif
-#endif /* OS2 */
}
}
}
@@ -995,13 +847,13 @@ int main(int argc __attribute__((unused)),char **argv __attribute__((unused)))
MY_INIT(argv[0]);
if (argc > 1 && argv[1][0] == '-' && argv[1][1] == '#')
+ {
DBUG_PUSH(argv[1]+2);
-
+ }
pthread_mutex_init(&LOCK_thread_count,MY_MUTEX_INIT_FAST);
pthread_cond_init(&COND_thread_count,NULL);
/* Start a alarm handling thread */
-#ifndef OS2
sigemptyset(&set);
sigaddset(&set,SIGINT);
sigaddset(&set,SIGQUIT);
@@ -1019,7 +871,6 @@ int main(int argc __attribute__((unused)),char **argv __attribute__((unused)))
sigaddset(&set,THR_CLIENT_ALARM);
VOID(pthread_sigmask(SIG_UNBLOCK, &set, (sigset_t*) 0));
#endif
-#endif /* OS2 */
pthread_attr_init(&thr_attr);
pthread_attr_setscope(&thr_attr,PTHREAD_SCOPE_PROCESS);
@@ -1066,8 +917,8 @@ int main(int argc __attribute__((unused)),char **argv __attribute__((unused)))
}
}
pthread_mutex_unlock(&LOCK_thread_count);
- end_thr_alarm(1);
thr_alarm_info(&alarm_info);
+ end_thr_alarm(1);
printf("Main_thread: Alarms: %u max_alarms: %u next_alarm_time: %lu\n",
alarm_info.active_alarms, alarm_info.max_used_alarms,
alarm_info.next_alarm_time);
diff --git a/mysys/thr_lock.c b/mysys/thr_lock.c
index 27203c2d23c..2a1b94a363e 100644
--- a/mysys/thr_lock.c
+++ b/mysys/thr_lock.c
@@ -71,7 +71,7 @@ multiple read locks.
*/
#if !defined(MAIN) && !defined(DBUG_OFF) && !defined(EXTRA_DEBUG)
-#define DBUG_OFF
+#define FORCE_DBUG_OFF
#endif
#include "mysys_priv.h"
@@ -481,7 +481,7 @@ thr_lock(THR_LOCK_DATA *data, THR_LOCK_OWNER *owner,
data->type=lock_type;
data->owner= owner; /* Must be reset ! */
VOID(pthread_mutex_lock(&lock->mutex));
- DBUG_PRINT("lock",("data: 0x%lx thread: %ld lock: 0x%lx type: %d",
+ DBUG_PRINT("lock",("data: 0x%lx thread: 0x%lx lock: 0x%lx type: %d",
(long) data, data->owner->info->thread_id,
(long) lock, (int) lock_type));
check_locks(lock,(uint) lock_type <= (uint) TL_READ_NO_INSERT ?
@@ -500,7 +500,7 @@ thr_lock(THR_LOCK_DATA *data, THR_LOCK_OWNER *owner,
and the read lock is not TL_READ_NO_INSERT
*/
- DBUG_PRINT("lock",("write locked by thread: %ld",
+ DBUG_PRINT("lock",("write locked by thread: 0x%lx",
lock->write.data->owner->info->thread_id));
if (thr_lock_owner_equal(data->owner, lock->write.data->owner) ||
(lock->write.data->type <= TL_WRITE_DELAYED &&
@@ -622,7 +622,7 @@ thr_lock(THR_LOCK_DATA *data, THR_LOCK_OWNER *owner,
statistic_increment(locks_immediate,&THR_LOCK_lock);
goto end;
}
- DBUG_PRINT("lock",("write locked by thread: %ld",
+ DBUG_PRINT("lock",("write locked by thread: 0x%lx",
lock->write.data->owner->info->thread_id));
}
else
@@ -658,7 +658,7 @@ thr_lock(THR_LOCK_DATA *data, THR_LOCK_OWNER *owner,
goto end;
}
}
- DBUG_PRINT("lock",("write locked by thread: %ld, type: %d",
+ DBUG_PRINT("lock",("write locked by thread: 0x%lx, type: %d",
lock->read.data->owner->info->thread_id, data->type));
}
wait_queue= &lock->write_wait;
@@ -720,7 +720,7 @@ static inline void free_all_read_locks(THR_LOCK *lock,
}
lock->read_no_write_count++;
}
- DBUG_PRINT("lock",("giving read lock to thread: %ld",
+ DBUG_PRINT("lock",("giving read lock to thread: 0x%lx",
data->owner->info->thread_id));
data->cond=0; /* Mark thread free */
VOID(pthread_cond_signal(cond));
@@ -738,7 +738,7 @@ void thr_unlock(THR_LOCK_DATA *data)
THR_LOCK *lock=data->lock;
enum thr_lock_type lock_type=data->type;
DBUG_ENTER("thr_unlock");
- DBUG_PRINT("lock",("data: 0x%lx thread: %ld lock: 0x%lx",
+ DBUG_PRINT("lock",("data: 0x%lx thread: 0x%lx lock: 0x%lx",
(long) data, data->owner->info->thread_id, (long) lock));
pthread_mutex_lock(&lock->mutex);
check_locks(lock,"start of release lock",0);
@@ -798,7 +798,7 @@ void thr_unlock(THR_LOCK_DATA *data)
if (data->type == TL_WRITE_CONCURRENT_INSERT &&
(*lock->check_status)(data->status_param))
data->type=TL_WRITE; /* Upgrade lock */
- DBUG_PRINT("lock",("giving write lock of type %d to thread: %ld",
+ DBUG_PRINT("lock",("giving write lock of type %d to thread: 0x%lx",
data->type, data->owner->info->thread_id));
{
pthread_cond_t *cond=data->cond;
@@ -1011,7 +1011,7 @@ void thr_multi_unlock(THR_LOCK_DATA **data,uint count)
TL_WRITE_ONLY to abort any new accesses to the lock
*/
-void thr_abort_locks(THR_LOCK *lock)
+void thr_abort_locks(THR_LOCK *lock, bool upgrade_lock)
{
THR_LOCK_DATA *data;
DBUG_ENTER("thr_abort_locks");
@@ -1033,7 +1033,7 @@ void thr_abort_locks(THR_LOCK *lock)
lock->read_wait.last= &lock->read_wait.data;
lock->write_wait.last= &lock->write_wait.data;
lock->read_wait.data=lock->write_wait.data=0;
- if (lock->write.data)
+ if (upgrade_lock && lock->write.data)
lock->write.data->type=TL_WRITE_ONLY;
pthread_mutex_unlock(&lock->mutex);
DBUG_VOID_RETURN;
@@ -1091,6 +1091,216 @@ my_bool thr_abort_locks_for_thread(THR_LOCK *lock, pthread_t thread)
}
+/*
+ Downgrade a WRITE_* to a lower WRITE level
+ SYNOPSIS
+ thr_downgrade_write_lock()
+ in_data Lock data of thread downgrading its lock
+ new_lock_type New write lock type
+ RETURN VALUE
+ NONE
+ DESCRIPTION
+ This can be used to downgrade a lock already owned. When the downgrade
+ occurs also other waiters, both readers and writers can be allowed to
+ start.
+ The previous lock is often TL_WRITE_ONLY but can also be
+ TL_WRITE and TL_WRITE_ALLOW_READ. The normal downgrade variants are
+ TL_WRITE_ONLY => TL_WRITE_ALLOW_READ After a short exclusive lock
+ TL_WRITE_ALLOW_READ => TL_WRITE_ALLOW_WRITE After discovering that the
+ operation didn't need such a high lock.
+ TL_WRITE_ONLY => TL_WRITE after a short exclusive lock while holding a
+ write table lock
+ TL_WRITE_ONLY => TL_WRITE_ALLOW_WRITE After a short exclusive lock after
+ already earlier having dongraded lock to TL_WRITE_ALLOW_WRITE
+ The implementation is conservative and rather don't start rather than
+ go on unknown paths to start, the common cases are handled.
+
+ NOTE:
+ In its current implementation it is only allowed to downgrade from
+ TL_WRITE_ONLY. In this case there are no waiters. Thus no wake up
+ logic is required.
+*/
+
+void thr_downgrade_write_lock(THR_LOCK_DATA *in_data,
+ enum thr_lock_type new_lock_type)
+{
+ THR_LOCK *lock=in_data->lock;
+ enum thr_lock_type old_lock_type= in_data->type;
+#ifdef TO_BE_REMOVED
+ THR_LOCK_DATA *data, *next;
+ bool start_writers= FALSE;
+ bool start_readers= FALSE;
+#endif
+ DBUG_ENTER("thr_downgrade_write_only_lock");
+
+ pthread_mutex_lock(&lock->mutex);
+ DBUG_ASSERT(old_lock_type == TL_WRITE_ONLY);
+ DBUG_ASSERT(old_lock_type > new_lock_type);
+ in_data->type= new_lock_type;
+ check_locks(lock,"after downgrading lock",0);
+
+#if TO_BE_REMOVED
+ switch (old_lock_type)
+ {
+ case TL_WRITE_ONLY:
+ case TL_WRITE:
+ case TL_WRITE_LOW_PRIORITY:
+ /*
+ Previous lock was exclusive we are now ready to start up most waiting
+ threads.
+ */
+ switch (new_lock_type)
+ {
+ case TL_WRITE_ALLOW_READ:
+ /* Still cannot start WRITE operations. Can only start readers. */
+ start_readers= TRUE;
+ break;
+ case TL_WRITE:
+ case TL_WRITE_LOW_PRIORITY:
+ /*
+ Still cannot start anything, but new requests are no longer
+ aborted.
+ */
+ break;
+ case TL_WRITE_ALLOW_WRITE:
+ /*
+ We can start both writers and readers.
+ */
+ start_writers= TRUE;
+ start_readers= TRUE;
+ break;
+ case TL_WRITE_CONCURRENT_INSERT:
+ case TL_WRITE_DELAYED:
+ /*
+ This routine is not designed for those. Lock will be downgraded
+ but no start of waiters will occur. This is not the optimal but
+ should be a correct behaviour.
+ */
+ break;
+ default:
+ DBUG_ASSERT(0);
+ }
+ break;
+ case TL_WRITE_DELAYED:
+ case TL_WRITE_CONCURRENT_INSERT:
+ /*
+ This routine is not designed for those. Lock will be downgraded
+ but no start of waiters will occur. This is not the optimal but
+ should be a correct behaviour.
+ */
+ break;
+ case TL_WRITE_ALLOW_READ:
+ DBUG_ASSERT(new_lock_type == TL_WRITE_ALLOW_WRITE);
+ /*
+ Previously writers were not allowed to start, now it is ok to
+ start them again. Readers are already allowed so no reason to
+ handle them.
+ */
+ start_writers= TRUE;
+ break;
+ default:
+ DBUG_ASSERT(0);
+ break;
+ }
+ if (start_writers)
+ {
+ /*
+ At this time the only active writer can be ourselves. Thus we need
+ not worry about that there are other concurrent write operations
+ active on the table. Thus we only need to worry about starting
+ waiting operations.
+ We also only come here with TL_WRITE_ALLOW_WRITE as the new
+ lock type, thus we can start other writers also of the same type.
+ If we find a lock at exclusive level >= TL_WRITE_LOW_PRIORITY we
+ don't start any more operations that would be mean those operations
+ will have to wait for things started afterwards.
+ */
+ DBUG_ASSERT(new_lock_type == TL_WRITE_ALLOW_WRITE);
+ for (data=lock->write_wait.data; data ; data= next)
+ {
+ /*
+ All WRITE requests compatible with new lock type are also
+ started
+ */
+ next= data->next;
+ if (start_writers && data->type == new_lock_type)
+ {
+ pthread_cond_t *cond= data->cond;
+ /*
+ It is ok to start this waiter.
+ Move from being first in wait queue to be last in write queue.
+ */
+ if (((*data->prev)= data->next))
+ data->next->prev= data->prev;
+ else
+ lock->write_wait.last= data->prev;
+ data->prev= lock->write.last;
+ lock->write.last= &data->next;
+ data->next= 0;
+ check_locks(lock, "Started write lock after downgrade",0);
+ data->cond= 0;
+ pthread_cond_signal(cond);
+ }
+ else
+ {
+ /*
+ We found an incompatible lock, we won't start any more write
+ requests to avoid letting writers pass other writers in the
+ queue.
+ */
+ start_writers= FALSE;
+ if (data->type >= TL_WRITE_LOW_PRIORITY)
+ {
+ /*
+ We have an exclusive writer in the queue so we won't start
+ readers either.
+ */
+ start_readers= FALSE;
+ }
+ }
+ }
+ }
+ if (start_readers)
+ {
+ DBUG_ASSERT(new_lock_type == TL_WRITE_ALLOW_WRITE ||
+ new_lock_type == TL_WRITE_ALLOW_READ);
+ /*
+ When we come here we know that the write locks are
+ TL_WRITE_ALLOW_WRITE or TL_WRITE_ALLOW_READ. This means that reads
+ are ok
+ */
+ for (data=lock->read_wait.data; data ; data=next)
+ {
+ next= data->next;
+ /*
+ All reads are ok to start now except TL_READ_NO_INSERT when
+ write lock is TL_WRITE_ALLOW_READ.
+ */
+ if (new_lock_type != TL_WRITE_ALLOW_READ ||
+ data->type != TL_READ_NO_INSERT)
+ {
+ pthread_cond_t *cond= data->cond;
+ if (((*data->prev)= data->next))
+ data->next->prev= data->prev;
+ else
+ lock->read_wait.last= data->prev;
+ data->prev= lock->read.last;
+ lock->read.last= &data->next;
+ data->next= 0;
+
+ if (data->type == TL_READ_NO_INSERT)
+ lock->read_no_write_count++;
+ check_locks(lock, "Started read lock after downgrade",0);
+ data->cond= 0;
+ pthread_cond_signal(cond);
+ }
+ }
+ }
+ check_locks(lock,"after starting waiters after downgrading lock",0);
+#endif
+ pthread_mutex_unlock(&lock->mutex);
+ DBUG_VOID_RETURN;
+}
/* Upgrade a WRITE_DELAY lock to a WRITE_LOCK */
diff --git a/mysys/thr_mutex.c b/mysys/thr_mutex.c
index 425e5fce459..42f9fe5f600 100644
--- a/mysys/thr_mutex.c
+++ b/mysys/thr_mutex.c
@@ -356,3 +356,80 @@ void safe_mutex_end(FILE *file __attribute__((unused)))
}
#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)
+{
+ ulong i;
+ volatile ulong j;
+
+ j = 0;
+
+ for (i = 0; i < delayloops * 50; i++)
+ j += i;
+
+ return(j);
+}
+
+#define MY_PTHREAD_FASTMUTEX_SPINS 8
+#define MY_PTHREAD_FASTMUTEX_DELAY 4
+
+int my_pthread_fastmutex_init(my_pthread_fastmutex_t *mp,
+ const pthread_mutexattr_t *attr)
+{
+ static int cpu_count= 0;
+#ifdef _SC_NPROCESSORS_CONF
+ if (!cpu_count && (attr == MY_MUTEX_INIT_FAST))
+ cpu_count= sysconf(_SC_NPROCESSORS_CONF);
+#endif
+
+ if ((cpu_count > 1) && (attr == MY_MUTEX_INIT_FAST))
+ mp->spins= MY_PTHREAD_FASTMUTEX_SPINS;
+ else
+ mp->spins= 0;
+ return pthread_mutex_init(&mp->mutex, attr);
+}
+
+int my_pthread_fastmutex_lock(my_pthread_fastmutex_t *mp)
+{
+ int res;
+ uint i;
+ uint maxdelay= MY_PTHREAD_FASTMUTEX_DELAY;
+
+ for (i= 0; i < mp->spins; i++)
+ {
+ res= pthread_mutex_trylock(&mp->mutex);
+
+ if (res == 0)
+ return 0;
+
+ if (res != EBUSY)
+ return res;
+
+ mutex_delay(maxdelay);
+ maxdelay += ((double) random() / (double) RAND_MAX) *
+ MY_PTHREAD_FASTMUTEX_DELAY + 1;
+ }
+ return pthread_mutex_lock(&mp->mutex);
+}
+#endif /* defined(THREAD) && defined(MY_PTHREAD_FASTMUTEX) && !defined(SAFE_MUTEX) */
diff --git a/mysys/trie.c b/mysys/trie.c
new file mode 100644
index 00000000000..8daa6f3e661
--- /dev/null
+++ b/mysys/trie.c
@@ -0,0 +1,236 @@
+/* Copyright (C) 2005 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 */
+
+/*
+ Implementation of trie and Aho-Corasick automaton.
+ Supports only charsets that can be compared byte-wise.
+
+ TODO:
+ Add character frequencies. Can increase lookup speed
+ up to 30%.
+ Implement character-wise comparision.
+*/
+
+
+#include "mysys_priv.h"
+#include <m_string.h>
+#include <my_trie.h>
+#include <my_base.h>
+
+
+/*
+ SYNOPSIS
+ TRIE *trie_init (TRIE *trie, CHARSET_INFO *charset);
+
+ DESCRIPTION
+ Allocates or initializes a `TRIE' object. If `trie' is a `NULL'
+ pointer, the function allocates, initializes, and returns a new
+ object. Otherwise, the object is initialized and the address of
+ the object is returned. If `trie_init()' allocates a new object,
+ it will be freed when `trie_free()' is called.
+
+ RETURN VALUE
+ An initialized `TRIE*' object. `NULL' if there was insufficient
+ memory to allocate a new object.
+*/
+
+TRIE *trie_init (TRIE *trie, CHARSET_INFO *charset)
+{
+ MEM_ROOT mem_root;
+ DBUG_ENTER("trie_init");
+ DBUG_ASSERT(charset);
+ init_alloc_root(&mem_root,
+ (sizeof(TRIE_NODE) * 128) + ALLOC_ROOT_MIN_BLOCK_SIZE,
+ sizeof(TRIE_NODE) * 128);
+ if (! trie)
+ {
+ if (! (trie= (TRIE *)alloc_root(&mem_root, sizeof(TRIE))))
+ {
+ free_root(&mem_root, MYF(0));
+ DBUG_RETURN(NULL);
+ }
+ }
+
+ memcpy(&trie->mem_root, &mem_root, sizeof(MEM_ROOT));
+ trie->root.leaf= 0;
+ trie->root.c= 0;
+ trie->root.next= NULL;
+ trie->root.links= NULL;
+ trie->root.fail= NULL;
+ trie->charset= charset;
+ trie->nnodes= 0;
+ trie->nwords= 0;
+ DBUG_RETURN(trie);
+}
+
+
+/*
+ SYNOPSIS
+ void trie_free (TRIE *trie);
+ trie - valid pointer to `TRIE'
+
+ DESCRIPTION
+ Frees the memory allocated for a `trie'.
+
+ RETURN VALUE
+ None.
+*/
+
+void trie_free (TRIE *trie)
+{
+ MEM_ROOT mem_root;
+ DBUG_ENTER("trie_free");
+ DBUG_ASSERT(trie);
+ memcpy(&mem_root, &trie->mem_root, sizeof(MEM_ROOT));
+ free_root(&mem_root, MYF(0));
+ DBUG_VOID_RETURN;
+}
+
+
+/*
+ SYNOPSIS
+ my_bool trie_insert (TRIE *trie, const byte *key, uint keylen);
+ trie - valid pointer to `TRIE'
+ key - valid pointer to key to insert
+ keylen - non-0 key length
+
+ DESCRIPTION
+ Inserts new key into trie.
+
+ RETURN VALUE
+ Upon successful completion, `trie_insert' returns `FALSE'. Otherwise
+ `TRUE' is returned.
+
+ NOTES
+ If this function fails you must assume `trie' is broken.
+ However it can be freed with trie_free().
+*/
+
+my_bool trie_insert (TRIE *trie, const byte *key, uint keylen)
+{
+ TRIE_NODE *node;
+ TRIE_NODE *next;
+ byte p;
+ uint k;
+ DBUG_ENTER("trie_insert");
+ DBUG_ASSERT(trie && key && keylen);
+ node= &trie->root;
+ trie->root.fail= NULL;
+ for (k= 0; k < keylen; k++)
+ {
+ p= key[k];
+ for (next= node->links; next; next= next->next)
+ if (next->c == p)
+ break;
+
+ if (! next)
+ {
+ TRIE_NODE *tmp= (TRIE_NODE *)alloc_root(&trie->mem_root,
+ sizeof(TRIE_NODE));
+ if (! tmp)
+ DBUG_RETURN(TRUE);
+ tmp->leaf= 0;
+ tmp->c= p;
+ tmp->links= tmp->fail= tmp->next= NULL;
+ trie->nnodes++;
+ if (! node->links)
+ {
+ node->links= tmp;
+ }
+ else
+ {
+ for (next= node->links; next->next; next= next->next) /* no-op */;
+ next->next= tmp;
+ }
+ node= tmp;
+ }
+ else
+ {
+ node= next;
+ }
+ }
+ node->leaf= keylen;
+ trie->nwords++;
+ DBUG_RETURN(FALSE);
+}
+
+
+/*
+ SYNOPSIS
+ my_bool trie_prepare (TRIE *trie);
+ trie - valid pointer to `TRIE'
+
+ DESCRIPTION
+ Constructs Aho-Corasick automaton.
+
+ RETURN VALUE
+ Upon successful completion, `trie_prepare' returns `FALSE'. Otherwise
+ `TRUE' is returned.
+*/
+
+my_bool ac_trie_prepare (TRIE *trie)
+{
+ TRIE_NODE **tmp_nodes;
+ TRIE_NODE *node;
+ uint32 fnode= 0;
+ uint32 lnode= 0;
+ DBUG_ENTER("trie_prepare");
+ DBUG_ASSERT(trie);
+
+ tmp_nodes= (TRIE_NODE **)my_malloc(trie->nnodes * sizeof(TRIE_NODE *), MYF(0));
+ if (! tmp_nodes)
+ DBUG_RETURN(TRUE);
+
+ trie->root.fail= &trie->root;
+ for (node= trie->root.links; node; node= node->next)
+ {
+ node->fail= &trie->root;
+ tmp_nodes[lnode++]= node;
+ }
+
+ while (fnode < lnode)
+ {
+ TRIE_NODE *current= (TRIE_NODE *)tmp_nodes[fnode++];
+ for (node= current->links; node; node= node->next)
+ {
+ TRIE_NODE *fail= current->fail;
+ tmp_nodes[lnode++]= node;
+ while (! (node->fail= trie_goto(&trie->root, fail, node->c)))
+ fail= fail->fail;
+ }
+ }
+ my_free((gptr)tmp_nodes, MYF(0));
+ DBUG_RETURN(FALSE);
+}
+
+
+/*
+ SYNOPSIS
+ void ac_trie_init (TRIE *trie, AC_TRIE_STATE *state);
+ trie - valid pointer to `TRIE'
+ state - value pointer to `AC_TRIE_STATE'
+
+ DESCRIPTION
+ Initializes `AC_TRIE_STATE' object.
+*/
+
+void ac_trie_init (TRIE *trie, AC_TRIE_STATE *state)
+{
+ DBUG_ENTER("ac_trie_init");
+ DBUG_ASSERT(trie && state);
+ state->trie= trie;
+ state->node= &trie->root;
+ DBUG_VOID_RETURN;
+}